fix(agent-office): 코드 리뷰 Critical/Important 이슈 수정

- REST 404 응답을 HTTPException으로 변경 (tuple 반환 버그)
- MusicAgent 폴링을 asyncio.create_task로 비동기화 (이벤트 루프 블로킹 해소)
- WebSocket JSON 파싱 에러 핸들링 추가
- StockAgent add_alert 파라미터 검증 추가
- 미사용 의존성 제거 (requests, python-telegram-bot)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-11 09:08:58 +09:00
parent 3a63bfac15
commit 6922217da6
4 changed files with 16 additions and 9 deletions

View File

@@ -63,7 +63,9 @@ class MusicAgent(BaseAgent):
approve_task(task_id, via="telegram") approve_task(task_id, via="telegram")
await self.transition("working", "작곡 중...", task_id) await self.transition("working", "작곡 중...", task_id)
asyncio.create_task(self._poll_composition(task_id, task))
async def _poll_composition(self, task_id: str, task: dict) -> None:
try: try:
input_data = task["input_data"] input_data = task["input_data"]
payload = { payload = {

View File

@@ -45,12 +45,16 @@ class StockAgent(BaseAgent):
return {"ok": True, "message": "뉴스 수집 시작"} return {"ok": True, "message": "뉴스 수집 시작"}
if command == "add_alert": if command == "add_alert":
symbol = params.get("symbol")
target_price = params.get("target_price")
if not symbol or target_price is None:
return {"ok": False, "message": "symbol과 target_price는 필수입니다"}
config = get_agent_config(self.agent_id) config = get_agent_config(self.agent_id)
alerts = config["custom_config"].get("alerts", []) alerts = config["custom_config"].get("alerts", [])
alerts.append({ alerts.append({
"symbol": params["symbol"], "symbol": symbol,
"name": params.get("name", params["symbol"]), "name": params.get("name", symbol),
"target_price": params["target_price"], "target_price": target_price,
"direction": params.get("direction", "above"), "direction": params.get("direction", "above"),
}) })
from ..db import update_agent_config from ..db import update_agent_config

View File

@@ -1,6 +1,6 @@
import os import os
import json import json
from fastapi import FastAPI, WebSocket, WebSocketDisconnect from fastapi import FastAPI, HTTPException, WebSocket, WebSocketDisconnect
from fastapi.middleware.cors import CORSMiddleware from fastapi.middleware.cors import CORSMiddleware
from .config import CORS_ALLOW_ORIGINS from .config import CORS_ALLOW_ORIGINS
@@ -48,7 +48,10 @@ async def websocket_endpoint(ws: WebSocket):
}, ensure_ascii=False)) }, ensure_ascii=False))
while True: while True:
data = await ws.receive_text() data = await ws.receive_text()
msg = json.loads(data) try:
msg = json.loads(data)
except json.JSONDecodeError:
continue
await _handle_ws_message(msg) await _handle_ws_message(msg)
except WebSocketDisconnect: except WebSocketDisconnect:
pass pass
@@ -86,7 +89,7 @@ def list_agents():
def agent_detail(agent_id: str): def agent_detail(agent_id: str):
config = get_agent_config(agent_id) config = get_agent_config(agent_id)
if not config: if not config:
return {"error": "Agent not found"}, 404 raise HTTPException(status_code=404, detail="Agent not found")
agent = get_agent(agent_id) agent = get_agent(agent_id)
state_info = {"state": agent.state, "detail": agent.state_detail} if agent else {} state_info = {"state": agent.state, "detail": agent.state_detail} if agent else {}
return {**config, **state_info} return {**config, **state_info}
@@ -114,7 +117,7 @@ def pending_tasks():
def task_detail(task_id: str): def task_detail(task_id: str):
task = get_task(task_id) task = get_task(task_id)
if not task: if not task:
return {"error": "Task not found"}, 404 raise HTTPException(status_code=404, detail="Task not found")
return task return task
@app.post("/api/agent-office/command") @app.post("/api/agent-office/command")

View File

@@ -1,7 +1,5 @@
fastapi==0.115.6 fastapi==0.115.6
uvicorn[standard]==0.30.6 uvicorn[standard]==0.30.6
requests==2.32.3
apscheduler==3.10.4 apscheduler==3.10.4
python-telegram-bot==21.5
websockets>=12.0 websockets>=12.0
httpx>=0.27 httpx>=0.27