fix(core): validate run_in_background parameter type - #7597
Conversation
|
Thanks for the PR! Template looks good ✓ Problem: this is an observed bug with real evidence, not theoretical hardening. #7571 documents a captured session where an explicit Direction: aligned. The issue asks for exactly this contract — an explicit background request should either be honored or fail fast, never silently downgrade. Honoring nested background is out of scope for v1 (a nested launcher can't honor the completion contract: Size: core path ( Approach: scope feels right. The guard reuses the existing Moving on to code review. 🔍 中文说明感谢贡献! 模板完整 ✓ 问题:这是一个已观测到的 bug,有真实证据,不是理论性加固。#7571 记录了一次捕获的会话:在非顶层上下文中显式传入 方向:对齐。issue 要求的正是这个契约——显式后台请求要么被正常执行,要么快速失败,绝不应静默降级。v1 不支持嵌套后台执行(嵌套启动方无法履行完成契约:其工具集不含 规模:触及核心路径( 方案:范围合理。保护逻辑复用了现有的 进入代码审查 🔍 — Qwen Code · qwen3.8-max-preview Reviewed at |
Code reviewBefore reading the diff, my independent take on #7571 was: detect an explicit What I verified against the code:
No correctness, security, or convention issues found. No duplication — the existing helper is reused. Real-scenario testingThis change is a core scheduling contract with no UI surface, and the real-world trigger — a model choosing The "before" evidence is the issue's captured session (silent foreground, ~192s / ~991K tokens) plus the old test that asserted the downgrade ( 中文说明代码审查在读 diff 之前,我对 #7571 的独立方案是:在 针对代码核实的内容:
未发现正确性、安全性或规范问题。无重复代码——复用了现有辅助方法。 真实场景测试此变更是一个没有 UI 表面的核心调度契约,而真实世界的触发条件——模型在真正的嵌套 subagent 内部选择 "修复前"证据是 issue 捕获的会话(静默前台,约 192 秒 / 约 99 万 token)加上旧测试对降级的断言;diff 将其替换为拒绝断言。ESLint 和 — Qwen Code · qwen3.8-max-preview Reviewed at |
|
Confidence: 5/5 — a textbook minimal fix: reuses the existing spawn-block helper, changes nothing beyond the intended contract, and is fully covered by deterministic tests that drive the real code path. Stepping back: this solves a real, evidenced problem (the ~192s / ~991K-token silent-foreground incident in #7571), and it does the smallest thing that satisfies the issue's contract — an explicit background request from a nested context now fails fast with an actionable message instead of silently changing execution mode. The implementation matches my independent proposal; I found no simpler path it missed. Every line in the diff earns its place — the guard, the helper reuse, the description updates, and the non-boolean check that keeps the guard from being bypassed. There are no drive-by edits. The behavior change is intentional and correctly bounded: only an explicit The one thing this PR doesn't have is a model-driven TUI before/after, but that's the right call: the trigger is nondeterministic and there's no UI surface, so the deterministic test against the real 中文说明置信度:5/5 —— 一个教科书式的最小修复:复用现有的 spawn-block 辅助方法,除目标契约外没有任何改动,并由驱动真实代码路径的确定性测试完整覆盖。 退一步看:这解决了一个真实、有证据的问题(#7571 中约 192 秒 / 约 99 万 token 的静默前台事件),并且用满足 issue 契约的最小方式实现——嵌套上下文中的显式后台请求现在会带着可执行的信息快速失败,而不是静默改变执行模式。实现与我的独立方案一致;我没有找到它遗漏的更简路径。diff 中每一行都物有所值——守卫、辅助方法复用、描述更新,以及防止守卫被绕过的非 boolean 校验。没有顺手改动。 行为变更是有意的且边界正确:只有嵌套会话中显式的 这个 PR 唯一没有的是模型驱动的 TUI before/after,但这是正确的选择:触发条件不确定且没有 UI 表面,因此针对真实 — Qwen Code · qwen3.8-max-preview Reviewed at |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
LGTM, looks ready to ship. ✅
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Reviewed. Suggestions are inline.
— qwen3.7-max via Qwen Code /review
…il-fast # Conflicts: # packages/core/src/tools/agent/agent.test.ts # packages/core/src/tools/agent/agent.ts
|
Merged the latest main to clear the conflict and kept the nested background rejection debug trace in place. Verified with |
gwinthis
left a comment
There was a problem hiding this comment.
Review: APPROVE (C=0)
Minimal defensive validation (+17/-0): rejects run_in_background: 'true' (string) with a clear error message. Models sometimes pass string "true" instead of boolean true — this catches it at the validation boundary before the value reaches the agent launcher.
Verification: Test covers the exact case ('true' string → /run_in_background.*boolean/i error). The @ts-expect-error annotation correctly documents that raw model parameters are untrusted.
Pattern: Validate model-supplied parameters at the tool boundary. The model's JSON schema says boolean, but the actual payload is untrusted — typeof checks are the right defense.
中文说明
评审:APPROVE (C=0)
最小化防御性校验(+17/-0):拒绝 run_in_background: 'true'(字符串)。模型有时传字符串 "true" 而非布尔 true——在工具边界处捕获。
模式: 在工具边界校验模型提供的参数。JSON schema 说 boolean,但实际 payload 不可信——typeof 检查是正确的防御。
— qwen3.7-max via Qwen Code /review
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
— qwen3.7-max via Qwen Code /review
|
Closing this follow-up because #7593 already fixed the failure mode reported in #7571. The original session’s Agent calls used boolean run_in_background values; this PR only handles a separate malformed string input that was not involved in the incident. If AgentTool’s broader schema-validation inconsistency is observed in practice, it should be addressed as a separate, evidence-driven change rather than as a one-field follow-up here. |
What this PR does
Rejects non-boolean
run_in_backgroundvalues at the Agent tool's raw parameter boundary, before an invocation is created.Why it's needed
The Agent tool uses custom parameter validation and does not invoke the base JSON Schema validator. OpenAI-compatible tool arguments are parsed from model-provided JSON and reach this validator without property-level type enforcement. A value such as
"true"therefore bypasses the strict boolean guard added by #7593 and then participates in background routing through JavaScript truthiness: a top-level call runs in the background, while a nested call silently falls back to the foreground.Rejecting malformed values keeps the execution contract consistent and prevents non-boolean inputs from bypassing the nested-background fix.
Reviewer Test Plan
How to verify
run_in_background: "true"as a raw Agent tool parameter and confirm validation returns a boolean-type error before invocation construction.true,false, and omitted values retain their existing behavior.trueremains handled by the guard merged in fix(core): reject nested background requests #7593.Evidence (Before & After)
Before: latest
mainaccepts a raw string value and routes it according to JavaScript truthiness.After: the malformed value is rejected during parameter validation. The complete core Agent test file passes 198/198 tests; build, typecheck, and ESLint also pass. Screenshots are N/A because this is a non-UI parameter-validation change.
Tested on
Environment (optional)
Local Node.js 22 development environment.
Risk & Scope
Linked Issues
Follow-up to #7593
Related: #7571
中文说明
这个 PR 做了什么
在创建 invocation 之前,于 Agent 工具的原始参数边界拒绝非 boolean 类型的
run_in_background值。为什么需要
Agent 工具使用自定义参数校验,并不会调用基础 JSON Schema 校验器。OpenAI 兼容的工具参数从模型提供的 JSON 中解析后,在没有属性级类型约束的情况下到达该校验逻辑。因此,
"true"这样的值会绕过 #7593 添加的严格 boolean 保护,并通过 JavaScript truthiness 参与后台路由:顶层调用会在后台执行,嵌套调用则会静默回退到前台。拒绝异常类型的值可以保持执行契约一致,并防止非 boolean 输入绕过嵌套后台修复。
Reviewer 测试计划
如何验证
run_in_background: "true"作为 Agent 工具原始参数传入,确认校验会在构造 invocation 之前返回 boolean 类型错误。true、false以及省略该参数时,原有行为保持不变。true时,仍由 fix(core): reject nested background requests #7593 合入的保护逻辑处理。前后证据
修复前:最新
main会接受原始字符串值,并根据 JavaScript truthiness 对其进行路由。修复后:异常类型的值会在参数校验阶段被拒绝。完整 core Agent 测试文件 198/198 通过,build、typecheck 和 ESLint 也均通过。该变更属于非 UI 参数校验,因此截图不适用。
测试平台
环境
本地 Node.js 22 开发环境。
风险与范围
关联 Issue
#7593 的后续补强
相关:#7571