fix(runtime): resolve a Responses relay from one API base - #3797
Open
Sandu1213 wants to merge 1 commit into
Open
fix(runtime): resolve a Responses relay from one API base#3797Sandu1213 wants to merge 1 commit into
Sandu1213 wants to merge 1 commit into
Conversation
A custom OpenAI Responses relay configured with its host root passed the connection probe and then failed every model refresh. The probe posts to `<root>/responses`, which relays answer, while discovery requested `<root>/models` instead of the `/v1/models` an OpenAI-compatible surface publishes — so the connection looked verified and its catalog never updated. Normalize the configured relay URL once into the API base that send, probe, and discovery all derive from: a path-less root self-heals to `/v1`, as `anthropicV1BaseUrl` and `googleV1BetaBaseUrl` already do for their versions; an authored path (`/v1`, `/relay/v1`) is preserved verbatim; the endpoint form reduces to its base. Scoped to `openai-responses-compatible`, because built-ins such as DeepSeek legitimately serve `/responses` and `/models` at their own unversioned root and must not be rewritten. Refs apache#3320 Generated-by: Claude Opus 5
Astro-Han
reviewed
Aug 25, 2026
Astro-Han
left a comment
Contributor
There was a problem hiding this comment.
I reviewed this head and found no blocking issues.
The relay base normalization now consistently heals bare roots to /v1 and strips trailing /responses at the endpoint, aligning probe, discovery, and send. Scoped only to openai-responses-compatible to avoid breaking built-in providers that serve both paths. Tests lock the five normalization cases.
No P0-P2. Checks on afb7b5d have no hosted report yet — not green.
简体中文
该头未发现阻断。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A custom OpenAI Responses relay configured with its host root —
http://relay.example:3000— passes the connection probe and then fails every model refresh. The probe posts to<root>/responses, which relays answer, while discovery requests<root>/modelsinstead of the/v1/modelsan OpenAI-compatible surface publishes. The connection reads as verified and its catalog never updates.responsesRelayApiBaseUrlnormalizes the configured relay URL once into the single API base that send, probe, and discovery all derive from:http://relay.example:3000http://relay.example:3000/v1http://relay.example:3000/http://relay.example:3000/v1https://relay.example/v1https://relay.example/v1https://relay.example/v1/responseshttps://relay.example/v1https://relay.example/relay/v1https://relay.example/relay/v1resolveModelRuntimeapplies it to the send and probe addresses,fetchProviderModelsStrictto discovery, so the two can no longer disagree. Root self-healing followsanthropicV1BaseUrlandgoogleV1BetaBaseUrl; an authored path is preserved verbatim, soopenResponsesUrl's deliberate "no assumed/v1" contract (#2972) is unchanged for every other provider.Fixes #3320
Review focus
The scope is the product decision. Only
openai-responses-compatibleself-heals. DeepSeek shipshttps://api.deepseek.comand legitimately serves/responsesand/modelsat that unversioned root, so a blanket root →/v1rule would break a built-in;a DeepSeek root base keeps serving Responses at the root it publishesguards exactly that. The alternative raised on the issue — keep the configured base authoritative and warn about a bare host root in the add/edit form — leaves the two addresses resolving differently and still requires the user to know the version segment. Happy to move to it if that is the direction you want.Coordination: #3320 is assigned to @Xinbeok. Its other half — a failed discovery dropping the manually configured fallback model — already merged as #3581, so the URL half is what remains. Close this if it duplicates work already in flight.
Verification
npx tsc -p packages/runtime/tsconfig.json— clean.node --test "dist/**/*.test.js"inpackages/runtime— 3031 tests, 0 failures, including the three new cases.provider-urls.ts,model-runtime.ts, andmodel-fetcher.tsand rebuilding turnsa Responses relay configured with its host root discovers and probes one /v1 basered —actual '/models',expected '/v1/models'.npx biome lint .andnpx biome format .— clean repo-wide.npm --workspace @maka/core run test:dist— 656/656.Pre-existing on
mainat 689a451 and unchanged by this branch (reproduced with the branch stashed):npm run buildstops in@maka/runtime-host—src/__tests__/execution-host-queue.test.tsstill callsqueryTurn/stopTurn/startTurn, which refactor(runtime-host): use typed request as sole operation API #3784 removed fromRuntimeHostConnection.@maka/desktopand@maka/uitherefore could not be built or typechecked locally.@maka/storage— 5SqliteSessionMetadataStoresteering/follow-up failures. This branch touches no storage code.AI use
Select exactly one:
Tool(s) and scope: Claude Opus 5 investigated the two call sites, wrote the normalizer, its three call-site wirings, and the tests; the commit carries a
Generated-by: Claude Opus 5trailer. A human reviewed the scoping decision, ran the checks above, and owns the submission.Checklist
Does this PR entail a change in behavior?