Skip to content

fix(images): fall through combo edit targets on /v1/images/edits - #12653

Merged
diegosouzapw merged 2 commits into
cheaper-inference:release/v3.8.51from
pacocartones:fix/12547-image-combo-edits-fallback
Sep 11, 2026
Merged

diegosouzapw merged 2 commits into
cheaper-inference:release/v3.8.51from
pacocartones:fix/12547-image-combo-edits-fallback

Conversation

@pacocartones

Copy link
Copy Markdown
Contributor

Summary

  • A combo used on /v1/images/edits only tried its first target with a modelStr (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 via executeImageCombo, skipping missing-creds/rate-limited ones and only stopping on a terminal 400/401/403).
  • Fix (your two-step plan): extracted executeImageCombo's per-target iteration/skip/terminal-classification into a generic runImageComboTargets(...); /generations calls it with the generation dispatch, behaviour byte-identical. Wired it into /v1/images/edits with 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

  • Change type: routing (images)
  • Focused tests and category gates from the golden path
  • npm run lint
  • Reconciled with the current active release base; focused checks rerun afterward
  • Production-code changes include a new or updated automated test in this PR

Tests 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 /generations behaviour is asserted unchanged.

Coverage Notes

  • open-sse/services/imageCombo.ts (extracted runImageComboTargets; the /generations dispatch and response tail are unchanged) and src/app/api/v1/images/edits/route.ts (edit-capable filter + per-provider edit dispatch + a bare-combo diversion inserted before resolveImageRouteModel, mirroring generations). 28 neighbouring image/combo tests stay green; typecheck:core clean; complexity ratchets under baseline. Deliberate low-risk choice: the edit-combo path has its own dispatchImageEditTarget reusing the same provider handlers rather than refactoring the single-model postHandler branches, to avoid changing single-model /edits error bodies; a combo target returning a terminal 400 stops iteration, matching the existing generation terminal-400 semantics.

/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
diegosouzapw merged commit a0c52ba into cheaper-inference:release/v3.8.51 Sep 11, 2026
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>
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.
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.

fix(images): /v1/images/edits flattens a combo to its first target and never falls back

2 participants