Skip to content

feat(web-search): add explicit provider fallback support#63571

Closed
scriptsth wants to merge 14 commits into
openclaw:mainfrom
scriptsth:feat/web-search-provider-fallback
Closed

feat(web-search): add explicit provider fallback support#63571
scriptsth wants to merge 14 commits into
openclaw:mainfrom
scriptsth:feat/web-search-provider-fallback

Conversation

@scriptsth

@scriptsth scriptsth commented Apr 9, 2026

Copy link
Copy Markdown

When a provider is explicitly configured with a fallbacks array, retry the next configured provider on any error instead of failing immediately. Without fallbacks, explicit mode keeps existing fail-fast behavior.

Summary

Describe the problem and fix in 2–5 bullets:

If this PR fixes a plugin beta-release blocker, title it fix(<plugin-id>): beta blocker - <summary> and link the matching Beta blocker: <plugin-name> - <summary> issue labeled beta-blocker. Contributors cannot label PRs, so the title is the PR-side signal for maintainers and automation.

  • Problem:
  • Why it matters:
  • What changed:
  • What did NOT change (scope boundary):

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

  • Closes #
  • Related #
  • This PR fixes a bug or regression

Root Cause (if applicable)

For bug fixes or regressions, explain why this happened, not just what changed. Otherwise write N/A. If the cause is unclear, write Unknown.

  • Root cause:
  • Missing detection / guardrail:
  • Contributing context (if known):

Regression Test Plan (if applicable)

For bug fixes or regressions, name the smallest reliable test coverage that should catch this. Otherwise write N/A.

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file:
  • Scenario the test should lock in:
  • Why this is the smallest reliable guardrail:
  • Existing test that already covers this (if any):
  • If no new test is added, why not:

User-visible / Behavior Changes

List user-visible changes (including defaults/config).
If none, write None.

Diagram (if applicable)

For UI changes or non-trivial logic flows, include a small ASCII diagram reviewers can scan quickly. Otherwise write N/A.

Before:
[user action] -> [old state]

After:
[user action] -> [new state] -> [result]

Security Impact (required)

  • New permissions/capabilities? (Yes/No)
  • Secrets/tokens handling changed? (Yes/No)
  • New/changed network calls? (Yes/No)
  • Command/tool execution surface changed? (Yes/No)
  • Data access scope changed? (Yes/No)
  • If any Yes, explain risk + mitigation:

Repro + Verification

Environment

  • OS:
  • Runtime/container:
  • Model/provider:
  • Integration/channel (if any):
  • Relevant config (redacted):

Steps

  1. Configure tools.web.search.provider = "google" with tools.web.search.fallbacks = ["duckduckgo", "bing", "searx"]
  2. Make a web search request that triggers a provider error (e.g., invalid API key, network failure)
  3. Observe that the search retries with each fallback provider in order (google → duckduckgo → bing → searx) until one succeeds
  4. Verify the final result comes from the first available fallback provider

Expected

  • fallbacks logic worked as expected

Actual

  • fallbacks logic worked as expected

Evidence

Attach at least one:

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

What you personally verified (not just CI), and how:

  • Verified scenarios:
  • Edge cases checked:
  • What you did not verify:

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

If a bot review conversation is addressed by this PR, resolve that conversation yourself. Do not leave bot review conversation cleanup for maintainers.

Compatibility / Migration

  • Backward compatible? (Yes)
  • Config/env changes? (Yes)
  • Migration needed? (No)
  • If yes, exact upgrade steps:

Risks and Mitigations

List only real risks for this PR. Add/remove entries as needed. If none, write None.

  • Risk:
    • None

When a provider is explicitly configured with a fallbacks array, retry
the next configured provider on any error instead of failing immediately.
Without fallbacks, explicit mode keeps existing fail-fast behavior.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation size: M labels Apr 9, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f64b43f0b1

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/web-search/runtime.ts Outdated
@greptile-apps

greptile-apps Bot commented Apr 9, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds explicit provider fallback support to runWebSearch: when tools.web.search.fallbacks is configured alongside an explicit provider, the runtime retries each listed fallback in order on failure; without fallbacks, explicit-provider mode keeps the existing fail-fast behavior. Config type, Zod schema, generated schema, labels, help text, and baseline hash are all updated consistently.

  • The duplicate import declarations for resolvePluginWebSearchProviders and resolveRuntimeWebSearchProviders from the same module path (../plugins/web-search-providers.runtime.js) at lines 7–8 of runtime.ts will fail the eslint/no-duplicate-imports correctness rule enabled by categories.correctness: \"error\" in .oxlintrc.json; they should be merged into one statement before merge.

Confidence Score: 4/5

Safe to merge after fixing the duplicate import lint failure.

The fallback logic itself is correct, well-tested, and the config surface is consistently updated. Score is 4 rather than 5 because the duplicate import declarations from the same module path will cause pnpm check to fail under the repo's correctness: error oxlint policy, which is a required gate before landing on main.

src/web-search/runtime.ts (duplicate import at lines 7–8)

Vulnerabilities

No security concerns identified. The change adds provider-retry logic that stays within the existing credential and provider-registry surfaces — no new network endpoints, no secrets handling changes, and no expansion of access scope.

Comments Outside Diff (1)

  1. src/web-search/runtime.ts, line 7-8 (link)

    P1 Duplicate import declarations from the same module

    Both resolvePluginWebSearchProviders and resolveRuntimeWebSearchProviders are imported from ../plugins/web-search-providers.runtime.js in separate statements. With categories.correctness: "error" in .oxlintrc.json, the eslint/no-duplicate-imports rule will fire on this and cause pnpm check to fail.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: src/web-search/runtime.ts
    Line: 7-8
    
    Comment:
    **Duplicate import declarations from the same module**
    
    Both `resolvePluginWebSearchProviders` and `resolveRuntimeWebSearchProviders` are imported from `../plugins/web-search-providers.runtime.js` in separate statements. With `categories.correctness: "error"` in `.oxlintrc.json`, the `eslint/no-duplicate-imports` rule will fire on this and cause `pnpm check` to fail.
    
    
    
    How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/web-search/runtime.ts
Line: 7-8

Comment:
**Duplicate import declarations from the same module**

Both `resolvePluginWebSearchProviders` and `resolveRuntimeWebSearchProviders` are imported from `../plugins/web-search-providers.runtime.js` in separate statements. With `categories.correctness: "error"` in `.oxlintrc.json`, the `eslint/no-duplicate-imports` rule will fire on this and cause `pnpm check` to fail.

```suggestion
import {
  resolvePluginWebSearchProviders,
  resolveRuntimeWebSearchProviders,
} from "../plugins/web-search-providers.runtime.js";
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: src/web-search/runtime.ts
Line: 333-337

Comment:
**Redundant optional chaining in type-predicate filter**

`Boolean(p)` already guards against `null`/`undefined` before the `&&`, so `p?.id` on the next condition can never be nullish — the `?.` is redundant. Using plain `p.id` here keeps the intent clearer and avoids a misleading suggestion that `p` could still be absent at that point.

```suggestion
          .filter(
            (p): p is PluginWebSearchProviderEntry => Boolean(p) && p.id !== primaryProviderId,
          ),
```

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "feat(web-search): add explicit provider ..." | Re-trigger Greptile

Comment thread src/web-search/runtime.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1542f95790

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/web-search/runtime.ts Outdated
Use normalizeLowercaseStringOrEmpty on fallback ids to ensure consistent
matching with primary provider field, handling mixed-case/whitespace.

Co-Authored-By: Claude Opus 4.6 <[email protected]>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 948ce231bb

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/web-search/runtime.ts Outdated
When providerId is explicitly provided (for example via CLI --provider
override), ignore config fallbacks and fail fast to preserve deterministic
provider-specific runs and debugging.

Co-Authored-By: Claude Opus 4.6 <[email protected]>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 000f534310

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/web-search/runtime.ts Outdated
Prevent the same provider from being retried multiple times when
duplicate fallback IDs are configured, avoiding extra latency and
repeated billable requests on failure paths.

Co-Authored-By: Claude Opus 4.6 <[email protected]>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 938bb54f43

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/web-search/runtime.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 938bb54f43

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/web-search/runtime.ts Outdated
When explicit fallback mode is enabled, resolve the primary provider from
the config provider field instead of relying on runtime-ordered candidates,
preventing stale runtime metadata from bypassing the intended primary.

Co-Authored-By: Claude Opus 4.6 <[email protected]>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 348b0b21ee

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/web-search/runtime.ts Outdated
…lves

Previously allowFallback was enabled whenever tools.web.search.fallbacks was
non-empty, even if every fallback id was invalid. Now it only enables
fallback when at least one usable fallback candidate exists.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@scriptsth

Copy link
Copy Markdown
Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5041018ad1

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/web-search/runtime.ts Outdated
…anning

When tools.web.search.provider is set to an unknown id but runtime metadata
marks selection as explicit, the fallback path is now skipped and candidates
are used instead, preventing Error("undefined") when no fallback resolves.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@scriptsth

Copy link
Copy Markdown
Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

return {
provider: candidate.id,
result: await definition.execute(params.args),
};

P1 Badge Treat provider error payloads as fallback failures

This fallback path only retries on thrown exceptions, but many web-search providers report auth/validation failures by returning an { error: ..., message: ... } payload instead of throwing (for example, missing-key responses in provider implementations). In those cases runWebSearch returns the primary provider response immediately and never reaches configured tools.web.search.fallbacks, so explicit fallback mode silently fails for common real-world failures like missing or invalid credentials.

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Many providers return { error: ... } payloads instead of throwing on auth
failures. Now these are treated as failures and trigger fallback retry,
not immediate return.

Co-Authored-By: Claude Opus 4.6 <[email protected]>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 48136ac7b4

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/web-search/runtime.ts Outdated
…failure

Return error payloads instead of throwing to preserve structured fields
like message/docs that providers return for user-facing diagnostics.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@scriptsth

Copy link
Copy Markdown
Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9aa16cf436

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/web-search/runtime.ts Outdated
Only retry error payloads when explicit fallback mode is configured,
preserving existing auto-detect behavior.

Co-Authored-By: Claude Opus 4.6 <[email protected]>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 706c365926

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/web-search/runtime.ts Outdated
@clawsweeper clawsweeper Bot added rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. and removed status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 4, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the stale Marked as stale due to inactivity label Jun 5, 2026
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. and removed rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. labels Jun 14, 2026
@clawsweeper clawsweeper Bot added rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jun 16, 2026
@steipete

steipete commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Thanks @scriptsth. Closing this stale conflicting implementation branch while keeping #80843 open. This head retries every provider error instead of only retryable failures and can silently drop configured fallback provider IDs, with no live fallback proof. A replacement should start from current main, preserve the full fallback chain, and test retry classification explicitly.

@steipete steipete closed this Jul 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Improvements or additions to documentation merge-risk: 🚨 auth-provider 🚨 May break OAuth, tokens, provider routing, model choice, or credentials. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. P2 Normal backlog priority with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. size: M status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. triage: blank-template Candidate: PR template appears mostly untouched. triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. triage: refactor-only Candidate: refactor/cleanup-only PR without maintainer context.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants