Repository navigation
fix(images): fall through combo edit targets on /v1/images/edits - #12653
Merged
diegosouzapw merged 2 commits intoSep 11, 2026
Conversation
/v1/images/edits resolved a bare combo/alias name to only its first target via resolveSingleImageComboTarget() and dispatched that one, so a combo whose first target is not edit-capable (or lacks credentials) hard-errored even when a later target could service the edit — while the same combo works on /v1/images/generations, which iterates every target (cheaper-inference#9239). Extract executeImageCombo's per-target skip/terminal classification into a shared runImageComboTargets loop and wire it into /v1/images/edits behind an edit-capable filter and per-provider edit dispatch. Bare combos now divert to the shared loop before resolveImageRouteModel (mirroring generations), missing credentials are skipped rather than returned as a hard 401, and generations behavior is unchanged (dispatch stays handleImageGeneration). Closes cheaper-inference#12547
diegosouzapw
merged commit Sep 11, 2026
a0c52ba
into
cheaper-inference:release/v3.8.51
13 of 16 checks passed
diegosouzapw
added a commit
that referenced
this pull request
Sep 11, 2026
…ough added #12653 made /v1/images/edits fall through to the next combo target, and each per-target attempt resolves credentials of its own — one more classified site in that route (5 -> 6). Drift from the base tip, not from this branch. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
7 tasks done
Githab-capibara
added a commit
to Githab-capibara/OmniRoute
that referenced
this pull request
Sep 17, 2026
…aper-inference#12653) The asymmetry was the bug: `/generations` iterated every image-capable target while `/edits` only ever tried the first. Extracting the iteration into `runImageComboTargets` and proving `/generations` byte-identical before wiring `/edits` onto it is the right order. Missing credentials skipping rather than hard-401 now matches generations too. --- Validated in one consolidated worktree cut from `release/v3.8.51`, boarded with the rest of this batch — zero conflicts between the 19 PRs. - `typecheck:core` clean; `check:dashboard-typecheck` OK (206 pre-existing, all within the frozen baseline); `check:changelog-integrity` OK - complexity 2802 / baseline 3218 and cognitive-complexity 1267 / baseline 1437 — both under baseline - 226 of 228 focused assertions green across the batch's 23 test files. The 2 remaining belong to cheaper-inference#12551, which is held separately. Two batch-owned defects were found and fixed in flight, both pure base drift: `173_xp_action_counts.sql` collided with `173_call_logs_video_content_removed.sql` (renumbered to 176 on cheaper-inference#12651 — it aborted every DB open, which is what 53 of the first run's failures were), and the feature-flag catalog was missing the `SERVER_OWNED_TOOL_LOOP_ENABLED` row the base gained after cheaper-inference#12552 was written.⚠️ base-red inherited: cheaper-inference#12732 — `Docs Gates`, `Merge integrity`, `No new ESLint warnings`, `Unit Tests fast-path` and `Fast Quality Gates` reproduce on the pure tip (provider count 356 vs the 358 the modules define, SKILL.md drift, and `open-sse/utils/stream.ts` at 3115 > frozen 3098, which this batch does not touch). Thanks @pacocartones — the `file:line` citations and the explicit out-of-scope notes on every one of these made a 19-PR batch reviewable in one pass.
muhamadgalihsaputra
pushed a commit
to niyatna/NiyatnaRoute
that referenced
this pull request
Sep 27, 2026
…aper-inference#12653) The asymmetry was the bug: `/generations` iterated every image-capable target while `/edits` only ever tried the first. Extracting the iteration into `runImageComboTargets` and proving `/generations` byte-identical before wiring `/edits` onto it is the right order. Missing credentials skipping rather than hard-401 now matches generations too. --- Validated in one consolidated worktree cut from `release/v3.8.51`, boarded with the rest of this batch — zero conflicts between the 19 PRs. - `typecheck:core` clean; `check:dashboard-typecheck` OK (206 pre-existing, all within the frozen baseline); `check:changelog-integrity` OK - complexity 2802 / baseline 3218 and cognitive-complexity 1267 / baseline 1437 — both under baseline - 226 of 228 focused assertions green across the batch's 23 test files. The 2 remaining belong to cheaper-inference#12551, which is held separately. Two batch-owned defects were found and fixed in flight, both pure base drift: `173_xp_action_counts.sql` collided with `173_call_logs_video_content_removed.sql` (renumbered to 176 on cheaper-inference#12651 — it aborted every DB open, which is what 53 of the first run's failures were), and the feature-flag catalog was missing the `SERVER_OWNED_TOOL_LOOP_ENABLED` row the base gained after cheaper-inference#12552 was written.⚠️ base-red inherited: cheaper-inference#12732 — `Docs Gates`, `Merge integrity`, `No new ESLint warnings`, `Unit Tests fast-path` and `Fast Quality Gates` reproduce on the pure tip (provider count 356 vs the 358 the modules define, SKILL.md drift, and `open-sse/utils/stream.ts` at 3115 > frozen 3098, which this batch does not touch). Thanks @pacocartones — the `file:line` citations and the explicit out-of-scope notes on every one of these made a 19-PR batch reviewable in one pass.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
/v1/images/editsonly tried its first target with amodelStr(resolveSingleImageComboTarget) — no fallback — so a combo whose first target isn't edit-capable, or lacks credentials, was flattened to a hard error, while the same combo works on/v1/images/generations(which iterates every image-capable target viaexecuteImageCombo, skipping missing-creds/rate-limited ones and only stopping on a terminal 400/401/403).executeImageCombo's per-target iteration/skip/terminal-classification into a genericrunImageComboTargets(...);/generationscalls it with the generation dispatch, behaviour byte-identical. Wired it into/v1/images/editswith an edit-capable filter and an edit dispatch, so it falls through to a later target; missing credentials now skip (not a hard 401), matching generations.Related Issues
Validation
npm run lintTests Added Or Updated
tests/unit/image-combo-edits-fallback-12547.test.ts— 5 tests: a non-edit-capable first target and a missing-credentials first target both fall through to a later edit-capable target on/edits(RED on base: hard 400/401; GREEN with the fix: 200), and/generationsbehaviour is asserted unchanged.Coverage Notes
open-sse/services/imageCombo.ts(extractedrunImageComboTargets; the/generationsdispatch and response tail are unchanged) andsrc/app/api/v1/images/edits/route.ts(edit-capable filter + per-provider edit dispatch + a bare-combo diversion inserted beforeresolveImageRouteModel, mirroring generations). 28 neighbouring image/combo tests stay green;typecheck:coreclean; complexity ratchets under baseline. Deliberate low-risk choice: the edit-combo path has its owndispatchImageEditTargetreusing the same provider handlers rather than refactoring the single-modelpostHandlerbranches, to avoid changing single-model/editserror bodies; a combo target returning a terminal 400 stops iteration, matching the existing generation terminal-400 semantics.