@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,144 @@
1
+ // ingest.video-correct task (§10.2 pass4, ported from cezhi-verify 04). Second
2
+ // Gemini pass: video + merged roster (context) + first-pass transcript → flat
3
+ // JSON corrections (name/same_person/speaker/dialogue fixes + notes). Reuses the
4
+ // episode's already-uploaded file. Prompt + schema VERBATIM from the tuned
5
+ // scaffold; Gemini structured output via responseJsonSchema.
6
+ import { CliError, EXIT_RUNTIME } from "../../../common.js";
7
+ export const VIDEO_CORRECT_SYSTEM = "你是短剧剧本的跨集校对器。你会拿到:本集原视频、一份跨集资产花名册(context)、以及第一遍对本集生成的剧本 md。" +
8
+ "第一遍是单集独立生成的,可能有四类错:①字幕谐音把人名带偏(本名被写成同音近音的别字);②同一个人跨集用了不同称呼(某集用职务/外貌称呼,花名册里有其规范本名);③口型与字幕冲突导致对白抄错;" +
9
+ "④**说话人认错**——第一遍按「画面里此刻是谁的脸」定说话人,但剧里有几个长相相似的角色(尤其一批花白头发、国字脸的中老年男性高管),画面识别会把他们互相认错。" +
10
+ "对第④类,光看脸救不了(他们本来就像),必须用**剧情逻辑**:" +
11
+ "台词内容、彼此的称呼(谁叫谁「哥」「老许」「X总」)、场景里的关系(谁在求谁、谁在训谁、谁下跪谁站着、谁是主角谁是对手)," +
12
+ "这些能锁定『这场戏在场的是哪几个人、每句话是谁说的』——这是跨镜头的剧情推理,比单帧人脸可靠。" +
13
+ "推理顺序:**先不管第一遍标了谁,只从台词+称呼+剧情关系推断这场有哪些人、谁对谁说话;再回头比对第一遍标的说话人,矛盾的就用 speaker_fixes 纠正。剧情锁定的身份优先于画面外貌。**" +
14
+ "你的任务:对照原视频画面(人脸/口型/视觉锚点)、剧情逻辑、和 context 花名册,只输出**校正指令**,不要重写整集。没有要改的就返回空数组。";
15
+ const CORRECTION_SCHEMA = {
16
+ type: "object",
17
+ additionalProperties: false,
18
+ required: ["name_fixes", "same_person", "speaker_fixes", "dialogue_fixes", "notes"],
19
+ properties: {
20
+ name_fixes: {
21
+ type: "array",
22
+ description: "人物命名校正:字幕谐音坑、跨集同人不同称呼",
23
+ items: {
24
+ type: "object",
25
+ additionalProperties: false,
26
+ required: ["from", "to", "scope", "reason"],
27
+ properties: {
28
+ from: { type: "string", description: "第一遍 md 里用的名字(可能是字幕谐音带偏的,或未听到本名时按职务/外貌起的名)" },
29
+ to: { type: "string", description: "校正后的规范名(来自 context 花名册)" },
30
+ scope: { type: "string", enum: ["all", "dialogue_only"], description: "all=该名字所有出现都改;dialogue_only=只改对白里的称呼" },
31
+ reason: { type: "string", description: "依据:视觉锚点/口型/context 匹配,一句话" },
32
+ },
33
+ },
34
+ },
35
+ same_person: {
36
+ type: "array",
37
+ description: "跨集同人合并判定(本名 vs 职务称呼 vs 听错的名)",
38
+ items: {
39
+ type: "object",
40
+ additionalProperties: false,
41
+ required: ["names", "reason"],
42
+ properties: {
43
+ names: { type: "array", items: { type: "string" }, description: "判定为同一个人的多个称呼,规范名放第一个" },
44
+ reason: { type: "string", description: "依据的视觉锚点,一句话" },
45
+ },
46
+ },
47
+ },
48
+ speaker_fixes: {
49
+ type: "array",
50
+ description: "说话人/在场人校正:第一遍按画面里谁的脸定说话人,但长相相似的角色(一批花白头发老头)会认错。用剧情逻辑(谁对谁说话、称呼、场景关系)纠正标错的人。",
51
+ items: {
52
+ type: "object",
53
+ additionalProperties: false,
54
+ required: ["ts", "from", "to", "reason"],
55
+ properties: {
56
+ ts: { type: "string", description: "这句台词/动作的时间戳,原样照抄第一遍 md 里那一行的时间戳(MM:SS.sss)" },
57
+ from: { type: "string", description: "第一遍标错的说话人/在场人名" },
58
+ to: { type: "string", description: "按剧情逻辑应为的正确人名(来自 context 花名册)" },
59
+ reason: { type: "string", description: "剧情依据:台词内容/称呼/场景关系为什么锁定这个人,一句话(如:这场是甲向乙下跪求他回来,跪着说'哥对不起你'的只能是甲,第一遍误标成了另一个长相相似的角色)" },
60
+ },
61
+ },
62
+ },
63
+ dialogue_fixes: {
64
+ type: "array",
65
+ description: "对白内容校正:仅限同音谐音错字、串台词、关键数字错。不做称呼规范化——台词里怎么称呼一律保留原话。",
66
+ items: {
67
+ type: "object",
68
+ additionalProperties: false,
69
+ required: ["ts", "speaker", "wrong", "right", "reason"],
70
+ properties: {
71
+ ts: { type: "string", description: "对白时间戳,原样照抄第一遍 md 里那一行的时间戳(MM:SS.sss)" },
72
+ speaker: { type: "string", description: "规范说话人名(此字段可用规范名;但下面的 right 台词正文不许用规范名替换称呼)" },
73
+ wrong: { type: "string", description: "第一遍里抄错的对白文本片段" },
74
+ right: { type: "string", description: "订正后的对白文本。**只订正同音/谐音错字或串台词**,其余保持原样。严禁把台词里对人物的称呼(某总/某董/某哥/老某)替换成花名册规范名(那个人的本名)——称呼是台词原话,规范名只进 speaker 字段。" },
75
+ reason: { type: "string", description: "为什么是抄错:说明是『同音错字订正』(徐→许)还是『串台词/数字错』。若你写的理由是\"规范名/称呼规范化/应称呼其本名\",说明这是越界,不要提交这条。" },
76
+ },
77
+ },
78
+ },
79
+ notes: { type: "array", items: { type: "string" }, description: "其他值得记录的问题(如镜头误读、幻觉),不强制修,仅记录" },
80
+ },
81
+ };
82
+ export function videoCorrectPrompt(episodeNo, contextMd, pass1Md) {
83
+ return `第 ${episodeNo} 集的校对。
84
+
85
+ ========== 跨集资产 CONTEXT(花名册,规范名以此为准) ==========
86
+ ${contextMd}
87
+
88
+ ========== 第一遍对本集生成的剧本 md(待校正) ==========
89
+ ${pass1Md}
90
+
91
+ ========== 任务 ==========
92
+ 对照上方原视频,逐条检查第一遍 md:
93
+ 1. **name_fixes**:本集里有没有被字幕带偏的人名(对口型/看字幕字样判断),或用了「X总」这类称呼而 context 里有对应规范本名的 —— 给出 from→to。
94
+ 2. **same_person**:本集出现的人,和 context 花名册里哪个是同一个人(比对视觉锚点:发型/眼镜/脸型/体型/年龄段)。**这是重点,要主动合并,不要因为名字不同就漏判**:
95
+ - 本集常用职称/敬称(「X总」「X董」「X秘书」)指代的,几乎一定是花名册里已有的某个规范本名 —— 逐个比对锚点,吻合就合并(如 本集某「X总」戴金丝眼镜+花白背头+国字脸 ⇄ 花名册里某本名同锚点 ⇒ 判同人,规范名用那个本名放第一个)。
96
+ - 判据是**视觉锚点吻合**,不要求名字字面相同。锚点有轻微出入(银丝/金丝眼镜、灰/花白头发)属正常噪声,不影响判定。
97
+ - 只有当锚点明显冲突(性别/年龄段/发型完全不符)才不合并。宁可主动合并本集的「X总」到花名册规范名,也不要留一堆孤立的「X总」。
98
+ 3. **speaker_fixes(重点,治长相相似的老头互认)**:逐场用剧情逻辑核对说话人/在场人:
99
+ - 先从台词内容+称呼+场景关系推断「这场戏在场的是谁、谁对谁说话」,**不要先信第一遍标的名字**。
100
+ - 例:某场台词是「我跪下了」「哥对不起你」「我不该听那人的鬼话」——这是一个认错求人的角色(结合上下文是甲向乙下跪求他),这场只有甲+乙,没有别人;如果第一遍把跪着说话的标成了另一个长相相似的第三人,就是认错了,报 from=那个第三人 to=甲。
101
+ - 判据是**剧情**不是脸:几个长相相近的角色(如一批花白头发、国字脸的中老年男性)画面像,但「谁在这场、谁说这话」由剧情唯一确定。凡第一遍 speaker 与剧情矛盾的,都纠正。
102
+ 4. **dialogue_fixes(严格限定,别越界改台词)**:只修两类**明显抄错**:
103
+ - **同音/谐音错字**:字幕把某个音写成了错字,但读音相同、指的是同一个对象——只把错字订正成对的字(例:某人的姓被写成同音的别字,则把带这个姓的称呼里的错字改回对的姓,如把同音写错的「X总」订正为正确姓氏的「X总」;名字某个字听岔写成近音字,订正回对的字)。订正的是**错字本身**,不是换一种叫法。
104
+ - **串台词/关键数字错**:整句抄到别处、或金额数字明显抄错。
105
+ - **铁律:台词内容一个字都不能按花名册去"规范化"。** 人物在台词里**被怎么称呼**(某个「X董」「X哥」「X总」「老X」)是这句台词的原话,即使花名册规范名是他的本名,也**绝对不许**把台词里的称呼替换成规范名——台词里是「X董」就保持「X董」,是「X哥」就保持「X哥」。称呼是谁、规范名是谁,是两回事;规范名只用于 speaker/name 字段,永不进台词正文。
106
+ - 判据自检:如果你想把 wrong→right 改的是「一种称谓换成另一种称谓」(董→天明、哥→总、总→本名),那就是越界,不要改;只有「同一个音的错字订正」才做。
107
+ 5. **notes**:镜头误读、明显幻觉(如把满场的镜头描述成空场)等,记录即可。
108
+
109
+ 只输出校正,不确定的不要瞎改。严格按 schema 返回 JSON。`;
110
+ }
111
+ function correctError(message, received) {
112
+ return new CliError("INGEST VIDEO CORRECT FAILED", message, {
113
+ exitCode: EXIT_RUNTIME, errorCode: "INGEST_VIDEO_CORRECT_FAILED", received,
114
+ nextSteps: ["Inspect the episode error sidecar and rerun `scriptctl ingest`."],
115
+ });
116
+ }
117
+ const asList = (v) => (Array.isArray(v) ? v : []);
118
+ const str = (v) => (typeof v === "string" ? v : "");
119
+ const strList = (v) => asList(v).map(str).filter(Boolean);
120
+ export async function runVideoCorrect(port, file, episodeNo, contextMd, pass1Md, fps, signal) {
121
+ const response = await port.generate({
122
+ file,
123
+ system: VIDEO_CORRECT_SYSTEM,
124
+ user: videoCorrectPrompt(episodeNo, contextMd, pass1Md),
125
+ fps,
126
+ responseJsonSchema: CORRECTION_SCHEMA,
127
+ ...(signal ? { signal } : {}),
128
+ });
129
+ let raw;
130
+ try {
131
+ raw = JSON.parse(response.text);
132
+ }
133
+ catch {
134
+ throw correctError(`episode ${episodeNo}: corrections were not valid JSON`, [response.text.slice(0, 200)]);
135
+ }
136
+ return {
137
+ name_fixes: asList(raw["name_fixes"]).map((x) => { const o = x; return { from: str(o["from"]), to: str(o["to"]), scope: str(o["scope"]) || "all", reason: str(o["reason"]) }; }),
138
+ same_person: asList(raw["same_person"]).map((x) => { const o = x; return { names: strList(o["names"]), reason: str(o["reason"]) }; }),
139
+ speaker_fixes: asList(raw["speaker_fixes"]).map((x) => { const o = x; return { ts: str(o["ts"]), from: str(o["from"]), to: str(o["to"]), reason: str(o["reason"]) }; }),
140
+ dialogue_fixes: asList(raw["dialogue_fixes"]).map((x) => { const o = x; return { ts: str(o["ts"]), speaker: str(o["speaker"]), wrong: str(o["wrong"]), right: str(o["right"]), reason: str(o["reason"]) }; }),
141
+ notes: strList(raw["notes"]),
142
+ };
143
+ }
144
+ //# sourceMappingURL=video-correct.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video-correct.js","sourceRoot":"","sources":["../../../../src/llm/tasks/ingest/video-correct.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { TaskVideoPort, VideoFileHandle } from "../../types.js";
2
+ export declare const VIDEO_TRANSCRIBE_SYSTEM: string;
3
+ export declare function buildTranscribeUser(episodeNo: number): string;
4
+ export declare function runVideoTranscribe(port: TaskVideoPort, file: VideoFileHandle, episodeNo: number, fps: number, signal?: AbortSignal): Promise<string>;
@@ -0,0 +1,105 @@
1
+ // ingest.video-transcribe task (§10.2 pass1). Gemini turns one episode video
2
+ // into a high-fidelity screenplay markdown: `## 梗概`, then `# 剧本` (scenes with
3
+ // sub-second [MM:SS.sss] timestamps + typed-speaker anchors), then `# 资产` (a
4
+ // character roster carrying cross-episode visual anchors/role — the evidence the
5
+ // merge layer needs). Built on the text MARKDOWN spec, extended with timestamps
6
+ // and per-character anchors. The upload/reuse of the media file is orchestrated
7
+ // by the pipeline (a handle is passed in); this task only generates.
8
+ import { CliError, EXIT_RUNTIME } from "../../../common.js";
9
+ export const VIDEO_TRANSCRIBE_SYSTEM = "你是短剧视频转剧本的分析器。输入是一整集短剧视频(竖屏、1-2 分钟)。" +
10
+ "你的任务是把这一集**逐镜头、高保真**地转写成一份 markdown 剧本流文档,供转绘 agent 后续出图使用。" +
11
+ "核心要求:不漏镜头、动作/对白/实体准确、不脑补、时间戳对齐画面。";
12
+ export function buildTranscribeUser(episodeNo) {
13
+ return `把这一集(第 ${episodeNo} 集)视频转成一份 markdown 剧本流文档。
14
+
15
+ Output format: 一份 markdown 文档。顺序固定:先 \`## 梗概\`,再 \`# 剧本\`,再 \`# 资产\`。
16
+ 不要用 \`\`\` 代码块包裹,不要在文档前后加任何解释性文字。
17
+
18
+ ## 梗概
19
+ <按发生顺序概括本集剧情,200-300 字,纯文本,不用 markdown 结构语法>
20
+
21
+ # 剧本
22
+
23
+ ## 场景 1
24
+ - 时空: <内|外> <日|夜>
25
+ - 时间: <MM:SS.sss-MM:SS.sss,本场在视频中的起止时间>
26
+ - 地点: <稳定主空间地点名>
27
+ - 角色: <单人角色1>(状态), <角色2>(状态) ← 状态=整套着装造型,如 (黑色西装)
28
+ - 道具: <需保持一致的道具1>, <道具2>
29
+
30
+ > [act] [MM:SS.sss] 动作或环境描写(逐镜头,含镜头景别)。**只写画面里发生的动作/环境,绝不把台词字幕抄进来**——短剧每句话底部那条对白字幕是冗余的,属于对应的 [dlg],act 里一个字都不要出现(详见「画面字幕的取舍」铁律)。
31
+ > [dlg|name] [MM:SS.sss] 角色对白(以口型/音轨为准)。
32
+ > [dlg|name|emotion] [MM:SS.sss] 带情绪标签的对白。
33
+ > [dlg|broadcast:名] [MM:SS.sss] 广播/画外音/主持人等非人物发声。
34
+ > [think|name] [MM:SS.sss] 角色心声/内心独白(画外音但明确是某人所想)。
35
+
36
+ ## 场景 2
37
+ ...
38
+
39
+ # 资产
40
+
41
+ ## 人物
42
+ 每个点名或反复出现的具体单人角色,用如下**多行**格式(这是本协议的重点,务必填全):
43
+ - <角色名>
44
+ 外观: <跨集恒定的身份长相:性别 + 年龄段 + 脸型五官 + 发型发色 + 体型身高 + 固定标记(痣/疤/眼镜/胡须)+ 气质。**不含服饰**,服饰属状态>
45
+ 锚点: <最好认的 1-3 个视觉特征,一句话,用于在别的镜头里重新指认这个人。例:花白背头+金丝眼镜+国字脸>
46
+ 声线: <音色/口音/说话方式,画外或未露脸时的辅助辨识。没有可写「未知」>
47
+ 作用: <这个人在剧情里的身份与关系,例:男主 / 空降副总裁、男主对头 / 男主多年副手>
48
+
49
+ ## 场景
50
+ - <地点名>: <空间类型/规模/风格/主色调/光线/陈设>
51
+
52
+ ## 道具
53
+ - <道具名>: <类别/尺寸/材质/颜色/标志特征>
54
+
55
+ ## 发声源
56
+ - <发声源名>(broadcast|system|prop|location): <声音描述>
57
+
58
+ ## 人物状态
59
+ - <角色名>|<状态名>: <这个状态下的具体可视外观,只写稳定造型,不写动作/情绪/镜头>
60
+
61
+ 规则:
62
+ - 台词以人物**实际开口(口型/音轨)**为准。画面字幕可能是**谐音错字或译文**,与口型冲突时以口型为准,把你判断的正确人名/词写进对白正文即可。
63
+ - **画面字幕的取舍(铁律,最容易犯错,务必照做)**:短剧几乎每句台词底部都压着一条对白字幕,它只是把角色**正在说的这句话**用文字又显示一遍——这类字幕是**对白的冗余复制,必须彻底丢弃**,只保留对应的 [dlg] 行即可,**绝对不要**在任何 act 里写「画面字幕:<某句话>」去复述台词。
64
+ - 判据(每遇到一条画面文字都过一遍):这条字幕的内容,是不是差不多就是紧邻的某句台词(某个 [dlg]/[think])?——**是 ⇒ 直接删,act 里不留任何痕迹**;否 ⇒ 才可能保留。
65
+ - 正例(该删):一句台词是「你少管闲事」,画面底部同时显示同样的字幕——只保留那条 [dlg|某人] 你少管闲事,**不要**再写一条 [act] 去注明「画面字幕:你少管闲事」。哪怕字幕和台词有一两个字出入(谐音/漏字),只要显然是同一句,也删。
66
+ - 反例(该留,写进 act 并注明「画面字幕:xxx」):**不是任何人此刻在说的话**、承载对白之外新信息的画面文字,才留——人物介绍/身份头衔条、系统/UI 提示文字、时间地点交代(如「三年后」「上海·总部」)、旁白性说明、关键道具上的文字。判别关键:它是「谁正在开口说的台词」还是「画面上一段独立信息」?前者删,后者留。
67
+ - **人物介绍/姓名头衔条例外**:它承载正式姓名这一新信息,既要写进 act,又要据它把对应角色命名为该正式姓名(见「角色命名」)。
68
+ - 角色命名(重要):
69
+ - **命名优先级:书面正式姓名 > 口头喊出的本名 > 纯描述名。** 三者按下面规则取最高可得的一档。
70
+ - **画面给了书面正式姓名**(人物介绍条/姓名头衔卡/来电显示/工牌/名片/署名等,明确把一个正式姓名标注在某个人身上)→ **就用这个正式姓名当该角色的名**,哪怕全集里所有人只当面喊他职务/敬称(「X总」「X董」「老X」)。书面介绍条是剧方给出的权威身份,优先级高于旁人对他的称呼。判断这条介绍字幕是**压在哪个人身上**(谁的镜头/谁的位置),就把名安到那个人,并在后续该角色的所有 [dlg]/[think] 都用这个正式姓名,保持全集统一。
71
+ - **听到本名**(对白里明确喊出的姓名)而没有书面姓名条 → 用听到的规范本名(不要用字幕同音近音的误写)。
72
+ - **既没有书面姓名、也没听到本名** → 只能用**不含姓氏的纯描述名**:按身份或外貌,如「前上司」「下跪的男人」「黑衣女子」「湿发中年男」。并在 锚点 写清体貌,方便第二遍跨集对号。
73
+ - **严禁凭空捏造带姓氏或像真名的称呼**:没有在视频里真实听到/看到「王总」「李董」「小许」这类称呼时,绝不能自己编一个安上去。捏造的带姓假名会被下游误当成真实人名,污染跨集归并(例:某集把没听到名字的角色随手叫「王总」,其实他是花名册里的别人,假姓一旦落地就很难纠)。宁可用「前上司」这种一眼可见是临时描述的名,也不要编「王总」。
74
+ - 只有当某个「X总/X董/X姐」称呼是**视频里真实出现的**(有人这么叫他、或字幕这么写),才可以用。
75
+ - \`## 人物\` 只登记具体单人角色;众人/群众/路人用 \`group:名\` 发声或写进 action,不进人物。
76
+ - 状态=整套着装/发型/持续妆造等宏观造型档位,用描述性命名(金色礼服/深灰西装),不用「默认/常态」。情绪、姿态、临时脏污、普通便装不是状态。
77
+ - action 正文逐镜头写实,不要合并镜头、不要脑补画面外信息。
78
+ - 每个 [act]/[dlg]/[think] 都要带 [MM:SS.sss] 时间戳(毫秒三位,精确对齐该镜头/该句起始画面)。
79
+
80
+ 现在开始输出这一集的完整 markdown 文档。`;
81
+ }
82
+ function transcribeError(message, received) {
83
+ return new CliError("INGEST TRANSCRIBE FAILED", message, {
84
+ exitCode: EXIT_RUNTIME,
85
+ errorCode: "INGEST_TRANSCRIBE_FAILED",
86
+ received,
87
+ nextSteps: ["Inspect the episode error sidecar and rerun `scriptctl ingest`."],
88
+ });
89
+ }
90
+ // Transcribe one already-uploaded episode video to markdown. A too-short result
91
+ // is treated as a failed transcription (§12.3: empty responses do not retry).
92
+ export async function runVideoTranscribe(port, file, episodeNo, fps, signal) {
93
+ const response = await port.generate({
94
+ file,
95
+ system: VIDEO_TRANSCRIBE_SYSTEM,
96
+ user: buildTranscribeUser(episodeNo),
97
+ fps,
98
+ ...(signal ? { signal } : {}),
99
+ });
100
+ const markdown = response.text.trim();
101
+ if (markdown.length < 40)
102
+ throw transcribeError(`episode ${episodeNo}: transcript too short`, [`length: ${markdown.length}`]);
103
+ return markdown;
104
+ }
105
+ //# sourceMappingURL=video-transcribe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video-transcribe.js","sourceRoot":"","sources":["../../../../src/llm/tasks/ingest/video-transcribe.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,8EAA8E;AAC9E,6EAA6E;AAC7E,iFAAiF;AACjF,gFAAgF;AAChF,gFAAgF;AAChF,qEAAqE;AAErE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAG5D,MAAM,CAAC,MAAM,uBAAuB,GAClC,sCAAsC;IACtC,6DAA6D;IAC7D,mCAAmC,CAAC;AAEtC,MAAM,UAAU,mBAAmB,CAAC,SAAiB;IACnD,OAAO,UAAU,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0BAmEF,CAAC;AAC3B,CAAC;AAED,SAAS,eAAe,CAAC,OAAe,EAAE,QAAkB;IAC1D,OAAO,IAAI,QAAQ,CAAC,0BAA0B,EAAE,OAAO,EAAE;QACvD,QAAQ,EAAE,YAAY;QACtB,SAAS,EAAE,0BAA0B;QACrC,QAAQ;QACR,SAAS,EAAE,CAAC,iEAAiE,CAAC;KAC/E,CAAC,CAAC;AACL,CAAC;AAED,gFAAgF;AAChF,8EAA8E;AAC9E,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,IAAmB,EACnB,IAAqB,EACrB,SAAiB,EACjB,GAAW,EACX,MAAoB;IAEpB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC;QACnC,IAAI;QACJ,MAAM,EAAE,uBAAuB;QAC/B,IAAI,EAAE,mBAAmB,CAAC,SAAS,CAAC;QACpC,GAAG;QACH,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC9B,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IACtC,IAAI,QAAQ,CAAC,MAAM,GAAG,EAAE;QAAE,MAAM,eAAe,CAAC,WAAW,SAAS,wBAAwB,EAAE,CAAC,WAAW,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IAC9H,OAAO,QAAQ,CAAC;AAClB,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { JsonSchema } from "../types.js";
2
+ export declare const EPISODE_TITLE_SCHEMA: JsonSchema;
3
+ export declare const SYNOPSIS_SCHEMA: JsonSchema;
4
+ export declare const SCRIPT_SYNOPSIS_SCHEMA: JsonSchema;
5
+ export declare const STATE_BINDING_SCHEMA: JsonSchema;
@@ -0,0 +1,107 @@
1
+ export const EPISODE_TITLE_SCHEMA = {
2
+ type: "object",
3
+ required: ["episode_titles"],
4
+ additionalProperties: false,
5
+ properties: {
6
+ episode_titles: {
7
+ type: "array",
8
+ items: {
9
+ type: "object",
10
+ required: ["episode", "title"],
11
+ additionalProperties: false,
12
+ properties: { episode: { type: "integer" }, title: { type: "string" } },
13
+ },
14
+ },
15
+ },
16
+ };
17
+ export const SYNOPSIS_SCHEMA = {
18
+ type: "object",
19
+ required: ["synopsis"],
20
+ additionalProperties: false,
21
+ properties: { synopsis: { type: "string" } },
22
+ };
23
+ export const SCRIPT_SYNOPSIS_SCHEMA = {
24
+ type: "object",
25
+ required: ["synopsis", "theme", "logline", "style", "main_characters"],
26
+ additionalProperties: false,
27
+ properties: {
28
+ synopsis: { type: "string" },
29
+ theme: { type: "string" },
30
+ logline: { type: "string" },
31
+ style: { type: "string" },
32
+ main_characters: {
33
+ type: "array",
34
+ items: {
35
+ type: "object",
36
+ required: ["name", "role"],
37
+ additionalProperties: false,
38
+ properties: { name: { type: "string" }, role: { type: "string" } },
39
+ },
40
+ },
41
+ },
42
+ };
43
+ const STATE_REF_SCHEMA = {
44
+ type: "array",
45
+ items: {
46
+ type: "object",
47
+ required: ["asset_id", "state_id"],
48
+ additionalProperties: false,
49
+ properties: { asset_id: { type: "string" }, state_id: { type: ["string", "null"] } },
50
+ },
51
+ };
52
+ export const STATE_BINDING_SCHEMA = {
53
+ type: "object",
54
+ required: ["scenes"],
55
+ additionalProperties: false,
56
+ properties: {
57
+ scenes: {
58
+ type: "array",
59
+ items: {
60
+ type: "object",
61
+ required: ["scene_id"],
62
+ additionalProperties: false,
63
+ properties: {
64
+ scene_id: { type: "string" },
65
+ actors: {
66
+ ...STATE_REF_SCHEMA,
67
+ items: {
68
+ type: "object", required: ["actor_id", "state_id"], additionalProperties: false,
69
+ properties: { actor_id: { type: "string" }, state_id: { type: ["string", "null"] } },
70
+ },
71
+ },
72
+ locations: {
73
+ ...STATE_REF_SCHEMA,
74
+ items: {
75
+ type: "object", required: ["location_id", "state_id"], additionalProperties: false,
76
+ properties: { location_id: { type: "string" }, state_id: { type: ["string", "null"] } },
77
+ },
78
+ },
79
+ props: {
80
+ ...STATE_REF_SCHEMA,
81
+ items: {
82
+ type: "object", required: ["prop_id", "state_id"], additionalProperties: false,
83
+ properties: { prop_id: { type: "string" }, state_id: { type: ["string", "null"] } },
84
+ },
85
+ },
86
+ state_changes: {
87
+ type: "array",
88
+ items: {
89
+ type: "object",
90
+ required: ["action_index", "target_kind", "target_id", "to_state_id"],
91
+ additionalProperties: false,
92
+ properties: {
93
+ action_index: { type: "integer" },
94
+ target_kind: { type: "string", enum: ["actor", "location", "prop"] },
95
+ target_id: { type: "string" },
96
+ from_state_id: { type: ["string", "null"] },
97
+ to_state_id: { type: "string" },
98
+ effective_from: { type: "string", enum: ["before_action", "after_action"] },
99
+ },
100
+ },
101
+ },
102
+ },
103
+ },
104
+ },
105
+ },
106
+ };
107
+ //# sourceMappingURL=schemas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../../src/llm/tasks/schemas.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,97 @@
1
+ export type LlmProtocol = "anthropic" | "openai-compatible" | "google-gemini";
2
+ export type LlmTaskId = "direct.episode-titles" | "direct.batch-extract" | "direct.episode-synopsis" | "direct.synopsis-reduction" | "direct.script-synopsis" | "direct.asset-grouping" | "direct.asset-curation" | "direct.asset-curation-audit" | "direct.location-canonicalization" | "direct.state-curation" | "direct.state-binding" | "metadata.global" | "metadata.descriptions" | "synopsis.chunk" | "synopsis.episode" | "synopsis.arc" | "synopsis.script-overview" | "ingest.text-normalize" | "ingest.mention-resolve" | "ingest.asset-extract" | "ingest.asset-curate" | "ingest.asset-recall" | "ingest.asset-refine" | "ingest.state-reconcile" | "ingest.speaker-audit" | "ingest.video-transcribe" | "ingest.video-correct" | "ingest.roster-recall" | "ingest.roster-refine" | "ingest.roster-canon" | "ingest.roster-remerge" | "ingest.state-merge";
3
+ export type LlmTaskMode = "text" | "tool" | "video";
4
+ export type JsonSchema = Record<string, unknown>;
5
+ export interface TextGenerationRequest {
6
+ system: string;
7
+ user: string;
8
+ maxOutputTokens: number;
9
+ signal?: AbortSignal;
10
+ }
11
+ export interface ToolDefinition {
12
+ name: string;
13
+ description: string;
14
+ inputSchema: JsonSchema;
15
+ }
16
+ export interface ToolGenerationRequest extends TextGenerationRequest {
17
+ tool: ToolDefinition;
18
+ }
19
+ export interface TextGenerationResponse {
20
+ text: string;
21
+ finishReason: string;
22
+ attempts: number;
23
+ raw?: unknown;
24
+ }
25
+ export interface ToolGenerationResponse {
26
+ input: unknown;
27
+ finishReason: string;
28
+ attempts: number;
29
+ raw?: unknown;
30
+ }
31
+ export interface LlmAdapter {
32
+ generateText(request: TextGenerationRequest): Promise<TextGenerationResponse>;
33
+ generateTool(request: ToolGenerationRequest): Promise<ToolGenerationResponse>;
34
+ }
35
+ export interface VideoFileHandle {
36
+ name: string;
37
+ uri: string;
38
+ mimeType: string;
39
+ }
40
+ export interface VideoGenerationRequest {
41
+ file: VideoFileHandle;
42
+ system?: string;
43
+ user: string;
44
+ fps: number;
45
+ maxOutputTokens: number;
46
+ responseJsonSchema?: JsonSchema;
47
+ signal?: AbortSignal;
48
+ }
49
+ export interface VideoGenerationResponse {
50
+ text: string;
51
+ finishReason: string;
52
+ attempts: number;
53
+ raw?: unknown;
54
+ }
55
+ export interface VideoUnderstandingPort {
56
+ upload(localPath: string, mimeType: string, signal?: AbortSignal): Promise<VideoFileHandle>;
57
+ generate(request: VideoGenerationRequest): Promise<VideoGenerationResponse>;
58
+ delete(handle: VideoFileHandle, signal?: AbortSignal): Promise<void>;
59
+ }
60
+ export interface TaskVideoPort {
61
+ upload(localPath: string, mimeType: string, signal?: AbortSignal): Promise<VideoFileHandle>;
62
+ generate(request: Omit<VideoGenerationRequest, "maxOutputTokens">): Promise<VideoGenerationResponse>;
63
+ delete(handle: VideoFileHandle, signal?: AbortSignal): Promise<void>;
64
+ }
65
+ export interface LlmRouteInfo {
66
+ task: LlmTaskId;
67
+ profile: string;
68
+ provider: string;
69
+ protocol: LlmProtocol;
70
+ model: string;
71
+ fingerprint: string;
72
+ }
73
+ export interface LlmRouteUsage extends LlmRouteInfo {
74
+ calls: number;
75
+ reused: number;
76
+ attempts: number;
77
+ }
78
+ export interface LlmTaskExecutor {
79
+ generateText(task: LlmTaskId, request: Omit<TextGenerationRequest, "maxOutputTokens">): Promise<TextGenerationResponse>;
80
+ generateTool(task: LlmTaskId, request: Omit<ToolGenerationRequest, "maxOutputTokens">): Promise<ToolGenerationResponse>;
81
+ videoPort(task: LlmTaskId): TaskVideoPort;
82
+ route(task: LlmTaskId): LlmRouteInfo;
83
+ routes(): LlmRouteInfo[];
84
+ recordReuse(task: LlmTaskId): void;
85
+ usage(): LlmRouteUsage[];
86
+ readonly configSource: "builtin" | "file";
87
+ }
88
+ export type LlmErrorCode = "auth" | "endpoint" | "timeout" | "rate_limited" | "request_failed" | "truncated" | "content_filtered" | "empty_response" | "invalid_response";
89
+ export declare class LlmTransportError extends Error {
90
+ readonly code: LlmErrorCode;
91
+ readonly retryable: boolean;
92
+ readonly details: string[];
93
+ constructor(code: LlmErrorCode, message: string, options?: {
94
+ retryable?: boolean;
95
+ details?: string[];
96
+ });
97
+ }
@@ -0,0 +1,13 @@
1
+ export class LlmTransportError extends Error {
2
+ code;
3
+ retryable;
4
+ details;
5
+ constructor(code, message, options = {}) {
6
+ super(message);
7
+ this.name = "LlmTransportError";
8
+ this.code = code;
9
+ this.retryable = options.retryable ?? false;
10
+ this.details = options.details ?? [];
11
+ }
12
+ }
13
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/llm/types.ts"],"names":[],"mappings":"AA0JA,MAAM,OAAO,iBAAkB,SAAQ,KAAK;IACjC,IAAI,CAAe;IACnB,SAAS,CAAU;IACnB,OAAO,CAAW;IAE3B,YAAY,IAAkB,EAAE,OAAe,EAAE,UAAuD,EAAE;QACxG,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,mBAAmB,CAAC;QAChC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,KAAK,CAAC;QAC5C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;IACvC,CAAC;CACF"}
@@ -1,2 +1,2 @@
1
1
  import { type Report } from "../common.js";
2
- export declare function commandDoctor(_opts?: Record<string, unknown>): [Report, number];
2
+ export declare function commandDoctor(opts?: Record<string, unknown>): [Report, number];