--- title: "日历能力缺失修复 + UI 布局优化 + 会话 404 处理" date: 2026-06-28 category: docs/solutions/logic-errors module: tools/calendar_tool, server/app, server/routes/portal, frontend/stores/chat problem_type: logic_error component: service_object symptoms: - "LLM 回复'我没有提醒功能',不调用 calendar 工具创建事件" - "calendar_tool 构建 reminder_rules 但未传入 service.create_event,提醒规则被静默丢弃" - "default agent 在 CalendarTool 注册前创建,系统提示中缺少 calendar 工具描述" - "系统提示出现重复的 '## 可用工具' 段落" - "deleteConversation 未清理 pendingConversations,删除进行中的会话导致状态泄漏" - "404 处理器递归调用 selectConversation 无保护,多会话过期时级联触发 N 次网络请求" - "右侧面板收起按钮未垂直居中" - "SystemMonitorPanel monitor 标签页缺少 flex 布局,滚动和垂直居中失效" - "WS connected 事件在 ID 不变时未清除 is_local 标志" - "gui_mode 变量在 lifespan 中未定义(F821)" root_cause: logic_error resolution_type: code_fix severity: high tags: [code-review, calendar, reminder, websocket, system-prompt, ui-layout, state-management] --- # 日历能力缺失修复 + 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)**:`default` agent 在 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 ### 日历能力断裂的完整因果链 1. `lifespan` 启动时先创建 `default` agent(第 177 行),此时 CalendarTool 尚未注册 2. agent 的 `_system_prompt` 在创建时通过 `_build_tools_description` 固化,不含 calendar 工具 3. 日历子系统初始化(第 438 行)注册 CalendarTool 到 `app.state.tool_registry` 4. 但 `default` agent 已缓存的 `_tool_registry` 和 `_system_prompt` 不会自动更新 5. LLM 在 ReAct 循环中看不到 calendar 工具,回复"我没有这个能力" 6. 即使 LLM 调用了 calendar 工具,`reminder_rules` 未传入 `create_event`,提醒不会触发 ### 修复方案 1. **P0**:在 `calendar_tool.py` 的 `create_event` 调用中添加 `reminder_rules=reminder_rules` 参数;添加 `reminder_offset_minutes` 范围校验(0-43200) 2. **P2**:在 `app.py` 中注册 CalendarTool 后,将其追加到 `default` agent 的 `_tool_registry`,剥离已有"## 可用工具"段落后重新拼接系统提示 3. **P1**:`deleteConversation` 添加 `markConversationDone(id)` 清理 pending 状态,跳过 `is_local` 会话的 API 调用,删除当前会话时自动切换 4. **P1**:404 处理器添加 `_is404Recovering` 递归保护标志 5. **P2**:`SystemMonitorPanel` monitor 容器添加 `display: flex; flex-direction: column` 6. **P3**:`PortalConnectionManager.send_json` 遍历前快照列表;WS `connected` 无条件清除 `is_local`;移除 `if(calendarStore)` 死代码 ## Verification - `ruff check` 通过(修复了 `gui_mode` F821 未定义错误) - `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 丢失](file:///Users/Chiguyong/Code/Fischer/fischer-agentkit/docs/solutions/integration-issues/jwt-secret-dev-mode-user-id-mismatch.md) — 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](file:///Users/Chiguyong/Code/Fischer/fischer-agentkit/docs/solutions/ui-bugs/calendar-agent-create-no-refresh.md) — `CalendarService.create_event` 创建成功后未广播 `calendar_event_created` WS 消息,前端有 handler 但收不到 **预防规则**:变更型 service 方法(`create_event` / `update_event` / `delete_event`)若前端有对应视图,必须在成功提交后广播 WS 事件,不能依赖下次 GET 轮询。`notify_callback` 注入模式是本项目的既定做法(见 [CONCEPTS.md → Service Broadcast Callback](file:///Users/Chiguyong/Code/Fischer/fischer-agentkit/CONCEPTS.md))。