Repository navigation
Conversation
There was a problem hiding this comment.
Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.
An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.
Builds on append_endpoint_path: base_url may carry a query (stored
parameters win over client ones), {api_key} fills the key into the URL
with no auth header, and key_header picks Bearer, api-key or x-api-key.
Exact endpoints serve their protocol's path and its sub-paths only, so
count_tokens and stored responses continue after the endpoint while
embeddings and the connection test no longer reach them.
t0saki
force-pushed
the
feat/gateway-full-endpoint
branch
from
October 15, 2026 06:03
177e8ce to
9b00c23
Compare
This branch has not been deployed
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.
Description
#6100 added
append_endpoint_pathso an upstream can use its Base URL as the complete request endpoint. That is not enough for the endpoints that motivated it:https://RES.openai.azure.com/openai/deployments/DEP/chat/completions?api-version=2024-10-21) need a query string, whichUpstream.validate_urlstill rejects, and take the key in anapi-keyheader, whileupstream_headers()always sendsAuthorization: Bearer.base_url, which is returned to read-only callers, shown in the upstream list and echoed by the connection test. The key field is also mandatory and always sent as Bearer.count_tokenswas sent to the messages endpoint,/v1/responses/{id}to the create endpoint, embeddings and other protocol-less requests to the chat endpoint, and the connection test sentGET /v1/modelsthere and reported the 404/405 as "models unavailable".For the same reasons the VLM import skipped every Azure credential.
This PR builds on #6100 (keeping its field, toggle and wording) and fills these gaps.
Human Involvement
Related Issue
Follow-up to #6100. User feedback: the gateway cannot use fully custom endpoints such as Azure OpenAI or URLs that embed the key.
Type of Change
Changes Made
base_url: allowed in both modes (credentials and fragments are still rejected; the trailing slash is stripped from the path only). Stored parameters come first and win over client parameters with the same name, so a client cannot overrideapi-version.{api_key}placeholder: the only brace text allowed, never in the host. The key is URL-encoded into the stored address at send time only (never into the client's path or query), and no auth header is sent. Stored, listed and test-result URLs keep the placeholder.key_header:authorization(default, unchanged behavior),api-keyorx-api-key; the latter two send only that header.append_endpoint_path=False): the protocol's primary path goes to the URL, its sub-paths continue after it (…/messages/count_tokens,…/responses/{id}), other paths return 404, and protocol-less requests (embeddings, files, …) never select such an upstream; stored responses still find an exact responses upstream. The connection test returnsexact_endpoint_untestablewithout sending anything; in base mode it keeps the stored query and fills the key.azureand LiteLLMazure/<deployment>credentials become exact-endpoint chat upstreams at{api_base}/openai/deployments/{deployment}/chat/completions?api-version={api_version or 2025-01-01-preview}withkey_header="api-key".append_endpoint_pathandkey_headerare refreshed on re-import.{api_key}, reset when switching providers), URL validation and preview that accept queries and the placeholder, and a disabled connection test for exact endpoints. en and zh-CN strings stay in sync.22-gateway-operations.md,25-gateway.md): queries,{api_key}, the key header, an Azure OpenAI deployment example, which requests an exact endpoint serves, Azure OpenAI v1 / Claude in Microsoft Foundry / Gemini OpenAI-compatible base URLs, the corrected passthrough description, Azure import, and the removedazureskip reason.Testing
I have added tests that prove my fix is effective or that my feature works
New and existing unit tests pass locally with my changes
I have tested this on the following platforms:
pytest tests/gateway tests/server/test_gateway_vlm.py: 746 passed. New shared URL vectors intests/fixtures/gateway_upstream_urls.jsoncover stored queries, query merging, exact-endpoint sub-paths, the embeddings 404 and the placeholder; app tests cover an Azure-style request (api-keyonly, merged query), a key-in-query request with no auth header, and a stored response fetched through an exact responses endpoint.Studio:
vitest run src/routes/gateway src/i18n370 passed, including an upstream stored beforeappend_endpoint_pathexisted (its test button stays enabled).tscreports no errors in gateway files; ESLint and Prettier are clean on changed files.ruff format --checkandruff checkpass on changed Python files.Checklist
Screenshots (if applicable)
N/A
Additional Notes
base_url, including its query, still clears the stored key and headers, as before.