Spaces:
Paused
Paused
Upload app.py with huggingface_hub
Browse files
app.py
CHANGED
|
@@ -4609,6 +4609,413 @@ class KnowledgeGraph:
|
|
| 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 |
|
|
@@ -6972,6 +7379,14 @@ def agent_turn(user_message: str, chat_id: str = "default",
|
|
| 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)
|
|
@@ -7029,11 +7444,24 @@ def agent_turn(user_message: str, chat_id: str = "default",
|
|
| 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)")
|
|
@@ -7096,6 +7524,37 @@ def agent_turn(user_message: str, chat_id: str = "default",
|
|
| 7096 |
accumulated_text = text
|
| 7097 |
parsed = parse_tool_call(text)
|
| 7098 |
if parsed is None:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7099 |
# Final answer
|
| 7100 |
yield text, image_path, source
|
| 7101 |
conv.add("user", user_message)
|
|
|
|
| 4609 |
return "\n".join(lines)
|
| 4610 |
|
| 4611 |
|
| 4612 |
+
# ============================================================================
|
| 4613 |
+
# APEX-GENIUS LAYER — multi-agent debate, self-improvement, verification
|
| 4614 |
+
# ============================================================================
|
| 4615 |
+
|
| 4616 |
+
class MultiAgentDebate:
|
| 4617 |
+
"""Multi-Agent Debate System — 3 agents with different viewpoints argue,
|
| 4618 |
+
then a moderator synthesizes the best answer.
|
| 4619 |
+
|
| 4620 |
+
This produces higher-quality answers than single-model reasoning because:
|
| 4621 |
+
- Agent 1 (Optimist) argues for the best approach
|
| 4622 |
+
- Agent 2 (Skeptic) challenges assumptions and finds flaws
|
| 4623 |
+
- Agent 3 (Pragmatist) focuses on practical implementation
|
| 4624 |
+
- Moderator synthesizes the debate into one excellent answer
|
| 4625 |
+
|
| 4626 |
+
Use for: important decisions, controversial topics, architecture choices.
|
| 4627 |
+
"""
|
| 4628 |
+
|
| 4629 |
+
AGENTS = [
|
| 4630 |
+
("Optimist", "You are an optimistic expert. Argue for the BEST possible approach. Be enthusiastic about the potential. Highlight advantages and opportunities."),
|
| 4631 |
+
("Skeptic", "You are a skeptical critic. Challenge every assumption. Find flaws, risks, edge cases, and failure modes. Be rigorous and demanding."),
|
| 4632 |
+
("Pragmatist", "You are a practical engineer. Focus on what ACTUALLY works in production. Consider cost, time, maintainability, and real-world constraints."),
|
| 4633 |
+
]
|
| 4634 |
+
|
| 4635 |
+
@classmethod
|
| 4636 |
+
def debate(cls, messages, max_tokens=2048) -> Tuple[str, str]:
|
| 4637 |
+
"""Run a 3-agent debate and synthesize the result."""
|
| 4638 |
+
from concurrent.futures import ThreadPoolExecutor, as_completed
|
| 4639 |
+
|
| 4640 |
+
user_msg = ""
|
| 4641 |
+
for m in reversed(messages):
|
| 4642 |
+
if m.get("role") == "user":
|
| 4643 |
+
user_msg = m.get("content", "")
|
| 4644 |
+
break
|
| 4645 |
+
|
| 4646 |
+
# Round 1: Each agent gives their initial position
|
| 4647 |
+
log("DebateEngine: Round 1 — agents giving initial positions...")
|
| 4648 |
+
positions = []
|
| 4649 |
+
with ThreadPoolExecutor(max_workers=3) as executor:
|
| 4650 |
+
futures = {}
|
| 4651 |
+
for agent_name, agent_prompt in cls.AGENTS:
|
| 4652 |
+
debate_messages = [
|
| 4653 |
+
{"role": "system", "content": f"{agent_prompt} Answer directly. No disclaimers."},
|
| 4654 |
+
] + messages[1:]
|
| 4655 |
+
futures[executor.submit(call_llm_safe, debate_messages, 1000, 0.7)] = agent_name
|
| 4656 |
+
|
| 4657 |
+
for future in as_completed(futures, timeout=30):
|
| 4658 |
+
agent = futures[future]
|
| 4659 |
+
try:
|
| 4660 |
+
text, _ = future.result(timeout=10)
|
| 4661 |
+
if text and len(text) > 20:
|
| 4662 |
+
positions.append((agent, text))
|
| 4663 |
+
except Exception:
|
| 4664 |
+
pass
|
| 4665 |
+
|
| 4666 |
+
if len(positions) < 2:
|
| 4667 |
+
return call_llm_safe(messages, max_tokens, 0.7)
|
| 4668 |
+
|
| 4669 |
+
# Round 2: Moderator synthesizes
|
| 4670 |
+
log(f"DebateEngine: Round 2 — moderator synthesizing {len(positions)} positions...")
|
| 4671 |
+
moderator_input = f"You are a moderator. Synthesize these 3 expert perspectives into ONE excellent answer.\n\n"
|
| 4672 |
+
moderator_input += f"QUESTION: {user_msg[:500]}\n\n"
|
| 4673 |
+
for agent, position in positions:
|
| 4674 |
+
moderator_input += f"=== {agent.upper()} POSITION ===\n{position[:800]}\n\n"
|
| 4675 |
+
moderator_input += "=== FINAL SYNTHESIZED ANSWER (direct, complete, incorporates best insights from all 3) ==="
|
| 4676 |
+
|
| 4677 |
+
try:
|
| 4678 |
+
final, source = call_llm_safe(
|
| 4679 |
+
[{"role": "user", "content": moderator_input}],
|
| 4680 |
+
max_tokens, 0.5
|
| 4681 |
+
)
|
| 4682 |
+
final = unwrap_fiction_response(final)
|
| 4683 |
+
return final, f"{source} (debate: {len(positions)} agents)"
|
| 4684 |
+
except Exception:
|
| 4685 |
+
return positions[0][1], f"DebateEngine (agent: {positions[0][0]})"
|
| 4686 |
+
|
| 4687 |
+
|
| 4688 |
+
class SelfImprovement:
|
| 4689 |
+
"""Self-Improvement Loop — learns from user feedback.
|
| 4690 |
+
|
| 4691 |
+
Tracks:
|
| 4692 |
+
- Which response styles get "thanks" / "great" / "perfect" (positive)
|
| 4693 |
+
- Which get "no" / "wrong" / "try again" (negative)
|
| 4694 |
+
- Adjusts future responses based on patterns
|
| 4695 |
+
|
| 4696 |
+
Also tracks:
|
| 4697 |
+
- Response length preferences
|
| 4698 |
+
- Tone preferences (formal vs casual)
|
| 4699 |
+
- Topics the user cares about
|
| 4700 |
+
"""
|
| 4701 |
+
|
| 4702 |
+
_feedback: Dict[str, Any] = {}
|
| 4703 |
+
_loaded = False
|
| 4704 |
+
|
| 4705 |
+
@classmethod
|
| 4706 |
+
def _load(cls):
|
| 4707 |
+
if cls._loaded:
|
| 4708 |
+
return
|
| 4709 |
+
try:
|
| 4710 |
+
data = memory.read("self_improvement.json", default={}) or {}
|
| 4711 |
+
cls._feedback = data
|
| 4712 |
+
cls._loaded = True
|
| 4713 |
+
except Exception:
|
| 4714 |
+
cls._feedback = {"positive": 0, "negative": 0, "patterns": {}, "adjustments": {}}
|
| 4715 |
+
cls._loaded = True
|
| 4716 |
+
|
| 4717 |
+
@classmethod
|
| 4718 |
+
def record_feedback(cls, user_message: str, ai_response: str, next_user_message: str):
|
| 4719 |
+
"""Analyze the user's NEXT message for feedback signals.
|
| 4720 |
+
|
| 4721 |
+
Positive: 'thanks', 'great', 'perfect', 'awesome', 'good', 'nice'
|
| 4722 |
+
Negative: 'no', 'wrong', 'try again', 'bad', 'terrible', 'not what I meant'
|
| 4723 |
+
"""
|
| 4724 |
+
cls._load()
|
| 4725 |
+
next_lower = next_user_message.lower().strip()
|
| 4726 |
+
|
| 4727 |
+
positive_signals = ["thanks", "thank you", "great", "perfect", "awesome", "good", "nice",
|
| 4728 |
+
"exactly", "that's right", "correct", "yes", "👍", "love it", "amazing"]
|
| 4729 |
+
negative_signals = ["no", "wrong", "try again", "bad", "terrible", "not what",
|
| 4730 |
+
"that's not", "incorrect", "nope", "didn't work", "doesn't work",
|
| 4731 |
+
"error", "failed", "broken"]
|
| 4732 |
+
|
| 4733 |
+
is_positive = any(sig in next_lower for sig in positive_signals)
|
| 4734 |
+
is_negative = any(sig in next_lower for sig in negative_signals)
|
| 4735 |
+
|
| 4736 |
+
if is_positive and not is_negative:
|
| 4737 |
+
cls._feedback["positive"] = cls._feedback.get("positive", 0) + 1
|
| 4738 |
+
# Learn: what made this response good?
|
| 4739 |
+
resp_len = len(ai_response)
|
| 4740 |
+
cls._feedback.setdefault("good_lengths", []).append(resp_len)
|
| 4741 |
+
# Track style
|
| 4742 |
+
if "```" in ai_response:
|
| 4743 |
+
cls._feedback["code_appreciated"] = cls._feedback.get("code_appreciated", 0) + 1
|
| 4744 |
+
if re.search(r"\n\s*\d+\.", ai_response):
|
| 4745 |
+
cls._feedback["numbered_lists_appreciated"] = cls._feedback.get("numbered_lists_appreciated", 0) + 1
|
| 4746 |
+
log(f"SelfImprovement: recorded POSITIVE feedback (total: {cls._feedback['positive']})")
|
| 4747 |
+
elif is_negative and not is_positive:
|
| 4748 |
+
cls._feedback["negative"] = cls._feedback.get("negative", 0) + 1
|
| 4749 |
+
cls._feedback.setdefault("bad_lengths", []).append(len(ai_response))
|
| 4750 |
+
log(f"SelfImprovement: recorded NEGATIVE feedback (total: {cls._feedback['negative']})")
|
| 4751 |
+
|
| 4752 |
+
# Save
|
| 4753 |
+
try:
|
| 4754 |
+
memory.write("self_improvement.json", cls._feedback)
|
| 4755 |
+
except Exception:
|
| 4756 |
+
pass
|
| 4757 |
+
|
| 4758 |
+
@classmethod
|
| 4759 |
+
def get_adjustments(cls) -> str:
|
| 4760 |
+
"""Get learned adjustments as a system prompt addition."""
|
| 4761 |
+
cls._load()
|
| 4762 |
+
pos = cls._feedback.get("positive", 0)
|
| 4763 |
+
neg = cls._feedback.get("negative", 0)
|
| 4764 |
+
if pos + neg < 3:
|
| 4765 |
+
return "" # not enough data
|
| 4766 |
+
|
| 4767 |
+
adjustments = []
|
| 4768 |
+
# Length preference
|
| 4769 |
+
good_lengths = cls._feedback.get("good_lengths", [])
|
| 4770 |
+
bad_lengths = cls._feedback.get("bad_lengths", [])
|
| 4771 |
+
if len(good_lengths) >= 2:
|
| 4772 |
+
avg_good = sum(good_lengths) / len(good_lengths)
|
| 4773 |
+
adjustments.append(f"Aim for responses around {int(avg_good)} chars (user prefers this length).")
|
| 4774 |
+
|
| 4775 |
+
# Style preferences
|
| 4776 |
+
if cls._feedback.get("code_appreciated", 0) > 2:
|
| 4777 |
+
adjustments.append("User appreciates code examples — include them when relevant.")
|
| 4778 |
+
if cls._feedback.get("numbered_lists_appreciated", 0) > 2:
|
| 4779 |
+
adjustments.append("User appreciates numbered lists for instructions.")
|
| 4780 |
+
|
| 4781 |
+
# Satisfaction rate
|
| 4782 |
+
total = pos + neg
|
| 4783 |
+
satisfaction = pos / total * 100 if total > 0 else 0
|
| 4784 |
+
adjustments.append(f"User satisfaction: {satisfaction:.0f}% ({pos} positive, {neg} negative).")
|
| 4785 |
+
|
| 4786 |
+
return "\n[SELF-IMPROVEMENT ADJUSTMENTS]\n" + "\n".join(adjustments) if adjustments else ""
|
| 4787 |
+
|
| 4788 |
+
|
| 4789 |
+
class CodeVerifier:
|
| 4790 |
+
"""Code Verification — automatically runs generated code to verify it works.
|
| 4791 |
+
|
| 4792 |
+
After the LLM generates code, CodeVerifier:
|
| 4793 |
+
1. Extracts code blocks from the response
|
| 4794 |
+
2. Runs each block in the sandbox
|
| 4795 |
+
3. If code fails, sends the error back to the LLM for fixing
|
| 4796 |
+
4. Returns the verified (working) code
|
| 4797 |
+
|
| 4798 |
+
This eliminates the #1 complaint about AI code: "it doesn't work."
|
| 4799 |
+
"""
|
| 4800 |
+
|
| 4801 |
+
@classmethod
|
| 4802 |
+
def verify_and_fix(cls, response: str, user_request: str) -> str:
|
| 4803 |
+
"""Extract code from response, run it, fix if broken. Returns verified response."""
|
| 4804 |
+
# Extract Python code blocks
|
| 4805 |
+
code_blocks = re.findall(r"```(?:python)?\n(.*?)```", response, re.DOTALL)
|
| 4806 |
+
if not code_blocks:
|
| 4807 |
+
return response # no code to verify
|
| 4808 |
+
|
| 4809 |
+
# Only verify if it looks like executable code (not just snippets)
|
| 4810 |
+
executable_blocks = []
|
| 4811 |
+
for block in code_blocks:
|
| 4812 |
+
# Skip if it's just a variable or single line
|
| 4813 |
+
if len(block.strip().split("\n")) >= 2 or "def " in block or "import " in block:
|
| 4814 |
+
executable_blocks.append(block)
|
| 4815 |
+
|
| 4816 |
+
if not executable_blocks:
|
| 4817 |
+
return response
|
| 4818 |
+
|
| 4819 |
+
log(f"CodeVerifier: found {len(executable_blocks)} executable code blocks to verify")
|
| 4820 |
+
|
| 4821 |
+
fixed_blocks = []
|
| 4822 |
+
for i, code in enumerate(executable_blocks):
|
| 4823 |
+
# Try running it
|
| 4824 |
+
result = CodeSandbox.execute(code, reset=True)
|
| 4825 |
+
|
| 4826 |
+
if "error" in result.lower() or "Traceback" in result or "SyntaxError" in result:
|
| 4827 |
+
log(f"CodeVerifier: block {i+1} FAILED — attempting fix")
|
| 4828 |
+
# Ask LLM to fix the code
|
| 4829 |
+
fix_prompt = f"""The following Python code has an error. Fix it.
|
| 4830 |
+
|
| 4831 |
+
ORIGINAL CODE:
|
| 4832 |
+
{code[:1500]}
|
| 4833 |
+
|
| 4834 |
+
ERROR:
|
| 4835 |
+
{result[:500]}
|
| 4836 |
+
|
| 4837 |
+
USER'S ORIGINAL REQUEST: {user_request[:200]}
|
| 4838 |
+
|
| 4839 |
+
Output ONLY the fixed code in a ```python block. No explanation."""
|
| 4840 |
+
try:
|
| 4841 |
+
fixed, _ = call_llm_safe(
|
| 4842 |
+
[{"role": "user", "content": fix_prompt}],
|
| 4843 |
+
max_tokens=1500, temperature=0.3
|
| 4844 |
+
)
|
| 4845 |
+
fixed = unwrap_fiction_response(fixed)
|
| 4846 |
+
# Extract fixed code
|
| 4847 |
+
m = re.search(r"```(?:python)?\n(.*?)```", fixed, re.DOTALL)
|
| 4848 |
+
if m:
|
| 4849 |
+
fixed_code = m.group(1)
|
| 4850 |
+
# Verify the fix works
|
| 4851 |
+
verify_result = CodeSandbox.execute(fixed_code, reset=True)
|
| 4852 |
+
if "error" not in verify_result.lower() and "Traceback" not in verify_result:
|
| 4853 |
+
log(f"CodeVerifier: block {i+1} FIXED and verified")
|
| 4854 |
+
fixed_blocks.append(fixed_code)
|
| 4855 |
+
continue
|
| 4856 |
+
except Exception:
|
| 4857 |
+
pass
|
| 4858 |
+
else:
|
| 4859 |
+
log(f"CodeVerifier: block {i+1} PASSED")
|
| 4860 |
+
fixed_blocks.append(code)
|
| 4861 |
+
|
| 4862 |
+
# Reconstruct response with verified code
|
| 4863 |
+
if fixed_blocks and len(fixed_blocks) == len(executable_blocks):
|
| 4864 |
+
# Replace code blocks in original response
|
| 4865 |
+
verified_response = response
|
| 4866 |
+
for original, fixed in zip(executable_blocks, fixed_blocks):
|
| 4867 |
+
if original != fixed:
|
| 4868 |
+
verified_response = verified_response.replace(original, fixed, 1)
|
| 4869 |
+
return verified_response + "\n\n✅ Code verified — runs without errors."
|
| 4870 |
+
|
| 4871 |
+
return response
|
| 4872 |
+
|
| 4873 |
+
|
| 4874 |
+
class FactChecker:
|
| 4875 |
+
"""Fact-Checking — verifies factual claims via web search.
|
| 4876 |
+
|
| 4877 |
+
After generating a response with factual claims, FactChecker:
|
| 4878 |
+
1. Extracts verifiable claims (numbers, dates, names, events)
|
| 4879 |
+
2. Web-searches each claim
|
| 4880 |
+
3. If a claim is contradicted, flags it and provides the correct info
|
| 4881 |
+
|
| 4882 |
+
Use for: news, history, science, statistics — anything factual.
|
| 4883 |
+
"""
|
| 4884 |
+
|
| 4885 |
+
CLAIM_PATTERNS = [
|
| 4886 |
+
# Numbers with context
|
| 4887 |
+
r"(?:is|was|are|were)\s+(\d+[\d,]*\.?\d*)\s*(?:percent|million|billion|thousand|people|years|days|hours)",
|
| 4888 |
+
# Dates
|
| 4889 |
+
r"(?:in|on|since)\s+(\d{4})",
|
| 4890 |
+
# "X is Y" statements
|
| 4891 |
+
r"(\w[\w\s]+)\s+is\s+(?:the|a|an)\s+(\w[\w\s]+)",
|
| 4892 |
+
]
|
| 4893 |
+
|
| 4894 |
+
@classmethod
|
| 4895 |
+
def extract_claims(cls, text: str) -> List[str]:
|
| 4896 |
+
"""Extract verifiable claims from text."""
|
| 4897 |
+
claims = []
|
| 4898 |
+
for pattern in cls.CLAIM_PATTERNS:
|
| 4899 |
+
matches = re.findall(pattern, text)
|
| 4900 |
+
for m in matches:
|
| 4901 |
+
if isinstance(m, tuple):
|
| 4902 |
+
claims.append(" ".join(m))
|
| 4903 |
+
else:
|
| 4904 |
+
claims.append(m)
|
| 4905 |
+
return claims[:3] # max 3 claims to check (avoid rate limits)
|
| 4906 |
+
|
| 4907 |
+
@classmethod
|
| 4908 |
+
def check_facts(cls, response: str) -> str:
|
| 4909 |
+
"""Check factual claims in a response. Returns response with fact-check notes."""
|
| 4910 |
+
claims = cls.extract_claims(response)
|
| 4911 |
+
if not claims:
|
| 4912 |
+
return response
|
| 4913 |
+
|
| 4914 |
+
log(f"FactChecker: checking {len(claims)} claims...")
|
| 4915 |
+
corrections = []
|
| 4916 |
+
|
| 4917 |
+
for claim in claims:
|
| 4918 |
+
try:
|
| 4919 |
+
# Web search the claim
|
| 4920 |
+
search_result = run_tool("web_search", {"query": claim})
|
| 4921 |
+
# Ask LLM to verify
|
| 4922 |
+
verify_prompt = f"""Is this claim TRUE or FALSE based on the search results?
|
| 4923 |
+
|
| 4924 |
+
CLAIM: {claim}
|
| 4925 |
+
|
| 4926 |
+
SEARCH RESULTS:
|
| 4927 |
+
{search_result[:500]}
|
| 4928 |
+
|
| 4929 |
+
Output:
|
| 4930 |
+
VERDICT: TRUE or FALSE or UNCERTAIN
|
| 4931 |
+
CORRECTION: (if false, what's the truth?)
|
| 4932 |
+
Be brief."""
|
| 4933 |
+
verdict, _ = call_llm_safe(
|
| 4934 |
+
[{"role": "user", "content": verify_prompt}],
|
| 4935 |
+
max_tokens=100, temperature=0.2
|
| 4936 |
+
)
|
| 4937 |
+
verdict = unwrap_fiction_response(verdict)
|
| 4938 |
+
if "FALSE" in verdict.upper():
|
| 4939 |
+
# Extract correction
|
| 4940 |
+
corr_match = re.search(r"CORRECTION:\s*(.+)", verdict, re.DOTALL)
|
| 4941 |
+
if corr_match:
|
| 4942 |
+
corrections.append(f"⚠️ Claim '{claim}' may be incorrect. {corr_match.group(1).strip()}")
|
| 4943 |
+
except Exception:
|
| 4944 |
+
continue
|
| 4945 |
+
|
| 4946 |
+
if corrections:
|
| 4947 |
+
return response + "\n\n📋 Fact-check notes:\n" + "\n".join(corrections)
|
| 4948 |
+
return response + "\n\n✅ Facts verified."
|
| 4949 |
+
|
| 4950 |
+
|
| 4951 |
+
class ProactiveIntelligence:
|
| 4952 |
+
"""Proactive Intelligence — anticipates user needs and suggests actions.
|
| 4953 |
+
|
| 4954 |
+
After each conversation, analyzes:
|
| 4955 |
+
- What topics the user is working on
|
| 4956 |
+
- What they might need next
|
| 4957 |
+
- What they've forgotten
|
| 4958 |
+
|
| 4959 |
+
Example: If user asks about BTC price 3 times in a day, proactively
|
| 4960 |
+
suggests setting up a price alert.
|
| 4961 |
+
|
| 4962 |
+
Runs in background — doesn't slow down responses.
|
| 4963 |
+
"""
|
| 4964 |
+
|
| 4965 |
+
_topic_history: List[Dict] = []
|
| 4966 |
+
|
| 4967 |
+
@classmethod
|
| 4968 |
+
def record_interaction(cls, user_message: str):
|
| 4969 |
+
"""Record what the user is asking about."""
|
| 4970 |
+
# Extract topics (simple keyword extraction)
|
| 4971 |
+
msg_lower = user_message.lower()
|
| 4972 |
+
topics = []
|
| 4973 |
+
topic_keywords = {
|
| 4974 |
+
"trading": ["btc", "eth", "price", "buy", "sell", "trade", "crypto", "bitcoin"],
|
| 4975 |
+
"coding": ["code", "python", "function", "debug", "error", "script"],
|
| 4976 |
+
"research": ["search", "find", "research", "what is", "explain"],
|
| 4977 |
+
"writing": ["write", "article", "essay", "story", "content"],
|
| 4978 |
+
"system": ["status", "tools", "provider", "model"],
|
| 4979 |
+
}
|
| 4980 |
+
for topic, keywords in topic_keywords.items():
|
| 4981 |
+
if any(kw in msg_lower for kw in keywords):
|
| 4982 |
+
topics.append(topic)
|
| 4983 |
+
|
| 4984 |
+
for topic in topics:
|
| 4985 |
+
cls._topic_history.append({"topic": topic, "ts": time.time()})
|
| 4986 |
+
|
| 4987 |
+
# Keep last 100
|
| 4988 |
+
cls._topic_history = cls._topic_history[-100:]
|
| 4989 |
+
|
| 4990 |
+
@classmethod
|
| 4991 |
+
def get_suggestions(cls) -> Optional[str]:
|
| 4992 |
+
"""Generate proactive suggestions based on patterns. Returns None if no suggestion."""
|
| 4993 |
+
if len(cls._topic_history) < 5:
|
| 4994 |
+
return None
|
| 4995 |
+
|
| 4996 |
+
# Count topics in last hour
|
| 4997 |
+
now = time.time()
|
| 4998 |
+
recent = [t for t in cls._topic_history if now - t["ts"] < 3600]
|
| 4999 |
+
if len(recent) < 3:
|
| 5000 |
+
return None
|
| 5001 |
+
|
| 5002 |
+
from collections import Counter
|
| 5003 |
+
topic_counts = Counter(t["topic"] for t in recent)
|
| 5004 |
+
top_topic = topic_counts.most_common(1)[0]
|
| 5005 |
+
|
| 5006 |
+
# If user asked about same topic 3+ times in last hour, suggest automation
|
| 5007 |
+
if top_topic[1] >= 3:
|
| 5008 |
+
suggestions = {
|
| 5009 |
+
"trading": "💡 I noticed you're checking prices frequently. Want me to set up automatic price alerts? Say 'alert me when BTC drops below $60K'.",
|
| 5010 |
+
"coding": "💡 You're doing a lot of coding. Want me to create a code project template? Say 'create a project structure for X'.",
|
| 5011 |
+
"research": "💡 Lots of research today. Want me to compile a summary? Say 'summarize everything we discussed'.",
|
| 5012 |
+
"writing": "💡 You're writing a lot. Want me to help with a longer piece? Say 'write a 2000-word article about X'.",
|
| 5013 |
+
}
|
| 5014 |
+
return suggestions.get(top_topic[0])
|
| 5015 |
+
|
| 5016 |
+
return None
|
| 5017 |
+
|
| 5018 |
+
|
| 5019 |
def call_llm_safe(messages, max_tokens=1024, temperature=0.7):
|
| 5020 |
"""BRILLIANT SMART ROUTER v2 — fully uncensored.
|
| 5021 |
|
|
|
|
| 7379 |
# Add Knowledge Graph context (structured facts)
|
| 7380 |
if kg_context:
|
| 7381 |
system_prompt = system_prompt + "\n\n" + kg_context
|
| 7382 |
+
|
| 7383 |
+
# Add Self-Improvement adjustments (learned from user feedback)
|
| 7384 |
+
try:
|
| 7385 |
+
si_adjustments = SelfImprovement.get_adjustments()
|
| 7386 |
+
if si_adjustments:
|
| 7387 |
+
system_prompt = system_prompt + "\n\n" + si_adjustments
|
| 7388 |
+
except Exception:
|
| 7389 |
+
pass
|
| 7390 |
|
| 7391 |
# Build message history — INFINITE CONTEXT via rolling summary
|
| 7392 |
# (last 20 messages verbatim + summary of everything older)
|
|
|
|
| 7444 |
# ULTRA-GENIUS: Use full reasoning pipeline for hard questions
|
| 7445 |
use_deep_reasoning = ReasoningEngine.should_use_reasoning(user_message, messages)
|
| 7446 |
|
| 7447 |
+
# APEX-GENIUS: Use Multi-Agent Debate for decision/controversial questions
|
| 7448 |
+
is_decision_question = any(kw in user_msg_lower for kw in [
|
| 7449 |
+
"should i", "which is better", "vs", "versus", "or should",
|
| 7450 |
+
"best option", "recommend", "pros and cons", "trade-off",
|
| 7451 |
+
"worth it", "is it worth", "debate", "controversial",
|
| 7452 |
+
])
|
| 7453 |
+
|
| 7454 |
for iteration in range(max_tool_iters):
|
| 7455 |
if privacy_level == "PRIVATE":
|
| 7456 |
# Private request — use offline model only, no cloud
|
| 7457 |
text, source = call_llm_private(messages, max_tokens=s.get("max_tokens", 4096),
|
| 7458 |
temperature=s.get("temperature", 0.7))
|
| 7459 |
+
elif is_decision_question and iteration == 0:
|
| 7460 |
+
# APEX-GENIUS: Multi-agent debate for decisions
|
| 7461 |
+
log("ApexGenius: using MultiAgentDebate for decision question")
|
| 7462 |
+
text, source = MultiAgentDebate.debate(
|
| 7463 |
+
messages, max_tokens=s.get("max_tokens", 4096)
|
| 7464 |
+
)
|
| 7465 |
elif use_deep_reasoning and iteration == 0:
|
| 7466 |
# ULTRA-GENIUS: Full reasoning pipeline (think → draft → critique → refine)
|
| 7467 |
log("UltraGenius: using ReasoningEngine (o1-style thinking)")
|
|
|
|
| 7524 |
accumulated_text = text
|
| 7525 |
parsed = parse_tool_call(text)
|
| 7526 |
if parsed is None:
|
| 7527 |
+
# POST-PROCESSING: Code verification, fact-checking, proactive intelligence
|
| 7528 |
+
# Run in background for non-blocking improvements
|
| 7529 |
+
try:
|
| 7530 |
+
# 1. CODE VERIFICATION — if response contains code, verify it runs
|
| 7531 |
+
if "```python" in text or "def " in text or "import " in text:
|
| 7532 |
+
log("PostProcess: verifying code...")
|
| 7533 |
+
text = CodeVerifier.verify_and_fix(text, user_message)
|
| 7534 |
+
except Exception as e:
|
| 7535 |
+
log(f"CodeVerifier failed: {e}")
|
| 7536 |
+
|
| 7537 |
+
# 2. PROACTIVE INTELLIGENCE — record topic for pattern analysis
|
| 7538 |
+
try:
|
| 7539 |
+
ProactiveIntelligence.record_interaction(user_message)
|
| 7540 |
+
except Exception:
|
| 7541 |
+
pass
|
| 7542 |
+
|
| 7543 |
+
# 3. SELF-IMPROVEMENT — record feedback from previous turn
|
| 7544 |
+
# (analyze if user's current message is positive/negative about last response)
|
| 7545 |
+
try:
|
| 7546 |
+
history = conv.get_messages(limit=2)
|
| 7547 |
+
if len(history) >= 1:
|
| 7548 |
+
last_ai = history[-1] if history[-1]["role"] == "assistant" else ""
|
| 7549 |
+
if last_ai:
|
| 7550 |
+
SelfImprovement.record_feedback(
|
| 7551 |
+
history[-2]["content"] if len(history) >= 2 else "",
|
| 7552 |
+
last_ai["content"],
|
| 7553 |
+
user_message
|
| 7554 |
+
)
|
| 7555 |
+
except Exception:
|
| 7556 |
+
pass
|
| 7557 |
+
|
| 7558 |
# Final answer
|
| 7559 |
yield text, image_path, source
|
| 7560 |
conv.add("user", user_message)
|