"""Read/export model diagnostics from the task's existing trace database.""" from datetime import UTC, datetime import json import time from apps.admin_console.database.connection import db_session def request_diagnostics( session_id: str, *, db_path=None, limit: int | None = None, offset: int = 0 ) -> dict: with db_session(db_path) as conn: session = conn.execute( "SELECT status FROM sessions WHERE session_id = ?", (session_id,) ).fetchone() sql = ( "SELECT payload FROM traces WHERE session_id = ? AND type = 'llm_diagnostic' " "ORDER BY timestamp DESC" ) params: tuple = (session_id,) total = conn.execute( "SELECT count(*) FROM traces WHERE session_id=? AND type='llm_diagnostic'", params, ).fetchone()[0] if limit is not None: sql += " LIMIT ? OFFSET ?" params += (limit, offset) rows = conn.execute(sql, params).fetchall() review_rows = conn.execute( "SELECT payload FROM traces WHERE session_id = ? " "AND type = 'final_review_diagnostic' ORDER BY timestamp DESC" + (" LIMIT ?" if limit is not None else ""), (session_id, limit) if limit is not None else (session_id,), ).fetchall() requests = [] seen = set() running = bool(session and session["status"] in {"running", "resuming"}) for row in rows: try: value = json.loads(row["payload"]) except (ValueError, TypeError): continue if not isinstance(value, dict): continue request_id = value.get("request_id") value["active"] = ( running and offset == 0 and request_id not in seen and value.get("phase") in { "waiting_response", "waiting_output", "receiving_output", "generating_tool_arguments", "retry_wait", } ) seen.add(request_id) value["timestamps_utc"] = { field: datetime.fromtimestamp(value[field], UTC).isoformat() for field in ( "started_at", "request_sent_at", "headers_at", "first_output_at", "last_output_at", "ended_at", "retry_at", ) if isinstance(value.get(field), (int, float)) } requests.append(value) final_reviews = [] for row in review_rows: try: value = json.loads(row["payload"]) except (ValueError, TypeError): continue if not isinstance(value, dict): continue value["active"] = ( running and offset == 0 and not final_reviews and value.get("status") == "running" ) if value["active"] and isinstance(value.get("started_at"), (int, float)): value["elapsed_seconds"] = round(max(0.0, time.time() - value["started_at"]), 3) value["remaining_seconds"] = round( max(0.0, value.get("total_seconds", 0.0) - value["elapsed_seconds"]), 3 ) value["budget_observed_at"] = time.time() value["timestamps_utc"] = { field: datetime.fromtimestamp(value[field], UTC).isoformat() for field in ("started_at", "deadline_at", "ended_at") if isinstance(value.get(field), (int, float)) } final_reviews.append(value) return { "schema_version": 1, "session_id": session_id, "session_status": session["status"] if session else "unknown", "collected_at": time.time(), "requests": requests, "final_reviews": final_reviews, "total": total, "offset": offset, "next_offset": offset + limit if limit is not None and offset + limit < total else None, "note": "时间戳为 Unix 秒;timestamps_utc 为 UTC。HTTP 200 不代表完整输出。usage=null 表示服务未报告用量。历史任务没有记录的字段无法补推。", } def diagnostics_json(session_id: str) -> str: return json.dumps(request_diagnostics(session_id), ensure_ascii=False, indent=2)