feat: finalize production cleanup with structured agent responses and project governance

This commit is contained in:
Space-Banane
2026-05-27 18:08:52 +02:00
parent a19b285232
commit c09f0ee9c0
17 changed files with 737 additions and 126 deletions

View File

@@ -1,5 +1,6 @@
from __future__ import annotations
import json
import threading
import time
import uuid
@@ -159,6 +160,7 @@ class JobManager:
ended_at=ended_at,
error=error_text,
result=error_text,
response_json=json.dumps({"return": error_text, "data": None}, ensure_ascii=False),
)
self._publish(
job_id,
@@ -237,6 +239,7 @@ class JobManager:
ended_at=ended_at,
error=err,
result=err,
response_json=json.dumps({"return": err, "data": None}, ensure_ascii=False),
)
self._publish(job_id, {"ts": ended_at, "step": 0, "event_type": "job_failed", "payload": {"error": err}})
with self._lock:
@@ -251,7 +254,14 @@ class JobManager:
job_id,
status=status,
ended_at=ended_at,
result=result.result,
result=result.return_message,
response_json=json.dumps(
{
"return": result.return_message,
"data": result.data,
},
ensure_ascii=False,
),
error=result.error,
steps=result.steps,
cancelled=1 if result.cancelled else 0,
@@ -271,7 +281,8 @@ class JobManager:
"event_type": "job_finished",
"payload": {
"status": status,
"result": result.result,
"result": result.return_message,
"response": {"return": result.return_message, "data": result.data},
"error": result.error,
"cancelled": result.cancelled,
"usage": result.usage.to_dict(),
@@ -318,10 +329,10 @@ class JobManager:
job["is_running_thread"] = live.thread.is_alive()
else:
job["is_running_thread"] = False
return job
return self._normalize_job_payload(job)
def list_jobs(self, limit: int = 100) -> list[dict[str, Any]]:
return self.db.list_jobs(limit=limit)
return [self._normalize_job_payload(job) for job in self.db.list_jobs(limit=limit)]
def get_events(self, job_id: str, limit: int = 500) -> list[dict[str, Any]]:
return self.db.get_job_events(job_id, limit=limit)
@@ -331,3 +342,12 @@ class JobManager:
with self._lock:
stats["live_running_threads"] = sum(1 for job in self._running.values() if job.thread.is_alive())
return stats
def _normalize_job_payload(self, job: dict[str, Any]) -> dict[str, Any]:
response = job.get("response")
if not isinstance(response, dict):
response = {"return": str(job.get("result") or ""), "data": None}
job["response"] = response
job["return"] = str(response.get("return") or "")
job["data"] = response.get("data")
return job