# Agent Runtime Closed Loop E2E Implementation Plan > **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task. **Goal:** 让 agent 闭环在真实本地环境中可验证:`runs` 支持首聊自动建会话,并通过真实异步任务、真实 LLM、真实落库与真实 SSE 证明端到端可用。 **Architecture:** 在 `v1/agent` 服务层引入“可选 session_id + 自动建会话”语义;保持已有 owner 鉴权路径。重构诊断脚本并新增 live E2E 用例,统一验证 run 入队、事件流、数据库状态、成本统计与删除语义。通过最小侵入改造现有 run/resume 流程,确保兼容已存在调用。 **Tech Stack:** FastAPI, SQLAlchemy async, Celery, Redis Stream, LiteLLM, PyJWT, pytest, httpx --- ### Task 1: 扩展 API 契约(session_id 可选) **Files:** - Modify: `backend/src/v1/agent/schemas.py` - Modify: `backend/src/v1/agent/router.py` - Test: `backend/tests/integration/v1/agent/test_routes.py` **Step 1: Write the failing test** 在 `test_routes.py` 新增用例:请求体不传 `session_id` 仍返回 202,且响应含 `session_id`。 **Step 2: Run test to verify it fails** Run: `uv run pytest backend/tests/integration/v1/agent/test_routes.py -k "runs and session" -v` Expected: FAIL,提示 `session_id` 缺失导致 422 或 mock 接口签名不匹配。 **Step 3: Write minimal implementation** - `RunRequest.session_id` 改为可选。 - `enqueue_run` 调用 service 时传可选值。 - `TaskAcceptedResponse` 增加 `created: bool` 字段。 **Step 4: Run test to verify it passes** Run: `uv run pytest backend/tests/integration/v1/agent/test_routes.py -v` Expected: PASS。 **Step 5: Commit** ```bash git add backend/src/v1/agent/schemas.py backend/src/v1/agent/router.py backend/tests/integration/v1/agent/test_routes.py git commit -m "feat: allow agent runs without pre-created session" ``` ### Task 2: 服务层支持自动建会话并保持鉴权 **Files:** - Modify: `backend/src/v1/agent/service.py` - Modify: `backend/src/v1/agent/repository.py` - Modify: `backend/src/v1/agent/dependencies.py` - Test: `backend/tests/unit/v1/agent/test_service.py` (new) **Step 1: Write the failing test** 新增单测覆盖: - `session_id is None` 时调用 `create_session_for_user` 并返回 `created=True` - `session_id 有值` 时复用并校验 owner **Step 2: Run test to verify it fails** Run: `uv run pytest backend/tests/unit/v1/agent/test_service.py -v` Expected: FAIL,当前 service 无自动建会话能力。 **Step 3: Write minimal implementation** - repository 增加 `create_session_for_user(user_id)`。 - service `enqueue_run` 处理两条路径: - 无 `session_id`:先创建 session。 - 有 `session_id`:校验 owner。 - 返回 `TaskAccepted(task_id, session_id, created)`。 **Step 4: Run test to verify it passes** Run: `uv run pytest backend/tests/unit/v1/agent/test_service.py -v` Expected: PASS。 **Step 5: Commit** ```bash git add backend/src/v1/agent/service.py backend/src/v1/agent/repository.py backend/src/v1/agent/dependencies.py backend/tests/unit/v1/agent/test_service.py git commit -m "feat: auto-create chat session on first agent run" ``` ### Task 3: 对齐 runtime 闭环数据断言(messages/sessions/cost) **Files:** - Modify: `backend/src/core/agent/application/run_service.py` - Modify: `backend/src/core/agent/application/resume_service.py` - Modify: `backend/src/core/agent/infrastructure/persistence/message_repository.py` - Modify: `backend/src/core/agent/infrastructure/persistence/session_repository.py` - Test: `backend/tests/integration/core/agent/test_queue_run_resume.py` **Step 1: Write the failing test** 在集成测试增加断言: - `sessions.total_tokens`、`sessions.total_cost` 有更新 - `messages` 的 token/cost 字段与 session 聚合一致 **Step 2: Run test to verify it fails** Run: `uv run pytest backend/tests/integration/core/agent/test_queue_run_resume.py -v` Expected: FAIL,当前默认 token/cost 为 0,未做聚合更新。 **Step 3: Write minimal implementation** - run/resume 流程接入 usage/cost 结果(来自 litellm 返回或 fallback 规则)。 - message 写入时填充 input/output tokens 与 cost。 - session 更新时累加 total_tokens/total_cost。 **Step 4: Run test to verify it passes** Run: `uv run pytest backend/tests/integration/core/agent/test_queue_run_resume.py -v` Expected: PASS。 **Step 5: Commit** ```bash git add backend/src/core/agent/application/run_service.py backend/src/core/agent/application/resume_service.py backend/src/core/agent/infrastructure/persistence/message_repository.py backend/src/core/agent/infrastructure/persistence/session_repository.py backend/tests/integration/core/agent/test_queue_run_resume.py git commit -m "feat: persist runtime token and cost aggregates" ``` ### Task 4: 补齐软删除级联(session -> messages) **Files:** - Modify: `backend/src/core/agent/infrastructure/persistence/session_repository.py` - Modify: `backend/src/v1/agent/service.py` - Test: `backend/tests/integration/core/agent/test_queue_run_resume.py` **Step 1: Write the failing test** 新增用例:软删 session 后,同会话 messages 的 `deleted_at` 同步写入。 **Step 2: Run test to verify it fails** Run: `uv run pytest backend/tests/integration/core/agent/test_queue_run_resume.py -k soft_delete -v` Expected: FAIL,当前无软删级联。 **Step 3: Write minimal implementation** - repository 增加 `soft_delete_session_with_messages(session_id)`。 - service 调用时使用同事务批量更新 messages。 **Step 4: Run test to verify it passes** Run: `uv run pytest backend/tests/integration/core/agent/test_queue_run_resume.py -k soft_delete -v` Expected: PASS。 **Step 5: Commit** ```bash git add backend/src/core/agent/infrastructure/persistence/session_repository.py backend/src/v1/agent/service.py backend/tests/integration/core/agent/test_queue_run_resume.py git commit -m "fix: cascade soft delete from sessions to messages" ``` ### Task 5: 重构诊断脚本并新增 live E2E **Files:** - Modify: `test_agent_sse_flow.py` - Create: `backend/tests/e2e/test_agent_closed_loop_live.py` - Modify: `docs/bugs/2026-03-05-agent-runtime-bugs.md` **Step 1: Write the failing test** 新增 live E2E 用例(`@pytest.mark.live`): - 首聊不传 `session_id` 返回 202 - 订阅 SSE 收到关键事件 - DB 断言 session/messages/tokens/cost **Step 2: Run test to verify it fails** Run: `uv run pytest backend/tests/e2e/test_agent_closed_loop_live.py -m live -v` Expected: FAIL,当前契约或脚本未对齐。 **Step 3: Write minimal implementation** - 清理脚本重复/不可达逻辑。 - 增加健康检查、阶段化日志、超时和错误根因输出。 - E2E 用例复用脚本中的 helper(JWT、SSE 解析、DB 断言)。 **Step 4: Run test to verify it passes** Run: - `uv run python test_agent_sse_flow.py --new-session` - `uv run pytest backend/tests/e2e/test_agent_closed_loop_live.py -m live -v` Expected: PASS。 **Step 5: Commit** ```bash git add test_agent_sse_flow.py backend/tests/e2e/test_agent_closed_loop_live.py docs/bugs/2026-03-05-agent-runtime-bugs.md git commit -m "test: add live closed-loop agent e2e verification" ``` ### Task 6: 全量验证与文档同步 **Files:** - Modify: `docs/runtime/runtime-runbook.md` - Modify: `docs/runtime/runtime-route.md` **Step 1: Run targeted checks** Run: - `uv run pytest backend/tests/unit/v1/agent/test_service.py -v` - `uv run pytest backend/tests/integration/v1/agent/test_routes.py -v` - `uv run pytest backend/tests/integration/core/agent/test_queue_run_resume.py -v` - `uv run pytest backend/tests/e2e/test_agent_closed_loop_live.py -m live -v` Expected: PASS。 **Step 2: Run quality gates** Run: - `uv run ruff check backend/src backend/tests` - `uv run basedpyright` Expected: PASS。 **Step 3: Update docs** 记录本地启动流程、真实 LLM 前置配置、live E2E 执行方式和故障排查。 **Step 4: Commit** ```bash git add docs/runtime/runtime-runbook.md docs/runtime/runtime-route.md git commit -m "docs: document live agent closed-loop e2e workflow" ```