Skip to content

feat(websearch): batched-query schema for Parallel#28219

Open
NormallyGaussian wants to merge 4 commits into
anomalyco:devfrom
NormallyGaussian:feat-websearch-objective-param
Open

feat(websearch): batched-query schema for Parallel#28219
NormallyGaussian wants to merge 4 commits into
anomalyco:devfrom
NormallyGaussian:feat-websearch-objective-param

Conversation

@NormallyGaussian
Copy link
Copy Markdown
Contributor

@NormallyGaussian NormallyGaussian commented May 18, 2026

Issue for this PR

Closes #28216

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

When the websearch tool routes to Parallel, the MCP call is currently objective: query, search_queries: [query] — the same string twice. That throws away the two things Parallel's API is designed to combine: a natural-language objective for ranking and a small batch of diverse keyword search_queries for retrieval.

This PR adds objective and additionalQueries (1–2 items) to the tool schema only when Parallel is the resolved provider for the session (env override or OPENCODE_ENABLE_PARALLEL flag). A new helper shouldExposeParallelExtras decides per-call; the Exa-only schema (BaseParameters) is unchanged. Wording on the new fields and the appended description block are lifted from docs.parallel.ai/search/best-practices — the canonical "prefer over repeated keyword searches" / "diverse, 3-6 words, no sentences" language — so the model is nudged toward one batched call instead of three chained ones.

The exported Parameters type used by execute keeps both fields optional, since the actual params at runtime depend on which model-facing schema was active.

How did you verify your code works?

  • bun test test/tool/websearch.test.ts — 23 pass, including new cases for shouldExposeParallelExtras across every env branch, ParallelParameters accept/reject (objective + additionalQueries required, batch size bounds), and execute-side Parameters tolerating either shape.
  • bun test (full opencode suite) — 2733 pass / 0 fail / 18 snapshots. New snapshots for websearch (base, Exa-only mode) and websearch (parallel mode) lock the model-facing JSON Schema for both gating outcomes.
  • bun run typecheck — clean.
  • bun run lint — 0 errors.
  • Manual TUI run on minimax-m2.5-free (Zen) with OPENCODE_WEBSEARCH_PROVIDER=parallel: prompted "research what Tesla, Ford, and GM each reported for Q1 2026 earnings, especially margins". Confirmed in the dev DB that each websearch part now has a populated objective and additionalQueries array, and each MCP request bundles 3 diverse queries instead of 1.

Screenshots / recordings

Parallel:
image

Exa:
image

DB rows from the manual test, showing the new fields populated (one row per call; objective is a real sentence, additionalQueries has 2 diverse keyword variants):

provider query objective additionalQueries
parallel Tesla Q1 2026 earnings margin Find Q1 2026 earnings and margin performance for Tesla ["Tesla Q1 2026 revenue profit","Tesla Q1 2026 automotive gross margin"]
parallel Ford Q1 2026 earnings margin Find Q1 2026 earnings and margin performance for Ford ["Ford Q1 2026 revenue profit","Ford Q1 2026 operating margin"]
parallel GM Q1 2026 earnings margin Find Q1 2026 earnings and margin performance for GM ["GM Q1 2026 revenue profit","GM Q1 2026 operating margin"]

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

Adds `objective` and `additionalQueries` (min 1, max 2) to the websearch
tool schema when the resolved provider is Parallel. Mirrors the
canonical schema from docs.parallel.ai/search/best-practices: required
fields, 3-6 word query guidance, anti-chaining language in the
description.

The schema and description are gated by a new `shouldExposeParallelExtras`
helper so the fields are only shown to the model when Parallel is the
chosen provider (env override or flag). The execute-side `Parameters`
keeps both fields optional so the tool still works when Parallel is
gated out (Exa-only schema lacks them at the wire layer).

Parallel call site uses the new fields:
  objective       = params.objective ?? params.query
  search_queries  = [params.query, ...(params.additionalQueries ?? [])]

Exa call site unchanged.

Tests:
  - shouldExposeParallelExtras across all env branches
  - ParallelParameters schema accepts/rejects (objective and
    additionalQueries required; size bounds)
  - execute-side Parameters tolerates either shape
  - JSON Schema snapshots for both model-facing variants and the
    execute-side Parameters
- additionalQueries: drop minItems=1, keep maxItems=2. The previous
  required-min-1 over-constrained simple single-topic Parallel searches
  by forcing the model to invent variants. Parallel docs treat 2-3
  total queries as a recommendation, not a hard floor.
- query (Parallel mode): override description to specify keyword shape
  (3-6 words, no sentences). Previously the generic description allowed
  sentence-form input that we then routed into search_queries[0] —
  Parallel expects each entry to be keyword-style, so this fixes a
  schema/runtime mismatch that would have degraded result quality.
- parameters.test.ts: drop the `websearch 1` (execute-side Parameters)
  JSON Schema snapshot. After this PR's refactor, the model only ever
  sees BaseParameters or ParallelParameters; snapshotting Parameters
  under "wire shape" was misleading and didn't guard the gating logic.
- tests updated for the new schema shape.
@NormallyGaussian NormallyGaussian force-pushed the feat-websearch-objective-param branch from 6eac970 to df545d3 Compare May 18, 2026 19:30
@NormallyGaussian NormallyGaussian marked this pull request as ready for review May 18, 2026 19:32
@NormallyGaussian
Copy link
Copy Markdown
Contributor Author

FYI @nexxeln

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE]: Parallel Search: Improve api CALL

1 participant