@starreel/mcp 0.1.158 → 0.1.161

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.
@@ -17,6 +17,7 @@ import { tmpdir } from 'node:os';
17
17
  import { dirname, join } from 'node:path';
18
18
  import { fileURLToPath } from 'node:url';
19
19
  import { assertSafeToolchainDir, TOOLCHAIN_FILENAMES } from '../path-guard.js';
20
+ import { SEEDANCE25_PHOTOREAL_NOTE } from './guide-data.js';
20
21
  const TOOLCHAIN_USAGE = [
21
22
  '1. 三个脚本放同一目录(assemble.sh 需可执行位)。',
22
23
  '2. 把 export_handoff_pack 的返回体存成 manifest.json。',
@@ -197,7 +198,7 @@ export const WORKFLOW_HINT = '★三档执行策略(别把三档混着问客户)
197
198
  'gemini-3.1-flash-lite-image(香蕉2 Lite·便宜·31点)/doubao-seedream-5-0-260128(Seedream5.0);generate_frames 可临时覆盖某次。' +
198
199
  '★2.5 按输入量计费(基础11点+每张参考图18点),香蕉/Seedream 是一口价——参考图多的镜头要把这笔算进预算。' +
199
200
  '★视频引擎四选一(drama级·AI 建剧时必须主动按剧选型引导并给价差让客户定):' +
200
- '【选型决策树】①写实真人剧→seedance-2.5(默认·指令遵循/人脸细节最强·720p 212点/秒),预算敏感可 hailuo-3(约1/3成本70点/秒·强保真编辑·但单镜约6分钟);' +
201
+ '【选型决策树】①写实真人剧→hailuo-3(约1/3成本70点/秒·强保真编辑·可出2K·但单镜约6分钟;不传 video_engine 时平台按画风自动选它);' + SEEDANCE25_PHOTOREAL_NOTE + '(动漫/风格化剧仍默认 seedance-2.5,指令遵循/细节最强·720p 212点/秒);' +
201
202
  '②风格化/动画/3D卡通剧·空镜·产品镜→wan3.0(约4折84点/秒·最长30秒·最短2秒计费·单镜约2分钟),赶交付用 wan3.0-prime(126点/秒·约1分钟);' +
202
203
  '③★写实真人剧绝不选 wan3.0/prime——WAN 输出侧真人脸审核在 720p+ 一致拒、重试救不回;' +
203
204
  '④★★叙事剧(有对白、讲连贯故事、镜头节奏要稳的)慎选 wan3.0/prime:WAN 会在**单个分镜片内自行换机位硬切**' +
@@ -239,7 +240,13 @@ export const WORKFLOW_HINT = '★三档执行策略(别把三档混着问客户)
239
240
  '★两条导入通道都是确定性的——写错了也会原样建进去,所以**先取契约再自检再导**:分镜表走 get_storyboard_table_spec → check_storyboard_table → import_storyboard_table;' +
240
241
  '客户自己的工具/表格能导出结构化数据、或让外部 AI 直接产 JSON 时走 get_bulk_import_spec → check_bulk_import → bulk_import_storyboards(只建分镜;角色/场景/道具由 extract_assets 从剧本提取,导入按名字绑定已有的——先 extract 再导)。' +
241
242
  '两条导入默认带 auto_complete(后台 AI 补专业字段 + 出图/视频提示词,文本步后付,调用前告知客户):回执 started=true 就用 get_autofill_status 轮询到 done 再 review_storyboards——补全会改镜,先审的 token 会失效。' +
242
- '用 get_pipeline_status 查进度(按项目类型返回专属步骤)。';
243
+ '用 get_pipeline_status 查进度(按项目类型返回专属步骤)。' +
244
+ '★★【开场方案·建剧后第一件事·免费】先问基本视频参数(项目类型/画幅/集数×每集分钟/题材:写实真人 realistic_human·动漫风格化 stylized·产品空镜 product/原声还是配音),' +
245
+ '再调 get_production_menu 拿**当前可用**的三档套餐(效果说明+实时预估+不计入项)讲给客户——别凭记忆推荐模型,某些模型对某些题材会临时不可用,菜单已过滤;' +
246
+ '然后让客户选执行模式(pro 每步自己把控 / auto 一键出片 / custom 选环节托管)、预算 budget_points 与自动追加上限(0/10/20/30%),' +
247
+ '把汇总讲清楚、客户明确同意后才调 confirm_production_plan(customer_confirmed:true)——不许替客户确认。' +
248
+ '确认过方案的剧:收费派发前平台复核模型仍可用、报价上界不超过预算×(1+追加%),被拦(402 BUDGET_WOULD_EXCEED / 409 MODEL_UNAVAILABLE)就停下问客户,别自己换模型或调预算。' +
249
+ 'confirm 返回 403 PRODUCTION_PLAN_NOT_OPEN = 本剧未开放(灰度),照原流程逐步确认。';
243
250
  const ETHNICITY_CODES = [
244
251
  'east_asian', 'southeast_asian', 'south_asian', 'central_asian',
245
252
  'caucasian', 'middle_eastern', 'african', 'latin_american',
@@ -282,8 +289,9 @@ const PROJECT_SETTINGS_FIELDS = {
282
289
  'gemini-3.1-flash-image(香蕉2·71点)/gemini-3-pro-image(香蕉Pro·精细·175点)/gemini-3.1-flash-lite-image(香蕉2 Lite·31点)/' +
283
290
  'doubao-seedream-5-0-260128(Seedream 5.0)。建剧即定、整剧统一;generate_frames 可临时覆盖某次出图。★各模型实测优劣(一次过率/手部结构/安全拒绝率/画风稳定度)与选型步骤见 get_capabilities_guide(section=model_guide)'),
284
291
  // drama 级视频引擎(整剧统一,单镜/批量/场景组/重生全走它;按镜例外入口:quote_videos 的 shot_engines / quote_regenerate_shot_video 的 model / edit_video_shot 的 model)
285
- video_engine: z.enum(VIDEO_ENGINES).optional().describe('视频引擎(★drama级·整剧统一·AI必须按剧选型主动引导:写实真人剧→seedance-2.5 或降本 hailuo-3;风格化/动画/3D卡通/空镜/产品镜→wan3.0(赶交付 wan3.0-prime);写实真人剧绝不选 wan——720p+ 真人脸被厂商审核一致拒):' +
286
- 'seedance-2.5(默认·全能力:帧链/场景组/就地编辑/延长/参考图锚·720p约212点/秒) / ' +
292
+ video_engine: z.enum(VIDEO_ENGINES).optional().describe('视频引擎(★drama级·整剧统一·AI必须按剧选型主动引导:写实真人剧→hailuo-3(' + SEEDANCE25_PHOTOREAL_NOTE + ');风格化/动画/3D卡通/空镜/产品镜→wan3.0(赶交付 wan3.0-prime);写实真人剧绝不选 wan——720p+ 真人脸被厂商审核一致拒):' +
293
+ 'seedance-2.5(动漫/风格化剧默认·全能力:帧链/场景组/就地编辑/延长/参考图锚·720p约212点/秒;真人题材暂未开放) / ' +
294
+ '★不传时平台按画风自动选:写实/未定画风→hailuo-3,动漫/风格化→seedance-2.5。' +
287
295
  'hailuo-3(MiniMax H3:约1/3成本 720p 70点/秒·原生对白与音效·支持2K·单镜约6分钟·支持就地编辑(强保真)与成片续写·关键帧组/时间戳区间暂不可用;编辑/续写输入视频另按秒计费) / ' +
288
296
  'wan3.0(WAN 3.0:约4折成本 720p 84点/秒·原生对白与音效·支持1080P·单次最长30秒·最短2秒计费·支持就地编辑(强语义)与成片续写·关键帧组/时间戳区间暂不可用;★写实真人720p+可能被厂商审核拒绝,风格化/动画剧适用;★★会在单个分镜片内自行换机位硬切(实测11/12镜)→叙事剧慎用,详见选型决策树④) / ' +
289
297
  'wan3.0-prime(WAN 3.0 高速版:能力同wan3.0·出片约2×·费率1.5×=720p 126点/秒;镜内自剪同 wan3.0)。' +
@@ -1871,6 +1879,66 @@ export function registerProduceTools(server, client) {
1871
1879
  'spent_source=usage_mirror 表示账本暂不可达、回退到本地镜像(偏少,不含文本/配乐),向客户报数时须注明。' +
1872
1880
  '★不含账号级语音扣费:音色库克隆、音色设计、音色试听不属于任何一部剧,只记在账号账单里——' +
1873
1881
  '客户问「一共花了多少」时要说明这部分另计,不要把 spent 当成全部费用。', { drama_id: z.number().int().positive() }, async ({ drama_id }) => jsonResult(await client.produceGet(`/dramas/${drama_id}/budget-status`)));
1882
+ // ========== 一键出片开场方案(2026-10-15)==========
1883
+ server.tool('get_production_menu', '★开场第二步(免费·只读·不需要剧号):按客户的基本视频参数,返回**当前可用**的三档模型套餐(省钱/标准/高品质)。' +
1884
+ '每档给:图片模型+视频引擎+分辨率、效果说明(effect)、实时预估(estimate:每集与全剧的 typical 通常花费与 upper 上界,breakdown 分项)、' +
1885
+ 'warnings(所选模型近期繁忙/失败偏多)、substitutions(本档首选模型暂不可用、退到后备组合的原因)。' +
1886
+ '某档 available=false 表示该档模型当前都不可用(unavailable_reason 说明),别推荐它。' +
1887
+ 'estimate=null 表示价格服务暂时取不到实时单价——如实告诉客户「暂时估不出」,别自己编数字。' +
1888
+ 'not_included 列出不在预估里的花费(文本步、配音配乐、质检重出),一并讲给客户;质检重出这部分正是「自动追加」兜底的。' +
1889
+ 'availability 是全部模型对该题材的可用性(专业客户自选模型时用,unavailable 的不能选)。' +
1890
+ '★题材 content_class 决定可用性:同一引擎可能动漫可用、写实真人暂不可用——按剧情实际画面选,别为了用某个模型改题材。', {
1891
+ content_class: z.enum(['realistic_human', 'stylized', 'product']).describe('题材:realistic_human 写实真人 / stylized 动漫·风格化 / product 产品·空镜'),
1892
+ episodes: z.number().int().min(1).max(200).describe('集数'),
1893
+ minutes_per_episode: z.number().positive().max(30).describe('每集时长(分钟),预估按每镜约 5.3 秒折算镜数'),
1894
+ aspect_ratio: z.string().optional().describe('画幅,如 9:16 / 16:9(只影响视频报价)'),
1895
+ assets: z.object({
1896
+ characters: z.number().int().min(0).max(100).optional(),
1897
+ scenes: z.number().int().min(0).max(200).optional(),
1898
+ props: z.number().int().min(0).max(200).optional(),
1899
+ }).optional().describe('资产图粗估的数量假设(默认 6 角色/8 场景/6 道具),知道大概数量就传,预估更准'),
1900
+ }, async (args) => jsonResult(await client.producePost('/production-menu', args)));
1901
+ server.tool('confirm_production_plan', '★开场最后一步:把客户**明确同意**的整份方案写进本剧(免费)。写入图片模型/视频引擎/分辨率/预算,并记录题材、执行模式、自动追加上限与确认快照。' +
1902
+ '调用前必须把汇总完整讲给客户:所选套餐与效果、全剧预估(通常值与上界)、执行模式、预算、追加比例,以及「追加只在预算用完后才动用、到硬上限会停下来问」——客户点头才传 customer_confirmed:true。' +
1903
+ '★确认后平台在每次收费派发前复核:①本剧模型对本剧题材仍可用,否则 409 MODEL_UNAVAILABLE;②报价上界+已花 ≤ 预算×(1+追加%),否则 402 BUDGET_WOULD_EXCEED(都未扣费)。' +
1904
+ '被拦就停下问客户,别自己换模型、别自己调预算。' +
1905
+ '★执行模式本期只记录:各层审查(review_*)与 agent 质检照旧,error 照旧要客户知情才能 acknowledge_review。' +
1906
+ '★选套餐要带 expected_combo(该档 combo 原样)与 expected_total_upper:确认的必须是客户看到的那组模型与预估。' +
1907
+ '409 PACKAGE_CHANGED = 菜单返回后该档换了组合或预估明显上涨,返回体里有新的组合与预估,重新讲给客户、同意后带新值再确认;' +
1908
+ '409 PACKAGE_UNAVAILABLE / MODEL_UNAVAILABLE = 确认这一刻该模型不可用了,重新 get_production_menu 让客户改选。403 PRODUCTION_PLAN_NOT_OPEN = 本剧未开放(灰度),照原流程逐步确认。', {
1909
+ drama_id: z.number().int().positive(),
1910
+ customer_confirmed: z.literal(true).describe('客户已听完汇总并明确同意(必须为 true;不许替客户确认)'),
1911
+ content_class: z.enum(['realistic_human', 'stylized', 'product']),
1912
+ package_key: z.enum(['economy', 'standard', 'premium']).optional().describe('选菜单里的一档;与 custom 二选一'),
1913
+ expected_combo: z.object({
1914
+ image_model: z.string(),
1915
+ video_engine: z.string(),
1916
+ video_resolution: z.string(),
1917
+ }).optional().describe('选 package_key 时必填:把 get_production_menu 里该档的 combo 原样传回。确认这一刻若该档已换成别的组合,平台回 409 PACKAGE_CHANGED、不写入'),
1918
+ expected_total_upper: z.number().positive().optional().describe('该档的 estimate.total.upper(客户看到的全剧预估上界)。重算后涨幅超过 5% 也会 409 PACKAGE_CHANGED'),
1919
+ assets: z.object({
1920
+ characters: z.number().int().min(0).max(200).optional(),
1921
+ scenes: z.number().int().min(0).max(200).optional(),
1922
+ props: z.number().int().min(0).max(200).optional(),
1923
+ }).optional().describe('调 get_production_menu 时传过 assets 就原样再传一次,否则按默认数量重算的预估对不上客户看到的'),
1924
+ custom: z.object({
1925
+ image_model: z.string(),
1926
+ video_engine: z.string(),
1927
+ video_resolution: z.enum(['480p', '720p', '1080p']).optional(),
1928
+ }).optional().describe('专业客户自选模型(须在 get_production_menu 的 availability 里是可用的);与 package_key 二选一'),
1929
+ execution_mode: z.enum(['pro', 'auto', 'custom']).describe('pro 每步客户把控 / auto 一键出片 / custom 按环节选托管'),
1930
+ stage_control: z.object({
1931
+ script: z.enum(['customer', 'agent']), storyboards: z.enum(['customer', 'agent']), assets: z.enum(['customer', 'agent']),
1932
+ frames: z.enum(['customer', 'agent']), videos: z.enum(['customer', 'agent']), compose: z.enum(['customer', 'agent']),
1933
+ }).optional().describe('execution_mode=custom 时必填:每个环节 customer(客户把控)或 agent(托管)'),
1934
+ budget_points: z.number().int().positive().optional().describe('预算(点)。auto / custom 必填(客户授权 agent 自主花费的上限);建议不低于所选套餐的 estimate.total.upper'),
1935
+ overrun_pct: z.union([z.literal(0), z.literal(10), z.literal(20), z.literal(30)]).optional().describe('自动追加上限(%),默认 0。硬上限 = 预算 × (1 + 本值/100)'),
1936
+ episodes: z.number().int().min(1).max(200),
1937
+ minutes_per_episode: z.number().positive().max(30),
1938
+ }, async ({ drama_id, ...body }) => jsonResult(await client.producePost(`/dramas/${drama_id}/production-plan`, body)));
1939
+ server.tool('get_production_plan', '查本剧已确认的开场方案(免费)。返回方案快照、当前模型、models_unavailable_now(本剧模型此刻已不可用时非空——出图/出视频前要先问客户怎么办)、' +
1940
+ 'budget(含 hard_cap 硬上限、overrun_in_use 是否已在动用追加额度)。confirmed=false 表示还没确认过方案。' +
1941
+ '★budget.overrun_in_use 变成 true 时主动告诉客户「预算已用完、正在动用追加额度,还剩 cap_remaining 点」。', { drama_id: z.number().int().positive() }, async ({ drama_id }) => jsonResult(await client.produceGet(`/dramas/${drama_id}/production-plan`)));
1874
1942
  // ========== P1 · 整集配音(成片前的强制音频步)==========
1875
1943
  server.tool('assign_voices', '★给本集所有角色分配音色(配音导演 agent 按性别/性格/年龄/角色定位+项目语言选)。' +
1876
1944
  'voiceStyle 不是提取时自动填的——不分配,generate_tts 就没音色。文本步(LLM)后付。' +