@starreel/mcp 0.1.225 → 0.1.231
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/SKILL.md +34 -3
- package/dist/i18n/tools.en.json +7 -7
- package/dist/i18n/tools.zh-CN.json +7 -7
- package/dist/tools/produce.js +36 -8
- package/openapi.json +51 -9
- package/package.json +1 -1
- package/server.json +2 -2
package/SKILL.md
CHANGED
|
@@ -95,7 +95,8 @@ announces a condensed version as MCP `instructions` at connect time.
|
|
|
95
95
|
| Their own **footage** for a shot (screen recording, product b-roll, an existing clip) | `upload_shot_footage` → that shot is no longer AI-generated (frames/video skipped, final cut uses the clip as-is, duration written back from the clip); **it overwrites whatever AI video that shot already had**, and afterwards every AI video call on it (including `edit_video_shot`) is refused with **409** until you `clear_shot_footage` or pass `replace_user_footage: true` | pasting an externally AI-generated clip to "fix" a shot — it carries none of this film's identity / style anchors; use `regenerate_shot_video` instead |
|
|
96
96
|
| A clip that should **drive the motion** of an AI shot (a blocking/previz pass, a dance or action reference) | `edit_video_shot` with `reference_video_urls` — the shot keeps its AI video and borrows the clip's movement. To make the clip itself the source and restyle it in place, `upload_shot_footage` it first, then `edit_video_shot` with `replace_user_footage: true` | `upload_shot_footage` alone — that registers the clip as the finished shot, so nothing gets restyled and every later AI call on it returns 409 |
|
|
97
97
|
| A clip whose **motion should be kept while the people / outfits are redrawn** (video repaint) — their own footage or a shot already generated here | `get_repaint_capabilities` (is it enabled for this drama; `relayMaxSegments`) → for their own clip, `upload_shot_footage` it onto a shot first → `quote_repaint_shot_video` → `repaint_shot_video` (prompt + reference image; with no `reference_image_url` the shot's character portrait is used — without any reference the person is redrawn too) **or** `quote_reskin_shot_video` → `reskin_shot_video` (`first_frame_url` = an already-reskinned first frame that matches the original first frame's composition, pose and props exactly) → `get_repaint_status` with the returned id until `completed` → `restore_repaint_original` to switch back (free). Motion, lip timing and camera move follow the source and its audio is carried over. ≤5 s is one charge (billed as 5 s); with long-shot relay enabled, 5–~14 s is split into ≤3 relayed segments, one charge each, and the quote is the total and the charge cap. A quote is tied to the shot's current video — if that video changes, generating returns 409; re-quote (free) | `edit_video_shot` to swap the whole cast or wardrobe (it edits by instruction); clips longer than ~14 s (`split_shot` first) |
|
|
98
|
-
| `review_storyboards` reports `forbidden_term` (light / color-temperature / BGM wording in the shot text) | every hit is listed at once in the finding's `hits` (`shot`, `field`, `term`) → `get_shot_prompts` to read that field (`description` is returned there too) → `update_shot` to remove the term from that field; if the intent is lighting, move it to `update_shot`'s `lighting` field (not scanned, and video / image generation read it) → `review_storyboards` again | rewriting the whole shot blind, or putting the lighting back into `description` / prompts in other words |
|
|
98
|
+
| `review_storyboards` reports `forbidden_term` (light / color-temperature / BGM wording in the shot text) | every hit is listed at once in the finding's `hits` (`shot`, `field`, `term`) → `get_shot_prompts` to read that field (`description` is returned there too) → `update_shot` to remove the term from that field; if the intent is lighting, move it to `update_shot`'s `lighting` field (not scanned, and video / image generation read it); a hit with `field=sound_effect` is fixed with `update_shot`'s `sound_effect` field (its current value is in `get_shot_prompts` too) → `review_storyboards` again | rewriting the whole shot blind, or putting the lighting back into `description` / prompts in other words |
|
|
99
|
+
| A shot/reverse-shot or over-the-shoulder pair (camera over A's shoulder onto B, then over B's shoulder onto A) | `update_shot` the second shot with `continuity_intent: "shot_change"` — it keeps the frame chain (re-framed first frame) but never takes the video-extension path, so the shot is rendered from its own first/last frames | `continuous_action` on a reverse shot: extension continues the previous clip's camera and the model invents the turned-around view |
|
|
99
100
|
| A scene plate that came out wrong (backdrop, era, light, layout) | `get_scene_prompt` → `update_scene` (`image_prompt`) → `quote_regenerate_scene_image` (tell the customer the points — it includes the lighting reference the platform auto-derives after a plate change when no wide-shot frame exists) → `regenerate_scene_image` with that `quote_id` (after `upload_scene_image` the platform does **not** auto-create the lighting reference — if the reply says `lighting_ref.needed`, quote it with `quote_scene_lighting_ref` and, once the customer agrees, `generate_scene_lighting_ref`); already-rendered shot frames still anchor on the old plate, so regenerate those shots too | re-running `generate_scene_images` (it only fills scenes that have **no** plate — it will not touch this one) |
|
|
100
101
|
| A voice sample / a required voice | `clone_voice` → `speak_with_voice` → `set_character_voice` / `assign_voices` | cloning without the rights-holder's consent |
|
|
101
102
|
| No sample, but a character already speaks in a rendered shot | `set_voice_anchor_from_shot` (free; native-audio dramas: locks the voice for later videos) → regenerate `stale_shots` | picking the voice after the whole episode is rendered |
|
|
@@ -666,6 +667,15 @@ content that will be rejected.
|
|
|
666
667
|
`upload_shot_frame` is for art the customer already owns — the one exception is
|
|
667
668
|
a **local touch-up of this shot's own platform candidate** (option 2 below).
|
|
668
669
|
|
|
670
|
+
**Does this shot continue from the previous one?** For a first frame, the quote
|
|
671
|
+
and the receipt carry `continuity`: `follows_previous_shot: true` means the
|
|
672
|
+
previous shot's last frame will be pinned as reference #1, so its people, pose
|
|
673
|
+
and camera position carry over (`note` says why). For a jump cut, a scene change
|
|
674
|
+
or a detail close-up of only hands / an object, pass `continuity_mode:
|
|
675
|
+
'independent'` on **both** `quote_shot_frame` and `generate_shot_frame`
|
|
676
|
+
(`follow_previous` forces continuation even across a cut). The two calls must
|
|
677
|
+
use the same value, otherwise 409 — re-quote.
|
|
678
|
+
|
|
669
679
|
**Only a small part of the frame is wrong?** (a face, an open mouth, a fringe of
|
|
670
680
|
halo pixels, a stray object) — use `quote_local_frame_edit` → `local_frame_edit`
|
|
671
681
|
instead of redrawing the whole frame or fixing it in an outside tool. Box the area
|
|
@@ -758,6 +768,22 @@ content that will be rejected.
|
|
|
758
768
|
lets it through). Relay your QC findings to the user verbatim. Listing a
|
|
759
769
|
`ref` you never opened is signing off on the user's money.
|
|
760
770
|
|
|
771
|
+
**Check action and camera movement against the user's own script, not
|
|
772
|
+
against the platform's description.** Shot materials carry `shot_spec`
|
|
773
|
+
(shot type, `movement`, `action` with `action_in` / `action_out`, first and
|
|
774
|
+
last frame prompts). At the storyboard layer compare every shot with the
|
|
775
|
+
"picture" and "camera / movement" columns of the user's original
|
|
776
|
+
(`get_script` → `original_content`, or the storyboard table they gave you)
|
|
777
|
+
— `shot_action`, `camera_movement`. At the frame layer check that each first
|
|
778
|
+
frame is the *start* of the action and camera move and each last frame its
|
|
779
|
+
end (`frame_is_start_state`: a first frame that already shows the end state
|
|
780
|
+
leaves the video with no action), and compare left/right position, facing
|
|
781
|
+
and eyeline with the neighbouring shots (`screen_direction`). At the video
|
|
782
|
+
layer sample the start, middle and end of every clip: the action is played
|
|
783
|
+
out to the end, no extra limbs or objects appear, and the sound matches the
|
|
784
|
+
script (`action_complete`). Say in each note what you compared against — a
|
|
785
|
+
one-line summary is not a check.
|
|
786
|
+
|
|
761
787
|
**The user's specific requirements are not covered by "the review passed".**
|
|
762
788
|
When the user asks for something specific about a shot or the whole episode
|
|
763
789
|
(identity, wardrobe, prop color, lip sync, visual artifacts…), register it in
|
|
@@ -988,7 +1014,9 @@ what? which shots are key moments? where is the emotional valley?),
|
|
|
988
1014
|
(`{speaker, text}` per line — parsed by the same parser subtitles and voice-over
|
|
989
1015
|
use, so the speaker you see is the one that will be voiced), `is_key_moment` and
|
|
990
1016
|
`emotion_intensity`. One call covers the whole episode; the prompt bodies stay
|
|
991
|
-
per shot via `get_shot_prompts
|
|
1017
|
+
per shot via `get_shot_prompts`, which is also where you read back `shot_type`,
|
|
1018
|
+
`angle`, `camera_movement` and `continuity_intent` after changing them with
|
|
1019
|
+
`update_shot`.
|
|
992
1020
|
|
|
993
1021
|
When the frame or the motion is off in a way the business text cannot express,
|
|
994
1022
|
edit the shot's prompt bodies directly: `get_shot_prompts` reads the current
|
|
@@ -1315,7 +1343,10 @@ from an internal measured run (one character, 3 shots, 18 s, `hailuo-3`):
|
|
|
1315
1343
|
generating frames.
|
|
1316
1344
|
- **Adjacent continuous-action shots are generated as one group**, and their
|
|
1317
1345
|
durations get re-split by content (6 s + 5 s came back as ~8 s + 3.7 s). Check
|
|
1318
|
-
`get_scene_group_plan` before generating videos.
|
|
1346
|
+
`get_scene_group_plan` before generating videos. This only applies while
|
|
1347
|
+
long-take mode is on: if the plan's top-level `active` is `false`
|
|
1348
|
+
(`scene_group_mode` off), its `groups` are a preview only — every shot is
|
|
1349
|
+
generated and billed on its own.
|
|
1319
1350
|
- **Tail frames only help shots generated on their own.** Check
|
|
1320
1351
|
`get_scene_group_plan` first: a grouped shot's tail frame is never sent to
|
|
1321
1352
|
the video model (only the group head's first frame is, except Seedance 2.5
|
package/dist/i18n/tools.en.json
CHANGED
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"get_frame_retry_diagnosis": "Free read-only query for image-task losing-streak diagnosis, evidence task IDs, and next action. When diagnosis_required, call this tool first: audit failures should re-review existing candidates; unknown causes should be rechecked first; do not redraw with identical input or change the script without authorization. ★Returned recovery_options are the three choices after image generation failure (ordered free→free→paid, no need to disturb customer when needs_attention=false): ① adopt_rejected select an audit-misjudged candidate from rejected/unselected candidates (get_frame_candidates→adopt_frame_candidate, candidates is adoptable count); ② upload_fixed locally patch this shot’s platform candidate then upload_shot_frame; ③ regenerate modify content per diagnosis then quote_shot_frame→generate_shot_frame. When ask_customer=true, present all three to the customer and let them choose; do not approve on their behalf or pay for regeneration without authorization. failure_class=transient is incidental failure; wait and retry same input. not_self_healable is overdue account/insufficient credits/quota full/model unavailable; regeneration is useless (regenerate.available=false); handle account or change model first.",
|
|
28
28
|
"get_image_dispatch": "Free read-only query of a shot frame’s dispatch ledger: which reference images were actually used, each image’s purpose and character ownership, whether it reached the model, at which step and why any missing or pre-dispatch removed image was removed (e.g. conflicting object named by era precheck), and the final prompt actually sent to the image model. Use to answer “which image was used and why the result does not look like it”; check facts before deciding to regenerate, do not repeatedly pay for redraws by guessing. ledger=partial/none means the image was generated before ledger launch; missing fields are honestly null.",
|
|
29
29
|
"get_frame_candidates": "Free read-only: **all candidates** for a shot’s first frame/last frame (same data as the image acceptance workbench). Each candidate includes original image URL (rejected ones too; can open directly at original size), status, whether currently in use (adopted), rejection reason reject (main primary code / code specific cause / details / class routing: needs_content_fix=content must change, content_retryable=content issue but reroll succeeds about 1/3, transient=audit did not complete or incidental—not image disqualification), audit evidence audit (warnings Chinese conclusion, expected design requirements, derived_shot_type inferred shot size with rationale, boxes positions of subjects/body parts in frame; candidates before 2026-10-07 have no archived evidence and are null, not proof they were audited), and which reference images were actually used (references: purpose/character ownership/whether delivered). storyboard.tail_endstate is the “last frame≈first frame” check conclusion (current=false means the conclusion is not for the current two images). ★When a shot is repeatedly rejected, or the customer asks “what did those rejected images look like / why not adopt them”, call this first: inspect each original image and evidence, then decide whether to change storyboard, references, or reroll—do not blindly pay to regenerate. To see a specific image’s final prompt use get_image_dispatch(generation_id). If the customer has seen the original image and confirms the image is fine and the audit was wrong, use adopt_frame_candidate for manual adoption (free); manual_adoption non-empty = this candidate was manually approved. recovery_options gives the three choices after failure by frame position (pick false rejection / patch and upload / regenerate), same criteria as get_frame_retry_diagnosis.",
|
|
30
|
-
"adopt_frame_candidate": "Free: manually adopt a completed first-frame/last-frame candidate (rejected by audit rejected, unselected dismissed, or completed but previously in use then replaced) as the active frame for this shot—manual fallback for audit misjudgment (e.g. setting explicitly specified by author contract was judged conflicting), and can switch back to a previous one at any time. ★You must first use get_frame_candidates so the customer has seen the original image and rejection reason, and only call after explicit customer consent (adopting a rejected candidate requires explicit customer consent in every execution mode, autopilot included); do not self-approve just to move the process along. Can only adopt this shot’s same frame position, completed, has image, and not currently active. Manual approval is recorded on the candidate (who/when/original rejection reason); original rejection reason is retained for statistics. If this shot already has video, it will be marked pending regeneration (video was generated from old frames; need regenerate_shot_video). If this frame is customer-uploaded or finalized, pass replace_user_frame:true to replace it (and unfinalize). If same frame position has image generation in progress or this shot has video in progress, returns 409; wait for it to finish before adopting.",
|
|
30
|
+
"adopt_frame_candidate": "Free: manually adopt a completed first-frame/last-frame candidate (rejected by audit rejected, unselected dismissed, or completed but previously in use then replaced) as the active frame for this shot—manual fallback for audit misjudgment (e.g. setting explicitly specified by author contract was judged conflicting), and can switch back to a previous one at any time. ★You must first use get_frame_candidates so the customer has seen the original image and rejection reason, and only call after explicit customer consent (adopting a rejected candidate requires explicit customer consent in every execution mode, autopilot included); do not self-approve just to move the process along. ★Before adopting, check the shot (get_storyboards first_frame_prompt / last_frame_prompt / action_in / action_out / movement): an adopted first frame must be the start of the action, an adopted last frame its end—if a first-frame candidate already shows the end state (the person has already arrived, the action is already done) or draws the camera move's end point into its start, the video will have no action in it; pick another candidate or fix the prompt and regenerate. Can only adopt this shot’s same frame position, completed, has image, and not currently active. Manual approval is recorded on the candidate (who/when/original rejection reason); original rejection reason is retained for statistics. If this shot already has video, it will be marked pending regeneration (video was generated from old frames; need regenerate_shot_video). If this frame is customer-uploaded or finalized, pass replace_user_frame:true to replace it (and unfinalize). If same frame position has image generation in progress or this shot has video in progress, returns 409; wait for it to finish before adopting.",
|
|
31
31
|
"get_stale_portrait_frames": "Free read-only query for which active first frames/last frames in an episode were drawn using old assets for characters that have since been replaced (old character sheet, old turnaround, old body/hair image). Use after changing a character sheet to confirm impact scope, then let the customer decide which shots to regenerate (regeneration costs credits; this tool changes no data). verdict=stale must include evidence: ledger-old-asset (dispatch ledger directly recorded use of old image) / references-previous-asset (references include that character’s previous old asset) / portrait-born-after-frame (current character sheet was created after this frame). If not provable, mark unknown with reason; do not treat as stale. has_video=true means this shot’s video is also based on old frame; after regenerating frames, video must be regenerated.",
|
|
32
32
|
"get_asset_versions": "Read-only query for all image/video versions of a shot, historical view links, dependency IDs and version hashes, plus four independent facts: generated → consistent with current input → audit valid → adopted. If historical dependency records are missing, show unknown; do not fabricate snapshots. Free. video_lock is the customer-accepted video lock (lock_shot_video): when locked=true that video counts as current by choice; frames_changed_since_lock=true means frames changed after the lock but no regeneration is needed.",
|
|
33
33
|
"lock_shot_video": "Lock a shot's current video as the customer-accepted version (free; generates nothing, changes no asset). Use it when the customer has explicitly said \"keep this take\" and the shot's frames / scene / character were changed afterwards. While locked, asset changes no longer mark the shot stale: review_videos stops reporting video_stale (a warning video_locked_frames_changed instead), get_asset_versions shows acceptance_locked=true with the drift listed in drift_while_locked, native-voice stale_shots skip it, and the compose preflight does not flag it; regenerate_shot_video / edit_video_shot / repaint / reskin / footage upload or clear / a whole-episode generate_videos that would replace it all return 409 VIDEO_LOCKED. The lock freezes the video generation id and the inputs it was made from (first/last frame URLs, prompt, reference list). Only the video currently in use can be locked (a generation_id that is not it returns 409 NOT_CURRENT_VIDEO; no video returns 409 NO_VIDEO). If the video is swapped by another path, the lock lapses (video_lock.broken=true in get_asset_versions). Lock only after the customer explicitly confirms; never treat generation finishing or a model judgement as acceptance. To regenerate, get the customer's OK and call unlock_shot_video first.",
|
|
@@ -51,11 +51,11 @@
|
|
|
51
51
|
"autofill_storyboards": "(Recommended) AI one-click fills missing storyboard fields across the episode (or only the shots in storyboard_ids); by default it **only fills blanks and does not overwrite existing values** (only overwrites when overwrite=true). Improves storyboard completeness; do before image generation. Async in background, postpaid text step (billed per shot that actually calls AI). ★Before running, confirm character/scene/prop bindings (check get_storyboards character_ids / scene_id / prop_ids shot by shot against the customer's original). If a missing binding turns up after auto-completion, just fix it with update_shot; **do not re-import the episode**—re-import replaces the storyboards, discards the auto-completion and charges again. ★**Quote first with quote_autofill** (same overwrite / storyboard_ids), tell the customer shots_to_fill and estimated_points / typical_points, and **run this tool only after the customer agrees**. ★When done, read the receipt from get_autofill_status (which fields were written on how many shots, how many skipped, how many still lack contracts) and tell the customer—the internal fields written here are not readable via get_storyboards, so don’t let the customer think they were charged for nothing. ★The platform already completed one round when storyboards were saved: in fill-empty mode, shots with no gaps left (all six narrative text fields present, vocal direction present on shots with dialogue, and contract present when contract auto-fill is on) are skipped with no AI call and no charge; only overwrite:true reruns the whole episode and bills every shot. ★Completion writes narrative/rhythm internal fields and composition contracts; get_storyboards / get_shot_prompts do not return these fields, so no visible change on read-back is normal—check the counts in the get_autofill_status receipt; it **does not change** image/video prompt text. ★When platform contract auto-fill is enabled, it also tries to add contracts to shots **without composition contracts** (whether enabled is indicated by the note in the import receipt contract_coverage; visible headcount / subject range / shot size are judged by it for both image generation and review; with default overwrite:false, existing contracts are untouched; **overwrite:true also rewrites existing contracts**)—if auto_complete was off during import and the contract_coverage note points to this tool, call it once before image generation. If this episode already has autofill running, this run **will not queue** (prevents duplicate-click duplicate charges); newly imported shots must wait until get_autofill_status is done before calling again. ★To trial a small range first: pass storyboard_ids (1–50 shot ids of this episode, from get_storyboards); only those shots are filled, others make no AI call and are not charged; omit = whole episode. If a completion is already running in this episode, the subset does not start: the receipt returns started=false, reason=fill batch already running; call again after get_autofill_status reaches done.",
|
|
52
52
|
"enhance_shot_prompts": "(Optional enhancement · ★not required · has side effects) AI batch-enhances the whole episode's image_prompt. ★It **rewrites existing prompts** (including manually edited ones); and **must be done before generate_frames**—changing prompts after image generation makes images stale and requires paid regeneration. Not required to get a film through the pipeline; do only if the customer explicitly requests it. Async in background, postpaid text step.",
|
|
53
53
|
"complete_ending_motifs": "(Optional enhancement·★not required·conditional) Complete missing visual motifs in the ending segment (graft visual echoes onto ending shots). ★Prerequisite: this drama already has motifs (none = no-op); this will **modify ending shot action/descriptions**, so do it before generating images (otherwise already-generated ending shots become stale). Backend async, billed after the text step.",
|
|
54
|
-
"tail_frame_plan": "★Free read-only: which shots in this episode **need independent last frames** (shots whose terminal state ≠ initial state—large camera move/object released/state change). It uses the same criteria the platform uses for video generation; you cannot guess this yourself, so call it once after first frames are done. Returns shots_needing_last_frame(total), ready(shots with first frames already available and can get last frames now), pending_first_frame(shots that need last frames but whose first frames are not ready yet—call this tool again after first frames finish). After getting the ready list: use quote_frames + generate_frames with frame_type=last_frame to batch-fill. ★After last frames are filled (or this tool reports 0), the next step is seams: chain_frames(dry_run:true) to view plan and estimate, execute after customer confirmation, then review_frames. ★Skipping last frames will not error, but those shots have only one first-frame anchor during video generation, so the model improvises the terminal state—bad action completion, large camera moves ending back at the starting composition, etc. usually come from this. Zero cost, callable anytime.",
|
|
54
|
+
"tail_frame_plan": "★Free read-only: which shots in this episode **need independent last frames** (shots whose terminal state ≠ initial state—large camera move/object released/state change). Camera-move shots (pan/push/pull/track/crane, start and end compositions differ) are counted per drama rollout; write the camera move into the shot's movement or action (e.g. “the camera slowly tilts down to …”) — a shot whose prompt only says “fixed camera” is treated as static. It uses the same criteria the platform uses for video generation; you cannot guess this yourself, so call it once after first frames are done. Returns shots_needing_last_frame(total), ready(shots with first frames already available and can get last frames now), pending_first_frame(shots that need last frames but whose first frames are not ready yet—call this tool again after first frames finish). After getting the ready list: use quote_frames + generate_frames with frame_type=last_frame to batch-fill. ★After last frames are filled (or this tool reports 0), the next step is seams: chain_frames(dry_run:true) to view plan and estimate, execute after customer confirmation, then review_frames. ★Skipping last frames will not error, but those shots have only one first-frame anchor during video generation, so the model improvises the terminal state—bad action completion, large camera moves ending back at the starting composition, etc. usually come from this. Zero cost, callable anytime.",
|
|
55
55
|
"quote_frames": "Quote: how many credits to batch-generate frames for an episode. Returns frames_to_generate, estimated_points, quote_id. Zero cost. frame_type defaults to first_frame(only shots missing first frames); last_frame only generates shots that have first frames and lack last frames; both fills both. ★Quote is tiered by the **actual model and resolution that will be used**; response includes price_breakdown(count and unit price per tier). If you plan to temporarily switch models in generate_frames, pass the same image_model when quoting, otherwise prices differ. ★Both sides must pass the same image_model — mismatch is rejected directly (400 IMAGE_MODEL_MISMATCH), because the model determines the billing tier; different sources mean \"estimate ≠ charge\". Passing neither on both sides also counts as consistent (uses the drama setting). Deprecated models (all FLUX series) are always rejected; do not pass them. ★Returns two numbers: estimated_points is the **upper bound** (estimated by maximum reference-image count; prepare this balance to avoid mid-run 402), typical_points is the **usual cost**. Tell the customer both; quoting only the upper bound makes it look much more expensive. For fixed-price models (e.g. Nano Banana series), they are equal.",
|
|
56
56
|
"generate_frames": "Batch-generate frames after confirmation: backend async. Poll with get_storyboards; done when first_frame_image/last_frame_image is filled shot by shot. ★Image generation is slow—tens of seconds to minutes per image (especially HD models); a full episode may take 10+ minutes. When polling, check frame_status: **pending=still generating (keep waiting patiently; do not treat as failure; do not call generate_frames again; duplicate triggers=wasted credits)**, ready=done, failed=only this is real failure. Do not decide generation failed or retry just because “it still has not appeared after waiting a while”. Frames must be generated before video, otherwise video degrades into images with no consistency anchors. ★**Before generating frames, prepare both anchors**: character sheets (generate_portraits_and_sheets, anchors people) and empty scene baseplates (generate_scene_images, anchors scenes). Missing baseplates will not block you, but the first shot of each scene will have no background anchor (the platform fallback fill only benefits later shots in the same scene), so the background starts drifting from the first shot. Use the generate_scene_images step in get_pipeline_status to verify completed/total. frame_type must match what quote_frames used (default first_frame). ★This is **batch fill-missing-frames**: it only generates images for shots “missing that frame”; shots that already have first frames are skipped—this is normal design, not “the system refusing to regenerate”. To **regenerate/redraw an existing frame for one shot** (e.g. after changing a character sheet and wanting the new image to take effect), use generate_shot_frame (single-shot regeneration with platform identity anchor), not this tool, and definitely not a self-made image via upload_shot_frame. ★**This tool generates only first frames by default; framing is a two-pass process**: after first frames finish, you must call the free tail_frame_plan once—it tells you, using the platform’s own criteria, which shots need independent tail frames (end state ≠ start state: large camera move/object released/state change, about 30%; you cannot guess this yourself), then batch-fill with frame_type=last_frame. Production data: in 32 episodes, 30 generated only first frames for the whole episode, and 23 proceeded all the way to video: those shots had only one first-frame anchor when generating video, so the model freely invented the end state. shots_needing_last_frame in this tool’s response is this count; if it is not 0, do not go straight to review_frames. ★frames_planned in the response is **planned count, not successful count**—this endpoint returns before the backend dispatch loop starts. Real progress is only in get_storyboards first_frame_image / get_jobs per-item generation records; insufficient balance (402) aborts the whole batch, and polling forever will not produce results—check balance instead of continuing to wait. ★★**If a few shots repeatedly fail while all others are ready**: that is not “not enough waiting”; those shots are being repeatedly rejected by content gates. Check fail_reason in get_storyboards (repeat_rejected / diagnosis_required / needs_content_fix / contract_rejected). If diagnosis_required, first diagnose existing candidates per fail_hint; if audit is wrong, re-audit first; if evidence is insufficient, re-check first; do not redraw unchanged or rewrite the script on your own. Then **run run_precheck** (can be run after the fact; it will tell you what contradiction it is), follow its hints to use update_shot to change shot size/description/bound characters, then regenerate. Do not keep spinning generate_frames, and do not send the customer to external tools to make images—external images bypass identity anchors and frame audit, so faces/costumes/style will drift.\n★【Storyboard review hard gate · free】Before this step you must call review_storyboards first: relay every returned finding to the customer verbatim (each with code=issue type, shots=hit shot numbers, action=which tool to use to fix), then pass review_token into this tool. Without review it is rejected with 400. If content changes after review → token auto-invalidates; just review again (still free). error findings block by default; only if the customer is informed and insists on continuing as-is may you pass acknowledge_review:true—pushing ahead with issues is likely to produce a junk video and still charges normally (acknowledge_review only means the customer personally agreed; any execution mode requires explicit customer consent, including autopilot). In autopilot steps, only whitelisted heuristic errors can pass with auto_acknowledge:true (platform decides; if not whitelisted returns 400 AUTOPILOT_MUST_ASK: must_ask_customer=true means pause and ask customer; false = self-fix per action and re-review). ★Gray-release dramas also require you (agent) to personally QC: inspect materials item by item per agent_qc returned by review_storyboards, answer every checklist item, and submit via submit_qc_report before this token can be used (not submitted → 400 agent_qc_required; report has issues → blocked by default just like error).\n★【Asset-layer hard gate · free】You must also run review_assets first (character appearance images/scene images/prop images) and pass its review_token as asset_review_token here (coexists with storyboard-layer review_token; both are required; gray-release dramas missing it will 400 and name review_assets). Generating frames does not invalidate the asset token. ⚠️ Batch quote confirmation flow: first call the corresponding quote_* tool to get estimated_points and quote_id, then call this tool with quote_id (quote confirmation depends on execution mode: professional mode / unconfirmed plan / this step controlled by customer → explain to customer and proceed only after customer agrees; do not decide for them; this step in autopilot → do not ask customer, follow get_production_plan autopilot.default_decisions, platform records it in get_autopilot_log). Autopilot-step quotes must be within the hard budget cap; if blocked by 402 BUDGET_WOULD_EXCEED, stop and ask the customer. ★**Image-generation quotes (character sheets/scene images/frame generation) provide two numbers**: estimated_points is the **upper bound** (estimated using the maximum reference-image count for that model, ensuring you do not start with an underbudget and hit 402 midway); typical_points in the same response is the **typical cost**. Tell the customer both—only saying the upper bound makes it seem much more expensive (the full-reference upper bound can exceed typical by 2x+), while only saying the typical value may leave insufficient balance. For fixed-price models they are equal; then one number is enough. Video-generation quote and charge use the same function; this range does not exist.",
|
|
57
|
-
"quote_shot_frame": "Quote: how many credits to redraw/fill **one frame of one shot** (one frame = one image). Returns estimated_points, quote_id. Zero cost. Use this when the customer says \"shot N is wrong/needs changes\", instead of using another image platform and then upload_shot_frame. ★Response includes billing_kind/unit_points(actual billing tier and unit price); if you will switch models in generate_shot_frame, pass the same image_model when quoting. ★Both sides must pass the same image_model — mismatch is rejected directly (400 IMAGE_MODEL_MISMATCH), because the model determines the billing tier; different sources mean \"estimate ≠ charge\". Passing neither on both sides also counts as consistent (uses the drama setting). Deprecated models (all FLUX series) are always rejected; do not pass them. ★Returns two numbers: estimated_points is the **upper bound** (estimated by maximum reference-image count; prepare this balance to avoid mid-run 402), typical_points is the **usual cost**. Tell the customer both; quoting only the upper bound makes it look much more expensive. For fixed-price models (e.g. Nano Banana series), they are equal.",
|
|
58
|
-
"generate_shot_frame": "After confirmation, generate or regenerate the frame for **one shot** (async). This is the proper path to fix a shot image: the platform will carry this shot’s character identity anchors, scene/prop reference images, style anchor, and frame audit; regenerated images stay consistent with the whole film. Using external tools to generate then upload bypasses this entire chain, so character/clothing/style will inevitably drift. Regeneration overwrites the shot’s existing frame image (including prior uploads) and marks this shot’s video as needing regeneration. A last frame requires this shot’s first frame to be ready (otherwise use first_frame or both first). Completion criterion: poll get_storyboards and watch this shot’s first_frame_image/last_frame_image change.\n★Inherited reopen (reopen_pair_id): if get_storyboards returns this field on a shot, pass it through unchanged to reroll only the actually problematic side among first/last frames—the other previously generated candidate is preserved as-is, not regenerated and not charged again. When passing it, you no longer need frame_type (it will be ignored; the platform decides which side to regenerate); quote_id still must come from quote_shot_frame (frame_type may be first_frame or last_frame; single-frame price is the same). If the shot has no reopen_pair_id field (inheritance conditions not met), do not pass this parameter; use normal frame_type retry.\n★★If generating a last frame is blocked with “this shot is marked as state changed, but nowhere says what it looks like at the end”: the correct fix is to use update_shot to write the ending state into last_frame_prompt, then generate—**do not simply add allow_missing_terminal and force it**. For this type of shot, generating a last frame as-is historically succeeds only 9.4% of the time (40.2% when an end-state description exists), so forcing it will mostly waste one charge. Only pass that parameter when you confirm this shot is intended to look “almost unchanged”.\n★One-click final cut hosted flow: the same shot may regenerate frames at most 3 rounds (one call counts as one round; both also counts as one round). At the limit, returns **409 AUTOPILOT_SHOT_REGEN_LIMIT** (not dispatched, not charged, quote not consumed)—do not bypass with another tool. Stop and ask the customer: if the customer agrees to more regeneration, quote and generate normally with customer_approved_more_regens:true (grants another limit); if the customer accepts the current state, proceed downward, and the next paid call must include acknowledge_review:true to record confirmation. Professional mode and customer-controlled stages are not subject to this limit.\n★【Storyboard review hard gate · free】Before this step you must call review_storyboards: tell the customer every returned finding verbatim (each with code=issue type, shots=hit shot numbers, action=which tool to use for fixing), then pass review_token into this tool. If not reviewed, it will be rejected with 400. If content changes after review → token auto-invalidates; just re-review once (still free). error findings block by default; only when the customer is informed and insists on continuing as-is may you pass acknowledge_review:true—pushing ahead with known issues is likely to produce unusable footage and still charges normally (acknowledge_review only means the customer personally agreed; every execution mode requires explicit customer consent, hosted included). In hosted stages, only allowlisted heuristic errors may pass with auto_acknowledge:true (platform decides; if not allowlisted, returns 400 AUTOPILOT_MUST_ASK: must_ask_customer=true means pause and ask the customer, false = self-fix according to action and re-review). ★Grayscale dramas also require you (agent) to personally QC: inspect assets item by item per agent_qc returned by review_storyboards, answer the checklist line by line, and submit via submit_qc_report before this token can be used (not submitted → 400 agent_qc_required; problematic report → blocks by default just like error).\n★【Asset-layer hard gate · free】You must also run review_assets first (character sheet images / scene images / prop images), and pass its review_token as asset_review_token (coexists with the storyboard-layer review_token; both are required; grayscale dramas missing it get 400 naming review_assets). Generating frames does not invalidate the asset token. ⚠️ Batch quote confirmation flow: first call the corresponding quote_* tool to get estimated_points and quote_id, then call this tool with quote_id (quote confirmation depends on execution mode: professional mode / unconfirmed plan / customer-controlled stage → explain to the customer and proceed only after customer approval; hosted stage → do not ask the customer, follow get_production_plan autopilot.default_decisions, and the platform records it in get_autopilot_log). Hosted-stage quotes must stay within the hard budget cap; if blocked by 402 BUDGET_WOULD_EXCEED, stop and ask the customer. ★**Image-generation quotes (character sheet / scene image / frame generation) return two numbers**: estimated_points is the **upper bound** (estimated using that model’s maximum reference-image count, ensuring you do not start with an underbudgeted run that hits 402 midway); typical_points in the same response is the **typical cost**. Tell the customer both—only saying the upper bound makes it look much more expensive (the max-reference upper bound can exceed 2× the typical value), while only saying the typical value may leave insufficient balance. For fixed-price models they are equal, so one number is enough. Video-generation quote and charge use the same function; no such range exists.",
|
|
57
|
+
"quote_shot_frame": "Quote: how many credits to redraw/fill **one frame of one shot** (one frame = one image). Returns estimated_points, quote_id. Zero cost. Use this when the customer says \"shot N is wrong/needs changes\", instead of using another image platform and then upload_shot_frame. ★Response includes billing_kind/unit_points(actual billing tier and unit price); if you will switch models in generate_shot_frame, pass the same image_model when quoting. ★Both sides must pass the same image_model — mismatch is rejected directly (400 IMAGE_MODEL_MISMATCH), because the model determines the billing tier; different sources mean \"estimate ≠ charge\". Passing neither on both sides also counts as consistent (uses the drama setting). Deprecated models (all FLUX series) are always rejected; do not pass them. ★When the first frame is generated (first_frame/both) the response includes continuity: follows_previous_shot=true means the previous shot's last frame will be pinned as reference image #1 (carrying over that shot's people, pose and camera position); note explains why. If this shot should not continue from the previous one (jump cut, scene change, a detail close-up of only hands/props, etc.), pass continuity_mode:'independent' on both the quote and the generate call. ★Returns two numbers: estimated_points is the **upper bound** (estimated by maximum reference-image count; prepare this balance to avoid mid-run 402), typical_points is the **usual cost**. Tell the customer both; quoting only the upper bound makes it look much more expensive. For fixed-price models (e.g. Nano Banana series), they are equal. ★With frame_type=both, if the platform judges this shot needs no independent last frame (end ≈ start, no camera move) it generates only the first frame: the quote returns frames_to_generate=1, charges only the first frame, and includes last_frame_skipped explaining why — **tell the customer verbatim that no last frame will be made**. If the customer really wants a last frame (e.g. a camera move whose start and end differ), pass force_independent_last_frame:true on both the quote and the generate call.",
|
|
58
|
+
"generate_shot_frame": "After confirmation, generate or regenerate the frame for **one shot** (async). This is the proper path to fix a shot image: the platform will carry this shot’s character identity anchors, scene/prop reference images, style anchor, and frame audit; regenerated images stay consistent with the whole film. Using external tools to generate then upload bypasses this entire chain, so character/clothing/style will inevitably drift. Regeneration overwrites the shot’s existing frame image (including prior uploads) and marks this shot’s video as needing regeneration. A last frame requires this shot’s first frame to be ready (otherwise use first_frame or both first). Completion criterion: poll get_storyboards and watch this shot’s first_frame_image/last_frame_image change. The receipt for a first frame includes continuity (whether this run continues from the previous shot, and why); continuity_mode must match the quote, otherwise 409 — re-quote.\n★Inherited reopen (reopen_pair_id): if get_storyboards returns this field on a shot, pass it through unchanged to reroll only the actually problematic side among first/last frames—the other previously generated candidate is preserved as-is, not regenerated and not charged again. When passing it, you no longer need frame_type (it will be ignored; the platform decides which side to regenerate); quote_id still must come from quote_shot_frame (frame_type may be first_frame or last_frame; single-frame price is the same). If the shot has no reopen_pair_id field (inheritance conditions not met), do not pass this parameter; use normal frame_type retry.\n★★If generating a last frame is blocked with “this shot is marked as state changed, but nowhere says what it looks like at the end”: the correct fix is to use update_shot to write the ending state into last_frame_prompt, then generate—**do not simply add allow_missing_terminal and force it**. For this type of shot, generating a last frame as-is historically succeeds only 9.4% of the time (40.2% when an end-state description exists), so forcing it will mostly waste one charge. Only pass that parameter when you confirm this shot is intended to look “almost unchanged”.\n★One-click final cut hosted flow: the same shot may regenerate frames at most 3 rounds (one call counts as one round; both also counts as one round). At the limit, returns **409 AUTOPILOT_SHOT_REGEN_LIMIT** (not dispatched, not charged, quote not consumed)—do not bypass with another tool. Stop and ask the customer: if the customer agrees to more regeneration, quote and generate normally with customer_approved_more_regens:true (grants another limit); if the customer accepts the current state, proceed downward, and the next paid call must include acknowledge_review:true to record confirmation. Professional mode and customer-controlled stages are not subject to this limit.\n★【Storyboard review hard gate · free】Before this step you must call review_storyboards: tell the customer every returned finding verbatim (each with code=issue type, shots=hit shot numbers, action=which tool to use for fixing), then pass review_token into this tool. If not reviewed, it will be rejected with 400. If content changes after review → token auto-invalidates; just re-review once (still free). error findings block by default; only when the customer is informed and insists on continuing as-is may you pass acknowledge_review:true—pushing ahead with known issues is likely to produce unusable footage and still charges normally (acknowledge_review only means the customer personally agreed; every execution mode requires explicit customer consent, hosted included). In hosted stages, only allowlisted heuristic errors may pass with auto_acknowledge:true (platform decides; if not allowlisted, returns 400 AUTOPILOT_MUST_ASK: must_ask_customer=true means pause and ask the customer, false = self-fix according to action and re-review). ★Grayscale dramas also require you (agent) to personally QC: inspect assets item by item per agent_qc returned by review_storyboards, answer the checklist line by line, and submit via submit_qc_report before this token can be used (not submitted → 400 agent_qc_required; problematic report → blocks by default just like error).\n★【Asset-layer hard gate · free】You must also run review_assets first (character sheet images / scene images / prop images), and pass its review_token as asset_review_token (coexists with the storyboard-layer review_token; both are required; grayscale dramas missing it get 400 naming review_assets). Generating frames does not invalidate the asset token. ⚠️ Batch quote confirmation flow: first call the corresponding quote_* tool to get estimated_points and quote_id, then call this tool with quote_id (quote confirmation depends on execution mode: professional mode / unconfirmed plan / customer-controlled stage → explain to the customer and proceed only after customer approval; hosted stage → do not ask the customer, follow get_production_plan autopilot.default_decisions, and the platform records it in get_autopilot_log). Hosted-stage quotes must stay within the hard budget cap; if blocked by 402 BUDGET_WOULD_EXCEED, stop and ask the customer. ★**Image-generation quotes (character sheet / scene image / frame generation) return two numbers**: estimated_points is the **upper bound** (estimated using that model’s maximum reference-image count, ensuring you do not start with an underbudgeted run that hits 402 midway); typical_points in the same response is the **typical cost**. Tell the customer both—only saying the upper bound makes it look much more expensive (the max-reference upper bound can exceed 2× the typical value), while only saying the typical value may leave insufficient balance. For fixed-price models they are equal, so one number is enough. Video-generation quote and charge use the same function; no such range exists. ★frames_dispatched in the receipt is the number of images actually dispatched; when the last frame of a both request is judged unnecessary the receipt includes skipped_frames (not generated, not charged) — relay it to the customer verbatim.",
|
|
59
59
|
"quote_videos": "Quote: how many credits to batch-generate videos for an episode (same function as actual charge, relatively accurate). Returns estimated_points, quote_id. Zero cost. ⚠️ Video is a large expense; clearly tell the user the credits and wait for confirmation.\n★**Only counts shots actually dispatched this time**: shots that already have video are skipped during whole-episode resume, not regenerated and not priced—shots_total = shots priced this time (not total shots in episode), shots_already_done = shots with video skipped this time. Exception: if any shot in a scene group lacks video, the **entire group is regenerated**, and already-generated shots inside the group are also priced. All shots already have video ⇒ 400(no dispatchable shots; use regenerate_shot_video to regenerate a shot). If any shot's video is cleared after quoting (becomes pending video), generate_videos returns 409 requiring a new quote; it will not charge for shots outside the quote.\n★**Specify video engine per shot**: pass shot_engines={storyboard id: engine} to switch engines only for those shots and only for this whole-episode generation (does not change drama-level video_engine; other shots unchanged). Quote prices per shot accordingly; quote_id pins the engines, and generate_videos dispatches exactly them—changing engine requires a new quote. Receipt shot_engines = actual applied mapping; shot_engines_ungrouped = scene groups **split into per-shot generation** because they include specified shots (scene-group duration and multi-keyframes are planned for the drama engine; generating the whole group with a changed engine would lose shots/keyframes; after splitting, other shots in the group still generate per-shot with the drama engine, losing group-level one-pass continuity, so do not split a good group for one shot—check get_scene_group_plan first). Selected engine must support this drama's resolution (seedance-2.5 only 480p/720p; hailuo-3 only 720p/1080p; wan3.0/wan3.0-prime 480p~1080p), and shot duration must not exceed that engine's single-shot limit (seedance-2.5/wan3.0 30s, hailuo-3 15s), otherwise 400 (vendors truncate overlong shots; either switch engine or split_shot). Shots with specified engines must be generated this time: whole-episode generation will not regenerate shots already having video, so specifying an engine for one ⇒ 400; a split per-shot scene group only counts group members without video. If you only want to regenerate a few shots that already have video, using quote_regenerate_shot_video with model is cheaper. ★The response may carry an **unchained-seam hint** (does not affect review_token / quote / status codes): review_frames and generate_videos return unchained_seam_advisory; quote_videos returns an advisories entry with code=unchained_seams. seams lists adjacent seams (from_shot→to_shot) that chain_frames would chain but that are not chained yet: status=no_stamp (never chained) / pending (a chaining was dispatched but has not landed, or its audit has no verdict yet) / stale_anchor (the previous chaining anchor is no longer valid: the upstream shot's last frame was regenerated after chaining, so the seam must be re-chained) / join_failed (the last chaining regeneration was rejected / failed / superseded and never landed) / audit_failed (the chaining landed but the continuity audit judged it discontinuous — see seam_failed_dims in get_storyboards) / first_frame_regenerated (the downstream first frame was regenerated after the seam was reviewed, bypassing the chaining path, so the old chaining no longer counts) / not_linked (the planner judges the seam unchained but the cause is not evidenced); re-chain all of them per the plan; video_locked lists the same kind of seam where the downstream shot already has a video — chain_frames will not touch those, so fix them per shot with chain_shot_from_prev / chain_shot_from and then regenerate_shot_video (quote first). If seams is non-empty before generating videos, run chain_frames(dry_run:true) first, tell the customer the plan and price, execute after they agree, then re-run review_frames.",
|
|
60
60
|
"generate_videos": "After confirmation, batch-generate videos: one backend chain runs the full episode; if balance is insufficient it auto-aborts the whole chain (prevents duplicate charging). Requires first frames already generated for this episode (otherwise rejected). Poll get_storyboards; completion = video_url filled shot by shot.\n★【Hard gate: shot image review · free】Before this step you must call review_frames first: report the returned findings to the customer verbatim, item by item (each with code=issue type, shots=hit shot numbers, action=which tool to use to fix), then pass review_token into this tool. No review → 400 rejection. If content changes after review → token auto-invalidates; review once again (still free). If there is error, block by default; only if the customer is informed and insists on continuing as-is, pass acknowledge_review:true—pushing ahead with issues will very likely produce unusable footage and still charges normally (acknowledge_review only means the customer personally agreed; every execution mode requires explicit customer consent, including autopilot). In autopilot steps, only whitelisted heuristic errors may be released with auto_acknowledge:true (platform decides; if not whitelisted, returns 400 AUTOPILOT_MUST_ASK: must_ask_customer=true means pause and ask customer, false = self-fix per action then re-review). ★ Gray-release dramas also require you (agent) to personally QC: per review_frames returned agent_qc, inspect assets item by item, answer every checklist item, and submit via submit_qc_report before this token can be used (not submitted → 400 agent_qc_required; report has problems → blocked by default same as error). ⚠️ Batch quote confirmation flow: first call the corresponding quote_* tool to get estimated_points and quote_id, then call this tool with quote_id (quote confirmation follows execution mode: professional mode / unconfirmed plan / this step controlled by customer → explain to customer and proceed only after customer agrees; do not decide for customer; this step autopilot → do not ask customer, execute per get_production_plan autopilot.default_decisions, platform records it in get_autopilot_log). Autopilot-step quotes must stay within the hard budget cap; if blocked by 402 BUDGET_WOULD_EXCEED, stop and ask customer. ★ **Image-generation quotes (character sheet / scene image / frame generation) give two numbers**: estimated_points is the **upper bound** (estimated using that model's max reference-image count, ensuring you do not start with too-low budget and hit 402 mid-run); typical_points in the same response is the **usual cost**. Tell the customer both—only stating the upper bound makes it look much more expensive (with max reference images, the upper bound can exceed 2x the typical value); only stating the typical value may leave balance insufficient. For fixed-price models the two are equal; then one number is enough. Video-generation quote and charge use the same function; no range exists.\n★【Post-completion QC · free】After generation, wait for it to persist (check video_status in get_storyboards / get_pipeline_status), then call review_videos to review video and dubbing layers (missing video / video made from old frames / hard cut at ending / unexpected human voice / missing dubbing / voice timbre unassigned / original voice line expired); fix and re-review; then personally inspect each shot and listen to dubbing per agent_qc (action correct, face stable, lines complete, voice right), submit via submit_qc_report; compose_episode must carry its review_token. ★The response may carry an **unchained-seam hint** (does not affect review_token / quote / status codes): review_frames and generate_videos return unchained_seam_advisory; quote_videos returns an advisories entry with code=unchained_seams. seams lists adjacent seams (from_shot→to_shot) that chain_frames would chain but that are not chained yet: status=no_stamp (never chained) / pending (a chaining was dispatched but has not landed, or its audit has no verdict yet) / stale_anchor (the previous chaining anchor is no longer valid: the upstream shot's last frame was regenerated after chaining, so the seam must be re-chained) / join_failed (the last chaining regeneration was rejected / failed / superseded and never landed) / audit_failed (the chaining landed but the continuity audit judged it discontinuous — see seam_failed_dims in get_storyboards) / first_frame_regenerated (the downstream first frame was regenerated after the seam was reviewed, bypassing the chaining path, so the old chaining no longer counts) / not_linked (the planner judges the seam unchained but the cause is not evidenced); re-chain all of them per the plan; video_locked lists the same kind of seam where the downstream shot already has a video — chain_frames will not touch those, so fix them per shot with chain_shot_from_prev / chain_shot_from and then regenerate_shot_video (quote first). If seams is non-empty before generating videos, run chain_frames(dry_run:true) first, tell the customer the plan and price, execute after they agree, then re-run review_frames.",
|
|
61
61
|
"compose_episode": "Stitch all shot videos of one episode into one final cut (final stitching). **Free** (pure stitching, no quote confirmation required), async in backend. Before starting, a final-stitch precheck runs: shots missing video or video tasks still generating will hard-block with 400 and list the problem shots (blockers); fix them and retry. If you really want a partial final cut, pass force=true (shots missing video are skipped, final cut lacks shots, logged). advisories in the response (duration drift/orphan tasks/missing TTS/post_production_pending unfinished post-production effects) are warnings only, not blockers; handle them one by one before stitching. After starting, poll with get_final_cut.\n★【Video and dubbing review hard gate · Free】Before this step you must call review_videos: relay the returned findings to the customer verbatim one by one (each with code=issue type, shots=hit shot numbers, action=which tool to use to fix), then pass the review_token into this tool. If not reviewed, 400 rejection. If content changed after review → token auto-invalidates; just review again (still free). error blocks by default; only if the customer is informed and insists on proceeding as-is may you pass acknowledge_review:true — proceeding with known issues will likely produce unusable video and still charge credits as usual (acknowledge_review only means the customer personally agreed; every execution mode requires explicit customer consent, autopilot included). In autopilot, only whitelisted heuristic errors may pass with auto_acknowledge:true (platform decides; if not whitelisted, returns 400 AUTOPILOT_MUST_ASK: must_ask_customer=true means pause to ask customer, false = self-fix per action and re-review). ★ For gray rollout dramas, you (agent) must personally QC: inspect materials item by item per agent_qc from review_videos, answer every checklist item, and submit via submit_qc_report before this token can be used (not submitted → 400 agent_qc_required; report has issues → blocked by default like error).\n★★【Pre-compose checks · after review_videos passes, before compose_episode】Don't hunt for problems by repeatedly exporting the whole cut and trying transitions by hand — per-shot and seam problems have dedicated tools; run them in order before stitching: ① portraits / turnarounds / scene images / shot frames were changed in this episode → first get_stale_portrait_frames(episode_id, free) to see which shots' in-use frames are still based on old assets; for shots where it is unclear which version to use, get_asset_versions(storyboard_id, free) shows each shot's versions and dependencies (unknown means insufficient evidence, not stale; regenerating is paid, so give the list to the customer and let them decide); ② scan_intra_shot_cuts(episode_id, free) finds shots where the vendor hard-cut inside a single shot; ③ per shot, recommend_trim_window(storyboard_id, free) shows a frozen tail and the effective action window (shots inside a scene group return applicable=false — skip them); apply a recommendation with trim_shot (free); ④ audit_seams(episode_id) checks editing continuity at seams between adjacent shots: by default dry_run only lists what would be audited (free); actually running it is billed by real text-token usage — tell the customer, and only after they explicitly accept pass dry_run:false + confirm_usage_billing:true; read the result from seam_review in get_storyboards; ⑤ then compose_episode. If the final cut shows jump cuts / dragging tails / seams that don't match, go back to these tools to locate the shots and fix only those — don't keep re-exporting the whole cut by trial and error. These checks are advisory, not gates; trimming and seam audits don't invalidate the review_videos token.\n★【Post-completion QC · Free】After the final cut is ready, run review_final_cut (missing shots/subtitles not fitting/identity anchors/axis jumps/typos; proofread=false means no credits charged), tell the customer the conclusion; call confirm_delivery_acceptance only after customer confirmation (delivery acceptance requires explicit customer consent in every execution mode, autopilot included). force only bypasses the final-stitch precheck, not the review gate.",
|
|
@@ -138,9 +138,9 @@
|
|
|
138
138
|
"scan_voice_consistency": "★For original-voice dramas (video has built-in human speech), run this when the customer reports \"the same character's voice differs across shots / voice drifted\". Free (local inference, no vendor call). For each shot with dialogue, listens to vendor-generated human speech: whether the dialogue was fully spoken, and whether the voice resembles the timbre anchor bound to that character. **Async**: returns immediately; background full-episode scan takes about 10 minutes. Only one scan per episode can run at the same time (repeat calls return started=false). By default skips shots already scanned for the current video; rescan=true rescans all. Use get_voice_consistency to check progress and per-shot results.",
|
|
139
139
|
"get_voice_consistency": "Check progress and per-shot results of the voice consistency scan (started by scan_voice_consistency). Free. summary.voice_mismatch = shot numbers whose voice does not resemble the character timbre anchor (focus on these); dialogue_issues = shots where dialogue was incomplete/wrong/extra speech appeared; not_scanned_or_stale = not scanned yet or video changed and needs rescan. speaker_verdict=uncertain means the human speech is too short to judge; it is not an issue. For shots with inconsistent voice: first use get_pipeline_status native_voice_anchor to confirm the character has a bound voice, then regenerate_shot_video.",
|
|
140
140
|
"scan_dialogue_coverage": "★When the customer reports \"cut before the line finished / only half the dialogue was spoken\", run this first. Default **free, zero charge** (read-only access to persisted transcription audit results). Compares each original-voice shot's video audio track against the dialogue at word level, and reports conclusions by family: truncated (stops halfway through the line) / off_script (most spoken content is not the dialogue: improvising, repeating previous shot, only ambience) / extra_speech (dialogue is fully spoken but extra speech is added) / minor_gap (sporadic missing words, transcription error, ignore) / ok. ★Interpretation: the three reportable families have **different remedies**; do not simply lengthen every shot—measurements show 21% of shots with sufficient length still fail to finish the line, so \"too short\" is rarely the real cause (the platform already auto-raises duration by dialogue when saving storyboards). The correct fix for truncated/off_script is regenerate_shot_video (how much the vendor says is random each time; rerolling often gets the full line); if the same drama repeatedly has off_script, switch engine. ★never_audited is the most important section of this report: those shots have never been checked; \"not checked\" does not mean \"no issue\". rescan=true will run ASR comparison for them (compute-intensive, not instant; limit controls per-run cap), default does not run. TTS-dubbed shots are out of scope (TTS necessarily reads the full line; low coverage can only be transcription error). If the same episode also has \"cuts too fast\", that is a separate issue; run scan_intra_shot_cuts.",
|
|
141
|
-
"update_shot": "Shot-by-shot edit: change a single storyboard shot's text content (shot size/action/dialogue/visual description/camera movement, etc.), facial expression (expression_hint), duration (duration), final cut speed (speed_factor), character binding (character_ids), prop binding (prop_ids; full overwrite, [] clears—use it to fix a prop missed at import instead of re-importing the whole episode; edits do not auto-regenerate frames/video), voice-over marker (character_presence), and wardrobe binding (active_wardrobe_id / appearance_wardrobes). Send only fields to change; all others stay unchanged. ★Any shot edit (accepted or rejected) invalidates unconsumed quotes covering this shot; generation then returns 409 QUOTE_INVALIDATED—edit first, read back to verify, then quote. **Free** (pure text DB write). ★Changing dialogue automatically invalidates generated TTS voice-over and subtitles for this shot (tts must be regenerated); text edits do not auto-regenerate images/video. To make visuals follow text changes, edit then regen the corresponding shot. Use get_storyboards to inspect results (each shot includes character_ids / character_bindings / scene_id / prop_ids / active_wardrobe_id / appearance_wardrobes). ★★【Change clothes here, not in text】What appears in image generation is determined by **wardrobe binding**: single-character shots use active_wardrobe_id (one outfit for the whole shot); multi-character shots use appearance_wardrobes (per character). Writing \"wearing X clothes\" in description/action will not change clothes. Use list_wardrobe for wardrobe id; edits do not auto-regenerate images. To update visuals, regenerate this shot's first frame then video. ★★For native-audio shots (vendor-native audio), after changing dialogue the shot video is marked \"needs regeneration\"—because spoken lines are **baked into the video audio**. If you final-compose without regeneration, the final cut still speaks the old line (typical symptom: dialogue seems to have moved to another shot). compose_episode lists these shots under advisory `stale_video_after_edit`; correct handling is regenerate_shot_video before final compose. ★You may also directly edit this shot's four prompt bodies (image_prompt/video_prompt/first_frame_prompt/last_frame_prompt): read current values with get_shot_prompts first; do not overwrite from scratch. @char:N / @scene:M in the body are supplemental reference markers for image generation; keep them unchanged. ★Which character sheet is injected is determined by character_ids, and background by scene_id: deleting markers will not remove already-bound people from the image. To make someone not appear, edit character_ids; if they are voice-only, set character_presence to voice_only. Conversely, do not write @char markers for unbound characters—this will inject their image. ★★【If last-frame generation is blocked, edit here】If last-frame generation reports \"this shot is marked as a state change, but nowhere describes what it looks like at the end\" (TERMINAL_DESC_GATE), fix by writing **what the final image should look like** into this shot's last_frame_prompt, then regenerate the last frame. Do not retry image generation—shots of this type (action_motion_class=state_change without terminal state) historically succeed at 9.4%, versus 40.2% with terminal-state description; without adding the description, the vendor prompt has no terminal-state section, so it still draws the same as the first frame, is rejected again, and each regeneration still charges normally. terminal_desc_missing=true from get_shot_prompts is this signal.",
|
|
141
|
+
"update_shot": "Shot-by-shot edit: change a single storyboard shot's text content (shot size/action/dialogue/visual description/camera movement, etc.), facial expression (expression_hint), duration (duration), final cut speed (speed_factor), character binding (character_ids), prop binding (prop_ids; full overwrite, [] clears—use it to fix a prop missed at import instead of re-importing the whole episode; edits do not auto-regenerate frames/video), voice-over marker (character_presence), and wardrobe binding (active_wardrobe_id / appearance_wardrobes); read back shot size / angle / camera movement / edit intent and prompt text per shot with get_shot_prompts. Send only fields to change; all others stay unchanged. ★Any shot edit (accepted or rejected) invalidates unconsumed quotes covering this shot; generation then returns 409 QUOTE_INVALIDATED—edit first, read back to verify, then quote. **Free** (pure text DB write). ★Changing dialogue automatically invalidates generated TTS voice-over and subtitles for this shot (tts must be regenerated); text edits do not auto-regenerate images/video. To make visuals follow text changes, edit then regen the corresponding shot. Use get_storyboards to inspect results (each shot includes character_ids / character_bindings / scene_id / prop_ids / active_wardrobe_id / appearance_wardrobes). ★★【Change clothes here, not in text】What appears in image generation is determined by **wardrobe binding**: single-character shots use active_wardrobe_id (one outfit for the whole shot); multi-character shots use appearance_wardrobes (per character). Writing \"wearing X clothes\" in description/action will not change clothes. Use list_wardrobe for wardrobe id; edits do not auto-regenerate images. To update visuals, regenerate this shot's first frame then video. ★★For native-audio shots (vendor-native audio), after changing dialogue the shot video is marked \"needs regeneration\"—because spoken lines are **baked into the video audio**. If you final-compose without regeneration, the final cut still speaks the old line (typical symptom: dialogue seems to have moved to another shot). compose_episode lists these shots under advisory `stale_video_after_edit`; correct handling is regenerate_shot_video before final compose. ★You may also directly edit this shot's four prompt bodies (image_prompt/video_prompt/first_frame_prompt/last_frame_prompt): read current values with get_shot_prompts first; do not overwrite from scratch. @char:N / @scene:M in the body are supplemental reference markers for image generation; keep them unchanged. ★Which character sheet is injected is determined by character_ids, and background by scene_id: deleting markers will not remove already-bound people from the image. To make someone not appear, edit character_ids; if they are voice-only, set character_presence to voice_only. Conversely, do not write @char markers for unbound characters—this will inject their image. ★★【If last-frame generation is blocked, edit here】If last-frame generation reports \"this shot is marked as a state change, but nowhere describes what it looks like at the end\" (TERMINAL_DESC_GATE), fix by writing **what the final image should look like** into this shot's last_frame_prompt, then regenerate the last frame. Do not retry image generation—shots of this type (action_motion_class=state_change without terminal state) historically succeed at 9.4%, versus 40.2% with terminal-state description; without adding the description, the vendor prompt has no terminal-state section, so it still draws the same as the first frame, is rejected again, and each regeneration still charges normally. terminal_desc_missing=true from get_shot_prompts is this signal.",
|
|
142
142
|
"rederive_shot_contract": "Using this shot's **current** prompt body and character binding, let the platform re-derive the composition contract (how many visible people, whether the subject is a person or a partial/object, shot size). The contract itself is internal: cannot be read or edited directly. This tool only returns outcome: updated (changed and effective) / unchanged (derived result same as current) / rejected (derived result self-contradictory, not adopted, original contract kept) / no_candidate (no usable result, original contract kept) / stale (shot changed during derivation, result not written; call again after edits), plus note for next step. Insufficient credits returns 402. ★When to use: image generation/precheck/review repeatedly says the number of people is wrong, or a partial shot (hand/prop close-up) is treated as a full-person shot in generation or review, and you have already edited text or bindings—the autofiller only fills blanks and does not overwrite existing contracts; without this tool, edits will not enter the contract. ★Correct order: first update_shot to make the image text correct (who is visible, who is voice-only via character_presence voice_only, unbind anyone who should not appear from character_ids), then call this tool; calling without text edits usually returns unchanged. ★One text AI call, postpaid by token (same chain as autofill_storyboards); inform the customer before calling. ★Only changes this one contract field; does not touch dialogue/prompts/other specialized fields. Generated first/last frames are not auto-regenerated; to update visuals, regenerate frames for this shot (quote first). ★updated invalidates unconsumed frame/video quotes for this shot and the same episode; quote again afterward.",
|
|
143
|
-
"get_shot_prompts": "Read the four prompt **bodies** for one shot (image_prompt=first-frame image / video_prompt=dynamic performance / first_frame_prompt=what it looks like at start / last_frame_prompt=what it looks like at end), for direct fine-tuning then writing back with update_shot. Free. ★terminal_desc_missing=true in the response means this shot is marked as a \"state change\" but none of the three places describes the terminal state—last-frame generation will be blocked by the pre-gate. Fix by writing the end state into last_frame_prompt (do not retry image generation; retry will inevitably be rejected again and still charged). ★Also returns the current description (visual description)
|
|
143
|
+
"get_shot_prompts": "Read the four prompt **bodies** for one shot (image_prompt=first-frame image / video_prompt=dynamic performance / first_frame_prompt=what it looks like at start / last_frame_prompt=what it looks like at end), for direct fine-tuning then writing back with update_shot. Free. ★terminal_desc_missing=true in the response means this shot is marked as a \"state change\" but none of the three places describes the terminal state—last-frame generation will be blocked by the pre-gate. Fix by writing the end state into last_frame_prompt (do not retry image generation; retry will inevitably be rejected again and still charged). ★Also returns the current description (visual description), lighting (shot lighting) and sound_effect (shot sound effects)—review_storyboards forbidden-term matches are often in description / sound_effect, so read them here before editing; write lighting into lighting. ★Also returns the current shot_type (shot size) / angle / camera_movement / continuity_intent (edit intent)—after changing these with update_shot, read them back here to verify (the episode-wide get_storyboards does not include them); null = not set. ★Also returns expression_hint (author-specified facial expression for this shot; null=unspecified, platform infers from dialogue). Edit it with update_shot. expression_inferred is the storyboard AI's inferred expression when the script did not specify expression (read-only; null=no inference, or this shot's dialogue/action/mood/description/intensity changed and the inference is expired and no longer used); it has lower priority than expression_hint—if inference is unsatisfactory, write expression_hint with update_shot to override it. ★Per-shot on demand: read only the shot you edit (episode list get_storyboards does not include prompts). ★Returned asset_tokens are supplemental reference markers in the body (@char:N / @scene:M); keep them unchanged when rewriting. Which character sheet is injected is determined by bindings (character_ids / scene_id in get_storyboards); deleting markers will not remove bound characters. Markers with #variant are the only source for that variant image. Writing a marker for an unbound character will inject that character's image. ★This is the body layer in the storyboard sheet; during image/video generation the platform also appends identity anchors, consistency constraints, and reference-image instructions (not here, and you do not need to write them). Changing prompts does not auto-regenerate images/video; to update visuals, regen the corresponding shot.",
|
|
144
144
|
"rerender_episode": "Recompose the final cut from the current timeline (use after shot edits/cropping). **Free** (pure ffmpeg+COS), asynchronous in background.",
|
|
145
145
|
"replace_shot_dialogue": "Replace a shot's dialogue timbre/voice (transcribe + clone + redub). **Synchronous call**, returns product in about 1 minute, postpaid by usage with no debt. Requires this shot to have native-audio video + character voice character sheet audio. ★This is also the cheapest fix for \"this shot did not finish the line / spoke something else\": redub the full line with cloned voice and mute the native-audio segment, **without regenerating video**—charged at TTS tier (per thousand characters), orders of magnitude cheaper than regenerate_shot_video (billed per second; over a hundred credits per second at 720p). Tradeoff: the image lip-sync was performed to the original audio, so after replacement it may mismatch; almost lossless when lips are unclear (back view/long shot/voice-over), use caution on extreme close-ups. ★Product is automatically written back to the shot (returns persisted:true), but written back ≠ included in final cut: rely on productEffective from get_dialogue_repair_status—if true, rerender_episode to recompose; if false, first perform pendingCompose as instructed, then recompose, otherwise the final cut still uses old audio. ★If this shot already has a lip-sync product, the final cut prioritizes the lip-sync version, so replacing track will not take effect. For episode batch use repair_episode_dialogue.\n★Before writeback, the product is verified (same criteria as scan_dialogue_coverage): still truncated, repeated/extra speech (extra_speech), or not the line (off_script) → **not written back**, this cost automatically refunded, and error returns which category—these shots cannot be fixed by voice replacement; use regenerate_shot_video. On success, verify:verified=false means it could not be judged (transcription failed/line too short); it is still written back, but unverified, so listen yourself.",
|
|
146
146
|
"revoice_narration": "Replace the voice for a shot's **narration/voice-over** (or re-synthesize after editing narration text). **Does not regenerate video**: keeps visuals and on-screen dialogue, only mutes the narration segments, synthesizes them with the current narration voice, mixes back, then verifies. Synchronous call, charged at TTS tier (per thousand characters). ★Edit first, then call: to change voice, first set_character_voice for the \"narration\" character (or design_voice to create one); to change text, first update_shot the narration line in dialogue. ★Pure narration shots (only narration in this shot) work directly; **mixed shots** (on-screen dialogue plus narration) require sentence count to match the speech segments in the video. If not, it errors instead of guessing (a wrong guess could mute on-screen dialogue too)—then only regenerate_shot_video can fix it. ★If the dialogue field has no narration line, it errors directly; if the vendor randomly speaks in a no-dialogue shot, use replace_shot_dialogue mute_only. ★After writeback, the final cut uses it directly (no extra switch); rerender_episode is enough to recompose. If verification fails, it is not written back, and narration synthesis cost is not refunded.",
|
|
@@ -218,7 +218,7 @@
|
|
|
218
218
|
"chain_shot_from": "Use the first or last frame of **any shot** in the same episode as this shot's first frame. Two modes:\n· mode=copy(default, free): directly replace this shot's first frame with the source frame, pixel-identical—good for “return to the exact same image” or continuing the same camera position.\n· mode=reframe(deducts one image, must include quote_id from quote_chain_shot_from): regenerate the first frame anchored on the source frame and based on this shot's visual description—character/clothing/prop/lighting/scene continuity, while preserving this shot's own shot size and composition. Use this when the seam must connect while shot size changes.\n★If the source is not the previous shot's last frame (bookend / return to a previous image), the platform records the seam between this shot and the previous shot as an “intentional cut”, and automatic frame chaining will no longer overwrite it. If this shot already has video it will be marked for regeneration; if its first frame was uploaded by the customer or is finalized it will be rejected (409 reason=user-locked-frame, no image dispatched, no charge)—pass force:true only when overwriting it has explicit customer approval (required in every execution mode, including autopilot). force releases the upload / finalized protection and the new frame needs customer re-acceptance; for mode=reframe the quote must also carry force.",
|
|
219
219
|
"quote_align_prev_shot": "(Free quote) align_prev_shot regenerates **the previous shot's video** (deducts one video); quote before execution (quote confirmation follows execution mode: professional mode / unconfirmed plan / this step is customer-controlled → explain to the customer and proceed only after customer approval; do not decide for them; this step is autopiloted → do not ask the customer, execute per get_production_plan autopilot.default_decisions, and the platform records it in get_autopilot_log). Returns quote_id / estimated_points / prev_storyboard_id(which shot will be regenerated); if first-time portrait verification fee applies, kyc_first_time_points is listed separately.",
|
|
220
220
|
"align_prev_shot": "Seam-crack repair “align to previous shot”: this shot's first frame **does not change**; use it as the ending image and regenerate **the previous shot's video** in first/last-frame mode (previous shot's first frame unchanged), so the previous shot truly ends on this shot's opening image. Deducts one video and must include quote_id from quote_align_prev_shot. ★Use when the customer changed this shot's first frame (e.g. uploaded or regenerated a better one), but the previous shot's video is already done and you don't want to alter this shot's first frame to accommodate it. Do not use when neither shot has video yet—changing the first frame (chain_shot_from_prev / chain_shot_from) is cheaper. Async: poll get_storyboards for the previous shot's video_status.",
|
|
221
|
-
"get_scene_group_plan": "Get the scene group plan for an episode (how shots are grouped for continuous long shots). Free.",
|
|
221
|
+
"get_scene_group_plan": "Get the scene group plan for an episode (how shots are grouped for continuous long shots). Free. ★Check the top-level `active` first: false = long-take mode (scene_group_mode) is off for this drama, so `groups` is only a preview of how shots would be grouped once enabled and is **not in effect** — videos are generated and billed shot by shot, and regenerate_shot_video only touches that one shot; to use groups, enable long-take mode via update_project_settings first. When active is true, only groups with merged=true are generated in one pass.",
|
|
222
222
|
"quote_regenerate_scene_group": "Quote: how many credits to regenerate **one scene group** (one video request for the whole group, preserving intra-group continuity). Returns quote_id. No charge. shot_numbers must exactly equal the shot numbers of one group in get_scene_group_plan.\n★Optional video_engine: swap engine only for this whole-group regeneration (does not change the series-level video_engine); the quote is calculated with it and the quote_id pins it, so regenerate_scene_group will dispatch with it. The whole group is still one final cut, so total group duration must fit within that engine's single-segment limit (hailuo-3 15s; seedance-2.5/wan3.0 30s) and support this series resolution, otherwise 400—if so, use update_shot to set video_engine on individual shots (shots with it set will generate separately). Quote is calculated per shot (per-shot fallback if whole-group fails; per-shot is the upper bound); normal-path actual deduction is usually lower.",
|
|
223
223
|
"regenerate_scene_group": "After confirmation, regenerate one scene group (one video request for the whole group, async in background; poll each shot's video_url via get_storyboards). Grouping and engine are pinned by quote_id and cannot be changed here; if any shot in the group changes after quote, or grouping changes, the quote becomes invalid (409); just re-quote (free). ⚠️ Batch quote confirmation flow: first call the corresponding quote_* tool to get estimated_points and quote_id, then call this tool with quote_id (quote confirmation follows execution mode: professional mode / unconfirmed plan / this step is customer-controlled → explain to the customer and proceed only after customer approval; do not decide for them; this step is autopiloted → do not ask the customer, execute per get_production_plan autopilot.default_decisions, and the platform records it in get_autopilot_log). Autopiloted step quotes must stay within the hard budget cap; if blocked by 402 BUDGET_WOULD_EXCEED, stop and ask the customer. ★**Image-generation quotes (character sheet / scene image / frame generation) provide two numbers**: estimated_points is the **upper bound** (estimated by the model's max reference-image count, ensuring you won't start with an underbudget and get interrupted by 402 halfway); typical_points in the same response is the **usual cost**. Tell the customer both—only saying the upper bound makes it seem much more expensive (with max reference images the upper bound can exceed 2× the usual value), while only saying the usual cost may leave insufficient balance. For fixed-price models they are equal, so one number is enough. Video-generation quote and deduction use the same function; no such range exists.",
|
|
224
224
|
"generate_scene_groups": "Generate scene groups (group continuous shots; the foundation for continuous long shots / batch frame generation). Async in background.",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"get_frame_retry_diagnosis": "免费只读查询图片任务的连败诊断、证据任务 ID 和下一步动作。diagnosis_required 时先调用本工具:审计故障重审已有候选,未知原因先复核;不得原样重抽或擅自改剧本。★返回的 recovery_options 是出图失败后的三选一(按免费→免费→付费排序,needs_attention=false 时不必打扰客户):① adopt_rejected 从被拒/落选候选里挑审计误判的(get_frame_candidates→adopt_frame_candidate,candidates 是可采用张数);② upload_fixed 拿本镜平台候选局部修补后 upload_shot_frame;③ regenerate 按诊断改内容后 quote_shot_frame→generate_shot_frame。ask_customer=true 时三条都摆给客户由客户选,不许替客户放行或擅自付费重抽;failure_class=transient 是偶发失败、稍等按原输入重试即可,not_self_healable 是欠费/点数不足/配额满/模型不可用、重生也无用(regenerate.available=false),先处理账户或换模型。",
|
|
28
28
|
"get_image_dispatch": "免费只读查询一张镜头帧的派发台账:实际用了哪几张参考图、每张的用途与所属角色、是否送达模型、没送达或派发前被剔除的是哪一步因什么被剔(如时代预检点名的冲突物件),以及真正发给图片模型的最终提示词。用于回答「到底用了哪张图、为什么画面不像」;先查清再决定是否重出,别靠猜反复付费重抽。ledger=partial/none 表示该图生成于台账上线前,缺失字段如实为 null。",
|
|
29
29
|
"get_frame_candidates": "免费只读:一个镜头首帧/尾帧的**全部候选**(出图验收工作台同一份数据)。每张候选给原图地址(被拒的也在,可直接打开看原尺寸)、状态、是否为当前在用(adopted)、拒因 reject(main 主码 / code 具体病因 / details 明细 / class 分流:needs_content_fix=要改内容、content_retryable=内容问题但重掷约 1/3 能成、transient=审核没审成或偶发——不是画面不合格)、审计证据 audit(warnings 中文结论、expected 设计要求、derived_shot_type 画面推出的景别及依据、boxes 主体与身体部位在画面里的位置框;2026-10-07 前的候选无存档为 null,不代表审过)、以及这张图实际用了哪些参考图(references:用途/所属角色/是否送达)。storyboard.tail_endstate 是「尾帧≈首帧」检查结论(current=false 表示结论对应的不是现在这两张图)。★镜头反复被拒、或客户问「被拒的那几张到底什么样 / 为什么不采用」时先调它:逐张看原图和证据,再决定改分镜、改参考还是重掷——别盲目付费重抽。要看某张的最终提示词用 get_image_dispatch(generation_id)。客户看过原图确认画面没问题、是审计误判时,用 adopt_frame_candidate 人工采用(免费);manual_adoption 非空 = 该候选是人工放行的。recovery_options 按帧位给出失败后的三选一(挑误拒 / 修图上传 / 重生),与 get_frame_retry_diagnosis 同口径。",
|
|
30
|
-
"adopt_frame_candidate": "免费:人工采用一张已出完的首帧/尾帧候选(被审计拒掉 rejected、落选 dismissed,或曾经在用后被换下的 completed),作为本镜在用帧——审计误判时的人工兜底(例如作者契约写明的设定被判成冲突),也可随时换回之前那张。★必须先用 get_frame_candidates 让客户看过原图和拒因、客户明确同意采用后才调(采用被拒候选任何执行模式都须客户明确同意,托管也不例外)
|
|
30
|
+
"adopt_frame_candidate": "免费:人工采用一张已出完的首帧/尾帧候选(被审计拒掉 rejected、落选 dismissed,或曾经在用后被换下的 completed),作为本镜在用帧——审计误判时的人工兜底(例如作者契约写明的设定被判成冲突),也可随时换回之前那张。★必须先用 get_frame_candidates 让客户看过原图和拒因、客户明确同意采用后才调(采用被拒候选任何执行模式都须客户明确同意,托管也不例外);不许为了让流程走下去自行放行。★采用前先对照本镜分镜(get_storyboards 的 first_frame_prompt / last_frame_prompt / action_in / action_out / movement)确认:采首帧要是动作起点、采尾帧要是动作终点——首帧候选若已是动作终态(人已到位、动作已做完)或把运镜终点画进了起点,采用后视频里就没有动作过程,换一张或改提示词重出。只能采用本镜本帧位、已出完、有画面、且不是当前在用的那张;会在该候选上记录人工放行(谁/何时/原拒因),原拒因保留供统计。本镜已有视频的会标成待重生(视频是按旧帧出的,需 regenerate_shot_video)。本镜该帧是客户上传或已定稿的,要带 replace_user_frame:true 才会替换(并解除定稿)。同帧位有在途出图或本镜视频在途时返回 409,等它结束再采用。",
|
|
31
31
|
"get_stale_portrait_frames": "免费只读查询一集里哪些镜头的在用首帧/尾帧,是拿角色已被换掉的旧资产(旧定妆图、旧设定图、旧身体/发型图)画的。换定妆图后用它确认影响范围,再由客户决定重出哪些镜(重出要付费,本工具不改任何数据)。verdict=stale 必附证据:ledger-old-asset(派发台账直接记录用了旧图)/ references-previous-asset(参考图里有该角色以前的旧资产)/ portrait-born-after-frame(当前定妆图晚于该帧诞生);证不了的标 unknown 并给原因,不当作已过期。has_video=true 表示该镜视频也基于旧帧,重出帧后视频需重生。",
|
|
32
32
|
"get_asset_versions": "只读查询一个镜头的全部图片/视频版本、历史查看链接、依赖 ID 与版本哈希,以及已生成→与当前输入一致→审核有效→已采用四项独立事实。历史缺少依赖记录时显示未知,不补造快照。免费。video_lock 是客户锁定的已验收视频(lock_shot_video):locked=true 时这条按沿用算有效,frames_changed_since_lock=true 表示锁定后帧又改过但不需要重出。",
|
|
33
33
|
"lock_shot_video": "锁定某镜当前在用的视频为客户已验收版本(免费,不生成、不改素材)。用于客户明确说「这一镜就用这条」之后,首尾帧/场景/角色又被改过的情形:锁定后资产变动不再把这镜判过期——review_videos 不报 video_stale(改报 warning video_locked_frames_changed)、get_asset_versions 里这条 acceptance_locked=true 仍算当前有效(漂移原因照实列在 drift_while_locked)、原声剧声线 stale_shots 不列它、终拼预检不报编辑后未重生;regenerate_shot_video / edit_video_shot / repaint / reskin / 上传或清除实拍 / 整集 generate_videos 会替换它时一律 409 VIDEO_LOCKED。锁里冻结视频行 id 与它当时的生成输入(首尾帧 URL、prompt、参考清单)。只能锁当前在用的那条(传 generation_id 时必须正好是它,否则 409 NOT_CURRENT_VIDEO;本镜没视频 409 NO_VIDEO)。视频被别的路径换掉后锁自动失效(get_asset_versions 的 video_lock.broken=true)。★只有客户明确确认沿用才锁,不得把生成完成或模型判断当客户验收;要重出须客户同意后先 unlock_shot_video。",
|
|
@@ -51,11 +51,11 @@
|
|
|
51
51
|
"autofill_storyboards": "(推荐)AI 一键给全集(或 storyboard_ids 指定的几镜)分镜补全空缺字段,默认**只填空缺、不覆盖已有**(overwrite=true 才覆盖)。提升分镜完整性,出图前做。后台异步,文本步后付(按实际调 AI 的镜计费)。★跑之前先确认角色/场景/道具绑定无误(对照客户原稿逐镜核对 get_storyboards 的 character_ids / scene_id / prop_ids)。补全之后发现漏绑用 update_shot 补绑即可,**不要整集重导**——重导会替换分镜、补全结果作废、要重新付费。★**先 quote_autofill 报价**(同样的 overwrite / storyboard_ids),把 shots_to_fill 与 estimated_points / typical_points 告诉客户,**客户同意再跑**本工具。★跑完用 get_autofill_status 看回执(写了哪些字段各几镜、跳过几镜、还缺几镜契约)告诉客户——补全写的内部字段 get_storyboards 读不到,别让客户以为白扣。★拆镜落库时平台已自动补过一轮:只填空模式下已没有空缺的镜(六个叙事文本字段都已有、有台词的镜声音方向也已有,契约阀开时契约也已有)直接跳过,不调 AI、不扣费;overwrite:true 才会整集重跑并逐镜计费。★补全写的是叙事/节奏类内部字段与构图契约,get_storyboards / get_shot_prompts 不返回这些字段,回读看不到变化属正常,看 get_autofill_status 回执里的计数即可;它**不改**出图/视频提示词正文。★平台开启契约自动补全时,也会尝试给**没有构图契约**的镜补上契约(是否开启以导入回执 contract_coverage 的 note 为准;可见人数/主体范围/景别,出图与审核都按它判;默认 overwrite:false 时已有契约不动,**overwrite:true 会连已有契约一起重写**)——导入时关了 auto_complete、回执 contract_coverage 的 note 指向本工具的,出图前调一次。本集已有补全在跑时本次**不排队**(防重复点击重复扣费),新导入的镜要等 get_autofill_status 到 done 后再调。★想先小范围试跑看效果:传 storyboard_ids(1~50 个本集镜 id,用 get_storyboards 取),只补这些镜,其它镜不调 AI、不扣费;不传 = 整集。本集已有补全在跑时子集不启动,回执 started=false、reason=fill batch already running,等 get_autofill_status 到 done 再调。",
|
|
52
52
|
"enhance_shot_prompts": "(可选增强·★非必须·有副作用)AI 批量增强全集 image_prompt。★会**改写已有 prompt**(含手调的);且**务必 generate_frames 之前**做——出图后再改 prompt 会让图陈旧、要重生浪费钱。非跑通一部片的必需,客户点名再做。后台异步,文本步后付。",
|
|
53
53
|
"complete_ending_motifs": "(可选增强·★非必须·条件性)给结尾段补全缺失的视觉母题(嫁接视觉回响到结尾镜)。★前置:该剧已设 motifs(没设=空操作);会**改结尾镜 action/描述**,务必出图前做(否则结尾镜已出图会陈旧)。后台异步,文本步后付。",
|
|
54
|
-
"tail_frame_plan": "★免费只读:这一集**哪几镜需要独立尾帧**(末态≠首态的镜——大运镜/物体脱手/状态改变)
|
|
54
|
+
"tail_frame_plan": "★免费只读:这一集**哪几镜需要独立尾帧**(末态≠首态的镜——大运镜/物体脱手/状态改变)。运镜镜(摇/推/拉/移/升降,起止画面不同)按剧灰度计入;运镜要写进分镜的 movement 或 action(如「镜头缓慢向下摇到…」),只写在提示词里的「固定机位」会被当成静止。判定用的就是平台出视频时那套判据,你自己是猜不出来的,所以出完首帧务必调一次。返回 shots_needing_last_frame(总数)、ready(已有首帧、现在就能补尾帧的镜)、pending_first_frame(还需要尾帧但首帧尚未落地的镜——等首帧出完再调一次本工具)。拿到 ready 清单后:quote_frames + generate_frames 带 frame_type=last_frame 即可批量补。★尾帧补完(或本工具报 0)之后的下一步是接缝:chain_frames(dry_run:true) 看计划与预估、客户确认后执行,再 review_frames。★跳过尾帧不会报错,但那些镜出视频时只有首帧一个锚,末态由模型自由发挥——动作做不到位、大运镜结束又回到起点构图,多半就是这么来的。零扣费,可随时调。",
|
|
55
55
|
"quote_frames": "报价:给某一集批量出帧要多少点。返回 frames_to_generate、estimated_points、quote_id。零扣费。frame_type 默认 first_frame(只给缺首帧的镜出);last_frame 只给「已有首帧且缺尾帧」的镜出;both 两者都补。★报价按**实际会用的模型与分辨率**分档,响应带 price_breakdown(逐档张数与单价);打算在 generate_frames 里临时换模型,报价时就要把同一个 image_model 传进来,否则两边不是一个价。★两边必须传同一个 image_model —— 不一致会被直接拒(400 IMAGE_MODEL_MISMATCH),因为模型决定计费档,不同源就是「预估≠扣费」。两边都不传也算一致(用该剧设定的模型)。已下架的型号(FLUX 全系列)一律拒收,别再传。★返回两个数:estimated_points 是**上界**(按参考图张数上限估,拿它准备余额就不会中途 402),typical_points 是**通常花费**。两个都告诉客户,只报上界会让人以为贵得多。固定价模型(如 Nano Banana 系列)下两者相等。",
|
|
56
56
|
"generate_frames": "确认后批量出帧:后台异步。用 get_storyboards 轮询,first_frame_image/last_frame_image 逐镜填充即完成。★图片生成较慢——每张几十秒到数分钟(尤其高清模型),整集可能十几分钟。轮询看 frame_status:**pending=还在生成(继续耐心等,别当失败、别重复调 generate_frames,重复触发=白花钱)**、ready=完成、failed=才是真失败。别因为「等了一会儿还没出」就判定生成失败或重试。出视频前必须先出帧,否则视频会退化成无一致性锚点的画面。★**出帧前先把两个锚备齐**:定妆图(generate_portraits_and_sheets,锚人)与空景基板(generate_scene_images,锚景)。缺基板不会拦你,但每个场景的第一镜会没有背景锚(平台的兜底补图只惠及同场景后续镜),背景从首镜起就开始漂。用 get_pipeline_status 的 generate_scene_images 步核对 completed/total。frame_type 要与 quote_frames 用的一致(默认 first_frame)。★这是**批量补缺帧**:只给「缺该帧」的镜出图,已有首帧的镜会跳过——这是正常设计、不是\"系统拒绝重出\"。要**重出/重画某一镜已有的帧**(如换了定妆图要让新图生效),用 generate_shot_frame(单镜重生,平台带身份锚),不是这个工具、更不是自制图 upload_shot_frame。★**本工具默认只出首帧,出帧是两趟**:首帧出完必须调一次免费的 tail_frame_plan——它按平台自己的判据告出哪几镜需要独立尾帧(末态≠首态:大运镜/物体脱手/状态改变,占比约三成,你自己猜不出来),再用 frame_type=last_frame 批量补。生产实测 32 集里 30 集整集只出了首帧、其中 23 集一路出完视频:那些镜出视频时只有首帧一个锚,末态由模型自由发挥。本工具响应体里的 shots_needing_last_frame 就是这个数,不为 0 就别直接去 review_frames。★响应里的 frames_planned 是**计划数,不是已成功数**——本接口在后台派发循环开跑之前就返回了。真实进度只看 get_storyboards 的 first_frame_image / get_jobs 的逐条生成记录;余额不足(402)会中止整批,此时轮询再久也不会有结果,应去查余额而不是继续等。★★**个别镜反复出不来、其余镜都好了**:那不是等得不够久,是这几镜被内容闸连拒。看 get_storyboards 的 fail_reason(repeat_rejected / diagnosis_required / needs_content_fix / contract_rejected),若 diagnosis_required,先按 fail_hint 诊断已有候选;审计错误先重审,证据不足先复核,不要原样重抽或擅自改剧本。然后**跑 run_precheck**(事后也能跑,会告诉你是哪种矛盾),按它的提示用 update_shot 改景别/描述/绑定角色再重生。别继续 generate_frames 空转,也别把客户支去外部工具做图——外部图绕开身份锚与帧审计,人脸服装画风必漂。\n★【分镜审查硬闸·免费】本步前必须先调 review_storyboards:把返回的 findings 逐条原样告诉客户(每条带 code=问题类型、shots=命中镜号、action=该调哪个工具修),再把 review_token 传进本工具。未审查会被 400 拒。审查后又改了内容 → token 自动失效,复审一次即可(仍免费)。单镜工具(generate_shot_frame / regenerate_shot_video)只核本镜与相邻镜:改了别的镜不用复审;本镜、相邻镜或共享资产变了才 400——这时带 base_review_token=<旧 token> 调审查工具做增量复审,只重审变更镜,质检也只看变更镜。有 error 时默认拦截;客户知情并坚持照现状继续,才带 acknowledge_review:true——带病推进大概率产出废片且照常扣费(acknowledge_review 只代表客户本人同意,任何执行模式都须客户明确同意,托管也不例外);托管环节只有白名单内的启发式 error 能带 auto_acknowledge:true 放行(平台判,不在白名单回 400 AUTOPILOT_MUST_ASK:must_ask_customer=true 才暂停问客户,false = 按 action 自修复审)。★灰度剧还要你(agent)亲自质检:按 review_storyboards 返回的 agent_qc 逐件看素材、逐条答清单,调 submit_qc_report 提交后这张 token 才能用(没交 → 400 agent_qc_required;报告有问题 → 与 error 同样默认拦)。\n★【资产层硬闸·免费】还要先跑 review_assets(角色形象图/场景图/道具图),把它的 review_token 作为 asset_review_token 传进来(与分镜层的 review_token 并存,两张都要;灰度剧缺了会 400 并点名 review_assets)。出完帧不会让资产 token 失效。⚠️ 批量报价确认流程:先调对应的 quote_* 工具拿 estimated_points 与 quote_id,再用 quote_id 调本工具(报价确认按执行模式:专业模式 / 未确认方案 / 本环节由客户把控 → 讲给客户、客户同意才做,别替客户决定;本环节托管 → 不问客户,照 get_production_plan 的 autopilot.default_decisions 执行,平台记进 get_autopilot_log)。托管环节报价须在预算硬上限内,被 402 BUDGET_WOULD_EXCEED 拦下就停下问客户。★**出图类报价(定妆图/场景图/出帧)给的是两个数**:estimated_points 是**上界**(按该模型参考图张数上限估,保证你不会按低了的预算开跑、出到一半 402 中断);同一响应里的 typical_points 是**通常花费**。两个都要告诉客户——只说上界会让人以为贵得多(满参考图的上界可达通常值的 2 倍以上),只说通常值又会让余额准备不足。固定价模型下两者相等,这时说一个数就行。出视频的报价与扣费同函数,不存在这个区间。",
|
|
57
|
-
"quote_shot_frame": "报价:重画/补出**某一镜的某一帧**要多少点(一帧=一张图)。返回 estimated_points、quote_id。零扣费。客户说「第 N 镜画错了/要改」时用它,而不是拿别的图像平台出图再 upload_shot_frame。★响应带 billing_kind/unit_points(实际计费档与单价);要在 generate_shot_frame 里换模型,报价时传同一个 image_model。★两边必须传同一个 image_model —— 不一致会被直接拒(400 IMAGE_MODEL_MISMATCH),因为模型决定计费档,不同源就是「预估≠扣费」。两边都不传也算一致(用该剧设定的模型)。已下架的型号(FLUX 全系列)
|
|
58
|
-
"generate_shot_frame": "确认后给**某一镜**出帧或重生该帧(异步)。这是修某一镜画面的正路:平台会带上该镜的角色身份锚、场景/道具参考图、画风锚与帧审计,重生出的图与全片一致;用外部工具出图再上传会绕开这整条链路,人物/服装/画风必漂。重生会覆盖该帧现有图(含此前上传的),并把本镜视频标为待重生。尾帧需本镜首帧已就绪(否则先用 first_frame 或 both)。完成判据:轮询 get_storyboards 看该镜 first_frame_image/last_frame_image
|
|
57
|
+
"quote_shot_frame": "报价:重画/补出**某一镜的某一帧**要多少点(一帧=一张图)。返回 estimated_points、quote_id。零扣费。客户说「第 N 镜画错了/要改」时用它,而不是拿别的图像平台出图再 upload_shot_frame。★响应带 billing_kind/unit_points(实际计费档与单价);要在 generate_shot_frame 里换模型,报价时传同一个 image_model。★两边必须传同一个 image_model —— 不一致会被直接拒(400 IMAGE_MODEL_MISMATCH),因为模型决定计费档,不同源就是「预估≠扣费」。两边都不传也算一致(用该剧设定的模型)。已下架的型号(FLUX 全系列)一律拒收,别再传。★frame_type=both 时,平台判这一镜不需要独立尾帧(末态≈首态、没有运镜)会只出首帧:报价 frames_to_generate=1、只计首帧,并带 last_frame_skipped 说明原因——**原样告诉客户尾帧不会出**。客户确实要尾帧(例如起止画面不同的运镜)就报价与生成都带 force_independent_last_frame:true。★出首帧(first_frame/both)时响应带 continuity:follows_previous_shot=true 表示上一镜尾帧会钉在参考图第 1 位(承接上一镜的人物、姿势与机位),note 说明原因。这一镜不该接上一镜(跳切、换场、只拍手/道具的局部特写等),报价与生成都带 continuity_mode:'independent'。★返回两个数:estimated_points 是**上界**(按参考图张数上限估,拿它准备余额就不会中途 402),typical_points 是**通常花费**。两个都告诉客户,只报上界会让人以为贵得多。固定价模型(如 Nano Banana 系列)下两者相等。",
|
|
58
|
+
"generate_shot_frame": "确认后给**某一镜**出帧或重生该帧(异步)。这是修某一镜画面的正路:平台会带上该镜的角色身份锚、场景/道具参考图、画风锚与帧审计,重生出的图与全片一致;用外部工具出图再上传会绕开这整条链路,人物/服装/画风必漂。重生会覆盖该帧现有图(含此前上传的),并把本镜视频标为待重生。尾帧需本镜首帧已就绪(否则先用 first_frame 或 both)。完成判据:轮询 get_storyboards 看该镜 first_frame_image/last_frame_image 变化。★回执的 frames_dispatched 是真派出去的张数;both 的尾帧被平台判为不需要时会带 skipped_frames(没出、没扣尾帧的钱),原样告诉客户。出首帧的回执带 continuity(这次承接没承接上一镜、原因);continuity_mode 须与报价时一致,否则 409 重新报价。\n★继承重开(reopen_pair_id):get_storyboards 某镜带这个字段时,原样传进来可以只重掷首尾帧里真正有问题的那一侧——另一侧此前已经生成好的候选原样保留,不重新生成、不重新计费。传了它就不用再传 frame_type(会被忽略,由平台判定该重哪一侧);quote_id 仍要用 quote_shot_frame 报价(frame_type 传 first_frame 或 last_frame 均可,单帧同价)。若该镜没有 reopen_pair_id 字段(不满足继承条件),这个参数不要传,走常规 frame_type 重试。\n★★出尾帧若被拦下并提示「此镜标为状态改变,但没有任何地方说明结束时是什么样子」:正解是用 update_shot 把结束状态写进 last_frame_prompt 再出,**别直接加 allow_missing_terminal 硬上**——这类镜照现状出尾帧的历史成功率只有 9.4%(有终态描述的 40.2%),硬上多半是白扣一次钱。只有确认这一镜就是要「几乎不变」的画面时才带那个参数。\n★一键出片托管环节:同一镜重出帧最多 3 轮(一次调用算一轮,both 也算一轮),到上限回 **409 AUTOPILOT_SHOT_REGEN_LIMIT**(未派发、未扣费,quote 未消耗)——别换个工具绕,停下问客户:客户同意再出就照常报价、生成时带 customer_approved_more_regens:true(再给一份上限);客户接受现状就往下走,下一步收费调用带 acknowledge_review:true 记下确认。专业模式与客户把控的环节不受这个上限约束。\n★【分镜审查硬闸·免费】本步前必须先调 review_storyboards:把返回的 findings 逐条原样告诉客户(每条带 code=问题类型、shots=命中镜号、action=该调哪个工具修),再把 review_token 传进本工具。未审查会被 400 拒。审查后又改了内容 → token 自动失效,复审一次即可(仍免费)。单镜工具(generate_shot_frame / regenerate_shot_video)只核本镜与相邻镜:改了别的镜不用复审;本镜、相邻镜或共享资产变了才 400——这时带 base_review_token=<旧 token> 调审查工具做增量复审,只重审变更镜,质检也只看变更镜。有 error 时默认拦截;客户知情并坚持照现状继续,才带 acknowledge_review:true——带病推进大概率产出废片且照常扣费(acknowledge_review 只代表客户本人同意,任何执行模式都须客户明确同意,托管也不例外);托管环节只有白名单内的启发式 error 能带 auto_acknowledge:true 放行(平台判,不在白名单回 400 AUTOPILOT_MUST_ASK:must_ask_customer=true 才暂停问客户,false = 按 action 自修复审)。★灰度剧还要你(agent)亲自质检:按 review_storyboards 返回的 agent_qc 逐件看素材、逐条答清单,调 submit_qc_report 提交后这张 token 才能用(没交 → 400 agent_qc_required;报告有问题 → 与 error 同样默认拦)。\n★【资产层硬闸·免费】还要先跑 review_assets(角色形象图/场景图/道具图),把它的 review_token 作为 asset_review_token 传进来(与分镜层的 review_token 并存,两张都要;灰度剧缺了会 400 并点名 review_assets)。出完帧不会让资产 token 失效。⚠️ 批量报价确认流程:先调对应的 quote_* 工具拿 estimated_points 与 quote_id,再用 quote_id 调本工具(报价确认按执行模式:专业模式 / 未确认方案 / 本环节由客户把控 → 讲给客户、客户同意才做,别替客户决定;本环节托管 → 不问客户,照 get_production_plan 的 autopilot.default_decisions 执行,平台记进 get_autopilot_log)。托管环节报价须在预算硬上限内,被 402 BUDGET_WOULD_EXCEED 拦下就停下问客户。★**出图类报价(定妆图/场景图/出帧)给的是两个数**:estimated_points 是**上界**(按该模型参考图张数上限估,保证你不会按低了的预算开跑、出到一半 402 中断);同一响应里的 typical_points 是**通常花费**。两个都要告诉客户——只说上界会让人以为贵得多(满参考图的上界可达通常值的 2 倍以上),只说通常值又会让余额准备不足。固定价模型下两者相等,这时说一个数就行。出视频的报价与扣费同函数,不存在这个区间。",
|
|
59
59
|
"quote_local_frame_edit": "报价:**局部修改某一镜的某一帧**(修脸、闭嘴、去毛边、擦掉多出来的东西)要多少点。零扣费。客户只想改画面的一小块时用它,别拿外部图像工具改完再 upload_shot_frame——外部工具会连带改动已确认的其他细节、绕开身份锚与审计、来源链也断了;要整张重画才用 quote_shot_frame / generate_shot_frame。平台把修改区按羽化蒙版贴回原图:框外像素原样保留,只有框内被改。★计费:每个候选按一次出图扣(unit_points × candidates;张数固定,estimated_points 就是实扣,typical_points 与它相等)。**被平台判据拒掉的候选(贴回有接缝、没改到、身份审计不过)一律不退点**——报价时就要把这一点和点数一起讲给客户。厂商出图失败由平台自动退。★按剧、按类型灰度开放:没开放回 403 LOCAL_FRAME_EDIT_UNAVAILABLE,响应里 open_kinds 列出已对所有剧开放的类型(如 object_remove);要改的类型不在里面就只能 generate_shot_frame 整张重画。修脸类不带 character_id 回 400 CHARACTER_REQUIRED;修脸不送定妆图(只送底图局部),贴回后比对人脸判是不是同一个人(判不像的拒、拿不准的交人看,都照常计费)。",
|
|
60
60
|
"local_frame_edit": "确认后**局部修改某一镜的某一帧**(异步,扣费)。参数必须与 quote_local_frame_edit 那次完全相同(区域 / 指令 / 类型 / 角色 / 候选数 / 底图任一项变了 → 409 QUOTE_PARAMS_CHANGED,重新报价即可,免费)。返回 edit_id,之后用 get_local_frame_edit 轮询。★**不会自动替换当前帧**:候选出完先给客户看(composited_url),客户选定后调 adopt_local_frame_edit 才写进这一镜、并把本镜视频标为待重生;不采用,当前帧就不变。★被判据拒掉的候选照常计费、不退点。\n★【分镜审查硬闸·免费】本步前必须先调 review_storyboards:把返回的 findings 逐条原样告诉客户(每条带 code=问题类型、shots=命中镜号、action=该调哪个工具修),再把 review_token 传进本工具。未审查会被 400 拒。审查后又改了内容 → token 自动失效,复审一次即可(仍免费)。单镜工具(generate_shot_frame / regenerate_shot_video)只核本镜与相邻镜:改了别的镜不用复审;本镜、相邻镜或共享资产变了才 400——这时带 base_review_token=<旧 token> 调审查工具做增量复审,只重审变更镜,质检也只看变更镜。有 error 时默认拦截;客户知情并坚持照现状继续,才带 acknowledge_review:true——带病推进大概率产出废片且照常扣费(acknowledge_review 只代表客户本人同意,任何执行模式都须客户明确同意,托管也不例外);托管环节只有白名单内的启发式 error 能带 auto_acknowledge:true 放行(平台判,不在白名单回 400 AUTOPILOT_MUST_ASK:must_ask_customer=true 才暂停问客户,false = 按 action 自修复审)。★灰度剧还要你(agent)亲自质检:按 review_storyboards 返回的 agent_qc 逐件看素材、逐条答清单,调 submit_qc_report 提交后这张 token 才能用(没交 → 400 agent_qc_required;报告有问题 → 与 error 同样默认拦)。\n★【资产层硬闸·免费】还要先跑 review_assets(角色形象图/场景图/道具图),把它的 review_token 作为 asset_review_token 传进来(与分镜层的 review_token 并存,两张都要;灰度剧缺了会 400 并点名 review_assets)。出完帧不会让资产 token 失效。⚠️ 批量报价确认流程:先调对应的 quote_* 工具拿 estimated_points 与 quote_id,再用 quote_id 调本工具(报价确认按执行模式:专业模式 / 未确认方案 / 本环节由客户把控 → 讲给客户、客户同意才做,别替客户决定;本环节托管 → 不问客户,照 get_production_plan 的 autopilot.default_decisions 执行,平台记进 get_autopilot_log)。托管环节报价须在预算硬上限内,被 402 BUDGET_WOULD_EXCEED 拦下就停下问客户。★**出图类报价(定妆图/场景图/出帧)给的是两个数**:estimated_points 是**上界**(按该模型参考图张数上限估,保证你不会按低了的预算开跑、出到一半 402 中断);同一响应里的 typical_points 是**通常花费**。两个都要告诉客户——只说上界会让人以为贵得多(满参考图的上界可达通常值的 2 倍以上),只说通常值又会让余额准备不足。固定价模型下两者相等,这时说一个数就行。出视频的报价与扣费同函数,不存在这个区间。",
|
|
61
61
|
"get_local_frame_edit": "查一次局部返修的进度与结果(免费)。status=running 继续等;completed 后逐个候选看:composited_url(贴回原图后的成品,给客户看的就是它)、verdict(pass=可直接用;warn=能用但要人看——REGION_SEAM_WARN 边界可能有接缝 / EDIT_NOT_APPLIED 基本没改到 / IDENTITY_NEEDS_REVIEW 修脸后人脸比对分在灰区、平台不自动放行 / IDENTITY_NOT_JUDGEABLE 侧脸·低头·脸太小等判不了 / IDENTITY_COMPARE_LOW 旧版身份比对分偏低 / IDENTITY_AUDIT_UNAVAILABLE 身份没审成;reject=不建议用——REGION_MISALIGNED 贴回错位 / IDENTITY_MISMATCH 修脸后人脸比对判定换了人 / IDENTITY_AUDIT_REJECTED 帧审计不过,可能是原帧本身的构图问题)、reason_text(每条原因的中文说明,原样讲给客户)、metrics、identity_audit、identity_compare(修脸类身份比对:method=face_embedding 时按人脸特征向量判——与修改前同一张脸相似度 ≥0.75 放行、<0.60 判不像、中间交人看,vlm_reference 只记录;没有 method 字段的是旧版,只作参考)。★修脸结果仍要亲眼看是不是同一个人——侧脸、低头、小脸时平台判不了。下载 composited_url 亲眼看过、讲给客户,客户选定后用 adopt_local_frame_edit。被拒候选不退点(包括原帧本身问题导致帧审计不过的)。",
|
|
@@ -142,9 +142,9 @@
|
|
|
142
142
|
"scan_voice_consistency": "★原声剧(视频自带人声)客户报「同一个角色前后嗓音不一样 / 声线漂了」时跑这个。免费(本地推理,不调厂商)。对每个有台词的镜,听厂商生成的人声:台词念没念全,以及声音像不像该角色绑定的声线锚。**异步**:立即返回,后台整集约 10 分钟;同一集同时只跑一条(重复调用返回 started=false)。默认跳过已对当前视频扫过的镜,rescan=true 全部重扫。用 get_voice_consistency 查进度和逐镜结果。",
|
|
143
143
|
"get_voice_consistency": "查声线一致性扫描的进度与逐镜结果(scan_voice_consistency 启动的)。免费。summary.voice_mismatch=声音不像该角色声线锚的镜号(重点看);dialogue_issues=台词没念完/念错/多出说话声的镜;not_scanned_or_stale=还没扫或视频换过需重扫。speaker_verdict=uncertain 表示人声太短判不了,不是问题。声线不一致的镜:先用 get_pipeline_status 的 native_voice_anchor 确认角色已绑声线,再 regenerate_shot_video 重出。",
|
|
144
144
|
"scan_dialogue_coverage": "★客户报「话没说完就切 / 台词只念了一半」时先跑这个。默认**免费零扣费**(只读已落库的转录审计结果)。把该集每个原声镜的视频音轨与台词做词级比对,按族给出结论:truncated(念到一半就停) / off_script(念的大半不是台词:自说自话、重复上一镜、只有环境音) / extra_speech(台词念全了但还多念) / minor_gap(零星缺词,属转写误差,不必管) / ok。★判读:三个可上报的族**处置方向不同**,别一律加长镜头——实测镜长够的镜里仍有 21% 没念全,「太短」很少是真因(平台保存分镜时已按台词自动抬时长)。truncated/off_script 的正解都是 regenerate_shot_video(厂商每次说多少是随机的,重掷常能拿到整句);同一剧反复 off_script 则换引擎。★never_audited 是本报告最重要的一栏:那些镜从没被检测过,「没测过」不等于「没问题」。rescan=true 会对它们补跑 ASR 比对(耗算力、非瞬时,limit 控制单次上限),默认不跑。TTS 配音镜不在范围内(TTS 必然念全,低覆盖率只会是转写误差)。同一集若还伴随「切太快」,那是另一回事,跑 scan_intra_shot_cuts。",
|
|
145
|
-
"update_shot": "逐镜编辑:改单个分镜的文本内容(景别/动作/台词/画面描述/运镜等)、面部表情(expression_hint)、时长(duration)、成片变速(speed_factor)、镜间转场(transition_type / transition_duration_ms)、角色绑定(character_ids)、道具绑定(prop_ids)、画外音标记(character_presence)与服装绑定(active_wardrobe_id / appearance_wardrobes)。只传要改的字段、其余不动。★改镜(成功或被拒)都会作废覆盖本镜的未消费报价,生成时回 409 QUOTE_INVALIDATED——先改成功、回读核对,再报价。**免费**(纯文本写库)。★改 dialogue 会自动失效本镜已生成的 TTS 配音与字幕(需重出 tts);改文本不会自动重出图/视频,如需让画面跟上文本改动,改完再 regen 对应镜。用 get_storyboards 查改后结果(每镜带 character_ids / character_bindings / scene_id / prop_ids / active_wardrobe_id / appearance_wardrobes)
|
|
145
|
+
"update_shot": "逐镜编辑:改单个分镜的文本内容(景别/动作/台词/画面描述/运镜等)、面部表情(expression_hint)、时长(duration)、成片变速(speed_factor)、镜间转场(transition_type / transition_duration_ms)、角色绑定(character_ids)、道具绑定(prop_ids)、画外音标记(character_presence)与服装绑定(active_wardrobe_id / appearance_wardrobes)。只传要改的字段、其余不动。★改镜(成功或被拒)都会作废覆盖本镜的未消费报价,生成时回 409 QUOTE_INVALIDATED——先改成功、回读核对,再报价。**免费**(纯文本写库)。★改 dialogue 会自动失效本镜已生成的 TTS 配音与字幕(需重出 tts);改文本不会自动重出图/视频,如需让画面跟上文本改动,改完再 regen 对应镜。用 get_storyboards 查改后结果(每镜带 character_ids / character_bindings / scene_id / prop_ids / active_wardrobe_id / appearance_wardrobes);景别/机位/运镜/剪辑意图与提示词正文用 get_shot_prompts 逐镜回读。★★【换衣服改这里,不是改文字】出图穿什么由**服装绑定**决定:单人镜用 active_wardrobe_id(整镜一件),多人同框各穿各的用 appearance_wardrobes(逐角色)。把「穿某某衣服」写进 description/action 不会换衣服。服装 id 用 list_wardrobe 查;改完不会自动重出图,要让画面跟上需重生本镜首帧再重生视频。★★原声镜(厂商原生音频)改 dialogue 后,本镜视频会被标记「待重生」——因为台词是**烤进视频人声**的,不重生就终拼,成片里念的仍是改动前的台词(典型现象:台词像是跑到了别的镜头上)。compose_episode 会以 advisory `stale_video_after_edit` 列出这些镜;正确处置是先 regenerate_shot_video 再终拼。★也可直接改本镜的四条提示词正文(image_prompt/video_prompt/first_frame_prompt/last_frame_prompt):改前先用 get_shot_prompts 读现值,别凭空覆盖——正文里的 @char:N / @scene:M 是出图时的补充参考标记,照原样保留即可。★注入谁的定妆图由 character_ids 决定、背景由 scene_id 决定:删标记不会让已绑定的人从画面消失,要让某人不出现就改 character_ids,他只有声音(画外音)就用 character_presence 标 voice_only;反过来别给未绑定的角色写 @char 标记——会把他的图注入进来。★★【出尾帧被拦下就是来改这里】出尾帧若报「此镜标为状态改变,但没有任何地方说明结束时是什么样子」(TERMINAL_DESC_GATE),修法是把**结束时画面是什么样**写进本镜 last_frame_prompt,然后重新出尾帧。别去重试出图——这类镜(action_motion_class=state_change 却没写终态)的尾帧历史成功率 9.4%,有终态描述的是 40.2%;不补描述就重生,送厂商的提示词里根本没有终态段,画出来仍和首帧一样、还是会被拒,而每次重生都照常扣费。get_shot_prompts 的 terminal_desc_missing=true 就是这个信号。",
|
|
146
146
|
"rederive_shot_contract": "按本镜**当前**的正文与角色绑定,让平台重新推导构图契约(画面里可见几人、主体是人物还是局部/道具、景别)。契约本身不对外,读不到也改不了;本工具只回结论 outcome:updated(已改并生效)/ unchanged(推出来和原来一样)/ rejected(推出来自相矛盾,未采用,原契约保留)/ no_candidate(没拿到可用结果,原契约保留)/ stale(推导期间本镜又被改过,结果未写入,改完再调一次),附 note 说下一步。点数不足回 402。★什么时候用:出图/预检/审核反复说人数不对、局部镜(手部/道具特写)被当成完整人物出图或审核,而你已经改过正文或绑定——补全器只填空、不覆盖已有契约,不调本工具改动不会进契约。★正确顺序:先 update_shot 把画面写对(谁在画面里、谁只出声音用 character_presence 标 voice_only、不该出现的人从 character_ids 解绑),再调本工具;不改正文直接调多半回 unchanged。★一次文本 AI 调用,按 token 后付(与 autofill_storyboards 同链路),调用前告知客户。★只改契约这一个字段,不碰台词/提示词/其它专业字段;已出的首尾帧不会自动重出,要让画面跟上需对本镜重新出帧(先报价)。★updated 会作废本镜及同集未消费的出帧/出视频报价,之后要重新报价。",
|
|
147
|
-
"get_shot_prompts": "读某一镜的四条提示词**正文**(image_prompt=首帧画面 / video_prompt=动态表演 / first_frame_prompt=开始时什么样 / last_frame_prompt=结束时什么样),供直接微调后用 update_shot 写回。免费。★回执里的 terminal_desc_missing=true 表示本镜标为「状态改变」却三处都没说终态——出尾帧会被前置闸拦下,修法是把结束状态写进 last_frame_prompt(别重试出图,重试必然重复被拒且照常扣费)。★pose_timeline_stale 非 null = 本镜动作起止姿态里的秒数时间轴超出了当前时长(多见于改短 duration 后),出视频时那一端已自动不送;新时间轴写进 video_prompt。★同时回 description(画面描述)
|
|
147
|
+
"get_shot_prompts": "读某一镜的四条提示词**正文**(image_prompt=首帧画面 / video_prompt=动态表演 / first_frame_prompt=开始时什么样 / last_frame_prompt=结束时什么样),供直接微调后用 update_shot 写回。免费。★回执里的 terminal_desc_missing=true 表示本镜标为「状态改变」却三处都没说终态——出尾帧会被前置闸拦下,修法是把结束状态写进 last_frame_prompt(别重试出图,重试必然重复被拒且照常扣费)。★pose_timeline_stale 非 null = 本镜动作起止姿态里的秒数时间轴超出了当前时长(多见于改短 duration 后),出视频时那一端已自动不送;新时间轴写进 video_prompt。★同时回 description(画面描述)、lighting(本镜用光)与 sound_effect(本镜音效)现值——review_storyboards 的禁区词命中常在 description / sound_effect,改前先在这里读;用光写 lighting。★同时回 shot_type(景别)/ angle(机位)/ camera_movement(运镜)/ continuity_intent(剪辑意图)现值——update_shot 改完这几项就在这里回读核对(整集 get_storyboards 不含它们);null=未设。★同时回 expression_hint(本镜作者指定的面部表情,null=未指定、由平台按台词反推),改它用 update_shot。expression_inferred 是拆镜 AI 在剧本没写神态时按本镜内容推断的表情(只读;null=没推断,或本镜台词/动作/氛围/描述/强度改过、推断已过期不再使用);它优先级低于 expression_hint——推断不合意就用 update_shot 写 expression_hint 覆盖它。★逐镜按需:改哪镜读哪镜(整集列表 get_storyboards 不含提示词)。★返回的 asset_tokens 是正文里的补充参考标记(@char:N / @scene:M),改写时原样保留即可:本镜注入谁的定妆图由绑定决定(get_storyboards 的 character_ids / scene_id),删标记不会让已绑定的人消失;带 #变体 的标记是那张变体图的唯一来源;给未绑定的角色写标记会把他的图注入进来。★这是分镜表里的正文层;出图/出视频时平台还会在其上拼身份锚、一致性约束与参考图指令(不在此处,也无需你写)。改完提示词不会自动重出图/视频,要让画面跟上得再 regen 对应镜。",
|
|
148
148
|
"rerender_episode": "按当前 timeline 重拼成片(改完镜/裁剪后用)。**免费**(纯 ffmpeg+COS),后台异步。",
|
|
149
149
|
"replace_shot_dialogue": "换某镜对白音色/声线(转写+克隆重配)。**同步调用**,约 1 分钟返回产物,按用量后付不欠费。要求本镜有原声视频+角色声线定妆音。★它也是「这一镜台词没念完/念了别的」最经济的修法:用克隆音重配整句并静音原声段,**不重新生成视频**——按 TTS 档(千字符)计费,比 regenerate_shot_video(按秒计费,720p 每秒上百点)低几个数量级。代价:画面口型是按原音演的,换音后可能对不上;口型看不清的镜(背身/远景/画外)几乎无损,大特写慎用。★产物自动写回该镜(返回 persisted:true),但写回 ≠ 进成片:以 get_dialogue_repair_status 的 productEffective 为准——true 就 rerender_episode 重拼;false 时按 pendingCompose 先补合成再重拼,否则成片仍是旧音频。★该镜已有对口型产物时,成片优先用对口型版,换轨不会生效。整集批量用 repair_episode_dialogue。\n★写回前会对产物复核(与 scan_dialogue_coverage 同一判据):换完仍断音(truncated)、重复念/多念(extra_speech)、念的不是台词(off_script)→ **不写回**、本次费用自动退回,返回错误说明哪一类——这类镜换音修不好,改用 regenerate_shot_video。成功时返回 verify:verified=false 表示没判出来(转写失败/台词太短),照常写回但没复核过,自己听一下。",
|
|
150
150
|
"revoice_narration": "换某镜**旁白/画外音**的声音(或改过旁白文字后重配)。**不重新生成视频**:保留画面与出镜台词,只把旁白那几段静掉、按当前旁白声音重新合成并混回,再复核。同步调用,按 TTS 档(千字符)计费。★先改好再调:想换声音先 set_character_voice 给「旁白」角色(没有就 design_voice 造一个),想改文字先 update_shot 改 dialogue 里的旁白行。★纯旁白镜(本镜只有旁白)直接可用;**混合镜**(既有出镜台词又有旁白)要求分句数与视频里的语音段数一致,对不上就报错不猜(猜错会把出镜台词一起静掉)——这时只能 regenerate_shot_video。★台词栏没有旁白行会直接报错;厂商在无台词镜里乱念,用 replace_shot_dialogue 的 mute_only。★写回后成片会直接用它(不需要额外开关),rerender_episode 重拼即可;复核不通过不写回,旁白合成费不退。",
|
|
@@ -237,7 +237,7 @@
|
|
|
237
237
|
"chain_shot_from": "把同一集**任一镜**的首帧或尾帧接为本镜首帧。两种落法:\n· mode=copy(默认,免费):本镜首帧直接换成源帧,画面逐像素相同——适合「回到一模一样的画面」或同机位延续。\n· mode=reframe(扣一张图,必须带 quote_chain_shot_from 的 quote_id):以源帧为锚、按本镜画面描述重生首帧——人物/服装/道具/光线/场景延续,但保留本镜自己的景别与构图。景别有变化的缝要接,用这个。\n★源不是上一镜尾帧时(首尾呼应/回到某个画面),平台会把本镜与上一镜的缝记为「有意切换」,自动帧链不会再覆盖它。本镜已有视频的会被标为待重生;首帧是客户上传的或已定稿的会被拒(409 reason=user-locked-frame,不派图不扣费),覆盖它(任何执行模式都须客户明确同意,托管也不例外)才传 force:true(会解除上传 / 定稿保护,新图需客户重新验收;mode=reframe 的报价也要带 force)。",
|
|
238
238
|
"quote_align_prev_shot": "(免费报价)align_prev_shot 会重生**上一镜的视频**(扣一条视频),执行前先报价(报价确认按执行模式:专业模式 / 未确认方案 / 本环节由客户把控 → 讲给客户、客户同意才做,别替客户决定;本环节托管 → 不问客户,照 get_production_plan 的 autopilot.default_decisions 执行,平台记进 get_autopilot_log)。回 quote_id / estimated_points / prev_storyboard_id(被重生的是哪一镜);含首次人像核验费时另列 kyc_first_time_points。",
|
|
239
239
|
"align_prev_shot": "缝裂修复「对齐上一镜」:本镜首帧**不动**,以它为收尾画面、用首尾帧模式重生**上一镜的视频**(上一镜首帧不变),让上一镜真实收在本镜的开场画面上。扣一条视频,必须带 quote_align_prev_shot 的 quote_id。★适用:客户换过本镜首帧(比如上传或重生了一张更满意的),而上一镜的视频已经出好、不想改本镜首帧去迁就它。两镜都还没出视频时别用它——改首帧(chain_shot_from_prev / chain_shot_from)更便宜。异步:轮询 get_storyboards 看上一镜 video_status。",
|
|
240
|
-
"get_scene_group_plan": "查某一集的场景组规划(镜头如何归组做连续长镜)
|
|
240
|
+
"get_scene_group_plan": "查某一集的场景组规划(镜头如何归组做连续长镜)。免费。★先看回执顶层 active:false = 本剧长镜模式(scene_group_mode)未开启,groups 只是「开启后会怎么分」的预览、**不生效**——出视频按单镜逐个生成、按单镜计费,regenerate_shot_video 只动那一镜;要用分组先 update_project_settings 开启长镜模式。active:true 时 merged=true 的组才会整组一次生成。",
|
|
241
241
|
"quote_regenerate_scene_group": "报价:重出**一个场景组**(整组一次视频请求,组内连贯性保留)要多少点。返回 quote_id。零扣费。shot_numbers 必须正好等于 get_scene_group_plan 里某一组的镜号。\n★可选 video_engine:只为这一次整组重出换引擎(不改剧级 video_engine);报价按它计、quote_id 钉死,regenerate_scene_group 派发的就是它。整组仍一次成片,所以整组总时长必须在该引擎单段上限内(hailuo-3 15s;seedance-2.5/wan3.0 30s)且支持本剧分辨率,否则 400——那种情况改用 update_shot 给个别镜设 video_engine(设了的镜会单独出)。报价按逐镜计(整组失败会逐镜兜底,逐镜是上界),正常路径实扣通常更低。",
|
|
242
242
|
"regenerate_scene_group": "确认后重出一个场景组(整组一次视频请求,后台异步;用 get_storyboards 轮询各镜 video_url)。分组、引擎都由 quote_id 钉死,这里不能改;报价后组内任一镜被改、或分组变了,quote 作废(409),重新报价即可(免费)。⚠️ 批量报价确认流程:先调对应的 quote_* 工具拿 estimated_points 与 quote_id,再用 quote_id 调本工具(报价确认按执行模式:专业模式 / 未确认方案 / 本环节由客户把控 → 讲给客户、客户同意才做,别替客户决定;本环节托管 → 不问客户,照 get_production_plan 的 autopilot.default_decisions 执行,平台记进 get_autopilot_log)。托管环节报价须在预算硬上限内,被 402 BUDGET_WOULD_EXCEED 拦下就停下问客户。★**出图类报价(定妆图/场景图/出帧)给的是两个数**:estimated_points 是**上界**(按该模型参考图张数上限估,保证你不会按低了的预算开跑、出到一半 402 中断);同一响应里的 typical_points 是**通常花费**。两个都要告诉客户——只说上界会让人以为贵得多(满参考图的上界可达通常值的 2 倍以上),只说通常值又会让余额准备不足。固定价模型下两者相等,这时说一个数就行。出视频的报价与扣费同函数,不存在这个区间。",
|
|
243
243
|
"generate_scene_groups": "生成场景组(把连续镜头归组,连续长镜/批量出图的地基)。后台异步。",
|
package/dist/tools/produce.js
CHANGED
|
@@ -360,7 +360,8 @@ const PROJECT_SETTINGS_FIELDS = {
|
|
|
360
360
|
speech: z.enum(['unspecified', 'forbidden', 'required']).optional(),
|
|
361
361
|
music: z.enum(['unspecified', 'forbidden']).optional(),
|
|
362
362
|
pacing: z.enum(['unspecified', 'quiet']).optional(),
|
|
363
|
-
|
|
363
|
+
ambient: z.enum(['normal', 'minimal']).optional(),
|
|
364
|
+
}).strict().nullable().optional().describe('客户明确创作约束:speech=forbidden 禁止对白/旁白/演唱,music=forbidden 仅禁止本片输出混入配乐(允许生成/保存/选择音乐素材),pacing=quiet 保持平静节奏,ambient=minimal 原声视频人声干净、环境音极轻、无底噪(客户嫌原声底噪/嘶声/嗡鸣大时设;默认 normal 保留自然环境音;只影响之后新出的视频,已出的要重出才生效)。不推断;★整对象替换——改其中一项要先 get_drama 读出现有 creative_contract 把其它键一并带上,否则被清掉;null 清除,省略保持。环境声/音效不受禁止人声影响。'),
|
|
364
365
|
// drama 级图片模型(整剧统一画风):默认 ChatGPT Image 2.5 Flare(v0.9.1558)
|
|
365
366
|
image_model: z.string().optional().describe('图片模型(★drama级·整剧统一画风·默认 ChatGPT Image 2.5 Flare)。可选:' +
|
|
366
367
|
'gpt-image-2.5-flare(默认·基础11点+每张参考图18点)/gpt-image-2.5-sunburst(同价·中文字形与细节更准·慢约5秒)/' +
|
|
@@ -693,6 +694,7 @@ export function registerProduceTools(server, client) {
|
|
|
693
694
|
'recovery_options 按帧位给出失败后的三选一(挑误拒 / 修图上传 / 重生),与 get_frame_retry_diagnosis 同口径。', { storyboard_id: z.number().int().positive() }, async ({ storyboard_id }) => jsonResult(await client.produceGet(`/storyboards/${storyboard_id}/frame-workbench`)));
|
|
694
695
|
server.tool('adopt_frame_candidate', '免费:人工采用一张已出完的首帧/尾帧候选(被审计拒掉 rejected、落选 dismissed,或曾经在用后被换下的 completed),作为本镜在用帧——审计误判时的人工兜底(例如作者契约写明的设定被判成冲突),也可随时换回之前那张。' +
|
|
695
696
|
'★必须先用 get_frame_candidates 让客户看过原图和拒因、客户明确同意采用后才调' + ALWAYS_ASK('采用被拒候选') + ';不许为了让流程走下去自行放行。' +
|
|
697
|
+
'★采用前先对照本镜分镜(get_storyboards 的 first_frame_prompt / last_frame_prompt / action_in / action_out / movement)确认:采首帧要是动作起点、采尾帧要是动作终点——首帧候选若已是动作终态(人已到位、动作已做完)或把运镜终点画进了起点,采用后视频里就没有动作过程,换一张或改提示词重出。' +
|
|
696
698
|
'只能采用本镜本帧位、已出完、有画面、且不是当前在用的那张;会在该候选上记录人工放行(谁/何时/原拒因),原拒因保留供统计。' +
|
|
697
699
|
'本镜已有视频的会标成待重生(视频是按旧帧出的,需 regenerate_shot_video)。本镜该帧是客户上传或已定稿的,要带 replace_user_frame:true 才会替换(并解除定稿)。' +
|
|
698
700
|
'同帧位有在途出图或本镜视频在途时返回 409,等它结束再采用。', {
|
|
@@ -959,6 +961,7 @@ export function registerProduceTools(server, client) {
|
|
|
959
961
|
'★前置:该剧已设 motifs(没设=空操作);会**改结尾镜 action/描述**,务必出图前做(否则结尾镜已出图会陈旧)。后台异步,文本步后付。', { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.producePost(`/episodes/${episode_id}/storyboards/complete-motifs`)));
|
|
960
962
|
// ---------- 出首帧(frames) ----------
|
|
961
963
|
server.tool('tail_frame_plan', '★免费只读:这一集**哪几镜需要独立尾帧**(末态≠首态的镜——大运镜/物体脱手/状态改变)。' +
|
|
964
|
+
'运镜镜(摇/推/拉/移/升降,起止画面不同)按剧灰度计入;运镜要写进分镜的 movement 或 action(如「镜头缓慢向下摇到…」),只写在提示词里的「固定机位」会被当成静止。' +
|
|
962
965
|
'判定用的就是平台出视频时那套判据,你自己是猜不出来的,所以出完首帧务必调一次。' +
|
|
963
966
|
'返回 shots_needing_last_frame(总数)、ready(已有首帧、现在就能补尾帧的镜)、' +
|
|
964
967
|
'pending_first_frame(还需要尾帧但首帧尚未落地的镜——等首帧出完再调一次本工具)。' +
|
|
@@ -1015,19 +1018,29 @@ export function registerProduceTools(server, client) {
|
|
|
1015
1018
|
quote_id, frame_type, image_model, review_token, asset_review_token, acknowledge_review, auto_acknowledge, allow_era_ref_conflict,
|
|
1016
1019
|
})));
|
|
1017
1020
|
// ---------- 单镜出帧/重生(改某一镜的画面走这里,别去外部平台出图再传回来) ----------
|
|
1021
|
+
const CONTINUITY_MODE_ARG = z.enum(['auto', 'independent', 'follow_previous']).optional().describe('首帧的跨镜承接方式(只对 first_frame/both 的首帧生效):不传=auto,平台按剪辑意图、在画角色、景别与构图判断要不要把上一镜尾帧钉在参考图第 1 位;' +
|
|
1022
|
+
'independent=这一镜独立出,绝不带上一镜画面(跳切、换场、局部特写);follow_previous=强制承接上一镜(即使两镜之间标了切)。★报价与生成须传同一个值,否则 409 重新报价');
|
|
1018
1023
|
server.tool('quote_shot_frame', '报价:重画/补出**某一镜的某一帧**要多少点(一帧=一张图)。返回 estimated_points、quote_id。零扣费。' +
|
|
1019
1024
|
'客户说「第 N 镜画错了/要改」时用它,而不是拿别的图像平台出图再 upload_shot_frame。' +
|
|
1020
1025
|
'★响应带 billing_kind/unit_points(实际计费档与单价);要在 generate_shot_frame 里换模型,报价时传同一个 image_model。' +
|
|
1021
1026
|
'★两边必须传同一个 image_model —— 不一致会被直接拒(400 IMAGE_MODEL_MISMATCH),因为模型决定计费档,不同源就是「预估≠扣费」。两边都不传也算一致(用该剧设定的模型)。已下架的型号(FLUX 全系列)一律拒收,别再传。' +
|
|
1027
|
+
'★frame_type=both 时,平台判这一镜不需要独立尾帧(末态≈首态、没有运镜)会只出首帧:报价 frames_to_generate=1、只计首帧,并带 last_frame_skipped 说明原因——**原样告诉客户尾帧不会出**。' +
|
|
1028
|
+
'客户确实要尾帧(例如起止画面不同的运镜)就报价与生成都带 force_independent_last_frame:true。' +
|
|
1029
|
+
'★出首帧(first_frame/both)时响应带 continuity:follows_previous_shot=true 表示上一镜尾帧会钉在参考图第 1 位(承接上一镜的人物、姿势与机位),note 说明原因。' +
|
|
1030
|
+
'这一镜不该接上一镜(跳切、换场、只拍手/道具的局部特写等),报价与生成都带 continuity_mode:\'independent\'。' +
|
|
1022
1031
|
QUOTE_RANGE_HINT, {
|
|
1023
1032
|
storyboard_id: z.number().int().positive(),
|
|
1024
1033
|
frame_type: FRAME_TYPE_ARG.optional().describe('默认 first_frame;both=首尾各一张'),
|
|
1025
1034
|
image_model: z.string().optional().describe('按这个模型报价(★须与随后 generate_shot_frame 传的一致,否则 generate 会 400;不传=用 drama 级设定,默认 ChatGPT Image 2.5 Flare)'),
|
|
1026
|
-
|
|
1035
|
+
force_independent_last_frame: z.boolean().optional().describe('只对 frame_type=both 有意义:true=客户明确要独立尾帧,不让平台判据跳过(报价按首尾两张算)。★须与 generate_shot_frame 传的一致,否则 409 重新报价'),
|
|
1036
|
+
continuity_mode: CONTINUITY_MODE_ARG,
|
|
1037
|
+
}, async ({ storyboard_id, frame_type, image_model, force_independent_last_frame, continuity_mode }) => jsonResult(await client.producePost(`/storyboards/${storyboard_id}/frame/quote`, { frame_type, image_model, force_independent_last_frame, continuity_mode })));
|
|
1027
1038
|
server.tool('generate_shot_frame', '确认后给**某一镜**出帧或重生该帧(异步)。这是修某一镜画面的正路:平台会带上该镜的角色身份锚、' +
|
|
1028
1039
|
'场景/道具参考图、画风锚与帧审计,重生出的图与全片一致;用外部工具出图再上传会绕开这整条链路,人物/服装/画风必漂。' +
|
|
1029
1040
|
'重生会覆盖该帧现有图(含此前上传的),并把本镜视频标为待重生。尾帧需本镜首帧已就绪(否则先用 first_frame 或 both)。' +
|
|
1030
|
-
'完成判据:轮询 get_storyboards 看该镜 first_frame_image/last_frame_image
|
|
1041
|
+
'完成判据:轮询 get_storyboards 看该镜 first_frame_image/last_frame_image 变化。' +
|
|
1042
|
+
'★回执的 frames_dispatched 是真派出去的张数;both 的尾帧被平台判为不需要时会带 skipped_frames(没出、没扣尾帧的钱),原样告诉客户。' +
|
|
1043
|
+
'出首帧的回执带 continuity(这次承接没承接上一镜、原因);continuity_mode 须与报价时一致,否则 409 重新报价。\n' +
|
|
1031
1044
|
'★继承重开(reopen_pair_id):get_storyboards 某镜带这个字段时,原样传进来可以只重掷首尾帧里' +
|
|
1032
1045
|
'真正有问题的那一侧——另一侧此前已经生成好的候选原样保留,不重新生成、不重新计费。传了它就' +
|
|
1033
1046
|
'不用再传 frame_type(会被忽略,由平台判定该重哪一侧);quote_id 仍要用 quote_shot_frame 报价' +
|
|
@@ -1046,9 +1059,11 @@ export function registerProduceTools(server, client) {
|
|
|
1046
1059
|
reopen_pair_id: z.string().optional().describe('来自 get_storyboards 该镜的同名字段;只重掷有问题的那一侧,不必再传 frame_type'),
|
|
1047
1060
|
image_model: z.string().optional().describe('临时覆盖本次重画的图片模型(★必须与 quote_shot_frame 传的那个一致,否则 400 IMAGE_MODEL_MISMATCH;不传=用 drama 级设定,默认 ChatGPT Image 2.5 Flare);取值同 generate_frames'),
|
|
1048
1061
|
allow_missing_terminal: z.boolean().optional().describe('★逃生门,默认不传。本镜标为「状态改变」却没写终态时,出尾帧会被前置闸拦下;带 true 表示「我知道,照现状出」。正解是先 update_shot 补 last_frame_prompt——那类镜照现状出的成功率 9.4%,这个参数只用于确认本镜就该「几乎不变」的场合'),
|
|
1062
|
+
force_independent_last_frame: z.boolean().optional().describe('只对 frame_type=both 有意义:true=客户明确要独立尾帧,绕过平台判据(★须与 quote_shot_frame 传的一致)'),
|
|
1063
|
+
continuity_mode: CONTINUITY_MODE_ARG,
|
|
1049
1064
|
allow_era_ref_conflict: z.boolean().optional().describe('★默认不传。时代审核判定角色定妆参考与时代设定冲突时,出图会被拦下(未扣费):客户上传的定妆图及其派生图报 400 ERA_USER_REF_CONFLICT,平台生成的定妆图报 era_identity_ref_blocked。**先把冲突原因告诉客户、由客户确认造型无误**后才带 true' + ALWAYS_ASK('allow_era_ref_conflict ') + ':这些图保留不剔、照常出图。造型真不对就改定妆图,时代设定错了就 set_era_contract'),
|
|
1050
1065
|
...SHOT_REGEN_ARG,
|
|
1051
|
-
}, async ({ storyboard_id, quote_id, review_token, asset_review_token, acknowledge_review, auto_acknowledge, frame_type, replace_user_frame, reopen_pair_id, image_model, allow_missing_terminal, allow_era_ref_conflict, customer_approved_more_regens }) => jsonResult(await client.producePost(`/storyboards/${storyboard_id}/frame/generate`, { quote_id, review_token, asset_review_token, acknowledge_review, auto_acknowledge, frame_type, replace_user_frame, reopen_pair_id, image_model, allow_missing_terminal, allow_era_ref_conflict, customer_approved_more_regens })));
|
|
1066
|
+
}, async ({ storyboard_id, quote_id, review_token, asset_review_token, acknowledge_review, auto_acknowledge, frame_type, replace_user_frame, reopen_pair_id, image_model, allow_missing_terminal, force_independent_last_frame, continuity_mode, allow_era_ref_conflict, customer_approved_more_regens }) => jsonResult(await client.producePost(`/storyboards/${storyboard_id}/frame/generate`, { quote_id, review_token, asset_review_token, acknowledge_review, auto_acknowledge, frame_type, replace_user_frame, reopen_pair_id, image_model, allow_missing_terminal, force_independent_last_frame, continuity_mode, allow_era_ref_conflict, customer_approved_more_regens })));
|
|
1052
1067
|
// ---------- 镜头图局部返修(只修一小块,其余像素原样保留;按剧灰度) ----------
|
|
1053
1068
|
const LOCAL_EDIT_ARGS = {
|
|
1054
1069
|
storyboard_id: z.number().int().positive(),
|
|
@@ -1772,7 +1787,7 @@ export function registerProduceTools(server, client) {
|
|
|
1772
1787
|
});
|
|
1773
1788
|
server.tool('update_shot', '逐镜编辑:改单个分镜的文本内容(景别/动作/台词/画面描述/运镜等)、面部表情(expression_hint)、时长(duration)、成片变速(speed_factor)、镜间转场(transition_type / transition_duration_ms)、角色绑定(character_ids)、道具绑定(prop_ids)、画外音标记(character_presence)与服装绑定(active_wardrobe_id / appearance_wardrobes)。只传要改的字段、其余不动。★改镜(成功或被拒)都会作废覆盖本镜的未消费报价,生成时回 409 QUOTE_INVALIDATED——先改成功、回读核对,再报价。' +
|
|
1774
1789
|
'**免费**(纯文本写库)。★改 dialogue 会自动失效本镜已生成的 TTS 配音与字幕(需重出 tts);' +
|
|
1775
|
-
'改文本不会自动重出图/视频,如需让画面跟上文本改动,改完再 regen 对应镜。用 get_storyboards 查改后结果(每镜带 character_ids / character_bindings / scene_id / prop_ids / active_wardrobe_id / appearance_wardrobes)
|
|
1790
|
+
'改文本不会自动重出图/视频,如需让画面跟上文本改动,改完再 regen 对应镜。用 get_storyboards 查改后结果(每镜带 character_ids / character_bindings / scene_id / prop_ids / active_wardrobe_id / appearance_wardrobes);景别/机位/运镜/剪辑意图与提示词正文用 get_shot_prompts 逐镜回读。' +
|
|
1776
1791
|
'★★【换衣服改这里,不是改文字】出图穿什么由**服装绑定**决定:单人镜用 active_wardrobe_id(整镜一件),' +
|
|
1777
1792
|
'多人同框各穿各的用 appearance_wardrobes(逐角色)。把「穿某某衣服」写进 description/action 不会换衣服。' +
|
|
1778
1793
|
'服装 id 用 list_wardrobe 查;改完不会自动重出图,要让画面跟上需重生本镜首帧再重生视频。' +
|
|
@@ -1792,7 +1807,14 @@ export function registerProduceTools(server, client) {
|
|
|
1792
1807
|
'还是会被拒,而每次重生都照常扣费。get_shot_prompts 的 terminal_desc_missing=true 就是这个信号。', {
|
|
1793
1808
|
storyboard_id: z.number().int().positive(),
|
|
1794
1809
|
product_text_contract: z.object({ version: z.literal(1), strategy: z.enum(['generate_with_review', 'original_media', 'postproduction']), targets: z.array(z.object({ asset_kind: z.enum(['prop', 'product']), asset_id: z.number().int().positive(), reference_url: z.string().url(), region: z.object({ x: z.number(), y: z.number(), width: z.number(), height: z.number() }), exact_text: z.string().min(1).max(256) })).min(1).max(4) }).nullable().optional().describe('明确保留的实物原字:资产 ID、原图、归一化区域、原文及处理方式;生成不保证逐字正确,必须人工核对。null 清除声明,不回填历史。'),
|
|
1795
|
-
continuity_intent: z.enum(['continuous_action', 'shot_change', 'insert_detail', 'jump_cut']).optional().describe('
|
|
1810
|
+
continuity_intent: z.enum(['continuous_action', 'shot_change', 'insert_detail', 'jump_cut']).optional().describe('本镜相对上镜的剪辑意图,决定跨镜帧链与续拍怎么接:' +
|
|
1811
|
+
'continuous_action=同一动作往下走——帧链接续(本镜首帧接上镜尾帧);同场景、同景别、同一组角色且不是正反打时,平台开了续拍的剧会改走续拍' +
|
|
1812
|
+
'(拿上一镜视频当参考往下延长,不送本镜首尾帧);' +
|
|
1813
|
+
'shot_change=换景别/换机位(含正反打、过肩反打)——帧链按上镜尾帧重取景出本镜首帧,★不走续拍,本镜照常按自己的首尾帧出视频;' +
|
|
1814
|
+
'insert_detail=插入细节镜——断开帧链、不续拍,本镜独立出;' +
|
|
1815
|
+
'jump_cut=有意跳切——断开帧链、不续拍,本镜独立出。' +
|
|
1816
|
+
'★正反打/过肩反打(越过A肩头拍B → 越过B肩头拍A)标 shot_change,别标 continuous_action。剧级 frame_chain_mode=off 时帧链一律不接,续拍规则不变。' +
|
|
1817
|
+
'改变后旧双边审核失效;不自动生成或补审,已出的帧/视频不会自动重出。'),
|
|
1796
1818
|
character_ids: z.array(z.number().int().positive()).optional()
|
|
1797
1819
|
.describe('本镜出场角色 ID 列表(★全量覆盖式,非增量,漏传的角色会被解绑)。决定出图时注入哪些角色的定妆图/设定图——非人角色(动物/生物)也必须绑定,否则形象会漂移。id 必须来自当前集已关联角色'),
|
|
1798
1820
|
prop_ids: z.array(z.number().int().positive()).max(8).optional()
|
|
@@ -1826,6 +1848,8 @@ export function registerProduceTools(server, client) {
|
|
|
1826
1848
|
lighting: z.string().optional().describe('本镜用光(如「逆光」「左侧窗光、脸一半在暗处」)。★用光写这里,不要写进画面描述(description)或提示词:' +
|
|
1827
1849
|
'那几个字段写光影词会被 review_storyboards 判 forbidden_term 拦下,这一条不在禁区词扫描范围。出视频时作为 [Lighting] 段送达,出图按它匹配场景光照变体。' +
|
|
1828
1850
|
'全量覆盖现值,现值用 get_shot_prompts 读;改完不会自动重出图/视频'),
|
|
1851
|
+
sound_effect: z.string().nullable().optional().describe('本镜音效(如「木门吱呀」「远处犬吠」;全量覆盖现值,null 清空)。出视频时作为 [Audio] 段送给视频引擎,' +
|
|
1852
|
+
'review_storyboards 的禁区词也扫这一条(hits 里 field=sound_effect 时就在这里改)。现值用 get_shot_prompts 读;改完不会自动重出视频,要让声音跟上需重生本镜视频(先报价)'),
|
|
1829
1853
|
shot_type: z.string().optional().describe('景别(如 特写/中景/全景/远景)'),
|
|
1830
1854
|
angle: z.string().optional().describe('机位角度'),
|
|
1831
1855
|
camera_movement: z.string().optional().describe('运镜(推/拉/摇/移/跟/固定)'),
|
|
@@ -1875,7 +1899,8 @@ export function registerProduceTools(server, client) {
|
|
|
1875
1899
|
'★回执里的 terminal_desc_missing=true 表示本镜标为「状态改变」却三处都没说终态——' +
|
|
1876
1900
|
'出尾帧会被前置闸拦下,修法是把结束状态写进 last_frame_prompt(别重试出图,重试必然重复被拒且照常扣费)。' +
|
|
1877
1901
|
'★pose_timeline_stale 非 null = 本镜动作起止姿态里的秒数时间轴超出了当前时长(多见于改短 duration 后),出视频时那一端已自动不送;新时间轴写进 video_prompt。' +
|
|
1878
|
-
'★同时回 description(画面描述)
|
|
1902
|
+
'★同时回 description(画面描述)、lighting(本镜用光)与 sound_effect(本镜音效)现值——review_storyboards 的禁区词命中常在 description / sound_effect,改前先在这里读;用光写 lighting。' +
|
|
1903
|
+
'★同时回 shot_type(景别)/ angle(机位)/ camera_movement(运镜)/ continuity_intent(剪辑意图)现值——update_shot 改完这几项就在这里回读核对(整集 get_storyboards 不含它们);null=未设。' +
|
|
1879
1904
|
'★同时回 expression_hint(本镜作者指定的面部表情,null=未指定、由平台按台词反推),改它用 update_shot。' +
|
|
1880
1905
|
'expression_inferred 是拆镜 AI 在剧本没写神态时按本镜内容推断的表情(只读;null=没推断,或本镜台词/动作/氛围/描述/强度改过、推断已过期不再使用);它优先级低于 expression_hint——' +
|
|
1881
1906
|
'推断不合意就用 update_shot 写 expression_hint 覆盖它。' +
|
|
@@ -2613,7 +2638,10 @@ export function registerProduceTools(server, client) {
|
|
|
2613
2638
|
storyboard_id: z.number().int().positive().describe('缝右侧那一镜'),
|
|
2614
2639
|
quote_id: z.string().describe('来自 quote_align_prev_shot'),
|
|
2615
2640
|
}, async ({ storyboard_id, quote_id }) => jsonResult(await client.producePost(`/storyboards/${storyboard_id}/align-prev`, { quote_id })));
|
|
2616
|
-
server.tool('get_scene_group_plan', '查某一集的场景组规划(镜头如何归组做连续长镜)。免费。'
|
|
2641
|
+
server.tool('get_scene_group_plan', '查某一集的场景组规划(镜头如何归组做连续长镜)。免费。' +
|
|
2642
|
+
'★先看回执顶层 active:false = 本剧长镜模式(scene_group_mode)未开启,groups 只是「开启后会怎么分」的预览、**不生效**——' +
|
|
2643
|
+
'出视频按单镜逐个生成、按单镜计费,regenerate_shot_video 只动那一镜;要用分组先 update_project_settings 开启长镜模式。' +
|
|
2644
|
+
'active:true 时 merged=true 的组才会整组一次生成。', { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.produceGet(`/episodes/${episode_id}/scene-group-plan`)));
|
|
2617
2645
|
server.tool('quote_regenerate_scene_group', '报价:重出**一个场景组**(整组一次视频请求,组内连贯性保留)要多少点。返回 quote_id。零扣费。' +
|
|
2618
2646
|
'shot_numbers 必须正好等于 get_scene_group_plan 里某一组的镜号。' +
|
|
2619
2647
|
'\n★可选 video_engine:只为这一次整组重出换引擎(不改剧级 video_engine);报价按它计、quote_id 钉死,regenerate_scene_group 派发的就是它。' +
|
package/openapi.json
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
"openapi": "3.1.0",
|
|
3
3
|
"info": {
|
|
4
4
|
"title": "StarReel Production API",
|
|
5
|
-
"version": "0.1.
|
|
6
|
-
"description": "Turn a script into a finished, downloadable short-drama episode over REST.\n\nPipeline: script → AI rewrite → cast/scenes/props extraction → storyboards → portraits & sheets + scene plates → keyframes → video shots → TTS → final cut (.mp4).\n\n**Billing is prepaid and agent-safe**: big-ticket stages are quote-then-generate (`quote_*` returns a `quote_id`). For video, quote == actual charge. For images the quote is a *range* — models billed per reference image are priced before those are assembled, so `estimated_points` is the upper bound (size the balance by it and a run never dies half-way) and `typical_points` is the usual cost; fixed-price models return the two equal. Insufficient balance returns 402 — nothing half-runs and the account never goes negative.\n\nAuth: exchange your API key at `POST /v1/agent/token` for a 15-minute bearer token.\n\nGenerated from the @starreel/mcp v0.1.
|
|
5
|
+
"version": "0.1.231",
|
|
6
|
+
"description": "Turn a script into a finished, downloadable short-drama episode over REST.\n\nPipeline: script → AI rewrite → cast/scenes/props extraction → storyboards → portraits & sheets + scene plates → keyframes → video shots → TTS → final cut (.mp4).\n\n**Billing is prepaid and agent-safe**: big-ticket stages are quote-then-generate (`quote_*` returns a `quote_id`). For video, quote == actual charge. For images the quote is a *range* — models billed per reference image are priced before those are assembled, so `estimated_points` is the upper bound (size the balance by it and a run never dies half-way) and `typical_points` is the usual cost; fixed-price models return the two equal. Insufficient balance returns 402 — nothing half-runs and the account never goes negative.\n\nAuth: exchange your API key at `POST /v1/agent/token` for a 15-minute bearer token.\n\nGenerated from the @starreel/mcp v0.1.231 tool surface (operationIds match MCP tool names 1:1)."
|
|
7
7
|
},
|
|
8
8
|
"servers": [
|
|
9
9
|
{
|
|
@@ -1059,6 +1059,13 @@
|
|
|
1059
1059
|
"unspecified",
|
|
1060
1060
|
"quiet"
|
|
1061
1061
|
]
|
|
1062
|
+
},
|
|
1063
|
+
"ambient": {
|
|
1064
|
+
"type": "string",
|
|
1065
|
+
"enum": [
|
|
1066
|
+
"normal",
|
|
1067
|
+
"minimal"
|
|
1068
|
+
]
|
|
1062
1069
|
}
|
|
1063
1070
|
},
|
|
1064
1071
|
"required": [
|
|
@@ -1434,6 +1441,13 @@
|
|
|
1434
1441
|
"unspecified",
|
|
1435
1442
|
"quiet"
|
|
1436
1443
|
]
|
|
1444
|
+
},
|
|
1445
|
+
"ambient": {
|
|
1446
|
+
"type": "string",
|
|
1447
|
+
"enum": [
|
|
1448
|
+
"normal",
|
|
1449
|
+
"minimal"
|
|
1450
|
+
]
|
|
1437
1451
|
}
|
|
1438
1452
|
},
|
|
1439
1453
|
"required": [
|
|
@@ -7536,7 +7550,7 @@
|
|
|
7536
7550
|
"get": {
|
|
7537
7551
|
"operationId": "tail_frame_plan",
|
|
7538
7552
|
"summary": "★免费只读:这一集**哪几镜需要独立尾帧**(末态≠首态的镜——大运镜/物体脱手/状态改变)",
|
|
7539
|
-
"description": "★免费只读:这一集**哪几镜需要独立尾帧**(末态≠首态的镜——大运镜/物体脱手/状态改变)
|
|
7553
|
+
"description": "★免费只读:这一集**哪几镜需要独立尾帧**(末态≠首态的镜——大运镜/物体脱手/状态改变)。运镜镜(摇/推/拉/移/升降,起止画面不同)按剧灰度计入;运镜要写进分镜的 movement 或 action(如「镜头缓慢向下摇到…」),只写在提示词里的「固定机位」会被当成静止。判定用的就是平台出视频时那套判据,你自己是猜不出来的,所以出完首帧务必调一次。返回 shots_needing_last_frame(总数)、ready(已有首帧、现在就能补尾帧的镜)、pending_first_frame(还需要尾帧但首帧尚未落地的镜——等首帧出完再调一次本工具)。拿到 ready 清单后:quote_frames + generate_frames 带 frame_type=last_frame 即可批量补。★尾帧补完(或本工具报 0)之后的下一步是接缝:chain_frames(dry_run:true) 看计划与预估、客户确认后执行,再 review_frames。★跳过尾帧不会报错,但那些镜出视频时只有首帧一个锚,末态由模型自由发挥——动作做不到位、大运镜结束又回到起点构图,多半就是这么来的。零扣费,可随时调。",
|
|
7540
7554
|
"tags": [
|
|
7541
7555
|
"episodes"
|
|
7542
7556
|
],
|
|
@@ -9253,7 +9267,7 @@
|
|
|
9253
9267
|
"get": {
|
|
9254
9268
|
"operationId": "get_scene_group_plan",
|
|
9255
9269
|
"summary": "查某一集的场景组规划(镜头如何归组做连续长镜)",
|
|
9256
|
-
"description": "查某一集的场景组规划(镜头如何归组做连续长镜)
|
|
9270
|
+
"description": "查某一集的场景组规划(镜头如何归组做连续长镜)。免费。★先看回执顶层 active:false = 本剧长镜模式(scene_group_mode)未开启,groups 只是「开启后会怎么分」的预览、**不生效**——出视频按单镜逐个生成、按单镜计费,regenerate_shot_video 只动那一镜;要用分组先 update_project_settings 开启长镜模式。active:true 时 merged=true 的组才会整组一次生成。",
|
|
9257
9271
|
"tags": [
|
|
9258
9272
|
"episodes"
|
|
9259
9273
|
],
|
|
@@ -13269,7 +13283,7 @@
|
|
|
13269
13283
|
"put": {
|
|
13270
13284
|
"operationId": "update_shot",
|
|
13271
13285
|
"summary": "逐镜编辑:改单个分镜的文本内容(景别/动作/台词/画面描述/运镜等)、面部表情(expression_hint)、时长(duration)、成片变速(speed_factor)、镜间转场(transition_type / transiti",
|
|
13272
|
-
"description": "逐镜编辑:改单个分镜的文本内容(景别/动作/台词/画面描述/运镜等)、面部表情(expression_hint)、时长(duration)、成片变速(speed_factor)、镜间转场(transition_type / transition_duration_ms)、角色绑定(character_ids)、道具绑定(prop_ids)、画外音标记(character_presence)与服装绑定(active_wardrobe_id / appearance_wardrobes)。只传要改的字段、其余不动。★改镜(成功或被拒)都会作废覆盖本镜的未消费报价,生成时回 409 QUOTE_INVALIDATED——先改成功、回读核对,再报价。**免费**(纯文本写库)。★改 dialogue 会自动失效本镜已生成的 TTS 配音与字幕(需重出 tts);改文本不会自动重出图/视频,如需让画面跟上文本改动,改完再 regen 对应镜。用 get_storyboards 查改后结果(每镜带 character_ids / character_bindings / scene_id / prop_ids / active_wardrobe_id / appearance_wardrobes)
|
|
13286
|
+
"description": "逐镜编辑:改单个分镜的文本内容(景别/动作/台词/画面描述/运镜等)、面部表情(expression_hint)、时长(duration)、成片变速(speed_factor)、镜间转场(transition_type / transition_duration_ms)、角色绑定(character_ids)、道具绑定(prop_ids)、画外音标记(character_presence)与服装绑定(active_wardrobe_id / appearance_wardrobes)。只传要改的字段、其余不动。★改镜(成功或被拒)都会作废覆盖本镜的未消费报价,生成时回 409 QUOTE_INVALIDATED——先改成功、回读核对,再报价。**免费**(纯文本写库)。★改 dialogue 会自动失效本镜已生成的 TTS 配音与字幕(需重出 tts);改文本不会自动重出图/视频,如需让画面跟上文本改动,改完再 regen 对应镜。用 get_storyboards 查改后结果(每镜带 character_ids / character_bindings / scene_id / prop_ids / active_wardrobe_id / appearance_wardrobes);景别/机位/运镜/剪辑意图与提示词正文用 get_shot_prompts 逐镜回读。★★【换衣服改这里,不是改文字】出图穿什么由**服装绑定**决定:单人镜用 active_wardrobe_id(整镜一件),多人同框各穿各的用 appearance_wardrobes(逐角色)。把「穿某某衣服」写进 description/action 不会换衣服。服装 id 用 list_wardrobe 查;改完不会自动重出图,要让画面跟上需重生本镜首帧再重生视频。★★原声镜(厂商原生音频)改 dialogue 后,本镜视频会被标记「待重生」——因为台词是**烤进视频人声**的,不重生就终拼,成片里念的仍是改动前的台词(典型现象:台词像是跑到了别的镜头上)。compose_episode 会以 advisory `stale_video_after_edit` 列出这些镜;正确处置是先 regenerate_shot_video 再终拼。★也可直接改本镜的四条提示词正文(image_prompt/video_prompt/first_frame_prompt/last_frame_prompt):改前先用 get_shot_prompts 读现值,别凭空覆盖——正文里的 @char:N / @scene:M 是出图时的补充参考标记,照原样保留即可。★注入谁的定妆图由 character_ids 决定、背景由 scene_id 决定:删标记不会让已绑定的人从画面消失,要让某人不出现就改 character_ids,他只有声音(画外音)就用 character_presence 标 voice_only;反过来别给未绑定的角色写 @char 标记——会把他的图注入进来。★★【出尾帧被拦下就是来改这里】出尾帧若报「此镜标为状态改变,但没有任何地方说明结束时是什么样子」(TERMINAL_DESC_GATE),修法是把**结束时画面是什么样**写进本镜 last_frame_prompt,然后重新出尾帧。别去重试出图——这类镜(action_motion_class=state_change 却没写终态)的尾帧历史成功率 9.4%,有终态描述的是 40.2%;不补描述就重生,送厂商的提示词里根本没有终态段,画出来仍和首帧一样、还是会被拒,而每次重生都照常扣费。get_shot_prompts 的 terminal_desc_missing=true 就是这个信号。",
|
|
13273
13287
|
"tags": [
|
|
13274
13288
|
"storyboards"
|
|
13275
13289
|
],
|
|
@@ -13480,6 +13494,12 @@
|
|
|
13480
13494
|
"lighting": {
|
|
13481
13495
|
"type": "string"
|
|
13482
13496
|
},
|
|
13497
|
+
"sound_effect": {
|
|
13498
|
+
"type": [
|
|
13499
|
+
"string",
|
|
13500
|
+
"null"
|
|
13501
|
+
]
|
|
13502
|
+
},
|
|
13483
13503
|
"shot_type": {
|
|
13484
13504
|
"type": "string"
|
|
13485
13505
|
},
|
|
@@ -14330,7 +14350,7 @@
|
|
|
14330
14350
|
"post": {
|
|
14331
14351
|
"operationId": "adopt_frame_candidate",
|
|
14332
14352
|
"summary": "免费:人工采用一张已出完的首帧/尾帧候选(被审计拒掉 rejected、落选 dismissed,或曾经在用后被换下的 completed),作为本镜在用帧——审计误判时的人工兜底(例如作者契约写明的设定被判成冲突),也可随时换回之前那张",
|
|
14333
|
-
"description": "免费:人工采用一张已出完的首帧/尾帧候选(被审计拒掉 rejected、落选 dismissed,或曾经在用后被换下的 completed),作为本镜在用帧——审计误判时的人工兜底(例如作者契约写明的设定被判成冲突),也可随时换回之前那张。★必须先用 get_frame_candidates 让客户看过原图和拒因、客户明确同意采用后才调(采用被拒候选任何执行模式都须客户明确同意,托管也不例外)
|
|
14353
|
+
"description": "免费:人工采用一张已出完的首帧/尾帧候选(被审计拒掉 rejected、落选 dismissed,或曾经在用后被换下的 completed),作为本镜在用帧——审计误判时的人工兜底(例如作者契约写明的设定被判成冲突),也可随时换回之前那张。★必须先用 get_frame_candidates 让客户看过原图和拒因、客户明确同意采用后才调(采用被拒候选任何执行模式都须客户明确同意,托管也不例外);不许为了让流程走下去自行放行。★采用前先对照本镜分镜(get_storyboards 的 first_frame_prompt / last_frame_prompt / action_in / action_out / movement)确认:采首帧要是动作起点、采尾帧要是动作终点——首帧候选若已是动作终态(人已到位、动作已做完)或把运镜终点画进了起点,采用后视频里就没有动作过程,换一张或改提示词重出。只能采用本镜本帧位、已出完、有画面、且不是当前在用的那张;会在该候选上记录人工放行(谁/何时/原拒因),原拒因保留供统计。本镜已有视频的会标成待重生(视频是按旧帧出的,需 regenerate_shot_video)。本镜该帧是客户上传或已定稿的,要带 replace_user_frame:true 才会替换(并解除定稿)。同帧位有在途出图或本镜视频在途时返回 409,等它结束再采用。",
|
|
14334
14354
|
"tags": [
|
|
14335
14355
|
"storyboards"
|
|
14336
14356
|
],
|
|
@@ -14474,7 +14494,7 @@
|
|
|
14474
14494
|
"post": {
|
|
14475
14495
|
"operationId": "generate_shot_frame",
|
|
14476
14496
|
"summary": "确认后给**某一镜**出帧或重生该帧(异步)",
|
|
14477
|
-
"description": "确认后给**某一镜**出帧或重生该帧(异步)。这是修某一镜画面的正路:平台会带上该镜的角色身份锚、场景/道具参考图、画风锚与帧审计,重生出的图与全片一致;用外部工具出图再上传会绕开这整条链路,人物/服装/画风必漂。重生会覆盖该帧现有图(含此前上传的),并把本镜视频标为待重生。尾帧需本镜首帧已就绪(否则先用 first_frame 或 both)。完成判据:轮询 get_storyboards 看该镜 first_frame_image/last_frame_image
|
|
14497
|
+
"description": "确认后给**某一镜**出帧或重生该帧(异步)。这是修某一镜画面的正路:平台会带上该镜的角色身份锚、场景/道具参考图、画风锚与帧审计,重生出的图与全片一致;用外部工具出图再上传会绕开这整条链路,人物/服装/画风必漂。重生会覆盖该帧现有图(含此前上传的),并把本镜视频标为待重生。尾帧需本镜首帧已就绪(否则先用 first_frame 或 both)。完成判据:轮询 get_storyboards 看该镜 first_frame_image/last_frame_image 变化。★回执的 frames_dispatched 是真派出去的张数;both 的尾帧被平台判为不需要时会带 skipped_frames(没出、没扣尾帧的钱),原样告诉客户。出首帧的回执带 continuity(这次承接没承接上一镜、原因);continuity_mode 须与报价时一致,否则 409 重新报价。\n★继承重开(reopen_pair_id):get_storyboards 某镜带这个字段时,原样传进来可以只重掷首尾帧里真正有问题的那一侧——另一侧此前已经生成好的候选原样保留,不重新生成、不重新计费。传了它就不用再传 frame_type(会被忽略,由平台判定该重哪一侧);quote_id 仍要用 quote_shot_frame 报价(frame_type 传 first_frame 或 last_frame 均可,单帧同价)。若该镜没有 reopen_pair_id 字段(不满足继承条件),这个参数不要传,走常规 frame_type 重试。\n★★出尾帧若被拦下并提示「此镜标为状态改变,但没有任何地方说明结束时是什么样子」:正解是用 update_shot 把结束状态写进 last_frame_prompt 再出,**别直接加 allow_missing_terminal 硬上**——这类镜照现状出尾帧的历史成功率只有 9.4%(有终态描述的 40.2%),硬上多半是白扣一次钱。只有确认这一镜就是要「几乎不变」的画面时才带那个参数。\n★一键出片托管环节:同一镜重出帧最多 3 轮(一次调用算一轮,both 也算一轮),到上限回 **409 AUTOPILOT_SHOT_REGEN_LIMIT**(未派发、未扣费,quote 未消耗)——别换个工具绕,停下问客户:客户同意再出就照常报价、生成时带 customer_approved_more_regens:true(再给一份上限);客户接受现状就往下走,下一步收费调用带 acknowledge_review:true 记下确认。专业模式与客户把控的环节不受这个上限约束。\n★【分镜审查硬闸·免费】本步前必须先调 review_storyboards:把返回的 findings 逐条原样告诉客户(每条带 code=问题类型、shots=命中镜号、action=该调哪个工具修),再把 review_token 传进本工具。未审查会被 400 拒。审查后又改了内容 → token 自动失效,复审一次即可(仍免费)。单镜工具(generate_shot_frame / regenerate_shot_video)只核本镜与相邻镜:改了别的镜不用复审;本镜、相邻镜或共享资产变了才 400——这时带 base_review_token=<旧 token> 调审查工具做增量复审,只重审变更镜,质检也只看变更镜。有 error 时默认拦截;客户知情并坚持照现状继续,才带 acknowledge_review:true——带病推进大概率产出废片且照常扣费(acknowledge_review 只代表客户本人同意,任何执行模式都须客户明确同意,托管也不例外);托管环节只有白名单内的启发式 error 能带 auto_acknowledge:true 放行(平台判,不在白名单回 400 AUTOPILOT_MUST_ASK:must_ask_customer=true 才暂停问客户,false = 按 action 自修复审)。★灰度剧还要你(agent)亲自质检:按 review_storyboards 返回的 agent_qc 逐件看素材、逐条答清单,调 submit_qc_report 提交后这张 token 才能用(没交 → 400 agent_qc_required;报告有问题 → 与 error 同样默认拦)。\n★【资产层硬闸·免费】还要先跑 review_assets(角色形象图/场景图/道具图),把它的 review_token 作为 asset_review_token 传进来(与分镜层的 review_token 并存,两张都要;灰度剧缺了会 400 并点名 review_assets)。出完帧不会让资产 token 失效。⚠️ 批量报价确认流程:先调对应的 quote_* 工具拿 estimated_points 与 quote_id,再用 quote_id 调本工具(报价确认按执行模式:专业模式 / 未确认方案 / 本环节由客户把控 → 讲给客户、客户同意才做,别替客户决定;本环节托管 → 不问客户,照 get_production_plan 的 autopilot.default_decisions 执行,平台记进 get_autopilot_log)。托管环节报价须在预算硬上限内,被 402 BUDGET_WOULD_EXCEED 拦下就停下问客户。★**出图类报价(定妆图/场景图/出帧)给的是两个数**:estimated_points 是**上界**(按该模型参考图张数上限估,保证你不会按低了的预算开跑、出到一半 402 中断);同一响应里的 typical_points 是**通常花费**。两个都要告诉客户——只说上界会让人以为贵得多(满参考图的上界可达通常值的 2 倍以上),只说通常值又会让余额准备不足。固定价模型下两者相等,这时说一个数就行。出视频的报价与扣费同函数,不存在这个区间。",
|
|
14478
14498
|
"tags": [
|
|
14479
14499
|
"storyboards"
|
|
14480
14500
|
],
|
|
@@ -14532,6 +14552,17 @@
|
|
|
14532
14552
|
"allow_missing_terminal": {
|
|
14533
14553
|
"type": "boolean"
|
|
14534
14554
|
},
|
|
14555
|
+
"force_independent_last_frame": {
|
|
14556
|
+
"type": "boolean"
|
|
14557
|
+
},
|
|
14558
|
+
"continuity_mode": {
|
|
14559
|
+
"type": "string",
|
|
14560
|
+
"enum": [
|
|
14561
|
+
"auto",
|
|
14562
|
+
"independent",
|
|
14563
|
+
"follow_previous"
|
|
14564
|
+
]
|
|
14565
|
+
},
|
|
14535
14566
|
"allow_era_ref_conflict": {
|
|
14536
14567
|
"type": "boolean"
|
|
14537
14568
|
},
|
|
@@ -14992,7 +15023,7 @@
|
|
|
14992
15023
|
"post": {
|
|
14993
15024
|
"operationId": "quote_shot_frame",
|
|
14994
15025
|
"summary": "报价:重画/补出**某一镜的某一帧**要多少点(一帧=一张图)",
|
|
14995
|
-
"description": "报价:重画/补出**某一镜的某一帧**要多少点(一帧=一张图)。返回 estimated_points、quote_id。零扣费。客户说「第 N 镜画错了/要改」时用它,而不是拿别的图像平台出图再 upload_shot_frame。★响应带 billing_kind/unit_points(实际计费档与单价);要在 generate_shot_frame 里换模型,报价时传同一个 image_model。★两边必须传同一个 image_model —— 不一致会被直接拒(400 IMAGE_MODEL_MISMATCH),因为模型决定计费档,不同源就是「预估≠扣费」。两边都不传也算一致(用该剧设定的模型)。已下架的型号(FLUX 全系列)
|
|
15026
|
+
"description": "报价:重画/补出**某一镜的某一帧**要多少点(一帧=一张图)。返回 estimated_points、quote_id。零扣费。客户说「第 N 镜画错了/要改」时用它,而不是拿别的图像平台出图再 upload_shot_frame。★响应带 billing_kind/unit_points(实际计费档与单价);要在 generate_shot_frame 里换模型,报价时传同一个 image_model。★两边必须传同一个 image_model —— 不一致会被直接拒(400 IMAGE_MODEL_MISMATCH),因为模型决定计费档,不同源就是「预估≠扣费」。两边都不传也算一致(用该剧设定的模型)。已下架的型号(FLUX 全系列)一律拒收,别再传。★frame_type=both 时,平台判这一镜不需要独立尾帧(末态≈首态、没有运镜)会只出首帧:报价 frames_to_generate=1、只计首帧,并带 last_frame_skipped 说明原因——**原样告诉客户尾帧不会出**。客户确实要尾帧(例如起止画面不同的运镜)就报价与生成都带 force_independent_last_frame:true。★出首帧(first_frame/both)时响应带 continuity:follows_previous_shot=true 表示上一镜尾帧会钉在参考图第 1 位(承接上一镜的人物、姿势与机位),note 说明原因。这一镜不该接上一镜(跳切、换场、只拍手/道具的局部特写等),报价与生成都带 continuity_mode:'independent'。★返回两个数:estimated_points 是**上界**(按参考图张数上限估,拿它准备余额就不会中途 402),typical_points 是**通常花费**。两个都告诉客户,只报上界会让人以为贵得多。固定价模型(如 Nano Banana 系列)下两者相等。",
|
|
14996
15027
|
"tags": [
|
|
14997
15028
|
"storyboards"
|
|
14998
15029
|
],
|
|
@@ -15024,6 +15055,17 @@
|
|
|
15024
15055
|
},
|
|
15025
15056
|
"image_model": {
|
|
15026
15057
|
"type": "string"
|
|
15058
|
+
},
|
|
15059
|
+
"force_independent_last_frame": {
|
|
15060
|
+
"type": "boolean"
|
|
15061
|
+
},
|
|
15062
|
+
"continuity_mode": {
|
|
15063
|
+
"type": "string",
|
|
15064
|
+
"enum": [
|
|
15065
|
+
"auto",
|
|
15066
|
+
"independent",
|
|
15067
|
+
"follow_previous"
|
|
15068
|
+
]
|
|
15027
15069
|
}
|
|
15028
15070
|
}
|
|
15029
15071
|
}
|
|
@@ -15386,7 +15428,7 @@
|
|
|
15386
15428
|
"get": {
|
|
15387
15429
|
"operationId": "get_shot_prompts",
|
|
15388
15430
|
"summary": "读某一镜的四条提示词**正文**(image_prompt=首帧画面 / video_prompt=动态表演 / first_frame_prompt=开始时什么样 / last_frame_prompt=结束时什么样),供直接微调后用 u",
|
|
15389
|
-
"description": "读某一镜的四条提示词**正文**(image_prompt=首帧画面 / video_prompt=动态表演 / first_frame_prompt=开始时什么样 / last_frame_prompt=结束时什么样),供直接微调后用 update_shot 写回。免费。★回执里的 terminal_desc_missing=true 表示本镜标为「状态改变」却三处都没说终态——出尾帧会被前置闸拦下,修法是把结束状态写进 last_frame_prompt(别重试出图,重试必然重复被拒且照常扣费)。★pose_timeline_stale 非 null = 本镜动作起止姿态里的秒数时间轴超出了当前时长(多见于改短 duration 后),出视频时那一端已自动不送;新时间轴写进 video_prompt。★同时回 description(画面描述)
|
|
15431
|
+
"description": "读某一镜的四条提示词**正文**(image_prompt=首帧画面 / video_prompt=动态表演 / first_frame_prompt=开始时什么样 / last_frame_prompt=结束时什么样),供直接微调后用 update_shot 写回。免费。★回执里的 terminal_desc_missing=true 表示本镜标为「状态改变」却三处都没说终态——出尾帧会被前置闸拦下,修法是把结束状态写进 last_frame_prompt(别重试出图,重试必然重复被拒且照常扣费)。★pose_timeline_stale 非 null = 本镜动作起止姿态里的秒数时间轴超出了当前时长(多见于改短 duration 后),出视频时那一端已自动不送;新时间轴写进 video_prompt。★同时回 description(画面描述)、lighting(本镜用光)与 sound_effect(本镜音效)现值——review_storyboards 的禁区词命中常在 description / sound_effect,改前先在这里读;用光写 lighting。★同时回 shot_type(景别)/ angle(机位)/ camera_movement(运镜)/ continuity_intent(剪辑意图)现值——update_shot 改完这几项就在这里回读核对(整集 get_storyboards 不含它们);null=未设。★同时回 expression_hint(本镜作者指定的面部表情,null=未指定、由平台按台词反推),改它用 update_shot。expression_inferred 是拆镜 AI 在剧本没写神态时按本镜内容推断的表情(只读;null=没推断,或本镜台词/动作/氛围/描述/强度改过、推断已过期不再使用);它优先级低于 expression_hint——推断不合意就用 update_shot 写 expression_hint 覆盖它。★逐镜按需:改哪镜读哪镜(整集列表 get_storyboards 不含提示词)。★返回的 asset_tokens 是正文里的补充参考标记(@char:N / @scene:M),改写时原样保留即可:本镜注入谁的定妆图由绑定决定(get_storyboards 的 character_ids / scene_id),删标记不会让已绑定的人消失;带 #变体 的标记是那张变体图的唯一来源;给未绑定的角色写标记会把他的图注入进来。★这是分镜表里的正文层;出图/出视频时平台还会在其上拼身份锚、一致性约束与参考图指令(不在此处,也无需你写)。改完提示词不会自动重出图/视频,要让画面跟上得再 regen 对应镜。",
|
|
15390
15432
|
"tags": [
|
|
15391
15433
|
"storyboards"
|
|
15392
15434
|
],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@starreel/mcp",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.231",
|
|
4
4
|
"mcpName": "ai.starreel/starreel",
|
|
5
5
|
"description": "StarReel MCP server — drive the AI short-drama production pipeline (script → storyboards → frames → video → final cut) from Claude, Cursor, or any MCP client",
|
|
6
6
|
"license": "MIT",
|
package/server.json
CHANGED
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json",
|
|
3
3
|
"name": "ai.starreel/starreel",
|
|
4
4
|
"description": "Turn a script into a finished, downloadable short-drama episode — via MCP or REST.",
|
|
5
|
-
"version": "0.1.
|
|
5
|
+
"version": "0.1.231",
|
|
6
6
|
"websiteUrl": "https://starreel.ai",
|
|
7
7
|
"packages": [
|
|
8
8
|
{
|
|
9
9
|
"registryType": "npm",
|
|
10
10
|
"identifier": "@starreel/mcp",
|
|
11
|
-
"version": "0.1.
|
|
11
|
+
"version": "0.1.231",
|
|
12
12
|
"transport": {
|
|
13
13
|
"type": "stdio"
|
|
14
14
|
},
|