from __future__ import annotations import json import os import sys from pathlib import Path from typing import Any import httpx from fastapi import FastAPI from pydantic import BaseModel, Field ROOT = Path(__file__).resolve().parent sys.path.insert(0, str(ROOT)) from escalation.patcher import repair # noqa: E402 from harness.adapters import load # noqa: E402 from harness.engine import run_harness # noqa: E402 CONFIG: dict[str, Any] = json.loads((ROOT / "config.json").read_text(encoding="utf-8")) ADAPTER = load(str(CONFIG.get("adapter") or "generic")) # .get everywhere: ctx_compress has no tools, and a missing variable must not crash startup SLM_URL = os.environ.get("MT_SLM_URL", "") ROUTER_URL = os.environ.get("MT_ROUTER_URL", "") TOOLS_URL = os.environ.get("MT_TOOLS_URL", "") RELAY_URL = os.environ.get("MT_RELAY_URL", "") ESCALATION = CONFIG.get("escalation") or {} MODELS: list[str] = list(ESCALATION.get("models") or []) or [str(ESCALATION.get("preferred_model") or "")] TAIL_CHARS = int(ESCALATION.get("session_tail_chars") or 0) MAX_NEW = int((CONFIG.get("slm") or {}).get("max_new_tokens") or 3072) app = FastAPI(docs_url=None, redoc_url=None, openapi_url=None) class HarnessIn(BaseModel): item_id: str task: dict[str, Any] seed: int | None = None class RepairIn(BaseModel): item_id: str task: dict[str, Any] draft: Any = None trace: str = "" errors: str = "" ticket: str = "" seed: int | None = None class SystemIn(BaseModel): item_id: str task: dict[str, Any] floor: float = Field(ge=0.0, le=1.0) ticket: str = "" seed: int | None = None def decide(query: str, draft: str) -> float: if not ROUTER_URL: return 1.0 try: with httpx.Client(timeout=30.0) as http: response = http.post( ROUTER_URL.rstrip("/") + "/decide", json={"input": {"query": query, "draft": draft}} ) response.raise_for_status() answers = response.json().get("answers") or [] return float(answers[0]["probability"]) if answers else 0.0 except Exception: return 0.0 def _repair(payload: RepairIn | SystemIn, draft: Any, trace: str, errors: str) -> Any: return repair( payload.task, draft, trace, errors, adapter=ADAPTER, relay_url=RELAY_URL, ticket=payload.ticket, model=MODELS, tail_chars=TAIL_CHARS, max_tokens=MAX_NEW, ) def _harness(task: dict[str, Any], seed: int | None): return run_harness( task, adapter=ADAPTER, slm_url=SLM_URL, tools_url=TOOLS_URL, config=CONFIG, seed=seed ) @app.get("/health") def health() -> dict[str, str]: return {"status": "ok", "adapter": ADAPTER.name} @app.post("/harness/run") def harness_run(payload: HarnessIn) -> dict[str, Any]: result = _harness(payload.task, payload.seed) return { "answer": result.answer, "self_check": {"pass": result.verified}, "trace": result.trace, "steps": result.steps, } @app.post("/escalation/repair") def escalation_repair(payload: RepairIn) -> dict[str, Any]: return {"answer": _repair(payload, payload.draft, payload.trace, payload.errors)} @app.post("/system/run") def system_run(payload: SystemIn) -> dict[str, Any]: result = _harness(payload.task, payload.seed) draft = result.answer probability = decide(ADAPTER.query(payload.task), ADAPTER.as_text(draft)) if result.verified and probability >= payload.floor: return {"answer": draft, "route": "local", "p": probability} answer = _repair(payload, draft, result.trace, result.errors) return {"answer": answer, "route": "escalated", "p": probability} if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=int(os.environ.get("MT_PORT", "8080")), log_level="warning")