fix(grok): surface ACP slash commands and ignore skills-reload ids#4110
fix(grok): surface ACP slash commands and ignore skills-reload ids#4110Dishah3241 wants to merge 6 commits into
Conversation
Grok advertises skills via ACP available_commands_update, but the provider probe never mapped them into ServerProvider.slashCommands, so the T3 composer stayed empty. Collect those commands during ACP discovery (same shape Claude fills from SDK init). Separately, Grok emits non-numeric JSON-RPC ids such as skills-reload. Effect RpcClient BigInt-coerces request ids and threw, tearing the ACP stream. Drop non-numeric response ids that are not extension-pending before they reach RpcClient.
📝 WalkthroughWalkthroughGrok ACP discovery now receives the workspace directory, discovers slash commands alongside models, and includes them in provider snapshots. ACP transport filtering ignores non-numeric response IDs, with regression coverage for continued session-update decoding. ChangesGrok ACP discovery
ACP transport filtering
Estimated code review effort: 3 (Moderate) | ~25 minutes Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
ApprovabilityVerdict: Needs human review This PR introduces new slash command discovery capability with non-trivial async polling logic, timeout budgeting, and state management. Despite the 'fix' framing, this is a feature addition that changes what gets surfaced to users and warrants human review. You can customize Macroscope's approvability policy. Learn more. |
The ACP discovery session used process.cwd(), so project-local skills could differ from live Grok threads that open under ServerConfig.cwd. Pass the workspace cwd from GrokDriver into checkGrokProviderStatus / session/new, matching Claude's probe pattern.
|
@coderabbitai review |
✅ Action performedReview finished.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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.
Inline comments:
In `@apps/server/src/provider/Layers/GrokProvider.ts`:
- Around line 145-201: Use an Option-wrapped state for slash commands so
waitForGrokSlashCommands can distinguish no available_commands_update
notification from an explicitly empty parsed command list. Initialize the Ref as
None, set it to Some(parseAcpAvailableCommands(...)) in the
acp.handleSessionUpdate callback, and have the polling loop return the contained
list whenever the Option is Some, including an empty list; preserve the timeout
fallback and update the discovery flow in discoverGrokModelsViaAcp accordingly.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: de9b0895-a293-462f-b63a-9b187d0c101c
📒 Files selected for processing (7)
apps/server/src/provider/Drivers/GrokDriver.tsapps/server/src/provider/Layers/GrokProvider.test.tsapps/server/src/provider/Layers/GrokProvider.tsapps/server/src/provider/acp/parseAcpAvailableCommands.test.tsapps/server/src/provider/acp/parseAcpAvailableCommands.tspackages/effect-acp/src/protocol.test.tspackages/effect-acp/src/protocol.ts
Use Option on the slash-command probe ref so waitForGrokSlashCommands returns immediately on an explicit empty command list instead of polling until timeout when no non-empty update arrives.
CodeRabbit: track probe command state with Option (pending vs seen). Cursor: do not return early on Some([]); ACP may send empty then a later non-empty "changed" update. Return non-empty immediately; on timeout use the latest seen list (or []).
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 1d7fa62. Configure here.
An empty available_commands_update no longer burns the full slash-command wait budget, which could push ACP discovery past the 15s outer timeout. Wait up to 250ms after empty for a non-empty follow-up, else accept []. Still wait up to 2s when no notification has arrived yet.
After acp.start(), slash wait no longer always allocates a fresh 2s window. Cap it by time left under the 15s discovery timeout (minus a small reserve) so a slow session setup cannot discard already-discovered models. maxWaitMs <= 0 returns current commands immediately.

Summary
session/update→available_commands_update, including user skills). The Grok provider probe only discovered models and never filledServerProvider.slashCommands, so the composer menu stayed empty (Claude works because it maps SDK init commands).skills-reload: Grok emits non-numeric JSON-RPC ids such asskills-reload. EffectRpcClientdoesBigInt(requestId)and throwsCannot convert skills-reload to a BigInt, which showed up duringcheckGrokProviderStatus/startSession.Changes
packages/effect-acp: DropExit/Chunkmessages whoserequestIdis not a valid Effect RPC bigint and not extension-pending, so RpcClient never BigInt-crashes on agent-internal string ids.GrokProvider: During ACP model discovery, listen foravailable_commands_update, map viaparseAcpAvailableCommands, and publish asslashCommandson the ready snapshot (with a short wait aftersession/new, since Grok sends commands after the create response).Test plan
vp run --filter effect-acp test(31 passed)vp run --filter t3 test(includes new parse tests + GrokProvider; 1425 passed)vp run --filter effect-acp --filter t3 typecheck~/.grok/skills/, open T3 → Grok → confirm/menu lists skills (e.g.factory-plannerif present)Cannot convert skills-reload to a BigIntin server logs on Grok session startNotes
parseSessionUpdateEventstill ignoresavailable_commands_updatefor the thread event stream). Provider snapshot fill is enough for the composer menu, matching how Claude exposes commands.Note
Medium Risk
Touches ACP wire handling and Grok status probing; incorrect filtering could hide legitimate RPC responses, but changes are scoped to non-numeric ids and provider snapshot enrichment.
Overview
Fixes an empty Grok
/composer menu and ACP stream crashes during Grok provider checks.Grok provider discovery now uses
ServerConfig.cwd(notprocess.cwd()) for ACPsession/new, listens foravailable_commands_update, maps entries viaparseAcpAvailableCommands, and publishesslashCommandson the ready provider snapshot. Slash collection is best-effort with a short bounded wait so it does not blow the existing model-discovery timeout.effect-acpprotocol drops JSON-RPC responses whoserequestIdis not a valid bigint when they are not extension-pending (e.g. Grok’sskills-reload), avoidingBigInt(requestId)crashes that tear down the stream.Adds unit tests for the mapper, the protocol path, and explicit workspace
cwdoncheckGrokProviderStatus.Reviewed by Cursor Bugbot for commit 4fde55d. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Surface ACP slash commands in Grok provider and drop non-numeric JSON-RPC response ids
acp.start()to captureavailable_commands_updatenotifications, polls briefly for slash commands, and returns them alongside models in the provider status.ServerProviderSlashCommandobjects before surfacing them.checkGrokProviderStatusanddiscoverGrokModelsViaAcpnow accept an explicitcwdparameter passed fromServerConfig, replacing implicit reliance onprocess.cwd().Macroscope summarized 4fde55d.
Summary by CodeRabbit
New Features
Bug Fixes