Files
agent-maxim/agent/main.py
T
Anton 052591281d Initial clean version - Agent Maxim
- Complete agent system with planning and execution
- Bridge API with FastAPI server
- WhatsApp-style mobile dashboard
- Enhanced web search with query improvement
- Security guards and policy checks
- Comprehensive documentation
2026-04-09 18:07:43 +03:00

114 lines
4.0 KiB
Python

"""CLI entry point for the Minimal Viable Agent — Stage 1."""
from __future__ import annotations
import argparse
import sys
import uuid
from pathlib import Path
# Ensure the agent/ directory is on sys.path so imports work
sys.path.insert(0, str(Path(__file__).parent))
from core.controller import run_agent
from core.state import RunStatus, StepStatus
WORKSPACE_ROOT = Path(__file__).parent / "workspace"
def main() -> None:
import os
import sys
parser = argparse.ArgumentParser(
description="Minimal Viable Agent — Stage 1",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
examples:
python main.py --goal "inspect project"
python main.py --goal "create file hello.txt with text hello world"
python main.py --goal "проверь что тут есть"
""",
)
parser.add_argument("--goal", required=True, help="Goal for the agent to accomplish")
parser.add_argument("--run-id", default=None, help="Optional run ID (auto-generated if omitted)")
parser.add_argument("--trace-id", default=None, help="Trace ID for cross-layer observability")
args = parser.parse_args()
run_id = args.run_id or str(uuid.uuid4())[:8]
print(f"[agent] run_id : {run_id}")
print(f"[agent] workspace: {WORKSPACE_ROOT / 'runs' / run_id}")
print()
# Safe printing with encoding fallback (defined early for logging)
def safe_print(text: str, indent: int = 0) -> None:
"""Print text safely by replacing unencodable characters."""
try:
print(f"{' ' * indent}{text}")
except UnicodeEncodeError:
# Replace characters that can't be encoded
cleaned = text.encode(sys.stdout.encoding or 'utf-8', errors='replace').decode(sys.stdout.encoding or 'utf-8')
print(f"{' ' * indent}{cleaned}")
# === AGENT EXECUTION LOGGING START ===
safe_print("=== AGENT START ===")
safe_print(f"GOAL: {args.goal}")
print()
state = run_agent(run_id=run_id, goal=args.goal, workspace_root=WORKSPACE_ROOT, trace_id=args.trace_id)
# === AFTER PLANNER LOGGING ===
safe_print("=== AFTER PLANNER ===")
try:
print(f"Plan steps: {len(state.plan.steps)}")
for step in state.plan.steps:
print(f" - {step.step_id}: {step.kind} - {step.description}")
except Exception as e:
print(f"Error accessing plan: {e}")
print()
# === STEPS EXECUTION LOGGING ===
safe_print("=== STEPS EXECUTION ===")
try:
for step in state.plan.steps:
step_result = next((r for r in state.history if r.step_id == step.step_id), None)
if step_result:
status = "DONE" if step_result.status == StepStatus.DONE else "FAILED"
print(f" {step.step_id}: {step.kind} - {status}")
else:
print(f" {step.step_id}: {step.kind} - NOT EXECUTED")
except Exception as e:
print(f"Error accessing steps: {e}")
print()
# === AGENT EXECUTION LOGGING END ===
safe_print("=== AGENT END ===")
print()
# Print results
total = len(state.plan.steps)
done = sum(1 for s in state.plan.steps if s.status == StepStatus.DONE)
failed = sum(1 for s in state.plan.steps if s.status == StepStatus.FAILED)
print(f"[agent] status : {state.status.value.upper()}")
print(f"[agent] steps : {done} done, {failed} failed, {total} total")
print()
for result in state.history:
step = next((s for s in state.plan.steps if s.step_id == result.step_id), None)
kind = step.kind if step else "?"
icon = "[ok]" if result.status == StepStatus.DONE else "[!]"
safe_print(f"{icon} {result.step_id} ({kind})")
if result.output_text:
for line in result.output_text.rstrip().splitlines():
safe_print(line, indent=6)
if result.error:
safe_print(f"ERROR: {result.error}", indent=6)
print()
sys.exit(0 if state.status == RunStatus.DONE else 1)
if __name__ == "__main__":
main()