Repository navigation
fix(distill): 滤空窗口与「没写 JSON」分开报错,summary 枚举与 VALID 对齐(#502) - #504
modusensus wants to merge 1 commit into
Conversation
…align the prompt's type list (#502) The reporter's second shape after #493 unfroze: an audit row with raw_has_bracket = true and a 2.5-3.3K character body, yet `invalid summary JSON`. The JSON was fine - every entry had been dropped by the type filter, because the model invented localised categories ("env/version", "user need") and added id / source keys. ok:false means the cursor does not advance, so a window that is only wrong about a label gets replayed forever. The root cause is two menus that never matched, verified against main: the filter accepts 7 types, while the plain summary prompt lists 4 in both languages (only codingSummary had all 7), and neither says "use only these values" or "no extra keys" - grep for such a constraint across lang.js returns nothing. Both fixes are behaviour-free, in the reporter's own order (1, then 3): describeParseFailure classifies no-array / syntax / filtered-empty, the last one reporting `no valid summary entries (arr=N, valid=0)` with failure_kind, arr_count, invalid_entries and sample_types in the metadata so the invented labels are visible without re-reading the raw blob; and the summary prompt gains the full 7-value list plus an explicit no-invented-categories / no-extra-keys line in BOTH languages - fixing one leaves the other replaying the same way, and a twin guard cannot see both halves going stale together. raw_tail is added for outputs that start valid and drift later. Type normalisation (synonyms -> enum) is deliberately not done here: it would rescue content but shifts the stored category distribution, so it waits for the statistics fix 1 produces. The early return (no bracket at all, #493's arm B) now carries the same failure descriptor; without it the caller re-guesses the kind from whether a "[" appeared anywhere, and guesses do not belong in error messages.
There was a problem hiding this comment.
Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.
An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 10 minutes. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
Closes #502 · 报告见 #493(2026-10-21 19:12 那条)
一句话
summarize_compress有两种完全不同的失败,以前共用一句invalid summary JSON:一种模型在说话,另一种 JSON 合法、条目全被type枚举滤掉。后者因此被当成前者反复重放——游标不推进,同一个窗口一遍遍跑。现场(报告者给的数据,我按代码逐条核过)
失败行的
metadata.raw_has_bracket = true、raw_len2574/3299,而raw_head是:[ { "id": 1, "type": "环境/版本", "content": "…", "source": "工具结果:版本确认" }, … ]根因是两套菜单不一致(对照
main已核):summarize.js的VALIDlang.js的summaryprompt(zh + en)lang.js的codingSummary喂给模型的菜单和卡内容的闸门对不上,模型按最像中文标签的方式发挥是合理结果。
改了什么(按报告者排的 1 → 3,两条都零行为变更)
describeParseFailure分no-array/syntax/filtered-empty。第三种的错误消息写成no valid summary entries (arr=N, valid=0),metadata补failure_kind/arr_count/invalid_entries/sample_types(模型实际用的分类词原样带出来——不看这一眼就得去猜它是自造了「环境/版本」还是压根没写格式)。另补raw_tail(正文 > 500 字时给末 200 字):有些模型先写几条合法条目、再在后面跑偏,前 300 字看不出来。早退那一支(连方括号都没有,[0.9.3] 解析失败后确定性无限重试同一窗口:转录裸放 user 消息会被模型当成「该我回话了」 #493 的 B 臂)以前返回{ok:false, entries:[]}什么上下都不带,现在也带failure——否则下游只能靠「输出里有没有[」再猜一次,而猜出来的东西不该写进错误消息。summary中英两版枚举列全 7 个,并各加一句「只能取上面枚举里的值,不要自造分类;每项只输出上面列出的键,不要附加id、source等额外字段」。两种语言一起改——只改一种,另一种语言的窗口照样被滤空,而孪生守卫看不见「两边一起过期」。没做的一条:
type归一化(中文近义词 → 枚举)。它能把内容救回入库,但会改变入库分类分布;等上面第 1 条产出统计(哪些分类词被反复自造、频率多高)再判断值不值。这也是报告者自己的排序1 → 3 → 2。summarizeParseFailureMaxRetries继续默认关:这两种形态是该被修的,设成 2 会把它们连着窗口一起丢掉——护栏应该在 #502 落地之后再开。验证
npm test→ 2308 tests / 2307 pass / 0 fail / 1 skipped;check-sync✓ 76 文件test/summarize-parse-diagnostics.test.js5 条:filtered-empty报出 arr/valid 与sample_types、no-array仍用原消息且不许编出arr_count、有合法条目时不产出failure、raw_tail只在长正文时给、prompt 中英枚举与约束齐备error_message === "invalid summary JSON"改成等于新的精确消息,并加锁metadata含filtered-empty;行为断言一条没放松(状态仍是 error、窗口仍可重试、重试收到逐字节相同的转录)与 #503 的关系
#503(dream 侧围栏)与本条互不相干:那条改
dream.js/dream/sleep.js,本条改summarize.js/lang.js的summary段。两条会在 CHANGELOG 的[Unreleased]各加一个条目,后合的那条大概率要解一次行级冲突——那是文档拼接,不是代码耦合。