- L2 连接核查: /object_info preflight (node existence + combo values) with
5-min cache + manual refresh; analyze accepts endpoint_id, saved workflows
get POST /{id}/check; unreachable degrades to 无法核查, never blocks saving
- 测试工作流: jobs.origin='workflow_test' rides the real queue → ComfyUI →
outputs pipeline; only a downloadable, correctly-typed output counts as a
pass; dry-run refused; repeat clicks reuse the in-flight job; artifacts
isolated under assets/_workflow_test/{id}; retention keeps newest 5;
clear-tests + delete-workflow cascade cleanup; tasks page shows a 测试 badge
- Media groups: Autogrow detection generalized to video/audio lists
(ref_videos/ref_audios etc.), patcher clones/rewires per media family,
validation per list kind; entries appear only for actually-wired slots;
MiniMax H3 Ref2VA official-limit hints keyed off the node class
- 25 new backend tests (preflight / workflow-test / media-groups) against the
fake ComfyUI; fake server gains /object_info + drop_outputs knobs
Co-authored-by: multica-agent <github@multica.ai>
1. .form-col border-box — 384px is the outer width (a6 spec)
2. import preview counts all analyzed inputs, matching inline/studio counts
3. SSRF guard also runs on endpoint save (create + patch)
4. schemeless/garbled URL is a 400 format error, not a DNS-classified probe failure
5. ComfyUI health probe timeout 120s → 5s (matches the test probe)
6. workflow delete refuses (409) while pending/running jobs use it; delete errors surfaced in the UI
7. agent_llm_assignments: per-role incremental merge server-side + single-role delta payloads
8. test_shell_tool now portable (interpreter on PATH; PYTHON+approval instead of ffprobe)
9. test_video_continue pauses the queue singleton via monkeypatch (no leak into test_workbench)
Co-authored-by: multica-agent <github@multica.ai>
Unknown custom output nodes are never auto-typed by class-name semantics;
they stay pending until the user designates the real output node(s) and
media type. Picking a usage alone no longer enables a workflow, reanalyze/
migration/field edits never overwrite a user mapping, generation harvests
only the mapped nodes from ComfyUI history, and media-type mismatches or
missing node results fail for real instead of faking completion.
Co-authored-by: multica-agent <github@multica.ai>
Root cause: parse_dynamic_inputs only recognised (Input:role) title tags.
A workflow exported straight from ComfyUI has default titles, so its
input_schema was empty and the studio form rendered no prompt box; the
generate click then enqueued (or was blocked) with no toast at all.
- parser: untagged fallback detects prompt/negative (via wiring to
sampler positive/negative), seed/steps/cfg, latent width/height/batch,
numeric primitives, LoadImage/LoadImageMask/video/audio slots; only the
prompt is required; entries carry auto=true
- patcher: "<nodeId>@<widget>" keys target one widget on multi-widget
nodes, never overwrite linked inputs; LoadImageMask uploads like images
- workflows API re-derives an empty stored schema (old imports fixed
without re-import); smart_fill sort accepts subgraph/field ids
- studio: blocked submit toasts the reason and scrolls to the field;
success toasts "已提交"; submit errors show the API detail; job.failed
for this window's jobs toasts the reason; no-param workflows show a
note + disabled prompt box; auto-detected params show a note
- connections import: chip shows node count, toast reports real params
- Chinese messages for ComfyUI rejection/upload/timeout/execution errors
and playground workflow-not-found/disabled
- tests: native Qwen t2i / Qwen edit+mask / untagged H3 fixtures, patch
keys, backfill, full fake-ComfyUI chain, Chinese rejection
Co-authored-by: multica-agent <github@multica.ai>
- backend: project_stages/stage_runs tables; /api/workbench router
(overview, run agent with confirmed-upstream context only, edit draft,
confirm, restore, script import, in-flow image/video generation via the
shared queue with source=workbench); project stats gain real
stage_confirmed/stage_status/active_jobs
- frontend: /workbench picker + /workbench/[id] five-stage page (stepper,
per-stage editors, style direction chooser, storyboard table, asset
prompt cards with in-flow generation, shot video prompts with player,
agent + task side rail); nav 创作工作台 now opens it; home entries go
through the workbench (导入剧本 skips 剧本创作); project cards show
real five-stage progress; i18n keys in all seven dictionaries
- tests: 9 backend workbench tests (flow handoff, edit/confirm/restore,
import, generation, Chinese failure states)
Co-authored-by: multica-agent <github@multica.ai>
The editor's strip regex anchored on \\A — a Python-ism JS treats as a
literal — so it never matched: the editor showed the raw frontmatter and
every save re-wrapped the file in one more frontmatter layer. Extract the
strip into lib/skillFrontmatter.ts with a ^ anchor, import it from the
page, and guard it with scripts/check-skill-frontmatter.mjs (wired into
npm test): strips the render_skill_md block shape, exact split boundary,
idempotent, save-reload round-trip adds no layer, and the inline \\A
pattern is banned statically.
Also per review notes: skill toggles are now the spec-v2 §5 34x19 capsule
(amber track + dark knob when on), and version-history timestamps render
localized instead of the raw SQLite UTC string.
Co-authored-by: multica-agent <github@multica.ai>
Backend:
- agents_registry: five AIGC roles (剧本创作/视觉设计/分镜设计/素材资产/镜头脚本)
with zh personas, agent-chat mode text, and llm_role mapping onto the
models-page five-role binding surface (story/style/script/assets/video)
- agent_sessions.agent_key column + migration; sessions filter/exclusion;
named replies stamped with the owner agent's display name
- prompt assembly: per-agent persona + AGENT CHAT mode section replace the
generic sandbox text; mentions section suppressed for agent chats
- main loop routes the LLM through the agent's bound role
- skill admin surface: skill_overrides/skill_bindings/skill_versions tables,
PUT/PATCH/DELETE /api/agent/skills/{name} + bindings + versions/restore;
effective rule = global enable ∩ enabled per-agent binding; builtin skills
seeded to all five agents at upgrade; read_skill/list_skills gated for
named-agent sessions
Frontend:
- /agents is now the three-column A-darkroom page (agent list + skill library
/ chat with reused AgentChat / skill manager with editor, assignment
capsules, version history + rollback); per-agent model select synced with
the models page; narrow breakpoint turns the manager into a drawer
- legacy ?project=&task= deep links still route into the canvas flow
- i18n keys added to all 7 locales
Tests: tests/test_agent_roles.py + tests/test_skill_admin.py (27 cases)
Co-authored-by: multica-agent <github@multica.ai>
- /image and /video pages (a3/a4): three-column layout — params (connection,
workflow, upload slots driven by declared inputs, prompt/negative/seed/
size/duration fields, dynamic params), current-task card with live SSE
progress + cancel, result grid with zoom/send-to-img2img/download, video
player with custom amber controls + first/last-frame strip, right history
with retry/delete and failure reasons
- /tasks page: both task classes summarized with source labels
(独立生图/独立生视频/Playground/创作流程), filters, retry/cancel/delete
- nav: 生图/生视频/生成任务 real pages with active-jobs badge (进行数徽章)
- playground generate accepts source (studio-image/studio-video) for origin
labeling; api.ts types follow
- parseDbTs helper: UTC-naive backend timestamps parse as UTC so elapsed/
ETA/duration math is offset-correct
- backend tests: full-chain fake-ComfyUI server — image chain, video chain
with frame uploads, retry-after-failure, delete-removes-outputs, tasks
listing; i18n zh/en/es/fr/de/ja/ko complete
Co-authored-by: multica-agent <github@multica.ai>
- New /models page: LLM cards (type tag, agent-default badge, test state
with latency/consecutive failures), add/edit form (OpenAI-compatible
segment, mono base URL/model, masked key with sk-****tail, timeout
dropdown, save gated on a passing test), agent default-model panel for
the five AIGC agents, dashed server-connectivity notice, disabled
image/video tabs as future placeholders; responsive 1440/1024/768
breakpoints per spec-v2 §9.
- Scoped A darkroom design tokens in app.css (.a-darkroom) + Noto Sans SC.
- Top nav: add Agents and Models entries before Settings.
- Backend: add 'style' agent role, llm-test timeout_sec (5-60, default 10),
api_key_tail (last 4 chars) in public profiles; 4 new tests.
- i18n: 84 models.* keys + nav.agents/nav.models in all 7 dictionaries.
Co-authored-by: multica-agent <github@multica.ai>
- First-open default language is now Simplified Chinese (i18n.svelte.ts);
stored language choice still wins.
- New POST /api/settings/llm-test endpoint probes an OpenAI-compatible
endpoint with a 1-token chat completion; falls back to a saved profile's
secret so keys never travel back to the browser.
- Settings LLM cards gain a connection-test button with readable
success/failure feedback (auth / timeout / connect / HTTP detail),
localized in all seven dictionaries.
- Backend tests cover success, saved-secret reuse, 401, connection
refused, and input validation against a local fake OpenAI server.
Two agent-loop bugs found in the Sep 24 loop evaluation, folded into the
1.5.7 line:
1. A linked-session turn whose user message carried an image/video/document
attachment crashed 100% of the time: derive_llm_history projects multimodal
content as an OpenAI parts list, and orchestrate() read that list as the
goal and called .strip() on it (AttributeError: 'list' object has no
attribute 'strip'). New log.text_of_content() extracts the text part; the
goal read uses it, so single-loop and swarm paths both survive attachments.
2. When ask_user paused the turn mid tool-batch, the remaining calls of that
step never executed but also never received tool results, leaving an
assistant tool_calls message with dangling ids - an invalid request
sequence that strict OpenAI-compatible servers 400 on the next turn. The
pause path now synthesizes skipped tool/call + tool/result events and
tool-role messages for the un-executed ids before ending the turn.
The new multimodal-goal tests now stub the planner LLM: the attachment
appendix puts newlines in the extracted goal, so the message is never
trivial-path and the unstubbed planner made a real network call - the source
of the tests' flakiness (and the swarm-path test now attaches the document
it always claimed to).
Backend suite: 538 passed.
Three reported issues:
#66: the Video stage workflow picker was keyed by scene id, so choosing a
workflow for one clip overwrote every sibling clip. It is now keyed by clip
id, hydrates each clip's persisted choice, autosaves both
clips.workflow_id and form_workflow_id, and Generate One / Generate All
resolve the workflow per clip (a scene can mix image->video and
video->video extend across its clips).
#64: a 30-second ask could produce a 1:51 script - prompts carried no
per-scene scale and the duration rescale could only grow. Prompts now
state the total seconds and a per-scene budget, and the rescale may shrink
(floor 0.5) so over-written boards pull toward the target; content itself
is never edited.
#67: a hand-written directory path (e.g. ComfyUI's input dir) reached
ComfyUI and died as an opaque Errno 21. prepare_media_inputs now rejects
directory / missing local files before queueing with a node-naming error,
and the agent's run_workflow validates media input_values at call time.
Bare Comfy-side names pass untouched.
534 backend tests pass; svelte-check clean.
Live event logs (session 908) showed a planner-scheduled render task whose
tools were hidden by the HITL visibility rule, a story sub-agent denied the
add_scene tools the planner told it to use, deep-linked chats orphaning as
duplicate empty sessions, and new project assets missing from the canvas
until re-open. Render-intent now recognizes clip/shot/storyboard; sub-agent
payloads keep approval-gated tools visible (permission stays at the
execute-time guard, whose denial teaches ask_user); the story role owns
scene structure; the canvas deep-link session param is trusted; GET
/api/canvas/{id} auto-seeds new entity cards.