feat: Jon Snow Phase 2 — FastAPI orchestrator with LiteLLM brain
OpenAI-compatible API at :8900. Intent classifier routes status queries to FAST_MODEL (Ollama), task submissions to Plane, planning to SMART_MODEL. Reads agent-os logs for status context. Phase 3: approval gate + execution. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
AGENT_NAMES = {"hodor", "bran", "varys", "sam", "raven", "qyburn", "citadel", "jon"}
|
||||
|
||||
STATUS_PHRASES = {
|
||||
"status", "health", "running", "last run", "what did", "when did",
|
||||
"show me", "how is", "is it", "is running", "did it run", "output",
|
||||
"summary", "report", "check", "monitor", "alive", "up",
|
||||
}
|
||||
|
||||
TASK_PHRASES = {
|
||||
"create task", "add task", "add issue", "create issue", "log task",
|
||||
"log this", "new task", "new issue", "add to plane", "add to backlog",
|
||||
"plan", "schedule", "remind", "track", "todo", "to do",
|
||||
}
|
||||
|
||||
RESEARCH_PHRASES = {
|
||||
"research", "search", "find out", "look up", "what is", "explain",
|
||||
"how does", "documentation", "docs",
|
||||
}
|
||||
|
||||
|
||||
def classify_intent(message: str) -> str:
|
||||
msg = message.lower()
|
||||
words = set(msg.split())
|
||||
|
||||
# Agent name + query word → status
|
||||
if words & AGENT_NAMES:
|
||||
if any(p in msg for p in STATUS_PHRASES) or words & {"status", "check", "output", "run"}:
|
||||
return "status"
|
||||
|
||||
# Explicit task phrases → task
|
||||
if any(p in msg for p in TASK_PHRASES):
|
||||
return "task"
|
||||
|
||||
# Generic status signal words
|
||||
if any(p in msg for p in STATUS_PHRASES) and words & AGENT_NAMES:
|
||||
return "status"
|
||||
|
||||
# Status if asking purely about the agent ecosystem
|
||||
if words & AGENT_NAMES and not any(p in msg for p in {"build", "implement", "create", "make"}):
|
||||
return "status"
|
||||
|
||||
# Research intent → route to smart model
|
||||
if any(p in msg for p in RESEARCH_PHRASES):
|
||||
return "planning"
|
||||
|
||||
return "planning"
|
||||
|
||||
|
||||
def extract_agent_name(message: str) -> str | None:
|
||||
msg = message.lower()
|
||||
for name in AGENT_NAMES:
|
||||
if name in msg:
|
||||
return name
|
||||
return None
|
||||
|
||||
|
||||
PROJECT_KEYWORDS = {
|
||||
"bni": "BNI Scheduler",
|
||||
"scheduler": "BNI Scheduler",
|
||||
"monitor": "Monitoring",
|
||||
"monitoring": "Monitoring",
|
||||
"grafana": "Monitoring",
|
||||
"maester": "Maester Reports",
|
||||
"report": "Maester Reports",
|
||||
"csf": "Maester Reports",
|
||||
"nist": "Maester Reports",
|
||||
"portal": "Nexum Portal",
|
||||
"authelia": "Nexum Portal",
|
||||
"nexum": "Nexum Portal",
|
||||
}
|
||||
|
||||
|
||||
def extract_project_name(message: str) -> str | None:
|
||||
msg = message.lower()
|
||||
for kw, project in PROJECT_KEYWORDS.items():
|
||||
if kw in msg:
|
||||
return project
|
||||
return None
|
||||
Reference in New Issue
Block a user