Skip to content

fix: enforce configurable per-model image input limits - #3562

Merged
wsp1911 merged 2 commits into
GCWing:mainfrom
uiharuayako:codex/investigate-image-request-limits
Oct 27, 2026
Merged

wsp1911 merged 2 commits into
GCWing:mainfrom
uiharuayako:codex/investigate-image-request-limits

Conversation

@uiharuayako

Copy link
Copy Markdown
Contributor

Summary

A vision model that accepts at most three images can reject a request after four view_image results, then reject ordinary "Continue" messages because those pixels remain in history. Add an optional per-model max_images_per_request setting and enforce it on the complete outgoing request.

  • Leaving the setting empty preserves the existing image-history policy and legacy configuration fingerprints.
  • Reject oversized new user attachment batches before committing them to the conversation; keep the composer draft. Pools and channel routes use the smallest explicit limit among their enabled vision destinations for admission, respecting manual channel selection.
  • Apply one combined user/tool image budget at the actual selected AIClient send boundary, including fallback clients, compaction, suggestions and single-attempt Responses calls. Retain newer pixels first, explain omissions and allow files to be read again in smaller batches; preserve original history and tool-result identities.
  • Reject custom request-body message overrides when an image limit is configured, so they cannot bypass the budget.

Type and Areas

Bug fix. Configuration contracts, AI adapters, shared native runtime, Web UI model settings and attachment intake. Additional Rust changes mostly initialize the new optional field or preserve it through legacy model edits.

Motivation / Impact

With a configured limit of 3, a restored conversation containing four tool images sends only three images on plain continuation. Explicit user submissions above the selected route's limit are rejected before changing conversation state. Limits are model-specific; no provider-wide three-image restriction or agent-loop counter is introduced.

Verification

  • Configuration contracts: cargo test --offline --locked -p openbitfun-config-contracts --lib — 139 passed, including legacy JSON, runtime conversion, fingerprint stability, zero validation and custom-body compatibility.
  • Adapter budget: cargo test --offline --locked -p openbitfun-ai-adapters --lib client::image_budget::tests — 13 passed, including mixed user/tool inputs, parallel and multi-image results, four provider wire formats, all send entry points and actual loopback HTTP requests with limits changing from 5 to 3.
  • Shared runtime: the following focused command — 11 passed, including user admission, pools/manual/fallback routes, no context pollution, unchanged default elision, deterministic rejections and restored-context continuation:
    cargo test --offline --locked -p openbitfun-core --no-default-features --features agent-runtime,git --lib -- configured_image_limit input_image_count registry_reports_image_budget_validation_path image_inputs_keep_pixels_for_native_models_and_tool_paths_for_text_models image_elision_advances_in_batches_and_never_reverts new_images_keep_earlier_sent_messages_unchanged_between_elision_batches provider_rejections_stop_after_one_request_for_http_and_stream_errors
  • App Server edit compatibility: cargo test --offline --locked -p openbitfun-app-server --lib model_mutation_preserves_and_replaces_write_only_values — passed.
  • CLI edit compatibility: cargo test --offline --locked -p openbitfun-cli --bin openbitfun model_selection::tests — passed.
  • Web UI — 126 tests in nine files passed:
    pnpm --dir src/web-ui exec vitest run src/flow_chat/constants/chatInputConfig.test.ts src/flow_chat/components/ChatInputImageIntake.test.ts src/infrastructure/config/components/modelEditorRequestSettings.test.ts src/flow_chat/utils/externalFileIntake.test.ts src/infrastructure/config/components/ModelSettingsDialog.presentation.test.ts src/app/scenes/settings/pages/ai/ModelSettingsPage.presentation.test.ts src/flow_chat/components/ModelSelectorProviderLevels.test.tsx src/app/scenes/settings/pages/ai/ModelSettingsPage.loading.test.tsx src/flow_chat/utils/modelImageBudget.test.ts
  • pnpm run check:web, final pnpm --dir src/web-ui exec tsc --noEmit, pnpm run i18n:audit, node scripts/format-changed-rust.mjs --check and git diff --cached --check — passed.

Reviewer Notes

AI-assisted. Testing level: focused automated validation with synthetic credentials, temporary session state and loopback HTTP fixtures; model-setting entry/save/reset is covered by DOM tests. Native GUI appearance, live self-hosted providers, SSH workspaces, Remote Connect, Peer Device Mode and Detached Dispatch transports were not exercised. The limit is enforced by the upgraded executing host; older hosts ignore the optional setting and must be upgraded. It does not infer unknown provider limits from an error response.

Checklist

  • Focused change with no secrets, build artifacts, temporary prompts or unrelated work.
  • Relevant validation and acceptance limits are recorded above.
  • User-facing strings, three locales and the owning Desktop README are updated.

@uiharuayako

Copy link
Copy Markdown
Contributor Author

@wgqqqqq 您好,这个问题对于使用外部api来说很少见,但是对于使用自部署的模型来说相当致命,希望能review一下这个pr,限制给多模态模型的传入图片张数

@GCWing
GCWing requested review from wsp1911 and removed request for wsp1911 October 27, 2026 07:15
@wsp1911
wsp1911 merged commit 5713b24 into GCWing:main Oct 27, 2026
13 checks passed
Sign up for free to 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.

2 participants