VISHAL18for4 commited on
Commit
8dd5cb9
·
verified ·
1 Parent(s): 719579d

Delete chatbot.py

Browse files
Files changed (1) hide show
  1. chatbot.py +0 -210
chatbot.py DELETED
@@ -1,210 +0,0 @@
1
- """
2
- chatbot.py — Conversational AI that answers from what it has actually learned.
3
- Synthesizes knowledge into natural paragraph answers, like ChatGPT/Claude/Gemini.
4
- """
5
- import json, re, math, os, random
6
- from collections import Counter, defaultdict
7
- from html import unescape
8
-
9
- KNOWLEDGE_FILE = 'knowledge.jsonl'
10
- STOPWORDS = {
11
- 'a','an','the','is','it','in','on','at','to','for','of','and','or','but',
12
- 'was','are','were','be','been','have','has','had','do','does','did','will',
13
- 'would','could','should','may','might','that','this','these','those','with',
14
- 'from','by','as','not','also','than','then','so','if','when','what','how',
15
- 'who','which','its','their','our','your','my','his','her','we','they','he',
16
- 'she','you','i','me','him','us','them','said','says',
17
- }
18
-
19
- def tokenize(text):
20
- text = re.sub(r'[^\w\s]', ' ', text.lower())
21
- return [w for w in text.split() if w not in STOPWORDS and len(w) > 2]
22
-
23
- def clean_text(text):
24
- """Remove HTML artifacts from stored text."""
25
- text = unescape(text)
26
- text = re.sub(r'&#?[a-zA-Z0-9]+;', ' ', text)
27
- text = re.sub(r'<[^>]+>', ' ', text)
28
- text = re.sub(r'\s+', ' ', text).strip()
29
- return text
30
-
31
-
32
- class KnowledgeBase:
33
- def __init__(self):
34
- self.docs=[]; self.doc_tokens=[]; self.idf={}; self.last_count=0
35
- self._load()
36
-
37
- def _load(self):
38
- if not os.path.exists(KNOWLEDGE_FILE): return
39
- new_docs = []
40
- try:
41
- with open(KNOWLEDGE_FILE,'r',encoding='utf-8') as f:
42
- for line in f:
43
- line=line.strip()
44
- if line:
45
- try: new_docs.append(json.loads(line))
46
- except: pass
47
- except: return
48
- if len(new_docs)==self.last_count: return
49
- self.docs=new_docs; self.last_count=len(new_docs)
50
- self.doc_tokens=[tokenize(clean_text(d.get('text',''))) for d in self.docs]
51
- N=len(self.docs)
52
- df=defaultdict(int)
53
- for tokens in self.doc_tokens:
54
- for w in set(tokens): df[w]+=1
55
- self.idf={w:math.log((N+1)/(c+1))+1 for w,c in df.items()}
56
-
57
- def search(self, query, top_k=8):
58
- self._load()
59
- if not self.docs: return []
60
- q=tokenize(query)
61
- if not q: return []
62
- def score(dt):
63
- tf=Counter(dt); n=max(len(dt),1)
64
- return sum((tf[w]/n)*self.idf.get(w,0) for w in q if w in tf)
65
- ranked=sorted(range(len(self.docs)),key=lambda i:-score(self.doc_tokens[i]))
66
- return [(self.docs[i], score(self.doc_tokens[i])) for i in ranked[:top_k]
67
- if score(self.doc_tokens[i])>0]
68
-
69
- def get_stats(self):
70
- self._load()
71
- return {
72
- 'total': len(self.docs),
73
- 'categories': dict(Counter(d.get('category','other') for d in self.docs)),
74
- 'sources': dict(Counter(d.get('source','unknown') for d in self.docs)),
75
- }
76
-
77
-
78
- def _synthesize(query, results):
79
- """
80
- Turn retrieved article snippets into a natural conversational answer.
81
- Like ChatGPT — reads all sources, writes a coherent paragraph response.
82
- """
83
- q_tokens = set(tokenize(query))
84
-
85
- # Gather the best individual sentences across all docs
86
- all_sentences = []
87
- for doc, sc in results:
88
- text = clean_text(doc.get('text', ''))
89
- # Split into sentences
90
- sents = re.split(r'(?<=[.!?])\s+', text)
91
- for s in sents:
92
- s = s.strip()
93
- if len(s) < 30: continue
94
- overlap = len(q_tokens & set(tokenize(s)))
95
- # Slight relevance boost for sentences that mention query words
96
- all_sentences.append((overlap + sc * 0.3, s))
97
-
98
- # Deduplicate and pick top sentences
99
- seen = set(); chosen = []
100
- for score, sent in sorted(all_sentences, reverse=True):
101
- key = sent[:60].lower()
102
- if key not in seen and len(chosen) < 6:
103
- seen.add(key)
104
- chosen.append(sent)
105
-
106
- if not chosen:
107
- return None
108
-
109
- # Build a flowing paragraph (not a bullet dump)
110
- # Join sentences intelligently
111
- answer_sents = chosen[:4]
112
-
113
- # Fix any leftover HTML entities in chosen sentences
114
- answer_sents = [unescape(s) for s in answer_sents]
115
-
116
- # Combine into paragraphs
117
- if len(answer_sents) <= 2:
118
- paragraph = ' '.join(answer_sents)
119
- else:
120
- paragraph = ' '.join(answer_sents[:2])
121
- rest = ' '.join(answer_sents[2:])
122
- paragraph = paragraph + '\n\n' + rest
123
-
124
- return paragraph.strip()
125
-
126
-
127
- class RAGChatbot:
128
- def __init__(self):
129
- self.kb = KnowledgeBase()
130
-
131
- def _answer(self, query, results, stats):
132
- total = stats['total']
133
-
134
- if total == 0:
135
- return ("My brain is empty right now 🧠\n\n"
136
- "Go to **Control → ▶ Start Text** to feed me internet articles. "
137
- "The more I read, the smarter I get!")
138
-
139
- if not results:
140
- topics = ', '.join(list(stats['categories'].keys())[:5])
141
- return (f"I've read **{total} articles** so far, but I haven't learned "
142
- f"enough about *{query}* yet.\n\n"
143
- f"My current knowledge is mostly about: **{topics}**.\n\n"
144
- f"Keep me training and I'll learn more over time! 📚")
145
-
146
- answer = _synthesize(query, results)
147
- if not answer:
148
- return (f"I found related articles but couldn't form a clear answer yet. "
149
- f"Try asking in a different way!")
150
-
151
- # Conversational wrap — just the answer, clean and simple
152
- return answer
153
-
154
- def chat(self, user_message, history):
155
- history = list(history or [])
156
- msg = user_message.strip()
157
- if not msg: return history
158
-
159
- lower = msg.lower()
160
- stats = self.kb.get_stats()
161
-
162
- # ── Greetings ──
163
- if lower in ('hi','hello','hey','sup','yo','hiya','howdy','helo','hai'):
164
- total = stats['total']
165
- if total == 0:
166
- bot_reply = ("Hey! 👋 I'm your AI, but I haven't read anything yet.\n\n"
167
- "Go to **Control → ▶ Start Text** to start teaching me!")
168
- else:
169
- topics = ', '.join(list(stats['categories'].keys())[:4])
170
- bot_reply = (f"Hey! 👋 I've read **{total} articles** so far.\n\n"
171
- f"I know quite a bit about **{topics}**. What do you want to know?")
172
-
173
- elif any(p in lower for p in ('how are you','how r you',"what's up",'whats up')):
174
- bot_reply = "I'm doing great — always learning! 🤖 What do you want to know?"
175
-
176
- elif any(p in lower for p in ('who are you','what are you','what can you do','tell me about yourself')):
177
- bot_reply = (
178
- "I'm a **Living Neural Network** — an AI that learns from real internet articles in real time! 🧠\n\n"
179
- f"I've read **{stats['total']} articles** so far. Unlike ChatGPT, I only know what "
180
- "I've actually been trained on — no pre-built knowledge. "
181
- "The more articles I read, the smarter I get. Ask me anything I might have learned!"
182
- )
183
-
184
- elif lower in ('stats','status','what do you know','knowledge'):
185
- lines = '\n'.join(f"• **{k}**: {v} articles"
186
- for k,v in sorted(stats['categories'].items(),key=lambda x:-x[1]))
187
- srcs = ', '.join(f"{k} ({v})" for k,v in list(stats['sources'].items())[:6])
188
- bot_reply = (f"**My knowledge so far:**\n\n{lines or '• nothing yet'}\n\n"
189
- f"**Sources I've read from:** {srcs or 'none yet'}\n\n"
190
- f"**Total:** {stats['total']} articles")
191
-
192
- elif lower in ('help','?','commands'):
193
- bot_reply = ("Just ask me anything — I'll answer from what I've learned!\n\n"
194
- "**Examples:**\n"
195
- "- *What is science?*\n"
196
- "- *Who is Elon Musk?*\n"
197
- "- *What's happening in AI?*\n"
198
- "- *Tell me about climate change*\n\n"
199
- "Type `stats` to see what I know.")
200
-
201
- elif any(p in lower for p in ('thanks','thank you','thx','ty')):
202
- bot_reply = "You're welcome! 😊"
203
-
204
- else:
205
- results = self.kb.search(msg, top_k=8)
206
- bot_reply = self._answer(msg, results, stats)
207
-
208
- history.append({"role": "user", "content": user_message})
209
- history.append({"role": "assistant", "content": bot_reply})
210
- return history