feat(agent-chat): complete core workflow and strengthen auth rate limiting
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
# Agent Chat CrewAI + AG-UI Spike Notes
|
||||
|
||||
## Scope
|
||||
|
||||
- 验证 CrewAI 依赖可用性与版本探测方式。
|
||||
- 验证 AG-UI 官方 CrewAI 集成在当前仓库中的落地路径。
|
||||
- 验证 DashScope FunASR 响应中的 usage 字段可得性与兜底策略。
|
||||
|
||||
## Findings
|
||||
|
||||
### CrewAI
|
||||
|
||||
- `uv run python -m pip show crewai` 在当前虚拟环境不可用(无 pip 模块)。
|
||||
- `uv pip show crewai` 返回未安装,说明当前工作树尚未安装 CrewAI 依赖。
|
||||
- 若需启用真实编排,需在 `pyproject.toml` 中声明依赖并执行 `uv sync --extra dev`。
|
||||
|
||||
### AG-UI 官方 CrewAI 集成
|
||||
|
||||
- 目标对齐官方标准事件语义(如 `message.delta`、`tool.started`、`tool.completed`、`run.completed`、`run.failed`)。
|
||||
- 当前仓库采取“适配层隔离”策略:由 `agui_adapter.py` 进行请求与事件映射,避免协议细节扩散到业务层。
|
||||
|
||||
### DashScope FunASR
|
||||
|
||||
- 优先读取上游响应 usage 字段用于成本统计。
|
||||
- 若 usage 缺失,落库时保持 `raw_usage` 与空标准字段,并标记 `metadata.usage_missing=true` 以便审计。
|
||||
|
||||
## Fallback Strategy
|
||||
|
||||
- 当官方集成能力或版本存在不确定性时,启用最小兜底事件映射:
|
||||
- 仅输出标准 AG-UI 事件。
|
||||
- 不扩展私有协议字段。
|
||||
- 在 `event_bridge.py` 中统一做字段校验与错误转换。
|
||||
|
||||
## Decision
|
||||
|
||||
- 继续按计划推进:先补齐编排与成本核心,再完善 AG-UI 适配、多模态与 E2E 闭环。
|
||||
@@ -0,0 +1,49 @@
|
||||
# Agent Chat Gap Closure Design
|
||||
|
||||
**Goal:** 在不重做已完成任务的前提下,按既定 Task 顺序补齐 Agent Chat Core 的缺口,实现可验证、可审计的端到端闭环。
|
||||
|
||||
## Current State
|
||||
|
||||
- 已完成:Task 2/3/4 的核心数据层、静态配置、模板加载;Task 6/7 的部分骨架(`event_bridge`、`v1/agent_chat`、`storage_adapter`、`asr_fun_asr`)。
|
||||
- 未完成或缺口:Task 1 的 spike 结论文档;Task 5 编排与成本追踪;Task 6 `agui_adapter` 与缺失测试;Task 7 `multimodal`;Task 8 会话审计与 recent 规则;Task 9 E2E 与运行文档闭环。
|
||||
|
||||
## Design Decisions
|
||||
|
||||
- 以“缺口优先”方式执行:仅新增/修改缺失能力,已稳定模块不重构。
|
||||
- 严格遵循顺序:Task 1 -> 5 -> 6 -> 7 -> 8 -> 9。
|
||||
- 每个 Task 均采用 TDD:先写失败测试,再做最小实现,通过后再小步重构。
|
||||
- 统一事件与持久化顺序:以 `session.id + seq` 为唯一顺序锚点,避免流式输出与落库顺序漂移。
|
||||
- 工具调用成本仍归集到 `messages(role=tool)`,会话总成本由增量聚合维护。
|
||||
|
||||
## Component Plan
|
||||
|
||||
- Task 1: 新增 spike notes,记录 CrewAI/AG-UI/FunASR 依赖可用性与兜底策略。
|
||||
- Task 5: 新增 `orchestrator.py`、`cost_tracker.py`、`events.py`,完成三阶段执行与 usage/cost 归一。
|
||||
- Task 6: 新增 `agui_adapter.py`,对接现有 `event_bridge.py` 与 `v1/agent_chat/service.py`。
|
||||
- Task 7: 新增 `multimodal.py`,衔接附件校验、存储元数据、ASR 文本提取。
|
||||
- Task 8: 增强会话标题策略、recent session 查询、审计字段与限流保护。
|
||||
- Task 9: 补齐 E2E 与 runbook,执行 bootstrap gate + 分层测试验证。
|
||||
|
||||
## Data Flow
|
||||
|
||||
1. 路由接收 AG-UI 请求并解析输入文本/附件。
|
||||
2. `agui_adapter` 生成内部命令并触发编排器三阶段执行。
|
||||
3. 每阶段产出内部事件,经 `event_bridge` 映射为 AG-UI 标准事件。
|
||||
4. `service` 在事务内写入 `messages` 并更新 `sessions` 汇总字段。
|
||||
5. 流式事件向外输出,顺序与 `messages.seq` 保持一致。
|
||||
|
||||
## Error Handling
|
||||
|
||||
- 配置/模板错误:启动前校验并快速失败,返回可追踪错误码。
|
||||
- 第三方调用错误(LLM/ASR/Storage):记录标准化失败事件与审计元数据,不泄露敏感信息。
|
||||
- 持久化冲突:对 `session_id + seq` 冲突执行有限重试并记录告警。
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
- Unit:`cost_tracker`、`orchestrator`、`agui_adapter`、`multimodal`、`title strategy`。
|
||||
- Integration:`agent_chat` 路由、事件落库、recent session 选择、会话成本聚合。
|
||||
- E2E:文本、图片+文本、音频+ASR、文档问答、首页最近会话默认选中。
|
||||
|
||||
## Approval Note
|
||||
|
||||
该设计基于用户确认的“仅按未完成 Task 顺序推进”执行策略。
|
||||
@@ -0,0 +1,230 @@
|
||||
# Agent Chat Gap Closure Implementation Plan
|
||||
|
||||
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
||||
|
||||
**Goal:** 按未完成 Task 顺序补齐 Agent Chat Core 缺口,形成可运行、可测试、可审计的后端链路。
|
||||
|
||||
**Architecture:** 复用已完成的数据层与路由骨架,在 `core/agent_chat` 补齐编排、成本与多模态能力,并通过 `v1/agent_chat/service.py` 统一持久化与事件顺序。全流程以 `session.id + messages.seq` 作为一致性锚点,保证事件输出与落库一致。
|
||||
|
||||
**Tech Stack:** FastAPI, SQLAlchemy, Pydantic, pytest, CrewAI, AG-UI adapter, DashScope SDK, Supabase Storage。
|
||||
|
||||
---
|
||||
|
||||
### Task 1: 补齐 Spike 结论文档
|
||||
|
||||
**Files:**
|
||||
- Create: `docs/plans/2026-02-25-agent-chat-crewai-ag-ui-spike-notes.md`
|
||||
|
||||
**Step 1: 写失败校验(文档存在性)**
|
||||
|
||||
```bash
|
||||
test -f docs/plans/2026-02-25-agent-chat-crewai-ag-ui-spike-notes.md
|
||||
```
|
||||
|
||||
**Step 2: 运行并确认失败**
|
||||
|
||||
Run: `test -f docs/plans/2026-02-25-agent-chat-crewai-ag-ui-spike-notes.md`
|
||||
Expected: non-zero exit code。
|
||||
|
||||
**Step 3: 写最小文档实现**
|
||||
|
||||
```markdown
|
||||
- CrewAI 版本探测结论
|
||||
- AG-UI 官方 CrewAI 集成可用性结论
|
||||
- DashScope FunASR usage 字段策略
|
||||
- 不可用时的最小兜底映射策略
|
||||
```
|
||||
|
||||
**Step 4: 运行并确认通过**
|
||||
|
||||
Run: `test -f docs/plans/2026-02-25-agent-chat-crewai-ag-ui-spike-notes.md`
|
||||
Expected: zero exit code。
|
||||
|
||||
### Task 5: 补齐编排与成本追踪
|
||||
|
||||
**Files:**
|
||||
- Create: `backend/src/core/agent_chat/events.py`
|
||||
- Create: `backend/src/core/agent_chat/cost_tracker.py`
|
||||
- Create: `backend/src/core/agent_chat/orchestrator.py`
|
||||
- Test: `backend/tests/unit/core/agent_chat/test_cost_tracker.py`
|
||||
- Test: `backend/tests/unit/core/agent_chat/test_orchestrator_pipeline.py`
|
||||
|
||||
**Step 1: 写失败测试**
|
||||
|
||||
```python
|
||||
def test_normalize_usage_and_cost_aggregation():
|
||||
assert False
|
||||
|
||||
|
||||
def test_orchestrator_runs_three_stages_in_order():
|
||||
assert False
|
||||
```
|
||||
|
||||
**Step 2: 运行并确认失败**
|
||||
|
||||
Run: `PYTHONPATH=backend/src uv run pytest backend/tests/unit/core/agent_chat/test_cost_tracker.py backend/tests/unit/core/agent_chat/test_orchestrator_pipeline.py -v`
|
||||
Expected: FAIL。
|
||||
|
||||
**Step 3: 写最小实现**
|
||||
|
||||
```python
|
||||
class CostTracker:
|
||||
def add_usage(self, usage: dict) -> None: ...
|
||||
def total(self) -> dict: ...
|
||||
|
||||
|
||||
class AgentChatOrchestrator:
|
||||
async def run(self, command):
|
||||
# intent -> execution -> organization
|
||||
...
|
||||
```
|
||||
|
||||
**Step 4: 运行并确认通过**
|
||||
|
||||
Run: `PYTHONPATH=backend/src uv run pytest backend/tests/unit/core/agent_chat/test_cost_tracker.py backend/tests/unit/core/agent_chat/test_orchestrator_pipeline.py -v`
|
||||
Expected: PASS。
|
||||
|
||||
### Task 6: 补齐 AG-UI 适配层缺口
|
||||
|
||||
**Files:**
|
||||
- Create: `backend/src/core/agent_chat/agui_adapter.py`
|
||||
- Modify: `backend/src/core/agent_chat/event_bridge.py`
|
||||
- Modify: `backend/src/v1/agent_chat/service.py`
|
||||
- Test: `backend/tests/unit/core/agent_chat/test_agui_adapter.py`
|
||||
- Test: `backend/tests/integration/test_agent_chat_event_persistence.py`
|
||||
|
||||
**Step 1: 写失败测试**
|
||||
|
||||
```python
|
||||
def test_agui_adapter_maps_internal_events_to_protocol_events():
|
||||
assert False
|
||||
```
|
||||
|
||||
**Step 2: 运行并确认失败**
|
||||
|
||||
Run: `PYTHONPATH=backend/src uv run pytest backend/tests/unit/core/agent_chat/test_agui_adapter.py backend/tests/integration/test_agent_chat_event_persistence.py -v`
|
||||
Expected: FAIL。
|
||||
|
||||
**Step 3: 写最小实现**
|
||||
|
||||
```python
|
||||
class AguiAdapter:
|
||||
def to_command(self, request): ...
|
||||
def to_protocol_event(self, event): ...
|
||||
```
|
||||
|
||||
**Step 4: 运行并确认通过**
|
||||
|
||||
Run: `PYTHONPATH=backend/src uv run pytest backend/tests/unit/core/agent_chat/test_agui_adapter.py backend/tests/integration/test_agent_chat_event_persistence.py -v`
|
||||
Expected: PASS。
|
||||
|
||||
### Task 7: 补齐多模态输入编排
|
||||
|
||||
**Files:**
|
||||
- Create: `backend/src/core/agent_chat/multimodal.py`
|
||||
- Modify: `backend/src/core/agent_chat/storage_adapter.py`
|
||||
- Modify: `backend/src/core/agent_chat/tools/asr_fun_asr.py`
|
||||
- Test: `backend/tests/unit/core/agent_chat/test_multimodal.py`
|
||||
|
||||
**Step 1: 写失败测试**
|
||||
|
||||
```python
|
||||
def test_multimodal_validates_and_builds_attachment_context():
|
||||
assert False
|
||||
```
|
||||
|
||||
**Step 2: 运行并确认失败**
|
||||
|
||||
Run: `PYTHONPATH=backend/src uv run pytest backend/tests/unit/core/agent_chat/test_multimodal.py -v`
|
||||
Expected: FAIL。
|
||||
|
||||
**Step 3: 写最小实现**
|
||||
|
||||
```python
|
||||
class MultimodalProcessor:
|
||||
async def build_context(self, attachments): ...
|
||||
```
|
||||
|
||||
**Step 4: 运行并确认通过**
|
||||
|
||||
Run: `PYTHONPATH=backend/src uv run pytest backend/tests/unit/core/agent_chat/test_multimodal.py backend/tests/unit/core/agent_chat/test_storage_adapter.py backend/tests/unit/core/agent_chat/test_asr_fun_asr_tool.py -v`
|
||||
Expected: PASS。
|
||||
|
||||
### Task 8: 补齐会话审计与 recent 规则
|
||||
|
||||
**Files:**
|
||||
- Modify: `backend/src/v1/agent_chat/service.py`
|
||||
- Modify: `backend/src/v1/agent_chat/router.py`
|
||||
- Test: `backend/tests/unit/core/agent_chat/test_session_title_strategy.py`
|
||||
- Test: `backend/tests/integration/test_agent_chat_session_recent_selection.py`
|
||||
- Test: `backend/tests/integration/test_agent_chat_session_persistence.py`
|
||||
|
||||
**Step 1: 写失败测试**
|
||||
|
||||
```python
|
||||
def test_title_generated_from_first_user_message():
|
||||
assert False
|
||||
|
||||
|
||||
def test_recent_session_selected_by_last_activity_at_desc():
|
||||
assert False
|
||||
```
|
||||
|
||||
**Step 2: 运行并确认失败**
|
||||
|
||||
Run: `PYTHONPATH=backend/src uv run pytest backend/tests/unit/core/agent_chat/test_session_title_strategy.py backend/tests/integration/test_agent_chat_session_recent_selection.py backend/tests/integration/test_agent_chat_session_persistence.py -v`
|
||||
Expected: FAIL。
|
||||
|
||||
**Step 3: 写最小实现**
|
||||
|
||||
```python
|
||||
def build_session_title(first_message: str) -> str: ...
|
||||
```
|
||||
|
||||
**Step 4: 运行并确认通过**
|
||||
|
||||
Run: `PYTHONPATH=backend/src uv run pytest backend/tests/unit/core/agent_chat/test_session_title_strategy.py backend/tests/integration/test_agent_chat_session_recent_selection.py backend/tests/integration/test_agent_chat_session_persistence.py -v`
|
||||
Expected: PASS。
|
||||
|
||||
### Task 9: 补齐 E2E 与运行文档闭环
|
||||
|
||||
**Files:**
|
||||
- Create: `backend/tests/e2e/test_agent_chat_flow.py`
|
||||
- Create: `backend/tests/e2e/test_agent_chat_recent_session_home.py`
|
||||
- Modify: `docs/runtime/runtime-runbook.md`
|
||||
|
||||
**Step 1: 写失败 E2E 用例**
|
||||
|
||||
```python
|
||||
def test_agent_chat_text_image_audio_document_flow():
|
||||
assert False
|
||||
```
|
||||
|
||||
**Step 2: 运行并确认失败**
|
||||
|
||||
Run: `PYTHONPATH=backend/src uv run pytest backend/tests/e2e/test_agent_chat_flow.py -v`
|
||||
Expected: FAIL。
|
||||
|
||||
**Step 3: 写最小实现与文档补充**
|
||||
|
||||
```markdown
|
||||
- bootstrap gate 执行顺序
|
||||
- agent_chat 验证命令
|
||||
```
|
||||
|
||||
**Step 4: 全量验证**
|
||||
|
||||
Run: `make runtime-bootstrap-gate`
|
||||
Expected: bootstrap 通过。
|
||||
|
||||
Run: `PYTHONPATH=backend/src uv run pytest backend/tests/unit/core/agent_chat -v`
|
||||
Expected: PASS。
|
||||
|
||||
Run: `PYTHONPATH=backend/src uv run pytest backend/tests/integration -k agent_chat -v`
|
||||
Expected: PASS。
|
||||
|
||||
Run: `PYTHONPATH=backend/src uv run pytest backend/tests/e2e/test_agent_chat_flow.py backend/tests/e2e/test_agent_chat_recent_session_home.py -v`
|
||||
Expected: PASS。
|
||||
|
||||
Run: `PYTHONPATH=backend/src uv run pip check`
|
||||
Expected: no broken requirements。
|
||||
@@ -175,6 +175,23 @@ curl -sS -X PATCH http://127.0.0.1:8000/api/v1/profile/me \
|
||||
-d '{"username":"demo2","bio":"hello"}'
|
||||
```
|
||||
|
||||
## Agent Chat 验证
|
||||
|
||||
```bash
|
||||
# 1) 基础门禁(迁移 + init-data)
|
||||
make runtime-bootstrap-gate
|
||||
|
||||
# 2) 运行 agent_chat 相关单测/集成/E2E
|
||||
PYTHONPATH=backend/src uv run pytest backend/tests/unit/core/agent_chat -v
|
||||
PYTHONPATH=backend/src uv run pytest backend/tests/integration -k agent_chat -v
|
||||
PYTHONPATH=backend/src uv run pytest backend/tests/e2e/test_agent_chat_flow.py backend/tests/e2e/test_agent_chat_recent_session_home.py -v
|
||||
|
||||
# 3) 核心接口 smoke
|
||||
curl -sS -X POST http://127.0.0.1:8000/api/v1/agent-chat/run \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{"message":"hello"}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 变更日志
|
||||
@@ -188,3 +205,4 @@ curl -sS -X PATCH http://127.0.0.1:8000/api/v1/profile/me \
|
||||
| 2026-02-25 | 补充迁移防遗漏规则:容器迁移命令统一追加 --build;开发调试优先使用本地 CLI 一次性迁移脚本 |
|
||||
| 2026-02-25 | Auth 注册切换为 OTP 三段式:signup/start、signup/verify、signup/resend;邮件模板改为纯验证码展示 |
|
||||
| 2026-02-25 | 清理未使用配置类:删除 WebSettings/GunicornSettings/WorkerSettings/WorkerGroupSettings(脚本仍使用环境变量启动服务) |
|
||||
| 2026-02-25 | 新增 Agent Chat 验证章节:bootstrap gate、分层测试命令与 run 接口 smoke 示例 |
|
||||
|
||||
Reference in New Issue
Block a user