Skip to content

feat(pi): optional multi-provider web search for the coding agent#5951

Open
BillLeoutsakosvl346 wants to merge 2 commits into
stagingfrom
feature/pi-search
Open

feat(pi): optional multi-provider web search for the coding agent#5951
BillLeoutsakosvl346 wants to merge 2 commits into
stagingfrom
feature/pi-search

Conversation

@BillLeoutsakosvl346

Copy link
Copy Markdown
Contributor

Summary

Adds an optional internet search capability to the Pi Coding Agent block: a Search Provider dropdown (None, Exa, Serper, Parallel, Firecrawl), off by default, available in all three modes — Create PR, Review Code, and Local Dev.

  • Keys follow the block's existing pattern. The selected provider's key comes from the block field, falling back to Workspace Settings → BYOK, exactly like the model selector. A Sim-hosted key is never spent on search in any mode, so a missing key fails the run with a setup message rather than quietly billing Sim. Switching providers clears the key field, so the previous provider's key cannot be sent to the new one.
  • One tool, two execution paths. Local Dev and Review Code register a host-side web_search tool that reuses the existing exa_search / serper_search / parallel_search / firecrawl_search tools. Create PR has no host in the agent loop, so it gets a generated Pi extension written into the sandbox that makes its own bounded fetch calls. Both paths derive their requests from the same normalizer in search/normalize.ts, and search/parity.test.ts asserts the two produce byte-identical URLs, headers, and bodies per provider — the sandbox copy cannot import Sim's code, so that test is what keeps it from drifting.
  • Results are normalized and treated as untrusted. Every provider collapses to title, URL, snippet, and optional publication date, capped per field and per envelope, with a prompt guideline telling the model the content is untrusted data rather than instructions.
  • Bounded. 20 searches per run (Pi's agent loop has no turn ceiling of its own), a 10s per-call timeout, and failures classified as unauthorized / rate limited / timed out / unreachable instead of echoing provider text, which can carry injected instructions.

Two drive-by fixes it needed: serper_search was dropping the date field on organic results, and Sim's redaction patterns did not match keys named *ApiKey or passphrase.

Test plan

  • search/{normalize,tool,extension-source,parity}.test.ts — 62 tests covering argument clamping, per-provider normalization and fallback chains, envelope byte caps, key-source precedence, failure classification, the per-run budget, and host/sandbox request parity
  • pi-handler, keys, local-backend, cloud-backend, cloud-review-backend, blocks/blocks/pi, redaction, tools/serper — 826 tests pass, including backward compatibility for Pi blocks saved before the fields existed
  • tsc --noEmit, biome check, repo lint and format clean on the rebased base
  • Manual: run each mode against a real key for one provider, and confirm a missing key fails with the setup message

Reviewer notes

Two things worth a second opinion, both deliberate:

  1. Create PR delivers the search key to the sandbox as an env var, which the agent can read — it holds bash. This matches how the model provider key already reaches that mode, and is the reason search refuses a Sim-hosted key everywhere: only a key the user supplied themselves can get there.
  2. Review Code gains an outbound network channel in a mode that otherwise has none, so a malicious PR could in principle exfiltrate repository text through search queries. Bounded at roughly 10 KB per run by the call and query-length caps, and documented in pi.mdx as a reason not to enable search when reviewing untrusted forks of private repos.

Made with Cursor

Adds a search provider dropdown (Exa, Serper, Parallel, Firecrawl) to the Pi
block, off by default. The selected provider's key comes from the block field or
Workspace Settings → BYOK; a Sim-hosted key is never spent, so a missing key
fails the run with a setup message instead of quietly billing Sim.

Search is available in all three modes. Local Dev and Review Code register a
host-side tool that goes through the existing provider tools, while Create PR has
no host in the loop and gets a generated Pi extension in the sandbox. Both paths
derive their requests from one normalizer and are held together by a parity test,
since the sandbox copy cannot import Sim's code.

Results are normalized to title, URL, snippet, and publication date, capped per
field and per envelope, marked untrusted in the prompt, and limited to 20
searches per run so a tool loop cannot drain the workspace's quota.

Co-authored-by: Cursor <cursoragent@cursor.com>
@vercel

vercel Bot commented Jul 25, 2026

Copy link
Copy Markdown

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

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview, Comment Jul 25, 2026 1:58am

Request Review

@greptile-apps

greptile-apps Bot commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds optional, BYOK-only web search to every Pi Coding Agent mode.

  • Introduces provider selection, credential resolution, permission preflight, and secret redaction for Exa, Serper, Parallel AI, and Firecrawl.
  • Registers a normalized host-side search tool for Local Dev and Review Code and generates an equivalent sandbox extension for Create PR.
  • Bounds search calls, request duration, query/result sizes, and normalizes provider failures and result envelopes.
  • Documents the new network boundary and adds provider parity, backend, block configuration, redaction, and normalization tests.
  • Preserves Serper organic-result publication dates and expands sensitive-key detection.

Confidence Score: 5/5

The PR appears safe to merge, with no concrete blocking or independently actionable non-blocking defects identified.

The provider mappings, credential boundaries, permission checks, execution-mode integrations, bounded request behavior, normalization paths, and secret-redaction boundaries are internally consistent and covered by focused parity and backend tests.

Important Files Changed

Filename Overview
apps/sim/executor/handlers/pi/pi-handler.ts Resolves optional search configuration, enforces tool permissions before credential access, and dispatches mode-specific tool implementations.
apps/sim/executor/handlers/pi/search/normalize.ts Defines bounded provider-neutral arguments, request mappings, result normalization, and serialized output limits.
apps/sim/executor/handlers/pi/search/tool.ts Implements the host-side search adapter using existing registered tools, explicit user credentials, failure classification, and a per-run call budget.
apps/sim/executor/handlers/pi/search/extension-source.ts Generates the Create PR sandbox extension with equivalent provider requests, normalization, timeout, response-size, and call-count controls.
apps/sim/executor/handlers/pi/cloud-backend.ts Installs and activates the sandbox search extension when configured while extending credential redaction across surfaced outputs and errors.
apps/sim/executor/handlers/pi/cloud-review-backend.ts Registers host-side web search for Review Code and adjusts its sealed capability prompt and tool allowlist.
apps/sim/executor/handlers/pi/keys.ts Adds strict provider parsing and resolves search credentials exclusively from block input or workspace BYOK.
apps/sim/lib/core/security/redaction.ts Extends sensitive-field recognition to prefixed API-key names and passphrases.
apps/sim/tools/serper/search.ts Preserves the optional date supplied on Serper organic search results.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  Block[Pi block inputs] --> Handler[Pi handler]
  Handler --> Permission[Search permission preflight]
  Permission --> Keys[Block key or workspace BYOK]
  Keys --> Mode{Execution mode}
  Mode -->|Local Dev| Host[Host-side web_search tool]
  Mode -->|Review Code| Host
  Mode -->|Create PR| Sandbox[Generated sandbox extension]
  Host --> Tools[Existing provider ToolConfig]
  Sandbox --> APIs[Provider API]
  Tools --> Normalize[Normalized bounded results]
  APIs --> Normalize
  Normalize --> Agent[Pi agent]
Loading

Reviews (1): Last reviewed commit: "feat(pi): optional multi-provider web se..." | Re-trigger Greptile

`check:utils` bans `JSON.parse(JSON.stringify(...))`. The round-trip was
normalizing the host body to its wire form, which buys nothing here: the bodies
are plain JSON and `toEqual` already ignores undefined members.

Co-authored-by: Cursor <cursoragent@cursor.com>
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