fix(core): require integer microcompaction keep count#5652
Conversation
|
@qwen-code /triage |
|
Thanks for the PR, @tt-a1i! (Re-run after post-review commit update.) Template looks good ✓ On direction: straightforward bugfix for #5648 — fractional On approach: the scope is tight and every change earns its place. The Moving on to code review. 🔍 中文说明感谢 @tt-a1i 的贡献!(审查后提交更新,重新运行。) 模板完整 ✓ 方向:这是对 #5648 的直接 bugfix——小数 方案:范围紧凑,每处改动都有必要。 进入代码审查 🔍 — Qwen Code · qwen3.7-max |
Code ReviewThe Real-Scenario TestingInternal-metadata bug — no TUI change. Tested by driving the real Before (main branch — bug present)After (this PR — bug fixed)Key behavioral differences
Unit TestsAll 56 tests pass, including 9 new tests covering fractional, unsafe, empty-env, and fallback scenarios. 中文说明代码审查
实际场景测试内部元数据 bug——无 TUI 变更。通过 关键行为差异: S1(env=1.5)Before 报告小数 metadata — Qwen Code · qwen3.7-max |
|
This is a well-scoped bugfix that does exactly what it says. The 56 tests pass including 9 new edge-case tests. The post-review commit added tests for the reviewer's feedback (happy-path, zero/negative floor) without scope creep. Schema and docs are updated to match. Approving. ✅ 中文说明这是一个范围明确的 bugfix,完全按描述实现。 56 个测试全部通过,包括 9 个新边界测试。审查后的提交根据 reviewer 反馈增加了测试(正常路径、零/负数下限),无范围蔓延。Schema 和文档已同步更新。 批准合并。✅ — Qwen Code · qwen3.7-max |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
LGTM, looks ready to ship. ✅
✅ Local runtime verification — recommend mergeI verified this PR on Linux by building two real Method
Behavioral evidence (observed values)
The bug from #5648 reproduces exactly (S1): with a fractional A second failure mode the PR also fixes (S2/S3/S5): a fractional or unsafe count that exceeds the compactable-item count makes the old code silently disable compaction entirely (a huge Tests
RiskLow / surgical. Only invalid inputs change behavior (non-integer, unsafe-integer, or blank env). Every valid integer — including the floor-to-1 and negative cases — is unchanged. The only newly-rejected values are Verdict: ✅ the PR behaves exactly as described. Recommend merge. 🇨🇳 中文版(点击展开)✅ 本地运行时验证 — 建议合并我在 Linux 上对本 PR 做了真实验证:分别用 PR head 和它的父提交 方法
行为证据(实测值)
#5648 的 bug 被精确复现(S1): 当 本 PR 还修复了第二个失效模式(S2/S3/S5): 当小数或不安全的计数超过可压缩条目数时,旧代码会完全静默地禁用压缩(巨大的 测试
风险低 / 改动精准。 只有非法输入的行为会改变(非整数、不安全整数、或空 env)。所有合法整数 —— 包括 floor-to-1 和负数场景 —— 行为完全不变。唯一新被拒绝的值是 结论:✅ 本 PR 的行为与描述完全一致,建议合并。 |
| ).toBe('grep results'); | ||
| }); | ||
|
|
||
| it('ignores fractional QWEN_MC_KEEP_RECENT values', () => { |
There was a problem hiding this comment.
[Critical] Missing happy-path test for valid env var override. All 6 new tests exercise invalid QWEN_MC_KEEP_RECENT values that trigger fallback. No test sets QWEN_MC_KEEP_RECENT='3' with toolResultsNumToKeep: 1 and asserts keepRecent === 3.
If the env-parsing branch in resolveKeepRecent were accidentally broken (e.g. regex inverted, return value swapped), every existing test would still pass because they all exercise the fallback path. The env-var override mechanism — the primary purpose of the env var — has zero positive verification.
it('uses env var integer when it overrides settings', () => {
process.env['QWEN_MC_KEEP_RECENT'] = '3';
const history: Content[] = Array.from({ length: 4 }).flatMap((_, i) => [
makeToolCall('read_file'),
makeToolResult('read_file', `content ${i}`),
]);
const result = microcompactHistory(history, twoHoursAgo, {
...DEFAULT_SETTINGS,
toolResultsNumToKeep: 1,
});
expect(result.meta).toBeDefined();
expect(result.meta!.keepRecent).toBe(3);
expect(result.meta!.toolsKept).toBe(3);
expect(result.meta!.toolsCleared).toBe(1);
});— qwen3.7-max via Qwen Code /review
There was a problem hiding this comment.
added this exact happy-path coverage. QWEN_MC_KEEP_RECENT=3 now overrides toolResultsNumToKeep: 1, and the test asserts keepRecent=3, 3 kept, 1 cleared.
| ).toBe('grep results'); | ||
| }); | ||
|
|
||
| it('ignores fractional QWEN_MC_KEEP_RECENT values', () => { |
There was a problem hiding this comment.
[Critical] Missing test for env var '0' or a negative integer. These values pass the regex /^-?\d+$/ and Number.isSafeInteger, then hit Math.max(1, value) — a distinct branch from all current tests. The existing 'should floor keepRecent to 1' test only covers the settings path (toolResultsNumToKeep: 0), not the env-var path.
If Math.max(1, ...) were removed or weakened, 0 or -3 from the env would propagate to slice(-keepRecent), producing incorrect keep-recent counts with no failing test to catch it.
it('clamps zero and negative env var values to 1', () => {
process.env['QWEN_MC_KEEP_RECENT'] = '0';
const history: Content[] = [
makeToolCall('read_file'),
makeToolResult('read_file', 'old content'),
];
const result = microcompactHistory(history, twoHoursAgo, {
...DEFAULT_SETTINGS,
toolResultsNumToKeep: 1,
});
expect(result.meta).toBeDefined();
expect(result.meta!.keepRecent).toBe(1);
});— qwen3.7-max via Qwen Code /review
There was a problem hiding this comment.
covered this too. Added an it.each for QWEN_MC_KEEP_RECENT=0 and -2; both now pin the env-var clamp path to keepRecent=1.
✅ Local verification report (maintainer)Built and tested this PR locally to confirm the fix before merge. Environment
|
| Check | Command | Result |
|---|---|---|
| Target tests | vitest run microcompaction/microcompact.test.ts |
✅ 53/53 pass (47 + 6 new) |
| New tests | the 6 integer-validation cases | ✅ pass |
| Generated schema in sync | npm run generate:settings-schema → git diff |
✅ no diff (matches committed) |
| Types | tsc --noEmit (core + cli) |
✅ 0 errors each |
| Lint / Format | eslint / prettier --check on changed files |
✅ clean |
Mutation test (the key evidence). I reverted microcompact.ts to the main version (the Number.isFinite(Number(env)) parse) while keeping the new tests — all 6 fail. Each guards a distinct case (fractional env, settings fallback, unsafe-int env, unsafe-int settings, fractional settings). The standout is checks env integer syntax before numeric conversion with QWEN_MC_KEEP_RECENT=9007199254740990.5:
Number('9007199254740990.5') === 9007199254740990 // Number.isSafeInteger → true (!)
Float rounding turns that fractional string into a safe integer, so the old finiteness check would silently accept it. The new regex /^-?\d+$/ rejects the fractional string before numeric conversion — a genuinely load-bearing guard, and the test pins it.
Correctness review
- New
resolveKeepRecent(env, settings)always returns a positive safe integer (default5). Env path: integer-syntax regex →Number.isSafeInteger→Math.max(1, …); settings path:Number.isSafeInteger→Math.max(1, …), else default5. Negative env (-1) floors to1. This resolves bug(core): microcompaction keepRecent accepts fractional counts #5648 (fractionalkeepRecentmadeslice(-1.5)keep 1 whileMath.min(count, 1.5)reported1.5in metadata). - Schema side is consistent:
jsonSchemaOverride: { type: 'integer' }insettingsSchema.ts, the regeneratedsettings.schema.json(number → integer), and the docs row all agree, and the generated schema is verified in sync with the generator. - The new env-var tests are properly isolated (
afterEach(clearEnv)deletesQWEN_MC_KEEP_RECENT), so there's no cross-test pollution.
Verdict: code LGTM — but please rebase before merging. The logic is correct and thoroughly mutation-verified; the only blocker is the trivial settings.md table conflict from main's reformatting.
🇨🇳 中文版
✅ 本地验证报告(维护者)
合并前在本地构建并测试了本 PR 以确认修复。
环境
- macOS(Darwin 25.5),Node
v22.22.2 - PR head
6ac6bbe64,base76bdabadc,当前origin/main83caca65e - 方法:在 PR head 上建独立
git worktree,做干净的npm ci并重建core/acp-bridge,再逐条独立验证。
⚠️ 合并状态:CONFLICTING —— 合并前需要 rebase
代码是正确的(下方已验证),但本 PR 无法干净地合并到当前 main。恰好一个冲突,且很简单:
docs/users/configuration/settings.md—— main 重排了设置表(列宽 reflow),而本 PR 改了toolResultsNumToKeep那一行,于是整块表在空白字符上冲突。纯文档,无代码影响。settingsSchema.ts和settings.schema.json能自动合并(本 PR 的改动和 main 新增的customIgnoreFiles/modelProviders在不同区域)。
建议:rebase 到 main,采用 main 的表格式 + 重新应用那一处 number → integer 行改动,然后跑 npm run generate:settings-schema 让生成的 schema 保持同步。
结果
| 检查项 | 命令 | 结果 |
|---|---|---|
| 目标测试 | vitest run microcompaction/microcompact.test.ts |
✅ 53/53 通过(47 + 6 新) |
| 新增测试 | 6 个整数校验用例 | ✅ 通过 |
| 生成 schema 是否同步 | npm run generate:settings-schema → git diff |
✅ 无 diff(与提交一致) |
| 类型 | tsc --noEmit(core + cli) |
✅ 各 0 错误 |
| Lint / 格式 | 对改动文件跑 eslint / prettier --check |
✅ 干净 |
变异测试(关键证据)。 我把 microcompact.ts 还原成 main 版本(Number.isFinite(Number(env)) 解析),保留新测试 —— 6 个全部失败。每个守护一个不同情形(小数 env、settings 回退、不安全整数 env、不安全整数 settings、小数 settings)。最精彩的是 checks env integer syntax before numeric conversion,env=9007199254740990.5:
Number('9007199254740990.5') === 9007199254740990 // Number.isSafeInteger → true(!)
浮点舍入把这个小数字符串变成了安全整数,所以旧的 finiteness 检查会静默接受它。新的正则 /^-?\d+$/ 在数值转换之前就拒绝这个小数字符串 —— 是个真正起作用的守卫,这个测试正好锁定它。
正确性审查
- 新的
resolveKeepRecent(env, settings)永远返回正安全整数(默认5)。env 路径:整数语法正则 →Number.isSafeInteger→Math.max(1, …);settings 路径:Number.isSafeInteger→Math.max(1, …),否则默认5。负数 env(-1)被 floor 到1。这修复了 bug(core): microcompaction keepRecent accepts fractional counts #5648(小数keepRecent让slice(-1.5)保留 1,而Math.min(count, 1.5)在 metadata 里报1.5)。 - schema 侧一致:
settingsSchema.ts里的jsonSchemaOverride: { type: 'integer' }、重新生成的settings.schema.json(number → integer)、文档那一行三者一致,且生成的 schema 已验证与生成器同步。 - 新的 env 变量测试做了正确隔离(
afterEach(clearEnv)删除QWEN_MC_KEEP_RECENT),无跨测试污染。
结论:代码 LGTM —— 但合并前请先 rebase。 逻辑正确且经充分变异测试验证;唯一阻塞是 main 重排表格带来的那个简单的 settings.md 冲突。
6ac6bbe to
503020e
Compare
doudouOUC
left a comment
There was a problem hiding this comment.
Both Critical findings from the previous review (missing happy-path test, missing zero/negative test) have been properly addressed. The resolveKeepRecent implementation is clean and well-tested — all 56 tests pass, tsc and eslint are green.
LGTM ✅
— qwen3.7-max via Qwen Code /review
✅ Local runtime verification — real
|
| input | BEFORE (keepRecent, kept, cleared) | AFTER (keepRecent, kept, cleared) |
|---|---|---|
env "3", set 1 |
3, 3, 3 | 3, 3, 3 (same) |
env "0" / "-2", set 1 |
1, 1, 5 | 1, 1, 5 (same, floored) |
env " 3 " (spaces) |
3, 3, 3 | 3, 3, 3 (same, trimmed) |
env "1.5", set 3 |
1.5, 1, 5 | 3, 3, 3 (env ignored → settings) |
env "9007199254740992" (2⁵³), set 1 |
NO-OP — nothing cleared | 1, 1, 5 (env ignored → settings) |
env "9007199254740990.5", set 2 |
NO-OP — nothing cleared | 2, 2, 4 (regex rejects before precision loss) |
settings 1.5 |
1.5, 1, 5 | 5, 5, 1 (→ default) |
settings 2⁵³+1 |
NO-OP — nothing cleared | 5, 5, 1 (→ default) |
settings 5 |
5, 5, 1 | 5, 5, 1 (same) |
→ BEFORE accepts fractional counts (1.5) and, worse, huge/unsafe values make slice(-keepRecent) keep everything → microcompaction clears nothing. AFTER rejects them and falls back correctly. Valid integers are identical (no regression).
B — Real CLI E2E in tmux (the user-facing bug)
Ran the real dist/cli.js headless (-p … --approval-mode yolo) against a mock server returning two ~15 KB tool results, with toolResultsTotalCharsThreshold=20000, toolResultsNumToKeep=1, and the same malformed QWEN_MC_KEEP_RECENT=9007199254740992 for both arms — only the build differs:
- BEFORE → debug log:
[TOOL-RESULT MC] tool result chars 30298 > 20000, cleared 0 tool result(s), kept 1. Outbound round-3 request carries both tool results in full (15189 chars each). The malformed env silently disabled clearing. - AFTER → debug log:
[TOOL-RESULT MC] … cleared 1 tool result(s) (~3788 tokens). Outbound round-3 request: oldest result =[Old tool result content cleared], newest full. Clearing works despite the bad env.
C — Settings-schema A/B (ajv draft-07, as VS Code validates)
| value | OLD (number) |
NEW (integer) |
|---|---|---|
5, 0, -2 |
accept | accept |
1.5, 2.7 |
accept | REJECT |
9007199254740992 |
accept | accept |
NEW flags fractional values in settings.json; the schema can't express "safe integer" (2⁵³ passes), which is exactly why the runtime guard in (A) matters too — defense in depth. Regenerating settings.schema.json from source is byte-identical to the committed file (not hand-edited).
D — Unit tests + mutation (teeth)
microcompact.test.ts: 56/56 pass on head.- Mutation (revert prod to parent, keep head tests): exactly the 6 new integer-validation tests fail (fractional env, env-syntax-before-conversion, unsafe-int env, unsafe/fractional settings); the 3 integer-syntax-compatible new tests + 47 others stay green → the tests genuinely pin the new behavior.
Verdict
LGTM — verified on real builds. The headline win is that a malformed QWEN_MC_KEEP_RECENT/toolResultsNumToKeep no longer silently turns off idle/size context clearing (which would let history grow unbounded). No regression for valid integers. 👍
🇨🇳 中文版(点击展开)
✅ 本地运行时验证 —— 在真实构建产物上用 tmux 做 A/B 对比
我把 PR 两侧都编译成真实产物(head 503020e3 对比父提交 d350dd8d),并运行真正的编译代码 —— 既包括 microcompactHistory 函数,也包括在 tmux 伪终端中无头运行的真实 dist/cli.js。结论:整数校验修复正确;“非安全整数”这一情形是一个真实的“上下文清理被静默关闭”的 bug,本 PR 修复了它;合法整数行为不变;测试有效。建议合并。
PR 做了什么
resolveKeepRecent() 现在要求 QWEN_MC_KEEP_RECENT 环境变量(先用 /^-?\d+$/ 校验整数语法,再 Number.isSafeInteger)和 toolResultsNumToKeep 设置都必须是安全整数;非法值逐级回退(env → 设置 → 默认 5),合法值下限取 1。旧代码接受任何 Number.isFinite 的值。设置 schema 中 toolResultsNumToKeep 也由 number 改为 integer。
A —— 编译后的 microcompactHistory 在校验矩阵上的 A/B
驱动各构建中真实编译的函数(6 对工具结果,idle 触发)。keepRecent / 保留 / 清除:
| 输入 | BEFORE(keepRecent, 保留, 清除) | AFTER(keepRecent, 保留, 清除) |
|---|---|---|
env "3", set 1 |
3, 3, 3 | 3, 3, 3 (相同) |
env "0" / "-2", set 1 |
1, 1, 5 | 1, 1, 5 (相同,下限取 1) |
env " 3 "(空格) |
3, 3, 3 | 3, 3, 3 (相同,已 trim) |
env "1.5", set 3 |
1.5, 1, 5 | 3, 3, 3 (env 被忽略 → 设置) |
env "9007199254740992"(2⁵³), set 1 |
空操作 —— 什么都没清除 | 1, 1, 5 (env 被忽略 → 设置) |
env "9007199254740990.5", set 2 |
空操作 —— 什么都没清除 | 2, 2, 4 (正则在精度丢失前先拒绝) |
settings 1.5 |
1.5, 1, 5 | 5, 5, 1 (→ 默认) |
settings 2⁵³+1 |
空操作 —— 什么都没清除 | 5, 5, 1 (→ 默认) |
settings 5 |
5, 5, 1 | 5, 5, 1 (相同) |
→ BEFORE 会接受小数(1.5),更糟的是超大/非安全整数会让 slice(-keepRecent) 保留全部 → 微压缩什么都不清除。AFTER 会拒绝它们并正确回退。合法整数完全一致(无回归)。
B —— tmux 中的真实 CLI 端到端(面向用户的 bug)
无头运行真实 dist/cli.js(-p … --approval-mode yolo),mock 服务返回两个约 15 KB 的工具结果,设置 toolResultsTotalCharsThreshold=20000、toolResultsNumToKeep=1,两侧都用相同的非法值 QWEN_MC_KEEP_RECENT=9007199254740992,仅构建不同:
- BEFORE → 调试日志:
[TOOL-RESULT MC] tool result chars 30298 > 20000, cleared 0 tool result(s), kept 1。第 3 轮外发请求中两个工具结果都是完整的(各 15189 字符)。非法 env 静默关闭了清理。 - AFTER → 调试日志:
[TOOL-RESULT MC] … cleared 1 tool result(s) (~3788 tokens)。第 3 轮外发请求中:最旧结果 =[Old tool result content cleared],最新结果完整。即使 env 非法,清理也正常工作。
C —— 设置 schema 的 A/B(ajv draft-07,即 VS Code 的校验方式)
| 值 | OLD (number) |
NEW (integer) |
|---|---|---|
5, 0, -2 |
接受 | 接受 |
1.5, 2.7 |
接受 | 拒绝 |
9007199254740992 |
接受 | 接受 |
NEW 会在 settings.json 中标记小数值;schema 无法表达“安全整数”(2⁵³ 能通过),这正是为何 (A) 中的运行时校验同样重要 —— 纵深防御。从源码重新生成 settings.schema.json 与提交版逐字节一致(非手工编辑)。
D —— 单元测试 + 变异测试(有效性)
microcompact.test.ts:head 上 56/56 通过。- 变异测试(把生产代码退回父提交、保留 head 测试):恰好 6 个新增的整数校验用例失败(小数 env、先校验语法再转换、非安全整数 env、非安全/小数设置);其余 3 个“整数语法兼容”的新用例 + 47 个其他用例仍通过 → 测试确实锁住了新行为。
结论
LGTM —— 已在真实构建上验证。最大的收益是:非法的 QWEN_MC_KEEP_RECENT/toolResultsNumToKeep 不再静默关闭 idle/size 上下文清理(否则历史会无限增长)。合法整数无回归。👍
Verified locally on Linux: head-vs-parent build A/B of the compiled function + a real headless dist/cli.js run in tmux + ajv schema A/B + mutation testing; working tree restored clean afterwards.
|
@qwen-code /triage |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
LGTM, looks ready to ship. ✅
What this PR does
This PR makes the microcompaction keep-recent count resolve to a safe integer before it is used for slicing and diagnostic metadata. Invalid
QWEN_MC_KEEP_RECENTvalues now fall back tocontext.clearContextOnIdle.toolResultsNumToKeep, invalid settings values fall back to the default, and integer values below1are still floored to1.It also updates the settings schema, generated VS Code schema, and user docs so
context.clearContextOnIdle.toolResultsNumToKeepis described as an integer count.Why it's needed
QWEN_MC_KEEP_RECENT=1.5was accepted because the previous code only checkedNumber.isFinite(...). JavaScript array slicing coerces that fractional count, butmeta.keepRecentandmediaKeptcould still report fractional values. This made the retention behavior and diagnostic metadata disagree.Reviewer Test Plan
How to verify
Review the new
microcompactHistorytests for fractional, unsafe, and fallback keep-recent values. The key behavior to confirm is that invalid env values fall back to settings, invalid settings fall back to5, and valid integers below1still resolve to1.Commands run locally:
npx vitest run src/services/microcompaction/microcompact.test.ts --coverage.enabled=falsefrompackages/core- 53 tests passed.npx prettier --check packages/core/src/services/microcompaction/microcompact.ts packages/core/src/services/microcompaction/microcompact.test.ts packages/cli/src/config/settingsSchema.ts docs/users/configuration/settings.md packages/vscode-ide-companion/schemas/settings.schema.json- passed.npx eslint packages/core/src/services/microcompaction/microcompact.ts packages/core/src/services/microcompaction/microcompact.test.ts packages/cli/src/config/settingsSchema.ts- passed.git --no-pager diff --check- passed.node --import tsx/esm scripts/generate-settings-schema.ts- regeneratedpackages/vscode-ide-companion/schemas/settings.schema.json.npm run typecheck --workspace @qwen-code/qwen-code-core- passed.npm run typecheck --workspace @qwen-code/qwen-code- passed.npm run build --workspace @qwen-code/qwen-code-core && npm run build --workspace @qwen-code/qwen-code- passed.Evidence (Before & After)
Before: fractional env values such as
QWEN_MC_KEEP_RECENT=1.5could flow intometa.keepRecent, while slicing coerced the value differently. After: the new tests assert that fractional env values fall back to settings, unsafe env values are ignored, fractional settings fall back to the default, and metadata reports integer counts.Tested on
Environment (optional)
Local macOS development environment with the repository npm workspaces installed.
Risk & Scope
1to1.Linked Issues
Fixes #5648
AI Assistance Disclosure
I used Codex to review the changes, sanity-check the implementation against existing patterns, and help spot potential edge cases.
中文说明
这个 PR 做了什么
这个 PR 会先把 microcompaction 的 keep-recent 数量解析成安全整数,再用于切片和诊断元数据。无效的
QWEN_MC_KEEP_RECENT现在会回退到context.clearContextOnIdle.toolResultsNumToKeep,无效的 settings 值会回退到默认值,低于1的整数仍然会按1处理。它还同步更新了 settings schema、生成的 VS Code schema 和用户文档,把
context.clearContextOnIdle.toolResultsNumToKeep描述为整数数量。为什么需要
之前
QWEN_MC_KEEP_RECENT=1.5会被接受,因为旧逻辑只检查了Number.isFinite(...)。JavaScript 数组切片会对这个小数做隐式转换,但meta.keepRecent和mediaKept仍可能报告小数值,导致实际保留行为和诊断元数据不一致。Reviewer Test Plan
如何验证
查看新增的
microcompactHistory测试,覆盖小数、不安全整数和 keep-recent 回退逻辑。需要确认的关键行为是:无效 env 值会回退到 settings,无效 settings 会回退到5,低于1的有效整数仍会解析为1。本地运行过的命令:
npx vitest run src/services/microcompaction/microcompact.test.ts --coverage.enabled=false,在packages/core下运行,53 个测试通过。npx prettier --check packages/core/src/services/microcompaction/microcompact.ts packages/core/src/services/microcompaction/microcompact.test.ts packages/cli/src/config/settingsSchema.ts docs/users/configuration/settings.md packages/vscode-ide-companion/schemas/settings.schema.json,通过。npx eslint packages/core/src/services/microcompaction/microcompact.ts packages/core/src/services/microcompaction/microcompact.test.ts packages/cli/src/config/settingsSchema.ts,通过。git --no-pager diff --check,通过。node --import tsx/esm scripts/generate-settings-schema.ts,重新生成了packages/vscode-ide-companion/schemas/settings.schema.json。npm run typecheck --workspace @qwen-code/qwen-code-core,通过。npm run typecheck --workspace @qwen-code/qwen-code,通过。npm run build --workspace @qwen-code/qwen-code-core && npm run build --workspace @qwen-code/qwen-code,通过。证据(Before & After)
Before:像
QWEN_MC_KEEP_RECENT=1.5这样的小数 env 值可能进入meta.keepRecent,但切片逻辑会用不同方式隐式转换该值。After:新增测试断言小数 env 值会回退到 settings,不安全整数 env 值会被忽略,小数 settings 会回退到默认值,并且元数据报告整数计数。已测试平台
环境(可选)
本地 macOS 开发环境,已安装仓库 npm workspaces 依赖。
风险和范围
1的整数仍按1处理。关联 Issue
Fixes #5648
AI 协助披露
我使用 Codex 审查变更、对照现有模式做 sanity check,并帮助发现潜在边界情况。