feat(parallel): add Parallel as a bundled web_search provider#85158
Conversation
Dependency Changes DetectedThis PR changes dependency-related files. Maintainers should confirm these changes are intentional. Changed files:
Maintainer follow-up:
|
|
Warning Review the following alerts detected in dependencies. According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.
|
|
Codex review: needs real behavior proof before merge. Reviewed June 3, 2026, 2:58 AM ET / 06:58 UTC. Summary PR surface: Source +626, Tests +674, Docs +141, Config +35, Other +6. Total +1482 across 27 files. Reproducibility: unclear. The review failed before ClawSweeper could establish a reproduction path. Review metrics: none identified. Merge readiness Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch. Risk before merge
Maintainer options:
Next step before merge
Review detailsBest possible solution: Retry the Codex review after fixing the execution failure. Do we have a high-confidence way to reproduce the issue? Unclear. The review failed before ClawSweeper could establish a reproduction path. Is this the best way to solve the issue? Unclear. Retry the review first so ClawSweeper can evaluate the actual issue and fix direction. AGENTS.md: unclear because the file could not be read completely. Codex review notes: model gpt-5.5, reasoning high; reviewed against 2c9297339817. Label changesLabel changes:
Label justifications:
Evidence reviewedPR surface: Source +626, Tests +674, Docs +141, Config +35, Other +6. Total +1482 across 27 files. View PR surface stats
What I checked:
Likely related people:
What the crustacean ranks mean
Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics. How this review workflow works
|
b89f346 to
628cf23
Compare
628cf23 to
aa5fded
Compare
aa5fded to
1ef1300
Compare
1ef1300 to
085953c
Compare
Dependency GuardThis PR changes dependency-related files. Maintainers should confirm these changes are intentional. Changed files:
Maintainer follow-up:
|
Dependency graph changes are blockedOpenClaw does not accept dependency graph changes through PRs unless a repository admin or security explicitly authorizes the current head SHA. Dependency updates are generated internally by maintainers so external PRs cannot change the resolved graph. Detected dependency graph changes:
Auto-scrub was not attempted because this PR changes package manifest dependency graph fields:
Dependency graph changes must be reviewed by security or handled by maintainers internally. Please remove lockfile changes manually if they are not needed. To remove lockfile changes, restore them from the target branch: git fetch origin
git checkout 'origin/main' -- 'pnpm-lock.yaml'
git commit -m 'chore: remove dependency lockfile change'
git pushIf this PR intentionally needs a dependency graph change, ask a repository admin or member of The action will approve the current head SHA ( |
085953c to
225e302
Compare
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. Re-review progress:
|
225e302 to
db84391
Compare
- New extensions/parallel package modeled on extensions/exa
- Wires Parallel's POST /v1/search through the generic web_search contract,
exposing Parallel's recommended {objective, search_queries} shape (plus
optional count, session_id, client_model) so the model can supply both the
natural-language goal and 2-3 short keyword queries as Parallel docs advise
- client_model lets the model report its own slug so Parallel can tailor
optimizations for the consuming model's capabilities; partitions the cache
by client_model so different models do not silently share ranked excerpts
- Honors top-level tools.web.search.{maxResults,timeoutSeconds,cacheTtlMinutes}
via the shared SDK helpers (mergeScopedSearchConfig, withTrustedWebSearchEndpoint,
buildSearchCacheKey, read/writeCachedSearchPayload)
- Auto-detect order 75; auth via PARALLEL_API_KEY or
plugins.entries.parallel.config.webSearch.apiKey
- Optional baseUrl override for proxies (e.g. Cloudflare AI Gateway)
- Threads caller-supplied session_id through follow-up calls; strips
auto-generated session_id from the shared cache to avoid cross-task leaks
- Always sends advanced_settings.max_results so result volume matches the
OpenClaw web_search default (5) instead of Parallel's default (10)
- Identifies the plugin via User-Agent header built from package version
- Runtime accepts the generic `query` arg as a fallback so the operator
CLI (openclaw capability web.search) keeps working when Parallel is the
active provider: it is promoted into the lone `search_queries` entry.
`objective` stays optional and is never synthesized from a keyword
query (Parallel documents it as natural-language intent). Agent callers
using the native objective+search_queries shape take precedence; the
schema still advertises only the native keys
- Updates the agent tool-display extractor (src/agents/tool-display-common.ts)
to recognize Parallel's objective+search_queries shape so calls render with
query context in CLI progress and Codex activity metadata
- Adds /tools/parallel-search docs page, web.md provider listing, docs nav,
labeler entry, per-plugin registration contract test, and minimal core
touch-points (legacy migrate, registration cases, providers contract list,
runtime bundled list, vitest extension paths)
db84391 to
12a2b69
Compare
…aw#85158) - New extensions/parallel package modeled on extensions/exa - Wires Parallel's POST /v1/search through the generic web_search contract, exposing Parallel's recommended {objective, search_queries} shape (plus optional count, session_id, client_model) so the model can supply both the natural-language goal and 2-3 short keyword queries as Parallel docs advise - client_model lets the model report its own slug so Parallel can tailor optimizations for the consuming model's capabilities; partitions the cache by client_model so different models do not silently share ranked excerpts - Honors top-level tools.web.search.{maxResults,timeoutSeconds,cacheTtlMinutes} via the shared SDK helpers (mergeScopedSearchConfig, withTrustedWebSearchEndpoint, buildSearchCacheKey, read/writeCachedSearchPayload) - Auto-detect order 75; auth via PARALLEL_API_KEY or plugins.entries.parallel.config.webSearch.apiKey - Optional baseUrl override for proxies (e.g. Cloudflare AI Gateway) - Threads caller-supplied session_id through follow-up calls; strips auto-generated session_id from the shared cache to avoid cross-task leaks - Always sends advanced_settings.max_results so result volume matches the OpenClaw web_search default (5) instead of Parallel's default (10) - Identifies the plugin via User-Agent header built from package version - Runtime accepts the generic `query` arg as a fallback so the operator CLI (openclaw capability web.search) keeps working when Parallel is the active provider: it is promoted into the lone `search_queries` entry. `objective` stays optional and is never synthesized from a keyword query (Parallel documents it as natural-language intent). Agent callers using the native objective+search_queries shape take precedence; the schema still advertises only the native keys - Updates the agent tool-display extractor (src/agents/tool-display-common.ts) to recognize Parallel's objective+search_queries shape so calls render with query context in CLI progress and Codex activity metadata - Adds /tools/parallel-search docs page, web.md provider listing, docs nav, labeler entry, per-plugin registration contract test, and minimal core touch-points (legacy migrate, registration cases, providers contract list, runtime bundled list, vitest extension paths)
…aw#85158) - New extensions/parallel package modeled on extensions/exa - Wires Parallel's POST /v1/search through the generic web_search contract, exposing Parallel's recommended {objective, search_queries} shape (plus optional count, session_id, client_model) so the model can supply both the natural-language goal and 2-3 short keyword queries as Parallel docs advise - client_model lets the model report its own slug so Parallel can tailor optimizations for the consuming model's capabilities; partitions the cache by client_model so different models do not silently share ranked excerpts - Honors top-level tools.web.search.{maxResults,timeoutSeconds,cacheTtlMinutes} via the shared SDK helpers (mergeScopedSearchConfig, withTrustedWebSearchEndpoint, buildSearchCacheKey, read/writeCachedSearchPayload) - Auto-detect order 75; auth via PARALLEL_API_KEY or plugins.entries.parallel.config.webSearch.apiKey - Optional baseUrl override for proxies (e.g. Cloudflare AI Gateway) - Threads caller-supplied session_id through follow-up calls; strips auto-generated session_id from the shared cache to avoid cross-task leaks - Always sends advanced_settings.max_results so result volume matches the OpenClaw web_search default (5) instead of Parallel's default (10) - Identifies the plugin via User-Agent header built from package version - Runtime accepts the generic `query` arg as a fallback so the operator CLI (openclaw capability web.search) keeps working when Parallel is the active provider: it is promoted into the lone `search_queries` entry. `objective` stays optional and is never synthesized from a keyword query (Parallel documents it as natural-language intent). Agent callers using the native objective+search_queries shape take precedence; the schema still advertises only the native keys - Updates the agent tool-display extractor (src/agents/tool-display-common.ts) to recognize Parallel's objective+search_queries shape so calls render with query context in CLI progress and Codex activity metadata - Adds /tools/parallel-search docs page, web.md provider listing, docs nav, labeler entry, per-plugin registration contract test, and minimal core touch-points (legacy migrate, registration cases, providers contract list, runtime bundled list, vitest extension paths)
…aw#85158) - New extensions/parallel package modeled on extensions/exa - Wires Parallel's POST /v1/search through the generic web_search contract, exposing Parallel's recommended {objective, search_queries} shape (plus optional count, session_id, client_model) so the model can supply both the natural-language goal and 2-3 short keyword queries as Parallel docs advise - client_model lets the model report its own slug so Parallel can tailor optimizations for the consuming model's capabilities; partitions the cache by client_model so different models do not silently share ranked excerpts - Honors top-level tools.web.search.{maxResults,timeoutSeconds,cacheTtlMinutes} via the shared SDK helpers (mergeScopedSearchConfig, withTrustedWebSearchEndpoint, buildSearchCacheKey, read/writeCachedSearchPayload) - Auto-detect order 75; auth via PARALLEL_API_KEY or plugins.entries.parallel.config.webSearch.apiKey - Optional baseUrl override for proxies (e.g. Cloudflare AI Gateway) - Threads caller-supplied session_id through follow-up calls; strips auto-generated session_id from the shared cache to avoid cross-task leaks - Always sends advanced_settings.max_results so result volume matches the OpenClaw web_search default (5) instead of Parallel's default (10) - Identifies the plugin via User-Agent header built from package version - Runtime accepts the generic `query` arg as a fallback so the operator CLI (openclaw capability web.search) keeps working when Parallel is the active provider: it is promoted into the lone `search_queries` entry. `objective` stays optional and is never synthesized from a keyword query (Parallel documents it as natural-language intent). Agent callers using the native objective+search_queries shape take precedence; the schema still advertises only the native keys - Updates the agent tool-display extractor (src/agents/tool-display-common.ts) to recognize Parallel's objective+search_queries shape so calls render with query context in CLI progress and Codex activity metadata - Adds /tools/parallel-search docs page, web.md provider listing, docs nav, labeler entry, per-plugin registration contract test, and minimal core touch-points (legacy migrate, registration cases, providers contract list, runtime bundled list, vitest extension paths)
…26.6.5) (#963) This PR contains the following updates: | Package | Update | Change | |---|---|---| | [ghcr.io/openclaw/openclaw](https://openclaw.ai) ([source](https://github.com/openclaw/openclaw)) | patch | `2026.6.1` → `2026.6.5` | --- ### Release Notes <details> <summary>openclaw/openclaw (ghcr.io/openclaw/openclaw)</summary> ### [`v2026.6.5`](https://github.com/openclaw/openclaw/blob/HEAD/CHANGELOG.md#202665) [Compare Source](openclaw/openclaw@v2026.6.1...v2026.6.5) ##### Highlights - QQBot now strips model reasoning/thinking scaffolding before native delivery, preventing raw `<thinking>` content from leaking into channel replies. ([#​89913](openclaw/openclaw#89913), [#​90132](openclaw/openclaw#90132)) Thanks [@​openperf](https://github.com/openperf). - MCP tool results now coerce `resource_link`, `resource`, `audio`, malformed image, and future non-text/image blocks at the materialize boundary, preventing Anthropic 400s and poisoned session history after a tool returns richer MCP content. ([#​90710](openclaw/openclaw#90710), [#​90728](openclaw/openclaw#90728)) Thanks [@​RanSHammer](https://github.com/RanSHammer) and [@​849261680](https://github.com/849261680). - Anthropic extended-thinking sessions recover after prompt-cache expiry or Gateway restart because stream start events wait for `message_start`, letting pre-generation signature errors trigger the existing recovery retry. ([#​90667](openclaw/openclaw#90667), [#​90697](openclaw/openclaw#90697)) Thanks [@​openperf](https://github.com/openperf). - Parallel is now a bundled `web_search` provider with `PARALLEL_API_KEY` discovery, guarded endpoint handling, cache-safe session ids, onboarding picker support, and docs. ([#​85158](openclaw/openclaw#85158)) Thanks [@​NormallyGaussian](https://github.com/NormallyGaussian). - Google Vertex ADC users get static catalog rows and runtime model resolution again, while single-provider cooldown recovery and memory adapter status checks are more reliable. ([#​90506](openclaw/openclaw#90506), [#​90609](openclaw/openclaw#90609), [#​90717](openclaw/openclaw#90717), [#​90816](openclaw/openclaw#90816)) Thanks [@​849261680](https://github.com/849261680). - Matrix can preflight voice notes before mention gating, preserve thread reads/replies through Matrix relations pagination, and carry QA coverage for voice and thread flows. ([#​78016](openclaw/openclaw#78016), [#​90415](openclaw/openclaw#90415)) - Auth and plugin install state is more durable: auth profiles now live in SQLite, official npm plugin install records keep their trusted pins, and prerelease fallback integrity checks avoid carrying stale integrity forward. ([#​89102](openclaw/openclaw#89102), [#​88585](openclaw/openclaw#88585)) - macOS node mode no longer silently self-reconnects away from a healthy direct Gateway session, reducing unexpected companion app session churn. ([#​90668](openclaw/openclaw#90668), [#​90815](openclaw/openclaw#90815)) Thanks [@​vrurg](https://github.com/vrurg). - Upgrade and service paths are safer: cron legacy JSON stores migrate during doctor preflight, service env placeholders no longer mask state-dir secrets, WhatsApp startup waits are bounded, and disabled WhatsApp accounts tear down on config reload. ([#​90072](openclaw/openclaw#90072), [#​90208](openclaw/openclaw#90208), [#​90277](openclaw/openclaw#90277), [#​90488](openclaw/openclaw#90488), [#​90486](openclaw/openclaw#90486), [#​87951](openclaw/openclaw#87951), [#​87965](openclaw/openclaw#87965)) Thanks [@​MonkeyLeeT](https://github.com/MonkeyLeeT), [@​sallyom](https://github.com/sallyom), [@​mcaxtr](https://github.com/mcaxtr), and [@​MukundaKatta](https://github.com/MukundaKatta). ##### Changes - Search/providers: add the Parallel bundled web-search plugin, live provider tests, registration contracts, onboarding/docs wiring, and guarded `api.parallel.ai/v1/search` support. ([#​85158](openclaw/openclaw#85158)) Thanks [@​NormallyGaussian](https://github.com/NormallyGaussian). - Matrix/channels: add voice-message preflight and thread-aware read/reply behavior, including Matrix QA scenario wiring and docs for voice-message behavior. ([#​78016](openclaw/openclaw#78016), [#​90415](openclaw/openclaw#90415)) - Skills/ClawHub: install ClawHub skills backed by GitHub repositories through the resolved install API, download the pinned GitHub commit, keep install-policy checks, and report install telemetry after success. ([#​90478](openclaw/openclaw#90478)) Thanks [@​Patrick-Erichsen](https://github.com/Patrick-Erichsen). - Google Chat/channels: add native approval card actions and click handling so Google Chat approvals use platform-native cards instead of generic message flow. - Mobile: Android provider/model screens now surface expiring, unavailable, unresolved, and attention states more clearly, while iOS settings and Talk tabs keep diagnostics, gateway rows, attachment labels, and unavailable Talk controls reachable. - Memory: QMD search can use the new rerank toggle, and memory adapter status uses the resolved default model identity when checking plain status. ([#​61834](openclaw/openclaw#61834)) - Docs/tooling: add Parallel search docs, refresh weather-skill guidance toward `web_fetch`, clarify legacy `openai-codex` auth, document release/test helper scripts, and tighten changed-test routing docs for CI/debugging work. ([#​90028](openclaw/openclaw#90028), [#​90250](openclaw/openclaw#90250)) Thanks [@​fuller-stack-dev](https://github.com/fuller-stack-dev). - Release/process: switch release trains to `YYYY.M.PATCH` monthly patch numbering, keep pre-transition tags compatible, and pin the June 2026 floor at `2026.6.5` after the published beta. - Platform maintenance: refresh Android, Swift/macOS, Docker, CodeQL, Buildx, Docker build/push, and Codex Action dependencies for this release train. ([#​74980](openclaw/openclaw#74980), [#​81757](openclaw/openclaw#81757), [#​86481](openclaw/openclaw#86481), [#​86483](openclaw/openclaw#86483), [#​90601](openclaw/openclaw#90601)) - QQBot: add `/bot-group-allways on|off` slash command (with named-account and default-account support) to toggle whether group messages require an `@mention` before the bot replies, and clear the runtime config snapshot after the write so the new account-level `defaultRequireMention` takes effect immediately without restart. ([#​91423](openclaw/openclaw#91423)) Thanks [@​cxyhhhhh](https://github.com/cxyhhhhh). ##### Fixes - Channel content boundaries: QQBot now strips reasoning/thinking tags before sending, preserving final answers while hiding internal model narration from users. ([#​89913](openclaw/openclaw#89913), [#​90132](openclaw/openclaw#90132)) Thanks [@​openperf](https://github.com/openperf). - Agents/MCP/providers: coerce non-text/image MCP tool-result blocks before they reach provider converters, preserving valid images and turning richer MCP content into text instead of malformed image blocks. ([#​90710](openclaw/openclaw#90710), [#​90728](openclaw/openclaw#90728)) Thanks [@​RanSHammer](https://github.com/RanSHammer) and [@​849261680](https://github.com/849261680). - Anthropic/Codex/ACP/agent recovery: defer Anthropic stream start events until `message_start`, strip stale compaction thinking signatures before Anthropic replay, detect unsigned thinking-only stalls, refresh prompt fences after compaction writes, reject empty completion handoffs, preserve parent streaming-off overrides/shared progress commentary, forward heartbeat metadata to context-engine hooks, and cover Codex session/thread migration edge cases. ([#​90667](openclaw/openclaw#90667), [#​90697](openclaw/openclaw#90697), [#​90163](openclaw/openclaw#90163), [#​90108](openclaw/openclaw#90108), [#​89874](openclaw/openclaw#89874), [#​89505](openclaw/openclaw#89505), [#​90632](openclaw/openclaw#90632), [#​89302](openclaw/openclaw#89302), [#​90729](openclaw/openclaw#90729), [#​90317](openclaw/openclaw#90317), [#​90319](openclaw/openclaw#90319)) Thanks [@​openperf](https://github.com/openperf), [@​100yenadmin](https://github.com/100yenadmin), and [@​ooiuuii](https://github.com/ooiuuii). - Provider/model resolution: preserve Google Vertex ADC auth markers in generated catalogs, re-probe a single-provider primary after cooldown, share Codex model visibility, fail closed for unknown model auth, preserve Codex alias availability, keep unresolved profile refs unknown, and avoid resolving auth while listing models. ([#​90506](openclaw/openclaw#90506), [#​90609](openclaw/openclaw#90609), [#​90717](openclaw/openclaw#90717), [#​90702](openclaw/openclaw#90702)) Thanks [@​849261680](https://github.com/849261680). - Gateway/macOS/mobile: avoid duplicate Gateway probe warnings by identity, rate-limit node pairing requests while preserving paired-node reconnects, keep macOS node mode on a healthy direct Gateway session, keep iOS diagnostics and gateway rows reachable, and avoid Linux ARM Gradle resource tasks during Android builds. ([#​85791](openclaw/openclaw#85791), [#​90147](openclaw/openclaw#90147), [#​90668](openclaw/openclaw#90668), [#​90815](openclaw/openclaw#90815)) Thanks [@​giodl73-repo](https://github.com/giodl73-repo) and [@​vrurg](https://github.com/vrurg). - TUI/chat/Workboard/auto-reply: optimistic user messages stay stable across stale history reloads, runId reassignment, and abort windows instead of disappearing, jumping, or lingering as ghost rows; Workboard stale lifecycle bulk updates no longer overwrite newer status/provenance; message-tool sends now count as delivery. ([#​86205](openclaw/openclaw#86205), [#​89600](openclaw/openclaw#89600), [#​88592](openclaw/openclaw#88592), [#​90123](openclaw/openclaw#90123)) Thanks [@​RomneyDa](https://github.com/RomneyDa). - Cron/update/service env: doctor config preflight now migrates legacy cron JSON stores into SQLite before runtime reads, service env planning skips unresolved placeholders that would mask state-dir `.env` values, and session transcript rewrites keep registry markers/discriminants consistent. ([#​90072](openclaw/openclaw#90072), [#​90208](openclaw/openclaw#90208), [#​90277](openclaw/openclaw#90277), [#​90488](openclaw/openclaw#90488)) Thanks [@​MonkeyLeeT](https://github.com/MonkeyLeeT) and [@​sallyom](https://github.com/sallyom). - Security/config/tooling: guard MCP HTTP redirects, protect global agent config defaults, and keep release/test/tooling proof failures bounded and explicit. ([#​89732](openclaw/openclaw#89732), [#​90145](openclaw/openclaw#90145)) - Channels: WhatsApp restarts when per-account config changes, bounds background startup waits, closes failed sockets, and preserves reconnect behavior; Mattermost slash commands keep their state on `globalThis`; Feishu streaming cards preserve full merged content; voice-call tracks Twilio streams after connect; ClickClack reply tools respect `toolsAllow`. ([#​87951](openclaw/openclaw#87951), [#​87965](openclaw/openclaw#87965), [#​90486](openclaw/openclaw#90486), [#​68113](openclaw/openclaw#68113), [#​90534](openclaw/openclaw#90534), [#​90181](openclaw/openclaw#90181), [#​90607](openclaw/openclaw#90607), [#​89500](openclaw/openclaw#89500)) Thanks [@​MukundaKatta](https://github.com/MukundaKatta), [@​mcaxtr](https://github.com/mcaxtr), [@​infoanton](https://github.com/infoanton), [@​mushuiyu886](https://github.com/mushuiyu886), and [@​sahibzada-allahyar](https://github.com/sahibzada-allahyar). - Feishu: retry transient send rate-limit errors (HTTP 429, per-chat code 230020, tenant-level code 11232) with linear backoff, including SDK responses that fulfill with rate-limit bodies instead of throwing, and route streaming-card sends through the retry wrapper. ([#​89659](openclaw/openclaw#89659)) Thanks [@​ladygege](https://github.com/ladygege). - Release/CI/E2E: main CI guard drift, PR merge diff scoping, live Docker credential staging, base-image qualification, installer Docker classification, Playwright dependency install recovery, API-key auth for Codex live Docker lanes, Parallels option terminators, and JSON-mode progress handling are tighter so release proof fails cleaner. ([#​90532](openclaw/openclaw#90532), [#​90287](openclaw/openclaw#90287), [#​90058](openclaw/openclaw#90058)) Thanks [@​RomneyDa](https://github.com/RomneyDa), [@​hxy91819](https://github.com/hxy91819), and [@​mrunalp](https://github.com/mrunalp). - Release/CI/E2E: Docker E2E and live Docker harness runs now apply default memory, CPU, and process ceilings while preserving explicit per-lane overrides. - Release/CI/E2E: plugin lifecycle matrix resource sampling now fails phases that exceed RSS, wall-clock, or CPU ceilings instead of only logging the measurements. - Release/CI/E2E: Codex npm plugin live assertions now cap transcript discovery and diagnostic log reads so failure proof stays bounded. - Tests/state isolation: QA Lab valid-tool-call metrics now require runtime tool-call evidence when runtime parity data is available instead of counting tool-backed scenario pass status alone. - Tests/state isolation: QA Lab runtime parity now fails planned-only tool-call rows without matching tool results instead of treating matching mock plans as real tool evidence. - Tests/state isolation: provider, media, auth, cron, task, session, sandbox, Gateway, and Codex timeout fixtures now scope more home/state/env data per test, reducing cross-test leakage and making release validation failures less noisy. ([#​90027](openclaw/openclaw#90027), [#​89974](openclaw/openclaw#89974)) </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about these updates again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMDEuMSIsInVwZGF0ZWRJblZlciI6IjQzLjEwMS4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6WyJyZW5vdmF0ZS9jb250YWluZXIiLCJ0eXBlL3BhdGNoIl19--> Reviewed-on: https://git.erwanleboucher.dev/eleboucher/homelab/pulls/963
Summary
Note
AI-assisted PR. Prepared with the help of Claude (Opus 4.7). Implementation, audits, and iterative review were driven by Claude with
codex review --base origin/mainrun four times and two general-purpose subagents (repo-conventions audit + Parallel API best-practices audit against Parallel's docs, two rounds each). All findings addressed; final Codex pass returned "no actionable bugs found." The author personally reviewed every change, ran the live integration end-to-end (see Real behavior proof + Evidence), and understands the code being merged.extensions/parallel/as a new bundledweb_searchprovider modeled onextensions/exa/. Authenticates viaPARALLEL_API_KEY(orplugins.entries.parallel.config.webSearch.apiKey), hitsPOST https://api.parallel.ai/v1/search, and surfaces ranked excerpts through the genericweb_searchcontract.withTrustedWebSearchEndpoint,mergeScopedSearchConfig,buildSearchCacheKey,readCachedSearchPayload/writeCachedSearchPayload,wrapWebContent,resolveSearchTimeoutSeconds,resolveSearchCacheTtlMs,DEFAULT_SEARCH_COUNT); minimal core touch-points for legacy-config migrate, registration contract cases, runtime test allowlists, doctor migration, vitest paths, labeler, and docs nav.CHANGELOG.mdleft to maintainers perCONTRIBUTING.md. No standalone Parallel-only tool (kept scope to the genericweb_searchprovider tool to stay aligned with the Exa pattern and "keep it simple").Motivation
Parallel is purpose-built for agentic web search: it returns compressed, LLM-optimized excerpts ranked by reasoning utility, not human click-through. That fits OpenClaw's
web_searchcontract well and gives users a high-accuracy provider option alongside Brave/Exa/Firecrawl/Tavily/Perplexity. Parallel best practices (docs.parallel.ai/search/best-practices) were checked against the implementation; see Verification.Change Type (select all)
Scope (select all touched areas)
Linked Issue/PR
Real behavior proof (required for external PRs)
web_searchprovider in OpenClaw.pnpm openclaw onboard --flow quickstart --accept-risk --auth-choice skip --skip-channels --skip-skills --skip-daemon --skip-ui --skip-health, gateway viapnpm openclaw gateway run --port 18789 --bind loopback --force, TUI viapnpm openclaw tui, model via a real Anthropic key, search pinned toparallelviapnpm openclaw config set tools.web.search.provider parallel.From the repo root:
In another window:
OPENCLAW_LIVE_TEST=1 node scripts/run-vitest.mjs run extensions/parallel/parallel.live.test.tsapi.parallel.ai/v1/searchreturned real ranked results with asessionIdechoed back. TUI agent successfully usedweb_searchagainst Parallel and surfaced results to the model.searchId/sessionId. Confirmed identifyingUser-Agent: openclaw-parallel/<version> (<platform>)on outbound requests.baseUrloverride).cacheTtlMinutes-driven TTL expiry not exercised live (relies on the shared SDK helper).Root Cause (if applicable)
N/A.
Regression Test Plan (if applicable)
N/A — this is a feature, not a regression fix. Coverage added:
extensions/parallel/src/parallel-web-search-provider.test.ts(20 tests covering schema metadata, credential resolution, base URL normalization, count clamping, response normalization, session-id normalization, long-query → objective adaptation, cache-key partitioning by endpoint/count/session, missing-key payload, top-level web search settings honored end-to-end via mocked SDK fetch helper, session-id cache-leak protection).src/plugins/contracts/plugin-registration.parallel.contract.test.ts.src/plugins/web-search-providers.runtime.test.ts.src/plugins/contracts/providers.contract.test.ts.src/plugin-sdk/test-helpers/plugin-registration-contract-cases.ts.extensions/parallel/parallel.live.test.ts(gated onOPENCLAW_LIVE_TEST=1+PARALLEL_API_KEY).User-visible / Behavior Changes
web_searchprovider option:parallel. Configurable viaPARALLEL_API_KEYenv var orplugins.entries.parallel.config.webSearch.apiKeyconfig.plugins.entries.parallel.config.webSearch.baseUrloverrides the Parallel endpoint (e.g., for Cloudflare AI Gateway proxying). OpenClaw appends/v1/searchwhen the URL doesn't already end there.PARALLEL_API_KEYis the only configured key.https://docs.openclaw.ai/tools/parallel-search.pnpm openclaw onboardsearch-provider picker automatically (dynamic discovery; no static list to update).Diagram (if applicable)
Security Impact (required)
readConfiguredSecretString,readProviderEnvValue). API key flows through the standardwebSearch.apiKeyplugin config path (SecretRef-capable like all other web search providers).api.parallel.ai(or a user-configured base URL). All calls go through the SDK's guardedwithTrustedWebSearchEndpointhelper, which applies the existing OpenClaw network safety policy.withTrustedWebSearchEndpointguard; SSRF/loopback rules unchanged; response excerpts are wrapped viawrapWebContentso they're tagged untrusted before reaching the model.Repro + Verification
Environment
{ "tools": { "web": { "search": { "provider": "parallel", "enabled": true } } }, "plugins": { "entries": { "parallel": { "enabled": true } } } }Steps
pnpm buildexport PARALLEL_API_KEY=par-...pnpm openclaw onboard --flow quickstart --accept-risk --auth-choice skip --skip-channels --skip-skills --skip-daemon --skip-ui --skip-healthpnpm openclaw config set tools.web.search.provider parallel && pnpm openclaw config set plugins.entries.parallel.enabled truepnpm openclaw gateway run --port 18789 --bind loopback --force(window 1)pnpm openclaw tui(window 2), ask the agent to perform a web searchExpected
web_searchroutes to Parallel; response includesprovider: "parallel", ranked results with title/url/excerpts, and asessionId.Actual
Evidence
./scripts/clawlog.sh | grep parallelshows outboundapi.parallel.ai/v1/searchPOSTsHuman Verification (required)
web_searchcall via the TUI hits Parallel and surfaces real results to the model; live test (parallel.live.test.ts) hits the realapi.parallel.ai/v1/searchendpoint and asserts shape; onboard flow shows Parallel automatically in the search-provider picker; base URL override path validated via unit tests; missing-key path validated via unit tests; long-query →objectiveadaptation validated via unit tests; session-id cache-leak protection validated via unit tests.missing_parallel_api_keypayload); invalid base URL (invalid_base_urlpayload); query length > 200 chars (truncated to 200 insearch_queries[0], full text routed asobjective);countclamped to 1-40; caller-supplied vs auto-generatedsession_id(cache key partitioned; only caller-supplied id is preserved across cache hits).Review Conversations
Pre-PR review evidence (all green after iteration):
codex review --base origin/mainrun four times; final pass: "no actionable bugs found." All earlier P2/P3 findings addressed: top-level web-search settings now honored viamergeScopedSearchConfig; missing-key/invalid-base-url payloads point at the real config paths and the new docs page; defaultmax_resultsmatches OpenClaw'sDEFAULT_SEARCH_COUNT(5) instead of Parallel's default (10) so switching providers doesn't silently change result volume; long-query →objectiveadaptation handles Parallel's 200-charsearch_querieslimit; auto-generatedsessionIdstripped before caching to prevent cross-task contamination on cache hits.https://docs.parallel.ai/search/best-practicesandhttps://docs.parallel.ai/api-reference/search/search): two rounds, all PASS, no blocking findings.Compatibility / Migration
PARALLEL_API_KEYenv var orplugins.entries.parallel.config.webSearch.apiKeyconfig. Both auto-detected if present; ignored if absent.tools.web.search.parallel.*path, so it's listed inNON_MIGRATED_LEGACY_WEB_SEARCH_PROVIDER_IDSalongside Tavily (no doctor rewrite rule needed).Risks and Mitigations
api.parallel.ai).withTrustedWebSearchEndpointSDK guard. Same network policy as Exa/Brave/Firecrawl/Tavily. No new SSRF surface.advanced_settings.max_results = DEFAULT_SEARCH_COUNT(5) so result volume is consistent across providers. Locked by a unit test.session_idgetting cached and leaking across unrelated tasks.