Skip to content

fix: preserve hosted image tool preferences - #616

Open
Eleven-is-cool wants to merge 1 commit into
lidge-jun:devfrom
Eleven-is-cool:fix/model-hosted-tools-preference
Open

fix: preserve hosted image tool preferences#616
Eleven-is-cool wants to merge 1 commit into
lidge-jun:devfrom
Eleven-is-cool:fix/model-hosted-tools-preference

Conversation

@Eleven-is-cool

@Eleven-is-cool Eleven-is-cool commented Jul 28, 2026

Copy link
Copy Markdown

Summary

  • Add exact-model hosted-tool preference for Responses-compatible gateways.
  • Remove colliding client image_gen declarations and rewrite affected selectors to hosted image_generation without widening tool choice.
  • Validate the effective per-model Responses wire, including registry routing and OpenAI API virtual-model rewrites.

Root cause

Some gateways reserve the image tool namespace server-side. The existing generic normalization intentionally retains an empty client namespace, so those gateways reject the request before tool execution.

Validation

  • Targeted hosted-tool, provider-validation, and virtual-model regression tests
  • bun run typecheck
  • bun run privacy:scan
  • bun run lint:gui
  • bun run doctor:gui:if-changed
  • bun run build in docs-site

Full bun run test: 5,704 passed, 1 skipped; 28 existing environment-dependent model-catalog/network-policy failures remain outside this change.

Summary by CodeRabbit

  • New Features
    • Added modelPreferHostedTools to provider configuration for per-model opt-in to prefer hosted image_generation on supported non-forward openai-responses gateways.
    • When enabled for an exact model, rewrites colliding caller image_gen selections to hosted tooling while preserving tool-choice intent.
  • Documentation
    • Updated reference/architecture docs (multiple languages) describing the option, supported namespace(s), and forward-auth limitations.
  • Bug Fixes
    • Improved model-aware hosted-tool capability handling and OpenAI virtual -pro model resolution behavior.
  • Tests
    • Expanded coverage for config validation, management checks, virtual model aliasing, and hosted image tool preference behavior.

@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 6083b087-708a-4c5c-b157-ae1318e0ad47

📥 Commits

Reviewing files that changed from the base of the PR and between 2831925 and 1aba0e4.

📒 Files selected for processing (16)
  • docs-site/src/content/docs/ja/reference/configuration.md
  • docs-site/src/content/docs/ko/reference/configuration.md
  • docs-site/src/content/docs/reference/configuration.md
  • docs-site/src/content/docs/ru/reference/configuration.md
  • docs-site/src/content/docs/zh-cn/reference/configuration.md
  • src/adapters/openai-responses.ts
  • src/config.ts
  • src/providers/openai-virtual-models.ts
  • src/responses/hosted-tool-policy.ts
  • src/server/auth-cors.ts
  • src/types.ts
  • structure/04_transports-and-sidecars.md
  • tests/config.test.ts
  • tests/management-provider-validation.test.ts
  • tests/openai-api-virtual-models.test.ts
  • tests/openai-responses-passthrough.test.ts

📝 Walkthrough

Walkthrough

Adds exact-model modelPreferHostedTools configuration, validates provider wiring and hosted-tool support, preserves virtual model IDs, and normalizes conflicting OpenAI Responses image-generation tools and selectors.

Changes

Hosted tool preference

Layer / File(s) Summary
Configuration contract and validation
src/types.ts, src/config.ts, src/server/auth-cors.ts, tests/config.test.ts, tests/management-provider-validation.test.ts, docs-site/src/content/docs/.../reference/configuration.md, structure/04-transports-and-sidecars.md
Adds and documents modelPreferHostedTools, validates its shape, supported tools, auth mode, model support, and effective openai-responses wiring, with diagnostic coverage.
Model resolution and hosted-tool policy
src/providers/openai-virtual-models.ts, src/responses/hosted-tool-policy.ts, tests/openai-api-virtual-models.test.ts
Preserves the selected virtual model ID and centralizes model-specific hosted-tool rejection checks.
Responses request normalization
src/adapters/openai-responses.ts, tests/openai-responses-passthrough.test.ts
Filters unsupported hosted tools and rewrites configured-model image_gen declarations and selectors to image_generation, including nested and allowed_tools cases while retaining unrelated choices.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant ConfigurationValidator
  participant OpenAIResponsesAdapter
  participant OpenAIResponsesGateway
  Client->>ConfigurationValidator: Configure modelPreferHostedTools
  ConfigurationValidator->>ConfigurationValidator: Validate model, hosted tool, auth mode, and wire
  Client->>OpenAIResponsesAdapter: Send model, tools, and tool_choice
  OpenAIResponsesAdapter->>OpenAIResponsesAdapter: Remove image_gen conflicts and rewrite selectors
  OpenAIResponsesAdapter->>OpenAIResponsesGateway: Send normalized image_generation request
Loading

Possibly related PRs

  • lidge-jun/opencodex#492: Earlier Responses handling for image_gen and hosted image_generation collisions, including nested declarations.
  • lidge-jun/opencodex#588: Related Responses tool aliasing and tool_choice normalization behavior.

Suggested reviewers: lidge-jun, ingwannu

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 54.55% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: preserving hosted image tool preferences for exact models.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@github-actions github-actions Bot added the bug Something isn't working label Jul 28, 2026
@Eleven-is-cool
Eleven-is-cool force-pushed the fix/model-hosted-tools-preference branch from ab30dca to 1783957 Compare July 28, 2026 12:23
@Wibias

Wibias commented Jul 28, 2026

Copy link
Copy Markdown
Collaborator

Please change the PR to ready for review once you are finished @Eleven-is-cool

@Eleven-is-cool
Eleven-is-cool force-pushed the fix/model-hosted-tools-preference branch from 1783957 to e8ed8bf Compare July 29, 2026 02:14
@Eleven-is-cool
Eleven-is-cool marked this pull request as ready for review July 29, 2026 02:15

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

Copy link
Copy Markdown

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: e8ed8bf62d

ℹ️ 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 src/config.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/adapters/openai-responses.ts`:
- Around line 524-609: The tool-group traversal in preferConfiguredHostedTools
and normalizeImageGenClientTools is duplicated across top-level body.tools and
nested additional_tools entries. Extract a shared mapResponsesToolGroups helper
that applies a supplied mapper to both tool-group locations while preserving
unchanged references and rebuilding the body only when needed, then use it for
the strip and normalize flows without changing their distinct semantics.

In `@src/config.ts`:
- Around line 499-549: Update the forward-auth rejection in
modelPreferHostedToolsConfigError to check the actual provider.authMode
regardless of whether getProviderRegistryEntry(providerName) returns a registry
entry, while preserving the registry authKind fallback for providers without an
explicit forward mode. Ensure any non-empty configuration is rejected whenever
the effective provider mode is forward, matching
createResponsesPassthroughAdapter.buildRequest.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 095da904-3c44-44c0-9b26-f51e26545d3f

📥 Commits

Reviewing files that changed from the base of the PR and between ca7b104 and e8ed8bf.

📒 Files selected for processing (16)
  • docs-site/src/content/docs/ja/reference/configuration.md
  • docs-site/src/content/docs/ko/reference/configuration.md
  • docs-site/src/content/docs/reference/configuration.md
  • docs-site/src/content/docs/ru/reference/configuration.md
  • docs-site/src/content/docs/zh-cn/reference/configuration.md
  • src/adapters/openai-responses.ts
  • src/config.ts
  • src/providers/openai-virtual-models.ts
  • src/responses/hosted-tool-policy.ts
  • src/server/auth-cors.ts
  • src/types.ts
  • structure/04_transports-and-sidecars.md
  • tests/config.test.ts
  • tests/management-provider-validation.test.ts
  • tests/openai-api-virtual-models.test.ts
  • tests/openai-responses-passthrough.test.ts

Comment thread src/adapters/openai-responses.ts
Comment thread src/config.ts
@Eleven-is-cool
Eleven-is-cool force-pushed the fix/model-hosted-tools-preference branch from e8ed8bf to 012ab25 Compare July 29, 2026 06:13

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs-site/src/content/docs/reference/configuration.md`:
- Line 301: Clarify modelPreferHostedTools matching using the routing-resolved
model identity: explain that OpenAI virtual models retain their public selector
while Responses eligibility and exact preference matching resolve through the
underlying wire model, and that modelAdapters overrides are not matched against
the public selector. Apply equivalent clarification in
docs-site/src/content/docs/reference/configuration.md:301-301,
docs-site/src/content/docs/ja/reference/configuration.md:175-175,
docs-site/src/content/docs/ko/reference/configuration.md:184-184,
docs-site/src/content/docs/ru/reference/configuration.md:207-207, and
docs-site/src/content/docs/zh-cn/reference/configuration.md:175-175, translated
appropriately; align structure/04_transports-and-sidecars.md:75-80 with the same
resolved-model and wire behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: a47120b1-3ee6-45c0-bb9d-439369508cac

📥 Commits

Reviewing files that changed from the base of the PR and between e8ed8bf and 012ab25.

📒 Files selected for processing (16)
  • docs-site/src/content/docs/ja/reference/configuration.md
  • docs-site/src/content/docs/ko/reference/configuration.md
  • docs-site/src/content/docs/reference/configuration.md
  • docs-site/src/content/docs/ru/reference/configuration.md
  • docs-site/src/content/docs/zh-cn/reference/configuration.md
  • src/adapters/openai-responses.ts
  • src/config.ts
  • src/providers/openai-virtual-models.ts
  • src/responses/hosted-tool-policy.ts
  • src/server/auth-cors.ts
  • src/types.ts
  • structure/04_transports-and-sidecars.md
  • tests/config.test.ts
  • tests/management-provider-validation.test.ts
  • tests/openai-api-virtual-models.test.ts
  • tests/openai-responses-passthrough.test.ts

Comment thread docs-site/src/content/docs/reference/configuration.md Outdated
@Eleven-is-cool
Eleven-is-cool force-pushed the fix/model-hosted-tools-preference branch from 012ab25 to 53618c6 Compare July 29, 2026 07:00

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/adapters/openai-responses.ts`:
- Around line 558-609: Update preferConfiguredHostedTools so a tool_choice
rewritten to the hosted image-generation tool remains consistent with the
resulting tools and nested input.additional_tools: when client declarations are
stripped, either retain/re-add the hosted tool declaration or avoid rewriting
tool_choice unless a hosted entry remains. Add a regression test covering a
request containing only the client wrapper declaration.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 14d6f631-18ba-4a5d-be18-edc9eb35eba7

📥 Commits

Reviewing files that changed from the base of the PR and between 012ab25 and 53618c6.

📒 Files selected for processing (16)
  • docs-site/src/content/docs/ja/reference/configuration.md
  • docs-site/src/content/docs/ko/reference/configuration.md
  • docs-site/src/content/docs/reference/configuration.md
  • docs-site/src/content/docs/ru/reference/configuration.md
  • docs-site/src/content/docs/zh-cn/reference/configuration.md
  • src/adapters/openai-responses.ts
  • src/config.ts
  • src/providers/openai-virtual-models.ts
  • src/responses/hosted-tool-policy.ts
  • src/server/auth-cors.ts
  • src/types.ts
  • structure/04_transports-and-sidecars.md
  • tests/config.test.ts
  • tests/management-provider-validation.test.ts
  • tests/openai-api-virtual-models.test.ts
  • tests/openai-responses-passthrough.test.ts

Comment thread src/adapters/openai-responses.ts
@Eleven-is-cool
Eleven-is-cool force-pushed the fix/model-hosted-tools-preference branch from 53618c6 to 2831925 Compare July 29, 2026 07:19

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/adapters/openai-responses.ts`:
- Around line 574-621: Update the restoration logic around
preferConfiguredHostedTools to track every stripped declaration location, not
only the first nested additional_tools index. When toolChoiceChanged and no
hosted declaration remains, restore the hosted image-generation tool
independently in top-level tools and in every additional_tools entry that was
stripped; remove the if/else-if exclusivity while preserving unchanged requests
and existing tool ordering.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 390447f9-9773-4abc-b33e-e79c33acfbd0

📥 Commits

Reviewing files that changed from the base of the PR and between 53618c6 and 2831925.

📒 Files selected for processing (16)
  • docs-site/src/content/docs/ja/reference/configuration.md
  • docs-site/src/content/docs/ko/reference/configuration.md
  • docs-site/src/content/docs/reference/configuration.md
  • docs-site/src/content/docs/ru/reference/configuration.md
  • docs-site/src/content/docs/zh-cn/reference/configuration.md
  • src/adapters/openai-responses.ts
  • src/config.ts
  • src/providers/openai-virtual-models.ts
  • src/responses/hosted-tool-policy.ts
  • src/server/auth-cors.ts
  • src/types.ts
  • structure/04_transports-and-sidecars.md
  • tests/config.test.ts
  • tests/management-provider-validation.test.ts
  • tests/openai-api-virtual-models.test.ts
  • tests/openai-responses-passthrough.test.ts

Comment thread src/adapters/openai-responses.ts

@Wibias Wibias left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Verdict: Request changes

Useful opt-in fix for Responses-compatible gateways that reserve the hosted image namespace server-side. Not a duplicate of #492 / #588 / #90 — those handle conflict strip / namespace round-trip / hosted strip; this adds keyed modelPreferHostedTools so selected models can prefer hosted image_generation without widening tool choice for everyone. Worth landing after the gap below.


What it does

  • New provider config modelPreferHostedTools (exact model → ["image_generation"]).
  • On keyed Responses (non-forward): strip colliding client image_gen wrappers and rewrite affected tool_choice to hosted image_generation.
  • Validation rejects forward auth and non-Responses wires; virtual -pro IDs documented/tested.
  • Docs + structure notes updated.

Bugbot

Severity Location Finding
Medium src/adapters/openai-responses.ts ~610–620 (preferConfiguredHostedTools) Hosted restore is gated on toolChoiceChanged. If the request has client-only image_gen tools and a non-forcing tool_choice (auto / none / unset / unchanged string), the preference still strips the client surface but does not re-inject { type: "image_generation" }, so the wire can end with no image tool. Existing regressions only cover forced wrapper selectors (function / custom / allowed_tools) where tool_choice is rewritten.

Suggested fix: restore a hosted declaration whenever client image_gen was stripped and no hosted declaration remains in the request-wide tool set — not only when tool_choice was rewritten. Add a regression with tool_choice: "auto" (and optionally omitted) + client-only image_gen namespace under modelPreferHostedTools.


Security review

No medium+ security issues. Forward gating holds at validation and runtime; tool_choice rewrite stays scoped to operator opt-in + existing image-gen intent; model keys are lookup-only (no injection sink).


Codex / CodeRabbit open fixes

All prior threads are resolved; author responses look substantiated:

  • Codex P2 “validate configured adapter” — routing replaces registry-known adapter before wire check; accepted.
  • Rabbit forward-auth / registry authKind — verified at route boundary; accepted.
  • Rabbit shared mapper — withdrawn (different semantics).
  • Rabbit virtual-model docs — wording fixed across locales.
  • Rabbit restore hosted in same group — fixed in 28319250 for forced selectors.
  • Rabbit multi-location restore — withdrawn after Responses Lite “one request-wide tool set” clarification.

None of those need reopen. The Bugbot auto/non-forcing strip gap above is new and not covered by the resolved threads.


CI / process notes

  • Cross-platform CI was stuck on fork action_required; workflow runs were approved and are in progress — wait for green before merge.
  • maintainerCanModify is false on this fork PR, so maintainers cannot push the fix into the branch. Please enable “Allow edits from maintainers” or land the Bugbot fix yourself on this PR (no follow-up PR needed).
  • Branch is ~11 commits behind dev but currently mergeable; rebase only if conflicts appear.

Must-fix before merge

  1. Fix hosted restore when stripping client image_gen without a tool_choice rewrite (+ regression for tool_choice: "auto").
  2. Green Cross-platform CI on the tip.

No other must-fix from this review.

@Eleven-is-cool
Eleven-is-cool force-pushed the fix/model-hosted-tools-preference branch from 2831925 to 1aba0e4 Compare July 29, 2026 09:14
@Eleven-is-cool

Copy link
Copy Markdown
Author

Fixed the non-forcing selector gap in 1aba0e4.

Root cause: hosted restoration was incorrectly gated on toolChoiceChanged, so auto, none, and an omitted selector stripped the client wrapper without restoring { type: "image_generation" }.

Restoration now runs whenever a client wrapper was stripped and no hosted declaration remains, independent of selector rewriting. Added regressions for top-level auto / none / omitted selectors and Responses Lite additional_tools with auto.

Validated with bun test tests/openai-responses-passthrough.test.ts (51 passing), bun run typecheck, and bun run privacy:scan.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants