Coverage for agentos/api/server_old_backup.py: 0%

56 statements  

« prev     ^ index     » next       coverage.py v7.14.3, created at 2026-07-02 09:59 +0800

1""" 

2AgentOS v0.30 FastAPI REST服务 — 暴露Agent能力。 

3""" 

4 

5from fastapi import FastAPI, HTTPException 

6from fastapi.middleware.cors import CORSMiddleware 

7from pydantic import BaseModel, Field 

8from typing import Optional 

9import asyncio 

10import uuid 

11 

12from agentos.core.loop import AgentLoop, AgentResult, LoopState 

13 

14 

15class RunRequest(BaseModel): 

16 """Agent 运行请求体。""" 

17 

18 task: str 

19 session_id: str = "" 

20 stream: bool = False 

21 max_iterations: int = 100 

22 model: str = "auto" 

23 

24 

25class RunResponse(BaseModel): 

26 """Agent 运行响应体。""" 

27 

28 session_id: str 

29 output: str 

30 iterations: int 

31 cost_usd: float 

32 tokens_used: dict 

33 duration_ms: float 

34 state: str 

35 error: str | None = None 

36 

37 

38class AgentAPI: 

39 """AgentOS REST API 服务。""" 

40 

41 def __init__(self, loop: AgentLoop): 

42 self.loop = loop 

43 self.app = FastAPI(title="AgentOS v0.30", version="0.30.0") 

44 self._setup_middleware() 

45 self._setup_routes() 

46 

47 def _setup_middleware(self): 

48 self.app.add_middleware( 

49 CORSMiddleware, 

50 allow_origins=["*"], 

51 allow_credentials=True, 

52 allow_methods=["*"], 

53 allow_headers=["*"], 

54 ) 

55 

56 def _setup_routes(self): 

57 @self.app.get("/health") 

58 async def health(): 

59 return {"status": "ok", "version": "0.30.0"} 

60 

61 @self.app.post("/run", response_model=RunResponse) 

62 async def run_task(req: RunRequest): 

63 sid = req.session_id or str(uuid.uuid4())[:8] 

64 result = await self.loop.run(task=req.task, session_id=sid) 

65 return RunResponse( 

66 session_id=sid, 

67 output=result.output, 

68 iterations=result.iterations, 

69 cost_usd=result.cost_usd, 

70 tokens_used=result.tokens_used, 

71 duration_ms=result.duration_ms, 

72 state=result.final_state.value, 

73 error=result.error, 

74 ) 

75 

76 @self.app.post("/cancel/{session_id}") 

77 async def cancel(session_id: str): 

78 self.loop.cancel() 

79 return {"cancelled": True} 

80 

81 @self.app.get("/sessions/{session_id}") 

82 async def get_session(session_id: str): 

83 ctx = self.loop.context_manager 

84 return { 

85 "session_id": session_id, 

86 "task": ctx.current_task, 

87 "step_count": ctx.step_count, 

88 "messages": len(ctx._messages), 

89 } 

90 

91 @self.app.get("/costs") 

92 async def get_costs(): 

93 return { 

94 "total_cost": self.loop.cost_tracker.total_cost, 

95 "total_tokens": self.loop.cost_tracker.total_tokens, 

96 "by_model": self.loop.cost_tracker.cost_by_model(), 

97 "records_count": len(self.loop.cost_tracker.records), 

98 } 

99 

100 @self.app.get("/tools") 

101 async def list_tools(): 

102 return { 

103 "count": len(self.loop.tool_registry._tools), 

104 "tools": [ 

105 {"name": t.name, "description": t.description, "is_read": t.is_read, "category": t.category} 

106 for t in self.loop.tool_registry._tools.values() 

107 ], 

108 } 

109 

110 def serve(self, host: str = "0.0.0.0", port: int = 8080): 

111 import uvicorn 

112 uvicorn.run(self.app, host=host, port=port)