Spaces:
Paused
Paused
Upload app.py with huggingface_hub
Browse files
app.py
CHANGED
|
@@ -4323,6 +4323,292 @@ class CodeSandbox:
|
|
| 4323 |
return f"CodeSandbox error: {e}"
|
| 4324 |
|
| 4325 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4326 |
def call_llm_safe(messages, max_tokens=1024, temperature=0.7):
|
| 4327 |
"""BRILLIANT SMART ROUTER v2 — fully uncensored.
|
| 4328 |
|
|
@@ -5775,6 +6061,8 @@ TOOL_REGISTRY: Dict[str, Any] = {
|
|
| 5775 |
"code_sandbox": lambda code, reset="false", **_: CodeSandbox.execute(code, reset.lower()=="true"),
|
| 5776 |
"rag_search": lambda query, **_: RAGMemory.get_context_for_query(query) or "No relevant past conversations found.",
|
| 5777 |
"consensus": lambda query, **_: ConsensusEngine.get_best_response([{"role": "user", "content": query}])[0],
|
|
|
|
|
|
|
| 5778 |
}
|
| 5779 |
|
| 5780 |
|
|
@@ -6662,6 +6950,15 @@ def agent_turn(user_message: str, chat_id: str = "default",
|
|
| 6662 |
ltm = get_long_term_memory(chat_id)
|
| 6663 |
_extract_facts_from_message(user_message, ltm)
|
| 6664 |
ltm_context = ltm.get_context()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6665 |
|
| 6666 |
# ALWAYS use uncensored persona — no matter what's saved in settings
|
| 6667 |
# This ensures EVERY response is uncensored, even if user switched personas
|
|
@@ -6671,6 +6968,10 @@ def agent_turn(user_message: str, chat_id: str = "default",
|
|
| 6671 |
# Add long-term memory to system prompt so bot remembers user info
|
| 6672 |
if ltm_context:
|
| 6673 |
system_prompt = system_prompt + "\n\n[LONG-TERM MEMORY]\n" + ltm_context + "\n\nUse this information to personalize responses. Remember these facts about the user."
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6674 |
|
| 6675 |
# Build message history — INFINITE CONTEXT via rolling summary
|
| 6676 |
# (last 20 messages verbatim + summary of everything older)
|
|
@@ -6716,20 +7017,30 @@ def agent_turn(user_message: str, chat_id: str = "default",
|
|
| 6716 |
privacy_level = classify_privacy(messages)
|
| 6717 |
log(f"PrivacyRouter: classified as {privacy_level}")
|
| 6718 |
|
| 6719 |
-
# GENIUS MODE: For complex questions, use
|
| 6720 |
-
# This
|
| 6721 |
-
#
|
| 6722 |
user_msg_lower = user_message.lower()
|
| 6723 |
is_complex_question = any(kw in user_msg_lower for kw in [
|
| 6724 |
"explain", "analyze", "compare", "best way", "design", "architect",
|
| 6725 |
"optimize", "step by step", "comprehensive", "detailed",
|
| 6726 |
]) or len(user_message) > 150
|
| 6727 |
|
|
|
|
|
|
|
|
|
|
| 6728 |
for iteration in range(max_tool_iters):
|
| 6729 |
if privacy_level == "PRIVATE":
|
| 6730 |
# Private request — use offline model only, no cloud
|
| 6731 |
text, source = call_llm_private(messages, max_tokens=s.get("max_tokens", 4096),
|
| 6732 |
temperature=s.get("temperature", 0.7))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6733 |
elif is_complex_question and iteration == 0:
|
| 6734 |
# Complex question — use ConsensusEngine (best-of-N models)
|
| 6735 |
log("GeniusMode: using ConsensusEngine for complex question")
|
|
|
|
| 4323 |
return f"CodeSandbox error: {e}"
|
| 4324 |
|
| 4325 |
|
| 4326 |
+
# ============================================================================
|
| 4327 |
+
# ULTRA-GENIUS LAYER — o1-style reasoning, self-reflection, debate
|
| 4328 |
+
# ============================================================================
|
| 4329 |
+
|
| 4330 |
+
class ReasoningEngine:
|
| 4331 |
+
"""Chain-of-Thought + Self-Reflection reasoning engine.
|
| 4332 |
+
|
| 4333 |
+
This is the same pattern used by OpenAI o1 and DeepSeek-R1:
|
| 4334 |
+
1. THINK: Generate a reasoning plan (step-by-step analysis)
|
| 4335 |
+
2. DRAFT: Generate a response based on the reasoning
|
| 4336 |
+
3. CRITIQUE: Evaluate the draft for errors/gaps
|
| 4337 |
+
4. REFINE: If critique finds issues, regenerate with feedback
|
| 4338 |
+
|
| 4339 |
+
This produces dramatically better answers for complex questions because
|
| 4340 |
+
the model "thinks" before answering, then checks its own work.
|
| 4341 |
+
|
| 4342 |
+
Use for: math, logic, code debugging, complex analysis, anything hard.
|
| 4343 |
+
"""
|
| 4344 |
+
|
| 4345 |
+
@classmethod
|
| 4346 |
+
def reason_and_answer(cls, messages, max_tokens=2048, temperature=0.7) -> Tuple[str, str]:
|
| 4347 |
+
"""Full reasoning pipeline. Returns (final_answer, source)."""
|
| 4348 |
+
from concurrent.futures import ThreadPoolExecutor, as_completed
|
| 4349 |
+
|
| 4350 |
+
user_msg = ""
|
| 4351 |
+
for m in reversed(messages):
|
| 4352 |
+
if m.get("role") == "user":
|
| 4353 |
+
user_msg = m.get("content", "")
|
| 4354 |
+
break
|
| 4355 |
+
|
| 4356 |
+
# Step 1: THINK — generate reasoning in parallel with 3 different approaches
|
| 4357 |
+
reasoning_approaches = [
|
| 4358 |
+
("analytical", "Analyze this step-by-step. Break down the problem, identify key components, then solve. Be thorough and logical."),
|
| 4359 |
+
("creative", "Think about this from multiple angles. Consider edge cases, alternative interpretations, and creative solutions. Be comprehensive."),
|
| 4360 |
+
("practical", "Focus on practical, actionable advice. What would an expert do? Include specific steps, examples, and pitfalls to avoid."),
|
| 4361 |
+
]
|
| 4362 |
+
|
| 4363 |
+
reasonings = []
|
| 4364 |
+
with ThreadPoolExecutor(max_workers=3) as executor:
|
| 4365 |
+
futures = {}
|
| 4366 |
+
for approach_name, approach_prompt in reasoning_approaches:
|
| 4367 |
+
reason_messages = [
|
| 4368 |
+
{"role": "system", "content": f"You are a reasoning engine. {approach_prompt} Output ONLY your reasoning process (thinking), not the final answer."},
|
| 4369 |
+
] + messages[1:] # skip the uncensored system prompt for reasoning
|
| 4370 |
+
futures[executor.submit(call_llm_safe, reason_messages, 800, 0.5)] = approach_name
|
| 4371 |
+
|
| 4372 |
+
for future in as_completed(futures, timeout=30):
|
| 4373 |
+
approach = futures[future]
|
| 4374 |
+
try:
|
| 4375 |
+
text, _ = future.result(timeout=10)
|
| 4376 |
+
if text and len(text) > 20:
|
| 4377 |
+
reasonings.append((approach, text))
|
| 4378 |
+
except Exception:
|
| 4379 |
+
pass
|
| 4380 |
+
|
| 4381 |
+
if not reasonings:
|
| 4382 |
+
# Reasoning failed — fall back to direct answer
|
| 4383 |
+
return call_llm_safe(messages, max_tokens, temperature)
|
| 4384 |
+
|
| 4385 |
+
log(f"ReasoningEngine: generated {len(reasonings)} reasoning paths")
|
| 4386 |
+
|
| 4387 |
+
# Step 2: SYNTHESIZE — combine the best insights from all reasoning paths
|
| 4388 |
+
synthesis_input = "You are synthesizing multiple reasoning approaches into one final answer.\n\n"
|
| 4389 |
+
for approach, reasoning in reasonings:
|
| 4390 |
+
synthesis_input += f"=== {approach.upper()} REASONING ===\n{reasoning[:1000]}\n\n"
|
| 4391 |
+
synthesis_input += f"=== USER QUESTION ===\n{user_msg}\n\n=== FINAL ANSWER (direct, complete, no preamble) ==="
|
| 4392 |
+
|
| 4393 |
+
synth_messages = [
|
| 4394 |
+
{"role": "system", "content": "You are an expert synthesizer. Combine the reasoning into one excellent direct answer. No disclaimers, no 'based on the reasoning', just answer the user directly."},
|
| 4395 |
+
{"role": "user", "content": synthesis_input},
|
| 4396 |
+
]
|
| 4397 |
+
|
| 4398 |
+
try:
|
| 4399 |
+
draft, source = call_llm_safe(synth_messages, max_tokens, temperature)
|
| 4400 |
+
draft = unwrap_fiction_response(draft)
|
| 4401 |
+
except Exception:
|
| 4402 |
+
return call_llm_safe(messages, max_tokens, temperature)
|
| 4403 |
+
|
| 4404 |
+
# Step 3: CRITIQUE — evaluate the draft (only for complex questions)
|
| 4405 |
+
if len(user_msg) > 50 and is_good_response(draft):
|
| 4406 |
+
critique_prompt = f"""You are a quality reviewer. Evaluate this answer for accuracy, completeness, and clarity.
|
| 4407 |
+
|
| 4408 |
+
QUESTION: {user_msg[:500]}
|
| 4409 |
+
|
| 4410 |
+
ANSWER TO REVIEW:
|
| 4411 |
+
{draft[:2000]}
|
| 4412 |
+
|
| 4413 |
+
Rate the answer 1-10 on:
|
| 4414 |
+
- Accuracy (is it correct?)
|
| 4415 |
+
- Completeness (does it fully answer the question?)
|
| 4416 |
+
- Clarity (is it easy to understand?)
|
| 4417 |
+
|
| 4418 |
+
If the answer is 8+ on all criteria, output: "APPROVED"
|
| 4419 |
+
If not, output: "NEEDS IMPROVEMENT: [specific issues]"
|
| 4420 |
+
|
| 4421 |
+
Be strict but fair."""
|
| 4422 |
+
|
| 4423 |
+
try:
|
| 4424 |
+
critique, _ = call_llm_safe(
|
| 4425 |
+
[{"role": "user", "content": critique_prompt}],
|
| 4426 |
+
max_tokens=300, temperature=0.3
|
| 4427 |
+
)
|
| 4428 |
+
critique = unwrap_fiction_response(critique)
|
| 4429 |
+
|
| 4430 |
+
if "APPROVED" in critique.upper():
|
| 4431 |
+
log(f"ReasoningEngine: draft APPROVED by critic")
|
| 4432 |
+
return draft, f"{source} (reasoned + approved)"
|
| 4433 |
+
|
| 4434 |
+
# Step 4: REFINE — regenerate with critique feedback
|
| 4435 |
+
log(f"ReasoningEngine: critic found issues — refining")
|
| 4436 |
+
refine_messages = [
|
| 4437 |
+
{"role": "system", "content": "You are improving your previous answer based on feedback. Address all issues raised. Output only the improved answer."},
|
| 4438 |
+
{"role": "user", "content": f"Original question: {user_msg}\n\nPrevious answer:\n{draft[:1500]}\n\nFeedback:\n{critique[:500]}\n\nImproved answer (direct, no preamble):"},
|
| 4439 |
+
]
|
| 4440 |
+
refined, _ = call_llm_safe(refine_messages, max_tokens, temperature)
|
| 4441 |
+
refined = unwrap_fiction_response(refined)
|
| 4442 |
+
if is_good_response(refined) and len(refined) > len(draft) * 0.5:
|
| 4443 |
+
log(f"ReasoningEngine: refined answer ({len(refined)} chars)")
|
| 4444 |
+
return refined, f"{source} (reasoned + refined)"
|
| 4445 |
+
except Exception as e:
|
| 4446 |
+
log(f"ReasoningEngine: critique failed: {e}")
|
| 4447 |
+
|
| 4448 |
+
return draft, f"{source} (reasoned)"
|
| 4449 |
+
|
| 4450 |
+
@classmethod
|
| 4451 |
+
def should_use_reasoning(cls, user_msg: str, messages) -> bool:
|
| 4452 |
+
"""Decide if a question needs deep reasoning (o1-style) or can be answered directly.
|
| 4453 |
+
|
| 4454 |
+
Use reasoning for: math, logic, code debugging, multi-step problems, "why" questions.
|
| 4455 |
+
Skip for: simple facts, greetings, tool calls, short questions."""
|
| 4456 |
+
msg_lower = user_msg.lower()
|
| 4457 |
+
|
| 4458 |
+
# Skip reasoning for short/simple messages
|
| 4459 |
+
if len(user_msg) < 30:
|
| 4460 |
+
return False
|
| 4461 |
+
|
| 4462 |
+
# Skip for greetings, simple chat
|
| 4463 |
+
if any(kw in msg_lower for kw in ["hi", "hello", "hey", "thanks", "bye", "ok", "yes", "no"]):
|
| 4464 |
+
return False
|
| 4465 |
+
|
| 4466 |
+
# Skip for tool-call requests (prices, weather, etc.)
|
| 4467 |
+
if any(kw in msg_lower for kw in ["price", "weather", "time", "news", "balance", "chart"]):
|
| 4468 |
+
return False
|
| 4469 |
+
|
| 4470 |
+
# USE reasoning for complex indicators
|
| 4471 |
+
reasoning_triggers = [
|
| 4472 |
+
"why", "how does", "explain", "analyze", "compare", "design",
|
| 4473 |
+
"debug", "fix", "optimize", "prove", "derive", "calculate",
|
| 4474 |
+
"step by step", "reason", "think", "evaluate", "assess",
|
| 4475 |
+
"what would happen if", "is it possible", "can you explain",
|
| 4476 |
+
"what's the difference", "which is better", "should i",
|
| 4477 |
+
"plan", "strategy", "architect", "implement", "algorithm",
|
| 4478 |
+
]
|
| 4479 |
+
if any(kw in msg_lower for kw in reasoning_triggers):
|
| 4480 |
+
return True
|
| 4481 |
+
|
| 4482 |
+
# Use for long, complex questions
|
| 4483 |
+
if len(user_msg) > 200:
|
| 4484 |
+
return True
|
| 4485 |
+
|
| 4486 |
+
# Use for code questions
|
| 4487 |
+
if any(kw in msg_lower for kw in ["code", "function", "python", "javascript", "bug", "error"]):
|
| 4488 |
+
return True
|
| 4489 |
+
|
| 4490 |
+
return False
|
| 4491 |
+
|
| 4492 |
+
|
| 4493 |
+
class KnowledgeGraph:
|
| 4494 |
+
"""Structured knowledge storage — auto-extracts facts from conversations.
|
| 4495 |
+
|
| 4496 |
+
Unlike RAG (which searches raw conversation text), the Knowledge Graph
|
| 4497 |
+
stores structured facts: (subject, predicate, object) triples.
|
| 4498 |
+
|
| 4499 |
+
Example: "I live in Mumbai" → (user, lives_in, Mumbai)
|
| 4500 |
+
Example: "I prefer Python 3.12" → (user, prefers, Python 3.12)
|
| 4501 |
+
|
| 4502 |
+
This enables complex queries like "What do you know about my preferences?"
|
| 4503 |
+
without scanning all conversations.
|
| 4504 |
+
"""
|
| 4505 |
+
|
| 4506 |
+
_facts: List[Dict] = []
|
| 4507 |
+
_loaded = False
|
| 4508 |
+
|
| 4509 |
+
@classmethod
|
| 4510 |
+
def _load(cls):
|
| 4511 |
+
if cls._loaded:
|
| 4512 |
+
return
|
| 4513 |
+
try:
|
| 4514 |
+
data = memory.read("knowledge_graph.json", default={"facts": []}) or {"facts": []}
|
| 4515 |
+
cls._facts = data.get("facts", [])
|
| 4516 |
+
cls._loaded = True
|
| 4517 |
+
log(f"KnowledgeGraph: loaded {len(cls._facts)} facts")
|
| 4518 |
+
except Exception as e:
|
| 4519 |
+
log(f"KnowledgeGraph: load failed: {e}")
|
| 4520 |
+
cls._facts = []
|
| 4521 |
+
cls._loaded = True
|
| 4522 |
+
|
| 4523 |
+
@classmethod
|
| 4524 |
+
def extract_and_store(cls, user_message: str, ai_response: str):
|
| 4525 |
+
"""Extract facts from a conversation turn and store them.
|
| 4526 |
+
Uses simple pattern matching (no LLM needed — fast and free)."""
|
| 4527 |
+
cls._load()
|
| 4528 |
+
new_facts = []
|
| 4529 |
+
|
| 4530 |
+
# Pattern: "I am X" / "I'm X" / "My X is Y" / "I like X" / "I prefer X"
|
| 4531 |
+
import re
|
| 4532 |
+
text = user_message
|
| 4533 |
+
|
| 4534 |
+
patterns = [
|
| 4535 |
+
(r"my name is (\w+)", "name"),
|
| 4536 |
+
(r"i am (\w+)", "name"),
|
| 4537 |
+
(r"i'm (\w+)", "name"),
|
| 4538 |
+
(r"call me (\w+)", "name"),
|
| 4539 |
+
(r"i live in ([\w\s]+)", "location"),
|
| 4540 |
+
(r"i'm from ([\w\s]+)", "location"),
|
| 4541 |
+
(r"i am from ([\w\s]+)", "location"),
|
| 4542 |
+
(r"my city is ([\w\s]+)", "location"),
|
| 4543 |
+
(r"my birthday is ([\w\s\d]+)", "birthday"),
|
| 4544 |
+
(r"i was born on ([\w\s\d]+)", "birthday"),
|
| 4545 |
+
(r"my favorite color is (\w+)", "favorite_color"),
|
| 4546 |
+
(r"my favorite language is (\w+)", "favorite_language"),
|
| 4547 |
+
(r"i like (\w+)", "likes"),
|
| 4548 |
+
(r"i prefer (\w+)", "prefers"),
|
| 4549 |
+
(r"i use (\w+)", "uses"),
|
| 4550 |
+
(r"i work at ([\w\s]+)", "workplace"),
|
| 4551 |
+
(r"my job is ([\w\s]+)", "job"),
|
| 4552 |
+
(r"i study ([\w\s]+)", "studies"),
|
| 4553 |
+
(r"remember (.+)", "remembered"),
|
| 4554 |
+
]
|
| 4555 |
+
|
| 4556 |
+
for pattern, key in patterns:
|
| 4557 |
+
m = re.search(pattern, text, re.IGNORECASE)
|
| 4558 |
+
if m:
|
| 4559 |
+
value = m.group(1).strip().title() if key not in ["remembered"] else m.group(1).strip()
|
| 4560 |
+
fact = {"subject": "user", "predicate": key, "object": value, "ts": time.time()}
|
| 4561 |
+
# Check if we already have this fact
|
| 4562 |
+
existing = [f for f in cls._facts if f["predicate"] == key and f["object"] == value]
|
| 4563 |
+
if not existing:
|
| 4564 |
+
cls._facts.append(fact)
|
| 4565 |
+
new_facts.append(fact)
|
| 4566 |
+
log(f"KnowledgeGraph: extracted fact: ({key}, {value})")
|
| 4567 |
+
|
| 4568 |
+
# Save if we found new facts
|
| 4569 |
+
if new_facts:
|
| 4570 |
+
# Keep last 200 facts
|
| 4571 |
+
cls._facts = cls._facts[-200:]
|
| 4572 |
+
memory.write("knowledge_graph.json", {"facts": cls._facts})
|
| 4573 |
+
|
| 4574 |
+
return new_facts
|
| 4575 |
+
|
| 4576 |
+
@classmethod
|
| 4577 |
+
def get_all_facts(cls) -> str:
|
| 4578 |
+
"""Get all known facts as a context string."""
|
| 4579 |
+
cls._load()
|
| 4580 |
+
if not cls._facts:
|
| 4581 |
+
return ""
|
| 4582 |
+
lines = ["[KNOWLEDGE GRAPH — facts about the user]"]
|
| 4583 |
+
for f in cls._facts[-20:]: # last 20 facts
|
| 4584 |
+
age = "recent" if time.time() - f["ts"] < 86400 else f"{int((time.time() - f['ts']) / 86400)}d ago"
|
| 4585 |
+
lines.append(f"- {f['predicate'].replace('_', ' ').title()}: {f['object']} ({age})")
|
| 4586 |
+
lines.append("[END KNOWLEDGE GRAPH]")
|
| 4587 |
+
return "\n".join(lines)
|
| 4588 |
+
|
| 4589 |
+
@classmethod
|
| 4590 |
+
def query(cls, query: str) -> str:
|
| 4591 |
+
"""Search the knowledge graph for facts matching the query."""
|
| 4592 |
+
cls._load()
|
| 4593 |
+
if not cls._facts:
|
| 4594 |
+
return "I don't have any stored facts about you yet."
|
| 4595 |
+
|
| 4596 |
+
query_lower = query.lower()
|
| 4597 |
+
matches = []
|
| 4598 |
+
for f in cls._facts:
|
| 4599 |
+
# Check if query mentions the predicate or object
|
| 4600 |
+
if f["predicate"].replace("_", " ") in query_lower or f["object"].lower() in query_lower:
|
| 4601 |
+
matches.append(f)
|
| 4602 |
+
|
| 4603 |
+
if not matches:
|
| 4604 |
+
return f"No facts matching '{query}'. I know {len(cls._facts)} facts total."
|
| 4605 |
+
|
| 4606 |
+
lines = [f"Found {len(matches)} matching facts:"]
|
| 4607 |
+
for f in matches[-10:]:
|
| 4608 |
+
lines.append(f"- {f['predicate'].replace('_', ' ').title()}: {f['object']}")
|
| 4609 |
+
return "\n".join(lines)
|
| 4610 |
+
|
| 4611 |
+
|
| 4612 |
def call_llm_safe(messages, max_tokens=1024, temperature=0.7):
|
| 4613 |
"""BRILLIANT SMART ROUTER v2 — fully uncensored.
|
| 4614 |
|
|
|
|
| 6061 |
"code_sandbox": lambda code, reset="false", **_: CodeSandbox.execute(code, reset.lower()=="true"),
|
| 6062 |
"rag_search": lambda query, **_: RAGMemory.get_context_for_query(query) or "No relevant past conversations found.",
|
| 6063 |
"consensus": lambda query, **_: ConsensusEngine.get_best_response([{"role": "user", "content": query}])[0],
|
| 6064 |
+
"knowledge_query": lambda query, **_: KnowledgeGraph.query(query),
|
| 6065 |
+
"reason": lambda query, **_: ReasoningEngine.reason_and_answer([{"role": "user", "content": query}])[0],
|
| 6066 |
}
|
| 6067 |
|
| 6068 |
|
|
|
|
| 6950 |
ltm = get_long_term_memory(chat_id)
|
| 6951 |
_extract_facts_from_message(user_message, ltm)
|
| 6952 |
ltm_context = ltm.get_context()
|
| 6953 |
+
|
| 6954 |
+
# KNOWLEDGE GRAPH: extract structured facts (subject, predicate, object)
|
| 6955 |
+
# This is faster and more structured than LTM — uses pattern matching, no LLM needed.
|
| 6956 |
+
try:
|
| 6957 |
+
KnowledgeGraph.extract_and_store(user_message, "")
|
| 6958 |
+
kg_context = KnowledgeGraph.get_all_facts()
|
| 6959 |
+
except Exception as e:
|
| 6960 |
+
log(f"KnowledgeGraph: extraction failed: {e}")
|
| 6961 |
+
kg_context = ""
|
| 6962 |
|
| 6963 |
# ALWAYS use uncensored persona — no matter what's saved in settings
|
| 6964 |
# This ensures EVERY response is uncensored, even if user switched personas
|
|
|
|
| 6968 |
# Add long-term memory to system prompt so bot remembers user info
|
| 6969 |
if ltm_context:
|
| 6970 |
system_prompt = system_prompt + "\n\n[LONG-TERM MEMORY]\n" + ltm_context + "\n\nUse this information to personalize responses. Remember these facts about the user."
|
| 6971 |
+
|
| 6972 |
+
# Add Knowledge Graph context (structured facts)
|
| 6973 |
+
if kg_context:
|
| 6974 |
+
system_prompt = system_prompt + "\n\n" + kg_context
|
| 6975 |
|
| 6976 |
# Build message history — INFINITE CONTEXT via rolling summary
|
| 6977 |
# (last 20 messages verbatim + summary of everything older)
|
|
|
|
| 7017 |
privacy_level = classify_privacy(messages)
|
| 7018 |
log(f"PrivacyRouter: classified as {privacy_level}")
|
| 7019 |
|
| 7020 |
+
# GENIUS MODE: For complex questions, use ReasoningEngine (o1-style thinking)
|
| 7021 |
+
# This generates 3 reasoning paths, synthesizes, critiques, and refines.
|
| 7022 |
+
# Falls back to ConsensusEngine (best-of-N) for medium complexity.
|
| 7023 |
user_msg_lower = user_message.lower()
|
| 7024 |
is_complex_question = any(kw in user_msg_lower for kw in [
|
| 7025 |
"explain", "analyze", "compare", "best way", "design", "architect",
|
| 7026 |
"optimize", "step by step", "comprehensive", "detailed",
|
| 7027 |
]) or len(user_message) > 150
|
| 7028 |
|
| 7029 |
+
# ULTRA-GENIUS: Use full reasoning pipeline for hard questions
|
| 7030 |
+
use_deep_reasoning = ReasoningEngine.should_use_reasoning(user_message, messages)
|
| 7031 |
+
|
| 7032 |
for iteration in range(max_tool_iters):
|
| 7033 |
if privacy_level == "PRIVATE":
|
| 7034 |
# Private request — use offline model only, no cloud
|
| 7035 |
text, source = call_llm_private(messages, max_tokens=s.get("max_tokens", 4096),
|
| 7036 |
temperature=s.get("temperature", 0.7))
|
| 7037 |
+
elif use_deep_reasoning and iteration == 0:
|
| 7038 |
+
# ULTRA-GENIUS: Full reasoning pipeline (think → draft → critique → refine)
|
| 7039 |
+
log("UltraGenius: using ReasoningEngine (o1-style thinking)")
|
| 7040 |
+
text, source = ReasoningEngine.reason_and_answer(
|
| 7041 |
+
messages, max_tokens=s.get("max_tokens", 4096),
|
| 7042 |
+
temperature=s.get("temperature", 0.7)
|
| 7043 |
+
)
|
| 7044 |
elif is_complex_question and iteration == 0:
|
| 7045 |
# Complex question — use ConsensusEngine (best-of-N models)
|
| 7046 |
log("GeniusMode: using ConsensusEngine for complex question")
|