Skip to content

Preserve image inputs across configured model routes - #1577

Open
lihongguang-0014 wants to merge 8 commits into
mainfrom
feature/image-input-projection
Open

Preserve image inputs across configured model routes#1577
lihongguang-0014 wants to merge 8 commits into
mainfrom
feature/image-input-projection

Conversation

@lihongguang-0014

@lihongguang-0014 lihongguang-0014 commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator

Scope

Scope boundary: Preserve canonical image attachments while projecting each physical request according to the configured deployment's image capability.

  • Direct uses native image input when supported or unknown, then retries the same configured model with explicit image-not-analyzed markers only for recognized image-input rejection before visible output or tool effects.
  • Router considers only the configured c0-c3 deployments. It degrades to text markers after image-capable candidates are exhausted; the legacy image_model setting is retained but cannot add a hidden route.
  • Ensemble consistently uses a text-only virtual-model projection for every physical member.
  • Durable attachment manifests and canonical archive recovery preserve image identities across model switches, compaction, and forks. Explicit image references are protected from ordinary history trimming.
  • Replay and manifest writes honor admitted session identity and epoch. Missing media is marked unavailable without claiming that the original is retained.
  • WebUI and Desktop remove manual image-capability switches and stop writing tier capability flags. Router uses deployment-level API/catalog evidence, while legacy tier flags remain readable but cannot override that evidence. Upload controls remain available.
  • Editable routing settings and read-only preset previews omit the retired image-model row on both web and desktop. Existing saved configuration is preserved without adding an Ensemble member or changing provider participation.
  • Missing or malformed OpenRouter input modalities remain unknown rather than becoming a synthesized negative capability. Input and output modalities are not conflated.
  • Route snapshots and candidate chips exclude the implicit legacy image route while preserving actual historical winners.
  • Reattached native images receive request-local replay context so earlier text-only responses do not obscure their current availability; canonical messages remain unchanged.

Non-goals: New providers, unconfigured model fallback, OCR services, image generation, and changes to unrelated routing strategies.

Branch

Base branch: main

Target exception: N/A

Issue

Linked issue: None

If None, reason: User-requested multimodal routing and multi-turn attachment handling feature.

Release Note

Release note: Images now remain available across model switches and context compaction. Configured text-only routes continue with explicit markers instead of failing the whole turn or selecting an unconfigured vision model.

Tests

Ruff: uv run ruff check src tests passed.

Pytest: 3,274 passed, 5 skipped across provider, routing, image history, turn-runner, session/compaction, onboarding, gateway, and attachment functional regression suites. Follow-up runs passed: 121 routing tests, 94 session-wire/gateway-history tests, 119 history/ownership/attachment tests, 28 historical replay tests, and 146 live-profile harness/CI-governance tests (1 skipped). These batches overlap and are not an aggregate unique-test count.

Automatic-capability follow-up: 1,608 backend tests passed (4 skipped) across image guards/history, ownership, turn-runner, onboarding, and desktop integration contracts; 485 routing/capability/gateway/functional tests passed; 337 catalog/mutation tests passed; 287 catalog-refresh/compatibility tests passed (1 skipped); all 100 offline gateway-harness tests passed. These batches overlap.

Build: All 5,512 WebUI unit tests passed across 432 files with two workers. WebUI typecheck, architecture/security/i18n guards, and production build passed. Mypy passed for the affected core modules, including all five modules changed by automatic-capability follow-up. Desktop TypeScript build and router-tier normalization passed.

Regression tests: added

Settings-row follow-up: All 700 setup component/composable tests passed across 19 files. Full WebUI typecheck and production build passed; the rebuilt browser settings table was verified to display only C0-C3, with no image-model row. This follow-up changes presentation only and does not remove stored configuration or change auxiliary media-tool routing.

Notes: Independent subagent reviews covered routing, history recovery, and integration with current main. Session reset/epoch regressions include real SQLite races and a red/green check of the retired-owner pipeline boundary.

CI follow-up: Registered the four new test modules in the existing shard inventory without relaxing budgets. Updated the offline gateway harness to configure its vision route explicitly, reference intended historical attachments, and retain current main's incomplete-stream transport classification.

The default test path remains offline, deterministic, credential-free, and safe for forks.

Maintainer Live Check

Maintainer live check: yes

Surface: provider | browser | gateway

Maintainer-only note: Completed isolated browser/gateway smoke tests using already-configured deployments and a public repository image. The original user configuration was not changed. Contributors are not expected to provide secrets or run credentialed live checks.

  • Direct with a text-only model preserved the uploaded image, returned an explicit not-analyzed marker, and answered the text portion.
  • Switching to a configured vision model recovered the historical image without reuploading and produced a matching description.
  • Router with all four configured tiers text-only degraded to markers; after enabling the configured vision tier, it selected that tier and analyzed the image.
  • Ensemble projected image inputs to markers and completed the text task.
  • Switching back from vision to text-only sent zero native image blocks and clearly distinguished prior context from a new image analysis.
  • Historical images remained recoverable after gateway restart. Safe final-payload counters confirmed four reattached native image blocks in the historical vision request; accounting confirmed no call to the implicit legacy image model.

The smoke tests exposed and verified the candidate-display and replay-context fixes above. The rebuilt routing settings page was subsequently verified to have no image column or switch and to explain automatic capability resolution. A final live Router check retained a legacy false image flag on the configured vision tier: Router still selected that deployment from catalog evidence, sent three native historical image blocks, and returned a matching visual description without reuploading. Compaction, forks, unknown-capability rejection, and ownership races were validated by deterministic tests rather than manually forced live checks.

Safety

No secrets, local-only artifacts, private prompts/transcripts, channel identifiers, AI session artifacts, non-public fixtures, or tests/_private/ contents are included. The isolated live-test profile is outside the repository.

Compatibility: Legacy tier capability flags and the image-model row remain accepted; retired flags no longer change runtime capability or semantic preset ownership. Low-level model-catalog overrides retain their existing contract. No database migration is required. The policy change is platform-neutral; both web and desktop share the updated settings table and desktop serialization is covered independently.

Third-Party Origin

Third-party origin: none

Documentation Changes

  • Links point to existing repository files or stable external pages.
  • Code fences and Markdown tables render correctly on GitHub.
  • Examples avoid real secrets, local private paths, and private transcripts.

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.

1 participant