feat: support overridePaths in deployment interfaces #1969 - #1961
Merged
Merged
Conversation
khshanovskyi
requested review from
Oleksii-Klimov and
astsiapanay
as code owners
September 11, 2026 07:13
This comment has been minimized.
This comment has been minimized.
1 similar comment
This comment has been minimized.
This comment has been minimized.
khshanovskyi
commented
Sep 14, 2026
khshanovskyi
force-pushed
the
feat/interfaces-override-paths
branch
from
September 14, 2026 08:32
5ca9faa to
d30ecda
Compare
astsiapanay
reviewed
Sep 14, 2026
astsiapanay
previously approved these changes
Sep 14, 2026
KirylKurnosenka
previously approved these changes
Sep 14, 2026
Adds `interfaces.<type>.overridePaths` so DIAL Core can front services that
do not follow the DIAL API path contract: a per-operation path replaces the
default "base URL + ingress path" routing for models, applications and
interceptors.
- `DeploymentInterface.overridePaths` maps a new `OverridePathKey` constant
(`postAzureOpenaiChatCompletions`, `postAzureOpenaiEmbeddings`,
`postOpenaiResponses`, `getOpenaiResponsesById`, `deleteOpenaiResponsesById`,
`postOpenaiResponsesCancel`, `postAnthropicMessages`,
`postAnthropicMessagesCountTokens`) to the path applied under the base url.
A key this Core does not know is ignored, as an unknown interface type is.
- `PathTemplateUtil` substitutes exactly two tokens: `{overrideName}` first
(url-encoded, so brace-free) and `{id}` last (never rescanned). Braces carry
no other syntax — anything else is path text forwarded as written. `{id}` is
the deployment name for the deployments-POST family and the hop's response id
for Responses item operations.
- `DeploymentEndpointUtil.resolveRequestUri` consults the override per
operation, and a new `resolveResponseItemUri` serves Responses get/delete/
cancel, replacing the three sites that concatenated onto
`resolveResponsesBaseUri` (item controller, interceptor hop, background poll).
Overrides apply only to interfaces/base-url routing: legacy `endpoint`/
`responsesEndpoint` and translator-served interfaces are untouched, and
behaviour without `overridePaths` is unchanged.
- Config validation rejects a key declared under an interface that does not own
it, an empty path, `{id}` on an operation that carries none, and overrides on
a `mode: translator` entry — at config load and on every API write surface
(config-resource writes, custom application writes, admin validate/apply), so
a write cannot persist an entity the next rebuild would drop.
- Corrects the documented interface types applications serve: the Responses and
Anthropic Messages APIs work for applications, and nothing dropped them on
config read.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
ConfigPostProcessor and ConfigValidationService no longer know about HttpException: validateOverridePaths only accumulates ValidationWarnings, and each write surface turns them into its own layer's failure — an EntityResult/ValidationResult for the admin services, the established validationWarnings 422 for the config-resource controller (whose body building is now shared with checkCrossReferences and checkTranslator), and the service's own HttpException idiom for application writes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Per review. Renames the type and the identifiers named after it (pathKey -> pathMapping, findRequestPathKey -> findRequestPathMapping, Operation.key -> Operation.pathMapping); the JSON key names in overridePaths are unchanged. Also drops a stale line in the DeploymentInterface javadoc that still promised doubled braces escape. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Override-path validation short-circuited before pricing and cross-reference checks, so a write carrying both kinds of defects reported only the override paths. Collect all of them into one warnings list on both write paths (POST /v1/admin/apply and PUT /v1/models/...), keeping override-path errors fatal even when soft validation is on. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…rnings list Interceptor and Application prechecks went through a private String-returning helper while every other validation in the file collects into a List<ValidationWarning> and joins it. Use the common shape so a second validation can be added next to the first one. Also make override-path defects fatal for Model precheck even under soft validation, matching ConfigApplyService#applyModel: otherwise precheck reports the batch as valid and the real-apply phase then refuses the model, after its siblings have already been written. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
khshanovskyi
force-pushed
the
feat/interfaces-override-paths
branch
from
September 14, 2026 10:51
fcaccbd to
f34c681
Compare
KirylKurnosenka
approved these changes
Sep 14, 2026
Contributor
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
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.
Adds
interfaces.<type>.overridePathsso DIAL Core can front services that do not follow the DIAL API path contract (e.g. Switchyard serving/v1/chat/completions): a per-operation path replaces the default "base URL + ingress path" routing, with the exact tokens{id}and{overrideName}substituted. Applies to models, applications and interceptors.Applicable issues
interfacesconfig withoverridePaths#1969Description of changes
DeploymentInterfacegainsoverridePaths(overridePaths/override_paths), keyed by the newOverridePathKeyenum:postAzureOpenaiChatCompletions,postAzureOpenaiEmbeddings,postOpenaiResponses,getOpenaiResponsesById,deleteOpenaiResponsesById,postOpenaiResponsesCancel,postAnthropicMessages,postAnthropicMessagesCountTokens. Unknown key names are tolerated for forward compatibility, mirroring unknown interface types.PathTemplateUtilsubstitutes exactly the literal tokens{id}and{overrideName}; any other brace usage (typos like{Id}, unknown placeholders, literal braces) is rejected at config load by a dry-run render, keeping the brace syntax reserved for future tokens.DeploymentEndpointUtil.resolveRequestUriconsults the override for the deployments-POST family (chat completions, embeddings, responses create, anthropic messages/count_tokens); a newresolveResponseItemUricovers responses GET/DELETE/cancel by id and replaced the three call sites that concatenated ontoresolveResponsesBaseUri(item controller, interceptor hop, background poll). Overrides apply only in the interfaces/base-url flow — legacyendpoint/responsesEndpointand translator-served interfaces are untouched, and behavior withoutoverridePathsis byte-identical.{id}renders the deployment's name for the deployments-POST family (equal to the path id on direct calls, and still correct on the interceptor callback hop where the raw segment is the pseudo-idinterceptor) and the hop's response id for responses item operations;{overrideName}renders the URL-encodedoverrideName, falling back to the deployment name.{id}where the operation carries none, and overrides onmode: translatorentries are rejected at load for models, applications and interceptors — including theMergedConfigStorepartial-update write path, so a write cannot accept an entity the next full rebuild would drop.PathTemplateUtilTest,DeploymentEndpointUtilTest,ConfigPostProcessorTest; full-stackOverridePathsApiTestproving requests on standard Core paths reach the mock upstream on the overridden paths for chat completions (with{overrideName}), embeddings, anthropic messages/count_tokens, responses create + GET-by-id, an application, and unoverridden cancel/delete keeping default routing.docs/dynamic-settings/models.md, with pointers fromapplications.mdandinterceptors.md.Checklist
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
🤖 Generated with Claude Code