PicoBot/docs/CHANGELOG.md

48 KiB
Raw Permalink Blame History

变更日志

本文件记录 Picobot 各版本的显著变更,遵循 Keep a Changelog 风格。

[0.4.4] - 2026-08-18

较 [0.4.3] 的 8 个 commit 迭代,聚焦 全项目扫描修复话题列表刷新提速前端竞态与浮层修复 三大方向。

性能优化

话题列表刷新提速

  • token 统计改为增量维护列(topics 表新增统计列并由运行期增量归因),替代每次刷新的全表聚合,话题列表刷新显著变快;配套 129 行迁移与 262 行单测。
  • 新建/删除/重命名话题同样走 spawn_blocking 移出 async worker与批量操作统一提速。

日志降噪

  • 会话消息投递成功日志由 info 降级为 debug减少高频运行时日志输出。

修复

存储数据一致性(全项目扫描 F0

  • 修复外键约束失效根因:切换/删除话题与 http 清理路径补全被动删除(级联删除内存态与关联行),避免遗留孤立行导致外键约束在批量删除时触发失败。
  • 计数一致性:删除后按活 COUNT 重算 sessions/topicsmessage_count,新增 106 行回归单测覆盖。

并发健壮性

  • bash 取消泄漏:取消时正确终止子进程并将运行中标记回收,避免 bash 工具取消后进程残留、占住资源。
  • 子代理队列阻塞subagent 等待队列在取消/异常路径下正确清理修复子代理完成通知丢失导致主代理等待队列长期阻塞。task runtime 重构 158 行并补充取消语义。

前端竞态与浮层

  • list_topics / switch_topic 响应乱序覆盖:为话题列表与视图切换增加请求序号/响应对账,过期响应不再覆盖新状态,修复快速切换话题时列表与消息被旧响应覆盖。
  • 图片放大与工具详情浮层修复被相邻内容覆盖及定位错乱问题MessageBubble 图片放大、ToolDetailModal 浮层)。

指标可观测

  • 初始化时即注册基线 counter避免各指标启动后首次渲染为空、直到首个事件才出现。

[0.4.3] - 2026-08-18

0.4.2 的 14 个 commit 迭代,聚焦 长话题历史分页全链路性能优化(两批)长会话稳定性兜底对抗性审查修复 四大方向。

新增功能

长话题历史 keyset 分页加载

  • 后端新增 load_messages_for_topic_page,按 seq < cursor + limit(session_id, seq) 复合索引替代 OFFSET 深翻页,ChatMessage 增加 seq 游标字段,支持超大量历史消息。
  • 前端触顶增量加载:批次缓存在 pendingHistoryRef,收到 topic_history_end 一次性去重 prependscrollTop 按新增高度补偿锚定原头部消息不足一屏自动补页loading 超时 10s 自愈;流式输出中加载历史不清空流式累加器。

设置页字段 UX 改进

  • 设置页字段提示改为问号图标悬停气泡,避免长说明文本挤占布局宽度。

子代理运行时长配置化

  • max_run_secs 接入 AgentConfigconfig.jsonagents 段),不再硬编码;From 透传与所有字面构造点已补齐。
  • cli init 写入 agent 路径时保留既有 max_run_secs 而非重置默认。
  • max_run_secs 默认值由 360060 分钟)改为 0不限制避免长任务被单次执行时间上限中断需要时可在 config.jsonagents 段显式配置。

性能优化

第一批性能修复

  • 飞书通道 HTTP client新增 connect/全局超时token 刷新与 reaction 叠加紧超时,消除无限挂起风险。
  • SQLiteWAL 模式下 synchronous=NORMALper-connection with_init6 处批量写入循环改用 prepare_cached 复用预编译语句,写入吞吐显著提升。
  • web_fetch:复用长生命周期 HTTP client响应体改为流式限长读取上限=字符限额×4封顶 32MB替代全量读完再截断。
  • 前端:App.tsx effect/callback 依赖由 subAgentView 对象改为 subAgentTaskId 原始值,修复子代理流式期间 token 统计 500ms 定时器被每帧重置永不触发;MessageBubble / ToolDetailModalReactMarkdown components 与 remarkPlugins 提升为模块级常量,避免流式渲染期间每帧重建。

第二批性能修复

  • 同步阻塞操作附件处理、历史加载、scheduler/memory_search 的 SQLite 调用)全部移入 spawn_blocking,避免占用 async worker 线程。
  • LLM Provider reqwest::Client 按超时配置缓存复用,减少 TLS/连接建立开销。
  • Agent loop图片过滤加廉价预判避免全量深拷贝请求克隆改借用工具定义 Arc 化减少大对象复制。
  • 定向 COUNT / LIMIT 1 查询替代全量加载计数(wait_coordinatortask session 重建)。
  • 前端:面板/侧栏/聊天组件 memo 化;merged_tool 对象按值复用缓存;流式 delta rAF 节流批量 flushuseMemo 缓存分组排序结果。

MCP 可观测

  • MCP tool 调用全链路往返耗时入口→MCP server→返回新增 debug 日志,便于定位慢调用。

修复

长会话后新消息无响应(核心稳定性)

  • 发送 ExecutionCompleted 前惰性清理僵尸 running 子代理DB 标记 running 但执行任务已消失),解除 pending 消息长期阻塞。
  • Processor panic 路径补发 error 通知 + ExecutionCompleted,防止前端永久 loading。
  • Agent 单轮增加墙钟预算 max_run_secs,超时优雅退出并释放 topic 串行锁。
  • Topic 串行锁等待增加 info/warn 日志,长等待可观测。
  • Sanitize 清理结果回写 DBdelete_messages_by_ids),消除每次历史加载的重复修复开销。
  • Storage 新增 keyset 分页与按 ID 批量删除的单元测试,回归有保障。

对抗性审查修复

  • 子代理 spawn 顺序调整为「先注册 cancel_registry → 再写 DB running 记录」,消除 reap 误杀刚启动子代理的微秒级竞态窗口。
  • delete_messages_by_ids 删除后按活 COUNT 重算 sessions/topicsmessage_count,修复计数列漂移。

存储数据正确性

  • 归一化历史前缀累积污染的会话 ID一次性迁移修复会话 ID 被多次加前缀导致查询找不到对应行。
  • 清理旧版本遗留的空 CLI 会话,list_sessions 日志级别从 info 降级 debug减少运行噪音。

前端交互

  • 回到顶部改用 rAF 自驱动动画,修复消息多时平滑滚动被 virtualizer 纠正写入打断停在半路。
  • 视图切换滚动位置丢失:动态行高缓存按消息 id 键控,避免子智能体视图高度污染主视图,恢复后两帧 rAF 内不回写保存位置。
  • 顶部按钮链式贴顶:动画落定显式续链,分页 prepend 时贴到新顶部直到真正首条消息,关闭 virtualizer 行高修正的 scrollTop 自动补偿;用户滚动输入/回底/待办高亮/视图切换/分页耗尽时清除贴顶意图。

Provider 请求兼容

  • Anthropic 型 provider max_tokens 留空兜底从默认值提高至 8192。
  • 模型未配置 Temperature 时,请求体 JSON 不再携带该字段,避免部分供应商对显式 null/空值报错。

Windows 终端卡死

  • 启动时禁用 Windows 控制台 QuickEdit 模式并改为非阻塞日志写入,修复 stdout 输出被 QuickEdit 选中阻塞、需按回车才继续的历史顽疾。

0.4.2 - 2026-08-17

0.4.1 的 8 个 commit 迭代,聚焦 安全漏洞修复全链路性能优化前端健壮性 三大方向。

新增功能

部署安全加固

  • 前端生产构建产物与配置文件中,输出/展示时排除所有 token 相关敏感字段(api_key/auth_token/access_token 等),防止误写入日志或静态文件泄露凭据。

性能优化

前端流式渲染性能(子代理场景 P0

  • 子代理 stream_deltarequestAnimationFrame 批处理 delta 合并,避免每 token 一次 setState 触发子树重渲染。
  • 消息槽MessageBubble / SubagentCardReact.memo 包裹,流式期间跳过未变更项的 diff。
  • base64 附件解码改为分块处理,大文件解码时不阻塞主线程。

Bash 输出增量匹配与 HTTP 工具性能

  • Bash 增量匹配:每一次增量输出原先用 O(n²) 算法寻找已有匹配段,改为基于游标增量扫描,长 stdout 场景 CPU 占用显著下降。
  • Bash 缓冲上限:新增流式缓冲大小限制(默认 2MB超出时按行截断防止异常大输出撑爆内存。
  • http_request 复用 reqwest::Client(之前每次调用新建),建立连接池;响应体保持流式分块读取并累加限长。

数据库热路径优化

  • 热路径同步 SQLite 操作(get_topic_message_countload_messages_for_topic_full 等)改 tokio::task::spawn_blocking,解除 tokio worker 线程阻塞,多 topic 并行场景吞吐提升。
  • 定向查询优化:只查询需要的列(不加载 tool_calls_json / content 等大字段),减少 DB → 内存拷贝。

修复

安全漏洞

  • 升级 quinn-proto 0.11.14 → 0.11.16,修复 RUSTSEC-2026-0185 远程内存耗尽漏洞QUIC 握手畸形数据包导致的无界内存分配)。
  • npm audit fix 修复前端 4 个高危依赖漏洞:vite / postcss / undici / nanoid

子代理运行中状态丢失

  • 历史加载时对账 task running 占位:刷新页面或切换话题后,子代理卡片不再因 running 占位缺失而永远显示「运行中」。

重构

  • 清理 clippy 存量告警:替换不必要的 unwrap() 为 match/?,去除多余 .clone(),删除冗余分支与死代码。

0.4.1 - 2026-08-14

0.4.0 的 17 个 commit 迭代,聚焦 前端视觉重构话题级模型选择定时任务可靠性缓存占比统计调度器并发 五大方向。

新增功能

前端视觉重构(对齐 deepseek-harness 设计语言)

  • 重构前端视觉与三栏布局,对齐 deepseek-harness 设计语言。
  • 通道/会话切换移至设置页新增 ConnectionTab,连接状态上移 Logo 行,窄侧栏支持 compact 降级。
  • 工具卡片统一格式:子智能体显示「工具名 · 任务描述」,移除下方徽章与时间。

话题级模型选择

  • 后端持久化与 APItopics 表新增 provider / model 列 + 双写内存缓存。
  • 模型解析链:topic > session > expert > config 逐级覆盖;TaskToolResult 附带实际使用的模型。
  • 前端:ModelSelector 话题级化(topicId 透传 + 竞态防护),隐藏专家系统开关。
  • Task 卡片差异显示子代理模型名。

per-topic 输入草稿记忆

  • 切换话题时暂存当前草稿、切回时恢复,localStorage 持久化,删除话题时清理。

缓存占比统计

  • 新增缓存占比统计(cached_tokens),聚合查询收敛到共享列清单。
  • Provider 缓存命中诊断日志,兼容两种 usage 缓存格式解析。

定时任务可靠性

  • 静默定时任务执行后增加主动送达提示,避免结果静默丢失。
  • 调度器重构:任务执行移出 tick 循环,worker_queue_capacity 并发约束生效,实现非阻塞派发。

修复

  • 定时任务空历史执行:执行前自动补齐 topic修复 agent 空历史执行问题。
  • 前端缓存占比恒为 0TopicTokenStats 补齐 cached_tokens 字段(协议字段缺失)。
  • 通道失效回退:通道/会话切换迁移时修复通道失效后的自动回退。
  • 子代理完成状态转发:修复子代理完成状态在前端转发链路丢失。

内部改进

  • 缩减 INFO 日志量,高频诊断日志降级或删除。

测试

  • 定时任务 topic 补齐与消息送达回归测试。
  • 调度器非阻塞派发与并发容量回归测试。

0.4.0 - 2026-08-13

0.3.5 的 3 个 commit 迭代,聚焦 异步子代理 v8 架构/stop 取消流程前端子代理状态展示 三大方向。异步子代理 v8 为里程碑式架构升级:子代理执行从「父子同步串行」改为「后台异步 + 显式等待」,显著提升多子代理并行吞吐与父代理可控性。

新增功能

异步子代理 v8 架构(父代理不再阻塞)

  • 双通道异步通信:子代理结果走独立队列 sub_done_q(直达 wait不绕 SQLite → bus → reload用户消息复用现有 buschannel 适配器零改动。
  • wait_for_subagents 工具(新增 src/tools/wait_tool.rsselect! 等待子代理完成 / 用户消息 / 超时,支持 try_drain 批量消费task tool_result 返回 running + 引导提示,引导 LLM 调用 wait。
  • wait_coordinator(新增 src/gateway/wait_coordinator.rs):释放/重获取 serial_lock 的 in-tool waiting 模式,替代旧的 break-exit 方案;is_waiting 持锁后判断,无 TOCTOU。
  • task 工具异步 spawn 路径src/tools/task/runtime.rs +488CancellationToken 注册表 + RAII guard + Semaphore 并发限流。
  • 子代理完成回调携带 pending_task_ids 列表LLM 据此判断全局进度并决策下一步。
  • 崩溃恢复:启动时标记 running -> interruptedhistory 加载时对账占位;新增 pending_subagents 表 + 条件 UPDATE + mark_all_running_as_interrupted
  • 嵌套层级:仅顶层异步,避免复杂度爆炸。
  • 新增 docs/ASYNC_SUBAGENT_DESIGN.md 设计文档,记录 v8 三个核心不变量、wait 模式、取消机制与崩溃恢复策略。

修复

/stop 取消流程

  • wait_coordinator select! 添加 cancel 分支,完整清理状态。
  • ToolContext 注入 cancel_rxwatch::Receiver clone
  • agent_loop 工具执行 select! 对 wait 工具跳过竞速,防止 drop coordinator 清理逻辑。
  • 子代理完成状态通过 execution_completed metadata 传播。

前端子代理状态显示与渲染崩溃

  • MessageBubbletaskStatusConfig 补全 running/completed/cancelled/interrupted 状态配色,修复未知状态访问 undefined.borderColor 导致的白屏崩溃;添加安全回退到 failed 状态。
  • main.tsx:新增 ErrorBoundary 捕获 React 渲染错误,防止白屏并提供错误详情与恢复入口。
  • useMessages:收到子代理 execution_completed 事件后,更新主视图中 task tool result 占位消息的 status 字段running → completed/failed/cancelled消除永久黄色转圈。
  • protocol.tsExecutionCompleted 接口新增 subagent_statussubagent_summary 字段。

测试

  • src/tools/task/runtime.rs 测试模块持续扩充,覆盖异步 spawn / 取消 / 并发限流等核心路径。

0.3.5 - 2026-08-12

0.3.4 的 7 个 commit 迭代,聚焦 可观测性并发性能外部集成健壮性 三大方向。

新增功能

MCP 工具调用超时保护

  • McpToolWrapper 适配层用 tokio::time::timeout 包裹 call_tool,防止外部 MCP server 挂起导致 agent loop 无限阻塞。
  • 超时时间通过 config.mcp_tool_timeout_secs 配置(默认 300 秒0=不超时)。
  • 前端 McpTab 设置页提供输入框。

端到端可观测性整改

  • trace_id 全链路传播BusToolCallEmitter / SubAgentEmitter / processor 全链路设置 trace_id。
  • AgentEnd 指标配对:补发 5 个 cancel/defensive 路径的 AgentEnd 事件,闭合 AgentStart 指标。
  • LLM 计时修正attempt_start 移入 retry 循环,排除退避等待时间。
  • /metrics auth:非 loopback 部署时纳入 Bearer token 校验。
  • recorder 复用OnceLock 缓存 PrometheusHandle,热重启后不再返回 503。
  • 结构化日志:新增 tracing_ctx + JSON 日志格式支持。

修复

压缩期间 session 锁阻塞新建话题

  • 压缩任务在 LLM 调用2-5s期间持有 session 锁,阻塞 create_session 命令获取锁执行 switch_topic,导致新建话题后列表刷新延迟。
  • 将压缩重构为 4 阶段:
    1. 短暂持锁:读取 history/compressor/store/session_id/provider_config
    2. 释放锁LLM 压缩调用2-5s
    3. 释放锁DB 写入store 为 ArcDB 层自带事务保护)
    4. 短暂持锁reload 内存历史
  • 并发安全:同 topic 由调用方的 per-topic serial lock 保证串行;不同 topic 完全并行不受影响。

MCP 前端空输入重置为不超时

  • 清空输入框时回退到默认值 300 而非 00 表示不超时,与用户预期不符)。
  • 新增两个 tokio 测试覆盖有超时和无超时error pass-through路径。

移除 ChatContainer key remount 修复新建话题列表刷新延迟

  • 话题切换时 key={selectedTopic} 导致整个 ChatContainer 子树卸载重建,触发 ExpertSelector / ModelSelector 重新挂载并发起 3 次冗余 HTTP 请求(getSelectedExpert / listModelOptions / 模型选择刷新),引入 200-500ms 延迟。
  • 改用 topicId prop 透传话题 ID
    • App.tsx:移除 keyviewKey 纳入 selectedTopic 保持各话题独立滚动位置。
    • ChatContainer:新增 topicId prop 透传给 MessageInput
    • MessageInput:监听 topicId 变化清空草稿,替代原 key remount 重置机制。

Panic 安全增强

  • agent_loop.rs / processor.rs:用 catch_unwind 隔离工具执行和消息处理的 panic归一化为错误返回LLM 可见错误并自我纠正,防止用户消息被静默丢弃。
  • utils.rs:新增 panic_payload_message() 从 panic payload 中提取可读消息,支持 &str / String / 其他类型降级。
  • bus/message.rs:修复 sanitize_incomplete_tool_call_sequences 两阶段删除索引未全局排序导致的越界 panicPhase 1 降序 + Phase 1.5 升序 → 合并后必须重新排序)。

计算器健壮性

  • 拒绝 "NaN" / "inf" 等非有限输入,防止 sort_bypartial_cmp().unwrap() panic。
  • 修复阶乘溢出:上限从 170 降至 3435! 超出 u128::MAX),改用 checked_mul 替代 unchecked 乘法。
  • evaluate 表达式拒绝非有限结果(如 1/0 → inf、0/0 → NaN
  • 新增 7 个 tokio 测试覆盖所有边界场景。

测试

  • MCP 超时路径新增 2 个 tokio 单元测试。

0.3.4 - 2026-08-10

0.3.3 的 9 个 commit 迭代,聚焦 安全加固健壮性防御代码质量优化 三大方向。

新增功能

顶栏显示后端版本号

  • 复用现有 /health 端点返回的 CARGO_PKG_VERSION,避免在 package.json 重复维护版本号。
  • 前端挂载时拉取一次,失败则不显示徽标。

文件工具路径限制(最小权限原则)

  • 默认行为:文件读写编辑限制在当前工作目录内。
  • 新增配置项:tools.allowed_dirs(白名单目录列表)+ tools.file_access_unrestrictedopt-in 全局放开)。
  • 共享 resolve_file_path() 函数,使用 canonicalize() 防御符号链接与 .. 路径遍历。
  • 前端:设置页 > 工具标签新增"文件访问"卡片,含开关与目录标签编辑器。
  • 向后兼容:旧配置默认 cwd 限制(serde(default))。

安全修复

Shell 会话生命周期管理

  • GatewayState 持有 Arc<ShellSessionManager> 引用,网关关闭时(ctrl_c 和重启两条路径)调用 shutdown()
  • 新增防御性 Drop impl泄露会话时打 warn 日志。
  • 子进程 kill 添加 5s 超时,防止无限阻塞。

HTTP 工具 OOM 防护

  • WebFetchTool / HttpRequestTool 实现流式读取响应体(futures_util::StreamExt),防止大响应撑爆内存。
  • 检查 Content-Length 头,分块读取并累计校验大小。
  • 默认限制:WebFetch 200KBHttpRequest 4MB。

TimeTool 重复类型转换修复

  • 移除 time.rs 中重复的 u32::try_from 调用(复制粘贴错误)。

消除 16 处 unreachable! panic 风险

  • 15 个 command handler 文件中 _ => unreachable!() 替换为 _ => Err(CommandError::new(...)),防止 Command 枚举新增变体时运行时 panic。

配置占位符校验

  • 新增 validate_no_unresolved_placeholders(),拒绝包含未解析 <ENV_VAR>\ 占位符的配置。
  • 防止字面占位符字符串被当作真实 API key 发送到 LLM provider难以诊断的 401 根因)。
  • 首次运行跳过校验(create_default_config 模板场景)。

修复

切换话题后滚动到最新消息

  • 修复切换话题后不滚动到最新消息的问题。
  • 跟随意图仅由用户输入wheel/touch/key推翻程序触发的滚动不会打断用户浏览。
  • 将虚拟化 totalSize 纳入滚动依赖,使测量收敛到真实底部。

WebSocket 重连竞态修复

  • 修复 URL 切换时的 WebSocket 重连竞态问题。
  • 事件处理引入代际同一性守卫,孤儿 socket 事件整体忽略。
  • disconnect 恰好触发一次 onDisconnect,避免重复清理。

删除话题竞态修复

  • 修复删除选中话题时的竞态问题。
  • 乐观移除本地话题并以 null 作为唯一无选择哨兵。
  • 杜绝基于过期列表重选已删除话题。

重构

8 处 quick wins

  • shared.rs 提取 channel/cli 适配器公共逻辑,消除 124 行重复代码。
  • http_utils.rs 提取 HTTP 响应读取公共逻辑,http_request.rsweb_fetch.rs 共享实现。
  • bash.rs / shell_session.rs 简化冗余逻辑。
  • gateway/mod.rs 优化路由分支。
  • storage/mod.rs 精简查询逻辑。
  • mcp/client.rs 增强错误处理。

内部改进

  • 修复 release 构建编译器警告:补全 regex::Captures 显式生命周期标注,cfg(debug_assertions) 条件化仅 debug 使用的变量,AnthropicProvider::llm_timeout_secs 添加 cfg_attr allow(dead_code)
  • 飞书 channel 时间戳去重改用 crate::utils::current_timestamp(),消除 unwrap() panic 点并统一日志格式。
  • 批量更新依赖 patch 版本chrono, clap, anyhow, bytes 等),无 breaking change。

测试

  • cancel_manager.rs 新增 8 个单元测试,覆盖 register/cancel/remove/overwrite/list/cancel_all/drop-safety 核心路径。
  • session_pool.rs 新增 3 个单元测试,覆盖 is_scheduler_chat_id 路由逻辑。
  • 配置占位符校验新增 11 个单元测试,覆盖空值、小写、数字、去重、多占位符、首次运行、加载集成等边缘场景。

0.3.3 - 2026-08-07

0.3.2 的 12 个 commit 迭代,聚焦 前端渲染性能飞跃流式通信健壮性代码质量治理 三大方向。

新增功能

执行状态对账端点

  • 新增 GET /api/executions HTTP 端点,返回后端权威的执行中话题集合。前端 WebSocket 重连时调用此端点对账,修正断连期间丢失的 execution_completed 信号导致的状态漂移。

性能优化

消息列表虚拟化(长对话不再卡顿)

  • 引入 @tanstack/react-virtual 替换原 messages.map 全量渲染,只渲染视口内 + overscan=6 条消息DOM 节点数恒定。
  • measureElement 动态测量变高度消息(一行文本 vs 50 行代码块),estimateSize=120 提供初始估计,测量后自动校正。
  • Firefox 特殊处理 measureElementgetBoundingClientRect)。
  • 适配现有功能:自动滚到底部改用 virtualizer.scrollToIndexviewKey 滚动位置记忆保留;highlightedMessageId 先渲染目标项再 rAF 加 class流式 delta 不计数(消息条数不变)。
  • 性能对比500 条消息DOM 节点 10000+ → ~200首次渲染数百 ms → <16ms流式 diff 从全量列表降至仅可见项。

流式 delta 批处理(避免每 token 全数组拷贝)

  • streamingRef 累加 delta chunks + requestAnimationFrame 批量 flush将每秒数十次 O(n) 数组拷贝合并为一帧一次状态更新。
  • useMessages.ts 新增 streamingRef 累加器 + rAF 调度,所有 delta 只 push 到 refflushStreaming 批量落盘。
  • useChat.ts 5 处 setMessages([]) 改为 clearMessages(),切话题/会话/通道时重置流式 ref避免脏状态残留。
  • 复杂度O(n²·L) → O(n) 每帧。

改进

压缩阈值默认值下调

  • 工程化压缩阈值 threshold_ratio 从 0.7 下调至 0.550%LLM 压缩阈值 llm_compaction_threshold_ratio 从 0.5 下调至 0.330%)。
  • 降低触发门槛使压缩更积极介入,减少上下文溢出风险。同步更新相关注释、日志信息和前端 hint 文案。

修复

输入框/发送按钮状态按话题隔离

  • 将单一全局 isLoading 布尔值重构为按 topic_id 跟踪的 processingTopicIds 集合,isLoading 派生自当前选中话题是否在集合中。
  • 导航响应不再清空处理状态,切换话题后切回原话题仍能正确禁用输入。
  • 重连时通过 /api/executions 端点对账后端权威执行状态,修正断连期间丢失的 execution_completed 信号。

WebSocket 断连时清理流式状态

  • 修复 WebSocket 在流式输出中途断连时 streamingRefcontentChunks/index不重置导致重连后新消息 delta 追加到旧消息错误位置。
  • 修复链路:useWebSocketonDisconnect 回调 → useChatfinishStreaminguseMessagesfinishStreaming(重置 ref + flush pending chunks

会话消息泄露到定时任务视图

  • handleSchedulerMessageTier 1 路由)原先无条件吞掉所有可转换的 chat 消息,导致正在执行的实时消息被错误追加到调度器视图。
  • 修复:调度器视图只接收不带 topic_id 的历史加载消息;实时流式消息和带 topic_id 的实时消息 fall through 到主视图。

重构

公共工具函数提取与 DRY

  • 提取 src/utils.rs 公共工具函数模块,消除跨模块重复逻辑。
  • 修复飞书 channel 正则表达式重复编译问题,改为 Lazy<Regex> 一次编译。
  • 网关路由逻辑 DRY 化,减少 gateway/mod.rs 重复代码。
  • agent_loop / providers / config / storage 等多模块统一引用公共函数20 个文件受影响。
  • CI 新增安全审计步骤(cargo audit)。

内部改进

  • 存储模块应用 rustfmt 格式化(migrations.rs / row_mapping.rs / tests.rs)。
  • 降低 list_todos handler 与 gateway 转发日志级别为 debug减少子代理多次更新待办时的 INFO 日志噪音。
  • 删除临时优化计划文件 OPTIMIZATION_PLAN.md

测试

  • 新增 MessageList 虚拟化对抗性 smoke test5 个用例空消息渲染、100 条消息不崩溃、highlight 视口外不崩溃、viewKey 切换不崩溃、流式 rerender 不崩溃。
  • 新增流式断连对抗性测试2 个用例):stream_end 幂等性验证、多周期断连-重连循环下 finishStreaming 幂等验证。
  • 新增断连后新 delta 不污染旧消息测试(用例 17
  • 新增定时任务视图消息隔离测试(用例 16
  • 新增批量 delta 累加与 stream_endassistant_response 替换对抗性测试。

0.3.2 - 2026-08-06

0.3.1 的 7 个 commit 迭代,聚焦 上下文压缩可配置化网关安全加固并发模型优化错误防御性提升 四大方向。

新增功能

压缩算法关键参数暴露到设置页面

  • 将 4 个上下文压缩参数从硬编码提取到 config.json 顶层 compaction 节:
    • threshold_ratio0.7):工程化压缩触发阈值,占 context_window 的比例
    • llm_compaction_threshold_ratio0.5LLM 压缩触发阈值
    • truncate_max_tokens100工程化压缩时 tool 结果截断到的 token 数
    • preserve_count5LLM 三段压缩保留最旧/最新的 unit 数
  • 前端新增"上下文压缩"设置标签页Archive 图标4 个 number input 分两组展示。
  • ContextCompressor 内聚所有压缩参数,新增 with_compaction_config() 构造函数和 truncate_tool_results() 方法。
  • AgentLoop 通过调用 compressor.truncate_tool_results() 实现零参数耦合,压缩参数变更仅影响 ContextCompressor

HTTP API 认证与 CORS 防护

  • 新增 HTTP API 认证机制,未授权请求直接返回 401。
  • CORS 防护:明确指定允许的 origin阻止跨域未授权访问。
  • 修复密钥泄露风险:敏感信息不再出现在错误响应中。

改进

上下文压缩重构为两阶段+双阈值+三段保留

  • 两阶段压缩:工具调用完成后触发压缩流程,先用 prompt_tokens 判断 70% 阈值。
  • 阶段 1工程化压缩:截断非子代理 tool 结果到约 100 token仅改内存数据。
  • 阶段 2LLM 压缩):工程化压缩后若估算 token 仍超 50% 阈值,才调用 LLM 压缩。
  • 三段保留:保留最旧 5 个 unit + 中间段 LLM 摘要 + 最新 5 个 unit通过 HistoryUnit 原子单元保证 ToolRound 不被拆分。
  • LLM 压缩失败时降级为仅工程化压缩,不中断 agent loop。

迁移 parking_lot 锁并优化阻塞 IO 与内存管理

  • std::sync 锁替换为 parking_lot 实现,减少锁竞争开销。
  • 优化阻塞 IO 路径,避免热路径无谓阻塞。
  • 内存管理改进:减少不必要的克隆与分配。

修复

子智能体任务状态卡死

  • 修复已完成子智能体任务卡在"子智能体正在执行..."状态,前端无法正确展示结果。

飞书 channel 消息丢失

  • 修正飞书 reaction 语义,与飞书 API 规范对齐。
  • 增容 message bus 队列,避免高频消息场景下队列满导致最后一条消息丢失。

防御性错误处理

  • 替换 unreachable!() 宏调用为防御性错误返回,避免运行时 panic。
  • agent/gateway 关键路径改用 Result 传播错误,提升系统鲁棒性。

0.3.1 - 2026-08-05

0.3.0 的 19 个 commit 迭代,聚焦 历史压缩可追溯性token 统计准确性前端渲染稳定性工具执行可靠性网关吞吐优化 五大方向。

新增功能

历史压缩保留原消息(双视图分离)

  • 压缩流程从物理删除原消息改为标记位 is_compacted 分离两个视图:
    • LLM 视角load_messages_for_topic):只看 is_compacted=0 的压缩摘要 + 新消息context 仍精简。
    • UI 视角load_messages_for_topic_full):看原消息(含 is_compacted=1+ 新消息,排除压缩摘要,前端切回老话题仍能展示完整原始对话。
  • 新增 compact_topic_history:不删除原消息,仅打标记 + 插入摘要,同事务内删除旧摘要避免累积。修复 token 统计因压缩丢失 usage 的问题。
  • messages 表新增 is_compacted INTEGER NOT NULL DEFAULT 0migration 幂等。

Topic 维度 token 统计

  • 新增 batch_topic_token_stats,按 topic_id 聚合 token 消耗,替代原按 session_id 聚合导致的同 session 多 topic 共享总和问题。
  • 前端侧边栏每个 topic 显示独立 token 消耗与 context 占用百分比Coins 图标 + 数值,绿/黄/红三色指示)。
  • 主代理执行结束时触发 list_topics 刷新500ms 防抖),实时更新侧边栏 token 统计;子代理每轮执行也支持刷新。

设置页重启按钮

  • 设置页 Footer 区新增重启按钮,样式为 bg-tertiary + 边框,与主保存按钮区分。
  • 确认对话框区分触发来源:保存后触发显示"配置已保存 / 稍后",手动触发显示"重启服务 / 取消"并警告未保存改动。
  • 状态管理改用 restartDialogMode: 'saved' | 'manual' | null,按钮在重启期间显示 loading 并禁用。

设置页懒加载标签页与子代理管理

  • 拆分设置页为懒加载标签页,减少首屏渲染负担。
  • 前端支持子代理创建与删除,配合 PUT /api/subagents/update 端点。

LLM 主调用可配置重试机制0.3.0 收尾补充)

  • ProviderConfig 增加 max_retries 字段serde default=3向后兼容
  • agent_loop 流式 + summary 两个调用点实现重试循环:指数退避 1s/2s/4s仅对 429/502/503/504/timeout/connection reset 重试;流式仅在未 emit delta 时重试,避免重复输出。

修复

前端渲染稳定性

  • MessageBubble 使用 React.memo 避免流式期间不必要重渲染。
  • useWebSocket 回调 ref-化,避免父组件重渲染触发 WebSocket 无谓重连。
  • 修复触发滚动到底部按钮时新消息计数错误。
  • 修复话题重命名预填字段与写入字段不一致。
  • 修复流式期间消息重渲染、WebSocket 无谓重连与新消息计数错误。

子智能体结果展示

  • 失败/超时子智能体返回结构化结果,前端可点击查看详情,而非静默丢失。

Token 统计准确性

  • 修复 token 统计按 session_id 聚合导致同 session 多 topic 共享总和:改为按 topic_id 聚合,子代理消息通过 session_id NOT LIKE 'sub:%' 排除。
  • 修复主代理执行结束后 token 统计不刷新:useMessagesexecution_completed 事件时触发 bumpTopicRefreshTrigger()

工具执行可靠性

  • 修复 shell 工具超时未生效:adb start-server 守护进程继承 stdout 管道导致 EOF 阻塞,adb devices 误判 socket 等待为 stdin 等待绕过 deadline。新增 STREAM_DRAIN_MS 常量、改进 kill_and_reap、移除 should_return_pending 中的错误检查,确保 timeout 参数完全覆盖默认值。

安全加固

  • web_fetch 加固 SSRF 防护,禁用 HTTP 重定向,与 http_request 实现对齐。

MCP 兼容性

  • 限制 MCP server 名称字符并兜底 tool_name 清洗,避免非法字符导致 OpenAI API 400。

性能优化

网关吞吐

  • send_with_retryChannelFull 错误短路(不重试、不退避),加速队列消费,避免 dispatcher 在满队列时 7s 退避阻塞。
  • 新增 ChannelError::ChannelFull 变体,CliChanneltry_send 返回 Full 时映射为 ChannelFull

存储查询

  • get_topic_message_count 改用 SELECT COUNT(*) 在数据库侧计数,避免将所有消息(含 contenttool_calls_json 等大字段)加载到内存。

热路径优化

  • 减少热路径无谓拷贝与重复正则编译,跳过已完成 migration。

内部改进

  • 删除临时计划文件 PLAN.md
  • CHANGELOG 补充 LLM 重试机制条目并修正 commit 计数。

0.3.0 - 2026-08-04

0.2.0 的 18 个 commit 迭代,聚焦 Agent 执行与显示层解耦LLM 调用稳定性工程化基线并发持久化稳定性安全加固MCP 兼容性 六大方向。锁屏冻结架构修复经五轮对抗性审查验证。

新增功能

话题重命名

  • 新增 RenameTopic 命令与 TopicRenamed 协议消息,复用存储层已有的 update_topic_title 方法。后端响应携带刷新后的完整 topic 列表,前端零额外往返同步侧边栏。
  • 前端 TopicList 侧边栏增加内联编辑入口悬停显示铅笔图标Enter 提交 / Esc 取消 / blur 取消,通过 onMouseDown preventDefault 防止按钮点击时 input 提前失焦。

前端自动构建集成

  • 新增 build.rscargo build 时自动执行 npm install + npm run build,消除前后端构建割裂。支持 SKIP_FRONTEND_BUILD 环境变量跳过。

工程化基线

  • rustfmt.toml 固化 max_width=100 / 4 空格缩进;Cargo.toml 配置 [lints.rust][lints.clippy] 渐进式规则。
  • .github/workflows/ci.ymlRustfmt + clippy + test+ 前端eslint + tsc + test + prettier format:check双平台 CI。
  • Makefile 新增 check / fmt / fix 目标clippy 对齐 --all-targets --all-features
  • 前端 eslint flat config + prettier 配置,对 47 个前端文件统一格式化并在 CI 强制 format:check

默认迭代上限调整

  • max_tool_iterations 默认值调整为 1000匹配长任务子代理的实际需求。

LLM 主调用可配置重试机制

  • ProviderConfig 增加 max_retries 字段serde default=3向后兼容透传至 AgentRuntimeConfig 归属 agent 行为层,不进 ProviderRuntimeConfig 以保持 provider 构造包纯净。
  • agent_loop 流式 + summary 两个调用点实现重试循环:指数退避 1s/2s/4s仅对 429/502/503/504/timeout/connection reset 重试;流式仅在未 emit delta 时重试(AtomicBool 跟踪),避免重复输出;退避 sleep 期间响应 cancel_signal,取消优先。
  • 前端 ProviderConfig 类型和表单增加 max_retries 字段。
  • 7 个单元测试3 判定 + 4 行为540 个 lib 测试全绿。

架构修复

Agent 执行与显示层解耦(锁屏冻结根因修复)

根因:浏览器锁屏导致 WebSocket 半死,ws_sender.send().await 永久阻塞,级联阻塞 dispatcher → MessageBus → Agent Loop后端停止执行直到解锁。

基于第一性原理建立"执行-显示解耦"原则agent 执行只依赖 SQLite 持久化,实时广播是可丢弃的最佳努力通道。

  • MessageBus::publish_outboundsend().await 改为 try_send()bus 满时丢弃消息并告警agent 不再被显示层阻塞。新增 BusError::Dropped 变体。
  • WebSocket writer task 包裹 tokio::time::timeout(30s):半死连接超时即关闭。使用每连接独立的 CancellationToken(非共享的 CliChannel 级 token避免一个连接超时关闭所有连接。writer 退出时 cancel 通知主 loop 退出,确保 unregister_connection 执行。
  • CliChannel::sendsend().await 改为 try_send()dispatcher 单线程顺序处理,原阻塞式发送在 writer 卡住时会阻塞所有连接 37s改后立即返回。
  • 全仓 13 处 publish_outbound 调用统一区分 Droppedwarn预期背压/ Closederror异常日志级别消除监控噪音。scheduler 的 3 处 ? 改为 warn避免 Dropped 触发 misfire 重试风暴。
  • 前端 WebSocket 添加 25s 客户端 ping + 指数退避重连3s→6s→12s→24s→60s 封顶,上限 999 次)。重连后区分"重连恢复"与"首次/切换通道":前者保留断连前 messages 并刷新 topic 列表,后者清空数据避免污染。

安全加固

SSRF 重定向绕过修复

  • web_fetch 工具禁用 HTTP 重定向(redirect::Policy::none()):原 validate_url 只校验初始 URL 的 host跟随 302 跳转可重定向到 169.254.169.254(云元数据)或 127.0.0.1 等内网地址,绕过 is_private_host 的 SSRF 防护。与 http_request 工具保持一致。

Safety Guard 正则收紧

  • format 正则收紧为 \bformat\s+.*[a-z]:,要求出现盘符才拦截,避免误伤 dart formatbuf formatpytest --format 等合法命令。
  • 按平台分组注入规则Unix 不再注入 Windows 专用规则;Remove-Item 正则改为小写,与 guard_command 的大小写处理一致。

稳定性修复

SQLite 并发写入死锁

  • 7 个写事务从 BEGIN DEFERRED 改为 BEGIN IMMEDIATE:在事务开始即获取写锁,消除多 sub-agent 并发写入时的死锁路径。busy_timeout 从 5s 提升至 30s。
  • 根因:BEGIN DEFERRED 下多个事务可同时读 MAX(seq) 不持写锁提交时互相阻塞5s timeout 耗尽后返回 SQLITE_BUSYBEGIN IMMEDIATE 强制写者串行排队,顺带消除 MAX(seq)+1 竞态导致的 UNIQUE 约束冲突。

测试与代码质量

  • 修复 anthropic 错误链嵌套测试为真正的 #[source]原测试是无效的inner 变量被 let _ 抑制)。
  • 补充 anthropic provider 15 个纯函数单测(原 396 行零测试),覆盖 data URL 解析、图片过滤、字段过滤、响应反序列化、错误链格式化。
  • 修复 3 个失败测试:agent_md_template 写入模板内容 / StreamingAccumulator BTreeMap 保序 / source_order 断言补全。
  • 清理未使用的 dead code 函数与方法。
  • 新增 ARCHITECTURE.md 架构文档,聚焦数据流与 7 个关键设计决策。

CI 覆盖范围扩大

  • cargo build --lib 改为 cargo build,确保 main.rs 二进制入口被编译验证。
  • cargo test --lib 改为 cargo test,纳入 tests/ 目录集成测试。test_request_format.rs 的 8 个序列化测试此前从未在 CI 中运行。

跨平台构建修复

  • 修正依赖分类错误:rmcp / schemars / http / tower-http / rust-embed 均为跨平台 crate错放在 [target.'cfg(windows)'.dependencies] 下导致 Linux 构建失败,移出 target 段。

MCP 工具名清洗

  • OpenAI 要求 function name 匹配 ^[a-zA-Z0-9_-]+$,否则整个请求 400。MCP 工具名由 mcp_{server_key}_{tool_name} 拼成,两个输入源分别处理:
  • 后端:sanitize_tool_name 替换 tool_name 中的非法字符(., :, / 等)为 _,保留 server_keytool_name 原值用于路由,仅清洗 LLM 可见的 full_name,发生清洗时打 warn 日志便于定位。
  • 前端MCP 卡片头部改用 MapEntryHeader 支持点击重命名,addMcp / renameMcp 正则校验 server 名称 + toast 提示。顺手修了 MapEntryHeader 进入编辑时 val 未同步当前 name 的 bug。

0.2.0 - 2026-07-31

0.1.2 的 47 个 commit 迭代,聚焦 能力策略模型独立配置话题级并发隔离Agent Loop 性能优化 四大方向。

新增功能

能力策略CapabilityPolicy统一模型

  • 新增 CapabilityPolicy 领域模型,统一管理专家/子代理/技能的 allowed_skills / denied_skills / allowed_tools / denied_tools 四类白/黑名单。
  • 专家和子代理的 Markdown frontmatter 支持上述四类字段,在 create_agent 时按策略过滤 ToolRegistry(快照语义)。
  • 子代理支持数据驱动的工具过滤,删除旧版内置 explore 白名单。
  • 新增 HTTP 端点 GET /api/toolsPUT /api/subagents/update,供前端动态加载工具清单与更新子代理配置。
  • 前端引入通用 CheckboxList 勾选组件,将 capability 字段从自由文本 textarea 改为按来源分组的勾选式编辑,避免手输工具名。

模型独立配置

  • 专家和子代理的 Markdown frontmatter 新增 providermodel 可选字段,引用 config.json 中的 providers / models 表,可独立指定模型而不再继承主 agent。
  • 主 agent 支持会话级模型覆盖(provider / model 在配置层覆盖)。
  • 前端编辑模态框新增"模型配置"卡片,含 provider/model 下拉选择,选项由 GET /api/model-options 提供。
  • 专家引用不存在的 provider/model 时阻断会话并报错;子代理引用失败时将错误回传给 LLM。

话题级并发隔离

  • 实现聊天消息串行锁,确保同一聊天的消息处理串行执行。
  • 串行锁按 topic_id 键化,支持多话题并发执行,互不阻塞。
  • topic_id 全程显式传递(从消息接收到历史加载),修复消息错投与并发阻塞。
  • 内存历史缓存按 topic_id 键化(原按 chat_id),修复 DB 压缩时的 TOCTOU 覆盖问题。

子代理嵌套深度配置

  • 暴露 tools.task.max_nesting_depth 为可配置项(默认 2前端"Task 子代理"卡片新增输入框。
  • 保留双重防护:工具调用前校验 + 工具集构造时按深度移除 task 工具。

专家配置热更新

  • 专家配置保存后即时生效,无需重启网关。

工具调用序列前向检查

  • 添加工具调用序列的前向校验,确保 tool 消息紧随 assistant 的 tool_calls 消息,避免 OpenAI/DeepSeek API 400 错误。

前端测试基础设施

  • 引入 vitest 测试基础设施,添加 useChat handleServerMessage 特征测试。

性能优化

Agent Loop 性能P0

  • 工具定义缓存get_definitions() 从每轮迭代调用一次改为 process() 循环外构建一次。基于快照语义——单次 process()Arc<ToolRegistry> 不变,专家切换只影响下一次 create_agent
  • 轻量 token 估算:新增 estimate_text_tokens_from_chat_messages,直接基于 ChatMessage 累加字段长度,消除中间 text_only_messages: Vec<Message> 构造(原方案每条消息 × 5 字段双克隆)。
  • 工具 token 估算循环外预算serde_json::to_string 全量序列化工具定义从每轮一次降为 process() 内一次。
  • DB 写 offloadPersistingEmittedMessageHandlertokio::task::spawn_blocking 包装 SQLite 同步写,解除 tokio worker 线程阻塞,不改变失败语义(仅记日志不阻断主流程)。

SessionPool 锁范围收敛

  • ensure_session_internal 改为 double-checked locking先短暂持锁检查存在性释放锁后执行耗时的 session 创建含配置加载、agent 工厂构造),再次持锁插入并处理竞态。避免跨 session_factory.create().await 持有全局锁导致所有 channel 的 session 访问串行化。

修复

安全修复

  • 修复 SSRF 重定向绕过漏洞。
  • 修复符号链接路径遍历漏洞。
  • 修复 TodoItemSummary 字段缺失。

并发与稳定性

  • replace_todostransaction() 包裹 DELETE + INSERT保证原子性——中途失败自动回滚避免 todos 列表丢失。事务内复用同一连接查询返回值,消除 drop(conn) 后重新 pool.get() 的冗余。
  • 修复话题隔离下 topic_id 全程显式传递,解决消息错投与并发阻塞。
  • 修复内存历史按 topic_id 键化,新增 replace_topic_history 修复 DB 压缩覆盖。
  • 修复 http.rs 重启信号吞错P1
  • 修复 prompt 注入吞错P0

前端修复

  • 修复点击设置后白屏React hooks 顺序违规(useEffect 放在条件 return 之后导致 #310 错误)。
  • 修复 useEffect 依赖项缺失P0
  • 修复子智能体视图间歇性丢消息:同步前置 subAgentViewRef / subAgentStackRef
  • 修复子智能体工具消息去重:改为按 id + type 去重,修复工具状态卡在执行中。
  • 修复高亮消息时退出子智能体视图的问题。
  • 修复专家发现与前端选择多项问题。
  • 兼容 base_url 末尾斜杠,避免拼接产生双斜杠导致 404。
  • TodoWriteTool merge 模式内存为空时从 DB 回填,防止丢失旧项。

依赖与构建

  • 升级 wechatbot 的 reqwest 至 0.13,消除版本冲突。
  • rmcp 依赖从 git branch 迁移到 crates.io 版本。
  • 提交 Cargo.lock 以保证二进制构建可复现binary 项目约定)。

重构

前端架构

  • 重写 useChat 为组合根,消除上帝 Hook。
  • 抽取 useChat 的领域子 hook 与 messageMappers
  • 建立前端 API 客户端层,消除硬编码路径与重复 fetch
  • 拆分 ConfigPage.tsxstorage/mod.rsP2
  • 清理 P0/P1 技术债(any 类型、React key、dead_code、硬编码 URL

后端架构

  • 重构 AgentLoop 中的消息处理逻辑,简化工具结果处理和 LLM 请求构建。
  • 重构工具提示提供者,整合工具使用说明;删除冗余的 TodoPromptProvider
  • get_current / save_topic 直读 DB 加载消息,移除 SessionManager 依赖。
  • 改用 gray_matter 解析 Markdown frontmatter增加相应日志。
  • 优化工具使用说明,简化记忆检索和写入规则。
  • 移除未使用的 cli_sessions 变量,优化 ws.rs 中的代码。

内部改进

  • 增加整理意识,确保同类工作输出到同一文件夹。
  • 修复 MCP 日志输出。

0.1.2 - 2026-07-28

新增

  • WebSocket 连接泄漏修复,使用 CancellationToken 实现优雅重启。
  • 交互式 Shell 会话管理。
  • 数据库连接池优化会话存储,新增错误处理。
  • 平台特定的进程输入等待检查,增强 Bash 工具的用户授权检测。
  • 前端静态文件嵌入二进制。
  • React Web UI 前端界面。