75 lines
5.1 KiB
Markdown
75 lines
5.1 KiB
Markdown
---
|
||
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/` — 98 passed
|
||
- `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 布局 |
|