Some checks failed
- Integrate GPU scoring inline into reasoning/multi_path.py (auto-uses GPU when available) - Integrate GPU deduplication into multi_agent/consensus_engine.py - Add semantic_search() method to memory/semantic_graph.py with GPU acceleration - Integrate GPU training into self_improvement/training.py AutoTrainer - Fix all 758 ruff lint issues (whitespace, import sorting, unused imports, ambiguous vars, undefined names) - Fix all 40 mypy type errors across the codebase (no-any-return, union-attr, arg-type, etc.) - Fix deprecated ruff config keys (select/ignore -> [tool.ruff.lint]) - Add .dockerignore to exclude .venv/, tests/, docs/ from Docker builds - Add type hints and docstrings to verification/outcome.py - Fix E402 import ordering in witness_agent.py - Fix F821 undefined names in vector_pgvector.py and native.py - Fix E741 ambiguous variable names in reflective.py and recommender.py All 276 tests pass. 0 ruff errors. 0 mypy errors. Co-Authored-By: Nakamoto, S <defi@defi-oracle.io>
93 lines
3.0 KiB
Python
93 lines
3.0 KiB
Python
"""Interaction commands and user intent for Dvādaśa UX."""
|
|
|
|
import re
|
|
from enum import Enum
|
|
|
|
from pydantic import BaseModel, Field
|
|
|
|
from fusionagi.schemas.head import HeadId
|
|
|
|
|
|
class UserIntent(str, Enum):
|
|
"""User intent derived from commands or natural input."""
|
|
|
|
NORMAL = "normal"
|
|
HEAD_STRATEGY = "head_strategy"
|
|
SHOW_DISSENT = "show_dissent"
|
|
RERUN_RISK = "rerun_risk"
|
|
EXPLAIN_REASONING = "explain_reasoning"
|
|
SOURCES = "sources"
|
|
|
|
|
|
# Command patterns: /command [arg] or /command \n prompt
|
|
_COMMAND_PATTERNS: list[tuple[re.Pattern[str], UserIntent]] = [
|
|
(re.compile(r"^/head\s+(\w+)(?:\s+(.+))?\s*$", re.I | re.DOTALL), UserIntent.HEAD_STRATEGY),
|
|
(re.compile(r"^/show\s+dissent(?:\s+(.+))?\s*$", re.I | re.DOTALL), UserIntent.SHOW_DISSENT),
|
|
(re.compile(r"^/rerun\s+risk(?:\s+(.+))?\s*$", re.I | re.DOTALL), UserIntent.RERUN_RISK),
|
|
(re.compile(r"^/explain\s+reasoning(?:\s+(.+))?\s*$", re.I | re.DOTALL), UserIntent.EXPLAIN_REASONING),
|
|
(re.compile(r"^/sources(?:\s+(.+))?\s*$", re.I | re.DOTALL), UserIntent.SOURCES),
|
|
]
|
|
|
|
|
|
class ParsedCommand(BaseModel):
|
|
"""Parsed user command with intent and optional arguments."""
|
|
|
|
intent: UserIntent = Field(..., description="Detected intent")
|
|
head_id: HeadId | None = Field(default=None, description="For HEAD_STRATEGY: which head")
|
|
raw_input: str = Field(default="", description="Original user input")
|
|
cleaned_prompt: str = Field(default="", description="Prompt with command stripped if applicable")
|
|
|
|
|
|
def parse_user_input(text: str) -> ParsedCommand:
|
|
"""
|
|
Parse user input to detect commands and extract intent.
|
|
|
|
Examples:
|
|
"/head strategy" -> HEAD_STRATEGY, head_id=STRATEGY
|
|
"/show dissent" -> SHOW_DISSENT
|
|
"What is X?" -> NORMAL, cleaned_prompt="What is X?"
|
|
"""
|
|
stripped = (text or "").strip()
|
|
if not stripped:
|
|
return ParsedCommand(
|
|
intent=UserIntent.NORMAL,
|
|
raw_input=stripped,
|
|
cleaned_prompt=stripped,
|
|
)
|
|
|
|
for pattern, intent in _COMMAND_PATTERNS:
|
|
match = pattern.match(stripped)
|
|
if match:
|
|
head_id = None
|
|
cleaned = ""
|
|
if intent == UserIntent.HEAD_STRATEGY:
|
|
arg = (match.group(1) or "").lower()
|
|
rest = match.group(2) if match.lastindex and match.lastindex >= 2 else None
|
|
cleaned = (rest or "").strip()
|
|
try:
|
|
head_id = HeadId(arg)
|
|
except ValueError:
|
|
head_id = None
|
|
else:
|
|
rest = match.group(1) if match.lastindex and match.lastindex >= 1 else None
|
|
cleaned = (rest or "").strip()
|
|
return ParsedCommand(
|
|
intent=intent,
|
|
head_id=head_id,
|
|
raw_input=stripped,
|
|
cleaned_prompt=cleaned,
|
|
)
|
|
|
|
return ParsedCommand(
|
|
intent=UserIntent.NORMAL,
|
|
raw_input=stripped,
|
|
cleaned_prompt=stripped,
|
|
)
|
|
|
|
|
|
__all__ = [
|
|
"UserIntent",
|
|
"ParsedCommand",
|
|
"parse_user_input",
|
|
]
|