File size: 3,330 Bytes
c97f58a | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | 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"))
SLM_URL = os.environ["MT_SLM_URL"]
ROUTER_URL = os.environ.get("MT_ROUTER_URL", "")
TOOLS_URL = os.environ["MT_TOOLS_URL"]
RELAY_URL = os.environ["MT_RELAY_URL"]
PREFERRED_MODEL = str((CONFIG.get("escalation") or {}).get("preferred_model") or "")
app = FastAPI(docs_url=None, redoc_url=None, openapi_url=None)
class HarnessIn(BaseModel):
item_id: str
task: dict[str, Any]
class RepairIn(BaseModel):
item_id: str
task: dict[str, Any]
draft: Any = None
trace: str = ""
errors: str = ""
ticket: str = ""
class SystemIn(BaseModel):
item_id: str
task: dict[str, Any]
floor: float = Field(ge=0.0, le=1.0)
ticket: str = ""
def decide(query: str, draft: str) -> float:
if not ROUTER_URL:
return 1.0
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
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=PREFERRED_MODEL,
)
@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 = run_harness(
payload.task, adapter=ADAPTER, slm_url=SLM_URL, tools_url=TOOLS_URL, config=CONFIG
)
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 = run_harness(
payload.task, adapter=ADAPTER, slm_url=SLM_URL, tools_url=TOOLS_URL, config=CONFIG
)
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")
|