Skip to content

v15

Choose a tag to compare

@NeonMedusa NeonMedusa released this 10 Oct 08:02
· 1 commit to main since this release
feat(ai): 思考回传(interleaved reasoning)全链路 + 估算取大 + 压缩降级阶梯 + 失败救援

## 思考回传(能力表驱动)
- 能力表 interleaved 字段(reasoning / reasoning_content / reasoning_text):assistant
  消息有思考发内容、无思考发空串兜底(对齐 opencode "always set the field");未标记
  模型不回传;模型表重新生成(含 interleaved 字段)
- DB 加载与 worker 实时两路都带 reasoning;序列化测试覆盖 标记/空串/user-tool 不带

## 估算与发送同口径 → 取大(防漏压自锁)
- messageRequestBytes 带 count_reasoning:仅当前模型回传时计入 reasoning(压缩触发/
  保留区选择/tokens_before 同源)
- 预检估算 = max(账本口径, 全量字节口径):账本 = 上次真实 usage + 增量(可能口径过期,
  锚点带 provider+模型标签);字节口径永远按"当前要发什么"算——哪个大用哪个
- 修掉实测自锁:v15→新版迁移后锚点"模型相符"但口径过期(66.7 万 vs 实际 590 万)→
  不触发压缩 → 22.97MB 请求被网关掐流 → 4 连败
- 状态栏显示同口径(估算胜出加 ~ 前缀)

## 压缩(摘要)请求:默认带思考 + 阶梯降级
- 默认把思考作为 [thinking] 文本段喂给摘要器(对齐 pi/opencode;查证两家摘要提示词
  均无"思考怎么处理"指引 → 不额外加)
- 超预算阶梯:剥思考 → 工具加狠截断(2000→500 / 500→200)→ 从最老端丢消息
  (上一轮摘要始终保留、至少保留最后一条);预算按"1 token ≥ 3 字节"保守换算
- 摘要请求仍失败(重试耗尽)→ 剥思考重试一次

## 失败救援(P2 泛化)
- 重试耗尽的失败(不管原因、不认错误码)→ 强制压缩一次并重发整请求;只救一次防死循环
- 实测本网关超限不给错误体(HTTP 200 后直接掐流)→ 旧版"只认错误体"永远不会触发
- 错误体可识别为"输入超限"时保留更具体的日志/提示

## 体验与修复
- 发起前自动压缩改在 worker 首轮前异步执行:不再冻结界面 30~100 秒、消息不再滞留输入框
- ask 最终回答按 DB 行 id 兜底(发起前压缩重建历史后基线失效 → 曾 exit=4 无输出)
- 诊断:cache 请求指纹 / endpoint 标识 / 首折日志
- 文档:development §2.3、reasoning-retention(调研 + 决议落地)、cache-miss-analysis

## 验证
- 231/231 测试(新增:思考序列化、估算取大、摘要阶梯五档、溢出识别等)
- 卡死会话实测自愈:估算取大(5.56M)→ 触发压缩 → 带思考 20.8MB 超预算 → 剥思考
  1.48MB(455k tokens)→ 摘要成功 → 重建 → 56 条消息小请求 → 回复落库 ✅