Version: 0.6.5.dev.260316

 feat(agent): 通用分流接入随口问图编排,修复任务查询条数与重复输出问题

- ♻️ 将 Agent 路由升级为通用 `action` 分流机制,统一支持 `chat` / `quick_note_create` / `task_query`
- 🧩 新增 `taskquery` 子模块并落地图编排链路:`plan -> quadrant -> time_anchor -> tool_query -> reflect`
- 🔧 在图内接入 `query_tasks` 工具调用,支持自动放宽检索条件与反思重试,最多重试 2 次
- 🚪 保持 `/agent/chat` 作为多合一入口,不额外新增任务查询 HTTP 接口
- 🪄 修复“随口问”场景下的双重列表输出问题:LLM 仅保留简短前缀,任务列表统一由后端进行确定性渲染
- 🎯 修复显式数量约束失效问题:支持提取“来一个”“前 3 个”“top5”等数量表达,并将其锁定为 `limit`
- 🛡️ 防止在重试或放宽检索阶段改写用户显式指定的数量约束
-  补充并更新测试,覆盖路由解析、数量提取、`limit` 生效及重复输出等关键场景

📝 docs: 更新随口问链路文档与决策记录

- 📚 更新 README 5.4,新增/修订随口问链路 Mermaid 图
- 🧭 新增随口问功能决策记录 FDR
This commit is contained in:
Losita
2026-03-16 22:30:45 +08:00
parent 84371e2ff8
commit 09dca9f772
16 changed files with 2371 additions and 105 deletions

View File

@@ -23,14 +23,34 @@ func TestParseQuickNoteRouteControlTag_QuickNote(t *testing.T) {
if decision == nil {
t.Fatalf("decision 不应为空")
}
if decision.Action != route.ActionQuickNote {
t.Fatalf("action 解析错误,期望=%s 实际=%s", route.ActionQuickNote, decision.Action)
// 兼容逻辑:历史 quick_note 会被统一映射到 quick_note_create。
if decision.Action != route.ActionQuickNoteCreate {
t.Fatalf("action 解析错误,期望=%s 实际=%s", route.ActionQuickNoteCreate, decision.Action)
}
if strings.TrimSpace(decision.Reason) == "" {
t.Fatalf("reason 不应为空")
}
}
// TestParseRouteControlTag_TaskQuery
// 目的:验证通用分流中 action=task_query 的控制码可稳定解析。
func TestParseRouteControlTag_TaskQuery(t *testing.T) {
nonce := "taskquerynonce"
raw := `<SMARTFLOW_ROUTE nonce="taskquerynonce" action="task_query"></SMARTFLOW_ROUTE>
<SMARTFLOW_REASON>用户在查最紧急任务</SMARTFLOW_REASON>`
decision, err := route.ParseRouteControlTag(raw, nonce)
if err != nil {
t.Fatalf("解析失败: %v", err)
}
if decision == nil {
t.Fatalf("decision 不应为空")
}
if decision.Action != route.ActionTaskQuery {
t.Fatalf("action 解析错误,期望=%s 实际=%s", route.ActionTaskQuery, decision.Action)
}
}
// TestParseQuickNoteRouteControlTag_NonceMismatch
// 目的:确保 nonce 不匹配时直接报错,避免把非本次请求的控制码当作有效路由。
func TestParseQuickNoteRouteControlTag_NonceMismatch(t *testing.T) {