Skip to content

feat(routing): EndpointModeAuto for runtime protocol auto-detection - #1137

Open
0x0079 wants to merge 3 commits into
mainfrom
feat/endpoint-mode-auto
Open

feat(routing): EndpointModeAuto for runtime protocol auto-detection#1137
0x0079 wants to merge 3 commits into
mainfrom
feat/endpoint-mode-auto

Conversation

@0x0079

@0x0079 0x0079 commented Jun 5, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • EndpointModeAuto: new auto option for OpenAIEndpointMode that detects per-model protocol support at runtime — no static config needed for aggregator providers (OpenRouter, SiliconFlow, etc.) hosting models with mixed Chat Completions / Responses API support
  • Runtime fallback: on first request, tries the incoming protocol; if it fails with a retryable error, transparently retries with the alternate protocol. Success-only results are cached (24h TTL) so subsequent requests hit the right endpoint directly
  • E2E probe auto-detection: the probe subsystem also respects EndpointModeAuto, using the same cache for consistent behavior
  • Frontend: endpoint mode selector added to ProviderFormDialog with auto as a visible option

Design

  • EndpointCache (provider+model → protocol) with 24h TTL, success-only writes
  • firstChunkGate pattern buffers the response until commit/discard decision — no bytes hit the wire on failed first attempt
  • dispatchWithPriorityFailoverGated accepts an external gate to avoid nested gate commit signal issues
  • Error classification by exclusion: auth (401/403), rate limit (429), content errors are non-retryable; everything else triggers fallback
  • Override flags retain highest priority over auto-detection

Key files

File Change
ai/provider.go EndpointModeAuto constant
internal/server/endpoint_cache.go In-memory success cache
internal/server/endpoint_auto.go Error classification + helpers
internal/server/failover_dispatch.go Gated dispatch variant
internal/server/openai_chat.go Auto fallback in Chat handler
internal/server/openai_responses.go Auto fallback in Responses handler
internal/server/endpoint_resolution.go Explicit auto case
internal/probe/e2e.go Probe auto-detection with cache
frontend/src/components/ProviderFormDialog.tsx UI selector

Test plan

  • endpoint_cache_test.go: Get/Set, TTL expiry, concurrent safety
  • endpoint_auto_test.go: error classification (401→no retry, 404→retry, 429→no retry, context_length→no retry, unknown 500→retry)
  • endpoint_resolution_test.go: auto mode cases
  • Existing failover tests pass (signature unchanged)
  • Manual: configure provider as auto, verify chat-only model falls back correctly, cache populated on success

Generated by Claude Code

@0x0079
0x0079 force-pushed the feat/endpoint-mode-auto branch 5 times, most recently from 02f1a8c to 3f9ef19 Compare June 11, 2026 13:13
@0x0079
0x0079 force-pushed the feat/endpoint-mode-auto branch 2 times, most recently from 3d33661 to 112a94a Compare June 16, 2026 07:03
Adds an "auto" OpenAI endpoint mode: for OpenAI-compatible providers the
gateway tries the scenario-preferred protocol first, falls back to the
alternate on a retryable failure, and caches the winning protocol per
provider+model. Gated behind the global "auto_endpoint" experimental flag.

Rebased onto main and aligned with main's structure: endpoint code lives
in package server (protocol_endpoint.go + endpoint_auto.go/endpoint_cache.go),
not a separate internal/endpoint package — following main's housekeeping
consolidation. The auto path nests as protocol-fallback (outer) over
provider-failover (inner) sharing a single first-chunk gate, via the new
dispatchWithPriorityFailoverGated variant.

- ai: EndpointModeAuto + IsAutoEndpointMode; non-Codex OAuth defaults to auto
- server: resolveAutoTarget (override→cache→scenario), dispatchWithAutoFallback,
  EndpointCache; wired into chat + responses handlers via runOpenAI*Attempt
- protocol_endpoint: ResolveOpenAIEndpoint handles Auto (mirror incoming) as
  the non-auto fallback
- probe: E2E probe honors the endpoint cache
- client: IsNonRetryableForProtocolSwitch guards pointless protocol swaps
- config: auto_endpoint scenario flag
- frontend: experimental toggle + i18n (en/zh)

https://claude.ai/code/session_01N9JnUTVt41NcGxYyj3xewf
@0x0079
0x0079 force-pushed the feat/endpoint-mode-auto branch from 8583e6b to 6a54bbf Compare July 1, 2026 16:36
claude added 2 commits July 2, 2026 03:33
- Extract autoDispatchOrFailover: the ~25-line "auto vs plain failover"
  decision was duplicated verbatim in openai_chat.go and openai_responses.go,
  differing only by the IncomingAPIType constant and inner attempt body.
  Both call sites now share one helper.
- Drop the ok bool from autoDispatchFn. Every real call site returned
  ok=true unconditionally (dispatchWithPriorityFailoverGated never yields a
  nil provider), so served != nil alone was already the complete success
  signal; ok was a vestige of an earlier direct-transform design.

No behavior change; verified via existing endpoint_auto_test.go suite.

https://claude.ai/code/session_01N9JnUTVt41NcGxYyj3xewf
…point

endpoint_auto.go, endpoint_cache.go and their tests were split out of the
same feature (OpenAI endpoint resolution + auto-detection) that already
lives in protocol_endpoint.go. Four files for one cohesive concern was
unnecessary fragmentation — folded them back in, organized under section
banners (static resolution / cache / runtime auto-detection dispatch).

No code changes beyond the move; verified via full endpoint_auto_test.go
suite now inlined in protocol_endpoint_test.go.

https://claude.ai/code/session_01N9JnUTVt41NcGxYyj3xewf
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