Skip to content

fix(sse): bypass web-search fallback on Claude passthrough - #2960

Merged
diegosouzapw merged 1 commit into
cheaper-inference:release/v3.8.8from
terence71-glitch:fix/claude-web-search-passthrough-bypass
May 31, 2026
Merged

diegosouzapw merged 1 commit into
cheaper-inference:release/v3.8.8from
terence71-glitch:fix/claude-web-search-passthrough-bypass

Conversation

@terence71-glitch

@terence71-glitch terence71-glitch commented May 30, 2026 •

Copy link
Copy Markdown
Contributor

Summary

This PR makes the web-search fallback bypass explicit for native Claude → Claude passthrough requests.

The web-search fallback rewrites built-in web search tools into OmniRoute's omniroute_web_search function for providers that cannot execute web search natively. Codex native passthrough and Gemini targets were already bypassed, but Claude → Claude passthrough was only protected indirectly because Anthropic's current versioned tool type, web_search_20250305, was not part of the exact-match fallback matcher.

This change adds an explicit bypass when both sourceFormat and targetFormat are Claude, so native Anthropic web-search tools are forwarded untouched to the Claude upstream.

Changes

  • Add Claude → Claude native web-search bypass in supportsNativeWebSearchFallbackBypass().
  • Keep OpenAI-format clients targeting Claude on the fallback conversion path.
  • Add predicate coverage for native Codex passthrough, Gemini target, Claude → Claude passthrough, and negative cases.
  • Add end-to-end body behavior tests for:
    • Claude native web_search_20250305 forwarding
    • Claude bare web_search forwarding
    • Codex web_search_preview forwarding
    • OpenAI → Claude fallback conversion

Why

Claude Code / Anthropic Messages passthrough requests may include native Anthropic web-search tools. These should be handled by the Claude upstream, not rewritten into OmniRoute's fallback function.

The new bypass is intentionally narrow:

  • sourceFormat === "claude"
  • targetFormat === "claude"

This avoids breaking non-native requests such as OpenAI-format clients targeting Claude, where the tool still needs to be converted.

Validation

Focused regression tests pass:

node --import tsx --import ./open-sse/utils/setupPolyfill.ts --test tests/unit/web-search-fallback-format.test.ts

13 tests
13 pass
0 fail

Focused lint completed with no errors:

npx eslint open-sse/services/webSearchFallback.ts tests/unit/web-search-fallback-format.test.ts

Note: lint reports one warning for an existing explicit any in the committed test file:

tests/unit/web-search-fallback-format.test.ts
  224:47  warning  Unexpected any. Specify a different type  @typescript-eslint/no-explicit-any

The web-search fallback rewrites a built-in web_search tool into the
OmniRoute-fulfilled omniroute_web_search function for providers that
cannot run web search natively. Codex (nativeCodexPassthrough) and
Gemini (target format) were explicitly bypassed, but the Claude ->
Claude passthrough was not. It was only protected incidentally, because
Anthropic's versioned tool type (web_search_20250305) happens to be
absent from the exact-match matcher set — a bare or future-renamed
type would have started getting rewritten.

Add an explicit, symmetric bypass for sourceFormat === CLAUDE &&
targetFormat === CLAUDE so the native Anthropic web search tool is
forwarded untouched to the upstream (e.g. a Claude subscription driven
by Claude Code), regardless of the tool's exact type string. The
condition is narrowed to source AND target Claude: an OpenAI-format
client targeting a Claude provider sends a non-native tool that must
still be converted.

Tests (folded into the existing web-search-fallback-format suite):
predicate coverage for all three native bypasses (Codex/Gemini/Claude)
plus negative cases (OpenAI->OpenAI, OpenAI->Claude, Claude->OpenAI),
and end-to-end body assertions that the native Claude tool (versioned
and bare) and the Codex built-in tool are forwarded verbatim.

@gemini-code-assist gemini-code-assist 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.

Code Review

This pull request introduces a Claude-to-Claude native web search bypass in supportsNativeWebSearchFallbackBypass to forward native Claude tools untouched, and adds comprehensive unit tests covering the new bypass logic. The review feedback suggests improving type safety in the tests by replacing an explicit 'any' type assertion with a more specific type shape to avoid linter warnings.

assert.equal(fallback.enabled, true);
assert.equal(fallback.toolName, OMNIROUTE_WEB_SEARCH_FALLBACK_TOOL_NAME);
assert.equal(fallback.convertedToolCount, 1);
const tools = (body.tools as Record<string, any>[]) || [];

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.

medium

Using any triggers the @typescript-eslint/no-explicit-any linter warning. We can replace Record<string, any>[] with a more specific, type-safe shape that avoids any while still allowing direct property access to function and name.

  const tools = (body.tools as Array<{ function?: { name?: string }; name?: string }>) || [];

@kilo-code-bot

kilo-code-bot Bot commented May 30, 2026 •

Copy link
Copy Markdown

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Files Reviewed (2 files)
  • open-sse/services/webSearchFallback.ts — added sourceFormat parameter and Claude→Claude bypass
  • tests/unit/web-search-fallback-format.test.ts — comprehensive predicate + e2e coverage
Inline Comments (0)

No inline issues flagged.

Other Observations
  • Test file carries an existing explicit any (linter warning at line 224, noted in PR description but not addressed). Not introduced by this PR.
  • Nothing in the diff appears risky or erroneous. The fallback bypass symmetry (Codex / Gemini / Claude) is well-scoped and the OpenAI→Claude negative test correctly protects the conversion path.

Reviewed by step-3.7-flash-20260528 · 1,016,378 tokens

@diegosouzapw

Copy link
Copy Markdown
Collaborator

Thank you for your contribution! This PR has been reviewed and integrated into the upcoming v3.8.8 release. 🎉

@diegosouzapw
diegosouzapw merged commit 187bc50 into cheaper-inference:release/v3.8.8 May 31, 2026
3 checks passed
diegosouzapw added a commit that referenced this pull request Jun 1, 2026
…env-doc fixes

- bump package.json / open-sse / electron / openapi / llm.txt to 3.8.8
- restructure CHANGELOG: Unreleased -> [3.8.8], dedup broken Notion/MCP block (was 12x)
- add every PR since v3.8.7 that was missing: Quota Share Engine (#2859/#3022/#3032),
  page redesigns (#2827/#2839/#2847/#2849/#2869/#2873), and fixes #2960/#2973/#2984/
  #3021/#3029/#3031/#3035/#3036/#3037/#3039/#3043/#3028; folded #2978/#2988/#3041
- insert [3.8.8] section into all 41 i18n CHANGELOGs + sync llm.txt mirrors
- document OMNIROUTE_PLUGINS_ALLOW_EXEC in .env.example + ENVIRONMENT.md (env-doc-sync gap)
@diegosouzapw diegosouzapw mentioned this pull request Jun 2, 2026
HouMinXi pushed a commit to HouMinXi/OmniRoute that referenced this pull request Aug 2, 2026
HouMinXi pushed a commit to HouMinXi/OmniRoute that referenced this pull request Aug 2, 2026
…env-doc fixes

- bump package.json / open-sse / electron / openapi / llm.txt to 3.8.8
- restructure CHANGELOG: Unreleased -> [3.8.8], dedup broken Notion/MCP block (was 12x)
- add every PR since v3.8.7 that was missing: Quota Share Engine (cheaper-inference#2859/cheaper-inference#3022/cheaper-inference#3032),
  page redesigns (cheaper-inference#2827/cheaper-inference#2839/cheaper-inference#2847/cheaper-inference#2849/cheaper-inference#2869/cheaper-inference#2873), and fixes cheaper-inference#2960/cheaper-inference#2973/cheaper-inference#2984/
  cheaper-inference#3021/cheaper-inference#3029/cheaper-inference#3031/cheaper-inference#3035/cheaper-inference#3036/cheaper-inference#3037/cheaper-inference#3039/cheaper-inference#3043/cheaper-inference#3028; folded cheaper-inference#2978/cheaper-inference#2988/cheaper-inference#3041
- insert [3.8.8] section into all 41 i18n CHANGELOGs + sync llm.txt mirrors
- document OMNIROUTE_PLUGINS_ALLOW_EXEC in .env.example + ENVIRONMENT.md (env-doc-sync gap)
Poid-ZA pushed a commit to Poid-ZA/OmniRoute that referenced this pull request Aug 5, 2026
Poid-ZA pushed a commit to Poid-ZA/OmniRoute that referenced this pull request Aug 5, 2026
…env-doc fixes

- bump package.json / open-sse / electron / openapi / llm.txt to 3.8.8
- restructure CHANGELOG: Unreleased -> [3.8.8], dedup broken Notion/MCP block (was 12x)
- add every PR since v3.8.7 that was missing: Quota Share Engine (cheaper-inference#2859/cheaper-inference#3022/cheaper-inference#3032),
  page redesigns (cheaper-inference#2827/cheaper-inference#2839/cheaper-inference#2847/cheaper-inference#2849/cheaper-inference#2869/cheaper-inference#2873), and fixes cheaper-inference#2960/cheaper-inference#2973/cheaper-inference#2984/
  cheaper-inference#3021/cheaper-inference#3029/cheaper-inference#3031/cheaper-inference#3035/cheaper-inference#3036/cheaper-inference#3037/cheaper-inference#3039/cheaper-inference#3043/cheaper-inference#3028; folded cheaper-inference#2978/cheaper-inference#2988/cheaper-inference#3041
- insert [3.8.8] section into all 41 i18n CHANGELOGs + sync llm.txt mirrors
- document OMNIROUTE_PLUGINS_ALLOW_EXEC in .env.example + ENVIRONMENT.md (env-doc-sync gap)
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
muhamadgalihsaputra pushed a commit to niyatna/NiyatnaRoute that referenced this pull request Sep 27, 2026
…env-doc fixes

- bump package.json / open-sse / electron / openapi / llm.txt to 3.8.8
- restructure CHANGELOG: Unreleased -> [3.8.8], dedup broken Notion/MCP block (was 12x)
- add every PR since v3.8.7 that was missing: Quota Share Engine (cheaper-inference#2859/cheaper-inference#3022/cheaper-inference#3032),
  page redesigns (cheaper-inference#2827/cheaper-inference#2839/cheaper-inference#2847/cheaper-inference#2849/cheaper-inference#2869/cheaper-inference#2873), and fixes cheaper-inference#2960/cheaper-inference#2973/cheaper-inference#2984/
  cheaper-inference#3021/cheaper-inference#3029/cheaper-inference#3031/cheaper-inference#3035/cheaper-inference#3036/cheaper-inference#3037/cheaper-inference#3039/cheaper-inference#3043/cheaper-inference#3028; folded cheaper-inference#2978/cheaper-inference#2988/cheaper-inference#3041
- insert [3.8.8] section into all 41 i18n CHANGELOGs + sync llm.txt mirrors
- document OMNIROUTE_PLUGINS_ALLOW_EXEC in .env.example + ENVIRONMENT.md (env-doc-sync gap)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants