@lingjingai/scriptctl 0.25.5 → 0.25.7
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/dist/common.js +8 -6
- package/dist/common.js.map +1 -1
- package/dist/domain/direct-core.d.ts +6 -1
- package/dist/domain/direct-core.js +186 -48
- package/dist/domain/direct-core.js.map +1 -1
- package/dist/domain/script/validate.js +100 -1
- package/dist/domain/script/validate.js.map +1 -1
- package/dist/usecases/parse.js +1 -1
- package/dist/usecases/parse.js.map +1 -1
- package/package.json +1 -1
package/dist/common.js
CHANGED
|
@@ -78,7 +78,7 @@ export const MARKDOWN_BATCH_PROMPT_SPEC = "Output format: a single markdown docu
|
|
|
78
78
|
"\n" +
|
|
79
79
|
"## 场景 1\n" +
|
|
80
80
|
"- 时空: <内|外> <日|夜>\n" +
|
|
81
|
-
"- 地点: <稳定主空间地点名>[
|
|
81
|
+
"- 地点: <稳定主空间地点名>[场景状态]\n" +
|
|
82
82
|
"- 角色: <跨场景复用的具体单人角色1>, <角色2>(状态), <角色3>\n" +
|
|
83
83
|
"- 道具: <需要单独生成并保持一致的prop1>, <prop2>\n" +
|
|
84
84
|
"\n" +
|
|
@@ -208,14 +208,14 @@ export const PARSE_MD_SPEC = "scriptctl parse 输入 = 一个 md 工作区目录
|
|
|
208
208
|
" 梗概.md (可选)整部全文梗概\n" +
|
|
209
209
|
"\n" +
|
|
210
210
|
"🔴 铁律:正文 md 只管正文,绝不在正文里登记/输出任何资产。资产一律登记到上面对应\n" +
|
|
211
|
-
" 的 人物/场景/道具/发声源 md
|
|
211
|
+
" 的 人物/场景/道具/发声源 md 里。正文里只“引用”名字与已登记状态,不写描述。\n" +
|
|
212
212
|
"🔴 资产就这 4 份,全剧共用、大家一起加;同名只登一次,重复无妨(parse / 合并阶段去重)。\n" +
|
|
213
213
|
"🟡 只有正文、还没写资产 md?先跑 `scriptctl parse <dir> --extract-assets`:它从正文里\n" +
|
|
214
214
|
" 引用到的资产名出发,用 LLM 补出描述 / 世界观 / 主角,写回上面这几份资产 md 供你复核;\n" +
|
|
215
215
|
" 复核微调后再跑 `scriptctl parse <dir>`(纯确定性)装配 script.json。\n" +
|
|
216
216
|
"\n" +
|
|
217
217
|
"==================== 1. 正文 md(每集一个,ep_<NNN>.md) ====================\n" +
|
|
218
|
-
"# <本集标题> ←
|
|
218
|
+
"# <本集标题> ← 第一行,非「剧本/梗概」的顶级标题即本集标题;缺省时 parse 从正文生成短标题\n" +
|
|
219
219
|
"\n" +
|
|
220
220
|
"## 梗概\n" +
|
|
221
221
|
"<本集一段话梗概,纯文本,可多行>\n" +
|
|
@@ -224,9 +224,9 @@ export const PARSE_MD_SPEC = "scriptctl parse 输入 = 一个 md 工作区目录
|
|
|
224
224
|
"\n" +
|
|
225
225
|
"## 场景 1\n" +
|
|
226
226
|
"- 时空: <内|外> <日|夜>\n" +
|
|
227
|
-
"- 地点: <地点名>[
|
|
228
|
-
"- 角色: <角色1>, <角色2>(状态), <角色3> ← 只写名字,引用 人物.md
|
|
229
|
-
"- 道具: <道具1>, <道具2>
|
|
227
|
+
"- 地点: <地点名>[场景状态] ← 只写名字,引用 场景.md 里登记的地点/状态\n" +
|
|
228
|
+
"- 角色: <角色1>, <角色2>(状态), <角色3> ← 只写名字,引用 人物.md 里登记的角色/状态\n" +
|
|
229
|
+
"- 道具: <道具1>, <道具2>(状态), <道具3>[状态] ← 只写名字,引用 道具.md 里登记的道具/状态\n" +
|
|
230
230
|
"\n" +
|
|
231
231
|
"> [act] 动作或环境描写。\n" +
|
|
232
232
|
"> [dlg|name] 角色对白原文。\n" +
|
|
@@ -246,6 +246,8 @@ export const PARSE_MD_SPEC = "scriptctl parse 输入 = 一个 md 工作区目录
|
|
|
246
246
|
" - <状态名>: <这个状态下的具体可视外观>\n" +
|
|
247
247
|
" - <状态名>: ...\n" +
|
|
248
248
|
"(也接受扁平写法 `- <资产名>|<状态名>: 描述`;两种都行,最后合并去重。)\n" +
|
|
249
|
+
"正文未显式写状态时,parse 会自动绑定该资产的 `默认` 状态;没有 `默认` 且只有一个状态时,绑定唯一状态。\n" +
|
|
250
|
+
"多个非默认状态无法确定时保持 state_id:null,并由 validate 给出 warning。\n" +
|
|
249
251
|
"\n" +
|
|
250
252
|
"==================== 2. 人物.md(角色登记 + 状态) ====================\n" +
|
|
251
253
|
"# 人物\n" +
|
package/dist/common.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.js","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"common.js","sourceRoot":"","sources":["../src/common.ts"],"names":[],"mappings":"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"}
|
|
@@ -17,6 +17,7 @@ export declare function extractEpisodeTitleCandidate(header: string): string;
|
|
|
17
17
|
export declare function buildEpisodePlan(sourceText: string): Dict;
|
|
18
18
|
export declare function cleanName(name: unknown): string;
|
|
19
19
|
export declare function splitEntityState(raw: unknown): [string, string | null];
|
|
20
|
+
export declare function splitLocationState(raw: unknown): [string, string | null];
|
|
20
21
|
export declare function stateLabelError(stateName: unknown): string | null;
|
|
21
22
|
export declare function isStateLabelValid(stateName: unknown): boolean;
|
|
22
23
|
export declare function stateRejectionReason(targetKind: string, stateName: unknown): string | null;
|
|
@@ -192,5 +193,9 @@ export declare function actorCurationDecisions(script: Dict): Dict[];
|
|
|
192
193
|
export declare function propCurationDecisions(script: Dict): Dict[];
|
|
193
194
|
export declare function normalizeAssetCuration(script: Dict, rawCuration: unknown): Dict;
|
|
194
195
|
export declare function curateScriptAssets(script: Dict, rawCuration?: unknown): Dict;
|
|
195
|
-
|
|
196
|
+
interface MergeEpisodeResultsOptions {
|
|
197
|
+
bindDefaultStateRefs?: boolean;
|
|
198
|
+
trackUnresolvedStateRefs?: boolean;
|
|
199
|
+
}
|
|
200
|
+
export declare function mergeEpisodeResults(results: Dict[], title: string, opts?: MergeEpisodeResultsOptions): Dict;
|
|
196
201
|
export {};
|
|
@@ -27,6 +27,7 @@ const _DIALOGUE_RE = /^([^::]{1,40}?)(?:[((]([^))]{1,30})[))])?[::](.+
|
|
|
27
27
|
const _BRACKET_RE = /^【([^::】]+)[::](.+?)】?$/;
|
|
28
28
|
const _STATE_RE = /【([^】]+)】/g;
|
|
29
29
|
const _PAREN_ANNOTATION_RE = /[((]([^))]+)[))]/g;
|
|
30
|
+
const _LOC_STATE_RE = /\[([^\]]*)\]/g;
|
|
30
31
|
const _ANNOTATION_RE = /(?:【[^】]*】|[((][^))]*[))])/g;
|
|
31
32
|
export const BRACKET_ACTION_LABELS = new Set([
|
|
32
33
|
"字幕", "音效", "特效", "屏幕字", "人物牌", "旁白", "画面", "转场",
|
|
@@ -47,7 +48,6 @@ const _MD_SUB_HEADER_RE = /^##\s+(.+?)\s*$/;
|
|
|
47
48
|
const _MD_SCENE_HEADER_RE = /^##\s*场景\s*(\d+)\s*$/;
|
|
48
49
|
const _MD_SCENE_FIELD_RE = /^-\s*(时空|地点|角色|道具)\s*[::]\s*(.+?)\s*$/;
|
|
49
50
|
const _MD_TIME_SPACE_RE = /^(内|外|interior|exterior|in|out)\s+(日|夜|day|night)$/i;
|
|
50
|
-
const _MD_LOC_STATE_RE = /^(.+?)(?:【([^】]+)】)?$/;
|
|
51
51
|
const _MD_CHAR_ENTRY_RE = /^([^()(),,]+?)(?:[((]([^))]+)[))])?$/;
|
|
52
52
|
const _MD_ACTION_ANCHOR_RE = /^>\s*\[([A-Za-z]+)(?:\|([^|\]]+?)(?:\|([^|\]]+?))?)?\]\s*(.*)$/;
|
|
53
53
|
const _MD_ASSET_ENTRY_RE = /^-\s*([^::]+?)(?:\s*[::]\s*(.+?))?\s*$/;
|
|
@@ -261,6 +261,7 @@ function countOccurrences(s, sub, end) {
|
|
|
261
261
|
export function sceneContext(scene) {
|
|
262
262
|
const context = isDict(scene["context"]) ? scene["context"] : {};
|
|
263
263
|
return {
|
|
264
|
+
...context,
|
|
264
265
|
locations: isList(context["locations"]) ? context["locations"] : (asList(scene["locations"]) ?? []),
|
|
265
266
|
actors: isList(context["actors"]) ? context["actors"] : (asList(scene["actors"]) ?? []),
|
|
266
267
|
props: isList(context["props"]) ? context["props"] : (asList(scene["props"]) ?? []),
|
|
@@ -368,6 +369,20 @@ export function formatEpisodeTitle(episodeNum, rawTitle) {
|
|
|
368
369
|
return null;
|
|
369
370
|
return `第${episodeNum}集:${short}`;
|
|
370
371
|
}
|
|
372
|
+
function deterministicTitleFromScenes(episodeNum, scenes) {
|
|
373
|
+
for (const scene of scenes) {
|
|
374
|
+
for (const action of asList(scene["actions"])) {
|
|
375
|
+
const content = strOf(action["content"]).trim();
|
|
376
|
+
if (!content)
|
|
377
|
+
continue;
|
|
378
|
+
const short = content.replace(/[^\w一-鿿]+/gu, "");
|
|
379
|
+
if (short.length >= 2) {
|
|
380
|
+
return formatEpisodeTitle(episodeNum, short.slice(0, 8)) ?? `第${episodeNum}集:剧情转折${episodeNum}`;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
return episodeNum > 0 ? `第${episodeNum}集:剧情转折${episodeNum}` : undefined;
|
|
385
|
+
}
|
|
371
386
|
export function extractEpisodeTitleCandidate(header) {
|
|
372
387
|
let value = strOf(header).trim().replace(/^[#=\s]*/, "");
|
|
373
388
|
const match = reMatch(_EP_TITLE_PREFIX_RE, value);
|
|
@@ -457,6 +472,28 @@ export function splitEntityState(raw) {
|
|
|
457
472
|
}
|
|
458
473
|
return [cleanName(value), states.length > 0 ? states[states.length - 1] : null];
|
|
459
474
|
}
|
|
475
|
+
export function splitLocationState(raw) {
|
|
476
|
+
const value = strOf(raw).trim();
|
|
477
|
+
if (!value)
|
|
478
|
+
return ["", null];
|
|
479
|
+
const bracketStates = reFindAll(_LOC_STATE_RE, value).map((item) => item.trim()).filter((item) => item.length > 0);
|
|
480
|
+
const locName = cleanName(reReplace(_LOC_STATE_RE, value, ""));
|
|
481
|
+
if (bracketStates.length > 0) {
|
|
482
|
+
return [locName, bracketStates[bracketStates.length - 1]];
|
|
483
|
+
}
|
|
484
|
+
const states = [];
|
|
485
|
+
for (const item of reFindAll(_STATE_RE, value)) {
|
|
486
|
+
const v = item.trim();
|
|
487
|
+
if (v)
|
|
488
|
+
states.push(v);
|
|
489
|
+
}
|
|
490
|
+
for (const item of reFindAll(_PAREN_ANNOTATION_RE, value)) {
|
|
491
|
+
const v = item.trim();
|
|
492
|
+
if (v)
|
|
493
|
+
states.push(v);
|
|
494
|
+
}
|
|
495
|
+
return [locName, states.length > 0 ? states[states.length - 1] : null];
|
|
496
|
+
}
|
|
460
497
|
export function stateLabelError(stateName) {
|
|
461
498
|
const text = strOf(stateName).trim().replace(/\s+/g, "");
|
|
462
499
|
if (!text)
|
|
@@ -496,7 +533,7 @@ export function splitNames(raw) {
|
|
|
496
533
|
return result;
|
|
497
534
|
}
|
|
498
535
|
export function stripLocationState(location) {
|
|
499
|
-
return
|
|
536
|
+
return splitLocationState(location);
|
|
500
537
|
}
|
|
501
538
|
export function parseSceneHeader(line) {
|
|
502
539
|
const timeFirst = reMatch(_SCENE_TIME_FIRST_RE, line);
|
|
@@ -1440,6 +1477,7 @@ export function parseMarkdownBatch(text, batchPlan, opts = {}) {
|
|
|
1440
1477
|
actor_names: [],
|
|
1441
1478
|
actor_states: {},
|
|
1442
1479
|
prop_names: [],
|
|
1480
|
+
prop_states: {},
|
|
1443
1481
|
actions: [],
|
|
1444
1482
|
});
|
|
1445
1483
|
lastAction = null;
|
|
@@ -1517,13 +1555,10 @@ export function parseMarkdownBatch(text, batchPlan, opts = {}) {
|
|
|
1517
1555
|
}
|
|
1518
1556
|
}
|
|
1519
1557
|
else if (key === "地点") {
|
|
1520
|
-
const
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
const locState = (locMatch[2] || locStateFromName || "").trim();
|
|
1525
|
-
scene["location_state"] = locState && isReusableState("location", locState) ? locState : null;
|
|
1526
|
-
}
|
|
1558
|
+
const [locName, locStateFromName] = splitLocationState(value);
|
|
1559
|
+
scene["location_name"] = locName || "未知场景";
|
|
1560
|
+
const locState = strOf(locStateFromName).trim();
|
|
1561
|
+
scene["location_state"] = locState && isReusableState("location", locState) ? locState : null;
|
|
1527
1562
|
}
|
|
1528
1563
|
else if (key === "角色") {
|
|
1529
1564
|
for (let entry of value.split(/[,,、]/)) {
|
|
@@ -1547,10 +1582,14 @@ export function parseMarkdownBatch(text, batchPlan, opts = {}) {
|
|
|
1547
1582
|
}
|
|
1548
1583
|
else if (key === "道具") {
|
|
1549
1584
|
for (const entry of value.split(/[,,、]/)) {
|
|
1550
|
-
const [prop] =
|
|
1585
|
+
const [prop, inferredState] = splitLocationState(entry);
|
|
1586
|
+
const state = strOf(inferredState).trim() || null;
|
|
1551
1587
|
const propNames = scene["prop_names"];
|
|
1552
1588
|
if (prop && !propNames.includes(prop))
|
|
1553
1589
|
propNames.push(prop);
|
|
1590
|
+
if (prop && state && isReusableState("prop", state)) {
|
|
1591
|
+
scene["prop_states"][prop] = state;
|
|
1592
|
+
}
|
|
1554
1593
|
}
|
|
1555
1594
|
}
|
|
1556
1595
|
lastAction = null;
|
|
@@ -1626,28 +1665,38 @@ export function parseMarkdownBatch(text, batchPlan, opts = {}) {
|
|
|
1626
1665
|
for (const scene of scenes) {
|
|
1627
1666
|
scene["actions"] = scene["actions"].filter((a) => strOf(a["content"]).trim().length > 0);
|
|
1628
1667
|
}
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
const
|
|
1632
|
-
|
|
1633
|
-
stateLookup.
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
const
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
const
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
const
|
|
1649
|
-
|
|
1650
|
-
|
|
1668
|
+
if (!fragmentMode) {
|
|
1669
|
+
const stateLookup = new Map();
|
|
1670
|
+
for (const stateDef of stateDefs) {
|
|
1671
|
+
const key = `${strOf(stateDef["kind"])}::${strOf(stateDef["asset_name"])}`;
|
|
1672
|
+
if (!stateLookup.has(key))
|
|
1673
|
+
stateLookup.set(key, new Set());
|
|
1674
|
+
stateLookup.get(key).add(strOf(stateDef["state_name"]).trim());
|
|
1675
|
+
}
|
|
1676
|
+
for (const scene of scenes) {
|
|
1677
|
+
const actorStates = scene["actor_states"] || {};
|
|
1678
|
+
const filteredActorStates = {};
|
|
1679
|
+
for (const [actorName, stateName] of Object.entries(actorStates)) {
|
|
1680
|
+
const allowed = stateLookup.get(`actor::${actorName.trim()}`) ?? new Set();
|
|
1681
|
+
if (allowed.has(strOf(stateName).trim()))
|
|
1682
|
+
filteredActorStates[actorName] = stateName;
|
|
1683
|
+
}
|
|
1684
|
+
scene["actor_states"] = filteredActorStates;
|
|
1685
|
+
const propStates = scene["prop_states"] || {};
|
|
1686
|
+
const filteredPropStates = {};
|
|
1687
|
+
for (const [propName, stateName] of Object.entries(propStates)) {
|
|
1688
|
+
const allowed = stateLookup.get(`prop::${propName.trim()}`) ?? new Set();
|
|
1689
|
+
if (allowed.has(strOf(stateName).trim()))
|
|
1690
|
+
filteredPropStates[propName] = stateName;
|
|
1691
|
+
}
|
|
1692
|
+
scene["prop_states"] = filteredPropStates;
|
|
1693
|
+
const locName = strOf(scene["location_name"]).trim();
|
|
1694
|
+
const locState = strOf(scene["location_state"]).trim();
|
|
1695
|
+
if (locState) {
|
|
1696
|
+
const allowed = stateLookup.get(`location::${locName}`) ?? new Set();
|
|
1697
|
+
if (!allowed.has(locState))
|
|
1698
|
+
scene["location_state"] = null;
|
|
1699
|
+
}
|
|
1651
1700
|
}
|
|
1652
1701
|
}
|
|
1653
1702
|
if (scenes.length === 0) {
|
|
@@ -1657,9 +1706,11 @@ export function parseMarkdownBatch(text, batchPlan, opts = {}) {
|
|
|
1657
1706
|
throw _mdInvalid(label, hint);
|
|
1658
1707
|
}
|
|
1659
1708
|
const synopsis = synopsisLines.join("\n").trim();
|
|
1709
|
+
const episodeNum = Number(batchPlan["episode"] ?? 0);
|
|
1710
|
+
const title = batchPlan["title"] ?? parsedTitle ?? (fragmentMode ? deterministicTitleFromScenes(episodeNum, scenes) : undefined);
|
|
1660
1711
|
return {
|
|
1661
|
-
episode:
|
|
1662
|
-
title
|
|
1712
|
+
episode: episodeNum,
|
|
1713
|
+
title,
|
|
1663
1714
|
source_span: batchPlan["source_span"],
|
|
1664
1715
|
scenes,
|
|
1665
1716
|
actors,
|
|
@@ -1942,6 +1993,26 @@ export function expandCompactEpisodeResult(result, episodePlan) {
|
|
|
1942
1993
|
}
|
|
1943
1994
|
actions.push(action);
|
|
1944
1995
|
}
|
|
1996
|
+
const propNames = [];
|
|
1997
|
+
const propStates = {};
|
|
1998
|
+
for (const rawProp of asList(rawScene["pr"])) {
|
|
1999
|
+
let name = "";
|
|
2000
|
+
let state = "";
|
|
2001
|
+
if (typeof rawProp === "string") {
|
|
2002
|
+
name = rawProp.trim();
|
|
2003
|
+
}
|
|
2004
|
+
else if (isDict(rawProp)) {
|
|
2005
|
+
name = strOf(rawProp["n"]).trim();
|
|
2006
|
+
state = strOf(rawProp["st"]).trim();
|
|
2007
|
+
}
|
|
2008
|
+
else
|
|
2009
|
+
continue;
|
|
2010
|
+
if (!name)
|
|
2011
|
+
continue;
|
|
2012
|
+
uniqueAdd(propNames, name);
|
|
2013
|
+
if (state && isStateLabelValid(state))
|
|
2014
|
+
propStates[name] = state;
|
|
2015
|
+
}
|
|
1945
2016
|
scenes.push({
|
|
1946
2017
|
scene_num: normalizeInt(rawScene["n"], index + 1),
|
|
1947
2018
|
environment: {
|
|
@@ -1952,9 +2023,8 @@ export function expandCompactEpisodeResult(result, episodePlan) {
|
|
|
1952
2023
|
location_state: strOf(rawScene["ls"]).trim() || null,
|
|
1953
2024
|
actor_names: actorNames,
|
|
1954
2025
|
actor_states: actorStates,
|
|
1955
|
-
prop_names:
|
|
1956
|
-
|
|
1957
|
-
: [],
|
|
2026
|
+
prop_names: propNames,
|
|
2027
|
+
prop_states: propStates,
|
|
1958
2028
|
actions,
|
|
1959
2029
|
});
|
|
1960
2030
|
}
|
|
@@ -2014,8 +2084,20 @@ export function compactEpisodeResult(result) {
|
|
|
2014
2084
|
const propList = isList(scene["prop_names"])
|
|
2015
2085
|
? scene["prop_names"].map((it) => strOf(it).trim()).filter((it) => it)
|
|
2016
2086
|
: [];
|
|
2087
|
+
const propStates = isDict(scene["prop_states"]) ? scene["prop_states"] : {};
|
|
2088
|
+
const compactProps = [];
|
|
2089
|
+
let hasPropState = false;
|
|
2090
|
+
for (const propName of propList) {
|
|
2091
|
+
const propItem = { n: propName };
|
|
2092
|
+
const state = strOf(propStates[propName]).trim();
|
|
2093
|
+
if (state) {
|
|
2094
|
+
propItem["st"] = state;
|
|
2095
|
+
hasPropState = true;
|
|
2096
|
+
}
|
|
2097
|
+
compactProps.push(propItem);
|
|
2098
|
+
}
|
|
2017
2099
|
if (propList.length > 0)
|
|
2018
|
-
compactScene["pr"] = propList;
|
|
2100
|
+
compactScene["pr"] = hasPropState ? compactProps : propList;
|
|
2019
2101
|
const compactActions = [];
|
|
2020
2102
|
for (const action of asList(scene["actions"])) {
|
|
2021
2103
|
if (!isDict(action))
|
|
@@ -2196,7 +2278,7 @@ export function normalizeEpisodeResult(result, episodePlan) {
|
|
|
2196
2278
|
space: env["space"] === "interior" || env["space"] === "exterior" ? env["space"] : "interior",
|
|
2197
2279
|
time: env["time"] === "day" || env["time"] === "night" ? env["time"] : "day",
|
|
2198
2280
|
};
|
|
2199
|
-
const [locName, locStateFromName] =
|
|
2281
|
+
const [locName, locStateFromName] = splitLocationState(strOf(scene["location_name"] || "未知场景"));
|
|
2200
2282
|
scene["location_name"] = locName || "未知场景";
|
|
2201
2283
|
const rawLocationState = strOf(scene["location_state"] || locStateFromName || "").trim();
|
|
2202
2284
|
scene["location_state"] = rawLocationState && isReusableState("location", rawLocationState) ? rawLocationState : null;
|
|
@@ -2234,11 +2316,36 @@ export function normalizeEpisodeResult(result, episodePlan) {
|
|
|
2234
2316
|
}
|
|
2235
2317
|
scene["actor_states"] = actorStates;
|
|
2236
2318
|
const propNames = [];
|
|
2319
|
+
const inferredPropStates = {};
|
|
2237
2320
|
for (const rawProp of asList(scene["prop_names"])) {
|
|
2238
|
-
const [propName] =
|
|
2321
|
+
const [propName, stateFromName] = splitLocationState(rawProp);
|
|
2239
2322
|
uniqueAdd(propNames, propName);
|
|
2323
|
+
if (propName && stateFromName && isReusableState("prop", stateFromName))
|
|
2324
|
+
inferredPropStates[propName] = stateFromName;
|
|
2240
2325
|
}
|
|
2241
2326
|
scene["prop_names"] = propNames;
|
|
2327
|
+
const rawPropStates = scene["prop_states"];
|
|
2328
|
+
const propStates = { ...inferredPropStates };
|
|
2329
|
+
if (isDict(rawPropStates)) {
|
|
2330
|
+
for (const [propName, state] of Object.entries(rawPropStates)) {
|
|
2331
|
+
const [normalizedProp] = splitLocationState(propName);
|
|
2332
|
+
const normalizedState = strOf(state).trim();
|
|
2333
|
+
if (normalizedProp && normalizedState && isReusableState("prop", normalizedState)) {
|
|
2334
|
+
propStates[normalizedProp] = normalizedState;
|
|
2335
|
+
}
|
|
2336
|
+
}
|
|
2337
|
+
}
|
|
2338
|
+
else if (isList(rawPropStates)) {
|
|
2339
|
+
for (const item of rawPropStates) {
|
|
2340
|
+
if (!isDict(item))
|
|
2341
|
+
continue;
|
|
2342
|
+
const [propName] = splitLocationState(strOf(item["prop_name"]));
|
|
2343
|
+
const state = strOf(item["state"]).trim();
|
|
2344
|
+
if (propName && state && isReusableState("prop", state))
|
|
2345
|
+
propStates[propName] = state;
|
|
2346
|
+
}
|
|
2347
|
+
}
|
|
2348
|
+
scene["prop_states"] = propStates;
|
|
2242
2349
|
const actions = [];
|
|
2243
2350
|
for (const action of asList(scene["actions"])) {
|
|
2244
2351
|
if (!isDict(action))
|
|
@@ -3054,10 +3161,7 @@ export function curateScriptAssets(script, rawCuration = null) {
|
|
|
3054
3161
|
locations: locationDecisions,
|
|
3055
3162
|
};
|
|
3056
3163
|
}
|
|
3057
|
-
|
|
3058
|
-
// Merge episode results into a final script
|
|
3059
|
-
// ---------------------------------------------------------------------------
|
|
3060
|
-
export function mergeEpisodeResults(results, title) {
|
|
3164
|
+
export function mergeEpisodeResults(results, title, opts = {}) {
|
|
3061
3165
|
const actorNames = [];
|
|
3062
3166
|
const locationNames = [];
|
|
3063
3167
|
const propNames = [];
|
|
@@ -3227,6 +3331,15 @@ export function mergeEpisodeResults(results, title) {
|
|
|
3227
3331
|
}
|
|
3228
3332
|
let stateCounter = 0;
|
|
3229
3333
|
const stateIdsByTarget = new Map();
|
|
3334
|
+
const stateNamesByTarget = new Map();
|
|
3335
|
+
const rememberStateName = (kind, assetName, stateName) => {
|
|
3336
|
+
const key = `${kind}::${assetName}`;
|
|
3337
|
+
if (!stateNamesByTarget.has(key))
|
|
3338
|
+
stateNamesByTarget.set(key, []);
|
|
3339
|
+
const names = stateNamesByTarget.get(key);
|
|
3340
|
+
if (!names.includes(stateName))
|
|
3341
|
+
names.push(stateName);
|
|
3342
|
+
};
|
|
3230
3343
|
const actors = [];
|
|
3231
3344
|
for (const name of actorNames) {
|
|
3232
3345
|
const entry = { actor_id: actorIds.get(name), actor_name: name };
|
|
@@ -3238,6 +3351,7 @@ export function mergeEpisodeResults(results, title) {
|
|
|
3238
3351
|
const sid = fmtId("st", stateCounter);
|
|
3239
3352
|
const stateName = strOf(stateDef["state_name"]).trim();
|
|
3240
3353
|
stateIdsByTarget.set(`actor::${name}::${stateName}`, sid);
|
|
3354
|
+
rememberStateName("actor", name, stateName);
|
|
3241
3355
|
const stateEntry = { state_id: sid, state_name: stateName };
|
|
3242
3356
|
const description = strOf(stateDef["description"]).trim();
|
|
3243
3357
|
if (description)
|
|
@@ -3259,6 +3373,7 @@ export function mergeEpisodeResults(results, title) {
|
|
|
3259
3373
|
const sid = fmtId("st", stateCounter);
|
|
3260
3374
|
const stateName = strOf(stateDef["state_name"]).trim();
|
|
3261
3375
|
stateIdsByTarget.set(`location::${name}::${stateName}`, sid);
|
|
3376
|
+
rememberStateName("location", name, stateName);
|
|
3262
3377
|
const stateEntry = { state_id: sid, state_name: stateName };
|
|
3263
3378
|
const description = strOf(stateDef["description"]).trim();
|
|
3264
3379
|
if (description)
|
|
@@ -3280,6 +3395,7 @@ export function mergeEpisodeResults(results, title) {
|
|
|
3280
3395
|
const sid = fmtId("st", stateCounter);
|
|
3281
3396
|
const stateName = strOf(stateDef["state_name"]).trim();
|
|
3282
3397
|
stateIdsByTarget.set(`prop::${name}::${stateName}`, sid);
|
|
3398
|
+
rememberStateName("prop", name, stateName);
|
|
3283
3399
|
const stateEntry = { state_id: sid, state_name: stateName };
|
|
3284
3400
|
const description = strOf(stateDef["description"]).trim();
|
|
3285
3401
|
if (description)
|
|
@@ -3300,6 +3416,23 @@ export function mergeEpisodeResults(results, title) {
|
|
|
3300
3416
|
const normKind = _MD_SPEAKER_KIND_NORM[speakerKind.toLowerCase()] ?? _MD_SPEAKER_KIND_NORM[speakerKind] ?? "other";
|
|
3301
3417
|
return speakerIdsByName.get(`${normKind}::${speaker}`) ?? speakerIdsByName.get(`other::${speaker}`) ?? null;
|
|
3302
3418
|
};
|
|
3419
|
+
const stateIdForRef = (kind, assetName, explicitState, unresolved) => {
|
|
3420
|
+
const name = cleanName(assetName);
|
|
3421
|
+
if (!name)
|
|
3422
|
+
return null;
|
|
3423
|
+
const explicitName = strOf(explicitState).trim();
|
|
3424
|
+
if (explicitName) {
|
|
3425
|
+
const stateId = stateIdsByTarget.get(`${kind}::${name}::${explicitName}`) ?? null;
|
|
3426
|
+
if (!stateId && opts.trackUnresolvedStateRefs)
|
|
3427
|
+
unresolved.push({ kind, asset_name: name, state_name: explicitName });
|
|
3428
|
+
return stateId;
|
|
3429
|
+
}
|
|
3430
|
+
if (!opts.bindDefaultStateRefs)
|
|
3431
|
+
return null;
|
|
3432
|
+
const stateNames = stateNamesByTarget.get(`${kind}::${name}`) ?? [];
|
|
3433
|
+
const defaultName = stateNames.includes("默认") ? "默认" : stateNames.length === 1 ? stateNames[0] : "";
|
|
3434
|
+
return defaultName ? stateIdsByTarget.get(`${kind}::${name}::${defaultName}`) ?? null : null;
|
|
3435
|
+
};
|
|
3303
3436
|
const sortedResults = [...results].sort((a, b) => Number(a["episode"] ?? 0) - Number(b["episode"] ?? 0));
|
|
3304
3437
|
const episodes = [];
|
|
3305
3438
|
let sceneCounter = 0;
|
|
@@ -3308,8 +3441,9 @@ export function mergeEpisodeResults(results, title) {
|
|
|
3308
3441
|
for (const scene of asList(result["scenes"])) {
|
|
3309
3442
|
sceneCounter += 1;
|
|
3310
3443
|
const locName = cleanName(strOf(scene["location_name"] || "未知场景")) || "未知场景";
|
|
3444
|
+
const unresolvedStateRefs = [];
|
|
3311
3445
|
const locState = strOf(scene["location_state"]).trim();
|
|
3312
|
-
const locStateId =
|
|
3446
|
+
const locStateId = stateIdForRef("location", locName, locState, unresolvedStateRefs);
|
|
3313
3447
|
const sceneActorRefs = [];
|
|
3314
3448
|
for (const actorRaw of asList(scene["actor_names"])) {
|
|
3315
3449
|
const actor = cleanName(strOf(actorRaw));
|
|
@@ -3318,14 +3452,16 @@ export function mergeEpisodeResults(results, title) {
|
|
|
3318
3452
|
continue;
|
|
3319
3453
|
const actorStates = isDict(scene["actor_states"]) ? scene["actor_states"] : {};
|
|
3320
3454
|
const state = actorStates[actor];
|
|
3321
|
-
const stateId =
|
|
3455
|
+
const stateId = stateIdForRef("actor", actor, state, unresolvedStateRefs);
|
|
3322
3456
|
sceneActorRefs.push({ actor_id: aid, state_id: stateId });
|
|
3323
3457
|
}
|
|
3324
3458
|
const scenePropRefs = [];
|
|
3459
|
+
const propStates = isDict(scene["prop_states"]) ? scene["prop_states"] : {};
|
|
3325
3460
|
for (const rawProp of asList(scene["prop_names"])) {
|
|
3326
3461
|
const prop = cleanName(strOf(rawProp));
|
|
3327
|
-
if (propIds.has(prop))
|
|
3328
|
-
scenePropRefs.push({ prop_id: propIds.get(prop), state_id:
|
|
3462
|
+
if (propIds.has(prop)) {
|
|
3463
|
+
scenePropRefs.push({ prop_id: propIds.get(prop), state_id: stateIdForRef("prop", prop, propStates[prop], unresolvedStateRefs) });
|
|
3464
|
+
}
|
|
3329
3465
|
}
|
|
3330
3466
|
const actions = [];
|
|
3331
3467
|
for (const action of asList(scene["actions"])) {
|
|
@@ -3394,6 +3530,8 @@ export function mergeEpisodeResults(results, title) {
|
|
|
3394
3530
|
actors: sceneActorRefs,
|
|
3395
3531
|
props: scenePropRefs,
|
|
3396
3532
|
};
|
|
3533
|
+
if (unresolvedStateRefs.length > 0)
|
|
3534
|
+
context["unresolved_state_refs"] = unresolvedStateRefs;
|
|
3397
3535
|
scenes.push({
|
|
3398
3536
|
scene_id: fmtId("scn", sceneCounter),
|
|
3399
3537
|
environment: scene["environment"],
|