Skip to content

fix(agent-core-v2): count validation-rejected tool calls toward the repeat breaker - #2317

Merged
7Sageer merged 2 commits into
mainfrom
fix/agent-core-v2-dedup-register-rejected
Jul 28, 2026
Merged

fix(agent-core-v2): count validation-rejected tool calls toward the repeat breaker#2317
7Sageer merged 2 commits into
mainfrom
fix/agent-core-v2-dedup-register-rejected

Conversation

@7Sageer

@7Sageer 7Sageer commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Related Issue

No linked issue — v2 port of #2313 (merged as de0ba9d), explained below.

Problem

Same gap as #2313, on the v2 engine: the repeat breaker (toolDedupe) only counts tool calls that fire onBeforeExecuteTool. Calls rejected in preflight (missing/unavailable tool, guard denial, invalid args) never fire that veto event — and v2 additionally skipped the onDidExecuteTool hook for them, so the breaker never saw them at all. A model re-issuing the same invalid call got no reminders and no force-stop; the turn only ended at maxSteps, burning a provider request per step.

Reproduction (test/agent/toolDedupe/toolDedupe.test.ts): 12 identical Bash calls missing the required command + one trailing text response. Before: the turn consumes the 13th generation. After: it stops at exactly 12 with the full none → r1×2 → r2×3 → r3×4 → stop escalation chain.

What changed

v2 port of #2313, adapted to the DI hook architecture — the v1 fix hooked finalizeToolResult because every v1 call passes through it; in v2 the equivalent chokepoint (onDidExecuteTool) did not run for preflight-rejected calls, so the executor change comes first:

  • toolExecutorService.ts: run onDidExecuteTool for preflight-rejected calls too (tool stays unset for them — already optional in the hook contract). Existing hook consumers are unaffected: prompt delivery is delivery-gated, goal-outcome matching requires a successful UpdateGoal, and external hooks now fire PostToolUseFailure for rejected calls, matching v1 semantics. Rejected results also flow through the standard result normalization, so they now carry the same shape as runnable results (stopTurn: false).
  • toolDedupeService.ts: register calls that bypassed onBeforeExecuteTool late, at onDidExecuteTool time (registerSkipped, no-op when already registered). Args that failed JSON parsing normalize to {}, which would key every malformed-but-different attempt identically — those are keyed on the raw arguments text so only true re-issues count as repeats.
  • parseToolCallArguments moves from toolExecutorService.ts to the shared #/tool/tool-args-parse module so the dedupe domain reuses it instead of importing an impl file.
  • Tests: dedupe-level (rejected-call streak force-stops at 12 keeping the error flag; no double registration; identical/different malformed-args keying) and the turn-level reproduction above, plus the negative case (12 distinct malformed calls must not force-stop).

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue, or explained the problem above.
  • I have added tests that prove my feature works.
  • Ran gen-changesets skill, or this PR needs no changeset.
  • Ran gen-docs skill, or this PR needs no doc update.

@changeset-bot

changeset-bot Bot commented Jul 28, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 9d99e64

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@moonshot-ai/agent-core-v2 Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Jul 28, 2026

Copy link
Copy Markdown
pnpm dlx https://pkg.pr.new/@moonshot-ai/kimi-code@9d99e64
npx https://pkg.pr.new/@moonshot-ai/kimi-code@9d99e64

commit: 9d99e64

@7Sageer
7Sageer merged commit d88b377 into main Jul 28, 2026
14 checks passed
@7Sageer
7Sageer deleted the fix/agent-core-v2-dedup-register-rejected branch July 28, 2026 11:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant