@oh-story/dsh 0.1.7 → 0.1.9

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 (272) hide show
  1. package/README.md +30 -15
  2. package/lib/client.js +93 -16
  3. package/lib/client.js.map +2 -2
  4. package/lib/drama/manifest.json +165 -69
  5. package/lib/drama/skills/short-drama/SKILL.md +5 -1
  6. package/lib/drama/skills/short-drama/scripts/creator_markdown_check.py +126 -9
  7. package/lib/drama/skills/short-drama/scripts/project_tool.py +11 -0
  8. package/lib/drama/skills/short-drama-assets/references/character-and-look.md +18 -0
  9. package/lib/drama/skills/short-drama-assets/references/continuity-lock.md +10 -1
  10. package/lib/drama/skills/short-drama-edit/SKILL.md +148 -0
  11. package/lib/drama/skills/short-drama-edit/agents/openai.yaml +4 -0
  12. package/lib/drama/skills/short-drama-edit/assets/remotion/README.md +60 -0
  13. package/lib/drama/skills/short-drama-edit/assets/remotion/package.json +15 -0
  14. package/lib/drama/skills/short-drama-edit/assets/remotion/remotion.config.ts +6 -0
  15. package/lib/drama/skills/short-drama-edit/assets/remotion/src/Root.tsx +26 -0
  16. package/lib/drama/skills/short-drama-edit/assets/remotion/src/Subtitles.tsx +88 -0
  17. package/lib/drama/skills/short-drama-edit/assets/remotion/src/font.ts +46 -0
  18. package/lib/drama/skills/short-drama-edit/assets/remotion/src/index.ts +4 -0
  19. package/lib/drama/skills/short-drama-edit/assets/remotion/src/schema.ts +32 -0
  20. package/lib/drama/skills/short-drama-edit/assets/remotion/tsconfig.json +13 -0
  21. package/lib/drama/skills/short-drama-edit/assets//345/211/252/350/276/221/345/215/225.md +43 -0
  22. package/lib/drama/skills/short-drama-edit/references/cut-craft.md +81 -0
  23. package/lib/drama/skills/short-drama-edit/references/delivery-verify.md +58 -0
  24. package/lib/drama/skills/short-drama-edit/references/generated-footage.md +96 -0
  25. package/lib/drama/skills/short-drama-edit/references/sound-and-subtitles.md +113 -0
  26. package/lib/drama/skills/short-drama-edit/references/stage-contract.md +55 -0
  27. package/lib/drama/skills/short-drama-edit/scripts/edit_tool.py +1041 -0
  28. package/lib/drama/skills/short-drama-edit/scripts/selftest.py +456 -0
  29. package/lib/drama/skills/short-drama-image-prompts/assets/image-prompts.md +5 -0
  30. package/lib/drama/skills/short-drama-image-prompts/assets/lookdev-prompts.md +3 -0
  31. package/lib/drama/skills/short-drama-novel-analyze/references/aggregation-and-entities.md +2 -2
  32. package/lib/drama/skills/short-drama-novel-analyze/references/chapter-extraction.md +4 -1
  33. package/lib/drama/skills/short-drama-produce/SKILL.md +24 -3
  34. package/lib/drama/skills/short-drama-produce/references/adapter-contract.md +28 -0
  35. package/lib/drama/skills/short-drama-produce/references/providers/minimax-h3-video.md +24 -5
  36. package/lib/drama/skills/short-drama-produce/references/providers/seedance.md +7 -0
  37. package/lib/drama/skills/short-drama-produce/scripts/fixture_adapter.py +18 -1
  38. package/lib/drama/skills/short-drama-produce/scripts/production_tool.py +181 -2
  39. package/lib/drama/skills/short-drama-produce/scripts/provider_adapters.py +57 -2
  40. package/lib/drama/skills/short-drama-review/SKILL.md +3 -0
  41. package/lib/drama/skills/short-drama-review/references/production-quality-gates.md +20 -0
  42. package/lib/drama/skills/short-drama-review/references/rubric-visual-motion.md +36 -0
  43. package/lib/drama/skills/short-drama-storyboard/SKILL.md +7 -0
  44. package/lib/drama/skills/short-drama-storyboard/assets/keyframe-prompts.md +4 -0
  45. package/lib/drama/skills/short-drama-storyboard/references/shot-craft.md +39 -0
  46. package/lib/drama/skills/short-drama-storyboard/references/stage-contract.md +2 -0
  47. package/lib/drama/skills/short-drama-video-prompts/SKILL.md +7 -1
  48. package/lib/drama/skills/short-drama-video-prompts/references/minimax-h3.md +101 -6
  49. package/lib/drama/skills/short-drama-video-prompts/references/motion-recipe.md +7 -1
  50. package/lib/drama/skills/short-drama-video-prompts/references/performance-action-timing.md +35 -0
  51. package/lib/drama/skills/short-drama-video-prompts/references/production-prompt-grammar.md +3 -1
  52. package/lib/drama/skills/short-drama-video-prompts/references/seedance-2.0.md +13 -3
  53. package/lib/drama/skills/short-drama-video-prompts/references/seedance-2.5.md +35 -4
  54. package/lib/drama/skills/short-drama-video-prompts/references/stage-contract.md +1 -1
  55. package/lib/drama/skills/short-drama-write/SKILL.md +13 -2
  56. package/lib/drama/skills/short-drama-write/references/screenplay-format.md +6 -0
  57. package/lib/drama/skills/short-drama-write/references/stage-contract.md +1 -0
  58. package/lib/index.js +4 -2
  59. package/lib/index.js.map +2 -2
  60. package/lib/novel-to-game/VERSION +1 -1
  61. package/lib/novel-to-game/manifest.json +28 -28
  62. package/lib/novel-to-game/skills/game-art-direction/SKILL.md +6 -27
  63. package/lib/novel-to-game/skills/game-build/SKILL.md +12 -29
  64. package/lib/novel-to-game/skills/game-concept/SKILL.md +10 -26
  65. package/lib/novel-to-game/skills/game-qa/SKILL.md +5 -15
  66. package/lib/novel-to-game/skills/game-qa/references/test-design-method.md +1 -1
  67. package/lib/novel-to-game/skills/game-world-design/SKILL.md +19 -28
  68. package/lib/novel-to-game/skills/game-world-design/references/dialogue-design-method.md +1 -2
  69. package/lib/novel-to-game/skills/novel-game-analyze/SKILL.md +6 -9
  70. package/lib/novel-to-game/skills/novel-to-game/SKILL.md +6 -11
  71. package/lib/novel-to-game/skills/novel-to-game/references/intake-benchmark-reference.md +0 -4
  72. package/lib/novel-to-game/skills/novel-to-game/references/intake-method.md +1 -3
  73. package/lib/novel-to-game/skills/novel-to-game/references/pipeline-contract.md +3 -5
  74. package/lib/oh-story/manifest.json +292 -172
  75. package/lib/oh-story/roles/character-designer.md +1 -1
  76. package/lib/oh-story/roles/narrative-writer.md +56 -242
  77. package/lib/oh-story/roles/story-architect.md +1 -1
  78. package/lib/oh-story/skills/story/SKILL.md +1 -1
  79. package/lib/oh-story/skills/story/VERSION +1 -1
  80. package/lib/oh-story/skills/story/references/author-memory.md +10 -8
  81. package/lib/oh-story/skills/story-deslop/SKILL.md +20 -182
  82. package/lib/oh-story/skills/story-deslop/references/anti-ai-writing.md +19 -47
  83. package/lib/oh-story/skills/story-deslop/references/author-memory.md +10 -8
  84. package/lib/oh-story/skills/story-deslop/references/banned-words.md +3 -1
  85. package/lib/oh-story/skills/story-deslop/references/deslop-gates.md +154 -0
  86. package/lib/oh-story/skills/story-deslop/references/style-resolution.md +27 -0
  87. package/lib/oh-story/skills/story-deslop/scripts/check-ai-patterns.js +6 -1
  88. package/lib/oh-story/skills/story-deslop/scripts/check-degeneration.js +39 -20
  89. package/lib/oh-story/skills/story-deslop/scripts/normalize-punctuation.js +10 -5
  90. package/lib/oh-story/skills/story-deslop/scripts/style-whitelist.js +39 -0
  91. package/lib/oh-story/skills/story-import/SKILL.md +2 -2
  92. package/lib/oh-story/skills/story-import/references/format-and-structure.md +2 -2
  93. package/lib/oh-story/skills/story-import/references/tracking-initialization.md +31 -0
  94. package/lib/oh-story/skills/story-import/references/tracking-transaction.md +2 -29
  95. package/lib/oh-story/skills/story-import/scripts/check-outline-contract.js +176 -12
  96. package/lib/oh-story/skills/story-long-analyze/SKILL.md +1 -1
  97. package/lib/oh-story/skills/story-long-write/SKILL.md +20 -193
  98. package/lib/oh-story/skills/story-long-write/references/anti-ai-writing.md +19 -47
  99. package/lib/oh-story/skills/story-long-write/references/artifact-protocols.md +62 -7
  100. package/lib/oh-story/skills/story-long-write/references/author-memory.md +10 -8
  101. package/lib/oh-story/skills/story-long-write/references/banned-words.md +3 -1
  102. package/lib/oh-story/skills/story-long-write/references/benchmark-recall.md +20 -0
  103. package/lib/oh-story/skills/story-long-write/references/dialogue-mastery.md +6 -4
  104. package/lib/oh-story/skills/story-long-write/references/long-chapter-quality.md +2 -2
  105. package/lib/oh-story/skills/story-long-write/references/long-format.md +2 -0
  106. package/lib/oh-story/skills/story-long-write/references/outline-structure-theory.md +2 -0
  107. package/lib/oh-story/skills/story-long-write/references/project-files.md +108 -0
  108. package/lib/oh-story/skills/story-long-write/references/reference-index.md +87 -0
  109. package/lib/oh-story/skills/story-long-write/references/style-combat-face.md +1 -1
  110. package/lib/oh-story/skills/story-long-write/references/style-craft.md +9 -29
  111. package/lib/oh-story/skills/story-long-write/references/style-genre-modules.md +1 -1
  112. package/lib/oh-story/skills/story-long-write/references/style-resolution.md +27 -0
  113. package/lib/oh-story/skills/story-long-write/references/tracking-initialization.md +31 -0
  114. package/lib/oh-story/skills/story-long-write/references/tracking-transaction.md +2 -29
  115. package/lib/oh-story/skills/story-long-write/references/workflow-chapter.md +51 -52
  116. package/lib/oh-story/skills/story-long-write/references/workflow-daily.md +8 -7
  117. package/lib/oh-story/skills/story-long-write/references/workflow-setup.md +36 -15
  118. package/lib/oh-story/skills/story-long-write/references/writer-prompt-fallback.md +22 -0
  119. package/lib/oh-story/skills/story-long-write/references/writing-craft.md +69 -2
  120. package/lib/oh-story/skills/story-long-write/scripts/build_writer_prompt.py +410 -0
  121. package/lib/oh-story/skills/story-long-write/scripts/check-ai-patterns.js +6 -1
  122. package/lib/oh-story/skills/story-long-write/scripts/check-degeneration.js +39 -20
  123. package/lib/oh-story/skills/story-long-write/scripts/check-outline-contract.js +176 -12
  124. package/lib/oh-story/skills/story-long-write/scripts/check-outline-copy.js +90 -23
  125. package/lib/oh-story/skills/story-long-write/scripts/normalize-punctuation.js +10 -5
  126. package/lib/oh-story/skills/story-long-write/scripts/outline_view.py +283 -0
  127. package/lib/oh-story/skills/story-long-write/scripts/style-whitelist.js +39 -0
  128. package/lib/oh-story/skills/story-review/SKILL.md +13 -3
  129. package/lib/oh-story/skills/story-review/references/anti-ai-writing.md +19 -47
  130. package/lib/oh-story/skills/story-review/references/author-memory.md +10 -8
  131. package/lib/oh-story/skills/story-review/references/banned-words.md +3 -1
  132. package/lib/oh-story/skills/story-review/references/dialogue-mastery.md +6 -4
  133. package/lib/oh-story/skills/story-review/references/review-quality.md +2 -2
  134. package/lib/oh-story/skills/story-review/references/style-resolution.md +27 -0
  135. package/lib/oh-story/skills/story-review/references/tracking-initialization.md +31 -0
  136. package/lib/oh-story/skills/story-review/references/tracking-transaction.md +2 -29
  137. package/lib/oh-story/skills/story-review/scripts/check-ai-patterns.js +6 -1
  138. package/lib/oh-story/skills/story-review/scripts/check-degeneration.js +39 -20
  139. package/lib/oh-story/skills/story-review/scripts/normalize-punctuation.js +10 -5
  140. package/lib/oh-story/skills/story-review/scripts/style-whitelist.js +39 -0
  141. package/lib/oh-story/skills/story-setup/SKILL.md +17 -10
  142. package/lib/oh-story/skills/story-setup/references/agent-references/anti-ai-writing.md +19 -47
  143. package/lib/oh-story/skills/story-setup/references/agent-references/banned-words.md +3 -1
  144. package/lib/oh-story/skills/story-setup/references/agent-references/deslop-gates.md +154 -0
  145. package/lib/oh-story/skills/story-setup/references/agent-references/dialogue-mastery.md +6 -4
  146. package/lib/oh-story/skills/story-setup/references/agent-references/format-and-structure.md +2 -2
  147. package/lib/oh-story/skills/story-setup/references/agent-references/short-genre-formulas.md +1 -1
  148. package/lib/oh-story/skills/story-setup/references/agent-references/style-combat-face.md +1 -1
  149. package/lib/oh-story/skills/story-setup/references/agent-references/style-genre-modules.md +1 -1
  150. package/lib/oh-story/skills/story-setup/references/agent-references/style-resolution.md +27 -0
  151. package/lib/oh-story/skills/story-setup/references/agent-references/writing-craft.md +69 -2
  152. package/lib/oh-story/skills/story-setup/references/diagnostics.md +38 -0
  153. package/lib/oh-story/skills/story-short-analyze/references/analysis-writing-techniques.md +1 -1
  154. package/lib/oh-story/skills/story-short-analyze/references/source-story-quality.md +2 -2
  155. package/lib/oh-story/skills/story-short-write/SKILL.md +18 -186
  156. package/lib/oh-story/skills/story-short-write/references/author-memory.md +10 -8
  157. package/lib/oh-story/skills/story-short-write/references/banned-words.md +3 -1
  158. package/lib/oh-story/skills/story-short-write/references/benchmark-recall.md +60 -0
  159. package/lib/oh-story/skills/story-short-write/references/dialogue-mastery.md +6 -4
  160. package/lib/oh-story/skills/story-short-write/references/genre-styles//344/270/226/346/203/205/346/211/223/350/204/270.md +2 -2
  161. package/lib/oh-story/skills/story-short-write/references/genre-styles//345/217/214/347/224/267/344/270/273.md +1 -1
  162. package/lib/oh-story/skills/story-short-write/references/genre-styles//345/244/215/344/273/207/346/211/223/350/204/270.md +3 -3
  163. package/lib/oh-story/skills/story-short-write/references/genre-styles//345/256/205/346/226/227/345/256/253/346/226/227.md +3 -3
  164. package/lib/oh-story/skills/story-short-write/references/genre-styles//346/200/273/350/243/201/350/261/252/351/227/250.md +3 -3
  165. package/lib/oh-story/skills/story-short-write/references/genre-styles//346/202/254/347/226/221.md +5 -5
  166. package/lib/oh-story/skills/story-short-write/references/genre-styles//346/260/221/344/277/227/346/200/252/350/260/210.md +4 -4
  167. package/lib/oh-story/skills/story-short-write/references/genre-styles//347/224/234/345/256/240.md +5 -5
  168. package/lib/oh-story/skills/story-short-write/references/genre-styles//350/277/275/345/246/273/347/201/253/350/221/254/345/234/272.md +3 -3
  169. package/lib/oh-story/skills/story-short-write/references/genre-writing-formulas.md +1 -1
  170. package/lib/oh-story/skills/story-short-write/references/genre-writing-techniques.md +1 -1
  171. package/lib/oh-story/skills/story-short-write/references/reference-index.md +53 -0
  172. package/lib/oh-story/skills/story-short-write/references/short-craft.md +12 -14
  173. package/lib/oh-story/skills/story-short-write/references/short-deslop.md +10 -10
  174. package/lib/oh-story/skills/story-short-write/references/short-format.md +3 -1
  175. package/lib/oh-story/skills/story-short-write/references/short-prose-quality.md +2 -2
  176. package/lib/oh-story/skills/story-short-write/references/style-resolution.md +27 -0
  177. package/lib/oh-story/skills/story-short-write/references/workflow-design.md +77 -0
  178. package/lib/oh-story/skills/story-short-write/references/writing-workflow.md +5 -5
  179. package/lib/oh-story/skills/story-short-write/scripts/check-ai-patterns.js +6 -1
  180. package/lib/oh-story/skills/story-short-write/scripts/check-degeneration.js +39 -20
  181. package/lib/oh-story/skills/story-short-write/scripts/check-delivery-contract.js +34 -5
  182. package/lib/oh-story/skills/story-short-write/scripts/check-outline-copy.js +90 -23
  183. package/lib/oh-story/skills/story-short-write/scripts/normalize-punctuation.js +10 -5
  184. package/lib/oh-story/skills/story-short-write/scripts/style-whitelist.js +39 -0
  185. package/lib/types/client/drama-production-view.d.ts.map +1 -1
  186. package/lib/types/client/index.d.ts.map +1 -1
  187. package/lib/types/client/production-prompts.d.ts.map +1 -1
  188. package/lib/types/client/production-runtime.d.ts +17 -0
  189. package/lib/types/client/production-runtime.d.ts.map +1 -1
  190. package/lib/types/skill-provider.d.ts.map +1 -1
  191. package/lib/video-recap/CHANGELOG.md +31 -1
  192. package/lib/video-recap/manifest.json +162 -162
  193. package/lib/video-recap/skills/video-assemble/scripts/artifacts.py +4 -9
  194. package/lib/video-recap/skills/video-assemble/scripts/assemble.py +47 -60
  195. package/lib/video-recap/skills/video-assemble/scripts/assembly_contract.py +77 -115
  196. package/lib/video-recap/skills/video-assemble/scripts/assembly_settings.py +41 -40
  197. package/lib/video-recap/skills/video-assemble/scripts/audio_automation.py +22 -32
  198. package/lib/video-recap/skills/video-assemble/scripts/audio_mix.py +102 -192
  199. package/lib/video-recap/skills/video-assemble/scripts/jianying_builders.py +14 -35
  200. package/lib/video-recap/skills/video-assemble/scripts/jianying_model.py +14 -12
  201. package/lib/video-recap/skills/video-assemble/scripts/jianying_optional.py +8 -9
  202. package/lib/video-recap/skills/video-assemble/scripts/jianying_schema.py +3 -14
  203. package/lib/video-recap/skills/video-assemble/scripts/jianying_timeline_contract.py +23 -12
  204. package/lib/video-recap/skills/video-assemble/scripts/jianying_tracks.py +1 -4
  205. package/lib/video-recap/skills/video-assemble/scripts/jianying_writer.py +24 -25
  206. package/lib/video-recap/skills/video-assemble/scripts/lib.py +31 -85
  207. package/lib/video-recap/skills/video-assemble/scripts/media.py +100 -144
  208. package/lib/video-recap/skills/video-assemble/scripts/narration_audio.py +101 -195
  209. package/lib/video-recap/skills/video-assemble/scripts/render_preflight.py +10 -21
  210. package/lib/video-recap/skills/video-assemble/scripts/source_subtitles.py +90 -169
  211. package/lib/video-recap/skills/video-assemble/scripts/subtitle_core.py +69 -122
  212. package/lib/video-recap/skills/video-assemble/scripts/subtitle_render.py +10 -17
  213. package/lib/video-recap/skills/video-assemble/scripts/timeline.py +33 -48
  214. package/lib/video-recap/skills/video-assemble/scripts/timeline_emit.py +14 -20
  215. package/lib/video-recap/skills/video-assemble/scripts/visual_render.py +135 -213
  216. package/lib/video-recap/skills/video-cut/scripts/cut_cli.py +49 -57
  217. package/lib/video-recap/skills/video-cut/scripts/cut_contract.py +38 -74
  218. package/lib/video-recap/skills/video-cut/scripts/cut_render.py +46 -95
  219. package/lib/video-recap/skills/video-cut/scripts/lib.py +23 -25
  220. package/lib/video-recap/skills/video-cut/scripts/media_geometry.py +70 -173
  221. package/lib/video-recap/skills/video-cut/scripts/narration_mapping.py +28 -53
  222. package/lib/video-recap/skills/video-cut/scripts/sentence_boundaries.py +162 -322
  223. package/lib/video-recap/skills/video-recap/references/timeline-and-jianying.md +6 -7
  224. package/lib/video-recap/skills/video-recap/scripts/doctor.py +104 -124
  225. package/lib/video-recap/skills/video-recap/scripts/final_qc.py +255 -412
  226. package/lib/video-recap/skills/video-recap/scripts/lib.py +30 -52
  227. package/lib/video-recap/skills/video-recap/scripts/materials.py +97 -120
  228. package/lib/video-recap/skills/video-recap/scripts/mimo_qc_client.py +7 -12
  229. package/lib/video-recap/skills/video-recap/scripts/mimo_qc_evidence.py +46 -97
  230. package/lib/video-recap/skills/video-recap/scripts/mimo_qc_observations.py +18 -36
  231. package/lib/video-recap/skills/video-recap/scripts/mimo_qc_payload.py +29 -47
  232. package/lib/video-recap/skills/video-recap/scripts/mimo_qc_report.py +43 -76
  233. package/lib/video-recap/skills/video-recap/scripts/mimo_qc_runner.py +2 -1
  234. package/lib/video-recap/skills/video-recap/scripts/qc_contract.py +2 -1
  235. package/lib/video-recap/skills/video-recap/scripts/recap_cli.py +2 -2
  236. package/lib/video-recap/skills/video-recap/scripts/recap_inspect.py +129 -145
  237. package/lib/video-recap/skills/video-recap/scripts/recap_review.py +27 -20
  238. package/lib/video-recap/skills/video-recap/scripts/recap_runner.py +20 -31
  239. package/lib/video-recap/skills/video-recap/scripts/recap_runtime.py +31 -106
  240. package/lib/video-recap/skills/video-recap/scripts/recap_stage_qc.py +43 -113
  241. package/lib/video-recap/skills/video-recap/scripts/recap_timeline.py +196 -377
  242. package/lib/video-recap/skills/video-script/scripts/agent_brief.py +1 -1
  243. package/lib/video-recap/skills/video-script/scripts/agent_text.py +63 -172
  244. package/lib/video-recap/skills/video-script/scripts/brief_context.py +80 -135
  245. package/lib/video-recap/skills/video-script/scripts/brief_inputs.py +125 -167
  246. package/lib/video-recap/skills/video-script/scripts/brief_timeline.py +93 -208
  247. package/lib/video-recap/skills/video-script/scripts/deslop_qc.py +20 -46
  248. package/lib/video-recap/skills/video-script/scripts/lib.py +30 -26
  249. package/lib/video-recap/skills/video-script/scripts/narration_lint.py +145 -140
  250. package/lib/video-recap/skills/video-script/scripts/review_response.py +12 -42
  251. package/lib/video-recap/skills/video-script/scripts/review_runner.py +0 -6
  252. package/lib/video-recap/skills/video-script/scripts/speech_ownership.py +39 -100
  253. package/lib/video-recap/skills/video-script/scripts/timeline_fusion.py +33 -124
  254. package/lib/video-recap/skills/video-understanding/scripts/agent_brief.py +1 -1
  255. package/lib/video-recap/skills/video-understanding/scripts/agent_text.py +63 -172
  256. package/lib/video-recap/skills/video-understanding/scripts/asr.py +1 -2
  257. package/lib/video-recap/skills/video-understanding/scripts/brief_context.py +80 -135
  258. package/lib/video-recap/skills/video-understanding/scripts/brief_inputs.py +125 -167
  259. package/lib/video-recap/skills/video-understanding/scripts/brief_timeline.py +93 -208
  260. package/lib/video-recap/skills/video-understanding/scripts/consolidate.py +1 -1
  261. package/lib/video-recap/skills/video-understanding/scripts/deslop_qc.py +20 -46
  262. package/lib/video-recap/skills/video-understanding/scripts/lib.py +31 -26
  263. package/lib/video-recap/skills/video-understanding/scripts/narration_lint.py +145 -140
  264. package/lib/video-recap/skills/video-understanding/scripts/speech_ownership.py +39 -100
  265. package/lib/video-recap/skills/video-understanding/scripts/timeline_fusion.py +33 -124
  266. package/lib/video-recap/skills/video-understanding/scripts/vlm.py +1 -4
  267. package/lib/video-recap/skills/video-voiceover/scripts/dub.py +7 -13
  268. package/lib/video-recap/skills/video-voiceover/scripts/fish_audio.py +12 -30
  269. package/lib/video-recap/skills/video-voiceover/scripts/lib.py +98 -131
  270. package/lib/video-recap/skills/video-voiceover/scripts/tts_audio.py +17 -28
  271. package/lib/video-recap/skills/video-voiceover/scripts/voiceover.py +151 -240
  272. package/package.json +41 -41
@@ -2,40 +2,29 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
-
6
5
  import base64
7
-
8
6
  import hashlib
9
-
10
7
  import json
11
-
12
8
  import math
13
-
14
9
  import os
15
-
16
-
17
10
  import subprocess
18
-
19
11
  import tempfile
20
-
21
12
  from pathlib import Path
22
-
23
- from typing import Any, Callable, Mapping, Sequence
13
+ from typing import Any
14
+ from collections.abc import Callable, Mapping, Sequence
24
15
 
25
16
  import qc_contract
26
-
17
+ from mimo_qc_client import mimo_qc_api_call
27
18
  from mimo_qc_evidence import (
28
19
  _cache_evidence,
29
20
  _effective_config,
30
21
  _existing_final_output,
31
22
  _fingerprint_value,
32
- _redact,
33
23
  collect_evidence,
34
24
  safe_mimo_config,
35
25
  )
36
26
  from mimo_qc_observations import normalize_observations
37
27
  from mimo_qc_payload import _request_payload, _validated_live_output, build_payload
38
- from mimo_qc_client import mimo_qc_api_call
39
28
  from mimo_qc_contract import (
40
29
  ARTIFACT_NAME,
41
30
  DEFAULT_STAGE,
@@ -52,6 +41,7 @@ FrameSampler = Callable[..., Sequence[Mapping[str, Any]]]
52
41
 
53
42
 
54
43
  def _probe_duration(path: Path) -> float:
44
+ """Media duration via ffprobe; 0.0 when ffprobe cannot read it (frame sampling is advisory)."""
55
45
  result = subprocess.run(
56
46
  [
57
47
  "ffprobe",
@@ -72,7 +62,7 @@ def _probe_duration(path: Path) -> float:
72
62
  return 0.0
73
63
  try:
74
64
  return max(0.0, float(json.loads(result.stdout)["format"]["duration"]))
75
- except (KeyError, TypeError, ValueError, json.JSONDecodeError):
65
+ except (KeyError, ValueError):
76
66
  return 0.0
77
67
 
78
68
 
@@ -92,7 +82,7 @@ def sample_video_frames(
92
82
  return []
93
83
  if duration <= 0:
94
84
  return []
95
- count = min(int(max_frames), max(1, int(math.ceil(duration / 15.0))))
85
+ count = min(max_frames, max(1, math.ceil(duration / 15.0)))
96
86
  samples = []
97
87
  with tempfile.TemporaryDirectory(prefix="video-recap-mimo-qc-") as tmp:
98
88
  for index in range(count):
@@ -113,10 +103,7 @@ def sample_video_frames(
113
103
  "-frames:v",
114
104
  "1",
115
105
  "-vf",
116
- (
117
- f"scale={int(max_dimension)}:{int(max_dimension)}:"
118
- "force_original_aspect_ratio=decrease"
119
- ),
106
+ f"scale={max_dimension}:{max_dimension}:force_original_aspect_ratio=decrease",
120
107
  "-q:v",
121
108
  "4",
122
109
  str(destination),
@@ -138,21 +125,18 @@ def sample_video_frames(
138
125
  "timestamp": round(timestamp, 3),
139
126
  }
140
127
  )
141
- return samples[:MAX_FRAMES]
128
+ return samples
142
129
 
143
130
 
144
131
  def _frame_metadata(samples: Sequence[Mapping[str, Any]]) -> dict[str, Any]:
145
132
  return {
146
- "count": min(len(samples), MAX_FRAMES),
133
+ "count": len(samples),
147
134
  "max_frames": MAX_FRAMES,
148
135
  "max_dimension": MAX_FRAME_DIMENSION,
149
136
  "sampler_version": FRAME_SAMPLER_VERSION,
150
137
  "samples": [
151
- {
152
- "sha256": sample.get("sha256"),
153
- "timestamp": sample.get("timestamp"),
154
- }
155
- for sample in list(samples)[:MAX_FRAMES]
138
+ {"sha256": sample["sha256"], "timestamp": sample["timestamp"]}
139
+ for sample in samples
156
140
  ],
157
141
  }
158
142
 
@@ -165,8 +149,8 @@ def _cache_input(
165
149
  ) -> dict[str, Any]:
166
150
  return {
167
151
  "stage": stage,
168
- "model": payload.get("model"),
169
- "payload_fingerprint": payload.get("payload_fingerprint"),
152
+ "model": payload["model"],
153
+ "payload_fingerprint": payload["payload_fingerprint"],
170
154
  "evidence": _cache_evidence(evidence),
171
155
  "frames": frames,
172
156
  "contract": qc_contract.SCHEMA_VERSION,
@@ -174,29 +158,27 @@ def _cache_input(
174
158
 
175
159
 
176
160
  def _stage_reports(path: Path) -> dict[str, dict[str, Any]]:
161
+ """Per-stage reports from an existing aggregate mimo_qc.json, or {} before the first stage."""
177
162
  if not path.is_file():
178
163
  return {}
179
164
  try:
180
- report = json.loads(path.read_text(encoding="utf-8"))
181
- qc_contract.validate_report(report)
182
- except (OSError, ValueError, TypeError, qc_contract.QCContractError):
165
+ stages = json.loads(path.read_text(encoding="utf-8"))["metadata"]["stages"]
166
+ for report in stages.values():
167
+ qc_contract.validate_report(report)
168
+ return dict(stages)
169
+ except (
170
+ OSError,
171
+ ValueError,
172
+ TypeError,
173
+ KeyError,
174
+ AttributeError,
175
+ qc_contract.QCContractError,
176
+ ):
183
177
  return {}
184
- stages = report.get("metadata", {}).get("stages")
185
- if isinstance(stages, Mapping):
186
- valid = {}
187
- for stage, stage_report in stages.items():
188
- try:
189
- qc_contract.validate_report(stage_report)
190
- except (TypeError, qc_contract.QCContractError):
191
- continue
192
- valid[str(stage)] = dict(stage_report)
193
- return valid
194
- return {str(report["stage"]): report}
195
178
 
196
179
 
197
180
  def _error_name(exc: Exception) -> str:
198
- text = str(_redact(str(exc))).strip()
199
- return (text or type(exc).__name__)[:120]
181
+ return (str(exc).strip() or type(exc).__name__)[:120]
200
182
 
201
183
 
202
184
  def build_report(
@@ -224,28 +206,20 @@ def build_report(
224
206
  output = _existing_final_output(root, final_output)
225
207
  if output is not None:
226
208
  sampler = frame_sampler or sample_video_frames
227
- try:
228
- samples = list(
229
- sampler(
230
- output, max_frames=MAX_FRAMES, max_dimension=MAX_FRAME_DIMENSION
231
- )
232
- )[:MAX_FRAMES]
233
- except Exception:
234
- samples = []
209
+ samples = list(
210
+ sampler(output, max_frames=MAX_FRAMES, max_dimension=MAX_FRAME_DIMENSION)
211
+ )[:MAX_FRAMES]
235
212
  frame_meta = _frame_metadata(samples)
236
213
  cache_input = _cache_input(stage, payload, evidence, frame_meta)
237
214
  cache_key = _fingerprint_value(cache_input)
238
215
 
239
216
  if (
240
217
  not refresh
241
- and existing
218
+ and existing is not None
242
219
  and existing.get("metadata", {}).get("cache_key") == cache_key
243
220
  ):
244
221
  cached = json.loads(json.dumps(existing))
245
- cached["metadata"]["status"] = "cached"
246
- cached["metadata"]["mode"] = "live_cache"
247
- cached["metadata"]["request_count"] = 0
248
- qc_contract.validate_report(cached)
222
+ cached["metadata"].update(status="cached", mode="live_cache", request_count=0)
249
223
  return cached
250
224
 
251
225
  status = "completed"
@@ -266,6 +240,8 @@ def build_report(
266
240
  model_output = {"observations": []}
267
241
  status, error = "unavailable", "missing_key"
268
242
  else:
243
+ # Fail-open boundary for the third-party request: transport errors arrive as
244
+ # MiMoQCRequestError (a RuntimeError), malformed responses as ValueError.
269
245
  try:
270
246
  response = (api_call or mimo_qc_api_call)(
271
247
  _request_payload(payload, samples),
@@ -273,7 +249,7 @@ def build_report(
273
249
  timeout=60,
274
250
  )
275
251
  model_output = _validated_live_output(response)
276
- except Exception as exc:
252
+ except (RuntimeError, ValueError) as exc:
277
253
  model_output = {"observations": []}
278
254
  status, error = "failed", _error_name(exc)
279
255
  else:
@@ -302,26 +278,23 @@ def build_report(
302
278
  "payload": payload,
303
279
  "config": cfg,
304
280
  }
305
- report = qc_contract.build_report(
281
+ return qc_contract.build_report(
306
282
  artifact=ARTIFACT_NAME,
307
283
  stage=stage,
308
284
  findings=findings,
309
285
  metadata=metadata,
310
286
  )
311
- qc_contract.validate_report(report)
312
- return _redact(report)
313
287
 
314
288
 
315
289
  def _aggregate_reports(
316
290
  stage_reports: Mapping[str, Mapping[str, Any]], current_stage: str
317
291
  ) -> dict[str, Any]:
318
- current = stage_reports[current_stage]
319
292
  findings = [
320
293
  finding
321
294
  for stage_report in stage_reports.values()
322
- for finding in stage_report.get("findings", [])
295
+ for finding in stage_report["findings"]
323
296
  ]
324
- metadata = dict(current.get("metadata", {}))
297
+ metadata = dict(stage_reports[current_stage]["metadata"])
325
298
  metadata["stages"] = {
326
299
  stage: dict(report) for stage, report in stage_reports.items()
327
300
  }
@@ -339,13 +312,10 @@ def write_report(
339
312
  """Atomically merge one stage into mimo_qc.json and return the aggregate."""
340
313
  path = Path(output) if output else Path(work_dir) / ARTIFACT_NAME
341
314
  path.parent.mkdir(parents=True, exist_ok=True)
342
- safe_stage = _redact(dict(report))
343
- qc_contract.validate_report(safe_stage)
344
315
  stages = _stage_reports(path)
345
- stages[safe_stage["stage"]] = safe_stage
346
- aggregate = _aggregate_reports(stages, safe_stage["stage"])
347
- qc_contract.validate_report(aggregate)
348
- serialized = json.dumps(_redact(aggregate), ensure_ascii=False, indent=2) + "\n"
316
+ stages[report["stage"]] = dict(report)
317
+ aggregate = _aggregate_reports(stages, report["stage"])
318
+ serialized = json.dumps(aggregate, ensure_ascii=False, indent=2) + "\n"
349
319
  descriptor, temp_name = tempfile.mkstemp(prefix=f".{path.name}.", dir=path.parent)
350
320
  try:
351
321
  with os.fdopen(descriptor, "w", encoding="utf-8") as handle:
@@ -353,10 +323,7 @@ def write_report(
353
323
  handle.flush()
354
324
  os.fsync(handle.fileno())
355
325
  os.replace(temp_name, path)
356
- except Exception:
357
- try:
358
- os.unlink(temp_name)
359
- except OSError:
360
- pass
326
+ except BaseException:
327
+ Path(temp_name).unlink(missing_ok=True)
361
328
  raise
362
329
  return path, aggregate
@@ -10,7 +10,8 @@ import json
10
10
 
11
11
  from pathlib import Path
12
12
 
13
- from typing import Any, Callable, Mapping, Sequence
13
+ from typing import Any
14
+ from collections.abc import Callable, Mapping, Sequence
14
15
 
15
16
  import qc_contract
16
17
 
@@ -9,7 +9,8 @@ from __future__ import annotations
9
9
  import hashlib
10
10
  import re
11
11
  from pathlib import Path
12
- from typing import Any, Mapping, Sequence
12
+ from typing import Any
13
+ from collections.abc import Mapping, Sequence
13
14
  from urllib.parse import urlsplit, urlunsplit
14
15
 
15
16
 
@@ -3,7 +3,7 @@
3
3
  import argparse
4
4
  import os
5
5
 
6
- from recap_runtime import _env_bool
6
+ from lib import env_bool
7
7
 
8
8
  TTS_PROVIDERS = ("auto", "mimo-tts", "fish-audio")
9
9
 
@@ -46,7 +46,7 @@ def parse_args():
46
46
  parser.add_argument(
47
47
  "--mimo-qc-refresh",
48
48
  action="store_true",
49
- default=_env_bool("MIMO_QC_REFRESH", False),
49
+ default=env_bool("MIMO_QC_REFRESH", False),
50
50
  help="ignore a matching MiMo QC stage cache",
51
51
  )
52
52
  parser.add_argument(