Commit Graph
64 Commits
Author SHA1 Message Date
Benjiyaya b28f6eea2b feat: commit the local agent shell, history budget, and loop hardening
These files were already edited on this machine. Publish that tree instead of rewriting a slice onto a GitHub checkout.
2026-09-27 04:42:22 +08:00
Benjiyaya 61db492ee2 fix: keep the compiled H3 prompt when the continuity critic is unreadable
A prose critic reply was replacing the prompt with the fallback template. Retry once for JSON and leave the compiled text in place.
2026-09-27 04:36:57 +08:00
Benjiyaya 4a74b4c8f9 fix: agent tools follow Settings Queue timeout
The hidden 600s agent_tool_timeout_sec never appeared in Settings, so tool calls still died after Queue timeout was set to wait forever.
2026-09-27 04:23:57 +08:00
Benjiyaya 18bedfc394 feat: release 1.5.8 - one continuity plan for H3 clips 2026-09-27 03:10:48 +08:00
Benjiyaya a8fc4e451c fix(agent): attachments no longer crash linked-session turns; ask_user closes its tool batch
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.
2026-09-24 03:28:19 +08:00
Benjiyaya d2240b9c5a feat: release 1.5.7 - per-clip workflows, runtime budgets, media-path guards
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.
2026-09-24 02:26:47 +08:00
Benjiyaya 7551ba9d88 fix: accept name as an alias for a project's title so agent/API creates stop 422ing 2026-09-22 18:15:56 +08:00
Benjiyaya 6bd8ce1190 fix: release 1.5.5 - swarm renders enqueue, scenes get written, the board fills
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.
2026-09-22 03:48:57 +08:00
Benjiyaya ee7648d957 feat: release 1.5.4 - steering, Asset Library, canvas delete, agent hardening
- Mid-run steering input in AI Canvas + Build Scene (steering/message event, step-boundary drain, composer Steer mode)
- New /library Asset Library page: unlinked Playground media with All/Image/Video filters, 50-per-page lazy loading, bulk delete, add-to-project
- AI Canvas delete now persists: reference-checked file cleanup for playground-owned artifacts, entity tombstones, canvas.updated sync
- Agent loop hardening batch: swarm safety nets, clip tools in roles, capture false-success fix, planner fast-path, per-tool timeout, char-bounded history
- Build Scene Brief/Cut gates + MP4 export normalization
2026-09-19 06:31:14 +08:00
Benjiyaya bf557d8d5e feat: release 1.5.3 - fix the SSR localStorage crash on Node 22+
Patch the app-breaking regression 1.5.2 shipped: every server render threw
`localStorage.getItem is not a function`, so the UI only appeared behind a Vite
error overlay.

Node 22+ exposes a `localStorage` global that is not a Storage when no valid
`--localstorage-file` is set, which defeats the `typeof localStorage` guard the
language layer used. The code fix landed in 3363620; this commit cuts it as a
release and adds `npm test`, which fails if the unsafe idiom reappears.

Docs: docs/changelogs/2026-09-16-ssr-storage-fix.md
2026-09-16 04:22:07 +08:00
Benjiyaya 33636200f3 fix(i18n): stop SSR crashing on Node's non-Storage localStorage global
`localStorage.getItem is not a function` aborted every server render, so the
whole UI loaded behind a Vite error overlay.

Node 22+ exposes a global `localStorage`, and without a usable
`--localstorage-file` it is a bare object with no Storage methods. The
`typeof localStorage === 'undefined'` guard therefore passed and the next call
threw. It only bit at module/component scope, because SvelteKit evaluates those
on the server too — the same guard is harmless inside onMount and $effect.

Probe for a callable method in a shared storage helper instead of trusting the
binding to exist, and route the SSR-executed reads through it.
2026-09-16 04:17:42 +08:00
Benjiyaya f8855e8b07 chore(i18n): drop the dead toggleLanguage helper
It had no callers and its body hardcoded the en/zh pair, so it could not
have worked once the language set grew past two.
2026-09-16 04:02:33 +08:00
Benjiyaya a3588a2024 feat: complete the 1.5.2 language set (es/fr/de/ja/ko) and fix the reported version
The dictionary layer shipped with en/zh only, so the five other translations
were stranded outside the release while the notes described a bilingual UI.
Register them: seven languages, 1001 keys each, all typed against `Dict` so a
missing key fails the build instead of rendering the raw key.

Also align `__version__`, which had stayed at 1.4.1 through the 1.5.0 and 1.5.1
releases, leaving /api/health and the OpenAPI schema reporting a stale version.
The bat scripts now emit English so non-Chinese locales render them correctly.

Docs: docs/changelogs/2026-09-16-multilingual-ui.md
2026-09-16 04:00:14 +08:00
Benjiyaya fc7611ce7d fix(tests): let i18n dictionary keys through the SSE contract gate
The gate flags any `agent.*` / `job.*` / `canvas.*` string in calliope-web as
an SSE event the backend must publish. The new dictionary layer names UI labels
in those same dotted namespaces (`'canvas.tidy': 'Tidy'`), so every label read
as a missing event and the gate went red on main.

A dotted name that resolves to a dictionary key is a label, not a contract name:
collect the keys from lib/i18n/*.ts and exempt them.
2026-09-16 03:54:58 +08:00
Benjiyaya c6ef5e7204 feat: release 1.5.2 - bilingual UI (en/zh) and local start scripts
Ship the merged dictionary layer as 1.5.2. Every user-facing string now
resolves through the en/zh dictionaries instead of hardcoded English, with
a language switcher in the header and local setup/start scripts for the
first-run path.

Docs: docs/changelogs/2026-09-16-bilingual-ui.md
2026-09-16 03:41:41 +08:00
Benjiyaya 4c71cc497e feat(video): show the selected clip's shot brief in the composer
1.5 moved rendering to clips but the Video stage only surfaced the scene
script, so the workflow prompt field gave no hint of what an individual
clip performs. Each clip now carries its description, shot size, and
covered dialog lines into a brief panel above the composer, with a copy
button feeding the prompt. The stage splits into player + a scrollable
input inspector so the input stack can no longer squeeze the player out.
2026-09-13 02:57:17 +08:00
Benjiyaya ce0b4e1983 feat: release 1.5.0 — Build Scene 3D blockout composer + 1 scene : N shot clips
Build Scene (/build-scene): three.js + mannequin-js blockout viewport ported
from open-media, with per-session compositions (origin='scene' keeps rails
separate), agent shot_* tools as the only toolset for that surface, viewport
toolbar, keyframe motion + camera timeline with 60s video export, and
captures usable as project reference images.

Scene to Clips: clips table (1 scene : N renderable shots), coverage agent
breaks scenes into shots with full dialogue/action allocation, script
generation stays faithful to the screenplay (verbatim dialogue, content-
derived durations, chunked + durable inserts), video pipeline re-scoped to
clips (enqueue, continue-from, export, drafts), Script/Video UI clip-first
(#N.M labels, per-scene Break Into Shots scoped to one scene).

Agent loop: lean ReAct discipline with fail-streak escalation and budget
nudge; policy treats explicit user commands as permission; Build Scene tool
scope enforced mechanically; document + video attachments feed the VLM.
2026-09-11 18:05:21 +08:00
Benjiyaya f8faa72653 fix(agent): per-session event seq, parsed SSE echo, and vision attachments
Implements the intent of open PRs #48, #49, and part of #47 (all reviewed
against the working tree — none of the three bugs were fixed yet):

- #48 append_event returned cur.lastrowid (global row id) as the event's
  seq, while the INSERT allocates a per-session seq. The two only agree on
  a single-session DB, so ask_user's question_seq never matched
  latest_open_question() on a real install — card clicks never recorded an
  approval. The allocated seq is now read back from the inserted row; the
  atomic single-INSERT allocation is unchanged.

- #49 the agent.message SSE echo carried the raw agent_messages row
  (tool_args_json / tool_result_json strings, no parsed keys), while GET
  /sessions/{id} hands clients the parsed shape. _persist_message now
  returns parsed tool_args / tool_result alongside the raw keys, so the
  ask_user question card renders live instead of after a reload.

- #47 (partial) main.py carried the version as two literals that drifted
  from pyproject twice (1.3.2 reported 1.2.1; 1.4.1 reported 1.4.0). The
  version is now single-sourced in calliope.__version__, consumed by both
  FastAPI and /api/health; pyproject uses hatchling dynamic version. The
  PR's importlib.metadata approach was avoided: the venv's editable
  dist-info still says 0.1.0, which would report a third stale version.

- Vision attachments: user-attached images now project as OpenAI
  image_url content parts (data URLs read from disk), so vision-capable
  models see the actual pixels instead of a path line (derive_chat_rows /
  project_user_content, tested in test_agent_event_log).

Regression tests: per-session seq with a diverging second session, the
full card-answer flow across sessions, and the health version matching
the single-sourced metadata (tests/test_agent_interaction.py,
tests/test_projects.py).
2026-09-08 05:20:23 +08:00
Benjiyaya f4424a5c4f chore: release 1.4.1 — chunked story/script generation + working question cards 2026-09-07 05:43:15 +08:00
Benjiyaya dc5421c4a5 fix(agent): make ask_user question cards actually appear
The loop raised the end-turn control flow BEFORE logging/emitting the
ask_user tool result, so the frontend never received the question — the
chat sat on "working…" with no card until the user hit Stop or refreshed
(the report: "the agent loop just stops there"). The result is now
logged + emitted first, then the turn ends with status awaiting_input.

- Question card renders the question text plus stacked option buttons
  (long sentences read cleanly) and a hint line.
- Card answers are graded by first word: "Yes, replace with ~40 shorter
  scenes" grants, "No, keep existing scenes" refuses — previously a
  sentence option had to match "yes" exactly.
- Two regression tests: tool/result precedes turn/end with the question
  payload; option-sentence approval matrix.
2026-09-07 05:36:05 +08:00
Benjiyaya 447a4802c9 fix(agent): generate story beats and script scenes in chunks
Long-form generation asked the LLM for the whole board in one response —
a 50-beat story or 20-scene script is a multi-thousand-token JSON answer
that small/local models take minutes to stream, often under-deliver, and
then a single short chunk retried the ENTIRE thing. That is the "Draft
Storyline / Regenerate Script hangs" bug.

Both generators now write incrementally:
- Script: SCRIPT_CHUNK (4) scenes per call, each fed the full context plus
  the last two written scenes for continuity.
- Story: STORY_CHUNK (12) beats per call — a brief call (title, logline,
  cast, opening beats) then continuations given the established cast and
  recent beats.

Both renumber order_index gaplessly, retry only a short chunk, publish
agent.thinking progress per chunk, and keep single-call behavior for small
boards. The generate_story/generate_script agent tools route through the
same code, so the agent loop benefits too.
2026-09-06 16:07:10 +08:00
Benjiyaya e7640c74a4 chore: release 1.4.0 — AI Canvas changelog + version bump 2026-09-06 05:15:00 +08:00
Benjiyaya a11317ae0a feat(harness): canvas/skills/memory/interaction plugins + guard hardening
Self-registering harness plugins for the merged Canvas surface: canvas tools
(summarize/create/connect/link/update/run/post/delete, get-or-create sandbox
canvas), SKILL.md skills library with / composer picker, durable agent memory,
and ask_user question cards with structured HITL approvals. Guards emit typed
reason codes; stop cancels session jobs via ComfyUI interrupt; contract
vocabulary gate (contracts.json + export script) keeps web/backend names in sync.
2026-09-06 05:15:00 +08:00
Benjiyaya 045a729a07 feat(canvas): playable scene video cards + draggable chat panel width cap 30% 2026-09-06 05:15:00 +08:00
Benjiyaya 8bd0432f30 feat(nav): drop Agents link, AI Canvas is the primary surface 2026-09-06 05:15:00 +08:00
Benjiyaya 5932f4c081 feat(nav): rename to AI Canvas, drop Playground link, logo targets /canvas 2026-09-06 05:15:00 +08:00
Benjiyaya 5b7157a866 chore(canvas): drop unused imports flagged by ruff 2026-09-06 05:15:00 +08:00
Benjiyaya d3a2d397be feat(canvas): redirect /agents and /playground into the merged canvas surface 2026-09-06 05:15:00 +08:00
Benjiyaya 86d99b86d9 feat(canvas): merged shell route with Svelte Flow graph, collapsible rail, hosted agent chat 2026-09-06 05:15:00 +08:00
Benjiyaya dd51b914a9 feat(canvas): @xyflow/svelte dep + typed canvas API client 2026-09-06 05:15:00 +08:00
Benjiyaya 082e767c8e feat(canvas): CRUD router with entity auto-seed, tombstones, position persistence 2026-09-06 05:15:00 +08:00
Benjiyaya 6786115666 feat(canvas): canvas + canvas_node tables with project/session cascade scoping 2026-09-06 05:15:00 +08:00
Benjiyaya db414f92f1 fix: harden prompt preview — fail fast and never block Generate (1.3.2)
With an unreachable LLM endpoint the Review-prompt modal fired duplicate
long-hanging requests and left Generate impossible. Preview resolves now
fire exactly once per scene, the H3 rewrite times out after 30s and falls
back to the deterministic template, and on failure the modal populates the
editor with raw scene text so the user can edit + Generate or retry.
2026-08-31 23:41:17 +08:00
Benjiyaya 40934eb5f5 chore: bump @sveltejs/kit to 2.70.3, release 1.3.1
The old 2.20.x range carried high-severity npm audit advisories
(CSRF, dev-mode 404 XSS, handle-hook DoS), which pushed users toward
npm audit fix --force — a command that downgrades kit to a 2021
pre-release and breaks the install (issue #38). Bumping within the
major plus the safe audit fixes leaves only 3 low-severity transitives,
all requiring major downgrades. Recovery steps for affected users are
in the changelog.
2026-08-31 18:33:20 +08:00
Benjiyaya 9c8ea8f28f feat: prompt review gate, ComfyUI error surfacing, saved scene setups (1.3.0)
Issues #27/#33/#28. Generate now resolves the prompt first (saved draft
or H3 rewrite) and opens an editable review modal before enqueueing;
job history drawer shows each render's exact payload with copy-to-form.
ComfyUI 400s surface error.type + per-node messages; audio uploads go
flat and VHS audio: widgets are patched. Per-scene video settings
persist via scenes.video_settings_json (additive migration) and batch
generate honors them. Version bumped to 1.3.0.
2026-08-31 03:20:25 +08:00
Benjiyaya e896688963 chore: release 1.2.3 2026-08-29 21:45:49 +08:00
Benjiyaya 1ce2c2a535 feat: modal-based video source picker with project clip grid
The native select was too cramped for a project with many clips. Replace
it with a wide modal (Auto / Upload file / clip grid with thumbnails).
Clip options now cover any scene in the timeline, not just earlier ones,
and uploads wire through a hidden input. Also fix the Choose-Video modal
rendering blank under Clips/Uploads tabs: duplicate asset paths crashed
Svelte's keyed each mid-render — dedupe by path and clamp the active tab
when a tile's kind changes.
2026-08-29 21:43:05 +08:00
Benjiyaya 91cbaf1a44 docs: replace motion-context chain with video-extend continue flow 2026-08-29 05:30:18 +08:00
Benjiyaya c4f2e284a7 feat: relabel continue-from-previous scene toggle 2026-08-29 05:20:18 +08:00
Benjiyaya 36db1f90c9 feat: video-stage continue validator and clip picker 2026-08-29 05:17:35 +08:00
Benjiyaya 105c6ac6e3 feat: resolve continue-source clip at job time 2026-08-29 04:40:40 +08:00
Benjiyaya 85cccaef52 feat: validate video input for continue scenes at enqueue 2026-08-29 04:14:05 +08:00
Benjiyaya 59188a5b00 refactor: remove FirstMotion/NextMotion latent chain 2026-08-29 03:34:41 +08:00
Benjiyaya 4d1d38a542 fix: space stacked panels on settings tabs 2026-08-29 01:37:56 +08:00
Benjiyaya 5673914d61 chore: drop obsolete electron entries from root gitignore 2026-08-29 01:37:56 +08:00
Benjiyaya b87888f82b docs: changelog 2026-08-29, README updates, sub-folder gitignores 2026-08-29 01:37:56 +08:00
Benjiyaya aa30055e7a feat: report export fps in progress and thread voted rate 2026-08-29 01:14:20 +08:00
Benjiyaya 97d275d390 feat: export conforms to clip majority fps 2026-08-29 01:10:34 +08:00
Benjiyaya 10dacd840a feat: parse clip fps and vote export target rate 2026-08-29 01:03:25 +08:00
Benjiyaya acc1952e78 feat: model-per-agent picker in Settings agent tab 2026-08-29 00:54:09 +08:00
Benjiyaya 1d38f45ee5 feat: resolve agent LLM per role at client construction 2026-08-29 00:49:46 +08:00
Benjiyaya 290bc0dd74 feat: accept agent_llm_assignments in settings API 2026-08-29 00:31:05 +08:00
Benjiyaya 4943079cca feat: store per-agent LLM role assignments in config 2026-08-29 00:23:41 +08:00
Benjiyaya 22658f6147 Merge PR 25 locally for testing 2026-08-27 11:50:18 +08:00
Benjiyaya cfc13f4aee Stop offering a Windows zip while Create Project 404s.
The packaged FastAPI static mount returned JSON 404 for /project/{id}. Serve the SvelteKit fallback page for client routes, and point README at source until a zip is trustworthy.
2026-08-25 20:12:08 +08:00
Benjiyaya 7f2c6dce66 Bump version to 1.2.1 for the Windows zip release. 2026-08-24 04:33:27 +08:00
Benjiyaya 71bed77095 Add tabbed video ref picker, stricter agent HITL, and item attach.
Playground creates a new misc. item instead of overwriting one; item generate jobs persist the image path. Notes in docs/changelogs/2026-08-23.md.
2026-08-24 04:29:49 +08:00
BenjiyayaandCursor b587c56ce3 Keep Agents welcome chips on a newly created session.
Empty chats still offer Create a film, Draft a storyline, and Write a script.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-23 15:39:20 +08:00
BenjiyayaandCursor d79c9f4aba Merge origin/main: keep chain-from-prev-clip with H3 motion context
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-23 15:32:33 +08:00
BenjiyayaandCursor a1e329c9ef Calliope 1.2.0: agents, misc items, motion context, and queue timeout
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-23 15:29:44 +08:00
BenjiyayaandCursor 152234ac9b Fix LM Studio JSON mode failure and malformed LLM JSON parsing (v1.1.1)
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-20 01:09:22 +08:00
BenjiyayaandCursor 210e8998b8 Add MIT license and link it from README
Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-20 00:21:38 +08:00
Benjiyaya 170dc0695d Calliope 1.1.0: publish backend, web, and example workflows 2026-08-19 03:53:29 +08:00
Benjiyaya 83784ff4dc Calliope 1.0 2026-07-28 05:29:46 +08:00