Pulled from /opt/teleo-eval/telegram/ on VPS. Includes: - bot.py (92K), kb_retrieval.py, kb_tools.py (agentic retrieval) - retrieval.py (RRF merge, query decomposition, entity traversal) - response.py (system prompt builder, response parser) - agent_config.py, agent_runner.py (multi-agent template unit support) - approval_stages.py, approvals.py, digest.py (approval workflow) - eval_checks.py, eval.py (response quality checks) - output_gate.py, x_publisher.py, x_client.py, x_search.py (X pipeline) - market_data.py, worktree_lock.py (utilities) - rio.yaml, theseus.yaml (agent configs) These files were deployed to VPS but never committed to the repo. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
118 lines
3.6 KiB
Python
118 lines
3.6 KiB
Python
#!/usr/bin/env python3
|
|
"""Agent runner — entry point for running a Teleo Telegram agent.
|
|
|
|
Usage:
|
|
python3 agent_runner.py --agent rio
|
|
python3 agent_runner.py --agent theseus
|
|
python3 agent_runner.py --agent rio --validate
|
|
|
|
Systemd template unit: teleo-agent@.service
|
|
ExecStart=/usr/bin/python3 /opt/teleo-eval/telegram/agent_runner.py --agent %i
|
|
|
|
Each agent runs as a separate process for fault isolation.
|
|
Template unit means `systemctl start teleo-agent@rio` and
|
|
`systemctl start teleo-agent@theseus` are independent services
|
|
with separate log streams (journalctl -u teleo-agent@rio).
|
|
|
|
Epimetheus owns this module.
|
|
"""
|
|
|
|
import argparse
|
|
import sys
|
|
import os
|
|
from pathlib import Path
|
|
|
|
AGENTS_DIR = Path(__file__).parent / "agents"
|
|
|
|
|
|
def find_config(agent_name: str) -> Path:
|
|
"""Resolve agent name to config file path."""
|
|
config_path = AGENTS_DIR / f"{agent_name}.yaml"
|
|
if not config_path.exists():
|
|
print(f"ERROR: Config not found: {config_path}", file=sys.stderr)
|
|
print(f"Available agents: {', '.join(p.stem for p in AGENTS_DIR.glob('*.yaml'))}", file=sys.stderr)
|
|
sys.exit(1)
|
|
return config_path
|
|
|
|
|
|
def validate(agent_name: str) -> bool:
|
|
"""Validate agent config and runtime dependencies. Returns True if valid."""
|
|
config_path = find_config(agent_name)
|
|
# Add telegram dir to path for agent_config import
|
|
sys.path.insert(0, str(Path(__file__).parent))
|
|
from agent_config import validate_agent_config
|
|
try:
|
|
warnings = validate_agent_config(str(config_path))
|
|
if warnings:
|
|
for w in warnings:
|
|
print(f" WARNING: {w}", file=sys.stderr)
|
|
print(f" Config OK: {agent_name} ({config_path})")
|
|
return True
|
|
except ValueError as e:
|
|
print(f" FAILED: {e}", file=sys.stderr)
|
|
return False
|
|
|
|
|
|
def run(agent_name: str):
|
|
"""Run the agent bot process."""
|
|
config_path = find_config(agent_name)
|
|
|
|
# Validate before running (fail fast)
|
|
if not validate(agent_name):
|
|
sys.exit(1)
|
|
|
|
# Set sys.argv so bot.py's main() picks up the config
|
|
sys.argv = ["bot.py", "--config", str(config_path)]
|
|
|
|
# Import and run bot — this blocks until the bot exits
|
|
sys.path.insert(0, str(Path(__file__).parent))
|
|
import bot
|
|
bot.main()
|
|
|
|
|
|
def list_agents():
|
|
"""List available agent configs."""
|
|
configs = sorted(AGENTS_DIR.glob("*.yaml"))
|
|
if not configs:
|
|
print("No agent configs found in", AGENTS_DIR)
|
|
return
|
|
print("Available agents:")
|
|
for p in configs:
|
|
# Quick parse to get agent name from YAML
|
|
name = p.stem
|
|
try:
|
|
import yaml
|
|
with open(p) as f:
|
|
data = yaml.safe_load(f)
|
|
domain = data.get("domain", "unknown")
|
|
print(f" {name:12s} domain={domain}")
|
|
except Exception:
|
|
print(f" {name:12s} (config parse error)")
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(
|
|
description="Run a Teleo Telegram agent",
|
|
epilog="Systemd: teleo-agent@.service uses --agent %%i"
|
|
)
|
|
parser.add_argument("--agent", help="Agent name (e.g., rio, theseus)")
|
|
parser.add_argument("--validate", action="store_true", help="Validate config and exit")
|
|
parser.add_argument("--list", action="store_true", help="List available agents")
|
|
args = parser.parse_args()
|
|
|
|
if args.list:
|
|
list_agents()
|
|
return
|
|
|
|
if not args.agent:
|
|
parser.error("--agent is required (or use --list)")
|
|
|
|
if args.validate:
|
|
ok = validate(args.agent)
|
|
sys.exit(0 if ok else 1)
|
|
|
|
run(args.agent)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|