oudecheng
fc3a95b152
feat: 异步子代理 v8 实现与 /stop 取消流程修复
...
后端核心实现:
- 新增 wait_coordinator:释放/重获取 serial_lock 的 in-tool waiting 模式,替代旧的 break-exit 方案
- 新增 wait_for_subagents 工具:select! 等待子代理完成/用户消息/超时,支持 try_drain 批量消费
- task 工具异步 spawn 路径:CancellationToken 注册表 + RAII guard + Semaphore 并发限流
- process exit 安全检查:pending 子代理存在时抑制 ExecutionCompleted
- 崩溃恢复:启动时标记 running->interrupted,history 加载时对账占位
/stop 取消流程修复:
- wait_coordinator select! 添加 cancel 分支,完整清理状态
- ToolContext 注入 cancel_rx(watch::Receiver clone)
- agent_loop 工具执行 select! 对 wait 工具跳过竞速,防止 drop coordinator 清理逻辑
- 子代理完成状态通过 execution_completed metadata 传播
存储层:
- pending_subagents 表 + 条件 UPDATE
- mark_all_running_as_interrupted 崩溃恢复
2026-08-13 22:12:20 +08:00
oudecheng
29060315a3
feat(observability): 端到端可观测性整改,修复 trace_id 断链与指标配对
...
- 传播 trace_id:BusToolCallEmitter/SubAgentEmitter/processor 全链路设置
- AgentEnd 配对:补发 5 个 cancel/defensive 路径,闭合 AgentStart 指标
- LLM 计时修正:attempt_start 移入 retry 循环,排除退避等待时间
- /metrics auth:非 loopback 部署时纳入 Bearer token 校验
- recorder 复用:OnceLock 缓存 PrometheusHandle,热重启后不再返回 503
- 结构化日志:新增 tracing_ctx + JSON 日志格式支持
2026-08-12 08:26:42 +08:00
oudecheng
6252b600cd
refactor(compression): 重构上下文压缩为两阶段+双阈值+三段保留
...
压缩时机从 process 整体返回后提前到每轮工具调用完成后,更及时控制上下文大小。
两阶段压缩:
- 工程化压缩(70% 阈值触发):截断非子代理 tool 结果到 100 token,仅改内存不影响 DB
- LLM 压缩(50% 阈值触发):工程化压缩后仍超 50% 才调 LLM,避免不必要的 LLM 调用
LLM 压缩三段保留策略:
- 保留最旧 5 个 unit 和最新 5 个 unit 原样
- 中间段用 LLM 生成摘要(heavy prompt)
- SystemGuard 永远保留不计入配额
- ToolRound 原子性由 parse_to_units 保证,切分在 unit 边界
工程化压缩:
- truncate_tool_results_in_place 截断 role="tool" 且 tool_name!="task" 的消息
- 子代理返回(tool_name="task")保持原样
- char_indices 确保 UTF-8 字符边界安全,截断后追加 "...[已截断]" 标记
AgentLoop 集成:
- 新增 CompactionSink trait,LLM 压缩结果通过 sink 回写 DB
- AgentProcessResult 新增 compaction_performed 和 engineering_compaction_applied 标记
- finalize_result 据此决定是否 reload DB 历史(避免重复 append)和跳过兜底压缩
错误恢复:
- LLM 压缩失败降级为仅工程化压缩,不中断 agent loop
- sink.compact 失败记 error 日志继续使用内存压缩结果,DB 下次 process 会重新触发压缩
清理旧的 two-segment 差异化压缩代码(OLDER_BUDGET_RATIO、find_safe_split_point、
build_light_summary_prompt 等),新增 unit_to_messages 辅助函数。
2026-08-05 21:56:41 +08:00
oudecheng
cda14360af
chore: 建立工程化基线(rustfmt + clippy + CI + eslint + prettier)
...
配置:
- rustfmt.toml: 固化 max_width=100 / 4 空格缩进,cargo fmt 全量格式化
- Cargo.toml: 配置 [lints.rust] 与 [lints.clippy] 渐进式规则
- .github/workflows/ci.yml: Rust(fmt+clippy+test) + 前端(eslint+tsc+test) 双平台 CI
- Makefile: 新增 check/fmt/fix 目标,clippy 对齐 --all-targets --all-features
- web: eslint flat config + prettier 配置 + package.json 脚本与依赖
- src/main.rs: loop→while 修复 clippy::never_loop
对抗性审查发现并修复:
- eslint 缺 caughtErrorsIgnorePattern 导致 catch(_) 误报为 error
- 前端 lint 未接入 CI,现已补上 Lint 步骤
- Makefile 与 CI 的 clippy flags 不一致,已对齐
2026-08-03 23:24:02 +08:00
oudecheng
4baa8e7a6b
fix: 内存历史按 topic_id 键化,新增 replace_topic_history 修复 DB 压缩覆盖
...
- SessionHistory.chat_histories 改为 topic_histories 按 topic_id 键化,消除多话题并发时内存历史互相覆盖的根因
- is_current_turn 改用 current_topic == original_topic_id 直接比较,替代失效的内存最新消息匹配判断
- 新增 ConversationRepository::replace_topic_history 按 topic 删除/插入消息,解决 replace_active_history 删除整个 session 消息的 pre-existing 问题
- compaction 路径改用 replace_topic_history,避免压缩时覆盖其他 topic 的 DB 消息
- switch_topic 不再 remove_history,不同 topic 历史独立存储互斥
- append_persisted_message 仅当 topic_id == current_topic 时更新内存,防止延迟消息污染新话题历史
2026-07-28 15:32:42 +08:00
oudecheng
b042b45ac7
fix: 话题隔离 - topic_id 全程显式传递,修复消息错投与并发阻塞
...
问题:WS 端一个话题执行中时新建另一话题发消息,新会话无响应
(串行锁按 chat_id 阻塞),且首个话题完成后用户消息错误出现在
旧话题而非新话题(执行路径多次从共享 UI 状态读取 topic_id 产生竞态)。
核心修复(第一性原则):
执行上下文应在消息接收时一次性捕获,全程显式传递,不从共享可变
状态重复读取。
1. processor.rs: process_one 入口捕获 current_topic,传入 handle_message
和 set_agent_cancel_token
2. session_message_service.rs: handle_message 签名加 topic_id 参数,
透传给 MessageExecutionRequest
3. execution.rs: MessageExecutionRequest 加 topic_id 字段;
- 串行锁键改用 topic_id(不同 topic 并发,同 topic 串行)
- original_topic_id 优先用传入值,消除锁等待期间 topic 切换竞态
- append_persisted_message 调用传入 original_topic_id
- create_agent 调用传入 original_topic_id
4. session.rs: append_persisted_message 加 explicit_topic_id 参数;
create_agent/create_agent_with_provider_config 加 explicit_topic_id;
set_cancel_receiver/set_agent_cancel_token 加 topic_id 参数;
pending_cancel_tokens 查找改为优先 topic_id(避免并发 topic 执行时
cancel token 互相覆盖)
对抗性审查补丁:
- append_persisted_message: 仅当写入 topic 匹配当前活跃 topic 时才更新
内存历史,避免旧 topic 的排队消息污染已切换到的新 topic 内存历史
- prepare_and_execute_scheduled_task: 锁前一次性捕获 topic_id,锁后
复用同一值作为 original_topic_id,保证锁键与写入目标一致
已验证:cargo check 通过,gateway 模块 48 个测试通过(1 个预存在的
prompt 模板测试失败,与本次修改无关)。
2026-07-28 14:19:20 +08:00
oudecheng
3a8da51936
refactor: 串行锁按 topic_id 键化,支持多话题并发执行
...
将 chat_serial_locks 重命名为 topic_serial_locks,串行锁粒度从
chat_id 改为 topic_id。同一 topic 的消息处理仍串行执行,不同
topic 之间互不阻塞,为后续多话题并发修复铺路。
本提交仅重命名锁结构和访问方法,调用点仍用 chat_id 作为锁键
(回退兼容),不影响现有行为。
2026-07-28 14:17:12 +08:00
oudecheng
141ffda1ee
feat: 实现聊天消息的串行锁,确保同一聊天的消息处理串行执行
2026-07-15 17:47:52 +08:00
oudecheng
303f6d83e3
feat: 添加工具调用序列的前向检查,确保工具消息紧随助手消息后
2026-07-15 16:36:13 +08:00
oudecheng
7e24e57af4
fix: 修复 persistent_session_id 前缀重复累积问题
2026-07-03 16:32:24 +08:00
oudecheng
c72853c79d
feat: 添加 user_message_id 字段以支持用户消息的关联和同步
2026-06-24 15:13:36 +08:00
oudecheng
4866ea9538
fix: todo_write 持久化从 finalize_result 移到 BusToolCallEmitter,即时触发
...
之前持久化挂在 agent 全部完成后,长任务永远等不到。
现在每个 todo_write 工具调用完成时立即持久化到 SQLite。
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 16:58:05 +08:00
oudecheng
50d0b92336
feat: 添加详细工具视图和状态图标,支持放大查看功能
2026-06-12 16:49:20 +08:00
oudecheng
881fcace47
feat: 添加 todo_write 工具,支持全量替换和增量合并两种模式
...
- Tool: 纯内存实现 (Arc<RwLock<HashMap>>),零 DB 依赖,解耦持久化
- 状态机: pending → in_progress → completed/cancelled,单 in_progress 约束
- merge=false: 全量替换模式(默认)
- merge=true: 增量更新模式,只传变更的项,其余保留
- 隔离: scope_key = topic_id.unwrap_or(session_id),topic 和子代理隔离
- 持久化: TodoRepository trait + SessionStore SQLite 实现,在 Session 拦截器层完成
- 前端推送: WsOutbound::TodoList 事件
- Prompt: TodoPromptProvider 中文指令,子代理模板也包含
- 测试: 16 个单元测试,全部通过
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-12 14:19:07 +08:00
a2c7981d6d
feat: 添加 fresh_session 选项以支持清理历史记录
2026-06-02 23:31:05 +08:00
oudecheng
ea6fabe41d
feat: 添加持久化消息处理程序,增强定时任务消息的持久化能力
2026-06-02 18:42:50 +08:00
7d9355fd78
feat: WebSocket 媒体文件处理优化
...
- 后端 ws.rs: 处理前端上传的 base64 内容,保存到本地文件并更新路径
- 后端 ws.rs: 历史消息加载时从文件读取内容填充 base64,过滤 media_refs_json
- 前端 App.tsx: 传递 attachments 给 handleMessage 实现实时显示
- 前端 useChat.ts: handleMessage 支持 attachments 参数
- 前端 MessageInput.tsx: 支持剪贴板粘贴文件/图片
- 前端 MessageInput.tsx: 修复拖拽文件时闪烁问题
- 测试 test_request_format.rs: 补充缺失的 attachments 字段
2026-05-30 10:22:30 +08:00
oudecheng
06756a4816
fix: 修复消息持久化缺失 topic 关联和 assistant 文本丢失
...
- PersistingEmittedMessageHandler 新增 topic_id 参数,使用 append_message_with_topic 替代 append_message
- agent_loop 的所有退出路径中为最终 assistant 文本添加 emit_live_tool_call_message
- 更新 finalize_result filter,live_emitter 存在时抑制所有消息的 post-loop 广播
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 18:09:00 +08:00
oudecheng
d0051baa07
refactor: 消息持久化从批量改为实时逐条,通过装饰器模式实现
...
- 新增 PersistingEmittedMessageHandler 装饰器,在 emitter 广播前逐条落库
- processor 和 task/runtime 使用装饰器包裹 emitter,替代 post-loop 批量写入
- 移除 session_history 中的批量 DB 写入,仅保留内存历史更新
- execution 中跳过已由 live emitter 实时广播的工具消息,避免重复
- 前端支持运行中 task 工具卡片"查看实时进度"跳转子智能体视图
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 16:47:57 +08:00
b6f2de053d
refactor: 移除会话重置逻辑中的 reset_cutoff_seq 字段,优化会话管理和历史压缩逻辑
2026-05-23 18:38:34 +08:00
oudecheng
c817b1dde1
feat: 优化会话消息处理逻辑,支持在话题切换时正确保存消息并更新内存历史
2026-05-21 18:04:11 +08:00
oudecheng
8830027cbc
feat: 添加原始话题 ID 支持,优化消息保存逻辑以处理用户话题切换
2026-05-20 12:05:58 +08:00
oudecheng
025c0b5d7f
feat: 添加 session_id 支持到 OutboundMessage,优化会话管理
2026-05-15 10:00:17 +08:00
b77fc93d71
Refactor command handling and input adapters
...
- Removed the `format_session_list` function and related session handling from the client module.
- Simplified command output in the client by removing session-related commands.
- Introduced `ChannelInputAdapter` for parsing channel commands like `/new` and `/save`.
- Updated WebSocket handling to process commands via the new command system.
- Removed deprecated in-chat command handling from the gateway.
- Adjusted tests to reflect changes in command serialization and session handling.
- Enhanced session cleanup and job scheduling in the configuration module.
2026-05-14 22:23:02 +08:00
oudecheng
e712fd7645
feat: 修改提示词注入逻辑,确保每次处理用户消息时动态注入系统提示词;优化消息历史记录获取顺序
2026-05-14 11:28:53 +08:00
oudecheng
a06fceaf0c
feat: 添加系统提示词提供者,支持动态注入和组合多个提示词源
2026-05-13 14:55:50 +08:00
oudecheng
cadc5e5577
feat: 支持分离 session_chat_id 和 notification_chat_id,优化任务执行逻辑
2026-05-13 09:39:05 +08:00
e5e2b37246
feat: 重构会话管理逻辑,添加多个服务以优化会话和任务调度
...
Co-authored-by: Copilot <copilot@github.com>
2026-04-28 14:43:46 +08:00
008aba91ac
feat: 重构调度器以使用 AgentTaskExecutor 和 SchedulerMaintenanceService
...
- 更新调度器,将 SessionManager 替换为 AgentTaskExecutor 和 SchedulerMaintenanceService。
- 修改作业执行逻辑,使用新服务处理代理任务和内部事件。
- 添加新的 CliChannel 以处理 CLI 连接,并包括适当的注册和注销逻辑。
- 引入 AgentTaskExecutor 和 SchedulerMaintenanceService,用于管理代理任务和会话维护。
- 实现聊天命令处理,用于重置会话上下文。
- 添加后台历史压缩功能,以优化会话存储。
- 创建实用函数,用于准备通过 WebSocket 通信的出站消息。
- 为新功能添加测试,并确保现有测试通过。
Co-authored-by: Copilot <copilot@github.com>
2026-04-28 12:55:30 +08:00
14476bb101
feat: 添加 context_window_tokens 配置,调整模型温度并重构消息执行逻辑
2026-04-28 11:45:36 +08:00
fa3354db9c
feat: add context_window_tokens to model configuration and update related logic
...
- Introduced context_window_tokens in ModelConfig and LLMProviderConfig structs.
- Updated context window estimation logic in ContextCompressor to use context_window_tokens.
- Modified tests to accommodate new context_window_tokens field.
- Refactored memory maintenance logic into a new memory_maintenance.rs file for better organization.
- Ensured backward compatibility by providing default values where necessary.
Co-authored-by: Copilot <copilot@github.com>
2026-04-28 11:29:06 +08:00
b2c8d76820
feat: 添加最终结果处理和调度压缩功能,重构会话管理逻辑以优化代码结构
2026-04-28 10:58:01 +08:00
33f5a4cbd2
feat: 添加执行服务和提示管理功能,重构相关模块以优化代码结构
2026-04-28 10:51:54 +08:00