@starreel/mcp 0.1.177 → 0.1.189

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.
@@ -71,16 +71,23 @@ const QUOTE_RANGE_HINT = '★返回两个数:estimated_points 是**上界**(按
71
71
  const REVIEW_GATE_HINT = (tool, layer) => `\n★【${layer}审查硬闸·免费】本步前必须先调 ${tool}:把返回的 findings 逐条原样告诉客户` +
72
72
  `(每条带 code=问题类型、shots=命中镜号、action=该调哪个工具修),再把 review_token 传进本工具。` +
73
73
  `未审查会被 400 拒。审查后又改了内容 → token 自动失效,复审一次即可(仍免费)。` +
74
+ `单镜工具(generate_shot_frame / regenerate_shot_video)只核本镜与相邻镜:改了别的镜不用复审;本镜、相邻镜或共享资产变了才 400——` +
75
+ `这时带 base_review_token=<旧 token> 调审查工具做增量复审,只重审变更镜,质检也只看变更镜。` +
74
76
  `有 error 时默认拦截;客户知情并坚持照现状继续,才带 acknowledge_review:true——` +
75
77
  `带病推进大概率产出废片且照常扣费${ALWAYS_ASK('acknowledge_review 只代表客户本人同意,')};` +
76
78
  `托管环节只有白名单内的启发式 error 能带 auto_acknowledge:true 放行(平台判,不在白名单回 400 AUTOPILOT_MUST_ASK:must_ask_customer=true 才暂停问客户,false = 按 action 自修复审)。` +
77
79
  `★灰度剧还要你(agent)亲自质检:按 ${tool} 返回的 agent_qc 逐件看素材、逐条答清单,调 submit_qc_report 提交后这张 token 才能用` +
78
80
  `(没交 → 400 agent_qc_required;报告有问题 → 与 error 同样默认拦)。`;
79
81
  /** 五个审查工具共用:平台审查之外,外部 agent 亲自看素材的质检(2026-10-14 用户拍板)。 */
80
- const AGENT_QC_HINT = '\n★【agent 亲自质检·免费】返回的 agent_qc 里有本层清单(checklist)和本集要看的素材(materials,每件一个 ref,图/视频给链接)。' +
82
+ const AGENT_QC_HINT = '\n★【增量复审·省时省量】review_storyboards / review_frames / review_assets 可带 base_review_token(上一张已交质检且 verdict=pass 的本层 token):' +
83
+ '只把变更镜及其相邻镜列进 agent_qc.materials、findings 只回这些镜(incremental.applied=true,另有 findings_hidden 计数),质检报告只需覆盖它们;' +
84
+ '共享资产变了、base 没质检通过时自动退回整集(incremental.reason 说明原因)。改一两镜后别整集重审。' +
85
+ '\n★【agent 亲自质检·免费】返回的 agent_qc 里有本层清单(checklist)和本集要看的素材(materials,每件一个 ref,图/视频给链接)。' +
81
86
  '平台只判「有没有、在不在、被没被拒」,「像不像、对不对、好不好」要你自己看:图片下载打开看、视频至少抽开头/中间/结尾帧、文本用 tool 通读。' +
82
87
  '逐条回答清单(ok / issue / na,issue 写明哪件什么问题),看过的每个 ref 都列进 inspected,调 submit_qc_report 提交;质检结论原样讲给客户。' +
83
88
  'agent_qc.required=true 时没提交报告这张 review_token 进不了下一步(400 agent_qc_required),报告有问题与平台 error 同样默认拦。';
89
+ /** 增量复审(缺口 #16):上一张本层 token,已交质检且 pass 时只重审变更镜。 */
90
+ const BASE_REVIEW_ARG = z.string().optional().describe('增量复审:上一张本层 review_token(已交 agent 质检且 verdict=pass)。带上只重审变更镜及其相邻镜,素材与质检只覆盖它们;不满足条件自动退回整集');
84
91
  /** 资产层 token:出镜头图同时要分镜层(review_token)与资产层两张,资产层这张单独一个参数。 */
85
92
  const ASSET_REVIEW_ARG = {
86
93
  asset_review_token: z.string().optional().describe('★来自 review_assets 的凭据(资产层硬闸:角色形象图/场景图/道具图;灰度剧必填,缺了 400 会点名 review_assets)。与分镜层的 review_token 一起传'),
@@ -214,7 +221,7 @@ export const WORKFLOW_HINT = AUTOPILOT_HINT +
214
221
  '★★【单镜路径同样受审查闸】:generate_shot_frame 同样要带分镜层 review_token,regenerate_shot_video 同样要带镜头图片层 review_token——' +
215
222
  '别指望用逐镜工具绕开审查(实测有整集 25 镜全靠单镜出帧、一道闸都没碰到的做法,成片返工全是真扣费)。' +
216
223
  '出完帧**不会**让分镜层 token 失效(指纹只看分镜内容);只有改了分镜内容——update_shot / 导入 / 增删镜 / 改角色绑定——才要复审一次(免费、秒级)。' +
217
- '出完一镜的帧会让**镜头图片层** token 失效,下一镜 regenerate_shot_video 前 review_frames 一次即可。' +
224
+ '出完一镜的帧只让本镜与相邻镜的**镜头图片层** token 失效;要对它们 regenerate_shot_video 时带 base_review_token 增量 review_frames 即可。' +
218
225
  '★★【原声剧先锁声线,再批量出视频】use_clip_audio=true(默认)时每镜嗓音由视频厂商各自采样,不锁必漂,事后统一要逐镜重出。' +
219
226
  '有客户授权音源→clone_voice+set_character_voice,在 generate_videos 之前;没有→每个说话角色先用单镜工具 quote_regenerate_shot_video→regenerate_shot_video 出一镜台词较长的' +
220
227
  '(generate_videos 没有按镜参数、只批量补缺视频的镜;单镜重生对还没有视频的镜同样可用),' +
@@ -801,26 +808,27 @@ export function registerProduceTools(server, client) {
801
808
  '★code=forbidden_term 的 finding 带 `terms` 字段(命中的具体词,如「背景音乐」「强光」)与 `shots`(镜号),' +
802
809
  '照着这两个去 update_shot 改掉即可,不用逐字猜。' +
803
810
  '★禁区词判**否定语义**:写「无背景音乐」「不要配乐」不算违规(那是在遵守约束),不必为此改稿。' +
804
- '★warnings 里的「动作过载」(action_overload,advisory 不拦):一镜塞了超过时长承载量的独立动作,出视频前用 split_shot 拆开或删动作——成片后靠慢放/叠化补救不了。多人各做一件事或本身连贯的一串可忽略。' + AGENT_QC_HINT, { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.producePost(`/episodes/${episode_id}/review/storyboards`)));
811
+ '★warnings 里的「动作过载」(action_overload,advisory 不拦):一镜塞了超过时长承载量的独立动作,出视频前用 split_shot 拆开或删动作——成片后靠慢放/叠化补救不了。多人各做一件事或本身连贯的一串可忽略。' + AGENT_QC_HINT, { episode_id: z.number().int().positive(), base_review_token: BASE_REVIEW_ARG }, async ({ episode_id, base_review_token }) => jsonResult(await client.producePost(`/episodes/${episode_id}/review/storyboards`, base_review_token ? { base_review_token } : undefined)));
805
812
  server.tool('review_frames', '【第③道硬闸·免费】审查镜头图片层:角色身份锚覆盖(缺定妆图的角色在镜头里必漂)、出图失败率、' +
806
813
  '孤儿角色变体、场景图被人物污染。★generate_videos 之前必须先跑本工具——出视频是全链最贵的一步,' +
807
814
  '拿着漂移的首帧整集出视频是最典型的废片形态。按 findings.action 修完(多为 generate_character_portraits / ' +
808
815
  'generate_shot_frame 单镜重生)再复审。' +
809
816
  '★还会报**镜间接缝**(warning,不拦):code=seam_unchained(标了连续却从没做过首尾帧衔接,或发起的衔接重生没落地 / 衔接后首帧又被重生)/' +
810
817
  'seam_broken(接过但没接上,或上一镜尾帧在衔接之后又重生过),shots 是「与上一镜的缝有问题」的那一镜。出视频前修最便宜——视频按首帧生成,' +
811
- '首帧与上镜尾帧对不上,成片就是一次跳切。修法看 action(整集 chain_frames 先 dry_run;单道 chain_shot_from_prev / chain_shot_from)。' + AGENT_QC_HINT, { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.producePost(`/episodes/${episode_id}/review/frames`)));
818
+ '首帧与上镜尾帧对不上,成片就是一次跳切。修法看 action(整集 chain_frames 先 dry_run;单道 chain_shot_from_prev / chain_shot_from)。' + AGENT_QC_HINT, { episode_id: z.number().int().positive(), base_review_token: BASE_REVIEW_ARG }, async ({ episode_id, base_review_token }) => jsonResult(await client.producePost(`/episodes/${episode_id}/review/frames`, base_review_token ? { base_review_token } : undefined)));
812
819
  server.tool('review_assets', '【资产层硬闸·免费】审查本集**出镜**用到的角色形象图、场景图、道具图——覆盖与质量:' +
813
820
  '出镜角色缺定妆图 / 缺设定图 / 还在生成 / 生成失败 / 设定图被一致性闸拒收(hint 带拒收理由);' +
814
821
  '场景缺空景基板;分镜引用的道具缺道具图 / 被拒;道具图与本镜时代形制冲突;缺色彩脚本(warning)。' +
815
822
  '★出完定妆图、设定图、场景图、道具图后都调一次;generate_frames / generate_shot_frame 之前必须审过——' +
816
823
  '把返回的 review_token 作为 **asset_review_token**,连同分镜层的 review_token 一起传(两张都要)。' +
817
824
  '只看资产本身:出完镜头图不会让它失效;换了定妆图/场景图/道具图会失效,复审即可(免费、秒级)。' +
818
- 'findings 逐条讲给客户(code=问题类型、names=哪个角色/场景/道具、shots=影响的镜号、action=该调哪个工具修)。' + AGENT_QC_HINT, { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.producePost(`/episodes/${episode_id}/review/assets`)));
825
+ 'findings 逐条讲给客户(code=问题类型、names=哪个角色/场景/道具、shots=影响的镜号、action=该调哪个工具修)。' + AGENT_QC_HINT, { episode_id: z.number().int().positive(), base_review_token: BASE_REVIEW_ARG }, async ({ episode_id, base_review_token }) => jsonResult(await client.producePost(`/episodes/${episode_id}/review/assets`, base_review_token ? { base_review_token } : undefined)));
819
826
  server.tool('review_videos', '【视频与配音层硬闸·免费】审查本集视频与配音——覆盖与质量:缺视频 / 还在生成 / 生成失败 / 被厂商拒;' +
820
827
  '首帧换过而视频还是旧帧出的(video_stale);疑似片尾硬切、无台词镜意外人声(warning);' +
821
828
  '配音剧:台词镜缺配音、会开口的角色没音色、缺旁白角色;原声剧:出片时没挂上当前声线的镜、没锁声线的角色;缺配乐(warning)。' +
822
829
  '★出完视频、配音(generate_tts)、配乐后都调一次;compose_episode 之前必须审过,带返回的 review_token。' +
823
- '更细的检查(要解码画面/音轨)另有 scan_intra_shot_cuts / scan_dialogue_coverage / audit_silent_shot_audio;拼完成片再跑 review_final_cut。' + AGENT_QC_HINT, { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.producePost(`/episodes/${episode_id}/review/videos`)));
830
+ '更细的检查(要解码画面/音轨)另有 scan_intra_shot_cuts / scan_dialogue_coverage / audit_silent_shot_audio;拼完成片再跑 review_final_cut。' +
831
+ '★返回带 post_production_advisory = 剧本标注「后期」的叙事必需特效还没处理(平台不会合成):原样告诉客户,用 get_post_production_checklist 看清单。' + AGENT_QC_HINT, { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.producePost(`/episodes/${episode_id}/review/videos`)));
824
832
  server.tool('submit_qc_report', '提交你(agent)亲自看素材做的质检报告。免费。先调对应层的 review_*(script / storyboards / assets / frames / videos),' +
825
833
  '按返回的 agent_qc 逐件打开 materials 看、逐条回答 checklist,再调本工具。' +
826
834
  '★平台只校验报告**是否完整**,不评判你的结论:checklist 每个 id 都要答(ok / issue / na,issue 必须写 note 说清哪件什么问题);' +
@@ -986,7 +994,7 @@ export function registerProduceTools(server, client) {
986
994
  server.tool('compose_episode', '把某一集所有镜头视频拼成一条成片(终拼)。**免费**(纯拼接,无需报价确认),后台异步。' +
987
995
  '发起前有终拼预检:缺视频的镜或仍在生成中的视频任务会 400 硬阻断并列出问题镜(blockers),' +
988
996
  '补齐后重试;确要拼部分成片传 force=true(缺视频镜被跳过,成片缺镜,留痕)。' +
989
- '响应里的 advisories(时长偏差/孤儿任务/缺TTS)只提醒不阻断,建议逐条处理后再拼。发起后用 get_final_cut 轮询。' +
997
+ '响应里的 advisories(时长偏差/孤儿任务/缺TTS/post_production_pending 后期特效未完成)只提醒不阻断,建议逐条处理后再拼。发起后用 get_final_cut 轮询。' +
990
998
  REVIEW_GATE_HINT('review_videos', '视频与配音') +
991
999
  '\n★【完成后质检·免费】成片出来后跑 review_final_cut(缺镜/字幕放不下/身份锚/跳轴/错别字,proofread=false 则不扣费),' +
992
1000
  '结论讲给客户;客户确认后才 confirm_delivery_acceptance' + ALWAYS_ASK('交付验收') + '。force 只越过终拼预检,不越过审查闸。', {
@@ -1749,6 +1757,20 @@ export function registerProduceTools(server, client) {
1749
1757
  + 'account_overdue 不是你的点数问题,停下告知用户稍后再试,别反复重提;'
1750
1758
  + 'model_unavailable=所选视频模型的厂商已暂停或暂不可用,error 里列了可用的替代模型,问用户后换模型再提。'
1751
1759
  + '\n★带 **verify_rejected** = 这些镜换完复核没通过(断音/重复念/念错),产物没写回、费用已退——换音修不好,改 regenerate_shot_video。', { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.produceGet(`/episodes/${episode_id}/dialogue-repair-status`)));
1760
+ server.tool('get_post_production_checklist', '读本集的**后期特效清单**(免费)。剧本里 [VFX: …] 标注、分镜提示词里写「后期 / postproduction / composited later」的项,' +
1761
+ '**平台不会自动合成**——出图出视频按约束把它们留空,终拼也不补,不处理成片就缺这些叙事元素。' +
1762
+ '逐项给:镜号 shot_number、时间 start_s~end_s、内容 content、来源 source(vfx_tag 分镜标注 / prompt 提示词 / script_unassigned 改写稿里有但没落到任何镜)、' +
1763
+ 'narrative_required(叙事必需;画质类如调色为 false)、status(pending / done_external / waived)。' +
1764
+ '★拼成片前看一遍,把 narrative_required 的 pending 项讲给客户,问他:外部后期做(做完后 mark_post_production_item 标 done_external)、' +
1765
+ '改分镜让平台直接画出来(update_shot 改提示词后重出该镜)、或放弃(标 waived)。review_videos / compose_episode 会对未处理项给 advisory。', { episode_id: z.number().int().positive() }, async ({ episode_id }) => jsonResult(await client.produceGet(`/episodes/${episode_id}/post-production-checklist`)));
1766
+ server.tool('mark_post_production_item', '给后期特效清单里的一项打标记(免费):status=done_external(客户已在平台外完成)/ waived(客户决定不做)/ pending(撤销标记)。' +
1767
+ 'key 取自 get_post_production_checklist;分镜或提示词改过后 key 会变,400 时重读清单。' + ALWAYS_ASK('标记后期项') +
1768
+ '——标记只是记账,不会改成片;客户说外部做完了,成片要用外部那一版就走 register_external_delivery。', {
1769
+ episode_id: z.number().int().positive(),
1770
+ key: z.string().min(1).describe('清单项的 key'),
1771
+ status: z.enum(['done_external', 'waived', 'pending']),
1772
+ note: z.string().max(500).optional().describe('备注,如外部完成的工具/版本'),
1773
+ }, async ({ episode_id, key, status, note }) => jsonResult(await client.producePost(`/episodes/${episode_id}/post-production-checklist/mark`, { key, status, ...(note ? { note } : {}) })));
1752
1774
  server.tool('get_shot_name_card', '读这一镜的**人物名片**现值(免费):名字、头衔、显示位置那些。'
1753
1775
  + '\n★改之前先读一遍——set_shot_name_card 是**整体覆盖**,不读就改会把没打算动的字段清掉。', { storyboard_id: z.number().int().positive() }, async ({ storyboard_id }) => jsonResult(await client.produceGet(`/storyboards/${storyboard_id}/name-card`)));
1754
1776
  server.tool('generate_bgm', '给整集生成/更换 AI 配乐(按情绪弧线)。后台异步,按用量后付不欠费。返回情绪弧线段数与预估耗时;' +