"""端到端验证:SSE 订阅 + 任务提交,确认网关主动推送 task_done。""" import asyncio import json import uuid import httpx BASE = "http://127.0.0.1:8000" AUTH = "gw_Hz8Qp3Km9f" SESSION = f"e2e-{uuid.uuid4().hex[:8]}" async def main() -> None: async with httpx.AsyncClient(timeout=30) as client: # 1) 提交任务(携带 cli_session_id),任务类型用 agent 已注册的能力 resp = await client.post( f"{BASE}/api/cli/tasks", json={ "auth": AUTH, "task_type": "dev", "task_tags": ["code", "dev"], "description": "SSE 通知验证:创建临时文件", "cli_session_id": SESSION, "payload": { "type": "create_files", "files": [{"path": "_sse_probe.txt", "content": "hello-sse"}], }, "timeout": 120, }, ) print("submit status:", resp.status_code) task = resp.json() request_id = task["request_id"] print("request_id:", request_id, "initial status:", task["status"]) # 2) 订阅 SSE,等待 task_done got = [] async def subscribe(): try: async with client.stream( "GET", f"{BASE}/api/cli/events", params={"cli_session_id": SESSION, "auth": AUTH}, ) as stream: async for line in stream.aiter_lines(): if line.startswith("data: "): evt = json.loads(line[6:]) got.append(evt) print("SSE EVENT:", json.dumps(evt, ensure_ascii=False)) if evt.get("request_id") == request_id: return except Exception as exc: # noqa: BLE001 print("SSE error:", exc) # 3) 并行:订阅 + 轮询兜底打印(仅观察,不作为结论) await asyncio.gather( subscribe(), _poll_until_done(client, request_id), ) if any(e.get("request_id") == request_id for e in got): print("\nRESULT: PASS - SSE task_done received without polling") else: print("\nRESULT: FAIL - no SSE event for this request_id") async def _poll_until_done(client, request_id: str) -> None: for _ in range(60): r = await client.get(f"{BASE}/api/cli/tasks/{request_id}") if r.status_code == 404: await asyncio.sleep(2) continue t = r.json() print("poll status:", t["status"]) if t["status"] in ("success", "failed"): return await asyncio.sleep(2) if __name__ == "__main__": asyncio.run(main())