Spaces:
Running
Running
| from __future__ import annotations | |
| import json | |
| import os | |
| import time | |
| from pathlib import Path | |
| from typing import Any, Dict | |
| from fastapi import FastAPI, Query | |
| from fastapi.responses import FileResponse, StreamingResponse | |
| from fastapi.staticfiles import StaticFiles | |
| from agent_core import iter_problem_steps | |
| ROOT_DIR = Path(__file__).resolve().parent | |
| STATIC_DIR = ROOT_DIR / "static" | |
| OUTPUT_DIR = ROOT_DIR / "outputs" | |
| AGNES_MODEL = "agnes-2.0-flash" | |
| AGNES_CHAT_COMPLETIONS_URL = "https://apihub.agnes-ai.com/v1/chat/completions" | |
| app = FastAPI(title="General Algorithm Problem Solving Agent") | |
| app.mount("/static", StaticFiles(directory=STATIC_DIR), name="static") | |
| def load_env_file(path: Path) -> None: | |
| if not path.exists(): | |
| return | |
| for raw_line in path.read_text(encoding="utf-8", errors="ignore").splitlines(): | |
| line = raw_line.strip() | |
| if not line or line.startswith("#") or "=" not in line: | |
| continue | |
| key, value = line.split("=", 1) | |
| key = key.strip() | |
| value = value.strip().strip('"').strip("'") | |
| if key and key not in os.environ: | |
| os.environ[key] = value | |
| load_env_file(ROOT_DIR / ".env") | |
| def sse_event(payload: Dict[str, Any]) -> str: | |
| return f"data: {json.dumps(payload, ensure_ascii=False)}\n\n" | |
| def index() -> FileResponse: | |
| return FileResponse(STATIC_DIR / "index.html") | |
| def status() -> Dict[str, Any]: | |
| api_key = os.getenv("AGNES_API_KEY", "") | |
| return { | |
| "enabled": bool(api_key), | |
| "provider": "Agnes AI", | |
| "model": AGNES_MODEL, | |
| "base_url_configured": True, | |
| "workflow": [ | |
| "Memory", | |
| "Planner", | |
| "Retriever", | |
| "Executor", | |
| "Script Runner", | |
| "Evaluator", | |
| "Loop Controller", | |
| "Reflector", | |
| "Artifact Writer", | |
| ], | |
| } | |
| def run_agent( | |
| question: str = Query(..., min_length=1), | |
| ) -> StreamingResponse: | |
| def stream(): | |
| selected_key = os.getenv("AGNES_API_KEY", "") | |
| yield sse_event( | |
| { | |
| "type": "status", | |
| "title": "Agent 启动", | |
| "content": "已接收问题,开始初始化 Session Memory 与任务状态。", | |
| "time": time.strftime("%H:%M:%S"), | |
| } | |
| ) | |
| try: | |
| final_state = None | |
| for index, (item, state) in enumerate( | |
| iter_problem_steps( | |
| question, | |
| api_key=selected_key, | |
| base_url=AGNES_CHAT_COMPLETIONS_URL, | |
| model=AGNES_MODEL, | |
| ), | |
| start=1, | |
| ): | |
| final_state = state | |
| yield sse_event( | |
| { | |
| "type": "step", | |
| "index": index, | |
| "module": item.get("module", ""), | |
| "title": item.get("title", ""), | |
| "content": item.get("content", ""), | |
| "time": time.strftime("%H:%M:%S"), | |
| } | |
| ) | |
| time.sleep(0.05) | |
| if final_state is None: | |
| raise RuntimeError("Agent 未产生任何输出。") | |
| result = { | |
| "final_answer": final_state.final_answer, | |
| "pdf_path": final_state.pdf_path, | |
| "tex_path": final_state.tex_path, | |
| } | |
| yield sse_event( | |
| { | |
| "type": "final", | |
| "title": "最终答案", | |
| "content": result["final_answer"], | |
| "pdf_url": "/api/report/pdf", | |
| "tex_url": "/api/report/tex", | |
| "time": time.strftime("%H:%M:%S"), | |
| } | |
| ) | |
| yield sse_event({"type": "done"}) | |
| except Exception as exc: | |
| yield sse_event( | |
| { | |
| "type": "error", | |
| "title": "运行失败", | |
| "content": str(exc), | |
| "time": time.strftime("%H:%M:%S"), | |
| } | |
| ) | |
| yield sse_event({"type": "done"}) | |
| return StreamingResponse(stream(), media_type="text/event-stream") | |
| def report_pdf() -> FileResponse: | |
| path = OUTPUT_DIR / "solution_report.pdf" | |
| return FileResponse(path, filename="solution_report.pdf", media_type="application/pdf") | |
| def report_tex() -> FileResponse: | |
| path = OUTPUT_DIR / "solution_report.tex" | |
| return FileResponse(path, filename="solution_report.tex", media_type="text/plain") | |