Skip to content

Dedupe @agentclientprotocol/sdk to fix stale-schema request_permission errors - #156

Merged
soorya-u merged 8 commits into
mainfrom
fix/148-acp-sdk-version-skew
Aug 6, 2026
Merged

Dedupe @agentclientprotocol/sdk to fix stale-schema request_permission errors#156
soorya-u merged 8 commits into
mainfrom
fix/148-acp-sdk-version-skew

Conversation

@soorya-u

@soorya-u soorya-u commented Aug 5, 2026

Copy link
Copy Markdown
Owner

Summary

  • apps/cli depends on @agentclientprotocol/sdk@^1.1.0 directly, but @acp-kit/core@^0.10.2 pins ^0.18.0, which was resolving to a separate, stale 0.18.2 — the schema actually used at runtime by @acp-kit/core's connection factory in apps/cli/src/core/acp/transport.ts.
  • That old schema hard-fails session/request_permission requests (unrecognized array items fail the whole request) where the modern schema tolerates them (drops unrecognized items instead). This caused the repeated Invalid params errors when editing files.
  • Add a bun overrides entry to dedupe @agentclientprotocol/sdk to a single resolved version workspace-wide, bumped to the latest 1.3.0 for headroom against future drift, since the payload shapes are ultimately driven by Claude Code's own frequently-updating engine rather than anything pinned in this repo.
  • Fix a related, pre-existing (but previously latent) type gap surfaced by pointing tsc's hoisted resolution at the 1.x sdk: @acp-kit/core's own .d.ts references SessionModelState, a type dropped entirely from @agentclientprotocol/sdk's 1.x rewrite, which silently degraded to any and leaked into modelsFromSession.

Verification

  • bun pm why @agentclientprotocol/sdk shows a single resolved 1.3.0, used by both @cyrus/cli (direct) and @acp-kit/core (nested).
  • Confirmed the runtime exports @acp-kit/core actually imports (ClientSideConnection, ndJsonStream, PROTOCOL_VERSION) are unchanged in 1.3.0.
  • bun run check:types (workspace-wide) and apps/cli unit suite (105 tests, including all ACP-specific tests) pass.
  • syncpack lint clean.

Fixes #148

Test plan

  • bun install resolves a single @agentclientprotocol/sdk@1.3.0 across the workspace
  • bun run check:types passes workspace-wide
  • apps/cli unit tests pass (105/105)
  • syncpack lint passes

Summary by CodeRabbit

  • Bug Fixes

    • Improved approval requests so diff details are generated when raw change content lacks patch metadata.
    • Added clearer logging for wire-level response errors, including the originating request details.
    • Preserved message processing and forwarding even when matching request information is unavailable.
  • Chores

    • Updated the Agent Client Protocol SDK to version 1.3.0.

soorya-u and others added 3 commits August 5, 2026 22:15
apps/cli depends on @agentclientprotocol/sdk@^1.1.0 directly, but
@acp-kit/core pins ^0.18.0, resolving to a stale 0.18.2 that's actually
used at runtime by @acp-kit/core's connection factory. That old schema
hard-fails session/request_permission requests from the spawned
claude-code-acp bridge that the newer, lenient 1.1.0 schema accepts,
causing repeated "Invalid params" errors when editing files.

Fixes #148

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The prior override pinned the deduped version to 1.1.0, matching what
apps/cli already depended on directly, but that's not the latest
published release. Since the payload shapes causing #148 are driven by
Claude Code's own rapidly-updating engine rather than anything pinned
in this repo, track the newest sdk release for more schema headroom
instead of settling on the first version that happened to fix it.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@acp-kit/core's own .d.ts still references @agentclientprotocol/sdk's
SessionModelState/ModelInfo types, which were dropped entirely in the
1.x rewrite. tsc resolves the hoisted top-level sdk package for type
checking (independent of bun's runtime resolution, which correctly
keeps @acp-kit/core on its declared 0.18.x range), so once that
resolves to 1.x the type silently degrades to any and leaks into
modelsFromSession's .map callback. Mirror the wire shape locally
instead of trusting the broken upstream type.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Aug 5, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cyrus Ready Ready Preview Aug 6, 2026 5:56am

@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The CLI upgrades the ACP SDK, enriches approval request diffs, adds wire error logging with request correlation, and types native session model entries.

Changes

ACP observability and approval mapping

Layer / File(s) Summary
Approval diff enrichment
apps/cli/package.json, package.json, apps/cli/src/core/acp/events.ts, apps/cli/src/core/acp/events.test.ts
The ACP SDK requirement is upgraded. Approval request content is enriched with diff metadata. Tests cover generated additions, deletions, and patch content.
Wire error correlation
apps/cli/src/core/acp/logger.ts, apps/cli/src/core/acp/logger.test.ts, apps/cli/src/core/acp/interactive.ts
Wire middleware tracks JSON-RPC requests, logs correlated errors, removes completed requests, forwards frames, and is enabled in the interactive host. Tests cover ID collisions and unmatched frames.

Session model typing

Layer / File(s) Summary
Native session model typing
apps/cli/src/core/agents/catalog.ts
The catalog defines RawSessionModel and applies it when mapping native session models to model options.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ACPPeer
  participant InteractiveHost
  participant WireErrorLogger
  participant evlog
  ACPPeer->>InteractiveHost: JSON-RPC request
  InteractiveHost->>WireErrorLogger: inbound frame
  WireErrorLogger->>WireErrorLogger: track request by ID
  ACPPeer->>InteractiveHost: outbound error response
  InteractiveHost->>WireErrorLogger: error frame
  WireErrorLogger->>evlog: log request metadata and error
  WireErrorLogger->>InteractiveHost: forward frame
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies SDK deduplication and the stale-schema request_permission errors that the pull request addresses.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/148-acp-sdk-version-skew

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

soorya-u and others added 2 commits August 5, 2026 22:55
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Resolves the conflict in apps/cli/src/core/agents/catalog.ts between
main's hasNativeModelSelection routing fix (#153) and this branch's
RawSessionModel type-safety fix, keeping both: the native/config-option
routing logic from main, with the availableModels array still cast
through RawSessionModel since @acp-kit/core's own .d.ts still can't
resolve SessionModelState against the 1.x sdk.
@agentclientprotocol/sdk's internal request-error console.error was
dropped entirely in the 1.x rewrite (only the notification path still
logs) - confirmed by diffing 0.18.2's dist/acp.js against 1.3.0's
dist/jsonrpc.js. That means bumping the sdk (previous commits on this
branch) traded a loud, truncated error for a completely silent one:
session/request_permission failures now just vanish.

Add a wireMiddleware on the interactive host that taps every JSON-RPC
frame at the transport boundary, before @acp-kit/core's connection
does its own parsing/validation, and logs the originating request
alongside any error response via evlog instead of console.error so
the payload isn't truncated. This sits below @agentclientprotocol/sdk
entirely, so it keeps working regardless of future internal changes to
the sdk's own (evidently unstable) logging.

Lives in its own logger.ts module, separate from interactive.ts's
permission/elicitation host wiring.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
soorya-u and others added 2 commits August 6, 2026 10:39
The pending map was keyed only by JSON-RPC id, but ids are only unique
per direction: cyrus's own outgoing requests (out) and the agent's
incoming requests (in) each have independent id sequences that can
collide on the same number. The old deletion check fired on any frame
carrying result/error regardless of direction, so a response to one of
cyrus's own outgoing requests could evict a still-pending agent
request that happened to share the same id, before its real error
response arrived - losing the correlation this logger exists to
provide.

Only ever mutate `pending` from the two frames that actually belong to
the in-request/out-response pairing this tracks: set on inbound
requests, delete on our own outbound responses.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ions

Root cause of the "Invalid params" failures with no visible cause:
mapApprovalRequest() built toolCall.content directly from the raw ACP
diff content item ({type, path, oldText, newText}) and validated it
with ApprovalRequestEventSchema.parse(), whose DiffSchema requires
patch/additions/deletions - fields the ACP protocol's Diff type never
sends. Every file-edit permission request threw a ZodError before
pushing the approval_request UI event, which is why no popup ever
appeared. That ZodError propagated up through @acp-kit/core's
handlePermissionRequest catch/rethrow into the SDK's JSON-RPC
dispatcher, which correctly (if confusingly) reported it as
"-32602 Invalid params" - nothing to do with the SDK version work in
the earlier commits on this branch, which fixed a real but separate
issue.

The other three event mappers in this file (tool.start/update/end)
already call enrichDiffContent() to compute these fields locally from
oldText/newText before validating; mapApprovalRequest() was simply
missing the same call. Confirmed via a full ClientSideConnection +
createSdkConnectionFactory + createInteractiveHost reproduction fed
the real captured wire payload, and via a regression test that fails
with the exact same ZodError on the old code.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
apps/cli/src/core/acp/events.test.ts (1)

75-87: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert the generated diff values.

expect.any(Number) and expect.any(String) verify only the output types. They do not detect incorrect additions, deletions, or patch content. Assert one addition, one deletion, and the expected changed lines.

Suggested assertions
-							additions: expect.any(Number),
-							deletions: expect.any(Number),
-							patch: expect.any(String),
+							additions: 1,
+							deletions: 1,
+							patch: expect.stringMatching(/-old[\r\n]+\+new/),
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/cli/src/core/acp/events.test.ts` around lines 75 - 87, Strengthen the
diff object assertions in the approval_request test by replacing the broad
additions, deletions, and patch type checks with exact values: one addition, one
deletion, and the expected changed-line content. Keep the existing event,
toolCallId, and path assertions unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@apps/cli/src/core/acp/events.test.ts`:
- Around line 75-87: Strengthen the diff object assertions in the
approval_request test by replacing the broad additions, deletions, and patch
type checks with exact values: one addition, one deletion, and the expected
changed-line content. Keep the existing event, toolCallId, and path assertions
unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 2330bacc-ada9-4a30-ace3-418f85a8d7cf

📥 Commits

Reviewing files that changed from the base of the PR and between e12170c and fc7b3c3.

⛔ Files ignored due to path filters (1)
  • bun.lock is excluded by !**/*.lock
📒 Files selected for processing (8)
  • apps/cli/package.json
  • apps/cli/src/core/acp/events.test.ts
  • apps/cli/src/core/acp/events.ts
  • apps/cli/src/core/acp/interactive.ts
  • apps/cli/src/core/acp/logger.test.ts
  • apps/cli/src/core/acp/logger.ts
  • apps/cli/src/core/agents/catalog.ts
  • package.json

@soorya-u
soorya-u merged commit 9c1c4c9 into main Aug 6, 2026
9 checks passed
@soorya-u
soorya-u deleted the fix/148-acp-sdk-version-skew branch August 6, 2026 06:31
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.

session/request_permission 'Invalid params' errors from stale @agentclientprotocol/sdk version in dependency tree

1 participant