Some checks failed
Architecture Lint / Linter Tests (pull_request) Successful in 28s
Smoke Test / smoke (pull_request) Failing after 23s
Validate Config / YAML Lint (pull_request) Failing after 11s
Validate Config / JSON Validate (pull_request) Successful in 13s
Validate Config / Python Syntax & Import Check (pull_request) Failing after 31s
Validate Config / Python Test Suite (pull_request) Has been skipped
Validate Config / Shell Script Lint (pull_request) Failing after 23s
Validate Config / Cron Syntax Check (pull_request) Successful in 5s
Validate Config / Deploy Script Dry Run (pull_request) Successful in 7s
Validate Config / Playbook Schema Validation (pull_request) Successful in 15s
Validate Training Data / validate (pull_request) Failing after 18s
PR Checklist / pr-checklist (pull_request) Failing after 3m57s
Architecture Lint / Lint Repository (pull_request) Failing after 15s
- Moved 3 actively-used custom agent modules to timmy-config/extensions/ - shield.py (crisis & jailbreak detection) - privacy_filter.py (PII stripping for remote API calls) - smart_model_routing.py (cheap vs strong model heuristic) - Updated deploy.sh to copy extensions/ to ~/.hermes/agent/ - Added comprehensive migration doc in docs/AGENT_EXTENSION_MIGRATION.md - Archived 16 dead/unused agent/*.py modules to agent/archive/ in hermes-agent This is SIDECAR-3 — restructure agent/* extensions as sidecar skills. Docs: Closes #339
50 lines
1.7 KiB
Python
50 lines
1.7 KiB
Python
"""Smart model routing — decide cheap vs strong model.
|
|
|
|
Reimplements agent/smart_model_routing.py as a timmy-config extension.
|
|
Original was a custom hermes-agent module.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import re
|
|
from typing import Any, Dict, Optional
|
|
|
|
_COMPLEX_KEYWORDS = {
|
|
"debug", "debugging", "implement", "implementation", "refactor", "patch",
|
|
"traceback", "stacktrace", "exception", "error", "analyze", "analysis",
|
|
"investigate", "architecture", "design", "compare", "benchmark", "optimize",
|
|
"optimise", "review", "terminal", "shell", "tool", "tools", "pytest",
|
|
"test", "tests", "plan", "planning", "delegate", "subagent", "cron",
|
|
"docker", "kubernetes",
|
|
}
|
|
|
|
_URL_RE = re.compile(r"https?://|www\.", re.IGNORECASE)
|
|
|
|
def _contains_complex_keyword(text: str) -> bool:
|
|
lowered = text.lower()
|
|
return any(word in lowered for word in _COMPLEX_KEYWORDS)
|
|
|
|
def _contains_url(text: str) -> bool:
|
|
return bool(_URL_RE.search(text))
|
|
|
|
def needs_strong_model(messages: list[Dict[str, Any]], threshold: float = 0.3) -> bool:
|
|
"""Return True if the request needs a strong (expensive) model."""
|
|
if not messages:
|
|
return False
|
|
text = messages[-1].get('content', '')
|
|
if not text:
|
|
return False
|
|
keyword_hits = sum(1 for kw in _COMPLEX_KEYWORDS if kw in text.lower())
|
|
total_keywords = len(_COMPLEX_KEYWORDS)
|
|
score = keyword_hits / total_keywords if total_keywords else 0.0
|
|
if score >= threshold:
|
|
return True
|
|
if _contains_url(text):
|
|
return True
|
|
return False
|
|
|
|
def should_use_cheap_model(messages: list[Dict[str, Any]], cheap_model: str, strong_model: str) -> bool:
|
|
"""Return True if the request can safely use the cheap model."""
|
|
return not needs_strong_model(messages)
|