fix(cursor): reject WebFetch requests in band without hosted execution - #520
Open
JS-banana wants to merge 1 commit into
Open
fix(cursor): reject WebFetch requests in band without hosted execution#520JS-banana wants to merge 1 commit into
JS-banana wants to merge 1 commit into
Conversation
When a Cursor-backed model requests hosted WebFetch, the provider previously aborted the entire Run. This adds an in-band rejected response without granting hosted execution authority, lets the Run continue to Pi-owned tools or textual explanation, and bounds repeated requests to 3 rejections per Run. Closes openpi-dev#519 Related to openpi-dev#234, openpi-dev#484
tt-a1i
approved these changes
Sep 9, 2026
tt-a1i
left a comment
Collaborator
There was a problem hiding this comment.
Reviewed at exact head 6dd788c. Standards and Spec both pass with no P0-P3 findings. The wire surface is rejection-only, hosted WebFetch execution remains unavailable, Pi retains tool and permission ownership, unsupported interaction queries still fail closed, and recovery is bounded. Exact-head targeted tests and hosted CI are green.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When using a Cursor-backed model with Pi tools enabled (e.g.
cursor/cursor-grok-4.6-high), web fetch requests trigger a server-sideinteractionQuery(field 9:webFetchRequestQuery). Previously, the provider immediately threw an error upon receiving anyinteractionQuery, terminating the entireAgentService/RunwithstopReason: "error". This left the model no opportunity to recover, fall back to advertised Pi tools, or explain the limitation to the user.Closes #519
Related to #234, #484.
Value
Cursor-backed turns can gracefully handle hosted web fetch requests without aborting. The provider denies cloud-hosted web fetching in band, preserving Pi's exclusive tool ownership and permission boundaries while allowing the Run to continue to advertised Pi tools or clear textual explanations.
Approach
extensions/ai-providers/cursor/proto.ts, defineAgentClientMessage.interactionResponse(field 6), responseid(field 1), andWebFetchRequestResponse(field 9) with only therejected(field 2, carryingreason: string) branch. Noapprovedschema or hosted execution path is defined, ensuring strict fail-closed behavior.extensions/ai-providers/cursor/provider.ts, handlewebFetchRequestQueryby sending a correlatedinteractionResponsewith distinct feedback depending on whether Pi tools are advertised or in chat-only mode, allowing the Run to continue.MAX_WEB_FETCH_REJECTIONS = 3). On the fourth request, send the rejection and then settle explicitly with a terminal recovery-limit error, preventing infinite model loops.interactionQuerycases (such asaskQuestionInteractionQuery,switchModeRequestQuery,exaSearchRequestQuery) continue to fail closed explicitly. No MCP tools are renamed or filtered, and existing native exec handling (fix(cursor): recover from native tool requests without native execution #484) is untouched.Validation
node --test --experimental-strip-types tests/extensions/ai-providers/cursor.test.tspassed: 34 passed, 0 failed.Coverage includes:
interactionResponseandwebFetchRequestResponse.rejected;readtool execution and result replay;bun run checkpassed: config contract, discipline ledger, Web build & typecheck, Biome format check, Biome lint, andtsc --noEmit.bun run testpassed: Node 1,469 passed / 1 skipped / 0 failed; Vitest 9 files, 130 passed.git diff --checkpassed.Using Pi 0.85.1 and real account
cursor/cursor-grok-4.6-high:--tools read: The model requested web fetch, received the rejection, and concluded with assistantstopexplaining the inability to fetch, exiting 0 without terminal error.--tools read,bash: The model requested web fetch, received the rejection, successfully switched to the advertised Pibashtool to runcurl -fsSL --max-time 20 https://example.com/, received the HTML output, and concluded with assistantstopreporting the page title<title>Example Domain</title>, exiting 0.(Evidence boundary: While live validation confirmed successful Pi tool fallback under
read,bash, this is an exploratory recovery opportunity and not a claim that all models or prompts are guaranteed to recover automatically.)Impact
interactionResponsehandling and bounded rejection tracking withinstreamCursor.