Skip to content

fix(providers): centralize media request shaping#59469

Merged
vincentkoc merged 5 commits into
mainfrom
fix/provider-request-headers
Apr 2, 2026
Merged

fix(providers): centralize media request shaping#59469
vincentkoc merged 5 commits into
mainfrom
fix/provider-request-headers

Conversation

@vincentkoc

Copy link
Copy Markdown
Member

Summary

  • Problem: provider media/image/audio HTTP paths were still rebuilding baseUrl, private-network allowance, default auth headers, and attribution/header precedence independently.
  • Why it matters: phase 1 and phase 2 centralized request policy and model-path request shaping, but non-model HTTP paths were still a duplication hotspot for future proxy/custom-header/auth/TLS work.
  • What changed: added resolveProviderHttpRequestConfig to the provider HTTP seam and migrated OpenAI-compatible audio, Deepgram audio, Gemini media-understanding, Gemini image generation, and Moonshot video to use it.
  • What did NOT change (scope boundary): response parsing and provider-specific payload bodies stay provider-owned; stream wrapper consolidation is not part of this PR.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

Root Cause / Regression History (if applicable)

  • Root cause: provider HTTP call sites evolved separate request-building logic after model-path request shaping was centralized, so default auth/header/baseUrl behavior could drift by capability and provider.
  • Missing detection / guardrail: there was no shared seam test locking caller-header precedence plus default-header application across non-model HTTP paths.
  • Prior context (git blame, prior PR, issue, or refactor if known): this is the next phase after refactor(providers): add internal request config seam #59454, which introduced the internal request-config seam for model resolution.
  • Why this regressed now: it is older duplication, not a fresh regression from refactor(providers): add internal request config seam #59454. That PR made the remaining gap more obvious because model and non-model request shaping no longer matched structurally.
  • If unknown, what was ruled out: N/A

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file: src/media-understanding/shared.test.ts plus existing provider tests for OpenAI audio, Deepgram, Moonshot, and Gemini media/image paths.
  • Scenario the test should lock in: caller headers win over defaults; default auth headers are still injected when absent; explicit custom base URLs continue to enable private-network fetches for provider-owned endpoints.
  • Why this is the smallest reliable guardrail: the shared helper is now the merge point, and the provider tests prove the migrated call sites still emit the expected requests.
  • Existing test that already covers this (if any): provider-specific request-shape tests existed, but they did not lock in the shared merge contract.
  • If no new test is added, why not: N/A

User-visible / Behavior Changes

  • Providers that use the shared HTTP seam now resolve default auth headers, attribution headers, and explicit custom baseUrl handling through one path instead of per-provider merge logic.
  • Explicit caller header overrides remain preserved.

Diagram (if applicable)

Before:
[provider http path] -> [manual baseUrl/auth/header merge] -> [POST]
[another provider path] -> [slightly different manual merge] -> [POST]

After:
[provider http path] -> [resolveProviderHttpRequestConfig] -> [provider payload + POST]

Security Impact (required)

  • New permissions/capabilities? (No)
  • Secrets/tokens handling changed? (No)
  • New/changed network calls? (No)
  • Command/tool execution surface changed? (No)
  • Data access scope changed? (No)
  • If any Yes, explain risk + mitigation:

Repro + Verification

Environment

  • OS: macOS
  • Runtime/container: Node 22 / pnpm
  • Model/provider: OpenAI-compatible audio, Deepgram, Google Gemini, Moonshot
  • Integration/channel (if any): N/A
  • Relevant config (redacted): default provider config plus explicit custom baseUrl in scoped tests

Steps

  1. Run the affected media/image/audio providers with and without explicit header overrides.
  2. Inspect the emitted request headers and URL construction.
  3. Verify the shared helper preserves explicit headers and still injects defaults when absent.

Expected

  • Provider requests keep existing payload shapes while sharing one header/baseUrl/private-network merge path.

Actual

  • The migrated providers now use the shared helper and the targeted tests/build/check all pass.

Evidence

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Human Verification (required)

  • Verified scenarios: OpenAI audio attribution/auth override behavior, Deepgram auth/content-type defaults, Gemini media/image auth + baseUrl handling, Moonshot video request shaping, shared helper precedence tests.
  • Edge cases checked: explicit auth/header override, fallback base URL without private-network enablement, custom configured base URL with provider-owned private-network allowance.
  • What you did not verify: full pnpm test and live provider credentials.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? (Yes)
  • Config/env changes? (No)
  • Migration needed? (No)
  • If yes, exact upgrade steps:

Risks and Mitigations

  • Risk: the new helper is exported through openclaw/plugin-sdk/provider-http, so future changes to it become SDK-surface changes.
    • Mitigation: keep it narrow, additive, and covered by shared seam tests plus existing provider request-shape tests.
  • Risk: migrating more providers later could accidentally over-generalize request shaping.
    • Mitigation: this PR centralizes only common transport/header/baseUrl behavior and leaves payload construction/provider response parsing local.

@vincentkoc vincentkoc self-assigned this Apr 2, 2026
@vincentkoc
vincentkoc marked this pull request as ready for review April 2, 2026 05:45

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6ada6567c8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread extensions/google/media-understanding-provider.ts
Comment thread extensions/google/image-generation-provider.ts
@greptile-apps

greptile-apps Bot commented Apr 2, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR centralizes media/audio/image/video HTTP request shaping across OpenAI-compatible audio, Deepgram, Gemini, and Moonshot providers by introducing resolveProviderHttpRequestConfig — a shared helper that handles base-URL normalization, default-header injection with caller-header precedence, and allowPrivateNetwork derivation.

Key changes:

  • New resolveProviderHttpRequestConfig helper (src/media-understanding/shared.ts): merges caller headers over defaults and attribution headers in one place; exposes an explicit allowPrivateNetwork override so callers that pre-normalize URLs (Google providers) can supply the correct value themselves.
  • Google providers (image-generation-provider.ts, media-understanding-provider.ts): both correctly guard against the pre-normalized-URL pitfall by explicitly passing allowPrivateNetwork: Boolean(rawConfigBaseUrl?.trim()) before the URL is normalized, so the helper's params.allowPrivateNetwork ?? Boolean(params.baseUrl?.trim()) path uses the explicit value and private-network access is only enabled when a user has configured a custom endpoint.
  • Moonshot (media-understanding-provider.ts): the old call site omitted allowPrivateNetwork from postJsonRequest entirely (effectively hardcoded false); the new path correctly derives it from params.baseUrl, enabling private-network access for custom endpoints.
  • Tests (src/media-understanding/shared.test.ts): three cases lock in caller-header precedence, fallback-URL/no-private-network, and the explicit-override contract used by the Google providers — directly addressing the gap called out in the prior review thread.
  • SDK export (src/plugin-sdk/provider-http.ts): resolveProviderHttpRequestConfig is exported through the provider-http seam, making it available to plugin/extension authors.

Confidence Score: 5/5

  • Safe to merge — implementation is correct, previous P1 concerns about allowPrivateNetwork in Google providers are addressed, and new tests lock in the shared helper's contracts.
  • All previously flagged P1 issues (the allowPrivateNetwork always-true regression for Google providers) are resolved by the explicit allowPrivateNetwork parameter override in both Google call sites. The helper's precedence logic is correct and covered by tests. No new bugs were introduced. Remaining observations are at most P2 (the requestConfig.auth field in the returned struct is not populated by resolveProviderHttpRequestConfig, but callers don't use it and the PR description explicitly scopes future auth work out of this change).
  • No files require special attention — the Google provider allowPrivateNetwork handling and the shared seam tests are both in good shape.

Reviews (2): Last reviewed commit: "fix(google): preserve private network gu..." | Re-trigger Greptile

Comment thread extensions/google/image-generation-provider.ts
Comment thread src/media-understanding/shared.test.ts
@vincentkoc

Copy link
Copy Markdown
Member Author

@greptileai review

@vincentkoc
vincentkoc merged commit f28f0f2 into main Apr 2, 2026
42 of 46 checks passed
@vincentkoc
vincentkoc deleted the fix/provider-request-headers branch April 2, 2026 06:28
ngutman pushed a commit that referenced this pull request Apr 3, 2026
* fix(providers): centralize media request shaping

* style(providers): normalize shared request imports

* fix(changelog): add media request shaping entry

* fix(google): preserve private network guard
steipete pushed a commit to duncanita/openclaw that referenced this pull request Apr 4, 2026
* fix(providers): centralize media request shaping

* style(providers): normalize shared request imports

* fix(changelog): add media request shaping entry

* fix(google): preserve private network guard
lovewanwan pushed a commit to lovewanwan/openclaw that referenced this pull request Apr 28, 2026
* fix(providers): centralize media request shaping

* style(providers): normalize shared request imports

* fix(changelog): add media request shaping entry

* fix(google): preserve private network guard
ogt-redknie pushed a commit to ogt-redknie/OPENX that referenced this pull request May 2, 2026
* fix(providers): centralize media request shaping

* style(providers): normalize shared request imports

* fix(changelog): add media request shaping entry

* fix(google): preserve private network guard
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 9, 2026
* fix(providers): centralize media request shaping

* style(providers): normalize shared request imports

* fix(changelog): add media request shaping entry

* fix(google): preserve private network guard
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 24, 2026
* fix(providers): centralize media request shaping

* style(providers): normalize shared request imports

* fix(changelog): add media request shaping entry

* fix(google): preserve private network guard
Nachx639 pushed a commit to Nachx639/clawdbot that referenced this pull request Jun 17, 2026
* fix(providers): centralize media request shaping

* style(providers): normalize shared request imports

* fix(changelog): add media request shaping entry

* fix(google): preserve private network guard
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant