Commit Graph

2292 Commits

Author SHA1 Message Date
Vincent Koc
c05acc7a14 fix(testing): bind QA docker port probes to loopback 2026-06-17 14:18:03 +02:00
Vincent Koc
da67802baf fix(codex): respect lifecycle mismatch rotations 2026-06-17 10:30:45 +02:00
Vincent Koc
5ee0f13a54 fix(channels): reset completed command output detail 2026-06-17 10:30:45 +02:00
Vincent Koc
f3a1d1fcb0 feat(diagnostics): export security events to OTLP logs 2026-06-17 16:11:32 +08:00
ragesaq
f94a2506d2 feat(context-engine): pass runtime settings into lifecycle (#88750)
Merged via squash.

Prepared head SHA: 9a19334ee5
Co-authored-by: ragesaq <11304287+ragesaq@users.noreply.github.com>
Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>
Reviewed-by: @jalehman
2026-06-16 16:23:19 -07:00
keshavbotagent
257d540297 Keep command text in progress drafts (#93711)
* Keep command text in progress drafts

* test(channels): align successful progress drafts

---------

Co-authored-by: Vincent Koc <25068+vincentkoc@users.noreply.github.com>
2026-06-17 02:41:59 +08:00
Ayaan Zaidi
42dcf7075f Fix Telegram rich progress detail updates (#93698)
Merged via squash.

Prepared head SHA: 77da499825
Co-authored-by: obviyus <22031114+obviyus@users.noreply.github.com>
Co-authored-by: obviyus <22031114+obviyus@users.noreply.github.com>
Reviewed-by: @obviyus
2026-06-16 22:48:12 +05:30
Vincent Koc
08ff253e5f fix(ci): repair test helper type checks 2026-06-16 11:12:21 +02:00
Matt Gunnin
2cfcb3c932 AGT-80 AGT-81 Fix Discord ingress ack ordering (#93407)
Merged via squash.

Prepared head SHA: 55718a24fd
Co-authored-by: mgunnin <321368+mgunnin@users.noreply.github.com>
Co-authored-by: vincentkoc <25068+vincentkoc@users.noreply.github.com>
Reviewed-by: @vincentkoc
2026-06-16 16:54:46 +08:00
Jason (Json)
1e0062b44a feat: add Codex hosted web search (#93446)
Adds Codex as a selectable hosted web-search provider, routes native Codex search safely across model overrides, and isolates bounded hosted-search workers from configured tools.\n\nVerification: focused post-merge regression suite passed 202/202 tests on exact head 23824af49a.
2026-06-16 00:38:16 -06:00
Vincent Koc
ac8a3f367c fix(sqlite): disable WAL on network filesystems 2026-06-16 09:36:32 +08:00
Vincent Koc
d5c9e7ea99 test(plugin-sdk): ratchet surface budget checks 2026-06-16 02:56:41 +02:00
Ayaan Zaidi
da92615816 feat(telegram): send rich messages as rich html (#93286)
* feat(telegram): render rich messages through rich html

* docs(telegram): teach agents rich formatting

* fix(telegram): bound rich draft payloads (#93286)

* fix(telegram): narrow rich draft payload type (#93286)

* fix(telegram): preserve rich table cell formatting (#93286)

* fix(telegram): honor rich table mode config (#93286)

* fix(telegram): default rich markdown tables (#93286)

* fix(telegram): gate rich table block mode (#93286)

* fix(telegram): normalize raw rich html limits (#93286)

* fix(telegram): preserve link preview suppression (#93286)

* fix(telegram): preserve rich markdown headings (#93286)

* fix(telegram): reject unsupported rich media sources (#93286)

* fix(telegram): honor link preview off in rich chunks (#93286)

* fix(telegram): avoid double escaping markdown media (#93286)

* fix(telegram): render markdown media via placeholders (#93286)

* fix(telegram): preserve table text in prompt context (#93286)
2026-06-15 20:38:41 +05:30
Peter Steinberger
0314819f91 fix(agents): replace prose terminal classifiers (#93228)
* fix(agents): replace prose terminal classifiers

Co-authored-by: fuller-stack-dev <263060202+fuller-stack-dev@users.noreply.github.com>

* fix(agents): preserve terminal failure lifecycles

* fix(agents): order parallel terminal summaries

* fix(agents): preserve structured post-tool silence

* fix(agents): preserve structured replay provenance

---------

Co-authored-by: fuller-stack-dev <263060202+fuller-stack-dev@users.noreply.github.com>
2026-06-15 02:53:14 -07:00
Ben Badejo
3fc850fe86 fix(matrix): replace recovered command progress lines (#89920)
* fix(matrix): replace recovered command progress lines

* fix(matrix): replace recovered command progress lines

* fix(matrix): share command progress identity

* fix(channels): share command progress identity

* fix command progress draft replacement

* fix command progress ids without changing public line ids

* test(telegram): assert command progress preview update

* fix(telegram): keep progress preview test typed

---------

Co-authored-by: Benjamin Badejo <ben@benbadejo.com>
Co-authored-by: jesse-merhi <79823012+jesse-merhi@users.noreply.github.com>
2026-06-15 19:14:43 +10:00
Jason (Json)
77a682c5de fix(agents): retry empty post-tool final turns (#93073)
Recover assistant turns that complete tool work without producing a visible final answer, while preserving intentional silent replies.

Use concrete tool-instance replay safety across embedded, Codex, and Copilot runtimes so unknown, mutating, async-started, and durable recall operations fail closed. Preserve genuine empty Codex final items without promoting commentary or tool-progress echoes.

Supersedes #90872. Thanks @fuller-stack-dev.

Co-authored-by: fuller-stack-dev <263060202+fuller-stack-dev@users.noreply.github.com>
2026-06-15 00:08:57 -07:00
mushuiyu_xydt
44e6caff54 fix(memory): accept local default model path migration (#92954)
* fix(memory): accept local default model path migration

Treat the official local default embedding model's hf URI and downloaded GGUF path identities as equivalent so upgraded local memory indexes do not pause solely on path-format changes.

* fix(memory): satisfy local identity lint

Avoid filtered array tail access in the local model filename helper while preserving the same compatibility behavior.

* fix(memory): preserve local embedding identity aliases

---------

Co-authored-by: Vincent Koc <25068+vincentkoc@users.noreply.github.com>
2026-06-15 09:29:42 +08:00
Josh Lehman
f1b8827d20 refactor: route bundled plugin session callers through seam (#89129)
Merged via squash.

Prepared head SHA: 7975bc06ac
Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>
Co-authored-by: jalehman <550978+jalehman@users.noreply.github.com>
Reviewed-by: @jalehman
2026-06-14 12:26:53 -07:00
sandieman2
c67dc59b02 fix(reply): deliver final reply when queued follow-up claims session; scope dedupe to routed thread (#90943)
* fix(reply): deliver final reply when queued follow-up claims session; scope dedupe to routed thread

Two core bugs caused composed replies to be silently dropped (no delivery,
no error) when a second message arrived in the same thread mid-run:

1. dispatch-from-config: ensureDispatchReplyOperation only kept the
   dispatch-owned operation authoritative while it had no result. Once
   runReplyAgent completed the operation to drain queued follow-ups, a
   second same-thread inbound could claim the session and the first final
   reply would try to re-acquire the lane instead of finishing delivery,
   deadlocking behind the queued work. Keep the dispatch-owned operation
   authoritative through final delivery.

2. reply-payloads-dedupe: messaging-tool reply dedupe compared only the
   channel target, not the routed thread, so a send in one thread could
   suppress a later reply in a different thread. Thread the routed thread
   id through buildReplyPayloads + follow-up delivery and only fall back to
   channel-only matching for providers without a thread-aware suppression
   matcher when neither side carries thread evidence.

Adds regression tests; existing Telegram topic-suppression behavior is
preserved by gating the thread guard to providers lacking a plugin matcher.

* fix(reply): preserve threaded message delivery evidence

* fix(reply): dedupe final payloads by delivery route

* fix(slack): preserve native send thread evidence

* fix(reply): preserve explicit reply thread evidence

* fix(reply): align explicit reply route dedupe

* fix(reply): preserve delivery lane through final dispatch

* fix(mattermost): preserve threaded tool send routes

* chore(plugin-sdk): refresh API baseline

* fix(reply): align final delivery route dedupe

* fix(reply): gate followups on final delivery

* fix(reply): keep send receipts private

* fix(reply): infer implicit message provider

* fix(reply): align routed threading policy

* fix(reply): preserve queued delivery context

* fix(reply): hydrate queued system event routes

* fix(reply): hydrate queued execution routes

* fix(reply): scope final delivery barriers

* fix(slack): preserve DM target aliases

* fix(reply): mirror resolved source thread routes

* fix(mattermost): retain delayed delivery barrier

* fix(codex): separate message routing from tool policy

* fix(reply): consume normalized Slack DM targets once

* fix(slack): remove stale target alias

* style(reply): satisfy changed lint gates

* fix(mattermost): preserve explicit reply targets

* test: align Slack reply branch checks

* fix(reply): persist overflow summaries to admitted session

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-06-14 09:11:05 -07:00
Ayaan Zaidi
d498b1cce4 fix(plugin-sdk): expose delivery hints without utility imports 2026-06-14 18:18:20 +05:30
Ayaan Zaidi
210877a73e fix(auto-reply): share message-tool delivery hints 2026-06-14 18:18:20 +05:30
David
23d74dad12 fix(lmstudio): honor thinking off for binary reasoning models (#92002)
Scope disabled-thinking payload repair to LM Studio's lightweight provider stream hook. Preserve official OpenAI and Anthropic tool-calling paths.

Co-authored-by: David <32288+nxmxbbd@users.noreply.github.com>
2026-06-14 05:41:49 -07:00
brokemac79
d1299658ac fix(active-memory): preserve verbose recall summaries (#90739)
* fix(active-memory): preserve verbose recall summaries

* fix(active-memory): require recall evidence for recovery

* fix(active-memory): recognize capped recall results

* fix(active-memory): preserve grounded recall state

* refactor(active-memory): limit recovery to completed recalls

* fix(active-memory): ground terminal recall recovery

* fix(active-memory): limit unavailable recovery to completed replies

* fix(active-memory): harden recall evidence recovery

* fix(active-memory): preserve timeout recovery contract

* fix(active-memory): preserve capped failure evidence

* fix(active-memory): reject content-only recall failures

* fix(active-memory): ground completed recall summaries

* fix(active-memory): separate hook and recall timeouts

* fix(active-memory): classify custom tool failures

* fix(active-memory): preserve harness tool evidence

* fix(active-memory): reject explicit empty results

* fix(active-memory): wait for fallback recall evidence

* fix(codex): report dynamic tool results

* fix(active-memory): separate preflight recall deadline

* fix(active-memory): normalize recall tool names

* fix(agents): classify unavailable approvals

* docs(active-memory): clarify hook timeout phases

* test(active-memory): stabilize timeout abort proof

* fix(agents): preserve successful cancellation outcomes

---------

Co-authored-by: Peter Steinberger <steipete@gmail.com>
2026-06-13 23:38:58 -07:00
Vincent Koc
efca4b7e64 fix(memory): keep skipped recall diagnostics opt-in
Follow-up to #92745 after maintainer autoreview found that the skipped recall event widened the shipped MemoryHostEvent union and changed limited legacy reads.

Keep readMemoryHostEvents() source-compatible by filtering diagnostic records before applying limits, and expose skipped recall diagnostics through the opt-in MemoryHostEventRecord/readMemoryHostEventRecords path.

Original skipped-recall behavior landed in #92745 by @mushuiyu886.
2026-06-14 08:47:03 +08:00
Josh Avant
689ebc815b feat: support /btw in CLI-backed sessions (#92669)
* feat: support CLI btw side questions

* test: fix CLI prepare test fixture types

* fix: lazy load local btw runner
2026-06-13 19:36:53 +02:00
Hansraj Singh Thakur
ab559a7257 fix(channels): report progress draft startup failures (#92083)
Report timer-fired channel progress-draft startup failures at the shared gate boundary instead of silently dropping them. Explicitly awaited starts still reject, and failed timer starts remain retryable.

Refs #92031.

Co-authored-by: Hansraj Singh Thakur <hansraj136@gmail.com>
2026-06-13 00:42:13 -07:00
Rain
4a6666796f fix(moonshot): rewrite duplicate native Kimi tool call ids
Preserve the first native Kimi tool-call ID while rewriting repeated replay occurrences to deterministic OpenAI-style IDs and keeping paired tool results aligned. Moonshot responses-family behavior and providers that do not opt in remain unchanged.

Closes #51593

Co-authored-by: Pluviobyte <Pluviobyte@users.noreply.github.com>
2026-06-12 21:14:03 -07:00
Peter Steinberger
8c7e5c6918 feat(moonshot): add Kimi K2.7 Code support (#92554)
* feat(moonshot): add Kimi K2.7 Code support

* test(moonshot): surface K2.7 live provider errors

* ci(live): accept Kimi key for Moonshot sweeps

* test(moonshot): verify K2.7 across API regions
2026-06-12 17:37:28 -07:00
Josh Avant
9921825e17 Fix Telegram spooled buffered replay (#92281)
* fix telegram spooled buffered replay

* fix telegram replay type checks

* fix telegram replay lint

* test telegram replay visible output retry guard

* fix telegram rollback failure retry
2026-06-12 11:51:46 -05:00
Josh Avant
f3eb8e9714 Fix OTLP log trace correlation (#92276)
* fix diagnostics otel log trace correlation

* test diagnostics trace provenance contract
2026-06-12 10:54:21 -05:00
Lu Wang
43b4e27699 fix(thinking): apply Claude profile to anthropic-messages catalog rows (#92053)
* fix(thinking): apply Claude profile to anthropic-messages catalog rows

When a custom provider (e.g. `jdcloud-anthropic`) fronted Claude Opus over
the native anthropic-messages adapter, `--thinking xhigh` was silently
clamped to `off`. The thinking-profile dispatcher resolves bundled plugin
policy surfaces by exact provider id, so a renamed Anthropic-compatible
provider never reached the anthropic plugin's policy and `xhigh` was not
in the resulting profile.

`auto-reply/thinking.ts` already had a fallback keyed on
`context.api === "anthropic-messages"` that attached
`CLAUDE_FABLE_5_THINKING_PROFILE` for Fable models. Generalize it to use
`resolveClaudeThinkingProfile(modelId, params)` instead — the same
canonical helper the anthropic plugin uses — which still returns the Fable
profile for Fable models and now returns the correct Opus 4.7/4.8 profile
(with `xhigh`/`adaptive`/`max`) for Claude Opus regardless of provider id.

Non-Claude models on anthropic-messages routes still get the base
profile, and a Claude id on a non-Anthropic transport (e.g. an
openai-completions catalog row) is unaffected.

Fixes #91975

* fix(thinking): match native Anthropic includeNativeMax in fallback

Address ClawSweeper P2 review on #92053. The anthropic-messages fallback
in `resolveThinkingProfile` calls `resolveClaudeThinkingProfile` but
omits the `{ includeNativeMax: true }` option that the bundled anthropic
plugin uses (extensions/anthropic/provider-policy-api.ts:38,45).

For native-xhigh Claude families (Opus 4.7/4.8) this had no effect since
the native-xhigh branch already exposes `max`. But adaptive Claude
families that take the adaptive-default branch (e.g. claude-sonnet-4-6,
claude-opus-4-6) silently lost `max` parity on custom anthropic-messages
providers compared to native Anthropic policy.

Also add a regression test on `claude-sonnet-4-6` that verifies the
adaptive-branch path keeps `max` for custom providers.

* docs(thinking): document deliberate compat.xhigh bypass on anthropic-messages

Self-review surfaced a subtle behavior change worth documenting: when the
anthropic-messages fallback was generalized, non-Claude models on this
transport stop honoring catalog `compat.supportedReasoningEfforts: ["xhigh"]`
because they take the Claude base profile instead of falling through to the
later `catalogSupportsXHigh` upgrade path.

This is intentional — anthropic-messages does not carry a generic xhigh
contract; xhigh on this protocol is a Claude-family capability. Add an
inline comment at the resolver site and a regression test that locks the
suppression so the next reader (or a future patch) doesn't accidentally
restore the upgrade path.

* fix(thinking): extract Claude profile to leaf to break import cycle

The previous commits added a `resolveClaudeThinkingProfile` import from
`auto-reply/thinking.ts` to `plugin-sdk/provider-model-shared.ts`. The
shared barrel re-exports `provider-replay-helpers` and `plugins/types`,
which transitively reach back into `auto-reply` via the gateway server
methods chain — creating the madge cycle reported by
`check:madge-import-cycles`:

    auto-reply/thinking.ts
      -> ... -> plugin-sdk/provider-model-shared.ts
      -> plugins/{config-schema, host-hooks, ...} -> plugins/types.ts

Move `BASE_CLAUDE_THINKING_LEVELS`, `isClaudeAdaptiveThinkingDefaultModelId`,
and `resolveClaudeThinkingProfile` to a new leaf module
`src/plugins/provider-claude-thinking.ts` whose only imports are
`@openclaw/llm-core` and the existing leaf `provider-thinking.types`.

`provider-model-shared.ts` continues to re-export both helpers so existing
consumers (`extensions/anthropic/*`, the public test surface) are
unaffected. `auto-reply/thinking.ts` now imports the leaf directly,
breaking the cycle.

* test(thinking): add live proof harness for #91975 anthropic-messages clamp

---------

Co-authored-by: wanglu241 <wanglu241@jd.com>
2026-06-11 19:24:46 +09:00
Vincent Koc
9ffb5407f7 fix(providers): reconcile Claude profile routing 2026-06-11 11:11:21 +09:00
Vincent Koc
aabb8498da fix(providers): bound Claude model matching 2026-06-11 11:11:21 +09:00
Peter Steinberger
0e7b5c3429 feat(anthropic): support Claude Fable 5 adaptive thinking (#91882)
* feat(anthropic): support Claude Fable 5

* test(anthropic): tighten Fable stream fixtures

* fix(anthropic): preserve Vertex input types

* test(anthropic): use provider-ready Vertex effort

* fix(anthropic): support Fable deployment aliases

* fix(anthropic): discard incomplete Fable output

* feat(anthropic): support Fable on Bedrock

* fix(anthropic): preserve Fable reasoning contracts

* refactor(anthropic): unify canonical Claude model policy

* fix(anthropic): satisfy extension thinking types

* test(anthropic): complete canonical alias fixture

* fix(bedrock): scope thinking case declarations
2026-06-10 08:08:35 -07:00
brokemac79
b71d8e1c32 fix(sandbox): use materialized skill paths in startup prompts (#91791)
* fix(sandbox): use materialized skill paths in command prompts

* fix(sandbox): resolve backend prompt workdirs

* fix(sandbox): preserve custom backend prompt fallback

---------

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
2026-06-10 23:35:34 +09:00
Ayaan Zaidi
b2dec9cd50 feat(plugin-sdk): expose persistent dedupe import helpers 2026-06-10 14:52:22 +05:30
Ayaan Zaidi
b9095bf70d refactor(channel): share draft chunking resolver 2026-06-10 13:35:19 +05:30
Vincent Koc
7f1d82ab25 revert(sessions): defer session metadata sqlite
Reverts 538d36eaaa while preserving subsequent main changes. The beta-only SQLite downgrade rescue and reverse migration remain excluded.
2026-06-10 16:34:06 +09:00
Vincent Koc
b4cdd92119 fix(codex): avoid guardian review for local models (#88630)
* fix(codex): avoid guardian review for local models

* fix(codex): route app-server auto exec review

* fix(codex): make guardian requirements provider-aware

* fix(codex): block unrouted bound approvals

* fix(channels): satisfy ingress queue lint

* fix(codex): use local-model policy for side forks

* fix(extensions): satisfy ingress lint

* fix(codex): require trusted exec reviewer model

* fix(exec): share control command approval guards

* fix(codex): fail closed for unknown guardian model provider

* fix(codex): reject custom exec reviewer endpoints

* fix(codex): preserve bound providers on app-server reuse

* fix(codex): prefer qualified app-server model providers

* fix(codex): preserve guardian on model control switches

* fix(codex): retain local providers across model switches

* fix(codex): distrust aliased reviewer model refs

* fix(codex): preserve providers after thread rotation

* fix(codex): clear stale providers on qualified model switches

* fix(codex): prefer qualified models over legacy providers

* fix(codex): validate reviewer trust before auto approvals

* fix(codex): recompute reviewer policy after binding rotation

* fix(codex): normalize reviewer aliases before trust checks

* fix(codex): retain bound providers for slashed local models

* fix(codex): normalize provider trust checks for exec review

* fix(codex): ignore stale bindings for explicit providers

* fix(codex): share trusted reviewer endpoint policy

* fix(codex): keep network approvals on plugin path

* fix(codex): route provider-qualified model refs

* fix(codex): reject blank masked OpenAI base overrides

* fix(codex): scope exec reviewer alias trust

* fix(codex): distrust exec reviewer transport overrides
2026-06-09 21:38:22 -07:00
Agustin Rivera
f0d8048aa3 fix(search): enforce native web search tool policy (#91750)
* fix(search): enforce native web search tool policy

* fix(search): apply session policy to native web search

* fix(search): gate direct OpenAI native search

* fix(search): redact native web search provider context
2026-06-09 16:25:15 -07:00
Vincent Koc
66749a3713 test: consolidate wrapper facade coverage 2026-06-09 20:12:25 +09:00
Vincent Koc
73ce4fdcbb fix(plugin-sdk): align Discord component edit facade types (#91679)
* fix(plugin-sdk): align Discord component edit facade types

* test(plugin-sdk): satisfy Discord facade type lint

* test(upgrade): seed migrated survivor sessions

---------

Co-authored-by: openclaw-clownfish[bot] <280122609+openclaw-clownfish[bot]@users.noreply.github.com>
2026-06-09 19:58:10 +09:00
Josh Avant
9fdd56da21 fix(openai): require api-key auth for realtime voice (#91567)
* fix(openai): require api-key auth for realtime voice

* test(plugin-sdk): avoid auth profile store shadowing
2026-06-08 22:55:06 -05:00
Peter Steinberger
538d36eaaa refactor: move session metadata to SQLite (#91322)
* refactor: move session metadata to sqlite

* test: seed session stores with sqlite fixtures

* test: seed remaining session stores with sqlite fixtures

* fix: stabilize sqlite session cache freshness

* test: seed cli transcript metadata in sqlite
2026-06-07 23:17:35 -07:00
Jason (Json)
57e0bdaabe feat: add live provider model catalog helper
Summary:
- Add a shared live provider catalog runtime for SDK-backed providers.
- Route OpenAI, xAI, OpenCode Go, Chutes, DeepInfra, Venice, NVIDIA, and Vercel AI Gateway live model discovery through the shared helper.
- Remove duplicated provider-local live catalog caching and harden auth marker stripping, empty live-result retries, and OpenAI custom-base-url handling.

Verification:
- node scripts/run-vitest.mjs extensions/openai/openai-provider.test.ts src/plugin-sdk/provider-catalog-live-runtime.test.ts src/commands/models/list.source-plan.test.ts extensions/opencode-go/index.test.ts extensions/nvidia/provider-catalog.test.ts
- pnpm plugin-sdk:api:check
- pnpm lint --threads=8
- pnpm run lint:extensions:bundled
- pnpm run test:extensions:package-boundary:compile
- pnpm check:import-cycles
- pnpm exec oxfmt --check extensions/openai/openai-provider.ts extensions/openai/openai-provider.test.ts
- git diff --check origin/main...HEAD
- autoreview clean: no accepted/actionable findings reported
- AWS Crabbox focused remote proof: run_364680d1bff8 / cbx_2456fffafe01
- Earlier same-PR AWS Crabbox live proof: run_1f05ccab368e / cbx_7375c79fcf9b

Known proof gap:
- Final current-code true live-provider smoke was blocked by Crabbox secret hydration, documented in the PR proof comment.
2026-06-07 14:16:00 -07:00
Vincent Koc
e2524e0438 fix(ci): break plugin import cycles 2026-06-07 19:03:38 +09:00
Peter Steinberger
bab18d567b refactor(plugin-sdk): persist dedupe state in sqlite 2026-06-07 02:41:45 -07:00
Peter Steinberger
08ae0e6d29 refactor: store Zalo hosted media in plugin state
Move Zalo hosted outbound media metadata and expiry into plugin state, add SDK chunked hosted media storage, and keep CI/type/lint gates green after rebase.
2026-06-06 22:56:48 -07:00
Peter Steinberger
3f5e001844 fix: store memory-core dreams state in sqlite (#91056) 2026-06-06 18:38:45 -07:00
Matt H
983b65b0e0 feat(parallel): add free Parallel Search MCP as the zero-config default web_search provider (#90849)
* feat(parallel): add free Parallel Search MCP as the zero-config default web_search provider

Registers two Parallel web_search providers in the parallel plugin:
- parallel-free: keyless, always the free hosted Search MCP (search.parallel.ai/mcp);
  the zero-config default (autoDetectOrder 76) so web_search works with no key.
- parallel: the existing paid v1 REST API (requires PARALLEL_API_KEY).

Shared query/result normalization lives in parallel-search-normalize.ts (used by both
transports); a minimal Streamable-HTTP JSON-RPC client (parallel-mcp-search.runtime.ts)
backs the free path. UI brands the tool-call chip 'Parallel Web Search' on the free path
via a searchTransport marker; setup default mirrors runtime auto-detect.

* chore(parallel): register parallel-free in doctor legacy-web-search owners

parallel-free is a bundled web_search provider, so add it to the doctor's
exhaustive BUNDLED_LEGACY_WEB_SEARCH_OWNERS map (owned by the parallel plugin)
and the NON_MIGRATED set — it has no legacy tools.web.search.* shape, so this is
a no-op for migration, matching paid parallel/tavily. Keeps the registry
complete. (Spotted by diffing the earlier local WIP branch.)

* docs(parallel): restore concise frontmatter summary

* docs(parallel): clearer, professional copy; drop v1 REST jargon and UI-label claim

- Frame the two providers as Parallel Search (Free) vs paid Parallel Search;
  remove internal 'v1 REST API' wording.
- Remove conversational/overstated phrasing ('out of the box for everyone').
- Remove the 'labeled Parallel Web Search in the UI' claim (only renders in the
  Control UI, not the TUI). Scope the searchTransport code comment accordingly.

* revert(parallel): drop the "Parallel Web Search" tool-call branding

The label only rendered in the Control UI, never the TUI (a separate renderer
via src/agents/tool-display.ts). Extending it would put provider-specific
labeling into a shared/core display path, against the plugin-agnostic-core rule.

Reverts the Control-UI labelOverride wiring and removes the now-orphaned
searchTransport marker from the free provider's result. The result still carries
provider: "parallel-free".

* fix(parallel): cap free Search MCP session_id at its 100-char tools/list contract

The free parallel-free provider reused the paid ParallelSearchSchema, whose
session_id allows 1000 chars, but the live Search MCP tools/list schema caps
session_id at 100. Parameterize normalizeParallelSessionId(value, maxLength);
the free path passes 100 (paid keeps 1000) and advertises the tighter bound in
its own ParallelFreeSearchSchema. An over-limit caller id is dropped and a
fresh in-contract id is minted. Updates tests and docs accordingly.
2026-06-06 17:36:28 -07:00