@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.
- package/README.md +30 -15
- package/lib/client.js +93 -16
- package/lib/client.js.map +2 -2
- package/lib/drama/manifest.json +165 -69
- package/lib/drama/skills/short-drama/SKILL.md +5 -1
- package/lib/drama/skills/short-drama/scripts/creator_markdown_check.py +126 -9
- package/lib/drama/skills/short-drama/scripts/project_tool.py +11 -0
- package/lib/drama/skills/short-drama-assets/references/character-and-look.md +18 -0
- package/lib/drama/skills/short-drama-assets/references/continuity-lock.md +10 -1
- package/lib/drama/skills/short-drama-edit/SKILL.md +148 -0
- package/lib/drama/skills/short-drama-edit/agents/openai.yaml +4 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/README.md +60 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/package.json +15 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/remotion.config.ts +6 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/Root.tsx +26 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/Subtitles.tsx +88 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/font.ts +46 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/index.ts +4 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/src/schema.ts +32 -0
- package/lib/drama/skills/short-drama-edit/assets/remotion/tsconfig.json +13 -0
- package/lib/drama/skills/short-drama-edit/assets//345/211/252/350/276/221/345/215/225.md +43 -0
- package/lib/drama/skills/short-drama-edit/references/cut-craft.md +81 -0
- package/lib/drama/skills/short-drama-edit/references/delivery-verify.md +58 -0
- package/lib/drama/skills/short-drama-edit/references/generated-footage.md +96 -0
- package/lib/drama/skills/short-drama-edit/references/sound-and-subtitles.md +113 -0
- package/lib/drama/skills/short-drama-edit/references/stage-contract.md +55 -0
- package/lib/drama/skills/short-drama-edit/scripts/edit_tool.py +1041 -0
- package/lib/drama/skills/short-drama-edit/scripts/selftest.py +456 -0
- package/lib/drama/skills/short-drama-image-prompts/assets/image-prompts.md +5 -0
- package/lib/drama/skills/short-drama-image-prompts/assets/lookdev-prompts.md +3 -0
- package/lib/drama/skills/short-drama-novel-analyze/references/aggregation-and-entities.md +2 -2
- package/lib/drama/skills/short-drama-novel-analyze/references/chapter-extraction.md +4 -1
- package/lib/drama/skills/short-drama-produce/SKILL.md +24 -3
- package/lib/drama/skills/short-drama-produce/references/adapter-contract.md +28 -0
- package/lib/drama/skills/short-drama-produce/references/providers/minimax-h3-video.md +24 -5
- package/lib/drama/skills/short-drama-produce/references/providers/seedance.md +7 -0
- package/lib/drama/skills/short-drama-produce/scripts/fixture_adapter.py +18 -1
- package/lib/drama/skills/short-drama-produce/scripts/production_tool.py +181 -2
- package/lib/drama/skills/short-drama-produce/scripts/provider_adapters.py +57 -2
- package/lib/drama/skills/short-drama-review/SKILL.md +3 -0
- package/lib/drama/skills/short-drama-review/references/production-quality-gates.md +20 -0
- package/lib/drama/skills/short-drama-review/references/rubric-visual-motion.md +36 -0
- package/lib/drama/skills/short-drama-storyboard/SKILL.md +7 -0
- package/lib/drama/skills/short-drama-storyboard/assets/keyframe-prompts.md +4 -0
- package/lib/drama/skills/short-drama-storyboard/references/shot-craft.md +39 -0
- package/lib/drama/skills/short-drama-storyboard/references/stage-contract.md +2 -0
- package/lib/drama/skills/short-drama-video-prompts/SKILL.md +7 -1
- package/lib/drama/skills/short-drama-video-prompts/references/minimax-h3.md +101 -6
- package/lib/drama/skills/short-drama-video-prompts/references/motion-recipe.md +7 -1
- package/lib/drama/skills/short-drama-video-prompts/references/performance-action-timing.md +35 -0
- package/lib/drama/skills/short-drama-video-prompts/references/production-prompt-grammar.md +3 -1
- package/lib/drama/skills/short-drama-video-prompts/references/seedance-2.0.md +13 -3
- package/lib/drama/skills/short-drama-video-prompts/references/seedance-2.5.md +35 -4
- package/lib/drama/skills/short-drama-video-prompts/references/stage-contract.md +1 -1
- package/lib/drama/skills/short-drama-write/SKILL.md +13 -2
- package/lib/drama/skills/short-drama-write/references/screenplay-format.md +6 -0
- package/lib/drama/skills/short-drama-write/references/stage-contract.md +1 -0
- package/lib/index.js +4 -2
- package/lib/index.js.map +2 -2
- package/lib/novel-to-game/VERSION +1 -1
- package/lib/novel-to-game/manifest.json +28 -28
- package/lib/novel-to-game/skills/game-art-direction/SKILL.md +6 -27
- package/lib/novel-to-game/skills/game-build/SKILL.md +12 -29
- package/lib/novel-to-game/skills/game-concept/SKILL.md +10 -26
- package/lib/novel-to-game/skills/game-qa/SKILL.md +5 -15
- package/lib/novel-to-game/skills/game-qa/references/test-design-method.md +1 -1
- package/lib/novel-to-game/skills/game-world-design/SKILL.md +19 -28
- package/lib/novel-to-game/skills/game-world-design/references/dialogue-design-method.md +1 -2
- package/lib/novel-to-game/skills/novel-game-analyze/SKILL.md +6 -9
- package/lib/novel-to-game/skills/novel-to-game/SKILL.md +6 -11
- package/lib/novel-to-game/skills/novel-to-game/references/intake-benchmark-reference.md +0 -4
- package/lib/novel-to-game/skills/novel-to-game/references/intake-method.md +1 -3
- package/lib/novel-to-game/skills/novel-to-game/references/pipeline-contract.md +3 -5
- package/lib/oh-story/manifest.json +292 -172
- package/lib/oh-story/roles/character-designer.md +1 -1
- package/lib/oh-story/roles/narrative-writer.md +56 -242
- package/lib/oh-story/roles/story-architect.md +1 -1
- package/lib/oh-story/skills/story/SKILL.md +1 -1
- package/lib/oh-story/skills/story/VERSION +1 -1
- package/lib/oh-story/skills/story/references/author-memory.md +10 -8
- package/lib/oh-story/skills/story-deslop/SKILL.md +20 -182
- package/lib/oh-story/skills/story-deslop/references/anti-ai-writing.md +19 -47
- package/lib/oh-story/skills/story-deslop/references/author-memory.md +10 -8
- package/lib/oh-story/skills/story-deslop/references/banned-words.md +3 -1
- package/lib/oh-story/skills/story-deslop/references/deslop-gates.md +154 -0
- package/lib/oh-story/skills/story-deslop/references/style-resolution.md +27 -0
- package/lib/oh-story/skills/story-deslop/scripts/check-ai-patterns.js +6 -1
- package/lib/oh-story/skills/story-deslop/scripts/check-degeneration.js +39 -20
- package/lib/oh-story/skills/story-deslop/scripts/normalize-punctuation.js +10 -5
- package/lib/oh-story/skills/story-deslop/scripts/style-whitelist.js +39 -0
- package/lib/oh-story/skills/story-import/SKILL.md +2 -2
- package/lib/oh-story/skills/story-import/references/format-and-structure.md +2 -2
- package/lib/oh-story/skills/story-import/references/tracking-initialization.md +31 -0
- package/lib/oh-story/skills/story-import/references/tracking-transaction.md +2 -29
- package/lib/oh-story/skills/story-import/scripts/check-outline-contract.js +176 -12
- package/lib/oh-story/skills/story-long-analyze/SKILL.md +1 -1
- package/lib/oh-story/skills/story-long-write/SKILL.md +20 -193
- package/lib/oh-story/skills/story-long-write/references/anti-ai-writing.md +19 -47
- package/lib/oh-story/skills/story-long-write/references/artifact-protocols.md +62 -7
- package/lib/oh-story/skills/story-long-write/references/author-memory.md +10 -8
- package/lib/oh-story/skills/story-long-write/references/banned-words.md +3 -1
- package/lib/oh-story/skills/story-long-write/references/benchmark-recall.md +20 -0
- package/lib/oh-story/skills/story-long-write/references/dialogue-mastery.md +6 -4
- package/lib/oh-story/skills/story-long-write/references/long-chapter-quality.md +2 -2
- package/lib/oh-story/skills/story-long-write/references/long-format.md +2 -0
- package/lib/oh-story/skills/story-long-write/references/outline-structure-theory.md +2 -0
- package/lib/oh-story/skills/story-long-write/references/project-files.md +108 -0
- package/lib/oh-story/skills/story-long-write/references/reference-index.md +87 -0
- package/lib/oh-story/skills/story-long-write/references/style-combat-face.md +1 -1
- package/lib/oh-story/skills/story-long-write/references/style-craft.md +9 -29
- package/lib/oh-story/skills/story-long-write/references/style-genre-modules.md +1 -1
- package/lib/oh-story/skills/story-long-write/references/style-resolution.md +27 -0
- package/lib/oh-story/skills/story-long-write/references/tracking-initialization.md +31 -0
- package/lib/oh-story/skills/story-long-write/references/tracking-transaction.md +2 -29
- package/lib/oh-story/skills/story-long-write/references/workflow-chapter.md +51 -52
- package/lib/oh-story/skills/story-long-write/references/workflow-daily.md +8 -7
- package/lib/oh-story/skills/story-long-write/references/workflow-setup.md +36 -15
- package/lib/oh-story/skills/story-long-write/references/writer-prompt-fallback.md +22 -0
- package/lib/oh-story/skills/story-long-write/references/writing-craft.md +69 -2
- package/lib/oh-story/skills/story-long-write/scripts/build_writer_prompt.py +410 -0
- package/lib/oh-story/skills/story-long-write/scripts/check-ai-patterns.js +6 -1
- package/lib/oh-story/skills/story-long-write/scripts/check-degeneration.js +39 -20
- package/lib/oh-story/skills/story-long-write/scripts/check-outline-contract.js +176 -12
- package/lib/oh-story/skills/story-long-write/scripts/check-outline-copy.js +90 -23
- package/lib/oh-story/skills/story-long-write/scripts/normalize-punctuation.js +10 -5
- package/lib/oh-story/skills/story-long-write/scripts/outline_view.py +283 -0
- package/lib/oh-story/skills/story-long-write/scripts/style-whitelist.js +39 -0
- package/lib/oh-story/skills/story-review/SKILL.md +13 -3
- package/lib/oh-story/skills/story-review/references/anti-ai-writing.md +19 -47
- package/lib/oh-story/skills/story-review/references/author-memory.md +10 -8
- package/lib/oh-story/skills/story-review/references/banned-words.md +3 -1
- package/lib/oh-story/skills/story-review/references/dialogue-mastery.md +6 -4
- package/lib/oh-story/skills/story-review/references/review-quality.md +2 -2
- package/lib/oh-story/skills/story-review/references/style-resolution.md +27 -0
- package/lib/oh-story/skills/story-review/references/tracking-initialization.md +31 -0
- package/lib/oh-story/skills/story-review/references/tracking-transaction.md +2 -29
- package/lib/oh-story/skills/story-review/scripts/check-ai-patterns.js +6 -1
- package/lib/oh-story/skills/story-review/scripts/check-degeneration.js +39 -20
- package/lib/oh-story/skills/story-review/scripts/normalize-punctuation.js +10 -5
- package/lib/oh-story/skills/story-review/scripts/style-whitelist.js +39 -0
- package/lib/oh-story/skills/story-setup/SKILL.md +17 -10
- package/lib/oh-story/skills/story-setup/references/agent-references/anti-ai-writing.md +19 -47
- package/lib/oh-story/skills/story-setup/references/agent-references/banned-words.md +3 -1
- package/lib/oh-story/skills/story-setup/references/agent-references/deslop-gates.md +154 -0
- package/lib/oh-story/skills/story-setup/references/agent-references/dialogue-mastery.md +6 -4
- package/lib/oh-story/skills/story-setup/references/agent-references/format-and-structure.md +2 -2
- package/lib/oh-story/skills/story-setup/references/agent-references/short-genre-formulas.md +1 -1
- package/lib/oh-story/skills/story-setup/references/agent-references/style-combat-face.md +1 -1
- package/lib/oh-story/skills/story-setup/references/agent-references/style-genre-modules.md +1 -1
- package/lib/oh-story/skills/story-setup/references/agent-references/style-resolution.md +27 -0
- package/lib/oh-story/skills/story-setup/references/agent-references/writing-craft.md +69 -2
- package/lib/oh-story/skills/story-setup/references/diagnostics.md +38 -0
- package/lib/oh-story/skills/story-short-analyze/references/analysis-writing-techniques.md +1 -1
- package/lib/oh-story/skills/story-short-analyze/references/source-story-quality.md +2 -2
- package/lib/oh-story/skills/story-short-write/SKILL.md +18 -186
- package/lib/oh-story/skills/story-short-write/references/author-memory.md +10 -8
- package/lib/oh-story/skills/story-short-write/references/banned-words.md +3 -1
- package/lib/oh-story/skills/story-short-write/references/benchmark-recall.md +60 -0
- package/lib/oh-story/skills/story-short-write/references/dialogue-mastery.md +6 -4
- 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
- package/lib/oh-story/skills/story-short-write/references/genre-styles//345/217/214/347/224/267/344/270/273.md +1 -1
- 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
- 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
- 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
- package/lib/oh-story/skills/story-short-write/references/genre-styles//346/202/254/347/226/221.md +5 -5
- 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
- package/lib/oh-story/skills/story-short-write/references/genre-styles//347/224/234/345/256/240.md +5 -5
- 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
- package/lib/oh-story/skills/story-short-write/references/genre-writing-formulas.md +1 -1
- package/lib/oh-story/skills/story-short-write/references/genre-writing-techniques.md +1 -1
- package/lib/oh-story/skills/story-short-write/references/reference-index.md +53 -0
- package/lib/oh-story/skills/story-short-write/references/short-craft.md +12 -14
- package/lib/oh-story/skills/story-short-write/references/short-deslop.md +10 -10
- package/lib/oh-story/skills/story-short-write/references/short-format.md +3 -1
- package/lib/oh-story/skills/story-short-write/references/short-prose-quality.md +2 -2
- package/lib/oh-story/skills/story-short-write/references/style-resolution.md +27 -0
- package/lib/oh-story/skills/story-short-write/references/workflow-design.md +77 -0
- package/lib/oh-story/skills/story-short-write/references/writing-workflow.md +5 -5
- package/lib/oh-story/skills/story-short-write/scripts/check-ai-patterns.js +6 -1
- package/lib/oh-story/skills/story-short-write/scripts/check-degeneration.js +39 -20
- package/lib/oh-story/skills/story-short-write/scripts/check-delivery-contract.js +34 -5
- package/lib/oh-story/skills/story-short-write/scripts/check-outline-copy.js +90 -23
- package/lib/oh-story/skills/story-short-write/scripts/normalize-punctuation.js +10 -5
- package/lib/oh-story/skills/story-short-write/scripts/style-whitelist.js +39 -0
- package/lib/types/client/drama-production-view.d.ts.map +1 -1
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/client/production-prompts.d.ts.map +1 -1
- package/lib/types/client/production-runtime.d.ts +17 -0
- package/lib/types/client/production-runtime.d.ts.map +1 -1
- package/lib/types/skill-provider.d.ts.map +1 -1
- package/lib/video-recap/CHANGELOG.md +31 -1
- package/lib/video-recap/manifest.json +162 -162
- package/lib/video-recap/skills/video-assemble/scripts/artifacts.py +4 -9
- package/lib/video-recap/skills/video-assemble/scripts/assemble.py +47 -60
- package/lib/video-recap/skills/video-assemble/scripts/assembly_contract.py +77 -115
- package/lib/video-recap/skills/video-assemble/scripts/assembly_settings.py +41 -40
- package/lib/video-recap/skills/video-assemble/scripts/audio_automation.py +22 -32
- package/lib/video-recap/skills/video-assemble/scripts/audio_mix.py +102 -192
- package/lib/video-recap/skills/video-assemble/scripts/jianying_builders.py +14 -35
- package/lib/video-recap/skills/video-assemble/scripts/jianying_model.py +14 -12
- package/lib/video-recap/skills/video-assemble/scripts/jianying_optional.py +8 -9
- package/lib/video-recap/skills/video-assemble/scripts/jianying_schema.py +3 -14
- package/lib/video-recap/skills/video-assemble/scripts/jianying_timeline_contract.py +23 -12
- package/lib/video-recap/skills/video-assemble/scripts/jianying_tracks.py +1 -4
- package/lib/video-recap/skills/video-assemble/scripts/jianying_writer.py +24 -25
- package/lib/video-recap/skills/video-assemble/scripts/lib.py +31 -85
- package/lib/video-recap/skills/video-assemble/scripts/media.py +100 -144
- package/lib/video-recap/skills/video-assemble/scripts/narration_audio.py +101 -195
- package/lib/video-recap/skills/video-assemble/scripts/render_preflight.py +10 -21
- package/lib/video-recap/skills/video-assemble/scripts/source_subtitles.py +90 -169
- package/lib/video-recap/skills/video-assemble/scripts/subtitle_core.py +69 -122
- package/lib/video-recap/skills/video-assemble/scripts/subtitle_render.py +10 -17
- package/lib/video-recap/skills/video-assemble/scripts/timeline.py +33 -48
- package/lib/video-recap/skills/video-assemble/scripts/timeline_emit.py +14 -20
- package/lib/video-recap/skills/video-assemble/scripts/visual_render.py +135 -213
- package/lib/video-recap/skills/video-cut/scripts/cut_cli.py +49 -57
- package/lib/video-recap/skills/video-cut/scripts/cut_contract.py +38 -74
- package/lib/video-recap/skills/video-cut/scripts/cut_render.py +46 -95
- package/lib/video-recap/skills/video-cut/scripts/lib.py +23 -25
- package/lib/video-recap/skills/video-cut/scripts/media_geometry.py +70 -173
- package/lib/video-recap/skills/video-cut/scripts/narration_mapping.py +28 -53
- package/lib/video-recap/skills/video-cut/scripts/sentence_boundaries.py +162 -322
- package/lib/video-recap/skills/video-recap/references/timeline-and-jianying.md +6 -7
- package/lib/video-recap/skills/video-recap/scripts/doctor.py +104 -124
- package/lib/video-recap/skills/video-recap/scripts/final_qc.py +255 -412
- package/lib/video-recap/skills/video-recap/scripts/lib.py +30 -52
- package/lib/video-recap/skills/video-recap/scripts/materials.py +97 -120
- package/lib/video-recap/skills/video-recap/scripts/mimo_qc_client.py +7 -12
- package/lib/video-recap/skills/video-recap/scripts/mimo_qc_evidence.py +46 -97
- package/lib/video-recap/skills/video-recap/scripts/mimo_qc_observations.py +18 -36
- package/lib/video-recap/skills/video-recap/scripts/mimo_qc_payload.py +29 -47
- package/lib/video-recap/skills/video-recap/scripts/mimo_qc_report.py +43 -76
- package/lib/video-recap/skills/video-recap/scripts/mimo_qc_runner.py +2 -1
- package/lib/video-recap/skills/video-recap/scripts/qc_contract.py +2 -1
- package/lib/video-recap/skills/video-recap/scripts/recap_cli.py +2 -2
- package/lib/video-recap/skills/video-recap/scripts/recap_inspect.py +129 -145
- package/lib/video-recap/skills/video-recap/scripts/recap_review.py +27 -20
- package/lib/video-recap/skills/video-recap/scripts/recap_runner.py +20 -31
- package/lib/video-recap/skills/video-recap/scripts/recap_runtime.py +31 -106
- package/lib/video-recap/skills/video-recap/scripts/recap_stage_qc.py +43 -113
- package/lib/video-recap/skills/video-recap/scripts/recap_timeline.py +196 -377
- package/lib/video-recap/skills/video-script/scripts/agent_brief.py +1 -1
- package/lib/video-recap/skills/video-script/scripts/agent_text.py +63 -172
- package/lib/video-recap/skills/video-script/scripts/brief_context.py +80 -135
- package/lib/video-recap/skills/video-script/scripts/brief_inputs.py +125 -167
- package/lib/video-recap/skills/video-script/scripts/brief_timeline.py +93 -208
- package/lib/video-recap/skills/video-script/scripts/deslop_qc.py +20 -46
- package/lib/video-recap/skills/video-script/scripts/lib.py +30 -26
- package/lib/video-recap/skills/video-script/scripts/narration_lint.py +145 -140
- package/lib/video-recap/skills/video-script/scripts/review_response.py +12 -42
- package/lib/video-recap/skills/video-script/scripts/review_runner.py +0 -6
- package/lib/video-recap/skills/video-script/scripts/speech_ownership.py +39 -100
- package/lib/video-recap/skills/video-script/scripts/timeline_fusion.py +33 -124
- package/lib/video-recap/skills/video-understanding/scripts/agent_brief.py +1 -1
- package/lib/video-recap/skills/video-understanding/scripts/agent_text.py +63 -172
- package/lib/video-recap/skills/video-understanding/scripts/asr.py +1 -2
- package/lib/video-recap/skills/video-understanding/scripts/brief_context.py +80 -135
- package/lib/video-recap/skills/video-understanding/scripts/brief_inputs.py +125 -167
- package/lib/video-recap/skills/video-understanding/scripts/brief_timeline.py +93 -208
- package/lib/video-recap/skills/video-understanding/scripts/consolidate.py +1 -1
- package/lib/video-recap/skills/video-understanding/scripts/deslop_qc.py +20 -46
- package/lib/video-recap/skills/video-understanding/scripts/lib.py +31 -26
- package/lib/video-recap/skills/video-understanding/scripts/narration_lint.py +145 -140
- package/lib/video-recap/skills/video-understanding/scripts/speech_ownership.py +39 -100
- package/lib/video-recap/skills/video-understanding/scripts/timeline_fusion.py +33 -124
- package/lib/video-recap/skills/video-understanding/scripts/vlm.py +1 -4
- package/lib/video-recap/skills/video-voiceover/scripts/dub.py +7 -13
- package/lib/video-recap/skills/video-voiceover/scripts/fish_audio.py +12 -30
- package/lib/video-recap/skills/video-voiceover/scripts/lib.py +98 -131
- package/lib/video-recap/skills/video-voiceover/scripts/tts_audio.py +17 -28
- package/lib/video-recap/skills/video-voiceover/scripts/voiceover.py +151 -240
- package/package.json +41 -41
|
@@ -1,61 +1,29 @@
|
|
|
1
1
|
"""Load and format research, consolidation, and substrate context."""
|
|
2
2
|
|
|
3
3
|
import hashlib
|
|
4
|
-
|
|
5
|
-
import importlib.util
|
|
6
|
-
|
|
7
|
-
|
|
8
4
|
import json
|
|
9
|
-
|
|
10
|
-
|
|
11
5
|
import re
|
|
12
|
-
|
|
13
6
|
from pathlib import Path
|
|
14
7
|
|
|
15
8
|
from lib import CONFIG
|
|
16
9
|
|
|
17
|
-
from lib import log
|
|
18
|
-
|
|
19
|
-
try:
|
|
20
|
-
from deslop_qc import analyze_deslop_qc
|
|
21
|
-
except ModuleNotFoundError:
|
|
22
|
-
_deslop_qc_path = Path(__file__).with_name("deslop_qc.py")
|
|
23
|
-
_deslop_qc_spec = importlib.util.spec_from_file_location(
|
|
24
|
-
"deslop_qc", _deslop_qc_path
|
|
25
|
-
)
|
|
26
|
-
if _deslop_qc_spec is None or _deslop_qc_spec.loader is None:
|
|
27
|
-
raise
|
|
28
|
-
_deslop_qc_module = importlib.util.module_from_spec(_deslop_qc_spec)
|
|
29
|
-
_deslop_qc_spec.loader.exec_module(_deslop_qc_module)
|
|
30
|
-
analyze_deslop_qc = _deslop_qc_module.analyze_deslop_qc
|
|
31
|
-
|
|
32
10
|
|
|
33
11
|
def _load_background_research(work_dir):
|
|
34
|
-
"""Load the agent-authored background_research.json
|
|
35
|
-
|
|
36
|
-
This file is the single highest-leverage quality input (character names,
|
|
37
|
-
relationships, plot context). It used to be documented but never read by
|
|
38
|
-
any code, so researched story knowledge never reached the writing brief.
|
|
39
|
-
"""
|
|
12
|
+
"""Load the agent-authored background_research.json ({} when absent)."""
|
|
40
13
|
path = Path(work_dir) / "background_research.json"
|
|
41
14
|
if not path.exists():
|
|
42
15
|
return {}
|
|
43
|
-
|
|
44
|
-
data = json.loads(path.read_text(encoding="utf-8"))
|
|
45
|
-
except (json.JSONDecodeError, OSError) as exc:
|
|
46
|
-
log(f"警告: background_research.json 读取失败,忽略: {exc}")
|
|
47
|
-
return {}
|
|
48
|
-
return data if isinstance(data, dict) else {}
|
|
16
|
+
return json.loads(path.read_text(encoding="utf-8"))
|
|
49
17
|
|
|
50
18
|
|
|
51
19
|
def _clip_text(text, limit):
|
|
52
|
-
|
|
53
|
-
return
|
|
20
|
+
"""Collapse whitespace and clip. Research fields are optional, so None clips to ""."""
|
|
21
|
+
return re.sub(r"\s+", " ", str(text or "")).strip()[:limit]
|
|
54
22
|
|
|
55
23
|
|
|
56
24
|
def _format_background_research(research, limit=1800):
|
|
57
25
|
"""Render background_research.json into a bounded Story-context brief section."""
|
|
58
|
-
if not
|
|
26
|
+
if not research:
|
|
59
27
|
return []
|
|
60
28
|
lines = [
|
|
61
29
|
"## Story context (from background_research.json)",
|
|
@@ -72,50 +40,33 @@ def _format_background_research(research, limit=1800):
|
|
|
72
40
|
if value:
|
|
73
41
|
lines.append(f"- {label}: {value}")
|
|
74
42
|
|
|
75
|
-
characters = research.get("characters")
|
|
76
|
-
if
|
|
43
|
+
characters = research.get("characters", {})
|
|
44
|
+
if characters:
|
|
77
45
|
lines.append("- Characters:")
|
|
78
46
|
for name, desc in list(characters.items())[:12]:
|
|
79
|
-
|
|
80
|
-
clean_desc = _clip_text(desc, 160)
|
|
81
|
-
if clean_name:
|
|
82
|
-
lines.append(f" - {clean_name}: {clean_desc}")
|
|
47
|
+
lines.append(f" - {_clip_text(name, 60)}: {_clip_text(desc, 160)}")
|
|
83
48
|
|
|
84
|
-
details = research.get("character_details")
|
|
85
|
-
if
|
|
49
|
+
details = research.get("character_details", {})
|
|
50
|
+
if details:
|
|
86
51
|
lines.append("- Character details:")
|
|
87
52
|
for name, info in list(details.items())[:8]:
|
|
88
|
-
if not isinstance(info, dict):
|
|
89
|
-
continue
|
|
90
53
|
bits = []
|
|
91
|
-
aliases = info.get("aliases")
|
|
92
|
-
if
|
|
93
|
-
|
|
94
|
-
clean_aliases = [alias for alias in clean_aliases if alias]
|
|
95
|
-
if clean_aliases:
|
|
96
|
-
bits.append("别名 " + "/".join(clean_aliases))
|
|
54
|
+
aliases = [_clip_text(alias, 40) for alias in info.get("aliases", [])[:4]]
|
|
55
|
+
if aliases:
|
|
56
|
+
bits.append("别名 " + "/".join(aliases))
|
|
97
57
|
role = _clip_text(info.get("role"), 80)
|
|
98
58
|
if role:
|
|
99
59
|
bits.append(role)
|
|
100
|
-
rels = info.get("relationships")
|
|
101
|
-
if
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
lines.append(f" - {clean_name}: {'; '.join(bits)}")
|
|
109
|
-
|
|
110
|
-
arcs = research.get("plot_arcs")
|
|
111
|
-
if isinstance(arcs, list) and arcs:
|
|
60
|
+
rels = [_clip_text(rel, 80) for rel in info.get("relationships", [])[:4]]
|
|
61
|
+
if rels:
|
|
62
|
+
bits.append(";".join(rels))
|
|
63
|
+
if bits:
|
|
64
|
+
lines.append(f" - {_clip_text(name, 60)}: {'; '.join(bits)}")
|
|
65
|
+
|
|
66
|
+
arcs = research.get("plot_arcs", [])
|
|
67
|
+
if arcs:
|
|
112
68
|
lines.append("- Plot arcs:")
|
|
113
69
|
for arc in arcs[:8]:
|
|
114
|
-
if not isinstance(arc, dict):
|
|
115
|
-
value = _clip_text(arc, 180)
|
|
116
|
-
if value:
|
|
117
|
-
lines.append(f" - {value}")
|
|
118
|
-
continue
|
|
119
70
|
name = _clip_text(arc.get("name"), 80)
|
|
120
71
|
desc = _clip_text(arc.get("description"), 180)
|
|
121
72
|
status = _clip_text(arc.get("status"), 40)
|
|
@@ -123,15 +74,10 @@ def _format_background_research(research, limit=1800):
|
|
|
123
74
|
tail = f" [{status}]" if status else ""
|
|
124
75
|
lines.append(f" - {name}: {desc}{tail}".rstrip())
|
|
125
76
|
|
|
126
|
-
notes = research.get("cultural_notes")
|
|
127
|
-
if
|
|
77
|
+
notes = research.get("cultural_notes", [])
|
|
78
|
+
if notes:
|
|
128
79
|
lines.append("- Cultural notes:")
|
|
129
80
|
for note in notes[:6]:
|
|
130
|
-
if not isinstance(note, dict):
|
|
131
|
-
value = _clip_text(note, 160)
|
|
132
|
-
if value:
|
|
133
|
-
lines.append(f" - {value}")
|
|
134
|
-
continue
|
|
135
81
|
item = _clip_text(note.get("item"), 80)
|
|
136
82
|
expl = _clip_text(note.get("explanation"), 160)
|
|
137
83
|
if item and expl:
|
|
@@ -150,7 +96,8 @@ def _format_background_research(research, limit=1800):
|
|
|
150
96
|
if len(text) <= limit:
|
|
151
97
|
return lines
|
|
152
98
|
clipped = text[:limit].rsplit("\n", 1)[0].rstrip()
|
|
153
|
-
return
|
|
99
|
+
return [
|
|
100
|
+
*clipped.splitlines(),
|
|
154
101
|
"",
|
|
155
102
|
"[Story context clipped to keep ASR/visual evidence in context]",
|
|
156
103
|
"",
|
|
@@ -169,16 +116,9 @@ def assess_understanding_substrate(
|
|
|
169
116
|
so it must not grade as "rich"; otherwise the sparse-substrate warning, the research
|
|
170
117
|
directive, and the density relief never fire for exactly that cold-narration case.
|
|
171
118
|
"""
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
1 for s in scenes if isinstance(s, dict) and s.get("frame_facts")
|
|
176
|
-
)
|
|
177
|
-
desc_lens = [
|
|
178
|
-
len(str(s.get("description", "")).strip())
|
|
179
|
-
for s in scenes
|
|
180
|
-
if isinstance(s, dict)
|
|
181
|
-
]
|
|
119
|
+
asr_chars = sum(len(seg["text"]) for seg in asr_result)
|
|
120
|
+
scenes_with_facts = sum(1 for s in scenes_analysis if s.get("frame_facts"))
|
|
121
|
+
desc_lens = [len(s["description"]) for s in scenes_analysis]
|
|
182
122
|
avg_desc = sum(desc_lens) // len(desc_lens) if desc_lens else 0
|
|
183
123
|
|
|
184
124
|
has_asr = asr_chars >= 20
|
|
@@ -193,7 +133,7 @@ def assess_understanding_substrate(
|
|
|
193
133
|
return {
|
|
194
134
|
"level": level,
|
|
195
135
|
"asr_chars": asr_chars,
|
|
196
|
-
"scene_count": len(
|
|
136
|
+
"scene_count": len(scenes_analysis),
|
|
197
137
|
"scenes_with_frame_facts": scenes_with_facts,
|
|
198
138
|
"avg_description_len": avg_desc,
|
|
199
139
|
"has_story_context": bool(has_story_context),
|
|
@@ -202,7 +142,7 @@ def assess_understanding_substrate(
|
|
|
202
142
|
|
|
203
143
|
def _format_substrate_warning(assessment):
|
|
204
144
|
"""Render a loud brief banner when the understanding substrate is weak."""
|
|
205
|
-
if
|
|
145
|
+
if assessment["level"] == "rich":
|
|
206
146
|
return []
|
|
207
147
|
if assessment["level"] == "empty":
|
|
208
148
|
head = "⚠️ UNDERSTANDING SUBSTRATE IS EMPTY — narration will be generic guesswork unless you fix this first."
|
|
@@ -236,8 +176,8 @@ def _format_asr_chunks_for_brief(chunks, max_chunks=24):
|
|
|
236
176
|
"",
|
|
237
177
|
]
|
|
238
178
|
for chunk in chunks[:max_chunks]:
|
|
239
|
-
scene_ids = ",".join(str(sid) for sid in chunk
|
|
240
|
-
text =
|
|
179
|
+
scene_ids = ",".join(str(sid) for sid in chunk["scene_ids"]) or "n/a"
|
|
180
|
+
text = chunk["text"]
|
|
241
181
|
if len(text) > 900:
|
|
242
182
|
text = text[:897] + "..."
|
|
243
183
|
lines.extend(
|
|
@@ -266,29 +206,27 @@ def _format_timeline_fusion_for_brief(fusion, max_items=40):
|
|
|
266
206
|
"",
|
|
267
207
|
]
|
|
268
208
|
for item in fusion[:max_items]:
|
|
269
|
-
start, end = item
|
|
270
|
-
slots = item.get("narration_slots") or []
|
|
209
|
+
start, end = item["time_range"]
|
|
271
210
|
slot_text = (
|
|
272
211
|
", ".join(
|
|
273
212
|
f"{slot['start']:.1f}-{slot['end']:.1f}s/{slot['char_budget']}字"
|
|
274
|
-
for slot in
|
|
213
|
+
for slot in item["narration_slots"][:4]
|
|
275
214
|
)
|
|
276
215
|
or "none"
|
|
277
216
|
)
|
|
278
|
-
dialogue = item.get("dialogue_segments") or []
|
|
279
217
|
dialogue_text = (
|
|
280
218
|
"; ".join(
|
|
281
|
-
f"{seg['start']:.1f}-{seg['end']:.1f}s {seg
|
|
282
|
-
for seg in
|
|
283
|
-
if seg
|
|
219
|
+
f"{seg['start']:.1f}-{seg['end']:.1f}s {seg['text'][:80]}"
|
|
220
|
+
for seg in item["dialogue_segments"][:3]
|
|
221
|
+
if seg["text"]
|
|
284
222
|
)
|
|
285
223
|
or "none"
|
|
286
224
|
)
|
|
287
225
|
lines.extend(
|
|
288
226
|
[
|
|
289
|
-
f"### Fusion scene {item
|
|
290
|
-
f"- Visual: {item
|
|
291
|
-
f"- Dialogue overlap: {item
|
|
227
|
+
f"### Fusion scene {item['scene_id']}: {start:.1f}-{end:.1f}s ({item['recommended_mode']})",
|
|
228
|
+
f"- Visual: {item['visual_description']}",
|
|
229
|
+
f"- Dialogue overlap: {item['dialogue_overlap_seconds']:.1f}s | {dialogue_text}",
|
|
292
230
|
f"- Narration slots: {slot_text}",
|
|
293
231
|
"",
|
|
294
232
|
]
|
|
@@ -302,7 +240,7 @@ def _format_timeline_fusion_for_brief(fusion, max_items=40):
|
|
|
302
240
|
|
|
303
241
|
|
|
304
242
|
def _consolidation_model():
|
|
305
|
-
return CONFIG
|
|
243
|
+
return CONFIG["vlm_model"]
|
|
306
244
|
|
|
307
245
|
|
|
308
246
|
def _clean_asr_prompt_fingerprint():
|
|
@@ -332,70 +270,77 @@ def _index_prompt_fingerprint():
|
|
|
332
270
|
return hashlib.md5(prompt.encode("utf-8")).hexdigest()
|
|
333
271
|
|
|
334
272
|
|
|
335
|
-
def _load_consolidation(work_dir, scenes_analysis
|
|
336
|
-
"""Load consolidate.py's understanding_index.json only when provenance matches
|
|
273
|
+
def _load_consolidation(work_dir, scenes_analysis):
|
|
274
|
+
"""Load consolidate.py's understanding_index.json only when its provenance matches
|
|
275
|
+
the current vlm_analysis.json, model and index prompt ({} otherwise)."""
|
|
337
276
|
work_dir = Path(work_dir)
|
|
338
277
|
path = work_dir / "understanding_index.json"
|
|
339
278
|
meta_path = work_dir / "understanding_index.json.meta.json"
|
|
340
279
|
if not path.exists() or not meta_path.exists():
|
|
341
280
|
return {}
|
|
342
281
|
try:
|
|
343
|
-
data = json.loads(path.read_text(encoding="utf-8"))
|
|
344
282
|
meta = json.loads(meta_path.read_text(encoding="utf-8"))
|
|
345
|
-
|
|
283
|
+
source_md5 = hashlib.md5(
|
|
284
|
+
(work_dir / "vlm_analysis.json").read_bytes()
|
|
285
|
+
).hexdigest()
|
|
286
|
+
except (OSError, json.JSONDecodeError):
|
|
346
287
|
return {}
|
|
347
|
-
if not isinstance(
|
|
288
|
+
if not isinstance(meta, dict):
|
|
348
289
|
return {}
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
290
|
+
expected = {
|
|
291
|
+
"source_md5": source_md5,
|
|
292
|
+
"model": _consolidation_model(),
|
|
293
|
+
"prompt_md5": _index_prompt_fingerprint(),
|
|
294
|
+
}
|
|
295
|
+
if scenes_analysis:
|
|
296
|
+
expected["scene_count"] = len(scenes_analysis)
|
|
297
|
+
if not meta.items() >= expected.items():
|
|
353
298
|
return {}
|
|
354
|
-
|
|
299
|
+
try:
|
|
300
|
+
index = json.loads(path.read_text(encoding="utf-8"))
|
|
301
|
+
except (OSError, json.JSONDecodeError):
|
|
355
302
|
return {}
|
|
356
|
-
|
|
357
|
-
|
|
303
|
+
if not isinstance(index, dict) or not all(
|
|
304
|
+
isinstance(index.get(key), list)
|
|
305
|
+
for key in ("characters", "relationships", "plot_points", "entities")
|
|
306
|
+
):
|
|
358
307
|
return {}
|
|
359
|
-
if
|
|
308
|
+
if not all(isinstance(item, dict) for item in index["characters"]):
|
|
360
309
|
return {}
|
|
361
|
-
if
|
|
310
|
+
if not all(isinstance(item, dict) for item in index["relationships"]):
|
|
362
311
|
return {}
|
|
363
|
-
return
|
|
312
|
+
return index
|
|
364
313
|
|
|
365
314
|
|
|
366
315
|
def _format_consolidation(index):
|
|
367
|
-
"""Render consolidate.py's understanding_index.json into a compact brief section.
|
|
316
|
+
"""Render consolidate.py's understanding_index.json into a compact brief section.
|
|
317
|
+
|
|
318
|
+
plot_points/entities items are model output and may be bare strings or objects."""
|
|
368
319
|
if not index:
|
|
369
320
|
return []
|
|
370
321
|
lines = ["## Understanding index (from consolidate.py)", ""]
|
|
371
|
-
chars = index
|
|
322
|
+
chars = index["characters"]
|
|
372
323
|
if chars:
|
|
373
324
|
lines.append("- Characters:")
|
|
374
325
|
for c in chars:
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
else:
|
|
380
|
-
lines.append(f" - {c}")
|
|
381
|
-
rels = index.get("relationships") or []
|
|
326
|
+
lines.append(
|
|
327
|
+
f" - {c.get('name', '?')}: {str(c.get('description', '')).strip()}"
|
|
328
|
+
)
|
|
329
|
+
rels = index["relationships"]
|
|
382
330
|
if rels:
|
|
383
331
|
lines.append("- Relationships:")
|
|
384
332
|
for r in rels:
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
else:
|
|
390
|
-
lines.append(f" - {r}")
|
|
391
|
-
plot = index.get("plot_points") or []
|
|
333
|
+
lines.append(
|
|
334
|
+
f" - {r.get('a', '?')} — {r.get('relation', '?')} — {r.get('b', '?')}"
|
|
335
|
+
)
|
|
336
|
+
plot = index["plot_points"]
|
|
392
337
|
if plot:
|
|
393
338
|
lines.append("- Plot spine:")
|
|
394
339
|
lines.extend(
|
|
395
340
|
f" {i + 1}. {p.get('text', p) if isinstance(p, dict) else p}"
|
|
396
341
|
for i, p in enumerate(plot)
|
|
397
342
|
)
|
|
398
|
-
ents = index
|
|
343
|
+
ents = index["entities"]
|
|
399
344
|
if ents:
|
|
400
345
|
ent_names = [str(e.get("name", e) if isinstance(e, dict) else e) for e in ents]
|
|
401
346
|
lines.append(f"- Entities: {', '.join(ent_names)}")
|