17 Commits

Author SHA1 Message Date
小海
2933df2697 fix: improve truncation recovery and diagnostics for v2.7.7
- mark degraded requests in logs and viewer when execution quality drops
- record Anthropic toolCallsDetected correctly in summaries
- continue semantically incomplete long Write/Edit tool payloads
- restore truncated OpenAI stream long Write tool_calls
- update release docs, sample config, docker notes, and README guidance
2026-03-23 11:39:00 +08:00
huangzhenting
1bc91cac24 feat: 新增 SQLite 持久化支持 + Vue UI 后端过滤与分页优化
- 新增 src/logger-db.ts:SQLite 封装层(WAL 模式,支持写入/分页/状态计数/按需 payload 查询)
- logger.ts:双写 SQLite+JSONL,启动时 db_enabled 模式跳过 JSONL 读取避免 OOM,新增游标分页和后端过滤函数
- config.ts/config-api.ts:新增 db_enabled/db_path 配置字段及 LOG_DB_ENABLED/LOG_DB_PATH 环境变量
- log-viewer.ts/index.ts:新增 /api/requests/more 支持 status/keyword/since 后端过滤
- Vue UI:搜索框 400ms 防抖,状态/时间筛选立即触发后端查询,statusCounts 不受状态筛选影响,SSE 实时推送时增量更新计数
- 新增迁移工具 test/migrate-jsonl-to-sqlite.mjs 和单元测试 test/unit-logger-db.mjs
- 完善 README.md、config.yaml.example、docker-compose.yml、vue-ui/README.md 文档
2026-03-22 21:10:26 +08:00
huangzhenting
f317dc04b0 fix: 修复 thinking 截断时内容泄漏到正文的问题
问题:当模型 thinking 内容超出单次输出上限时,<thinking> 标签未闭合,
导致 thinking 内容被当作正文泄漏给客户端;续写请求中 assistantContext
含未闭合标签,模型不知道思考阶段已结束,继续输出 thinking 而非正文。

修复:
1. splitLeadingThinkingBlocks:未闭合时返回已积累的部分 thinkingContent
   而非空字符串,供调用方正确提取
2. handler.ts / openai-handler.ts:流结束 flush 新增 !complete 分支,
   提取截断的 thinkingContent,不将 thinking 内容 flush 为正文
3. 新增 closeUnclosedThinking:续写前补全缺失的 </thinking> 标签,
   应用于所有 4 处续写 assistantContext 构建,让模型正确从正文续写
4. shouldAutoContinueTruncatedToolResponse:json action 块未闭合时
   跳过 200-char 检查,修复 thinking 剥离后正文过短导致续写不触发的问题

测试:新增 unit-thinking-truncation.mjs(11个单元测试)、
e2e-thinking-truncation.mjs(3个实际 API 请求测试),全部通过
2026-03-22 14:10:58 +08:00
majorcheng
310fd8672d fix: complete OpenAI logs and default persisted logs to summary 2026-03-20 14:06:46 +08:00
小海
8a5117bbb1 v2.7.4: 截断安全 + 代理续写禁用 + 日志提示词对比视图
- 截断时跳过工具解析,防止损坏的工具调用(写入半截文件)
- maxAutoContinue 默认 0,交由 Claude Code 原生续写
- 系统提示词身份声明清除(防 prompt injection 拒绝)
- 流式热身窗口 96→300 chars(拒绝检测前不释放文本)
- 日志查看器「提示词对比」视图:原始 vs Cursor 转换后
- 转换摘要面板:工具数/消息数/上下文大小一目了然
- 标题提取增强:通用 XML 标签清除 + 更多引导语过滤
2026-03-18 11:56:26 +08:00
小海
59e9ef51c0 chore: 添加 CTF 测试脚本,更新 .gitignore
- 添加 e2e-ctf-bypass.mjs 和 e2e-ctf-proxy.mjs 测试脚本
- .gitignore: 忽略测试结果 JSON 文件 (test/*-results*.json)
- .gitignore: 忽略 .claude/ 本地配置目录
2026-03-18 10:36:08 +08:00
小海
8a6b11a4c7 perf: optimize prompt efficiency via A/B tested behaviorRules
- behaviorRules: append action-first directive reducing narration 37% (32%→20%)
  \"Each response must be maximally efficient: omit preamble and planning text
  when the next step is clear—go straight to the action block.\"
- Continuation suffix: shorten from ~180 chars to ~30 chars (83% token saving)
  \"Based on the output above, continue working...\" → \"Continue with the next action.\"
- Add A/B test harnesses (e2e-prompt-ab.mjs, e2e-prompt-ab2.mjs) for future prompt tuning

Tested 4 variants × 17 scenarios. Candidate B won with:
  - Narration ratio: 32% → 20%
  - Response latency: 2372ms → 1795ms (↓24%)
  - Zero over-action side effects
  - 9/9 continuation scenarios passed
2026-03-18 10:34:38 +08:00
Xu Kang
af6449300f Merge pull request #62 from majorcheng/main
Fix OpenAI stream usage in final chunk
2026-03-18 09:48:47 +08:00
小海
c06755c46c perf: 早期中止拒绝检测 + 降低重试/续写上限 + 续写上下文截断
性能优化:
- sendCursorRequest 支持外部 AbortSignal,允许调用方提前中止流
- 工具模式 executeStream 在前 200-400 字符即检测拒绝,立即中止流
  (原先等完整响应再检测,浪费 2-5s/次)
- MAX_REFUSAL_RETRIES 2→1,减少最差情况 API 调用次数
- maxAutoContinue 默认 3→2,减少续写开销
- 续写请求只发最后 2000 字符作为上下文(原先发完整响应,可能 10K+)

测试:
- 重写 perf-diag.mjs 公平对比:直连也使用相同 reframing 提示词
- 公平测试结果:代理平均 0.78x(比直连更快),无性能瓶颈
2026-03-18 09:46:36 +08:00
majorcheng
ee8a7135dd Fix OpenAI stream usage in final chunk 2026-03-18 09:19:37 +08:00
小海
5e0c9a3ce7 fix: 修复工具模式误续写导致的截断终止
避免短参数 tool_use 在已可恢复时继续隐式续写,减少 OpenClaw/Telegram 场景下的长时间挂起与 terminated。
同时统一 Anthropic 与 OpenAI 兼容接口的截断续写判定,并补充对应回归测试。

Made-with: Cursor
2026-03-17 15:11:22 +08:00
小海
ed6181a5a9 fix: harden OpenAI multimodal compatibility and image handling
Tighten image path normalization, preserve multimodal request content across OpenAI-compatible endpoints, and fail fast on unsupported image_file inputs so clients get predictable behavior instead of silent degradation.

Made-with: Cursor
2026-03-17 15:03:39 +08:00
小海
13098fb84d feat: 内网代理支持 (Issue #17)
- 新增 proxy-agent.ts: 基于 undici.ProxyAgent 让 Node.js fetch 走代理
- cursor-client.ts / vision.ts: 接入代理 dispatcher
- config.yaml: 补充代理配置说明 (含认证格式)
- 新增 16 个单元测试覆盖代理模块逻辑
- 版本升级至 v2.5.4
2026-03-11 14:42:17 +08:00
小海
ecf4fa82ee { "message": "fix: stop renaming file_path to path implicitly, and remove compression tests" } 2026-03-11 09:55:15 +08:00
小海
5f0f9b7936 feat: v2.5.1 - 上下文智能压缩 + 截断检测 + tolerantParse 增强
🗜️ 智能压缩
- 长对话老消息压缩而非丢弃,保留因果链语义
- 工具结果压缩为摘要,助手消息保留工具名
- 压缩率 70-80%,解决 Cursor 上下文溢出问题

⚠️ 截断检测
- 代码块/XML 未闭合时返回 stop_reason=max_tokens
- Claude Code 自动继续,无需手动点击"继续"

🔧 tolerantParse
- 新增正则兜底层,处理未转义双引号的 JSON
- 解决 position 5384 等长参数解析崩溃

🛡️ 拒绝 fallback 优化
- 工具模式下返回极短引导文本
2026-03-10 17:29:49 +08:00
小海
f12ca30893 feat(v2.5.0): Cursor IDE 完整适配 + 工具参数自动修复 + 增量流式优化
🖥️ Cursor IDE 适配:
- 新增 /v1/responses 端点(Responses API → Chat Completions 自动转换)
- 兼容 Cursor 扁平工具格式 { name, input_schema }
- 扩展 /v1/models 模型列表(claude-sonnet-4-5/4/3.5)
- 连续同角色消息自动合并(mergeConsecutiveRoles)
- content 数组中 tool_use/tool_result 块直接透传

🔧 工具参数自动修复 (tool-fixer.ts):
- normalizeToolArguments: file_path → path 字段名映射
- replaceSmartQuotes: 中文/法文智能引号替换
- repairExactMatchToolArguments: 模糊匹配修复
- extractToolResultNatural: 自然语言 tool_result 转换

🚀 流式增量优化:
- input_json_delta / tool_calls 按 128 字节分块
- 拒绝重试扩展到工具模式
- 极短响应自动重试

🧪 新增 44 个单元测试 (tool-fixer + openai-compat)
2026-03-10 16:27:19 +08:00
小海
c072795528 feat: 修复流式中断 + JSON 解析 + tool_choice 强制工具调用
核心修复:
- cursor-client.ts: 固定总超时 → 空闲超时,防止长输出被截断 (#12)
- converter.ts: tolerantParse 三级修复策略,处理截断 JSON (#13)
- types.ts: 新增 AnthropicToolChoice 类型,补齐 tool_choice 字段
- converter.ts: buildToolInstructions 支持 tool_choice,注入 MANDATORY 约束
- handler.ts: tool_choice=any 时检测无工具调用 → 自动追加强制消息重试

测试覆盖:
- test/unit-tolerant-parse.mjs: 18 个单元测试(tolerantParse/parseToolCalls)
- test/e2e-chat.mjs: 16 个 E2E 测试(基础问答、工具调用、流式、边界防御)
- test/e2e-agentic.mjs: 7 个 Agentic 压测(完整 Claude Code 工具链模拟)
- package.json: 新增 test:unit / test:e2e / test:agentic 快捷命令
2026-03-10 15:11:51 +08:00