oudecheng
|
3cef9da443
|
chore(release): 0.4.3——max_run_secs 默认改为不限制
max_run_secs 默认值由 3600(60 分钟)改为 0(不限制),避免长任务被单次执行时间上限中断;需要时可在 config.json 的 agents 段显式配置。同步版本号提升至 0.4.3 并更新 CHANGELOG。
|
2026-08-18 15:35:22 +08:00 |
|
oudecheng
|
6ac653bf51
|
fix(review): 对抗性审查修复——spawn 竞态窗口、max_run_secs 配置化、删除计数一致性
- 子代理 spawn 顺序调整为先注册 cancel_registry 再写 DB running 记录,消除 reap 误杀刚启动子代理的微秒级竞态窗口
- max_run_secs 接入 AgentConfig 配置项(config.json agents 段),不再硬编码;From 透传 + 全部字面构造点补齐
- delete_messages_by_ids 删除后按活 COUNT 重算 sessions/topics 的 message_count,修复计数列漂移
- cli init 修改 agent 路径保留既有 max_run_secs 而非重置默认
|
2026-08-18 09:46:21 +08:00 |
|
oudecheng
|
452c5ad0ef
|
fix(gateway): 修复长会话后新消息无响应——僵尸子代理清理、panic 兜底与运行预算
- 发送 ExecutionCompleted 前惰性清理僵尸 running 子代理(DB running 但执行任务已消失),解除 pending 阻塞
- processor panic 路径补发 error 通知 + ExecutionCompleted,防止前端永久 loading
- agent 单轮增加墙钟预算 max_run_secs,超时优雅退出释放 topic 串行锁
- topic 串行锁等待增加 info/warn 日志,长等待可观测
- sanitize 清理结果回写 DB(delete_messages_by_ids),消除每次加载的重复修复
- storage 新增 keyset 分页与按 ID 批量删除的单元测试
|
2026-08-18 09:33:07 +08:00 |
|
oudecheng
|
a629486ad3
|
perf(chat): 长话题历史分页——messages 按 seq keyset 增量加载
后端新增 load_messages_for_topic_page(seq < cursor + limit 分页,走 (session_id, seq) 索引替代 OFFSET 深翻页),ChatMessage 增加 seq 游标;历史批次消息带 topic_id 下发,前端以 seq+topic_id 双重判定批次归属,规避切话题瞬间在途旧批次污染。
前端触顶增量加载:批次缓存在 pendingHistoryRef,收到 topic_history_end 一次性去重 prepend,scrollTop 按新增高度补偿锚定原头部消息;不足一屏自动补页,loading 超时 10s 自愈;流式输出中加载历史不清空流式累加器,避免已流出文本丢失。
|
2026-08-18 07:51:31 +08:00 |
|
oudecheng
|
0159227828
|
perf: 第二批性能修复——blocking 线程池隔离、HTTP 客户端复用、前端 memo 与流式节流
- 同步阻塞操作(附件处理、历史加载、scheduler/memory_search 的 SQLite 调用)
移入 spawn_blocking,避免占用 async worker
- LLM Provider reqwest::Client 按超时配置缓存复用,减少 TLS/连接开销
- agent loop:图片过滤加廉价预判避免全量深拷贝;请求克隆改借用;工具定义 Arc 化
- 定向 COUNT/LIMIT 1 查询替代全量加载计数(wait_coordinator、task session 重建)
- 前端:面板/侧栏/聊天组件 memo 化;merged_tool 对象按值复用缓存;
流式 delta rAF 节流批量 flush;useMemo 缓存分组排序结果
|
2026-08-18 06:55:21 +08:00 |
|
oudecheng
|
1019dbe8cc
|
refactor(code-quality): 清理 clippy 存量告警(unwrap/clone/redundant 等)
- 移除无用克隆与冗余引用,减少不必要内存分配
- 规范 unwrap/expect 使用,修复可提前失败路径
- 修复 anthropic provider llm_timeout_secs 死代码并补全超时日志
- cargo fmt 统一格式
|
2026-08-16 23:22:22 +08:00 |
|
oudecheng
|
0f60b02ede
|
chore(log): 缩减 INFO 日志量,高频诊断日志降级/删除
1. 删除缓存诊断日志 4 处(openai.rs):排查已完结,字段已补齐,每次 LLM 调用都刷屏。
2. 删除 AgentPromptProvider 模型配置日志(agent_prompt_provider.rs):排查遗留,每次请求刷。
3. AgentFactory 创建日志 info→debug(agent_factory.rs):每轮对话刷,降级保留供偶发排查。
4. Calling tool / Tool calls detected info→debug(agent_loop.rs):每次工具调用都刷,全量参数打印开销大,tracing 在未启用级别时不评估字段。
5. LoadTaskMessages 3 条日志 info→debug(load_task_messages.rs):每次前端 trigger 都刷,一次 3 条。
6. 旧结果诊断日志 info→debug(execution.rs):每条消息首次 agent 迭代都触发。
7. pending subagents 日志 info→debug(processor.rs):子代理运行期高频率重复触发。
8. Updating current_session_id 仅变化时打(ws.rs):old==new 时每条消息都刷,无信息量。
编译通过,测试全绿。
|
2026-08-15 23:10:39 +08:00 |
|
oudecheng
|
b26a2c2512
|
feat(token): 新增缓存占比统计,聚合查询收敛到共享列清单
- 解析: OpenAIUsage 支持 DeepSeek prompt_cache_hit_tokens + OpenAI prompt_tokens_details.cached_tokens fallback;Anthropic 接入 cache_read_input_tokens
- 存储: messages 表新增 cached_tokens 列(幂等迁移),贯穿 INSERT/SELECT/聚合
- 解耦加固: 抽取 MESSAGE_LOAD_COLUMNS 收敛 6 处消息加载 SELECT;抽取 USAGE_SUM_COLUMNS + read_usage_sum_row 收敛 topic/session 两份重复 SUM 聚合
- 协议: SessionTokenStats/TopicTokenStats 新增 cached_tokens 字段
- 前端: 面板新增缓存命中行 + 缓存命中率进度条(命中率越高越绿,与 ctx 占用方向相反)
|
2026-08-15 19:21:51 +08:00 |
|
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
|
e0313ab8f3
|
fix: 增强 panic 安全与计算器健壮性
- agent_loop/processor: catch_unwind 隔离 panic,防止消息静默丢失
- calculator: 拒绝 NaN/Infinity 输入,修复阶乘溢出(上限 34),拒绝非有限表达式结果
- message: 修复 sanitize 两阶段删除索引未排序导致的越界 panic
- utils: 新增 panic_payload_message 提取可读 panic 消息
- .gitignore: 忽略 artifacts/ 测试产物目录
|
2026-08-13 08:38:36 +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
|
79d099a3bc
|
chore(compaction): 调整压缩阈值默认值
工程化压缩阈值 threshold_ratio: 0.7 → 0.5(50%)
LLM 压缩阈值 llm_compaction_threshold_ratio: 0.5 → 0.3(30%)
降低触发门槛使压缩更积极介入,减少上下文溢出风险。
同步更新相关注释、日志信息和前端 hint 文案。
|
2026-08-07 11:53:54 +08:00 |
|
oudecheng
|
510520e08e
|
refactor: 提取公共工具函数,修复飞书正则重复编译和网关路由DRY问题,添加CI安全审计
|
2026-08-07 08:33:15 +08:00 |
|
oudecheng
|
7b459b8ca1
|
feat(config): 压缩算法关键参数暴露到设置页面
将 4 个压缩参数(threshold_ratio、llm_compaction_threshold_ratio、
truncate_max_tokens、preserve_count)从硬编码提取到 config.json 顶层
compaction 节,前端新增 CompactionTab 供用户调整。
后端:
- config: 新增 CompactionConfig 结构体,Config 新增 compaction 字段
- context_compressor: 4 个参数内聚到 ContextCompressor 实例字段;
新增 with_compaction_config() 构造函数和 truncate_tool_results() 方法;
对用户配置做防御性 clamp(ratio ∈ [0.1,1.0],整数 ≥ 1)
- agent_loop: 调用 compressor.truncate_tool_results() 实现零参数耦合
- agent_factory: 新增 build_compressor() 方法,in-loop 与 sync 兜底
两条压缩路径共用同一套用户配置
- session: with_factories 改用 agent_factory.build_compressor(),修复
sync 压缩路径忽略用户配置的 P0 问题
前端:
- types: 新增 CompactionConfig 接口,TabId 新增 'compaction'
- 新建 CompactionTab.tsx,4 个 number input 分两组 SectionCard
- constants + ConfigPage: 注册"上下文压缩" Tab(Archive 图标)
清理:删除无调用方的 from_provider_config/from_runtime_config/with_config
方法及 DEFAULT_THRESHOLD_RATIO/LLM_COMPACTION_THRESHOLD_RATIO 常量。
测试:context_compressor 18 + session 31 + agent_loop 42 全通过。
|
2026-08-06 11:03:56 +08:00 |
|
oudecheng
|
e037de88a2
|
fix(agent,gateway): 替换 unreachable!() 为防御性错误返回
将 run_final_summary 和 send_with_retry 中的 unreachable!() 替换为
错误返回,避免未来重构导致循环体未返回时 panic 终止所有会话。
- agent_loop.rs: run_final_summary 兜底构造错误 AgentProcessResult,
含 emit_live_tool_call_message 推送,与 Err 不可重试路径一致
- outbound_dispatcher.rs: send_with_retry 兜底返回 ChannelError::SendError,
覆盖 RETRY_DELAYS_SECS 为空数组的边界情况
同时 outbound_dispatcher.rs 包含优先级队列重构:高优消息使用独立
high 队列和扩展重试策略,保证最终响应不被中间过程挤占丢弃。
|
2026-08-06 10:01:02 +08:00 |
|
oudecheng
|
bf8c227634
|
refactor: 迁移 parking_lot 锁并优化阻塞 IO 与内存管理
## 锁迁移:std::sync → parking_lot
消除锁中毒(poison)导致的级联崩溃风险。parking_lot 锁不会中毒,
且性能更优。迁移覆盖全部生产代码:
- experts/mod.rs: 4 RwLock + 13 expect
- skills/mod.rs: 1 RwLock + 11 expect
- tools/registry.rs: 1 RwLock + 2 expect
- gateway/model_selection.rs: 1 RwLock + 2 expect
- tools/task/repository.rs: 1 RwLock + 4 unwrap
- tools/task/runtime.rs: 2 RwLock + 17 expect
- gateway/session.rs + task/runtime.rs: stream_message_id Mutex
- gateway/processor.rs: description_generation_in_flight Mutex
- command/handler.rs + help.rs: metadata Mutex(公开 API)
- mcp/client.rs: stderr_lines Mutex
测试代码中的 std::sync::Mutex(串行化锁 + TestObserver)有意保留,
已通过 unwrap_or_else(|err| err.into_inner()) 做中毒恢复。
## P1: 阻塞 IO 迁移到 spawn_blocking
将 3 处阻塞 async worker 的操作迁移到 blocking 线程池:
- file_read.rs: read_to_string + 行处理 + base64 编码整体包入 spawn_blocking
- agent_loop.rs: 新增 preencode_images_for_request 两阶段预编码
(顺序分配预算 → 并行 spawn_blocking 编码),build_llm_request 改为 async
- wechat.rs: media_to_send_content 改为 async,std::fs::read 用 spawn_blocking 包裹
## P2: session_history topic_histories 内存上限
新增 MAX_CACHED_TOPICS=32 上限和 evict_inactive_if_needed 方法。
超限时驱逐非活跃 topic(不在 chat_topic_ids、不在 compression_in_flight、
serial_lock 未被持有)。活跃 topic 永不误驱逐。
remove_history 同步清理 topic_serial_locks,防止无限增长。
## P3: 减少 panic 面
agent_loop.rs retry 循环的 response.expect(...) 改为 ok_or_else(...)?
返回 AgentError::Other,逻辑 bug 不再导致整个 agent 崩溃。
## 对抗性审查修复
- preencode_images_for_request: 用 seen HashSet 去重,防止同 path 重复
编码导致 HashMap entry 覆盖(NoBudget 覆盖 Encoded 等)
- evict_inactive_if_needed: 检查 topic_serial_lock.try_lock(),防止驱逐
正在 agent 处理中的 topic(original_topic_id 不在 chat_topic_ids 但
agent 仍持锁)
- remove_history: 清理 topic_serial_locks
## 验证
- cargo check: 通过(仅既有 lifetime 警告)
- cargo test: 559 passed / 3 failed(均为环境/sandbox 权限问题,与本次改动无关)
|
2026-08-06 08:18:04 +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
|
1e9075e1ed
|
fix(subagent): 失败/超时子智能体返回结构化结果,支持前端点击查看详情
spawn()/resume() 在会话创建后的失败(含超时、执行错误、AgentCreationFailed)
现返回 Ok(TaskToolResult { status: "failed"/"timeout", task_id }) 而非 Err(e),
使 tool_result 内容始终为结构化 JSON。前端已有的 taskStatusConfig、StatusIcon、
"查看完整会话"按钮自动生效,同时修复服务重启后点击入口丢失的问题。
- runtime.rs: 提取 handle_task_failure 辅助方法统一处理失败;将 model_resolver/
create_subagent 的 ? 纳入 result 块,确保所有会话后失败都返回结构化结果;
修复 resume() 未区分 timeout 的 bug
- tool.rs: 根据 task_result.status 判断 success,失败时 output 仍为 JSON
- agent_loop.rs: 失败时 result.output 非空则透传(仅影响 task 工具),其他工具回退
到 "Error: {error}" 纯文本
|
2026-08-05 09:05:35 +08:00 |
|
oudecheng
|
5eec77ae10
|
perf: 减少热路径无谓拷贝与重复正则编译,并跳过已完成迁移
- agent_loop::filter_images_by_age_and_count 改返回 Cow<[ChatMessage]>,
无图片或无需过滤时零拷贝返回原切片引用,避免每次 LLM 调用都完整克隆消息列表
- anthropic::convert_image_url_to_anthropic 用 OnceLock 缓存 data URL 正则,
避免每次图片转换都重新编译正则
- memory_scope_key 迁移用 PRAGMA user_version 记录已迁移版本,
避免每次启动都执行全表 DELETE + UPDATE
|
2026-08-05 08:10:36 +08:00 |
|
oudecheng
|
2e4b1931a6
|
feat(tokens): 添加 topic 维度 token 消耗与上下文窗口占用统计
后端:
- openai provider 流式响应启用 stream_options.include_usage,从 SSE 末帧捕获 usage
- ChatMessage 新增 MessageUsage(prompt/completion/total/context_window_tokens)
- agent_loop 三处 LLM 调用点持久化 usage,含 context_window_tokens
- storage 新增 context_window_tokens 列及 migration,batch_session_token_stats 聚合查询
- last_prompt_tokens 查询过滤 prompt_tokens IS NOT NULL,跳过 error/cancel 消息
- build_topic_summaries 简化签名,context_window_tokens 从消息记录读取
- protocol 扩展 TopicTokenStats,按 session_id 聚合天然隔离子代理
前端:
- protocol.ts 新增 TopicTokenStats 类型
- useTopics 映射 token_stats 到 Topic
- TopicList 展示总 token 消耗与上下文占用百分比(绿/黄/红三色)
测试:outbound_dispatcher 4 个测试修复(drop(bus) 不关闭 bus,改用 abort)
|
2026-08-04 17:01:54 +08:00 |
|
oudecheng
|
457f6b2408
|
feat(retry): 为 LLM 主调用添加可配置重试机制,默认 3 次
- config: ProviderConfig 增加 max_retries 字段(serde default=3,向后兼容)
- config: LLMProviderConfig 透传 max_retries,不进 ProviderRuntimeConfig(保持 provider 构造包纯净)
- agent: AgentRuntimeConfig 增加 max_retries,归属 agent 行为层
- 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 测试全绿
|
2026-08-04 12:53:33 +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
|
3b0de7d071
|
refactor: 清理未使用的 dead code 函数与方法
|
2026-08-03 14:21:01 +08:00 |
|
oudecheng
|
92db80dc3f
|
perf(agent-loop): 缓存工具定义与轻量 token 估算,DB 写入 offload 至 blocking 池
- 工具定义在 process() 循环外构建一次(快照语义:单次 process 内 Arc<ToolRegistry> 不变)
- 工具 token 估算循环外预算一次,避免每轮 serde_json::to_string 全量序列化
- 新增 estimate_text_tokens_from_chat_messages 直接基于 ChatMessage 累加字段长度,
消除中间 text_only_messages: Vec<Message> 构造(N 条消息 × 5 字段双克隆 → 0)
- PersistingEmittedMessageHandler 用 spawn_blocking 包装 SQLite 同步写,
解除 tokio worker 线程阻塞,不改变失败语义(仅记日志不阻断主流程)
|
2026-07-31 08:22:58 +08:00 |
|
oudecheng
|
303f6d83e3
|
feat: 添加工具调用序列的前向检查,确保工具消息紧随助手消息后
|
2026-07-15 16:36:13 +08:00 |
|
oudecheng
|
46a1ca6853
|
refactor: 修复 3 项 P1 技术债(硬编码 URL / any 类型 / dead_code)
P1-1: 硬编码 wechat URL 抽常量统一两处
- config/mod.rs: 定义 pub const WECHAT_DEFAULT_BASE_URL
- cli/init.rs: import 并引用常量,消除字面量重复
- 消除两处不一致风险(default_wechat_base_url 与 init 向导)
P1-2: ConfigPage any 类型定义具体类型(8 处)
- types.ts: 新增 FeishuChannelConfig/WechatChannelConfig/ChannelConfig/
SchedulerJobConfig 类型;jobs?: any[] → SchedulerJobConfig[];
channels: Record<string, any> → Record<string, ChannelConfig>
- api/config.ts: 新增 RestartResponse 类型,data: any → RestartResponse
- ConfigPage.tsx: catch (e: any) ×2 → catch (e: unknown) + 类型守卫;
as any → as SchedulerConfig['misfire_policy'];
Record<string, any> → Partial<ChannelConfig>;(ch: any) → (ch: ChannelConfig)
P1-3: dead_code 18 处逐一审查清理
- 删除 10 处未使用函数/struct(YAGNI 原则):
context_compressor.rs (into_messages, is_tool_round)
agent_loop.rs (EmptySkillProvider struct + impl)
memory_maintenance.rs (run_for_scope)
session.rs (try_start/finish_background_compaction)
session_history.rs (try_start/finish_background_compaction)
tool_registry_factory.rs (shell_session_manager)
task/runtime.rs (effective_allowed_tools)
- 保留 8 处 serde 反序列化字段(删除会破坏 JSON 反序列化):
feishu.rs/openai.rs/anthropic.rs/skills/mod.rs/task/runtime.rs
|
2026-07-08 14:51:42 +08:00 |
|
oudecheng
|
393052ae48
|
refactor: 重构 AgentLoop 中的消息处理逻辑,简化工具结果处理和 LLM 请求构建
|
2026-07-08 09:33:11 +08:00 |
|
oudecheng
|
d7ff969560
|
feat: 增强消息处理,清理不完整的 tool_call 序列以防止数据污染
|
2026-07-06 09:04:32 +08:00 |
|
oudecheng
|
f3365f8d3a
|
feat: 添加 HistoryUnit 解析单元测试,验证系统守卫和工具调用的处理逻辑
|
2026-07-03 10:19:33 +08:00 |
|
oudecheng
|
51e06c8f73
|
feat: 实现两段历史压缩的同步处理,替换会话的活动历史记录
|
2026-07-03 09:52:45 +08:00 |
|
oudecheng
|
4071dcc6ee
|
feat: 更新取消结果构建逻辑,确保已生成消息包含在取消响应中
|
2026-07-02 18:27:22 +08:00 |
|
oudecheng
|
32d49601a2
|
feat: 更新取消信号处理,支持 interior mutability;优化 LLM 调用与工具执行的取消逻辑
|
2026-07-02 17:17:03 +08:00 |
|
oudecheng
|
95cf152ab9
|
fix(agent): 修复工具调用消息序列的完整性问题
- 在历史压缩时,移除保留消息中不完整的工具调用序列,防止API 400错误
- 压缩后对当前历史消息再次进行工具调用序列清理,确保消息序列有效性
- OpenAI请求构建中,增加位置感知的工具调用和结果配对验证
- 跳过含有不完整工具调用序列的助手消息,避免发送非法请求
- 剥离不完整助手消息的工具调用字段,作为普通助手消息序列化
- 跟踪并警告不完整工具调用序列和被跳过的消息索引
|
2026-06-23 08:44:48 +08:00 |
|
oudecheng
|
606fcbcd29
|
feat(agent): 注入并传递 tool_call_id 实现任务与工具调用精准关联
- 在 agent_loop 执行上下文中注入 tool_call_id,确保执行时传递该字段
- 在 agent_factory、ws、todo_read、todo_write 等多处构造对象时添加 tool_call_id 字段初始化
- 扩展协议定义及序列化,支持 tool_call_id 字段传递
- 在工具调用任务运行时传递 tool_call_id,便于事件追踪和层级关联
- 在前端 useChat hook 增加 tool_call_id 关联逻辑,实现 task_started 事件精准匹配和跳转
- 增加 pendingTaskNavs 缓存处理,解决 task_started 事件先于 tool_call 到达的顺序问题
- 调整消息渲染逻辑,根据 tool_call_id 进行优先匹配,提升用户交互体验
|
2026-06-22 10:22:36 +08:00 |
|
oudecheng
|
97c0e46348
|
feat(tests): 增加工具调用序列清理的单元测试,确保孤立工具结果的正确处理
|
2026-06-16 16:52:00 +08:00 |
|
oudecheng
|
416ac047e3
|
feat(agent): 在每个 LLM 请求前进行不完整工具调用序列的清理
|
2026-06-16 16:51:40 +08:00 |
|
|
|
fc7df67474
|
feat(streaming): 支持流式文本增量与结束信号功能
- 新增 StreamDelta 和 StreamEnd 类型,支持流式数据增量传输
- 扩展 LLMProvider trait,添加带回调的 chat_with_streaming 接口
- 修改 OpenAI Provider 实现,支持流式聊天回调传输增量数据
- Agent 流处理改为异步消费增量消息并传递给前端
- 保证流式增量和最终消息使用相同消息 ID 以便前端替换
- 修改消息总线和协议层,支持携带和识别流式消息的消息 ID
- 客户端 CLI 通过增量输出实现交互式流式响应显示
- Web 前端接收流式增量消息,追加到对应消息,实现实时显示
- 各通道(飞书、微信)支持转发流式增量和结束消息
- 任务工具运行时添加消息 ID 支持,保持消息一致性
- 统一消息构造函数新增流式增量和结束信号的构建方法
|
2026-06-14 10:24:52 +08:00 |
|
|
|
e37dea886b
|
refactor(tools): 优化交互式进程输出捕获逻辑
- 删除了 PendingUserAction 相关的冗余辅助消息发送代码
- 引入自适应 drain_until_stable 函数循环读取输出直到稳定
- 用 drain_until_stable 替代固定延时等待以捕获最终提示内容
- 确保进程等待 stdin 时完整且及时地捕获所有输出数据
- 移除过时的常量和注释,简化代码逻辑
- 保持对最大循环次数和间隔时间的限制防止死循环
|
2026-06-13 17:40:44 +08:00 |
|
|
|
640829ce52
|
fix(agent): 优化等待工具输出内容的提取逻辑
- 跳过标记行、session_id元数据和空行
- 跳过提示行,提取提示行之后的实际内容
- 限制提取内容最多20行,防止消息过长
- 当提取内容为空时,使用默认提示消息
- 改善助手消息的显示内容格式
|
2026-06-13 17:40:30 +08:00 |
|
|
|
988e77123c
|
feat: 精简日志记录,移除冗余信息,优化调试输出
|
2026-06-06 10:41:52 +08:00 |
|
|
|
fb90641774
|
feat: 增强日志记录,添加消息处理和工具执行的详细信息
|
2026-06-06 09:26:50 +08:00 |
|
oudecheng
|
d1d4998a26
|
feat: 增加工具结果字符限制,提升处理能力至 100,000 字符
|
2026-06-04 17:33:01 +08:00 |
|
oudecheng
|
2f529e96d0
|
feat: 添加滚动控制功能,支持回到顶部和回到底部的按钮
|
2026-06-04 16:00:43 +08:00 |
|
oudecheng
|
1b571e943f
|
feat: 添加停止当前执行的 Agent 功能,支持通过 /stop 命令取消执行
|
2026-06-03 16:49:29 +08:00 |
|
oudecheng
|
a11fdac86a
|
feat: 优化消息历史清理逻辑,支持移除任意位置的未完成工具调用序列
|
2026-06-03 15:14:18 +08:00 |
|
oudecheng
|
cb58d9f3f0
|
feat: 清理消息历史中不完整的 tool call 序列
新增 sanitize_incomplete_tool_call_sequences() 方法,移除末尾
缺少对应 tool result 的 assistant tool_calls 消息。解决进程中断
导致部分 tool call 序列残留、进而引发 API 报错的问题。
同时清理因父消息被移除而残留的孤儿 tool result 消息。
|
2026-06-02 20:40:05 +08:00 |
|
oudecheng
|
4d6d989247
|
feat: 添加工具执行时长字段,增强消息处理功能
|
2026-06-02 16:52:47 +08:00 |
|
oudecheng
|
f8fc0f7d0f
|
feat: 添加工具结果处理功能,支持执行时长记录和显示
|
2026-06-02 16:15:05 +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 |
|