fix: gjør /run og /run/dag async — fjerner asyncio.run()-konflikt med uvicorn event loop
Some checks failed
Check Python Version Consistency / Check Python Version (push) Has been cancelled

This commit is contained in:
Chris Christiansen 2026-06-24 17:15:05 +00:00
parent 0a876f8e30
commit 54a86568b6
2 changed files with 27 additions and 8 deletions

View File

@ -302,9 +302,16 @@ async def _run_async(message: str, user_id: str, session_id: str, mode: str, cal
def run(message: str, user_id: str = "opax", session_id: str = "default", mode: str = "light", caller_type: str = "agent") -> str: def run(message: str, user_id: str = "opax", session_id: str = "default", mode: str = "light", caller_type: str = "agent") -> str:
"""
Synkron inngang kun for CLI (if __name__ == '__main__').
Fra FastAPI/uvicorn skal _run_async kalles direkte med await.
"""
mode = _normalize_mode(mode) mode = _normalize_mode(mode)
authorize_mode(user_id, mode) authorize_mode(user_id, mode)
return asyncio.run(_run_async(message=message, user_id=user_id, session_id=session_id, mode=mode, caller_type=caller_type)) return asyncio.run(_run_async(
message=message, user_id=user_id,
session_id=session_id, mode=mode, caller_type=caller_type
))
if __name__ == "__main__": if __name__ == "__main__":

26
main.py
View File

@ -892,7 +892,7 @@ app.add_api_route("/billing/aws/forecast", endpoint=require_auth(authenticated_a
# ── AGENT ENDPOINTS ─────────────────────────────────────────────────────────── # ── AGENT ENDPOINTS ───────────────────────────────────────────────────────────
@app.post("/run") @app.post("/run")
def run_agent(req: RunRequest): async def run_agent(req: RunRequest): # ← async def
try: try:
authorize_mode(req.user_id, req.mode) authorize_mode(req.user_id, req.mode)
except ValueError as e: except ValueError as e:
@ -904,7 +904,13 @@ def run_agent(req: RunRequest):
error_msg = None error_msg = None
response = None response = None
try: try:
response = run(message=req.message, user_id=req.user_id, session_id=req.session_id, mode=req.mode) from agent import _run_async # ← importer async-funksjonen
response = await _run_async( # ← await direkte
message=req.message,
user_id=req.user_id,
session_id=req.session_id,
mode=req.mode,
)
except Exception as e: except Exception as e:
error_msg = str(e) error_msg = str(e)
raise HTTPException(status_code=500, detail=error_msg) raise HTTPException(status_code=500, detail=error_msg)
@ -912,7 +918,9 @@ def run_agent(req: RunRequest):
duration = round(time.monotonic() - start, 3) duration = round(time.monotonic() - start, 3)
success = error_msg is None success = error_msg is None
model = "gemini-2.5-flash" if req.mode in ("light", "A") else "gemini-2.5-pro" model = "gemini-2.5-flash" if req.mode in ("light", "A") else "gemini-2.5-pro"
log_agent_call(agent_id=AGENT_ID, input_payload={"message": req.message, "mode": req.mode}, output=response, model_used=model, mode=req.mode, duration_s=duration, success=success, error=error_msg) log_agent_call(agent_id=AGENT_ID, input_payload={"message": req.message, "mode": req.mode},
output=response, model_used=model, mode=req.mode,
duration_s=duration, success=success, error=error_msg)
store.push(AGENT_ID, "last_duration_s", duration) store.push(AGENT_ID, "last_duration_s", duration)
store.push(AGENT_ID, "last_mode", req.mode) store.push(AGENT_ID, "last_mode", req.mode)
store.push(AGENT_ID, "last_success", success) store.push(AGENT_ID, "last_success", success)
@ -922,24 +930,28 @@ def run_agent(req: RunRequest):
@app.post("/run/dag") @app.post("/run/dag")
def run_dag(req: DagRequest): async def run_dag(req: DagRequest):
try: try:
authorize_mode(req.user_id, req.mode) authorize_mode(req.user_id, req.mode)
except ValueError as e: except ValueError as e:
raise HTTPException(status_code=400, detail=str(e)) raise HTTPException(status_code=400, detail=str(e))
except PermissionError as e: except PermissionError as e:
raise HTTPException(status_code=403, detail=str(e)) raise HTTPException(status_code=403, detail=str(e))
from agent import _run_async
def make_agent_fn(msg, idx): def make_agent_fn(msg, idx):
def _agent_fn(payload): async def _agent_fn(payload):
return run(message=msg, user_id=payload["user_id"], session_id=f"{payload['session_id']}-dag-{idx}", mode=payload["mode"]) return await _run_async(message=msg, user_id=payload["user_id"], session_id=f"{payload['session_id']}-dag-{idx}", mode=payload["mode"])
_agent_fn.__name__ = f"opax-dag-{idx}" _agent_fn.__name__ = f"opax-dag-{idx}"
return _agent_fn return _agent_fn
payload = {"user_id": req.user_id, "session_id": req.session_id, "mode": req.mode} payload = {"user_id": req.user_id, "session_id": req.session_id, "mode": req.mode}
agent_fns = [make_agent_fn(msg, i) for i, msg in enumerate(req.messages)] agent_fns = [make_agent_fn(msg, i) for i, msg in enumerate(req.messages)]
agent_ids = [f"opax-dag-{i}" for i in range(len(req.messages))] agent_ids = [f"opax-dag-{i}" for i in range(len(req.messages))]
start = time.monotonic() start = time.monotonic()
tasks = build_agent_dag(agent_fns, payload, agent_ids) tasks = build_agent_dag(agent_fns, payload, agent_ids)
results = execute_dag(tasks, scheduler=req.scheduler) results = await execute_dag(tasks, scheduler=req.scheduler)
total_dur = round(time.monotonic() - start, 3) total_dur = round(time.monotonic() - start, 3)
store = get_store() store = get_store()
log_dag_execution(dag_id=req.session_id, agent_results=results, total_duration_s=total_dur) log_dag_execution(dag_id=req.session_id, agent_results=results, total_duration_s=total_dur)