Skip to content

Persian-Caesar/chatbot

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

34 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

@persian-caesar/chatbot 🚀

A lightweight, Persian-first, TypeScript chatbot engine
designed for fun, educational, and custom conversation experiences.

npm version npm downloads License: MIT

Current personality: "بچه" — an 8-year-old cheerful & innocent child-like character
Language focus: Modern Persian (Farsi) with natural, spoken style + emojis 😄

✨ Features

  • 🧠 Short-term memory (last 5 messages) + long-term context via quick.db
  • 📚 Markov chain response generation (learns from real conversations)
  • 🕸️ Simple Persian Knowledge Graph (triple extraction)
  • 😊 Rule-based sentiment analysis (positive/negative/neutral + intensifiers & negation)
  • 🌐 Web fallback search (DuckDuckGo + Persian Wikipedia)
  • Built-in FAQ answers for common questions
  • 🔄 Contextual follow-up questions when relevant
  • 🎭 Personality-driven fallback responses
  • 🔧 Easy database abstraction (currently QuickDB JSON driver)
  • Tiny & dependency-light (~ few KB gzipped + quick.db)

📦 Installation

npm install @persian-caesar/chatbot quick.db
# or
yarn add @persian-caesar/chatbot quick.db
# or
pnpm add @persian-caesar/chatbot quick.db

🚀 Quick Start

import { Database, default as ChatBot } from "@persian-caesar/chatbot";
import { QuickDB, JSONDriver } from "quick.db";

// 1. Create database instance
const db = new Database(new QuickDB({ driver: new JSONDriver() }));

// 2. Create chatbot (channelId can be guildId, threadId, userId, etc.)
const bot = new ChatBot(db, "global-channel-123", /* optional custom system prompt */);

// 3. Get reply
async function chat(message: string) {
  const reply = await bot.handleMessage(message);
  console.log("بچه:", reply);
}

chat("سلام خوبی؟");          // → جواب شاد و کودکانه
chat("چرا آسمون آبیه؟");     // → تلاش برای جستجو یا دانش عمومی
chat("پدرت کیه؟");            // → جواب FAQ آماده

📂 Project Structure

.
├── .github/workflows/publish.yml      # Auto-publish to npm & GitHub Packages
├── src/
│   ├── config.ts                      # Personality, system prompt, dictionaries
│   ├── index.ts                       # Main exports
│   ├── types.ts                       # Shared types (MessageRecord, Triple, MarkovEntry)
│   ├── models/
│   │   └── ChatBot.ts                 # Core logic → handleMessage()
│   └── utils/
│       ├── Database.ts                # QuickDB wrapper
│       ├── SearchService.ts           # DuckDuckGo + fa.wikipedia.org
│       └── SentimentAnalyzer.ts       # Lexicon-based sentiment (persian words)
├── test/
│   ├── server.js                      # Simple HTTP server for web testing
│   ├── test.html                      # Nice dark-themed chat UI (browser test)
│   └── test.js                        # Console readline test
├── .gitignore / .npmignore
├── LICENSE                            # MIT
├── package.json
├── tsconfig.json
└── README.md

🛠 Core Classes & Methods

ChatBot (main class)

Method Description Returns
new ChatBot(db, channelId?, systemPrompt?) Create instance per channel/user/thread
async handleMessage(text) Main entry point — full response pipeline Promise<string>
async reset() Clear conversation history & re-init system prompt Promise<void>

Internal pipeline order (stops at first success):

  1. Static FAQ
  2. Knowledge Graph query
  3. Negative sentiment reaction
  4. Positive sentiment boost (sometimes)
  5. Web search (question words: چرا، چطور، کجا، ...)
  6. Markov chain generation
  7. Semantic similarity to previous answers
  8. Personality fallback phrase

Database (wrapper)

Thin wrapper over quick.db

Method Usage example Notes
has(key) db.has("chat:global") boolean
get(key) db.get("markov:123") any or false
set(key, value) db.set("kg:abc", triples)
push(key, value) db.push("chat:global", msg) array append
delete(key) db.delete("chat:old")

Stored Database Keys (quick.db)

Key pattern Type Sample value / Purpose
chat:${channelId} MessageRecord[] Full conversation history (system + user + assistant)
markov:${channelId} MarkovEntry[] Learned bigram → next word probabilities
kg:${channelId} Triple[] Extracted {subject, predicate, object} facts

MessageRecord

{
  role: "system" | "user" | "assistant";
  content: string;
}

Triple (knowledge graph)

{
  subject: string;
  predicate: string;   // e.g. "is", "can", "درباره"
  object: string;
}

MarkovEntry

{
  gram: string;           // "سلام خوبی" or "[START] سلام"
  next: Record<string, number>;  // {"خوبی": 3, "چطوری": 1, ...}
}

⚙ Configuration (src/config.ts)

You can fork and customize:

  • systemPrompt → change character age/personality/tone
  • sentimentResponses → custom sad/happy replies
  • dictionaries → add more Persian positive/negative/intensifier/negation words

🧪 Testing

# Console test
node test/test.js

# Web test (open test/test.html in browser after running server)
node test/server.js

⚠ Limitations & Known Issues

  • Markov model can produce nonsense if little training data
  • Sentiment is lexicon-based → not contextual (no transformers)
  • Knowledge graph extraction is very naive (regex-based)
  • Web search is slow & rate-limited by free APIs
  • No rate limiting / spam protection yet
  • Persian tokenization is basic (no advanced NLP)

🌟 Contributing

Pull requests are welcome!
Especially welcome:

  • Better Persian tokenizer / stemmer
  • More advanced Markov (trigram, backoff)
  • Better sentiment with negation scope
  • Redis / better DB driver support
  • Rate limiting & message cleanup

📄 License

MIT © 2025 Sobhan (Sobhan-SRZA) & Persian-Caesar

Made with ❤️ for Persian community