feat(api): append mode for recalled reference images (+ fix recall socket double-emit)#9288
Open
lstein wants to merge 3 commits into
Open
feat(api): append mode for recalled reference images (+ fix recall socket double-emit)#9288lstein wants to merge 3 commits into
lstein wants to merge 3 commits into
Conversation
POST /api/v1/recall/{queue_id}?append=true now asks the frontend to add
the recalled reference images (ip_adapters and model-free
reference_images) to its existing list instead of replacing it. The flag
rides inside the event's parameters dict so the generated client schema
needs no regeneration, and is injected after the persistence loop so it
is never stored as a recall parameter. Mutually exclusive with strict.
The frontend dispatches refImagesRecalled with replace:false in append
mode, and skips the dispatch entirely when nothing resolved so a failed
append can never clear the user's current reference images.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
RecallParametersUpdatedEvent was emitted in two separate socket.io calls — one to the owner's user room, one to the admin room. A socket that belongs to both (the "system" user in single-user mode is also an admin, so it joins user:system AND admin) received the event twice. That double delivery was invisible for the scalar/replace recall fields, which are idempotent, but the append-mode reference-image recall pushes rather than replaces — so each append showed up as two copies of the same reference image in the InvokeAI canvas. Emit once to the room union [user_room, "admin"] instead. python-socketio deduplicates recipients across a room list, so a socket in both rooms is delivered to exactly once, while genuinely distinct owner/admin sockets still each receive it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rebuilds the committed OpenAPI schema and generated TypeScript types so the update_recall_parameters operation advertises the new append query parameter. Generated via 'make frontend-openapi' / 'frontend-typegen' equivalent; the only change is the added append param + its docstring. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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
Adds an append mode to the recall API for reference images, and fixes a latent double-delivery in the recall socket event that the new mode exposed.
feat(api): append mode for recalled reference images.POST /api/v1/recall/{queue_id}previously always replaced the frontend's reference-image list — therecall_parameters_updatedhandler dispatchedrefImagesRecalledwith a hard-codedreplace: true. This adds anappendquery parameter; whenappend=true, the recalledip_adapters/reference_imagesare added to the existing list (replace: false) instead of replacing it. The flag rides inside the event'sparametersdict so the generated client schema needs no regeneration, and it's injected after the persistence loop so it is never stored as a recall parameter.strictandappendare mutually exclusive (400). The frontend skips the dispatch entirely when nothing resolved, so a failed append can never clear the user's current reference images.fix(sockets): emit the recall event once to the owner+admin room union.RecallParametersUpdatedEventwas emitted in two separatesocket.iocalls — one touser:{user_id}, one toadmin. A socket belonging to both rooms (thesystemuser in single-user mode is also an admin, so it joins both) received the event twice. That was invisible for the idempotent scalar/replace recall fields, but the new append mode pushes rather than replaces, so each append showed up as two copies of the same reference image. Fixed by emitting once to the room union[user_room, "admin"]— python-socketio deduplicates recipients across a room list, so a socket in both rooms is delivered to exactly once while genuinely distinct owner/admin sockets each still receive it. Scoped to the recall event only; the other private events are idempotent UI updates where a double delivery is harmless.QA Instructions
POST /api/v1/recall/default?append=truewith{"reference_images": [{"image_name": "<an output image>"}]}.?append=false(or omitted) → the list is replaced, as before.?strict=true&append=true→ 400.Automated:
tests/app/routers/test_recall_parameters.py(append flag plumbing, strict/append mutual exclusion, not-persisted) andtests/app/routers/test_multiuser_authorization.py::TestWebSocketAuth::test_recall_parameters_emitted_once_to_owner_and_admin_rooms(single emit to the room union). Full recall + multiuser-auth suites pass (153 tests).Merge Plan
Standard merge. The frontend change is a single dispatch in
setEventListeners.tsx(no redux-slice schema change, no migration). Recommend a frontend rebuild on deploy so the append branch takes effect in the served UI.Checklist
refImagesRecalledwithreplace: false)What's Newcopy (if doing a release after this PR)🤖 Generated with Claude Code