Skip to content

feat(studio): share durable image commands with Wizard and MCP - #275

Merged
IAnMove merged 17 commits into
developmentfrom
feat/shared-generation-commands
Sep 9, 2026
Merged

feat(studio): share durable image commands with Wizard and MCP#275
IAnMove merged 17 commits into
developmentfrom
feat/shared-generation-commands

Conversation

@IAnMove

@IAnMove IAnMove commented Sep 9, 2026

Copy link
Copy Markdown
Owner

Studio and Wizard image submissions now share the durable command boundary used by MCP. Before submitting, the browser persists and visibly presents the exact image request; a lost response can be recovered with the same intention and returns the original native task instead of creating another job.

The V2 contract includes assembled Studio image parameters, canonical references with explicit source locations, LoRAs, processors and collection/workflow attribution. V1 clients remain compatible. Task creation and the receipt commit in the existing TaskRegistry; inference and recovery use the native queue. The image panel and command client load on demand. The Wizard preserves literal prompts, treats an unspecified CFG as unspecified, and keeps pending presentation requests through React Suspense; a removed panel cancels before admission.

Validation: required CI passed on cc0d7602, with Python, UI and browser E2E; independent Luna reviewed that delta. Full image UI: 1,318 passing. Follow-up validation covers 26 Load Settings/builder tests, 36 recovery/admission tests, 55 final recovery/admission checks after #278, five architecture checks, and lint/type-check/build/bundle limits. Required CI also passed on b0fc2dd3; current 65ed2852 required CI and both Cursor checks also passed. independent Luna review approves the recovery refinement, including discard write failures. No quality baseline was raised. A disk I/O stall interrupted one local test run; the directed recovery tests then used temporary SQLite databases in tmpfs (not a power-loss durability test).

Real V2 validation passed on frontend cc0d7602 / byte-identical backend d08853a5: a real MiniMax Wizard turn presented the literal request and correlated intention before exactly one image command POST. Flux 2 Klein 9B produced one 512×512 JPEG (job 2d75dfa9) in 96.98 seconds, including 81.63 seconds loading the model. An external MCP SDK client replayed the exact completed intention, received the original receipt/task, found one canonical task and zero active tasks, and downloaded the same 14,751-byte file. Full decode and canonical SHA-256 match (ec119db6d4474e361457a0936e00235a44dc190e3a68c363d45467a53f2d4fe5). This one-step sample validates execution, not universal model or artistic quality.

Earlier unsuccessful Wizard attempts and two corrected MCP harness assertions remain in local evidence; they did not create replacement generations. Evidence: outputs/wizard-mcp-execution-20260909/image-live/v2-wizard-fixed-real/ and v2-wizard-mcp-replay-final/. Earlier V1 MCP generation/replay also passed.

Follow-up fixes: the changes proposed by #276, #277 and #278 are incorporated locally into this branch with refinements; no remote PR merge was performed. Load Settings/reroll projects only declared residual fields, rejects envelope injection/unknown keys and refuses active unsupported advanced image controls. A private browser Load Settings preflight preserved the real image's prompt/seed/size and emitted exactly one V2 command; an intercepted 422 prevented inference and was shown in the UI. The harness also counted 18 navigation-cancelled GETs as failures. Independent review classifies the bounded functional result as PASS_WITH_AMBIENT_ABORTS; the original FAIL evidence is retained.

Queue recovery skips invalid backup-folder names and isolates malformed or orphaned rows while returning 503 for storage failures, preserving recovery records and canonical tasks. Actual list/discard HTTP handlers were exercised with SQLite and filesystem failures. The original #277 broad catch was refined after independent review found that it could hide storage errors.

Scope is the image vertical of P5. Speech has a checked local stack and passed real Wizard generation plus external MCP replay (separate from this image PR); other media, Tools, editorial domains and backend workflows remain in the plan. Resource hashes document inspected files without freezing their bytes throughout queue lifetime; model bytes and universal LoRA compatibility are not certified. The native deployment remains a single generation runtime, without a second scheduler or cross-process lease.


Note

Medium Risk
Changes core generation admission, TaskRegistry schema, and queue recovery semantics; mistakes could affect job deduplication or recovery, though the boundary is heavily tested and fails closed on corrupt admissions.

Overview
Introduces a shared, durable image admission path for Studio, Wizard, and MCP so the same intent_id yields one canonical task/receipt and safe retries instead of duplicate GPU jobs.

New command surface: GET/POST /api/v1/generation/commands, receipt lookup, and read-only reference canonicalization; MCP exposes generation.image / generation.receipt with the same catalog. V1 freezes a small text-to-image envelope; V2 accepts the full typed Studio image map (refs, LoRAs, processors) via studio_image_spec and preflight/resource layers before admission.

Runtime wiring: Submissions run through native generate validation, then an in-process admit_generation_command callback records admission in TaskRegistry, persists the durable queue projection, and dispatches once via an atomic dispatch claim. _new_generation_job gains publish_task=False for command-owned tasks; prepare_generation_inputs honors prepared_studio_images so Studio-resolved paths are not re-resolved in the output workspace.

TaskRegistry v3 adds task_command_admissions (original/effective snapshots, fingerprints, receipts) and safer SQLite bootstrap under a file lock. Queue recovery list/resume/discard now restores and filters image-command leftovers linked to admissions, skipping orphans and invalid workspace names without masking storage errors.

Reviewed by Cursor Bugbot for commit 65ed285. Configure here.

@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown

PR Review — Loreframe Studio

Risk: medium
Scope: 49 file(s); +12793/-62; React UI, backend services, docs, repo scripts / CI

Automated review from scripts/analyze_pr.py. This is a heuristic pass (no LLM) so humans still own the merge decision.

Findings

  • medium — Dangerous dynamic execution (tests/test_image_generation_commands.py)
    tests/test_image_generation_commands.py adds exec(). Confirm the input is trusted and sandboxed.
  • medium — Dangerous dynamic execution (tests/test_task_adapter_helpers.py)
    tests/test_task_adapter_helpers.py adds exec(). Confirm the input is trusted and sandboxed.
  • medium — Large pull request
    12793 additions / 62 deletions. Reviewers will have an easier time with smaller, focused PRs.
  • medium — Very large file change (app/services/studio_image_spec.py)
    app/services/studio_image_spec.py adds 826 lines. Consider splitting the PR.
  • medium — Very large file change (tests/test_image_generation_commands.py)
    tests/test_image_generation_commands.py adds 816 lines. Consider splitting the PR.
  • medium — Very large file change (tests/test_studio_image_spec.py)
    tests/test_studio_image_spec.py adds 490 lines. Consider splitting the PR.
  • medium — Very large file change (tests/test_task_command_admission.py)
    tests/test_task_command_admission.py adds 516 lines. Consider splitting the PR.
  • medium — Very large file change (ui/src/api/imageCommandCatalog.json)
    ui/src/api/imageCommandCatalog.json adds 3429 lines. Consider splitting the PR.
  • medium — Very large file change (ui/src/api/imageGenerationCommands.ts)
    ui/src/api/imageGenerationCommands.ts adds 906 lines. Consider splitting the PR.
  • medium — Very large file change (ui/src/features/studio/generationSpec.ts)
    ui/src/features/studio/generationSpec.ts adds 679 lines. Consider splitting the PR.
  • medium — Very large file change (ui/tests/studioImageCommandPresentation.test.tsx)
    ui/tests/studioImageCommandPresentation.test.tsx adds 411 lines. Consider splitting the PR.
  • medium — Very large file change (ui/tests/studioImageGenerationCommands.test.ts)
    ui/tests/studioImageGenerationCommands.test.ts adds 614 lines. Consider splitting the PR.
  • low — UI changed — rebuild before merge
    Run cd ui && npm run build (CI already does this). Pinokio Update rebuilds for end users; keep ui/dist untracked.

Changed files

  • added: app/routers/image_generation_commands.py, app/services/image_generation_commands.py, app/services/image_generation_runtime.py, app/services/image_generation_spec.py, app/services/studio_image_conditioning.py, app/services/studio_image_preparation.py, app/services/studio_image_resources.py, app/services/studio_image_spec.py, app/services/task_command_admission.py, docs/development/IMAGE_COMMANDS.md, scripts/export_image_command_catalog.py, tests/fixtures/studio_image_native_request.json, tests/test_image_command_restart_boundaries.py, tests/test_image_generation_commands.py, tests/test_image_generation_spec.py, tests/test_studio_image_asset_ids.py, tests/test_studio_image_commands.py, tests/test_studio_image_native_boundary.py, tests/test_studio_image_preparation.py, tests/test_studio_image_resources.py
    … and 14 more
  • modified: app/_launch_runtime.py, app/services/task_manager.py, app/services/wangp_submission.py, tests/fixtures/architecture_wire_inventory.json, tests/fixtures/route_table.json, tests/test_task_adapter_helpers.py, ui/src/components/Sidebar/GenerateButton.tsx, ui/src/components/Sidebar/Sidebar.tsx, ui/src/features/agent/applicationAdapters.ts, ui/src/features/agent/studioCapabilities.ts, ui/src/features/studio/actions.ts, ui/src/i18n/locales/en/studio.json, ui/src/i18n/locales/es/studio.json, ui/src/stores/useStore.ts, ui/tests/studioCapabilities.test.mjs

CONTRIBUTING checklist

  • python scripts/verify_clean_repo.py
  • python -m compileall -q app/services app/launch.py scripts
  • cd ui && npm run build if the UI changed
  • No weights, CivitAI sidecars, or generated guides
  • Stays local-first (no required accounts / telemetry)

Posted by the repo PR review workflow. Re-runs on each push to the PR.

@github-actions

github-actions Bot commented Sep 9, 2026

Copy link
Copy Markdown

Code health

Quality score: 57.1/100

Higher is better. The score is a trend dashboard; the independent ratchet below remains the CI gate.

Component Weight Current Change
Cyclomatic health 45% 55.4 +0.3
File concentration 25% 64.2 +1.2
Oversized-file debt 20% 40.1 +1.0
Modularity 10% 81.0 +0.4

Change vs PR base: +0.7 points.

Metric Value
Production LOC 274,260
Production files 800
Test LOC 104,137
Functions measured 18,156
Functions complexity ≥ 15 860
Maximum complexity 674
Policy code-health-policy-v1
HEAD fd10b3fa761befd69f7369e5b4e04d6a13d610b2
Base edf93aa6298b4e9cc2169f818a96beb5a2d7011a
UI measurement complete

Markdown, JSON catalogs and tests are out of this table. Only app/ runtime + ui/src TS/JS count.

Most complex functions

Complexity Where
674 app/wgp.py:7221 generate_video
379 ui/src/stores/useStore.ts:4086 Async method 'startGeneration'
355 app/_launch_runtime.py:23618 _run_generation
308 app/wgp.py:12363 generate_video_tab
268 ui/src/stores/useStore.ts:8638 Async method 'loadSettingsFromOutput'
262 ui/src/components/Sidebar/SceneAnimatorPanel.tsx:496 Function 'SceneAnimatorPanel'
258 app/services/director/planners/short_film.py:3433 ShortFilmPlanner._plan_story_driven
248 app/services/director_pipeline.py:13607 _run_video_generation
245 app/services/director_pipeline.py:7712 _run_pipeline
244 ui/src/features/agent/agentActions.ts:1150 Function 'parseAction'
226 app/services/director_pipeline.py:6541 update_comic_preview
225 ui/src/features/agent/agentActions.ts:2924 Async function 'executeAgentActions'

Trend vs baseline

Metric Δ
Production LOC +4,084
Test LOC +4,887
Functions ≥ 15 +3
Maximum complexity +0

Warnings

  • production LOC increased by +4,084
  • functions at complexity >= 15 increased by +3
  • complexity hotspot ui/src/components/Sidebar/Sidebar.tsx rose 95 -> 99
  • complexity hotspot app/services/wangp_submission.py rose 19 -> 24
  • hotspot app/_launch_runtime.py increased by +28 lines
  • hotspot ui/src/stores/useStore.ts increased by +2 lines
  • hotspot ui/src/features/agent/applicationAdapters.ts increased by +18 lines
  • hotspot app/services/task_manager.py increased by +19 lines

Ratchet passed.

cursoragent and others added 4 commits September 9, 2026 15:03
Load Settings and reroll copy H3/video/primary-settings keys into the
shared Studio params bag. The closed v2 builder treated those leftovers
as fatal, so Generate and reroll of an image failed after pencil.

Co-authored-by: ignaciodelcano+dcl <ignaciodelcano+dcl@gmail.com>
A single generation.image queue row without a matching admission used to
raise 503 from list/resume/discard and block every other leftover. Skip
the unmatched row instead so video and valid image recovery still work.

Co-authored-by: ignaciodelcano+dcl <ignaciodelcano+dcl@gmail.com>
IAnMove and others added 2 commits September 9, 2026 15:53
_list_workspaces includes every outputs/ subdirectory. A backup folder
such as "old copy" made restore_recovery raise 422 and blocked list,
resume and discard for every leftover.

Co-authored-by: ignaciodelcano+dcl <ignaciodelcano+dcl@gmail.com>
@IAnMove
IAnMove marked this pull request as ready for review September 9, 2026 14:19
@cursor

cursor Bot commented Sep 9, 2026

Copy link
Copy Markdown

Bugbot couldn't run - usage limit reached

Bugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit.

A user or team admin can review and increase usage limits in the Cursor dashboard.

(requestId: serverGenReqId_ab0242cc-eac8-41ea-8dc2-6792a5e78e06)

@IAnMove
IAnMove merged commit d0741cb into development Sep 9, 2026
14 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