6.4 KiB
6.4 KiB
| title | date | category | module | problem_type | component | symptoms | root_cause | resolution_type | severity | tags | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 日历能力缺失修复 + UI 布局优化 + 会话 404 处理 | 2026-06-28 | docs/solutions/logic-errors | tools/calendar_tool, server/app, server/routes/portal, frontend/stores/chat | logic_error | service_object |
|
logic_error | code_fix | high |
|
日历能力缺失修复 + UI 布局优化 + 会话 404 处理
Problem
用户报告三个问题:(1) AI 无法响应定时提醒请求("下周一提醒我准备项目启动会材料"),回复"我没有这个能力";(2) 右侧面板收起按钮未垂直居中;(3) 会话 404 错误导致 UI 异常。代码审查发现 16 个问题(1 P0、2 P1、6 P2、7 P3),核心根因是 CalendarTool 未正确接入 ReAct agent 的工具链。
Symptoms
- 日历能力完全失效(P0):
calendar_tool.py第 164-175 行构建了reminder_rules,但第 190-203 行调用service.create_event时未传递该参数——提醒规则被静默丢弃,提醒永远不会触发。 - LLM 看不到 calendar 工具(P2):
defaultagent 在 CalendarTool 注册前创建,缓存的工具集和系统提示中都没有calendar。即使后续注册了 CalendarTool 到tool_registry,agent 的_system_prompt已固化。 - 系统提示重复段落(P2):附加 CalendarTool 时读取已含"## 可用工具"的
_system_prompt作为base_prompt,再拼接新的"## 可用工具",产生两个重复段落。 - 删除会话状态泄漏(P1):
deleteConversation未调用markConversationDone,pending 状态残留。后端迟到的 result 事件可能被错误路由到新会话。 - 404 级联(P1):多个会话过期时,404 处理器递归调用
selectConversation无保护,导致 N 次顺序网络请求和 UI 卡顿。 - monitor 标签页布局失效(P2):容器 div 缺少
display: flex; flex-direction: column,子元素的flex: 1和overflow-y: auto不生效。
Root Cause
日历能力断裂的完整因果链
lifespan启动时先创建defaultagent(第 177 行),此时 CalendarTool 尚未注册- agent 的
_system_prompt在创建时通过_build_tools_description固化,不含 calendar 工具 - 日历子系统初始化(第 438 行)注册 CalendarTool 到
app.state.tool_registry - 但
defaultagent 已缓存的_tool_registry和_system_prompt不会自动更新 - LLM 在 ReAct 循环中看不到 calendar 工具,回复"我没有这个能力"
- 即使 LLM 调用了 calendar 工具,
reminder_rules未传入create_event,提醒不会触发
修复方案
- P0:在
calendar_tool.py的create_event调用中添加reminder_rules=reminder_rules参数;添加reminder_offset_minutes范围校验(0-43200) - P2:在
app.py中注册 CalendarTool 后,将其追加到defaultagent 的_tool_registry,剥离已有"## 可用工具"段落后重新拼接系统提示 - P1:
deleteConversation添加markConversationDone(id)清理 pending 状态,跳过is_local会话的 API 调用,删除当前会话时自动切换 - P1:404 处理器添加
_is404Recovering递归保护标志 - P2:
SystemMonitorPanelmonitor 容器添加display: flex; flex-direction: column - P3:
PortalConnectionManager.send_json遍历前快照列表;WSconnected无条件清除is_local;移除if(calendarStore)死代码
Verification
ruff check通过(修复了gui_modeF821 未定义错误)pytest tests/unit/calendar/— 109 passed(含 2026-06-29 新增的 2 个notify_callback广播回归测试)npm run typecheck— 通过
Files Changed
| 文件 | 修复内容 |
|---|---|
src/agentkit/tools/calendar_tool.py |
P0: 传递 reminder_rules + 范围校验 |
src/agentkit/server/app.py |
P2: 附加 CalendarTool 到 default agent + 剥离重复段落 + 修复 gui_mode F821 |
src/agentkit/server/frontend/src/stores/chat.ts |
P1: deleteConversation 清理 + 404 递归保护 + WS connected 清除 is_local + 移除死代码 |
src/agentkit/server/routes/portal.py |
P3: send_json 快照列表 |
src/agentkit/server/frontend/src/components/layout/SystemMonitorPanel.vue |
P2: monitor flex 布局 |
Related Issues
本 doc 修复的是"agent 看不到 calendar 工具 + reminder_rules 被丢弃"的根因。同一症状("agent 创建日历事件后 UI 看不到")还有两个不同的根因,调查时需同时排查:
- JWT secret 未设置导致 dev mode user_id 丢失 — AuthMiddleware 处于 dev mode,
current_user.user_id=None,DB 写入用 LLM hallucinate 的user_id,UI 查询用None→ 不匹配 - Calendar events created via agent chat do not refresh the calendar UI —
CalendarService.create_event创建成功后未广播calendar_event_createdWS 消息,前端有 handler 但收不到
预防规则:变更型 service 方法(create_event / update_event / delete_event)若前端有对应视图,必须在成功提交后广播 WS 事件,不能依赖下次 GET 轮询。notify_callback 注入模式是本项目的既定做法(见 CONCEPTS.md → Service Broadcast Callback)。