fix(agents): make wrapToolWithBeforeToolCallHook idempotent to prevent double hook execution (fixes #92973)#93009
Conversation
|
Codex review: needs real behavior proof before merge. Reviewed June 14, 2026, 12:27 PM ET / 16:27 UTC. Summary PR surface: Source +21, Tests +86. Total +107 across 3 files. Reproducibility: yes. Source inspection shows Review metrics: none identified. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Rank-up moves:
Proof guidance:
Risk before merge
Maintainer options:
Copy recommended automerge instructionNext step before merge
Security Review findings
Review detailsBest possible solution: Rebuild one current-context before_tool_call wrapper while preserving the current normalized tool shape, then remove the unused test variable and add coverage that asserts the final wrapper keeps normalized parameters. Do we have a high-confidence way to reproduce the issue? Yes. Source inspection shows Is this the best way to solve the issue? No. The PR fixes the stale-context direction but still rebuilds from the saved source tool instead of the normalized tool shape, so it is not yet the best safe fix. Full review comments:
Overall correctness: patch is incorrect AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning high; reviewed against aefd49909d41. Label changesLabel justifications:
Evidence reviewedPR surface: Source +21, Tests +86. Total +107 across 3 files. View PR surface stats
Security concerns:
Acceptance criteria:
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
Co-authored-by: zengLingbiao <[email protected]>
aa5b75f to
f903512
Compare
|
Land-ready verification for exact head
The probe also confirmed the normalized empty-object schema remained intact after rewrap. Fresh autoreview found no accepted/actionable findings. Exact-head CI is green, including the real-behavior-proof gate. Known proof gap: no external provider request was run specifically for this patch because it changes wrapper lifecycle only, not OpenAI/Anthropic serialization or transport. Both provider-policy assembly paths were exercised directly, and the unchanged provider/tool-call lanes are green in CI. |
Prevent duplicate `before_tool_call` execution when an already wrapped tool passes through schema normalization and coding-tool assembly. Preserve the normalized schema while replacing stale wrapper context with the current agent/session/run context. Fixes openclaw#92973. Co-authored-by: zengLingbiao <[email protected]>
Prevent duplicate `before_tool_call` execution when an already wrapped tool passes through schema normalization and coding-tool assembly. Preserve the normalized schema while replacing stale wrapper context with the current agent/session/run context. Fixes #92973. Co-authored-by: zengLingbiao <[email protected]> (cherry picked from commit 07dfdd4)
Prevent duplicate `before_tool_call` execution when an already wrapped tool passes through schema normalization and coding-tool assembly. Preserve the normalized schema while replacing stale wrapper context with the current agent/session/run context. Fixes openclaw#92973. Co-authored-by: zengLingbiao <[email protected]>
Prevent duplicate `before_tool_call` execution when an already wrapped tool passes through schema normalization and coding-tool assembly. Preserve the normalized schema while replacing stale wrapper context with the current agent/session/run context. Fixes openclaw#92973. Co-authored-by: zengLingbiao <[email protected]>
Prevent duplicate `before_tool_call` execution when an already wrapped tool passes through schema normalization and coding-tool assembly. Preserve the normalized schema while replacing stale wrapper context with the current agent/session/run context. Fixes openclaw#92973. Co-authored-by: zengLingbiao <[email protected]>
Summary
before_tool_callwrapper provenance through tool schema normalization.Verification
node scripts/run-vitest.mjs src/agents/agent-tools.create-openclaw-coding-tools.test.ts src/agents/agent-tools.schema.test.ts src/agents/agent-tools.before-tool-call.integration.e2e.test.ts src/agents/agent-tools.before-tool-call.e2e.test.ts src/agents/agent-tool-definition-adapter.test.ts src/agents/tool-search.test.ts src/mcp/plugin-tools-handlers.cancel.test.tscreateOpenClawCodingTools, a real active channel registry, and one deliberately prewrapped tool:openai: one hook call, one execution, current session/run context, normalized empty-object schema retained.anthropic: one hook call, one execution, current session/run context, normalized empty-object schema retained.pnpm check:changed:tbx_01kv3n790s40ertvxzv2xsbbzfpassed.tbx_01kv3nqsg2yc40gszdpscnjs7mpassed, 53 files and 951 tests.Real behavior proof
Behavior addressed: An already wrapped tool passing through
normalizeToolParametersandcreateOpenClawCodingToolscould acquire a nestedbefore_tool_callwrapper, causing duplicate policy/plugin hook execution.Real environment tested: macOS host, Node with tsx, production OpenClaw tool assembly and plugin registry paths; Linux Testbox for changed-surface checks.
Exact steps or command run after this patch: Ran a Node/tsx production-path probe that registered a channel tool already wrapped with stale context, assembled it once with
modelProvider: "openai"and once withmodelProvider: "anthropic", then executed each resulting tool.Evidence after fix: Copied live console output from the production-path probe:
Observed result after fix: Each provider-policy path executed the underlying tool once, fired the hook once, adopted the current run context, and retained
{ "type": "object", "properties": {} }after normalization.What was not tested: No external model API request was needed because this change does not touch provider serialization or transport. Official OpenAI and Anthropic tool schema paths were exercised through production assembly; direct provider tool calls remain covered by unchanged provider code and CI.