feat(vertex): wire RequestOverrides on the Vertex bridge (#302 §5, #339) - #460

Merged
moonming merged 2 commits into
mainfrom
feat/339-vertex-request-overrides
Jun 1, 2026
Merged

feat(vertex): wire RequestOverrides on the Vertex bridge (#302 §5, #339)#460
moonming merged 2 commits into
mainfrom
feat/339-vertex-request-overrides

Conversation

@moonming

Copy link
Copy Markdown
Member

What

Wires the per-ProviderKeyRequestOverrides pipeline (issue #302 §5 RuntimeConfig) into the Vertex bridge, mirroring OpenAiBridge step-for-step. Until now the override primitives existed (aisix-provider-openai::overrides) and the OpenAI bridge applied them, but the Vertex bridge ignored provider_key.request / .response entirely — a Vertex BYO/catalog key could configure overrides and they'd silently no-op.

Closes#339.

Contract pinned

Applied on all five publisher rails (8 dispatch methods: chat_gemini + _stream, chat_anthropic + _stream, chat_openai_shim + _stream, chat_mistral_ai21 + _stream):

Outbound body (apply_body_overrides, mirrors OpenAiBridge::prepare_outbound_body):

  1. param_renames → 2. param_constraints → 3. default_body_fields → 4. content_list_to_string (when the response override sets it)

Outbound headers (build_request_headers, mirrors the OpenAI builder): default_headers applied last via the shared apply_default_headers, which drops reserved auth headers and refuses to overwrite an already-set header.

Ordering invariant

The body pipeline runs before the Vertex rail-specific shaping (the Anthropic model/stream strip), so a default_body_fields block can never reintroduce a URL-borne model into a :rawPredict body. default_headers can never clobber the minted GCP OAuth Bearer (reserved-header guard + already-present guard, double protection).

All four body primitives are no-ops when the targeted top-level keys are absent, so applying them uniformly is safe across the heterogeneous rails (the Gemini contents shape simply doesn't match the OpenAI-style keys the request transforms target — default_body_fields / default_headers still apply there).

Reference implementation

  • OpenAiBridge::prepare_outbound_body + build_request_headerscrates/aisix-provider-openai/src/bridge.rs (the apply order + reserved-header guard this PR mirrors).
  • The override primitives + their unit tests — crates/aisix-provider-openai/src/overrides.rs (unchanged; reused verbatim via the crate's pub mod overrides).
  • Vertex rail wire shapes (model-in-URL vs model-in-body) already cited inline per rail (Google Vertex partner-model docs + the Anthropic Vertex SDK).

Tests

6 wiremock round-trips assert the recorded outbound body / headers reflect each override:

  • gemini_request_applies_default_body_fields — injected top-level field lands, contents preserved
  • gemini_request_applies_default_headers — added header reaches the wire
  • default_headers_cannot_overwrite_vertex_bearer_auth — an authorization default can't displace the minted Bearer; non-reserved companion still applies
  • openai_shim_request_applies_param_renamestemperature → renamed key, source gone
  • openai_shim_request_applies_param_constraints — over-max temperature clamped
  • anthropic_request_overrides_run_before_model_stripdefault_body_fields.model stays stripped, a genuine extra field lands, anthropic_version shaping still runs

cargo test -p aisix-provider-vertex → 87 passed. cargo clippy --all-targets clean. cargo fmt applied.

🤖 Generated with Claude Code

Mirror OpenAiBridge's apply pipeline on all five Vertex publisher rails
(Gemini / Anthropic / OpenAI-compat shim / Mistral / AI21, non-stream +
streaming): param_renames -> param_constraints -> default_body_fields ->
content_list_to_string on the outbound body, and default_headers on the
outbound headers. All primitives are no-ops when the targeted keys are
absent, so the pipeline is safe to call uniformly across the rails.
The body pipeline runs BEFORE the rail-specific shaping (the Anthropic
model/stream strip), so an override can never reintroduce a URL-borne
`model` into a :rawPredict body. default_headers reuses the shared guard
in apply_default_headers, so it can never clobber the minted OAuth Bearer
or any reserved auth header.
Reuses the pub primitives from aisix-provider-openai::overrides (the same
ones OpenAiBridge calls) so cp-api configures one wire shape for every
adapter.
Tests: 6 wiremock round-trips assert the recorded body / headers reflect
each override across the Gemini, shim, and Anthropic rails, plus the
reserved-auth guard and the model-strip ordering invariant.
@coderabbitai

coderabbitaiBot commented Jun 1, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@moonming, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 6 minutes and 38 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Free

Run ID: 64b084c8-8664-45be-a56f-8acfe6aa63fe

📥 Commits

Reviewing files that changed from the base of the PR and between 9513223 and 93ee140.

📒 Files selected for processing (1)
  • crates/aisix-provider-vertex/src/bridge.rs

Note

🎁 Summarized by CodeRabbit Free

Your organization has reached its limit of developer seats under the Pro Plan. For new users, CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please add seats to your subscription by visiting https://app.coderabbit.ai/login.If you believe this is a mistake and have available seats, please assign one to the pull request author through the subscription management page using the link above.

Comment @coderabbitai help to get the list of available commands and usage tips.

Independent pre-merge audit of #460 flagged two MEDIUM test-coverage gaps
(production wiring itself verified correct on all 8 rails):
- MEDIUM-1: the `content_list_to_string` branch (gated on the response
override block) was unverified on Vertex.
- MEDIUM-2: the streaming body-build path and the partner `:rawPredict`
URL builder rail had no override regression test — a rail dropping the
override call would still pass.
Adds 3 wiremock round-trips:
- openai_shim_stream_applies_default_body_fields — the streaming serialize
path applies overrides; stream:true stays in the body
- mistral_request_applies_default_body_fields_and_keeps_model_in_body —
the partner :rawPredict rail applies overrides without disturbing the
in-body model
- openai_shim_response_content_list_to_string_flattens_outbound_body —
the response-gated array->string content flatten reaches the wire
90 tests pass; clippy clean.
@moonming

Copy link
Copy Markdown
MemberAuthor

Independent pre-merge audit (CLAUDE.md §8) returned BLOCK on two MEDIUM test-coverage findings (production wiring verified correct + secure + panic-free on all 8 rails). Both resolved in the follow-up commit:

  • MEDIUM-1 (content_list_to_string response-gated branch untested on Vertex) → added openai_shim_response_content_list_to_string_flattens_outbound_body (multi-block message → flattened string on the wire).
  • MEDIUM-2 (streaming body-build path + partner :rawPredict URL rail had no override regression test) → added openai_shim_stream_applies_default_body_fields (stream serialize path) + mistral_request_applies_default_body_fields_and_keeps_model_in_body (partner URL rail).

90 tests pass; cargo clippy --all-targets clean. No HIGH findings; no gateway-behavior bugs surfaced (both findings were test-tightness, not product gaps).

@moonming
moonming merged commit 66677e8 into mainJun 1, 2026
8 checks passed
@moonming
moonming deleted the feat/339-vertex-request-overrides branch June 1, 2026 03:01
Sign up for freeto 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.

wire RequestOverrides on aisix-provider-vertex bridge (mirror OpenAiBridge apply pipeline)

1 participant

@moonming
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

feat(vertex): wire RequestOverrides on the Vertex bridge (#302 §5, #339) - #460

Merged
moonming merged 2 commits into
mainfrom
feat/339-vertex-request-overrides
Jun 1, 2026
Merged

feat(vertex): wire RequestOverrides on the Vertex bridge (#302 §5, #339)#460
moonming merged 2 commits into
mainfrom
feat/339-vertex-request-overrides

Conversation

@moonming

Copy link
Copy Markdown
Member

What

Wires the per-ProviderKeyRequestOverrides pipeline (issue #302 §5 RuntimeConfig) into the Vertex bridge, mirroring OpenAiBridge step-for-step. Until now the override primitives existed (aisix-provider-openai::overrides) and the OpenAI bridge applied them, but the Vertex bridge ignored provider_key.request / .response entirely — a Vertex BYO/catalog key could configure overrides and they'd silently no-op.

Closes#339.

Contract pinned

Applied on all five publisher rails (8 dispatch methods: chat_gemini + _stream, chat_anthropic + _stream, chat_openai_shim + _stream, chat_mistral_ai21 + _stream):

Outbound body (apply_body_overrides, mirrors OpenAiBridge::prepare_outbound_body):

  1. param_renames → 2. param_constraints → 3. default_body_fields → 4. content_list_to_string (when the response override sets it)

Outbound headers (build_request_headers, mirrors the OpenAI builder): default_headers applied last via the shared apply_default_headers, which drops reserved auth headers and refuses to overwrite an already-set header.

Ordering invariant

The body pipeline runs before the Vertex rail-specific shaping (the Anthropic model/stream strip), so a default_body_fields block can never reintroduce a URL-borne model into a :rawPredict body. default_headers can never clobber the minted GCP OAuth Bearer (reserved-header guard + already-present guard, double protection).

All four body primitives are no-ops when the targeted top-level keys are absent, so applying them uniformly is safe across the heterogeneous rails (the Gemini contents shape simply doesn't match the OpenAI-style keys the request transforms target — default_body_fields / default_headers still apply there).

Reference implementation

  • OpenAiBridge::prepare_outbound_body + build_request_headerscrates/aisix-provider-openai/src/bridge.rs (the apply order + reserved-header guard this PR mirrors).
  • The override primitives + their unit tests — crates/aisix-provider-openai/src/overrides.rs (unchanged; reused verbatim via the crate's pub mod overrides).
  • Vertex rail wire shapes (model-in-URL vs model-in-body) already cited inline per rail (Google Vertex partner-model docs + the Anthropic Vertex SDK).

Tests

6 wiremock round-trips assert the recorded outbound body / headers reflect each override:

  • gemini_request_applies_default_body_fields — injected top-level field lands, contents preserved
  • gemini_request_applies_default_headers — added header reaches the wire
  • default_headers_cannot_overwrite_vertex_bearer_auth — an authorization default can't displace the minted Bearer; non-reserved companion still applies
  • openai_shim_request_applies_param_renamestemperature → renamed key, source gone
  • openai_shim_request_applies_param_constraints — over-max temperature clamped
  • anthropic_request_overrides_run_before_model_stripdefault_body_fields.model stays stripped, a genuine extra field lands, anthropic_version shaping still runs

cargo test -p aisix-provider-vertex → 87 passed. cargo clippy --all-targets clean. cargo fmt applied.

🤖 Generated with Claude Code

Mirror OpenAiBridge's apply pipeline on all five Vertex publisher rails
(Gemini / Anthropic / OpenAI-compat shim / Mistral / AI21, non-stream +
streaming): param_renames -> param_constraints -> default_body_fields ->
content_list_to_string on the outbound body, and default_headers on the
outbound headers. All primitives are no-ops when the targeted keys are
absent, so the pipeline is safe to call uniformly across the rails.
The body pipeline runs BEFORE the rail-specific shaping (the Anthropic
model/stream strip), so an override can never reintroduce a URL-borne
`model` into a :rawPredict body. default_headers reuses the shared guard
in apply_default_headers, so it can never clobber the minted OAuth Bearer
or any reserved auth header.
Reuses the pub primitives from aisix-provider-openai::overrides (the same
ones OpenAiBridge calls) so cp-api configures one wire shape for every
adapter.
Tests: 6 wiremock round-trips assert the recorded body / headers reflect
each override across the Gemini, shim, and Anthropic rails, plus the
reserved-auth guard and the model-strip ordering invariant.
@coderabbitai

coderabbitaiBot commented Jun 1, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@moonming, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 6 minutes and 38 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Free

Run ID: 64b084c8-8664-45be-a56f-8acfe6aa63fe

📥 Commits

Reviewing files that changed from the base of the PR and between 9513223 and 93ee140.

📒 Files selected for processing (1)
  • crates/aisix-provider-vertex/src/bridge.rs

Note

🎁 Summarized by CodeRabbit Free

Your organization has reached its limit of developer seats under the Pro Plan. For new users, CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please add seats to your subscription by visiting https://app.coderabbit.ai/login.If you believe this is a mistake and have available seats, please assign one to the pull request author through the subscription management page using the link above.

Comment @coderabbitai help to get the list of available commands and usage tips.

Independent pre-merge audit of #460 flagged two MEDIUM test-coverage gaps
(production wiring itself verified correct on all 8 rails):
- MEDIUM-1: the `content_list_to_string` branch (gated on the response
override block) was unverified on Vertex.
- MEDIUM-2: the streaming body-build path and the partner `:rawPredict`
URL builder rail had no override regression test — a rail dropping the
override call would still pass.
Adds 3 wiremock round-trips:
- openai_shim_stream_applies_default_body_fields — the streaming serialize
path applies overrides; stream:true stays in the body
- mistral_request_applies_default_body_fields_and_keeps_model_in_body —
the partner :rawPredict rail applies overrides without disturbing the
in-body model
- openai_shim_response_content_list_to_string_flattens_outbound_body —
the response-gated array->string content flatten reaches the wire
90 tests pass; clippy clean.
@moonming

Copy link
Copy Markdown
MemberAuthor

Independent pre-merge audit (CLAUDE.md §8) returned BLOCK on two MEDIUM test-coverage findings (production wiring verified correct + secure + panic-free on all 8 rails). Both resolved in the follow-up commit:

  • MEDIUM-1 (content_list_to_string response-gated branch untested on Vertex) → added openai_shim_response_content_list_to_string_flattens_outbound_body (multi-block message → flattened string on the wire).
  • MEDIUM-2 (streaming body-build path + partner :rawPredict URL rail had no override regression test) → added openai_shim_stream_applies_default_body_fields (stream serialize path) + mistral_request_applies_default_body_fields_and_keeps_model_in_body (partner URL rail).

90 tests pass; cargo clippy --all-targets clean. No HIGH findings; no gateway-behavior bugs surfaced (both findings were test-tightness, not product gaps).

@moonming
moonming merged commit 66677e8 into mainJun 1, 2026
8 checks passed
@moonming
moonming deleted the feat/339-vertex-request-overrides branch June 1, 2026 03:01
Sign up for freeto 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.

wire RequestOverrides on aisix-provider-vertex bridge (mirror OpenAiBridge apply pipeline)

1 participant

@moonming
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(vertex): wire RequestOverrides on the Vertex bridge (#302 §5, #339) - #460

Merged
moonming merged 2 commits into
mainfrom
feat/339-vertex-request-overrides
Jun 1, 2026
Merged

feat(vertex): wire RequestOverrides on the Vertex bridge (#302 §5, #339)#460
moonming merged 2 commits into
mainfrom
feat/339-vertex-request-overrides

Conversation

@moonming

Copy link
Copy Markdown
Member

What

Wires the per-ProviderKeyRequestOverrides pipeline (issue #302 §5 RuntimeConfig) into the Vertex bridge, mirroring OpenAiBridge step-for-step. Until now the override primitives existed (aisix-provider-openai::overrides) and the OpenAI bridge applied them, but the Vertex bridge ignored provider_key.request / .response entirely — a Vertex BYO/catalog key could configure overrides and they'd silently no-op.

Closes#339.

Contract pinned

Applied on all five publisher rails (8 dispatch methods: chat_gemini + _stream, chat_anthropic + _stream, chat_openai_shim + _stream, chat_mistral_ai21 + _stream):

Outbound body (apply_body_overrides, mirrors OpenAiBridge::prepare_outbound_body):

  1. param_renames → 2. param_constraints → 3. default_body_fields → 4. content_list_to_string (when the response override sets it)

Outbound headers (build_request_headers, mirrors the OpenAI builder): default_headers applied last via the shared apply_default_headers, which drops reserved auth headers and refuses to overwrite an already-set header.

Ordering invariant

The body pipeline runs before the Vertex rail-specific shaping (the Anthropic model/stream strip), so a default_body_fields block can never reintroduce a URL-borne model into a :rawPredict body. default_headers can never clobber the minted GCP OAuth Bearer (reserved-header guard + already-present guard, double protection).

All four body primitives are no-ops when the targeted top-level keys are absent, so applying them uniformly is safe across the heterogeneous rails (the Gemini contents shape simply doesn't match the OpenAI-style keys the request transforms target — default_body_fields / default_headers still apply there).

Reference implementation

  • OpenAiBridge::prepare_outbound_body + build_request_headerscrates/aisix-provider-openai/src/bridge.rs (the apply order + reserved-header guard this PR mirrors).
  • The override primitives + their unit tests — crates/aisix-provider-openai/src/overrides.rs (unchanged; reused verbatim via the crate's pub mod overrides).
  • Vertex rail wire shapes (model-in-URL vs model-in-body) already cited inline per rail (Google Vertex partner-model docs + the Anthropic Vertex SDK).

Tests

6 wiremock round-trips assert the recorded outbound body / headers reflect each override:

  • gemini_request_applies_default_body_fields — injected top-level field lands, contents preserved
  • gemini_request_applies_default_headers — added header reaches the wire
  • default_headers_cannot_overwrite_vertex_bearer_auth — an authorization default can't displace the minted Bearer; non-reserved companion still applies
  • openai_shim_request_applies_param_renamestemperature → renamed key, source gone
  • openai_shim_request_applies_param_constraints — over-max temperature clamped
  • anthropic_request_overrides_run_before_model_stripdefault_body_fields.model stays stripped, a genuine extra field lands, anthropic_version shaping still runs

cargo test -p aisix-provider-vertex → 87 passed. cargo clippy --all-targets clean. cargo fmt applied.

🤖 Generated with Claude Code

Mirror OpenAiBridge's apply pipeline on all five Vertex publisher rails
(Gemini / Anthropic / OpenAI-compat shim / Mistral / AI21, non-stream +
streaming): param_renames -> param_constraints -> default_body_fields ->
content_list_to_string on the outbound body, and default_headers on the
outbound headers. All primitives are no-ops when the targeted keys are
absent, so the pipeline is safe to call uniformly across the rails.
The body pipeline runs BEFORE the rail-specific shaping (the Anthropic
model/stream strip), so an override can never reintroduce a URL-borne
`model` into a :rawPredict body. default_headers reuses the shared guard
in apply_default_headers, so it can never clobber the minted OAuth Bearer
or any reserved auth header.
Reuses the pub primitives from aisix-provider-openai::overrides (the same
ones OpenAiBridge calls) so cp-api configures one wire shape for every
adapter.
Tests: 6 wiremock round-trips assert the recorded body / headers reflect
each override across the Gemini, shim, and Anthropic rails, plus the
reserved-auth guard and the model-strip ordering invariant.
@coderabbitai

coderabbitaiBot commented Jun 1, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@moonming, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 6 minutes and 38 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Free

Run ID: 64b084c8-8664-45be-a56f-8acfe6aa63fe

📥 Commits

Reviewing files that changed from the base of the PR and between 9513223 and 93ee140.

📒 Files selected for processing (1)
  • crates/aisix-provider-vertex/src/bridge.rs

Note

🎁 Summarized by CodeRabbit Free

Your organization has reached its limit of developer seats under the Pro Plan. For new users, CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please add seats to your subscription by visiting https://app.coderabbit.ai/login.If you believe this is a mistake and have available seats, please assign one to the pull request author through the subscription management page using the link above.

Comment @coderabbitai help to get the list of available commands and usage tips.

Independent pre-merge audit of #460 flagged two MEDIUM test-coverage gaps
(production wiring itself verified correct on all 8 rails):
- MEDIUM-1: the `content_list_to_string` branch (gated on the response
override block) was unverified on Vertex.
- MEDIUM-2: the streaming body-build path and the partner `:rawPredict`
URL builder rail had no override regression test — a rail dropping the
override call would still pass.
Adds 3 wiremock round-trips:
- openai_shim_stream_applies_default_body_fields — the streaming serialize
path applies overrides; stream:true stays in the body
- mistral_request_applies_default_body_fields_and_keeps_model_in_body —
the partner :rawPredict rail applies overrides without disturbing the
in-body model
- openai_shim_response_content_list_to_string_flattens_outbound_body —
the response-gated array->string content flatten reaches the wire
90 tests pass; clippy clean.
@moonming

Copy link
Copy Markdown
MemberAuthor

Independent pre-merge audit (CLAUDE.md §8) returned BLOCK on two MEDIUM test-coverage findings (production wiring verified correct + secure + panic-free on all 8 rails). Both resolved in the follow-up commit:

  • MEDIUM-1 (content_list_to_string response-gated branch untested on Vertex) → added openai_shim_response_content_list_to_string_flattens_outbound_body (multi-block message → flattened string on the wire).
  • MEDIUM-2 (streaming body-build path + partner :rawPredict URL rail had no override regression test) → added openai_shim_stream_applies_default_body_fields (stream serialize path) + mistral_request_applies_default_body_fields_and_keeps_model_in_body (partner URL rail).

90 tests pass; cargo clippy --all-targets clean. No HIGH findings; no gateway-behavior bugs surfaced (both findings were test-tightness, not product gaps).

@moonming
moonming merged commit 66677e8 into mainJun 1, 2026
8 checks passed
@moonming
moonming deleted the feat/339-vertex-request-overrides branch June 1, 2026 03:01
Sign up for freeto 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.

wire RequestOverrides on aisix-provider-vertex bridge (mirror OpenAiBridge apply pipeline)

1 participant

@moonming
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(vertex): wire RequestOverrides on the Vertex bridge (#302 §5, #339) - #460

Merged
moonming merged 2 commits into
mainfrom
feat/339-vertex-request-overrides
Jun 1, 2026
Merged

feat(vertex): wire RequestOverrides on the Vertex bridge (#302 §5, #339)#460
moonming merged 2 commits into
mainfrom
feat/339-vertex-request-overrides

Conversation

@moonming

Copy link
Copy Markdown
Member

What

Wires the per-ProviderKeyRequestOverrides pipeline (issue #302 §5 RuntimeConfig) into the Vertex bridge, mirroring OpenAiBridge step-for-step. Until now the override primitives existed (aisix-provider-openai::overrides) and the OpenAI bridge applied them, but the Vertex bridge ignored provider_key.request / .response entirely — a Vertex BYO/catalog key could configure overrides and they'd silently no-op.

Closes#339.

Contract pinned

Applied on all five publisher rails (8 dispatch methods: chat_gemini + _stream, chat_anthropic + _stream, chat_openai_shim + _stream, chat_mistral_ai21 + _stream):

Outbound body (apply_body_overrides, mirrors OpenAiBridge::prepare_outbound_body):

  1. param_renames → 2. param_constraints → 3. default_body_fields → 4. content_list_to_string (when the response override sets it)

Outbound headers (build_request_headers, mirrors the OpenAI builder): default_headers applied last via the shared apply_default_headers, which drops reserved auth headers and refuses to overwrite an already-set header.

Ordering invariant

The body pipeline runs before the Vertex rail-specific shaping (the Anthropic model/stream strip), so a default_body_fields block can never reintroduce a URL-borne model into a :rawPredict body. default_headers can never clobber the minted GCP OAuth Bearer (reserved-header guard + already-present guard, double protection).

All four body primitives are no-ops when the targeted top-level keys are absent, so applying them uniformly is safe across the heterogeneous rails (the Gemini contents shape simply doesn't match the OpenAI-style keys the request transforms target — default_body_fields / default_headers still apply there).

Reference implementation

  • OpenAiBridge::prepare_outbound_body + build_request_headerscrates/aisix-provider-openai/src/bridge.rs (the apply order + reserved-header guard this PR mirrors).
  • The override primitives + their unit tests — crates/aisix-provider-openai/src/overrides.rs (unchanged; reused verbatim via the crate's pub mod overrides).
  • Vertex rail wire shapes (model-in-URL vs model-in-body) already cited inline per rail (Google Vertex partner-model docs + the Anthropic Vertex SDK).

Tests

6 wiremock round-trips assert the recorded outbound body / headers reflect each override:

  • gemini_request_applies_default_body_fields — injected top-level field lands, contents preserved
  • gemini_request_applies_default_headers — added header reaches the wire
  • default_headers_cannot_overwrite_vertex_bearer_auth — an authorization default can't displace the minted Bearer; non-reserved companion still applies
  • openai_shim_request_applies_param_renamestemperature → renamed key, source gone
  • openai_shim_request_applies_param_constraints — over-max temperature clamped
  • anthropic_request_overrides_run_before_model_stripdefault_body_fields.model stays stripped, a genuine extra field lands, anthropic_version shaping still runs

cargo test -p aisix-provider-vertex → 87 passed. cargo clippy --all-targets clean. cargo fmt applied.

🤖 Generated with Claude Code

Mirror OpenAiBridge's apply pipeline on all five Vertex publisher rails
(Gemini / Anthropic / OpenAI-compat shim / Mistral / AI21, non-stream +
streaming): param_renames -> param_constraints -> default_body_fields ->
content_list_to_string on the outbound body, and default_headers on the
outbound headers. All primitives are no-ops when the targeted keys are
absent, so the pipeline is safe to call uniformly across the rails.
The body pipeline runs BEFORE the rail-specific shaping (the Anthropic
model/stream strip), so an override can never reintroduce a URL-borne
`model` into a :rawPredict body. default_headers reuses the shared guard
in apply_default_headers, so it can never clobber the minted OAuth Bearer
or any reserved auth header.
Reuses the pub primitives from aisix-provider-openai::overrides (the same
ones OpenAiBridge calls) so cp-api configures one wire shape for every
adapter.
Tests: 6 wiremock round-trips assert the recorded body / headers reflect
each override across the Gemini, shim, and Anthropic rails, plus the
reserved-auth guard and the model-strip ordering invariant.
@coderabbitai

coderabbitaiBot commented Jun 1, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@moonming, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 6 minutes and 38 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Free

Run ID: 64b084c8-8664-45be-a56f-8acfe6aa63fe

📥 Commits

Reviewing files that changed from the base of the PR and between 9513223 and 93ee140.

📒 Files selected for processing (1)
  • crates/aisix-provider-vertex/src/bridge.rs

Note

🎁 Summarized by CodeRabbit Free

Your organization has reached its limit of developer seats under the Pro Plan. For new users, CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please add seats to your subscription by visiting https://app.coderabbit.ai/login.If you believe this is a mistake and have available seats, please assign one to the pull request author through the subscription management page using the link above.

Comment @coderabbitai help to get the list of available commands and usage tips.

Independent pre-merge audit of #460 flagged two MEDIUM test-coverage gaps
(production wiring itself verified correct on all 8 rails):
- MEDIUM-1: the `content_list_to_string` branch (gated on the response
override block) was unverified on Vertex.
- MEDIUM-2: the streaming body-build path and the partner `:rawPredict`
URL builder rail had no override regression test — a rail dropping the
override call would still pass.
Adds 3 wiremock round-trips:
- openai_shim_stream_applies_default_body_fields — the streaming serialize
path applies overrides; stream:true stays in the body
- mistral_request_applies_default_body_fields_and_keeps_model_in_body —
the partner :rawPredict rail applies overrides without disturbing the
in-body model
- openai_shim_response_content_list_to_string_flattens_outbound_body —
the response-gated array->string content flatten reaches the wire
90 tests pass; clippy clean.
@moonming

Copy link
Copy Markdown
MemberAuthor

Independent pre-merge audit (CLAUDE.md §8) returned BLOCK on two MEDIUM test-coverage findings (production wiring verified correct + secure + panic-free on all 8 rails). Both resolved in the follow-up commit:

  • MEDIUM-1 (content_list_to_string response-gated branch untested on Vertex) → added openai_shim_response_content_list_to_string_flattens_outbound_body (multi-block message → flattened string on the wire).
  • MEDIUM-2 (streaming body-build path + partner :rawPredict URL rail had no override regression test) → added openai_shim_stream_applies_default_body_fields (stream serialize path) + mistral_request_applies_default_body_fields_and_keeps_model_in_body (partner URL rail).

90 tests pass; cargo clippy --all-targets clean. No HIGH findings; no gateway-behavior bugs surfaced (both findings were test-tightness, not product gaps).

@moonming
moonming merged commit 66677e8 into mainJun 1, 2026
8 checks passed
@moonming
moonming deleted the feat/339-vertex-request-overrides branch June 1, 2026 03:01
Sign up for freeto 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.

wire RequestOverrides on aisix-provider-vertex bridge (mirror OpenAiBridge apply pipeline)

1 participant

@moonming
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

feat(vertex): wire RequestOverrides on the Vertex bridge (#302 §5, #339) - #460

Merged
moonming merged 2 commits into
mainfrom
feat/339-vertex-request-overrides
Jun 1, 2026
Merged

feat(vertex): wire RequestOverrides on the Vertex bridge (#302 §5, #339)#460
moonming merged 2 commits into
mainfrom
feat/339-vertex-request-overrides

Conversation

@moonming

Copy link
Copy Markdown
Member

What

Wires the per-ProviderKeyRequestOverrides pipeline (issue #302 §5 RuntimeConfig) into the Vertex bridge, mirroring OpenAiBridge step-for-step. Until now the override primitives existed (aisix-provider-openai::overrides) and the OpenAI bridge applied them, but the Vertex bridge ignored provider_key.request / .response entirely — a Vertex BYO/catalog key could configure overrides and they'd silently no-op.

Closes#339.

Contract pinned

Applied on all five publisher rails (8 dispatch methods: chat_gemini + _stream, chat_anthropic + _stream, chat_openai_shim + _stream, chat_mistral_ai21 + _stream):

Outbound body (apply_body_overrides, mirrors OpenAiBridge::prepare_outbound_body):

  1. param_renames → 2. param_constraints → 3. default_body_fields → 4. content_list_to_string (when the response override sets it)

Outbound headers (build_request_headers, mirrors the OpenAI builder): default_headers applied last via the shared apply_default_headers, which drops reserved auth headers and refuses to overwrite an already-set header.

Ordering invariant

The body pipeline runs before the Vertex rail-specific shaping (the Anthropic model/stream strip), so a default_body_fields block can never reintroduce a URL-borne model into a :rawPredict body. default_headers can never clobber the minted GCP OAuth Bearer (reserved-header guard + already-present guard, double protection).

All four body primitives are no-ops when the targeted top-level keys are absent, so applying them uniformly is safe across the heterogeneous rails (the Gemini contents shape simply doesn't match the OpenAI-style keys the request transforms target — default_body_fields / default_headers still apply there).

Reference implementation

  • OpenAiBridge::prepare_outbound_body + build_request_headerscrates/aisix-provider-openai/src/bridge.rs (the apply order + reserved-header guard this PR mirrors).
  • The override primitives + their unit tests — crates/aisix-provider-openai/src/overrides.rs (unchanged; reused verbatim via the crate's pub mod overrides).
  • Vertex rail wire shapes (model-in-URL vs model-in-body) already cited inline per rail (Google Vertex partner-model docs + the Anthropic Vertex SDK).

Tests

6 wiremock round-trips assert the recorded outbound body / headers reflect each override:

  • gemini_request_applies_default_body_fields — injected top-level field lands, contents preserved
  • gemini_request_applies_default_headers — added header reaches the wire
  • default_headers_cannot_overwrite_vertex_bearer_auth — an authorization default can't displace the minted Bearer; non-reserved companion still applies
  • openai_shim_request_applies_param_renamestemperature → renamed key, source gone
  • openai_shim_request_applies_param_constraints — over-max temperature clamped
  • anthropic_request_overrides_run_before_model_stripdefault_body_fields.model stays stripped, a genuine extra field lands, anthropic_version shaping still runs

cargo test -p aisix-provider-vertex → 87 passed. cargo clippy --all-targets clean. cargo fmt applied.

🤖 Generated with Claude Code

Mirror OpenAiBridge's apply pipeline on all five Vertex publisher rails
(Gemini / Anthropic / OpenAI-compat shim / Mistral / AI21, non-stream +
streaming): param_renames -> param_constraints -> default_body_fields ->
content_list_to_string on the outbound body, and default_headers on the
outbound headers. All primitives are no-ops when the targeted keys are
absent, so the pipeline is safe to call uniformly across the rails.
The body pipeline runs BEFORE the rail-specific shaping (the Anthropic
model/stream strip), so an override can never reintroduce a URL-borne
`model` into a :rawPredict body. default_headers reuses the shared guard
in apply_default_headers, so it can never clobber the minted OAuth Bearer
or any reserved auth header.
Reuses the pub primitives from aisix-provider-openai::overrides (the same
ones OpenAiBridge calls) so cp-api configures one wire shape for every
adapter.
Tests: 6 wiremock round-trips assert the recorded body / headers reflect
each override across the Gemini, shim, and Anthropic rails, plus the
reserved-auth guard and the model-strip ordering invariant.
@coderabbitai

coderabbitaiBot commented Jun 1, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@moonming, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 6 minutes and 38 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Free

Run ID: 64b084c8-8664-45be-a56f-8acfe6aa63fe

📥 Commits

Reviewing files that changed from the base of the PR and between 9513223 and 93ee140.

📒 Files selected for processing (1)
  • crates/aisix-provider-vertex/src/bridge.rs

Note

🎁 Summarized by CodeRabbit Free

Your organization has reached its limit of developer seats under the Pro Plan. For new users, CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please add seats to your subscription by visiting https://app.coderabbit.ai/login.If you believe this is a mistake and have available seats, please assign one to the pull request author through the subscription management page using the link above.

Comment @coderabbitai help to get the list of available commands and usage tips.

Independent pre-merge audit of #460 flagged two MEDIUM test-coverage gaps
(production wiring itself verified correct on all 8 rails):
- MEDIUM-1: the `content_list_to_string` branch (gated on the response
override block) was unverified on Vertex.
- MEDIUM-2: the streaming body-build path and the partner `:rawPredict`
URL builder rail had no override regression test — a rail dropping the
override call would still pass.
Adds 3 wiremock round-trips:
- openai_shim_stream_applies_default_body_fields — the streaming serialize
path applies overrides; stream:true stays in the body
- mistral_request_applies_default_body_fields_and_keeps_model_in_body —
the partner :rawPredict rail applies overrides without disturbing the
in-body model
- openai_shim_response_content_list_to_string_flattens_outbound_body —
the response-gated array->string content flatten reaches the wire
90 tests pass; clippy clean.
@moonming

Copy link
Copy Markdown
MemberAuthor

Independent pre-merge audit (CLAUDE.md §8) returned BLOCK on two MEDIUM test-coverage findings (production wiring verified correct + secure + panic-free on all 8 rails). Both resolved in the follow-up commit:

  • MEDIUM-1 (content_list_to_string response-gated branch untested on Vertex) → added openai_shim_response_content_list_to_string_flattens_outbound_body (multi-block message → flattened string on the wire).
  • MEDIUM-2 (streaming body-build path + partner :rawPredict URL rail had no override regression test) → added openai_shim_stream_applies_default_body_fields (stream serialize path) + mistral_request_applies_default_body_fields_and_keeps_model_in_body (partner URL rail).

90 tests pass; cargo clippy --all-targets clean. No HIGH findings; no gateway-behavior bugs surfaced (both findings were test-tightness, not product gaps).

@moonming
moonming merged commit 66677e8 into mainJun 1, 2026
8 checks passed
@moonming
moonming deleted the feat/339-vertex-request-overrides branch June 1, 2026 03:01
Sign up for freeto 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.

wire RequestOverrides on aisix-provider-vertex bridge (mirror OpenAiBridge apply pipeline)

1 participant

@moonming
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(vertex): wire RequestOverrides on the Vertex bridge (#302 §5, #339) - #460

Merged
moonming merged 2 commits into
mainfrom
feat/339-vertex-request-overrides
Jun 1, 2026
Merged

feat(vertex): wire RequestOverrides on the Vertex bridge (#302 §5, #339)#460
moonming merged 2 commits into
mainfrom
feat/339-vertex-request-overrides

Conversation

@moonming

Copy link
Copy Markdown
Member

What

Wires the per-ProviderKeyRequestOverrides pipeline (issue #302 §5 RuntimeConfig) into the Vertex bridge, mirroring OpenAiBridge step-for-step. Until now the override primitives existed (aisix-provider-openai::overrides) and the OpenAI bridge applied them, but the Vertex bridge ignored provider_key.request / .response entirely — a Vertex BYO/catalog key could configure overrides and they'd silently no-op.

Closes#339.

Contract pinned

Applied on all five publisher rails (8 dispatch methods: chat_gemini + _stream, chat_anthropic + _stream, chat_openai_shim + _stream, chat_mistral_ai21 + _stream):

Outbound body (apply_body_overrides, mirrors OpenAiBridge::prepare_outbound_body):

  1. param_renames → 2. param_constraints → 3. default_body_fields → 4. content_list_to_string (when the response override sets it)

Outbound headers (build_request_headers, mirrors the OpenAI builder): default_headers applied last via the shared apply_default_headers, which drops reserved auth headers and refuses to overwrite an already-set header.

Ordering invariant

The body pipeline runs before the Vertex rail-specific shaping (the Anthropic model/stream strip), so a default_body_fields block can never reintroduce a URL-borne model into a :rawPredict body. default_headers can never clobber the minted GCP OAuth Bearer (reserved-header guard + already-present guard, double protection).

All four body primitives are no-ops when the targeted top-level keys are absent, so applying them uniformly is safe across the heterogeneous rails (the Gemini contents shape simply doesn't match the OpenAI-style keys the request transforms target — default_body_fields / default_headers still apply there).

Reference implementation

  • OpenAiBridge::prepare_outbound_body + build_request_headerscrates/aisix-provider-openai/src/bridge.rs (the apply order + reserved-header guard this PR mirrors).
  • The override primitives + their unit tests — crates/aisix-provider-openai/src/overrides.rs (unchanged; reused verbatim via the crate's pub mod overrides).
  • Vertex rail wire shapes (model-in-URL vs model-in-body) already cited inline per rail (Google Vertex partner-model docs + the Anthropic Vertex SDK).

Tests

6 wiremock round-trips assert the recorded outbound body / headers reflect each override:

  • gemini_request_applies_default_body_fields — injected top-level field lands, contents preserved
  • gemini_request_applies_default_headers — added header reaches the wire
  • default_headers_cannot_overwrite_vertex_bearer_auth — an authorization default can't displace the minted Bearer; non-reserved companion still applies
  • openai_shim_request_applies_param_renamestemperature → renamed key, source gone
  • openai_shim_request_applies_param_constraints — over-max temperature clamped
  • anthropic_request_overrides_run_before_model_stripdefault_body_fields.model stays stripped, a genuine extra field lands, anthropic_version shaping still runs

cargo test -p aisix-provider-vertex → 87 passed. cargo clippy --all-targets clean. cargo fmt applied.

🤖 Generated with Claude Code

Mirror OpenAiBridge's apply pipeline on all five Vertex publisher rails
(Gemini / Anthropic / OpenAI-compat shim / Mistral / AI21, non-stream +
streaming): param_renames -> param_constraints -> default_body_fields ->
content_list_to_string on the outbound body, and default_headers on the
outbound headers. All primitives are no-ops when the targeted keys are
absent, so the pipeline is safe to call uniformly across the rails.
The body pipeline runs BEFORE the rail-specific shaping (the Anthropic
model/stream strip), so an override can never reintroduce a URL-borne
`model` into a :rawPredict body. default_headers reuses the shared guard
in apply_default_headers, so it can never clobber the minted OAuth Bearer
or any reserved auth header.
Reuses the pub primitives from aisix-provider-openai::overrides (the same
ones OpenAiBridge calls) so cp-api configures one wire shape for every
adapter.
Tests: 6 wiremock round-trips assert the recorded body / headers reflect
each override across the Gemini, shim, and Anthropic rails, plus the
reserved-auth guard and the model-strip ordering invariant.
@coderabbitai

coderabbitaiBot commented Jun 1, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@moonming, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 6 minutes and 38 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Free

Run ID: 64b084c8-8664-45be-a56f-8acfe6aa63fe

📥 Commits

Reviewing files that changed from the base of the PR and between 9513223 and 93ee140.

📒 Files selected for processing (1)
  • crates/aisix-provider-vertex/src/bridge.rs

Note

🎁 Summarized by CodeRabbit Free

Your organization has reached its limit of developer seats under the Pro Plan. For new users, CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please add seats to your subscription by visiting https://app.coderabbit.ai/login.If you believe this is a mistake and have available seats, please assign one to the pull request author through the subscription management page using the link above.

Comment @coderabbitai help to get the list of available commands and usage tips.

Independent pre-merge audit of #460 flagged two MEDIUM test-coverage gaps
(production wiring itself verified correct on all 8 rails):
- MEDIUM-1: the `content_list_to_string` branch (gated on the response
override block) was unverified on Vertex.
- MEDIUM-2: the streaming body-build path and the partner `:rawPredict`
URL builder rail had no override regression test — a rail dropping the
override call would still pass.
Adds 3 wiremock round-trips:
- openai_shim_stream_applies_default_body_fields — the streaming serialize
path applies overrides; stream:true stays in the body
- mistral_request_applies_default_body_fields_and_keeps_model_in_body —
the partner :rawPredict rail applies overrides without disturbing the
in-body model
- openai_shim_response_content_list_to_string_flattens_outbound_body —
the response-gated array->string content flatten reaches the wire
90 tests pass; clippy clean.
@moonming

Copy link
Copy Markdown
MemberAuthor

Independent pre-merge audit (CLAUDE.md §8) returned BLOCK on two MEDIUM test-coverage findings (production wiring verified correct + secure + panic-free on all 8 rails). Both resolved in the follow-up commit:

  • MEDIUM-1 (content_list_to_string response-gated branch untested on Vertex) → added openai_shim_response_content_list_to_string_flattens_outbound_body (multi-block message → flattened string on the wire).
  • MEDIUM-2 (streaming body-build path + partner :rawPredict URL rail had no override regression test) → added openai_shim_stream_applies_default_body_fields (stream serialize path) + mistral_request_applies_default_body_fields_and_keeps_model_in_body (partner URL rail).

90 tests pass; cargo clippy --all-targets clean. No HIGH findings; no gateway-behavior bugs surfaced (both findings were test-tightness, not product gaps).

@moonming
moonming merged commit 66677e8 into mainJun 1, 2026
8 checks passed
@moonming
moonming deleted the feat/339-vertex-request-overrides branch June 1, 2026 03:01
Sign up for freeto 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.

wire RequestOverrides on aisix-provider-vertex bridge (mirror OpenAiBridge apply pipeline)

1 participant

@moonming
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

feat(vertex): wire RequestOverrides on the Vertex bridge (#302 §5, #339) - #460

Merged
moonming merged 2 commits into
mainfrom
feat/339-vertex-request-overrides
Jun 1, 2026
Merged

feat(vertex): wire RequestOverrides on the Vertex bridge (#302 §5, #339)#460
moonming merged 2 commits into
mainfrom
feat/339-vertex-request-overrides

Conversation

@moonming

Copy link
Copy Markdown
Member

What

Wires the per-ProviderKeyRequestOverrides pipeline (issue #302 §5 RuntimeConfig) into the Vertex bridge, mirroring OpenAiBridge step-for-step. Until now the override primitives existed (aisix-provider-openai::overrides) and the OpenAI bridge applied them, but the Vertex bridge ignored provider_key.request / .response entirely — a Vertex BYO/catalog key could configure overrides and they'd silently no-op.

Closes#339.

Contract pinned

Applied on all five publisher rails (8 dispatch methods: chat_gemini + _stream, chat_anthropic + _stream, chat_openai_shim + _stream, chat_mistral_ai21 + _stream):

Outbound body (apply_body_overrides, mirrors OpenAiBridge::prepare_outbound_body):

  1. param_renames → 2. param_constraints → 3. default_body_fields → 4. content_list_to_string (when the response override sets it)

Outbound headers (build_request_headers, mirrors the OpenAI builder): default_headers applied last via the shared apply_default_headers, which drops reserved auth headers and refuses to overwrite an already-set header.

Ordering invariant

The body pipeline runs before the Vertex rail-specific shaping (the Anthropic model/stream strip), so a default_body_fields block can never reintroduce a URL-borne model into a :rawPredict body. default_headers can never clobber the minted GCP OAuth Bearer (reserved-header guard + already-present guard, double protection).

All four body primitives are no-ops when the targeted top-level keys are absent, so applying them uniformly is safe across the heterogeneous rails (the Gemini contents shape simply doesn't match the OpenAI-style keys the request transforms target — default_body_fields / default_headers still apply there).

Reference implementation

  • OpenAiBridge::prepare_outbound_body + build_request_headerscrates/aisix-provider-openai/src/bridge.rs (the apply order + reserved-header guard this PR mirrors).
  • The override primitives + their unit tests — crates/aisix-provider-openai/src/overrides.rs (unchanged; reused verbatim via the crate's pub mod overrides).
  • Vertex rail wire shapes (model-in-URL vs model-in-body) already cited inline per rail (Google Vertex partner-model docs + the Anthropic Vertex SDK).

Tests

6 wiremock round-trips assert the recorded outbound body / headers reflect each override:

  • gemini_request_applies_default_body_fields — injected top-level field lands, contents preserved
  • gemini_request_applies_default_headers — added header reaches the wire
  • default_headers_cannot_overwrite_vertex_bearer_auth — an authorization default can't displace the minted Bearer; non-reserved companion still applies
  • openai_shim_request_applies_param_renamestemperature → renamed key, source gone
  • openai_shim_request_applies_param_constraints — over-max temperature clamped
  • anthropic_request_overrides_run_before_model_stripdefault_body_fields.model stays stripped, a genuine extra field lands, anthropic_version shaping still runs

cargo test -p aisix-provider-vertex → 87 passed. cargo clippy --all-targets clean. cargo fmt applied.

🤖 Generated with Claude Code

Mirror OpenAiBridge's apply pipeline on all five Vertex publisher rails
(Gemini / Anthropic / OpenAI-compat shim / Mistral / AI21, non-stream +
streaming): param_renames -> param_constraints -> default_body_fields ->
content_list_to_string on the outbound body, and default_headers on the
outbound headers. All primitives are no-ops when the targeted keys are
absent, so the pipeline is safe to call uniformly across the rails.
The body pipeline runs BEFORE the rail-specific shaping (the Anthropic
model/stream strip), so an override can never reintroduce a URL-borne
`model` into a :rawPredict body. default_headers reuses the shared guard
in apply_default_headers, so it can never clobber the minted OAuth Bearer
or any reserved auth header.
Reuses the pub primitives from aisix-provider-openai::overrides (the same
ones OpenAiBridge calls) so cp-api configures one wire shape for every
adapter.
Tests: 6 wiremock round-trips assert the recorded body / headers reflect
each override across the Gemini, shim, and Anthropic rails, plus the
reserved-auth guard and the model-strip ordering invariant.
@coderabbitai

coderabbitaiBot commented Jun 1, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@moonming, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 6 minutes and 38 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Free

Run ID: 64b084c8-8664-45be-a56f-8acfe6aa63fe

📥 Commits

Reviewing files that changed from the base of the PR and between 9513223 and 93ee140.

📒 Files selected for processing (1)
  • crates/aisix-provider-vertex/src/bridge.rs

Note

🎁 Summarized by CodeRabbit Free

Your organization has reached its limit of developer seats under the Pro Plan. For new users, CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please add seats to your subscription by visiting https://app.coderabbit.ai/login.If you believe this is a mistake and have available seats, please assign one to the pull request author through the subscription management page using the link above.

Comment @coderabbitai help to get the list of available commands and usage tips.

Independent pre-merge audit of #460 flagged two MEDIUM test-coverage gaps
(production wiring itself verified correct on all 8 rails):
- MEDIUM-1: the `content_list_to_string` branch (gated on the response
override block) was unverified on Vertex.
- MEDIUM-2: the streaming body-build path and the partner `:rawPredict`
URL builder rail had no override regression test — a rail dropping the
override call would still pass.
Adds 3 wiremock round-trips:
- openai_shim_stream_applies_default_body_fields — the streaming serialize
path applies overrides; stream:true stays in the body
- mistral_request_applies_default_body_fields_and_keeps_model_in_body —
the partner :rawPredict rail applies overrides without disturbing the
in-body model
- openai_shim_response_content_list_to_string_flattens_outbound_body —
the response-gated array->string content flatten reaches the wire
90 tests pass; clippy clean.
@moonming

Copy link
Copy Markdown
MemberAuthor

Independent pre-merge audit (CLAUDE.md §8) returned BLOCK on two MEDIUM test-coverage findings (production wiring verified correct + secure + panic-free on all 8 rails). Both resolved in the follow-up commit:

  • MEDIUM-1 (content_list_to_string response-gated branch untested on Vertex) → added openai_shim_response_content_list_to_string_flattens_outbound_body (multi-block message → flattened string on the wire).
  • MEDIUM-2 (streaming body-build path + partner :rawPredict URL rail had no override regression test) → added openai_shim_stream_applies_default_body_fields (stream serialize path) + mistral_request_applies_default_body_fields_and_keeps_model_in_body (partner URL rail).

90 tests pass; cargo clippy --all-targets clean. No HIGH findings; no gateway-behavior bugs surfaced (both findings were test-tightness, not product gaps).

@moonming
moonming merged commit 66677e8 into mainJun 1, 2026
8 checks passed
@moonming
moonming deleted the feat/339-vertex-request-overrides branch June 1, 2026 03:01
Sign up for freeto 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.

wire RequestOverrides on aisix-provider-vertex bridge (mirror OpenAiBridge apply pipeline)

1 participant

@moonming
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

feat(vertex): wire RequestOverrides on the Vertex bridge (#302 §5, #339) - #460

Merged
moonming merged 2 commits into
mainfrom
feat/339-vertex-request-overrides
Jun 1, 2026
Merged

feat(vertex): wire RequestOverrides on the Vertex bridge (#302 §5, #339)#460
moonming merged 2 commits into
mainfrom
feat/339-vertex-request-overrides

Conversation

@moonming

Copy link
Copy Markdown
Member

What

Wires the per-ProviderKeyRequestOverrides pipeline (issue #302 §5 RuntimeConfig) into the Vertex bridge, mirroring OpenAiBridge step-for-step. Until now the override primitives existed (aisix-provider-openai::overrides) and the OpenAI bridge applied them, but the Vertex bridge ignored provider_key.request / .response entirely — a Vertex BYO/catalog key could configure overrides and they'd silently no-op.

Closes#339.

Contract pinned

Applied on all five publisher rails (8 dispatch methods: chat_gemini + _stream, chat_anthropic + _stream, chat_openai_shim + _stream, chat_mistral_ai21 + _stream):

Outbound body (apply_body_overrides, mirrors OpenAiBridge::prepare_outbound_body):

  1. param_renames → 2. param_constraints → 3. default_body_fields → 4. content_list_to_string (when the response override sets it)

Outbound headers (build_request_headers, mirrors the OpenAI builder): default_headers applied last via the shared apply_default_headers, which drops reserved auth headers and refuses to overwrite an already-set header.

Ordering invariant

The body pipeline runs before the Vertex rail-specific shaping (the Anthropic model/stream strip), so a default_body_fields block can never reintroduce a URL-borne model into a :rawPredict body. default_headers can never clobber the minted GCP OAuth Bearer (reserved-header guard + already-present guard, double protection).

All four body primitives are no-ops when the targeted top-level keys are absent, so applying them uniformly is safe across the heterogeneous rails (the Gemini contents shape simply doesn't match the OpenAI-style keys the request transforms target — default_body_fields / default_headers still apply there).

Reference implementation

  • OpenAiBridge::prepare_outbound_body + build_request_headerscrates/aisix-provider-openai/src/bridge.rs (the apply order + reserved-header guard this PR mirrors).
  • The override primitives + their unit tests — crates/aisix-provider-openai/src/overrides.rs (unchanged; reused verbatim via the crate's pub mod overrides).
  • Vertex rail wire shapes (model-in-URL vs model-in-body) already cited inline per rail (Google Vertex partner-model docs + the Anthropic Vertex SDK).

Tests

6 wiremock round-trips assert the recorded outbound body / headers reflect each override:

  • gemini_request_applies_default_body_fields — injected top-level field lands, contents preserved
  • gemini_request_applies_default_headers — added header reaches the wire
  • default_headers_cannot_overwrite_vertex_bearer_auth — an authorization default can't displace the minted Bearer; non-reserved companion still applies
  • openai_shim_request_applies_param_renamestemperature → renamed key, source gone
  • openai_shim_request_applies_param_constraints — over-max temperature clamped
  • anthropic_request_overrides_run_before_model_stripdefault_body_fields.model stays stripped, a genuine extra field lands, anthropic_version shaping still runs

cargo test -p aisix-provider-vertex → 87 passed. cargo clippy --all-targets clean. cargo fmt applied.

🤖 Generated with Claude Code

Mirror OpenAiBridge's apply pipeline on all five Vertex publisher rails
(Gemini / Anthropic / OpenAI-compat shim / Mistral / AI21, non-stream +
streaming): param_renames -> param_constraints -> default_body_fields ->
content_list_to_string on the outbound body, and default_headers on the
outbound headers. All primitives are no-ops when the targeted keys are
absent, so the pipeline is safe to call uniformly across the rails.
The body pipeline runs BEFORE the rail-specific shaping (the Anthropic
model/stream strip), so an override can never reintroduce a URL-borne
`model` into a :rawPredict body. default_headers reuses the shared guard
in apply_default_headers, so it can never clobber the minted OAuth Bearer
or any reserved auth header.
Reuses the pub primitives from aisix-provider-openai::overrides (the same
ones OpenAiBridge calls) so cp-api configures one wire shape for every
adapter.
Tests: 6 wiremock round-trips assert the recorded body / headers reflect
each override across the Gemini, shim, and Anthropic rails, plus the
reserved-auth guard and the model-strip ordering invariant.
@coderabbitai

coderabbitaiBot commented Jun 1, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@moonming, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 6 minutes and 38 seconds. Learn how PR review limits work.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Free

Run ID: 64b084c8-8664-45be-a56f-8acfe6aa63fe

📥 Commits

Reviewing files that changed from the base of the PR and between 9513223 and 93ee140.

📒 Files selected for processing (1)
  • crates/aisix-provider-vertex/src/bridge.rs

Note

🎁 Summarized by CodeRabbit Free

Your organization has reached its limit of developer seats under the Pro Plan. For new users, CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please add seats to your subscription by visiting https://app.coderabbit.ai/login.If you believe this is a mistake and have available seats, please assign one to the pull request author through the subscription management page using the link above.

Comment @coderabbitai help to get the list of available commands and usage tips.

Independent pre-merge audit of #460 flagged two MEDIUM test-coverage gaps
(production wiring itself verified correct on all 8 rails):
- MEDIUM-1: the `content_list_to_string` branch (gated on the response
override block) was unverified on Vertex.
- MEDIUM-2: the streaming body-build path and the partner `:rawPredict`
URL builder rail had no override regression test — a rail dropping the
override call would still pass.
Adds 3 wiremock round-trips:
- openai_shim_stream_applies_default_body_fields — the streaming serialize
path applies overrides; stream:true stays in the body
- mistral_request_applies_default_body_fields_and_keeps_model_in_body —
the partner :rawPredict rail applies overrides without disturbing the
in-body model
- openai_shim_response_content_list_to_string_flattens_outbound_body —
the response-gated array->string content flatten reaches the wire
90 tests pass; clippy clean.
@moonming

Copy link
Copy Markdown
MemberAuthor

Independent pre-merge audit (CLAUDE.md §8) returned BLOCK on two MEDIUM test-coverage findings (production wiring verified correct + secure + panic-free on all 8 rails). Both resolved in the follow-up commit:

  • MEDIUM-1 (content_list_to_string response-gated branch untested on Vertex) → added openai_shim_response_content_list_to_string_flattens_outbound_body (multi-block message → flattened string on the wire).
  • MEDIUM-2 (streaming body-build path + partner :rawPredict URL rail had no override regression test) → added openai_shim_stream_applies_default_body_fields (stream serialize path) + mistral_request_applies_default_body_fields_and_keeps_model_in_body (partner URL rail).

90 tests pass; cargo clippy --all-targets clean. No HIGH findings; no gateway-behavior bugs surfaced (both findings were test-tightness, not product gaps).

@moonming
moonming merged commit 66677e8 into mainJun 1, 2026
8 checks passed
@moonming
moonming deleted the feat/339-vertex-request-overrides branch June 1, 2026 03:01
Sign up for freeto 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.

wire RequestOverrides on aisix-provider-vertex bridge (mirror OpenAiBridge apply pipeline)

1 participant

@moonming