@lingjingai/scriptctl 0.35.0 → 0.36.1

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.
Files changed (364) hide show
  1. package/README.md +21 -5
  2. package/changes/0.36.0.md +24 -0
  3. package/dist/bin.js +0 -0
  4. package/dist/cli.d.ts +2 -1
  5. package/dist/cli.js +52 -128
  6. package/dist/cli.js.map +1 -1
  7. package/dist/common.d.ts +0 -16
  8. package/dist/common.js +2 -342
  9. package/dist/common.js.map +1 -1
  10. package/dist/domain/ingest/apply-plan.d.ts +23 -0
  11. package/dist/domain/ingest/apply-plan.js +210 -0
  12. package/dist/domain/ingest/apply-plan.js.map +1 -0
  13. package/dist/domain/ingest/assembler.d.ts +57 -0
  14. package/dist/domain/ingest/assembler.js +181 -0
  15. package/dist/domain/ingest/assembler.js.map +1 -0
  16. package/dist/domain/ingest/chunker.d.ts +9 -0
  17. package/dist/domain/ingest/chunker.js +38 -0
  18. package/dist/domain/ingest/chunker.js.map +1 -0
  19. package/dist/domain/ingest/evidence.d.ts +5 -0
  20. package/dist/domain/ingest/evidence.js +66 -0
  21. package/dist/domain/ingest/evidence.js.map +1 -0
  22. package/dist/domain/ingest/govern.d.ts +3 -0
  23. package/dist/domain/ingest/govern.js +127 -0
  24. package/dist/domain/ingest/govern.js.map +1 -0
  25. package/dist/domain/ingest/jsonl-parser.d.ts +6 -0
  26. package/dist/domain/ingest/jsonl-parser.js +187 -0
  27. package/dist/domain/ingest/jsonl-parser.js.map +1 -0
  28. package/dist/domain/ingest/markdown-parser.d.ts +6 -0
  29. package/dist/domain/ingest/markdown-parser.js +186 -0
  30. package/dist/domain/ingest/markdown-parser.js.map +1 -0
  31. package/dist/domain/ingest/records.d.ts +71 -0
  32. package/dist/domain/ingest/records.js +9 -0
  33. package/dist/domain/ingest/records.js.map +1 -0
  34. package/dist/domain/ingest/renumber.d.ts +14 -0
  35. package/dist/domain/ingest/renumber.js +130 -0
  36. package/dist/domain/ingest/renumber.js.map +1 -0
  37. package/dist/domain/ingest/script-v3.d.ts +94 -0
  38. package/dist/domain/ingest/script-v3.js +7 -0
  39. package/dist/domain/ingest/script-v3.js.map +1 -0
  40. package/dist/domain/ingest/state-reconcile.d.ts +11 -0
  41. package/dist/domain/ingest/state-reconcile.js +90 -0
  42. package/dist/domain/ingest/state-reconcile.js.map +1 -0
  43. package/dist/domain/ingest/validation.d.ts +11 -0
  44. package/dist/domain/ingest/validation.js +168 -0
  45. package/dist/domain/ingest/validation.js.map +1 -0
  46. package/dist/domain/ingest/video-aggregate.d.ts +23 -0
  47. package/dist/domain/ingest/video-aggregate.js +89 -0
  48. package/dist/domain/ingest/video-aggregate.js.map +1 -0
  49. package/dist/domain/ingest/video-apply.d.ts +37 -0
  50. package/dist/domain/ingest/video-apply.js +236 -0
  51. package/dist/domain/ingest/video-apply.js.map +1 -0
  52. package/dist/domain/ingest/video-md-parser.d.ts +2 -0
  53. package/dist/domain/ingest/video-md-parser.js +233 -0
  54. package/dist/domain/ingest/video-md-parser.js.map +1 -0
  55. package/dist/domain/ingest/video-records.d.ts +56 -0
  56. package/dist/domain/ingest/video-records.js +9 -0
  57. package/dist/domain/ingest/video-records.js.map +1 -0
  58. package/dist/domain/loom/index.d.ts +2 -1
  59. package/dist/domain/loom/index.js +12 -10
  60. package/dist/domain/loom/index.js.map +1 -1
  61. package/dist/domain/loom/types.d.ts +3 -2
  62. package/dist/domain/script/lookups.d.ts +3 -2
  63. package/dist/domain/script/lookups.js +25 -8
  64. package/dist/domain/script/lookups.js.map +1 -1
  65. package/dist/domain/script/patch/apply.js +2 -2
  66. package/dist/domain/script/patch/apply.js.map +1 -1
  67. package/dist/domain/script/patch/helpers.d.ts +3 -7
  68. package/dist/domain/script/patch/helpers.js +23 -96
  69. package/dist/domain/script/patch/helpers.js.map +1 -1
  70. package/dist/domain/script/patch/ops-action.d.ts +0 -2
  71. package/dist/domain/script/patch/ops-action.js +34 -100
  72. package/dist/domain/script/patch/ops-action.js.map +1 -1
  73. package/dist/domain/script/patch/ops-asset.d.ts +1 -0
  74. package/dist/domain/script/patch/ops-asset.js +102 -155
  75. package/dist/domain/script/patch/ops-asset.js.map +1 -1
  76. package/dist/domain/script/patch/ops-dialogue.d.ts +1 -4
  77. package/dist/domain/script/patch/ops-dialogue.js +43 -220
  78. package/dist/domain/script/patch/ops-dialogue.js.map +1 -1
  79. package/dist/domain/script/patch/ops-extend.js +8 -2
  80. package/dist/domain/script/patch/ops-extend.js.map +1 -1
  81. package/dist/domain/script/patch/ops-meta.js.map +1 -1
  82. package/dist/domain/script/patch/ops-scene.js +26 -39
  83. package/dist/domain/script/patch/ops-scene.js.map +1 -1
  84. package/dist/domain/script/patch/ops-state.d.ts +3 -3
  85. package/dist/domain/script/patch/ops-state.js +33 -49
  86. package/dist/domain/script/patch/ops-state.js.map +1 -1
  87. package/dist/domain/script/patch/registry.js +9 -13
  88. package/dist/domain/script/patch/registry.js.map +1 -1
  89. package/dist/domain/script/refs.js +23 -111
  90. package/dist/domain/script/refs.js.map +1 -1
  91. package/dist/domain/script/scene-refs.d.ts +3 -0
  92. package/dist/domain/script/scene-refs.js +35 -0
  93. package/dist/domain/script/scene-refs.js.map +1 -0
  94. package/dist/domain/script/schema.js +17 -21
  95. package/dist/domain/script/schema.js.map +1 -1
  96. package/dist/domain/script/text-util.d.ts +7 -0
  97. package/dist/domain/script/text-util.js +91 -0
  98. package/dist/domain/script/text-util.js.map +1 -0
  99. package/dist/help-text.js +117 -410
  100. package/dist/help-text.js.map +1 -1
  101. package/dist/infra/converters.js +1 -1
  102. package/dist/infra/converters.js.map +1 -1
  103. package/dist/infra/episode-title.d.ts +4 -0
  104. package/dist/infra/episode-title.js +129 -0
  105. package/dist/infra/episode-title.js.map +1 -0
  106. package/dist/infra/ingest/review-renderer.d.ts +1 -0
  107. package/dist/infra/ingest/review-renderer.js +431 -0
  108. package/dist/infra/ingest/review-renderer.js.map +1 -0
  109. package/dist/infra/ingest/source-resolver.d.ts +21 -0
  110. package/dist/infra/ingest/source-resolver.js +51 -0
  111. package/dist/infra/ingest/source-resolver.js.map +1 -0
  112. package/dist/infra/ingest/text-reader.d.ts +3 -0
  113. package/dist/infra/ingest/text-reader.js +27 -0
  114. package/dist/infra/ingest/text-reader.js.map +1 -0
  115. package/dist/infra/ingest/video-discovery.d.ts +8 -0
  116. package/dist/infra/ingest/video-discovery.js +60 -0
  117. package/dist/infra/ingest/video-discovery.js.map +1 -0
  118. package/dist/infra/ingest/workspace-store.d.ts +18 -0
  119. package/dist/infra/ingest/workspace-store.js +70 -0
  120. package/dist/infra/ingest/workspace-store.js.map +1 -0
  121. package/dist/infra/llm/anthropic-model.d.ts +11 -0
  122. package/dist/infra/llm/anthropic-model.js +109 -0
  123. package/dist/infra/llm/anthropic-model.js.map +1 -0
  124. package/dist/infra/llm/gemini-upload.d.ts +9 -0
  125. package/dist/infra/llm/gemini-upload.js +94 -0
  126. package/dist/infra/llm/gemini-upload.js.map +1 -0
  127. package/dist/infra/llm/gemini-video-model.d.ts +47 -0
  128. package/dist/infra/llm/gemini-video-model.js +163 -0
  129. package/dist/infra/llm/gemini-video-model.js.map +1 -0
  130. package/dist/infra/llm/openai-compatible-model.d.ts +14 -0
  131. package/dist/infra/llm/openai-compatible-model.js +157 -0
  132. package/dist/infra/llm/openai-compatible-model.js.map +1 -0
  133. package/dist/infra/llm/retry.d.ts +5 -0
  134. package/dist/infra/llm/retry.js +20 -0
  135. package/dist/infra/llm/retry.js.map +1 -0
  136. package/dist/llm/composition.d.ts +5 -0
  137. package/dist/llm/composition.js +5 -0
  138. package/dist/llm/composition.js.map +1 -0
  139. package/dist/llm/config.d.ts +26 -0
  140. package/dist/llm/config.js +201 -0
  141. package/dist/llm/config.js.map +1 -0
  142. package/dist/llm/registry.d.ts +44 -0
  143. package/dist/llm/registry.js +48 -0
  144. package/dist/llm/registry.js.map +1 -0
  145. package/dist/llm/router.d.ts +23 -0
  146. package/dist/llm/router.js +0 -0
  147. package/dist/llm/router.js.map +1 -0
  148. package/dist/llm/tasks/ingest/asset-curate.d.ts +13 -0
  149. package/dist/llm/tasks/ingest/asset-curate.js +45 -0
  150. package/dist/llm/tasks/ingest/asset-curate.js.map +1 -0
  151. package/dist/llm/tasks/ingest/asset-extract.d.ts +12 -0
  152. package/dist/llm/tasks/ingest/asset-extract.js +51 -0
  153. package/dist/llm/tasks/ingest/asset-extract.js.map +1 -0
  154. package/dist/llm/tasks/ingest/asset-govern.d.ts +22 -0
  155. package/dist/llm/tasks/ingest/asset-govern.js +143 -0
  156. package/dist/llm/tasks/ingest/asset-govern.js.map +1 -0
  157. package/dist/llm/tasks/ingest/mention-resolve.d.ts +9 -0
  158. package/dist/llm/tasks/ingest/mention-resolve.js +39 -0
  159. package/dist/llm/tasks/ingest/mention-resolve.js.map +1 -0
  160. package/dist/llm/tasks/ingest/plot-speaker.d.ts +11 -0
  161. package/dist/llm/tasks/ingest/plot-speaker.js +72 -0
  162. package/dist/llm/tasks/ingest/plot-speaker.js.map +1 -0
  163. package/dist/llm/tasks/ingest/roster-merge.d.ts +46 -0
  164. package/dist/llm/tasks/ingest/roster-merge.js +235 -0
  165. package/dist/llm/tasks/ingest/roster-merge.js.map +1 -0
  166. package/dist/llm/tasks/ingest/state-merge.d.ts +10 -0
  167. package/dist/llm/tasks/ingest/state-merge.js +84 -0
  168. package/dist/llm/tasks/ingest/state-merge.js.map +1 -0
  169. package/dist/llm/tasks/ingest/state-reconcile.d.ts +8 -0
  170. package/dist/llm/tasks/ingest/state-reconcile.js +44 -0
  171. package/dist/llm/tasks/ingest/state-reconcile.js.map +1 -0
  172. package/dist/llm/tasks/ingest/text-normalize.d.ts +10 -0
  173. package/dist/llm/tasks/ingest/text-normalize.js +89 -0
  174. package/dist/llm/tasks/ingest/text-normalize.js.map +1 -0
  175. package/dist/llm/tasks/ingest/video-correct.d.ts +30 -0
  176. package/dist/llm/tasks/ingest/video-correct.js +144 -0
  177. package/dist/llm/tasks/ingest/video-correct.js.map +1 -0
  178. package/dist/llm/tasks/ingest/video-transcribe.d.ts +4 -0
  179. package/dist/llm/tasks/ingest/video-transcribe.js +105 -0
  180. package/dist/llm/tasks/ingest/video-transcribe.js.map +1 -0
  181. package/dist/llm/tasks/schemas.d.ts +5 -0
  182. package/dist/llm/tasks/schemas.js +107 -0
  183. package/dist/llm/tasks/schemas.js.map +1 -0
  184. package/dist/llm/types.d.ts +97 -0
  185. package/dist/llm/types.js +13 -0
  186. package/dist/llm/types.js.map +1 -0
  187. package/dist/usecases/doctor.d.ts +1 -1
  188. package/dist/usecases/doctor.js +62 -9
  189. package/dist/usecases/doctor.js.map +1 -1
  190. package/dist/usecases/ingest/command.d.ts +5 -0
  191. package/dist/usecases/ingest/command.js +64 -0
  192. package/dist/usecases/ingest/command.js.map +1 -0
  193. package/dist/usecases/ingest/fanout.d.ts +10 -0
  194. package/dist/usecases/ingest/fanout.js +23 -0
  195. package/dist/usecases/ingest/fanout.js.map +1 -0
  196. package/dist/usecases/ingest/pass4-mention-resolve.d.ts +11 -0
  197. package/dist/usecases/ingest/pass4-mention-resolve.js +52 -0
  198. package/dist/usecases/ingest/pass4-mention-resolve.js.map +1 -0
  199. package/dist/usecases/ingest/pass5-extract.d.ts +7 -0
  200. package/dist/usecases/ingest/pass5-extract.js +50 -0
  201. package/dist/usecases/ingest/pass5-extract.js.map +1 -0
  202. package/dist/usecases/ingest/pass5-govern.d.ts +13 -0
  203. package/dist/usecases/ingest/pass5-govern.js +155 -0
  204. package/dist/usecases/ingest/pass5-govern.js.map +1 -0
  205. package/dist/usecases/ingest/pipeline.d.ts +28 -0
  206. package/dist/usecases/ingest/pipeline.js +144 -0
  207. package/dist/usecases/ingest/pipeline.js.map +1 -0
  208. package/dist/usecases/ingest/publish-command.d.ts +4 -0
  209. package/dist/usecases/ingest/publish-command.js +77 -0
  210. package/dist/usecases/ingest/publish-command.js.map +1 -0
  211. package/dist/usecases/ingest/status.d.ts +39 -0
  212. package/dist/usecases/ingest/status.js +155 -0
  213. package/dist/usecases/ingest/status.js.map +1 -0
  214. package/dist/usecases/ingest/video-pass3.d.ts +26 -0
  215. package/dist/usecases/ingest/video-pass3.js +0 -0
  216. package/dist/usecases/ingest/video-pass3.js.map +1 -0
  217. package/dist/usecases/ingest/video-pipeline.d.ts +32 -0
  218. package/dist/usecases/ingest/video-pipeline.js +202 -0
  219. package/dist/usecases/ingest/video-pipeline.js.map +1 -0
  220. package/dist/usecases/ingest/view-command.d.ts +4 -0
  221. package/dist/usecases/ingest/view-command.js +51 -0
  222. package/dist/usecases/ingest/view-command.js.map +1 -0
  223. package/dist/usecases/script/actions.js +2 -2
  224. package/dist/usecases/script/actions.js.map +1 -1
  225. package/dist/usecases/script/actor.js.map +1 -1
  226. package/dist/usecases/script/actors.js.map +1 -1
  227. package/dist/usecases/script/add-actor.js.map +1 -1
  228. package/dist/usecases/script/add-episode.js.map +1 -1
  229. package/dist/usecases/script/add-location.js.map +1 -1
  230. package/dist/usecases/script/add-prop.js.map +1 -1
  231. package/dist/usecases/script/alias.js.map +1 -1
  232. package/dist/usecases/script/assets.js.map +1 -1
  233. package/dist/usecases/script/context.js.map +1 -1
  234. package/dist/usecases/script/create.js +3 -6
  235. package/dist/usecases/script/create.js.map +1 -1
  236. package/dist/usecases/script/delete.js.map +1 -1
  237. package/dist/usecases/script/describe.js.map +1 -1
  238. package/dist/usecases/script/dialogue.js +6 -13
  239. package/dist/usecases/script/dialogue.js.map +1 -1
  240. package/dist/usecases/script/do.js +1 -1
  241. package/dist/usecases/script/do.js.map +1 -1
  242. package/dist/usecases/script/episodes.js.map +1 -1
  243. package/dist/usecases/script/{add-speaker.d.ts → importance.d.ts} +1 -1
  244. package/dist/usecases/script/importance.js +17 -0
  245. package/dist/usecases/script/importance.js.map +1 -0
  246. package/dist/usecases/script/insert.js.map +1 -1
  247. package/dist/usecases/script/issues.js.map +1 -1
  248. package/dist/usecases/script/lib.d.ts +8 -6
  249. package/dist/usecases/script/lib.js +81 -97
  250. package/dist/usecases/script/lib.js.map +1 -1
  251. package/dist/usecases/script/locations.js.map +1 -1
  252. package/dist/usecases/script/merge.js.map +1 -1
  253. package/dist/usecases/script/move.js.map +1 -1
  254. package/dist/usecases/script/props.js.map +1 -1
  255. package/dist/usecases/script/refs.js.map +1 -1
  256. package/dist/usecases/script/rename.js.map +1 -1
  257. package/dist/usecases/script/replace.js.map +1 -1
  258. package/dist/usecases/script/role.js.map +1 -1
  259. package/dist/usecases/script/scenes.js +8 -15
  260. package/dist/usecases/script/scenes.js.map +1 -1
  261. package/dist/usecases/script/script-patch.js +1 -1
  262. package/dist/usecases/script/script-patch.js.map +1 -1
  263. package/dist/usecases/script/script-validate.js +1 -1
  264. package/dist/usecases/script/script-validate.js.map +1 -1
  265. package/dist/usecases/script/session.d.ts +4 -4
  266. package/dist/usecases/script/session.js +57 -78
  267. package/dist/usecases/script/session.js.map +1 -1
  268. package/dist/usecases/script/split.js.map +1 -1
  269. package/dist/usecases/script/state-add.js.map +1 -1
  270. package/dist/usecases/script/state-delete.js.map +1 -1
  271. package/dist/usecases/script/state-rename.js.map +1 -1
  272. package/dist/usecases/script/summary.js.map +1 -1
  273. package/dist/usecases/script/synopsis-generate.d.ts +4 -5
  274. package/dist/usecases/script/synopsis-generate.js +30 -46
  275. package/dist/usecases/script/synopsis-generate.js.map +1 -1
  276. package/dist/usecases/script/transition.js.map +1 -1
  277. package/dist/usecases/script/type.js.map +1 -1
  278. package/dist/usecases/script/worldview.js.map +1 -1
  279. package/package.json +21 -17
  280. package/skills/scriptctl/SKILL.md +140 -120
  281. package/skills/scriptctl/references/atomic-write-workflow.md +12 -9
  282. package/skills/scriptctl/references/ingest-workflow.md +85 -0
  283. package/skills/scriptctl/references/state-reference-repair.md +26 -39
  284. package/dist/domain/direct/runner.d.ts +0 -25
  285. package/dist/domain/direct/runner.js +0 -88
  286. package/dist/domain/direct/runner.js.map +0 -1
  287. package/dist/domain/direct/stage.d.ts +0 -108
  288. package/dist/domain/direct/stage.js +0 -134
  289. package/dist/domain/direct/stage.js.map +0 -1
  290. package/dist/domain/direct/stages/asset-curation.d.ts +0 -2
  291. package/dist/domain/direct/stages/asset-curation.js +0 -10
  292. package/dist/domain/direct/stages/asset-curation.js.map +0 -1
  293. package/dist/domain/direct/stages/batch-extract.d.ts +0 -2
  294. package/dist/domain/direct/stages/batch-extract.js +0 -12
  295. package/dist/domain/direct/stages/batch-extract.js.map +0 -1
  296. package/dist/domain/direct/stages/batch-plan.d.ts +0 -2
  297. package/dist/domain/direct/stages/batch-plan.js +0 -9
  298. package/dist/domain/direct/stages/batch-plan.js.map +0 -1
  299. package/dist/domain/direct/stages/episode-merge.d.ts +0 -2
  300. package/dist/domain/direct/stages/episode-merge.js +0 -11
  301. package/dist/domain/direct/stages/episode-merge.js.map +0 -1
  302. package/dist/domain/direct/stages/episode-plan.d.ts +0 -2
  303. package/dist/domain/direct/stages/episode-plan.js +0 -9
  304. package/dist/domain/direct/stages/episode-plan.js.map +0 -1
  305. package/dist/domain/direct/stages/episode-synopsis.d.ts +0 -2
  306. package/dist/domain/direct/stages/episode-synopsis.js +0 -12
  307. package/dist/domain/direct/stages/episode-synopsis.js.map +0 -1
  308. package/dist/domain/direct/stages/episode-titles.d.ts +0 -2
  309. package/dist/domain/direct/stages/episode-titles.js +0 -12
  310. package/dist/domain/direct/stages/episode-titles.js.map +0 -1
  311. package/dist/domain/direct/stages/index.d.ts +0 -19
  312. package/dist/domain/direct/stages/index.js +0 -41
  313. package/dist/domain/direct/stages/index.js.map +0 -1
  314. package/dist/domain/direct/stages/metadata.d.ts +0 -2
  315. package/dist/domain/direct/stages/metadata.js +0 -11
  316. package/dist/domain/direct/stages/metadata.js.map +0 -1
  317. package/dist/domain/direct/stages/script-merge.d.ts +0 -2
  318. package/dist/domain/direct/stages/script-merge.js +0 -15
  319. package/dist/domain/direct/stages/script-merge.js.map +0 -1
  320. package/dist/domain/direct/stages/script-synopsis.d.ts +0 -2
  321. package/dist/domain/direct/stages/script-synopsis.js +0 -12
  322. package/dist/domain/direct/stages/script-synopsis.js.map +0 -1
  323. package/dist/domain/direct/stages/source-prepare.d.ts +0 -2
  324. package/dist/domain/direct/stages/source-prepare.js +0 -9
  325. package/dist/domain/direct/stages/source-prepare.js.map +0 -1
  326. package/dist/domain/direct/stages/state-binding.d.ts +0 -2
  327. package/dist/domain/direct/stages/state-binding.js +0 -9
  328. package/dist/domain/direct/stages/state-binding.js.map +0 -1
  329. package/dist/domain/direct/stages/state-curation.d.ts +0 -2
  330. package/dist/domain/direct/stages/state-curation.js +0 -10
  331. package/dist/domain/direct/stages/state-curation.js.map +0 -1
  332. package/dist/domain/direct/stages/validate.d.ts +0 -2
  333. package/dist/domain/direct/stages/validate.js +0 -10
  334. package/dist/domain/direct/stages/validate.js.map +0 -1
  335. package/dist/domain/direct-core.d.ts +0 -313
  336. package/dist/domain/direct-core.js +0 -8514
  337. package/dist/domain/direct-core.js.map +0 -1
  338. package/dist/domain/script/validate.d.ts +0 -22
  339. package/dist/domain/script/validate.js +0 -997
  340. package/dist/domain/script/validate.js.map +0 -1
  341. package/dist/infra/providers.d.ts +0 -97
  342. package/dist/infra/providers.js +0 -1396
  343. package/dist/infra/providers.js.map +0 -1
  344. package/dist/usecases/direct.d.ts +0 -27
  345. package/dist/usecases/direct.js +0 -4172
  346. package/dist/usecases/direct.js.map +0 -1
  347. package/dist/usecases/parse.d.ts +0 -15
  348. package/dist/usecases/parse.js +0 -429
  349. package/dist/usecases/parse.js.map +0 -1
  350. package/dist/usecases/script/add-speaker.js +0 -22
  351. package/dist/usecases/script/add-speaker.js.map +0 -1
  352. package/dist/usecases/script/export.d.ts +0 -3
  353. package/dist/usecases/script/export.js +0 -111
  354. package/dist/usecases/script/export.js.map +0 -1
  355. package/dist/usecases/script/overlap.d.ts +0 -3
  356. package/dist/usecases/script/overlap.js +0 -21
  357. package/dist/usecases/script/overlap.js.map +0 -1
  358. package/dist/usecases/script/speakers.d.ts +0 -3
  359. package/dist/usecases/script/speakers.js +0 -28
  360. package/dist/usecases/script/speakers.js.map +0 -1
  361. package/dist/usecases/script/state-change.d.ts +0 -3
  362. package/dist/usecases/script/state-change.js +0 -24
  363. package/dist/usecases/script/state-change.js.map +0 -1
  364. package/skills/scriptctl/references/direct-workflow.md +0 -72
@@ -0,0 +1,45 @@
1
+ // ingest.asset-curate task (§9, importance classification). Assigns each asset
2
+ // an importance tier — primary / secondary / background — rather than dropping
3
+ // anything. background = 龙套/背景 (downstream skips asset generation + state
4
+ // tracking); primary/secondary get rendered. Assets are judged in small same-
5
+ // kind groups (default 3) with rich evidence (name occurrences as ±2-line
6
+ // windows). Empty-tolerant (unlabelled assets default to secondary at apply).
7
+ import { generateOptional } from "./asset-govern.js";
8
+ const KIND_LABEL = { actor: "人物", location: "地点", prop: "道具" };
9
+ export const ASSET_CURATE_SYSTEM = [
10
+ "你在判断剧本资产是否需要单独出图。给你若干同类型资产,每个有 id、名字、出现场数、几处正文证据。",
11
+ "为每个资产打一档:featured(需要出图的具体资产)或 background(龙套/背景,不单独出图)。",
12
+ "- 人物:featured=具名的具体角色(有名有身份、值得单独出图,不论戏份多少);background=无名龙套/群体/泛称(仆人甲、丫鬟、群众、随从、禁军、路人、宾客、家族名如“顾家”、集体如“众人”)。",
13
+ "- 地点:featured=可独立布景、成场的具体空间;background=一次性微场景(走廊角落、门口、车内一角等)。",
14
+ "- 道具:featured=需要跨镜头连续性/推动剧情/可读内容/反复出现的关键道具;background=通用食物、杂物、一次性小道具、背景陈设。",
15
+ "只依据给出的证据判断,不脑补。判据是“是不是一个值得单独出图的具体资产”,不是戏份大小——具名配角戏少也要 featured;无名龙套戏多也是 background。",
16
+ "输出每个 id 一行:`<id>: featured` 或 `<id>: background`。不要输出别的。",
17
+ ].join("\n");
18
+ export function buildCurateUser(kind, items) {
19
+ const blocks = items.map((it) => [
20
+ `### ${it.id} ${it.names.join(" / ")} (出现 ${it.scenes} 场)`,
21
+ it.evidence || "(无正文证据)",
22
+ ].join("\n"));
23
+ return `类型:${KIND_LABEL[kind]}\n\n${blocks.join("\n---\n")}`;
24
+ }
25
+ export function parseCurate(raw, validIds) {
26
+ const out = new Map();
27
+ for (const line of raw.split("\n")) {
28
+ const m = /^([\w-]+)\s*[::]\s*(featured|background)/i.exec(line.trim());
29
+ if (m && validIds.has(m[1]))
30
+ out.set(m[1], m[2].toLowerCase());
31
+ }
32
+ return out;
33
+ }
34
+ // Returns id → importance for this group (missing ids default to featured later).
35
+ export async function runCurate(executor, kind, items, signal) {
36
+ if (items.length === 0)
37
+ return new Map();
38
+ const text = await generateOptional(executor, "ingest.asset-curate", {
39
+ system: ASSET_CURATE_SYSTEM,
40
+ user: buildCurateUser(kind, items),
41
+ ...(signal ? { signal } : {}),
42
+ });
43
+ return parseCurate(text, new Set(items.map((it) => it.id)));
44
+ }
45
+ //# sourceMappingURL=asset-curate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-curate.js","sourceRoot":"","sources":["../../../../src/llm/tasks/ingest/asset-curate.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,+EAA+E;AAC/E,0EAA0E;AAC1E,8EAA8E;AAC9E,0EAA0E;AAC1E,8EAA8E;AAI9E,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAIrD,MAAM,UAAU,GAAyB,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAErF,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,mDAAmD;IACnD,wDAAwD;IACxD,2GAA2G;IAC3G,+DAA+D;IAC/D,4EAA4E;IAC5E,qFAAqF;IACrF,0DAA0D;CAC3D,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEb,MAAM,UAAU,eAAe,CAAC,IAAU,EAAE,KAAmB;IAC7D,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC;QAC/B,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,CAAC,MAAM,KAAK;QAC5D,EAAE,CAAC,QAAQ,IAAI,SAAS;KACzB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACd,OAAO,MAAM,UAAU,CAAC,IAAI,CAAC,OAAO,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,GAAW,EAAE,QAAqB;IAC5D,MAAM,GAAG,GAAG,IAAI,GAAG,EAAsB,CAAC;IAC1C,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,MAAM,CAAC,GAAG,2CAA2C,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACxE,IAAI,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC;YAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC,CAAC,CAAE,CAAC,WAAW,EAAgB,CAAC,CAAC;IAClF,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,kFAAkF;AAClF,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,QAAyB,EAAE,IAAU,EAAE,KAAmB,EAAE,MAAoB;IAC9G,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,GAAG,EAAE,CAAC;IACzC,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC,QAAQ,EAAE,qBAAqB,EAAE;QACnE,MAAM,EAAE,mBAAmB;QAC3B,IAAI,EAAE,eAAe,CAAC,IAAI,EAAE,KAAK,CAAC;QAClC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC9B,CAAC,CAAC;IACH,OAAO,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC"}
@@ -0,0 +1,12 @@
1
+ import type { NameStateRef } from "../../../domain/ingest/records.js";
2
+ import type { LlmTaskExecutor } from "../../types.js";
3
+ export declare const ASSET_EXTRACT_SYSTEM: string;
4
+ export declare function buildExtractUser(bodyLines: string[], declaredActors: string[], declaredProps: string[]): string;
5
+ export declare function parseExtractOutput(raw: string): {
6
+ actors: NameStateRef[];
7
+ props: NameStateRef[];
8
+ };
9
+ export declare function runAssetExtract(executor: LlmTaskExecutor, bodyLines: string[], declaredActors: string[], declaredProps: string[], signal?: AbortSignal): Promise<{
10
+ actors: NameStateRef[];
11
+ props: NameStateRef[];
12
+ }>;
@@ -0,0 +1,51 @@
1
+ // ingest.asset-extract task (new §pass5-extract). Per scene, extract the actors
2
+ // present and the key (hero) props from the plain-text body, using the declared
3
+ // 人物/道具 as strong priors. Output reuses the declared-list format so the same
4
+ // parser applies. Declared entities are authoritative; the model augments with
5
+ // undeclared-but-present characters, key props, and per-scene appearance states.
6
+ import { parseEntityList } from "../../../domain/ingest/markdown-parser.js";
7
+ import { generateOptional } from "./asset-govern.js";
8
+ export const ASSET_EXTRACT_SYSTEM = [
9
+ "你在从一场戏里提取在场的具体人物和关键道具,供后续出图。给你本场已声明的人物/道具(可能不全或为空)和本场正文。",
10
+ "输出两行(没有就留空行):",
11
+ "人物: 名【本场外观状态,可省】, 名2, ...",
12
+ "道具: 关键道具, 道具2【状态,可省】, ...",
13
+ "规则:",
14
+ "- 人物只列**具体单人角色**;家族/机构/群体/泛称(顾家、大房、林家、众人、随从、丫鬟们…)绝不列入人物。",
15
+ "- 道具只列需要**跨镜头连续性**的关键物件(hero prop:推动剧情、需展示可读内容、反复出现或有身份标识);通用背景物、一次性小道具、身体部位(双腿等)不列。",
16
+ "- 状态写整套稳定可视外观(着装造型/发型/形态),不写动作/情绪/机位。",
17
+ "- 名字用正文/声明里出现的规范名;已声明的人物/道具默认都在场,除非正文明确表明不在。",
18
+ ].join("\n");
19
+ export function buildExtractUser(bodyLines, declaredActors, declaredProps) {
20
+ return [
21
+ `【已声明人物】${declaredActors.join("、") || "(无)"}`,
22
+ `【已声明道具】${declaredProps.join("、") || "(无)"}`,
23
+ "",
24
+ "【本场正文】",
25
+ bodyLines.join("\n") || "(无)",
26
+ ].join("\n");
27
+ }
28
+ export function parseExtractOutput(raw) {
29
+ let actors = [];
30
+ let props = [];
31
+ for (const line of raw.split("\n")) {
32
+ const m = /^\s*(人物|道具)\s*[::]\s*(.*)$/.exec(line.trim());
33
+ if (!m)
34
+ continue;
35
+ const refs = parseEntityList(m[2]);
36
+ if (m[1] === "人物")
37
+ actors = refs;
38
+ else
39
+ props = refs;
40
+ }
41
+ return { actors, props };
42
+ }
43
+ export async function runAssetExtract(executor, bodyLines, declaredActors, declaredProps, signal) {
44
+ const text = await generateOptional(executor, "ingest.asset-extract", {
45
+ system: ASSET_EXTRACT_SYSTEM,
46
+ user: buildExtractUser(bodyLines, declaredActors, declaredProps),
47
+ ...(signal ? { signal } : {}),
48
+ });
49
+ return parseExtractOutput(text);
50
+ }
51
+ //# sourceMappingURL=asset-extract.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-extract.js","sourceRoot":"","sources":["../../../../src/llm/tasks/ingest/asset-extract.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,gFAAgF;AAChF,6EAA6E;AAC7E,+EAA+E;AAC/E,iFAAiF;AAEjF,OAAO,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAC;AAG5E,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,0DAA0D;IAC1D,eAAe;IACf,2BAA2B;IAC3B,2BAA2B;IAC3B,KAAK;IACL,0DAA0D;IAC1D,sFAAsF;IACtF,uCAAuC;IACvC,8CAA8C;CAC/C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEb,MAAM,UAAU,gBAAgB,CAAC,SAAmB,EAAE,cAAwB,EAAE,aAAuB;IACrG,OAAO;QACL,UAAU,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,EAAE;QAC7C,UAAU,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,EAAE;QAC5C,EAAE;QACF,QAAQ;QACR,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK;KAC9B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC5C,IAAI,MAAM,GAAmB,EAAE,CAAC;IAChC,IAAI,KAAK,GAAmB,EAAE,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,MAAM,CAAC,GAAG,4BAA4B,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACzD,IAAI,CAAC,CAAC;YAAE,SAAS;QACjB,MAAM,IAAI,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC;QACpC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI;YAAE,MAAM,GAAG,IAAI,CAAC;;YAAM,KAAK,GAAG,IAAI,CAAC;IACtD,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AAC3B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,QAAyB,EAAE,SAAmB,EAAE,cAAwB,EAAE,aAAuB,EAAE,MAAoB;IAC3J,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC,QAAQ,EAAE,sBAAsB,EAAE;QACpE,MAAM,EAAE,oBAAoB;QAC5B,IAAI,EAAE,gBAAgB,CAAC,SAAS,EAAE,cAAc,EAAE,aAAa,CAAC;QAChE,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC9B,CAAC,CAAC;IACH,OAAO,kBAAkB,CAAC,IAAI,CAAC,CAAC;AAClC,CAAC"}
@@ -0,0 +1,22 @@
1
+ import type { ProvisionalAsset } from "../../../domain/ingest/assembler.js";
2
+ import type { AssetDecision, CanonicalInfo } from "../../../domain/ingest/apply-plan.js";
3
+ import { type LlmTaskExecutor } from "../../types.js";
4
+ export declare function generateOptional(executor: LlmTaskExecutor, task: Parameters<LlmTaskExecutor["generateText"]>[0], req: {
5
+ system: string;
6
+ user: string;
7
+ signal?: AbortSignal;
8
+ }): Promise<string>;
9
+ export type Kind = "actor" | "location" | "prop";
10
+ export declare const ASSET_RECALL_SYSTEM: string;
11
+ export declare function parseRecallGroups(raw: string, validIds: Set<string>): string[][];
12
+ declare function runRecall(executor: LlmTaskExecutor, assets: ProvisionalAsset[], kind: Kind, signal?: AbortSignal): Promise<string[][]>;
13
+ export declare const ASSET_REFINE_SYSTEM: string;
14
+ export declare function parseRefine(raw: string, groupIds: Set<string>): {
15
+ decisions: AssetDecision[];
16
+ canonical: Record<string, CanonicalInfo>;
17
+ };
18
+ declare function runRefine(executor: LlmTaskExecutor, group: ProvisionalAsset[], signal?: AbortSignal): Promise<{
19
+ decisions: AssetDecision[];
20
+ canonical: Record<string, CanonicalInfo>;
21
+ }>;
22
+ export { runRecall, runRefine };
@@ -0,0 +1,143 @@
1
+ // Pass5 asset governance LLM stages (§9.4/§9.5). Recall proposes candidate
2
+ // same-entity groups from a compact roster (cheap model); refine reads each
3
+ // group's full evidence and decides keep/merge/drop + canonical naming (high
4
+ // model). Prompts, formats, parsing and validation live here; deterministic
5
+ // coverage + apply live in domain/ingest/apply-plan.ts.
6
+ import { LlmTransportError } from "../../types.js";
7
+ // Some governance stages (recall / audit / state) legitimately have nothing to
8
+ // say; a provider that rejects empty text must not crash the pass. Treat an
9
+ // empty_response as an empty string so the parser yields "no action".
10
+ export async function generateOptional(executor, task, req) {
11
+ try {
12
+ return (await executor.generateText(task, req)).text;
13
+ }
14
+ catch (e) {
15
+ if (e instanceof LlmTransportError && e.code === "empty_response")
16
+ return "";
17
+ throw e;
18
+ }
19
+ }
20
+ const KIND_LABEL = { actor: "人物", location: "地点", prop: "道具" };
21
+ // ---- Stage C: recall -------------------------------------------------------
22
+ export const ASSET_RECALL_SYSTEM = [
23
+ "你在做剧本资产去重的粗召回。给你同一类型的资产花名册,每行一个:<id> | <所有名字> | <出现集/次数>。",
24
+ "找出**可能是同一实体不同称呼**的资产,把它们分组。只输出成员 ≥2 的可疑组;确定独立的不要输出。",
25
+ "只能引用给出的真实 id。宁可多召回(后面有精判复核),但不要把明显不同的人凑一组。",
26
+ "输出格式:每组一行,以 '- ' 开头,成员 id 用逗号分隔,例如:",
27
+ "- act_001, act_005, act_012",
28
+ "如果没有任何可合并的组,只输出一行 `无`。不要输出任何其它文字。",
29
+ ].join("\n");
30
+ function buildRoster(assets) {
31
+ return assets.map((a) => `${a.provisional_id} | ${a.names.join(" / ")} | ${a.occurrences.length}次`).join("\n");
32
+ }
33
+ export function parseRecallGroups(raw, validIds) {
34
+ const groups = [];
35
+ for (const line of raw.split("\n")) {
36
+ const t = line.trim();
37
+ if (!t.startsWith("-"))
38
+ continue;
39
+ const ids = t.replace(/^-\s*/, "").split(",").map((s) => s.trim()).filter((s) => validIds.has(s));
40
+ const unique = [...new Set(ids)];
41
+ if (unique.length >= 2)
42
+ groups.push(unique);
43
+ }
44
+ return groups;
45
+ }
46
+ // Recall windowing (§9.4): a single-shot recall over hundreds of assets (video
47
+ // dramas accumulate many per-episode locations/props) truncates. Slide
48
+ // overlapping windows and union the candidate groups; refine re-checks each, so
49
+ // a name landing in two windows' groups is harmless.
50
+ const RECALL_WINDOW = 80;
51
+ const RECALL_OVERLAP = 20;
52
+ async function runRecall(executor, assets, kind, signal) {
53
+ if (assets.length < 2)
54
+ return [];
55
+ const validIds = new Set(assets.map((a) => a.provisional_id));
56
+ const windows = [];
57
+ if (assets.length <= RECALL_WINDOW)
58
+ windows.push(assets);
59
+ else
60
+ for (let i = 0; i < assets.length; i += RECALL_WINDOW - RECALL_OVERLAP) {
61
+ windows.push(assets.slice(i, i + RECALL_WINDOW));
62
+ if (i + RECALL_WINDOW >= assets.length)
63
+ break;
64
+ }
65
+ const groups = [];
66
+ for (const w of windows) {
67
+ const text = await generateOptional(executor, "ingest.asset-recall", {
68
+ system: ASSET_RECALL_SYSTEM,
69
+ user: `类型:${KIND_LABEL[kind]}\n\n${buildRoster(w)}`,
70
+ ...(signal ? { signal } : {}),
71
+ });
72
+ groups.push(...parseRecallGroups(text, validIds));
73
+ }
74
+ // Drop exact-duplicate groups from overlapping windows.
75
+ const seen = new Set();
76
+ return groups.filter((g) => { const k = [...g].sort().join(" "); if (seen.has(k))
77
+ return false; seen.add(k); return true; });
78
+ }
79
+ // ---- Stage D: refine -------------------------------------------------------
80
+ export const ASSET_REFINE_SYSTEM = [
81
+ "你在做剧本资产**身份去重**。给你一组疑似同一实体的资产完整证据。判断哪些真是同一实体、哪些其实是不同实体,",
82
+ "把同一实体合并、并为每个保留下来的实体选 canonical 名与别名。(这里只管合并去重,不管重要程度、不删除资产。)",
83
+ "规则:canonical 名和别名只能来自输入出现过的名字;同类型才能合并;一个 id 只能归入一个最终实体;证据冲突就保持独立。",
84
+ "输出两段,不要输出别的文字:",
85
+ "# 决策",
86
+ "<id>: keep (保持独立)",
87
+ "<id>: merge <目标id> (与目标是同一实体;目标必须是本组里被 keep 的 id)",
88
+ "# 命名",
89
+ "<被keep的id>: <canonical名> | <别名1>, <别名2> (别名可省)",
90
+ ].join("\n");
91
+ function buildEvidence(assets) {
92
+ return assets.map((a) => [
93
+ `## ${a.provisional_id}`,
94
+ `名字: ${a.names.join(" / ")}`,
95
+ a.states.length ? `状态: ${a.states.map((s) => s.name).join(" / ")}` : null,
96
+ `出现: ${a.occurrences.length} 次`,
97
+ ].filter(Boolean).join("\n")).join("\n\n");
98
+ }
99
+ export function parseRefine(raw, groupIds) {
100
+ const decisions = [];
101
+ const canonical = {};
102
+ let section = null;
103
+ for (const line of raw.split("\n")) {
104
+ const t = line.trim();
105
+ if (t === "")
106
+ continue;
107
+ if (t.startsWith("#")) {
108
+ section = t.includes("决策") ? "decisions" : t.includes("命名") ? "canonical" : null;
109
+ continue;
110
+ }
111
+ if (section === "decisions") {
112
+ const m = /^([\w-]+)\s*[::]\s*(keep|merge)(?:\s+([\w-]+))?/i.exec(t);
113
+ if (!m || !groupIds.has(m[1]))
114
+ continue;
115
+ const action = m[2].toLowerCase();
116
+ if (action === "merge") {
117
+ if (!m[3] || !groupIds.has(m[3]))
118
+ continue;
119
+ decisions.push({ provisional_id: m[1], action, merge_into: m[3] });
120
+ }
121
+ else
122
+ decisions.push({ provisional_id: m[1], action });
123
+ }
124
+ else if (section === "canonical") {
125
+ const m = /^([\w-]+)\s*[::]\s*([^|]+?)(?:\s*\|\s*(.*))?$/.exec(t);
126
+ if (!m || !groupIds.has(m[1]))
127
+ continue;
128
+ const aliases = (m[3] ?? "").split(",").map((s) => s.trim()).filter(Boolean);
129
+ canonical[m[1]] = aliases.length ? { name: m[2].trim(), aliases } : { name: m[2].trim() };
130
+ }
131
+ }
132
+ return { decisions, canonical };
133
+ }
134
+ async function runRefine(executor, group, signal) {
135
+ const response = await executor.generateText("ingest.asset-refine", {
136
+ system: ASSET_REFINE_SYSTEM,
137
+ user: buildEvidence(group),
138
+ ...(signal ? { signal } : {}),
139
+ });
140
+ return parseRefine(response.text, new Set(group.map((a) => a.provisional_id)));
141
+ }
142
+ export { runRecall, runRefine };
143
+ //# sourceMappingURL=asset-govern.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asset-govern.js","sourceRoot":"","sources":["../../../../src/llm/tasks/ingest/asset-govern.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import type { LlmTaskExecutor } from "../../types.js";
2
+ export declare const MENTION_RESOLVE_SYSTEM: string;
3
+ export type MentionLine = {
4
+ idx: number;
5
+ text: string;
6
+ };
7
+ export declare function buildMentionUser(cast: string[], lines: MentionLine[]): string;
8
+ export declare function parseMentionRewrites(raw: string, valid: Set<number>): Map<number, string>;
9
+ export declare function runMentionResolve(executor: LlmTaskExecutor, cast: string[], lines: MentionLine[], signal?: AbortSignal): Promise<Map<number, string>>;
@@ -0,0 +1,39 @@
1
+ // ingest.mention-resolve task (§pass4). Plain-text pronoun resolution: given a
2
+ // scene's known cast and its numbered body lines, rewrite lines whose
3
+ // pronoun/vague reference (他/她/那人/一人/另一人…) can be pinned to a concrete
4
+ // cast member. Only pronoun substitution — the rest of the line stays verbatim.
5
+ // Empty output means nothing was resolvable.
6
+ import { generateOptional } from "./asset-govern.js";
7
+ export const MENTION_RESOLVE_SYSTEM = [
8
+ "你在把剧本正文里的代词/泛指(他、她、那人、一人、另一人、对方 等)替换成具体人名。",
9
+ "给你本场已知人物名单,和若干带编号的正文行。只有当你能从上下文确定某个代词具体指名单里的谁时,才改写该行。",
10
+ "铁律:只替换能确定的代词,其余文字**逐字不变**,不润色、不增删、不改标点。名字只能用名单里的。判不出就别动那行。",
11
+ "输出:每个被改写的行一行,格式 `编号<TAB>改写后的整行`。没改的行不要输出;没有任何可改的就输出空。",
12
+ ].join("\n");
13
+ export function buildMentionUser(cast, lines) {
14
+ return [`【本场人物】${cast.join("、") || "(无)"}`, "", "【正文行】", ...lines.map((l) => `${l.idx}\t${l.text}`)].join("\n");
15
+ }
16
+ export function parseMentionRewrites(raw, valid) {
17
+ const out = new Map();
18
+ for (const line of raw.split("\n")) {
19
+ const tab = line.indexOf("\t");
20
+ if (tab <= 0)
21
+ continue;
22
+ const idx = Number(line.slice(0, tab).trim().replace(/^[[]|[\]]$/g, ""));
23
+ const text = line.slice(tab + 1);
24
+ if (Number.isInteger(idx) && valid.has(idx) && text.trim())
25
+ out.set(idx, text);
26
+ }
27
+ return out;
28
+ }
29
+ export async function runMentionResolve(executor, cast, lines, signal) {
30
+ if (lines.length === 0 || cast.length === 0)
31
+ return new Map();
32
+ const text = await generateOptional(executor, "ingest.mention-resolve", {
33
+ system: MENTION_RESOLVE_SYSTEM,
34
+ user: buildMentionUser(cast, lines),
35
+ ...(signal ? { signal } : {}),
36
+ });
37
+ return parseMentionRewrites(text, new Set(lines.map((l) => l.idx)));
38
+ }
39
+ //# sourceMappingURL=mention-resolve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mention-resolve.js","sourceRoot":"","sources":["../../../../src/llm/tasks/ingest/mention-resolve.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,sEAAsE;AACtE,uEAAuE;AACvE,gFAAgF;AAChF,6CAA6C;AAG7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,CAAC,MAAM,sBAAsB,GAAG;IACpC,4CAA4C;IAC5C,uDAAuD;IACvD,4DAA4D;IAC5D,uDAAuD;CACxD,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAIb,MAAM,UAAU,gBAAgB,CAAC,IAAc,EAAE,KAAoB;IACnE,OAAO,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAClH,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,GAAW,EAAE,KAAkB;IAClE,MAAM,GAAG,GAAG,IAAI,GAAG,EAAkB,CAAC;IACtC,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,GAAG,IAAI,CAAC;YAAE,SAAS;QACvB,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,CAAC;QACzE,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;QACjC,IAAI,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE;YAAE,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IACjF,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,QAAyB,EAAE,IAAc,EAAE,KAAoB,EAAE,MAAoB;IAC3H,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,GAAG,EAAE,CAAC;IAC9D,MAAM,IAAI,GAAG,MAAM,gBAAgB,CAAC,QAAQ,EAAE,wBAAwB,EAAE;QACtE,MAAM,EAAE,sBAAsB;QAC9B,IAAI,EAAE,gBAAgB,CAAC,IAAI,EAAE,KAAK,CAAC;QACnC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC9B,CAAC,CAAC;IACH,OAAO,oBAAoB,CAAC,IAAI,EAAE,IAAI,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AACtE,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { LlmTaskExecutor } from "../../types.js";
2
+ export declare const PLOT_SPEAKER_SYSTEM: string;
3
+ export declare function plotSpeakerPrompt(episodeNo: number, allSynopsis: string, contextMd: string, pass1Md: string): string;
4
+ export interface PlotSpeakerFix {
5
+ ts: string;
6
+ line: string;
7
+ from: string;
8
+ to: string;
9
+ reason: string;
10
+ }
11
+ export declare function runPlotSpeaker(executor: LlmTaskExecutor, episodeNo: number, allSynopsis: string, contextMd: string, pass1Md: string, signal?: AbortSignal): Promise<PlotSpeakerFix[]>;
@@ -0,0 +1,72 @@
1
+ // Pure-plot speaker audit (§10.2 pass4b/pass5, ported from cezhi-verify 04b).
2
+ // No video: reads the whole-series per-episode briefs + roster + one episode's
3
+ // transcript and finds mis-attributed speakers using plot logic (称呼/对话回合/
4
+ // 因果/阵营). Catches errors whose SOURCE is the video (lip-sync residue) where
5
+ // pass4's video-trusting audit fails. Prompt VERBATIM from the tuned scaffold.
6
+ export const PLOT_SPEAKER_SYSTEM = "你是短剧剧本的说话人校对器。你只拿到文字:一份**全剧分集梗概**(建立人物阵营/敌友关系)、一份跨集资产花名册(context)、和某一集的剧本流 md(逐句带说话人标注和时间戳)。**你看不到视频,也不需要看**。" +
7
+ "你的唯一任务:通读这一集的剧情,找出**说话人被标错**的台词行。" +
8
+ "错误来源:第一遍是对着视频画面标说话人的,当镜头没切、上一句某人刚说完口型还在,下一句其实换了人说,画面会把它误标成同一个人。这类错**光看画面救不了,只能靠剧情**。" +
9
+ "判断用四种线索,且必须**唯一确定**才改:" +
10
+ "① 称呼——谁喊谁「老大/哥/老X/X总/爸/妈」:喊出这个称呼的人不可能是被称呼者本人(一个人不会当面用敬称/长辈称/绰号喊自己)。" +
11
+ "② 对话回合——一问一答、一让一应:谁抛的话、谁接的话,说话人应当在两个人之间交替,不会连着两句都是同一人自问自答(除非明显是独白)。" +
12
+ "③ 因果——谁得利谁道谢、谁做错谁道歉、谁下命令谁执行:由剧情角色关系唯一锁定。" +
13
+ "④ **阵营/立场矛盾(重要,靠全剧梗概判)**——某句话的立场(帮腔/示好/维护/巴结 vs 羞辱/打压/敌视)与被标说话人的**已知阵营**相反时,说话人标错了。例:一句在维护/巴结男主(『老板肯定站你的』『我就说吧』),却被标成男主的死对头——死对头不会替男主帮腔,这句必是男主的盟友说的。**先从梗概搞清谁和谁一伙、谁是谁的对头,再判这话该谁说。**" +
14
+ "**画面残留的典型形态(重点召回)**:某句台词的前一拍或后一拍动作描写指向的是另一个人(如『X 伸手抓住 Y』紧跟一句安抚的话——说话人多半是 X 不是镜头里的第三人),或连续两句被标同一人、但一句在喊称呼/表立场明显换了人。这类最容易被画面骗过,要主动查。" +
15
+ "**铁律:只在剧情明确矛盾、能唯一指认正确说话人时才输出一条 fix。** 只要有一丝不确定(可能是独白、可能你没读懂关系、正确人选不唯一),就**不要动**——宁可漏纠,不可错纠。不改台词内容,只纠说话人。没有要改的就返回空数组。";
16
+ const PLOT_SPEAKER_SCHEMA = {
17
+ type: "object",
18
+ additionalProperties: false,
19
+ required: ["speaker_fixes"],
20
+ properties: {
21
+ speaker_fixes: {
22
+ type: "array",
23
+ description: "说话人校正。只收『纯靠剧情逻辑就能确定标错了』的,证据不足一律不收。",
24
+ items: {
25
+ type: "object",
26
+ additionalProperties: false,
27
+ required: ["ts", "line", "from", "to", "reason"],
28
+ properties: {
29
+ ts: { type: "string", description: "这句被标错说话人的台词时间戳,原样照抄剧本流里那一行的 [MM:SS.sss]" },
30
+ line: { type: "string", description: "这句台词的原文(截前 15 字即可),用于人工核对定位" },
31
+ from: { type: "string", description: "剧本流里当前标的(错误)说话人" },
32
+ to: { type: "string", description: "按剧情逻辑应为的正确说话人(必须来自本集在场角色/花名册,不能凭空造名)" },
33
+ reason: { type: "string", description: "剧情依据一句话:靠什么称呼/对话回合/因果锁定是这个人(如:这句『谢谢老大』是得利者道谢、且喊对方『老大』,只能是受益并示好的一方,不是被喊老大的那个人)" },
34
+ },
35
+ },
36
+ },
37
+ },
38
+ };
39
+ export function plotSpeakerPrompt(episodeNo, allSynopsis, contextMd, pass1Md) {
40
+ return `第 ${episodeNo} 集的纯剧情说话人校对。
41
+
42
+ ========== 全剧分集梗概(建立人物阵营/敌友关系,用于判「谁不可能说这话」) ==========
43
+ ${allSynopsis}
44
+
45
+ ========== 跨集资产 CONTEXT(花名册,人物关系/称呼参考) ==========
46
+ ${contextMd}
47
+
48
+ ========== 本集剧本流 md(逐句带说话人 [dlg|说话人] 和时间戳) ==========
49
+ ${pass1Md}
50
+
51
+ ========== 任务 ==========
52
+ 先读全剧梗概,搞清本集涉及的人物**谁和谁一伙、谁是谁的对头**;再通读本集,用「称呼 / 对话回合 / 因果 / 阵营立场」四种线索,找出**说话人标错**的 [dlg]/[think] 行。
53
+ - 逐个可疑处问自己:这句话按剧情+阵营,说话人只可能是谁?和当前标注冲突吗?冲突且唯一 → 收一条 fix;不唯一或没读懂 → 跳过。
54
+ - 典型信号:① 某句在喊「老大/老X/哥/X总」,却把说话人标成了被喊的那个人本人;② 一段对话回合里说话人没有正常交替(连着两句标同一人、但内容明显是一问一答);③ 某句在帮腔/维护/巴结某人,却被标成那个人的**对头**(阵营矛盾);④ 一句台词紧挨的上一拍/下一拍动作指向的是另一个人。
55
+ - 正确说话人必须是本集真实在场、花名册里有的角色,不能编。注意本集可能用职称(宁总/齐总)指代,先对到梗概里的本名和阵营再判。
56
+ - ts 原样照抄那一行的时间戳。严格按 schema 返回 JSON,没有要改的返回空数组。`;
57
+ }
58
+ export async function runPlotSpeaker(executor, episodeNo, allSynopsis, contextMd, pass1Md, signal) {
59
+ const res = await executor.generateTool("ingest.speaker-audit", {
60
+ system: PLOT_SPEAKER_SYSTEM,
61
+ user: plotSpeakerPrompt(episodeNo, allSynopsis, contextMd, pass1Md),
62
+ tool: { name: "submit_speaker_fixes", description: "提交纯剧情说话人校正", inputSchema: PLOT_SPEAKER_SCHEMA },
63
+ ...(signal ? { signal } : {}),
64
+ });
65
+ const fixes = Array.isArray(res.input?.["speaker_fixes"]) ? res.input["speaker_fixes"] : [];
66
+ return fixes.map((f) => {
67
+ const o = f;
68
+ const s = (k) => (typeof o[k] === "string" ? o[k] : "");
69
+ return { ts: s("ts"), line: s("line"), from: s("from"), to: s("to"), reason: s("reason") };
70
+ }).filter((f) => f.from && f.to);
71
+ }
72
+ //# sourceMappingURL=plot-speaker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plot-speaker.js","sourceRoot":"","sources":["../../../../src/llm/tasks/ingest/plot-speaker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,46 @@
1
+ import type { LlmTaskExecutor } from "../../types.js";
2
+ export interface RosterEntryInput {
3
+ name: string;
4
+ episodes: number[];
5
+ anchors: string[];
6
+ appearances: string[];
7
+ roles: string[];
8
+ }
9
+ export declare const RECALL_SYSTEM: string;
10
+ export declare function mergePrompt(actors: RosterEntryInput[]): string;
11
+ export declare const REFINE_SYSTEM: string;
12
+ export declare function refinePrompt(members: RosterEntryInput[]): string;
13
+ export declare const CANON_SYSTEM: string;
14
+ export declare function canonPrompt(members: Array<{
15
+ name: string;
16
+ episodes: number[];
17
+ }>): string;
18
+ export declare const REMERGE_SYSTEM: string;
19
+ export declare function remergePrompt(entries: Array<{
20
+ name: string;
21
+ episodes: number[];
22
+ anchors: string[];
23
+ roles: string[];
24
+ }>): string;
25
+ export interface RosterGroup {
26
+ canonical: string;
27
+ aliases: string[];
28
+ reason: string;
29
+ }
30
+ export declare function runRosterRecall(executor: LlmTaskExecutor, entries: RosterEntryInput[], signal?: AbortSignal): Promise<RosterGroup[]>;
31
+ export declare function runRosterRefine(executor: LlmTaskExecutor, members: RosterEntryInput[], signal?: AbortSignal): Promise<string[][]>;
32
+ export declare function runRosterCanon(executor: LlmTaskExecutor, members: Array<{
33
+ name: string;
34
+ episodes: number[];
35
+ }>, signal?: AbortSignal): Promise<string>;
36
+ export interface RemergeGroup {
37
+ into: string;
38
+ names: string[];
39
+ reason: string;
40
+ }
41
+ export declare function runRosterRemerge(executor: LlmTaskExecutor, entries: Array<{
42
+ name: string;
43
+ episodes: number[];
44
+ anchors: string[];
45
+ roles: string[];
46
+ }>, signal?: AbortSignal): Promise<RemergeGroup[]>;