@event4u/agent-config 2.21.0 → 2.24.0

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 (67) hide show
  1. package/.agent-src/commands/video/from-script.md +123 -0
  2. package/.agent-src/commands/video/scene.md +92 -0
  3. package/.agent-src/commands/video/stitch.md +83 -0
  4. package/.agent-src/commands/video/storyboard.md +95 -0
  5. package/.agent-src/commands/video.md +59 -0
  6. package/.agent-src/personas/README.md +3 -0
  7. package/.agent-src/personas/ai-video-technical-director.md +81 -0
  8. package/.agent-src/personas/hollywood-director.md +99 -0
  9. package/.agent-src/personas/pixar-storyboard-artist.md +98 -0
  10. package/.agent-src/skills/adversarial-review/SKILL.md +2 -1
  11. package/.agent-src/skills/canvas-design/SKILL.md +11 -6
  12. package/.agent-src/skills/character-consistency/SKILL.md +120 -0
  13. package/.agent-src/skills/fe-design/SKILL.md +8 -0
  14. package/.agent-src/skills/motion-choreographer/SKILL.md +149 -0
  15. package/.agent-src/skills/pixar-storyteller/SKILL.md +107 -0
  16. package/.agent-src/skills/prompt-optimizer/SKILL.md +29 -5
  17. package/.agent-src/skills/react-shadcn-ui/SKILL.md +9 -0
  18. package/.agent-src/skills/refine-prompt/SKILL.md +57 -0
  19. package/.agent-src/skills/scene-expander/SKILL.md +122 -0
  20. package/.agent-src/skills/scene-expander/scene-blueprint.schema.yaml +108 -0
  21. package/.agent-src/skills/subagent-orchestration/SKILL.md +17 -15
  22. package/.agent-src/skills/tailwind-engineer/SKILL.md +14 -0
  23. package/.agent-src/skills/video-director/SKILL.md +113 -0
  24. package/.agent-src/templates/agent-settings.md +19 -0
  25. package/.agent-src/templates/agents/agent-project-settings.example.yml +53 -1
  26. package/.claude-plugin/marketplace.json +11 -1
  27. package/CHANGELOG.md +88 -138
  28. package/README.md +4 -4
  29. package/config/agent-settings.template.yml +28 -0
  30. package/docs/adrs/caveman/0001-default-off-until-bench.md +2 -2
  31. package/docs/adrs/cost/0001-hard-stop-hook.md +1 -1
  32. package/docs/adrs/smoke/0001-per-tier-smoke-scripts.md +2 -2
  33. package/docs/architecture.md +3 -3
  34. package/docs/archive/CHANGELOG-pre-2.20.0.md +159 -0
  35. package/docs/catalog.md +16 -5
  36. package/docs/contracts/command-clusters.md +1 -0
  37. package/docs/contracts/compression-default-kill-criterion.md +1 -1
  38. package/docs/contracts/file-ownership-matrix.json +344 -0
  39. package/docs/getting-started.md +1 -1
  40. package/docs/guidelines/prompt-templates.md +166 -0
  41. package/docs/parity/ruflo.md +3 -3
  42. package/package.json +1 -1
  43. package/scripts/ai-video/adapters/gemini-veo.sh +57 -0
  44. package/scripts/ai-video/adapters/higgsfield.sh +82 -0
  45. package/scripts/ai-video/adapters/kling.sh +54 -0
  46. package/scripts/ai-video/adapters/openai-images.sh +52 -0
  47. package/scripts/ai-video/adapters/sora.sh +54 -0
  48. package/scripts/ai-video/lib/adapter-common.sh +116 -0
  49. package/scripts/ai-video/lib/adapter-contract.md +163 -0
  50. package/scripts/ai-video/lib/fixtures/gemini-veo/result.json +1 -0
  51. package/scripts/ai-video/lib/fixtures/gemini-veo/scene-0001.mp4 +1 -0
  52. package/scripts/ai-video/lib/fixtures/higgsfield/result.json +1 -0
  53. package/scripts/ai-video/lib/fixtures/higgsfield/scene-0001.mp4 +1 -0
  54. package/scripts/ai-video/lib/fixtures/kling/result.json +1 -0
  55. package/scripts/ai-video/lib/fixtures/kling/scene-0001.mp4 +1 -0
  56. package/scripts/ai-video/lib/fixtures/openai-images/result.json +1 -0
  57. package/scripts/ai-video/lib/fixtures/openai-images/scene-0001.png +3 -0
  58. package/scripts/ai-video/lib/fixtures/sora/result.json +1 -0
  59. package/scripts/ai-video/lib/fixtures/sora/scene-0001.mp4 +1 -0
  60. package/scripts/ai-video/lib/load-config.sh +140 -0
  61. package/scripts/ai-video/lib/operator-pick.sh +119 -0
  62. package/scripts/ai-video/lib/parse-blueprint.sh +122 -0
  63. package/scripts/ai-video/lib/redact.sh +85 -0
  64. package/scripts/ai-video/lib/validate-deps.sh +132 -0
  65. package/scripts/ai-video/stitch.sh +154 -0
  66. package/scripts/ai-video/test-pipeline.sh +169 -0
  67. package/scripts/schemas/command.schema.json +8 -0
@@ -0,0 +1,166 @@
1
+ # Prompt Templates
2
+
3
+ Reference catalogue of prompt structures the [`prompt-optimizer`](../../.agent-src.uncompressed/skills/prompt-optimizer/SKILL.md)
4
+ skill picks from during the **Develop** step of the 4-D methodology.
5
+ Cited by the [`refine-prompt`](../../.agent-src.uncompressed/skills/refine-prompt/SKILL.md)
6
+ skill in `mini` mode for stack-aware shaping.
7
+
8
+ Templates are tools, not dogma. Pick by request type, not by upstream
9
+ whitelist — see the [Rejection note](#rejection-note) at the bottom.
10
+
11
+ ## When-to-pick rubric
12
+
13
+ | Request shape | First-choice template | Fallback |
14
+ |---|---|---|
15
+ | One-shot technical change (refactor, lint fix) | **RTF** | File-Scope |
16
+ | Multi-file refactor across a codebase | **File-Scope** | RTF |
17
+ | Marketing / brand / tone-heavy copy | **CO-STAR** | CRISPE |
18
+ | Mixed-audience explainer (technical + lay) | **CRISPE** | CO-STAR |
19
+ | Step-by-step explainer / tutorial | **RISEN** | Few-Shot |
20
+ | Pattern-heavy task (classification, extraction) | **Few-Shot** | RISEN |
21
+ | Multi-step reasoning or math | **CoT** | ReAct |
22
+ | Tool-using agent (web search, file ops) | **ReAct** | CoT |
23
+ | Image AI (Midjourney, SD, DALL·E) | **Visual Descriptor** | Reference-Image-Edit |
24
+ | Image edit from a source image | **Reference-Image-Edit** | Visual Descriptor |
25
+ | ComfyUI / node-graph image workflows | **ComfyUI** | Visual Descriptor |
26
+ | Reverse-engineer an existing good prompt | **Prompt Decompiler** | — |
27
+ | Honest critical feedback on a finished artifact (post, design, naming, proposal) — any domain | **Honest Sparring Partner** | CRISPE |
28
+
29
+ ## Text templates
30
+
31
+ ### RTF — Role · Task · Format
32
+ Smallest viable structure. Three lines: who the AI is, what to do,
33
+ how the output should look. Best for one-shot technical asks.
34
+
35
+ ### CO-STAR — Context · Objective · Style · Tone · Audience · Response
36
+ Six-slot structure originally from the Singapore GovTech prompt
37
+ study. Best for copy where audience and tone carry the message.
38
+
39
+ ### RISEN — Role · Input · Steps · Expectation · Narrowing
40
+ Step-explicit shape. Best for tutorials, walkthroughs, and any
41
+ output where the reader follows the prompt's structure.
42
+
43
+ ### CRISPE — Capacity · Role · Insight · Statement · Personality · Experiment
44
+ Six-slot, persona-heavy. Best when the *voice* matters more than
45
+ the structure (creative writing, explainers with a strong narrator).
46
+
47
+ ### CoT — Chain-of-Thought
48
+ Append "Think step by step" or "Reason aloud before answering" to
49
+ any base template. Best for multi-step reasoning, math, planning.
50
+ Pairs well with RTF or RISEN.
51
+
52
+ ### Few-Shot
53
+ Two to five worked examples inline before the actual ask. Best for
54
+ classification, extraction, format-mimicking. Costs tokens — keep
55
+ examples minimal and representative.
56
+
57
+ ### File-Scope
58
+ Codebase-aware variant of RTF. Names the files in scope, the
59
+ allowed-edit list, and the "do not touch" list explicitly. Best for
60
+ agent-driven refactors where blast radius matters.
61
+
62
+ ```
63
+ Role: senior TypeScript engineer
64
+ Files in scope: src/auth/*.ts, tests/auth/*.ts
65
+ Do not modify: src/db/*, package.json, tsconfig.json
66
+ Task: migrate from jsonwebtoken to jose; keep the exported API stable
67
+ Format: unified diff
68
+ ```
69
+
70
+ ### ReAct — Reason + Act
71
+ Interleaved thought / action / observation loop. Best for agents
72
+ with tools — web search, file ops, shell. Each cycle:
73
+
74
+ ```
75
+ Thought: <why I need this next step>
76
+ Action: <tool call>
77
+ Observation: <result>
78
+ ... repeat ...
79
+ Final Answer: <synthesis>
80
+ ```
81
+
82
+ ### Honest Sparring Partner
83
+ Domain-agnostic stance template for getting honest critical feedback on
84
+ a finished artifact — blog post, design draft, naming decision, business
85
+ proposal, care-plan, marketing copy. Works for any role (engineer,
86
+ graphic designer, nurse, founder) because the role slot is filled by
87
+ the user's actual profession, not hard-coded.
88
+
89
+ Five-slot shape:
90
+
91
+ ```
92
+ Role: <user's domain> — e.g. graphic designer, geriatric nurse, founder
93
+ Stance: honest sparring partner, not yes-man. Push back when something
94
+ is weak; acknowledge when something is solid; stay silent when
95
+ there is nothing substantive to add. No flattery openings, no
96
+ artificial criticism for its own sake.
97
+ Context-fit: ask ONE clarifying question only if real context is missing
98
+ (role, audience, constraint). Otherwise answer directly.
99
+ Artifact: <the finished thing — paste, link, or describe>
100
+ Ask: <what kind of reaction the user wants — "does the argument hold?",
101
+ "is the naming clear?", "would this land with audience X?">
102
+ ```
103
+
104
+ **Anti-pattern this rejects:** "what do you honestly think?" prompts that
105
+ either default to praise ("looks great!") or default to manufactured
106
+ criticism ("here are 5 problems...") regardless of whether the work
107
+ warrants either reaction. The stance slot makes the honest-when-warranted
108
+ contract explicit.
109
+
110
+ **Package equivalents** — inside this agent-config, the
111
+ [`adversarial-review`](../../.agent-src.uncompressed/skills/adversarial-review/SKILL.md)
112
+ skill implements the same stance via an Attack-Defend-Revise loop and is
113
+ the right tool when the user submits finished work for a critical take.
114
+ This template is for **end-users prompting their own LLM** (ChatGPT,
115
+ Claude, Gemini) outside this package.
116
+
117
+ ## Image templates
118
+
119
+ ### Visual Descriptor
120
+ Subject · style · composition · lighting · medium · mood · technical
121
+ parameters (aspect ratio, resolution). Best for Midjourney, Stable
122
+ Diffusion, DALL·E from a blank canvas.
123
+
124
+ ### Reference-Image-Edit
125
+ Source image reference + change set + preservation set. Names what
126
+ to change, what to keep, and the desired output framing. Best for
127
+ inpainting, style transfer, character consistency.
128
+
129
+ ### ComfyUI
130
+ Node-graph-aware. Names the workflow nodes (KSampler, CLIPTextEncode,
131
+ VAEDecode) and the parameter intent per node rather than the
132
+ parameter values. Best for advanced SD pipelines.
133
+
134
+ ## Reverse template
135
+
136
+ ### Prompt Decompiler
137
+ Given an existing good output, reconstruct the prompt that would
138
+ produce it. Used to mine prompts from public LLM artifacts. Not a
139
+ shaping template — a forensic one.
140
+
141
+ ## Rejection note
142
+
143
+ Upstream `nidhinjs/prompt-master` claims that only five techniques
144
+ are "safe" for production prompting:
145
+
146
+ - few-shot
147
+ - role assignment
148
+ - structured output
149
+ - constraint-based
150
+ - chain-of-thought
151
+
152
+ This package **rejects** that whitelist. CO-STAR, RISEN, CRISPE,
153
+ ReAct, and the image-AI templates above are first-class. The
154
+ "5 safe" framing came from a single benchmark on a single LLM
155
+ generation — it does not generalise. See AI Council session
156
+ `agents/council-responses/prompt-master-mini.json` (2026-05-17) for the analysis behind this rejection. <!-- council-ref-allowed: ADR decision trace -->
157
+
158
+ The right gate is request-type fit, not technique-whitelist
159
+ membership.
160
+
161
+ ## See also
162
+
163
+ - [`prompt-optimizer`](../../.agent-src.uncompressed/skills/prompt-optimizer/SKILL.md) — engine-outbound; cites this catalogue in its Develop step
164
+ - [`refine-prompt`](../../.agent-src.uncompressed/skills/refine-prompt/SKILL.md) — engine-inbound; uses templates in `mini` mode for stack-aware shaping
165
+ - [`prompt-engineering-patterns`](../../.agent-src.uncompressed/skills/prompt-engineering-patterns/SKILL.md) — production-LLM prompt patterns (sibling skill, not a catalogue)
166
+ - AI Council session: `agents/council-responses/prompt-master-mini.json` (2026-05-17) <!-- council-ref-allowed: ADR decision trace -->
@@ -2,7 +2,7 @@
2
2
 
3
3
  > Per-row verdict against the eight Ruflo measurement-governance patterns
4
4
  > catalogued in
5
- > [`external-findings.md § 2`](../../agents/audit-2026-05-14-north-star/external-findings.md).
5
+ > [`external-findings.md § 2`](../../agents/council-sessions/audit-2026-05-14-north-star/external-findings.md).
6
6
  > Owner roadmap: [`step-11-ruflo-parity.md`](../../agents/roadmaps/step-11-ruflo-parity.md)
7
7
  > (Phase 6 Step 1). Cross-index lives at
8
8
  > [`step-99-north-star-restructure.md`](../../agents/roadmaps/step-99-north-star-restructure.md)
@@ -10,7 +10,7 @@
10
10
  >
11
11
  > **Verdict legend:** `[x] covered by <file:line>` · `[~] superseded by <approach>` · `[!] gap`.
12
12
  > **Acceptance:** zero `[!]` rows. Closure flips the corresponding cell in the
13
- > [composite scorecard](../../agents/audit-2026-05-14-north-star/external-findings.md#5-composite-scorecard--agent-config-vs-the-field)
13
+ > [composite scorecard](../../agents/council-sessions/audit-2026-05-14-north-star/external-findings.md#5-composite-scorecard--agent-config-vs-the-field)
14
14
  > `vs Ruflo` column from `–` to `=` or `+`.
15
15
 
16
16
  **Measured-vs-claimed disclaimer:** Each row cites the **mechanism** that
@@ -41,6 +41,6 @@ mechanisms remain claimed until [`bench.json`](bench.json) soak completes
41
41
 
42
42
  ## Cross-references
43
43
 
44
- - Composite scorecard refresh: owned by [`step-99-north-star-restructure.md`](../../agents/roadmaps/step-99-north-star-restructure.md) Phase 5 Step 4 (replaces [`external-findings.md § 5`](../../agents/audit-2026-05-14-north-star/external-findings.md)).
44
+ - Composite scorecard refresh: owned by [`step-99-north-star-restructure.md`](../../agents/roadmaps/step-99-north-star-restructure.md) Phase 5 Step 4 (replaces [`external-findings.md § 5`](../../agents/council-sessions/audit-2026-05-14-north-star/external-findings.md)).
45
45
  - Bench-ruflo redundancy verdict: [`bench-ruflo.json`](bench-ruflo.json) (step-11 Phase 6 Step 2).
46
46
  - G5 redundancy gate cite: step-99 Acceptance Criteria row "G5 — external redundancy (Domination Mandate)".
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@event4u/agent-config",
3
- "version": "2.21.0",
3
+ "version": "2.24.0",
4
4
  "description": "Shared agent configuration \u2014 skills, rules, commands, guidelines, and templates for AI coding tools",
5
5
  "license": "MIT",
6
6
  "private": false,
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env bash
2
+ # gemini-veo.sh — Google Gemini Veo video generation adapter.
3
+ #
4
+ # Capability: audio=native. Veo accepts dialogue + ambient sound blocks
5
+ # and returns a muxed MP4. Async API: submit → poll (predictLongRunning)
6
+ # → fetch. The orchestrator drives all three subcommands; this script
7
+ # never auto-retries.
8
+ #
9
+ # Contract: scripts/ai-video/lib/adapter-contract.md
10
+ # Provider: top-level <provider id="gemini-veo" kind="video"> in
11
+ # agents/.ai-video.xml.
12
+
13
+ set -euo pipefail
14
+
15
+ # shellcheck source=../lib/adapter-common.sh
16
+ . "$(dirname "$0")/../lib/adapter-common.sh"
17
+
18
+ ADAPTER_ID="gemini-veo"
19
+
20
+ # Submit: read contract JSON from stdin, return {job_id, status:"queued"}.
21
+ aiv_cmd_submit() {
22
+ aiv_assert_dryrun
23
+ aiv_require_cmd curl jq
24
+ aiv_load_provider "${ADAPTER_ID}"
25
+ [ "$(aiv_key_status)" = "present" ] \
26
+ || aiv_die 6 "${ADAPTER_ID}: api key missing in agents/.ai-video.xml"
27
+
28
+ local stdin_json
29
+ stdin_json="$(cat)"
30
+ # Validate required prompt blocks early so a bad blueprint fails
31
+ # before any network call would happen.
32
+ printf '%s' "${stdin_json}" | jq -e '.prompt.subject and .prompt.action' >/dev/null \
33
+ || aiv_die 3 "${ADAPTER_ID}: stdin JSON missing required prompt.subject / prompt.action"
34
+
35
+ aiv_die 9 "${ADAPTER_ID}: live submit not yet wired (predictLongRunning endpoint requires per-key wiring)"
36
+ }
37
+
38
+ # Poll: check long-running operation status. Stub returns "done" so the
39
+ # stitcher path is exercisable end-to-end in dry-run; live mode is
40
+ # wired by the orchestrator once a real job_id exists.
41
+ aiv_cmd_poll() {
42
+ local job_id="${1:-}"
43
+ [ -n "${job_id}" ] || aiv_die 2 "${ADAPTER_ID}: poll <job_id> required"
44
+ aiv_assert_dryrun
45
+ aiv_die 9 "${ADAPTER_ID}: live poll not yet wired (job=${job_id})"
46
+ }
47
+
48
+ # Fetch: download the muxed MP4. Live mode is stubbed; dry-run returns
49
+ # the fixture path with audio_embedded=true.
50
+ aiv_cmd_fetch() {
51
+ local job_id="${1:-}"
52
+ [ -n "${job_id}" ] || aiv_die 2 "${ADAPTER_ID}: fetch <job_id> required"
53
+ aiv_assert_dryrun
54
+ aiv_die 9 "${ADAPTER_ID}: live fetch not yet wired (job=${job_id})"
55
+ }
56
+
57
+ aiv_dispatch "${ADAPTER_ID}" "native" "$@"
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env bash
2
+ # higgsfield.sh — Higgsfield motion-preset video adapter.
3
+ #
4
+ # Capability: per-model. The provider exposes named motion presets
5
+ # (e.g. Mix, Burst, DVD) each with its own audio behaviour. Capability
6
+ # discovery via `capability --preset <name>` so the orchestrator can
7
+ # pick the right mux path.
8
+ #
9
+ # Contract: scripts/ai-video/lib/adapter-contract.md
10
+ # Provider: top-level <provider id="higgsfield" kind="video"> in
11
+ # agents/.ai-video.xml. Preset → motion-choreographer profile mapping
12
+ # is documented in agents/ai-video/prompts/motion-choreography.md
13
+ # (Phase 6).
14
+
15
+ set -euo pipefail
16
+
17
+ # shellcheck source=../lib/adapter-common.sh
18
+ . "$(dirname "$0")/../lib/adapter-common.sh"
19
+
20
+ ADAPTER_ID="higgsfield"
21
+
22
+ # Map preset → audio capability. Conservative defaults; tuning table
23
+ # lives alongside the prompt library so creators can extend without
24
+ # touching this adapter.
25
+ higgsfield_audio_for_preset() {
26
+ case "${1:-}" in
27
+ mix|burst|dvd) printf 'none' ;;
28
+ cinematic|talk) printf 'native' ;;
29
+ *) printf 'none' ;;
30
+ esac
31
+ }
32
+
33
+ # Override capability handling so `capability --preset <name>` answers
34
+ # per-preset before falling through to the generic helper.
35
+ aiv_higgsfield_capability() {
36
+ local preset=""
37
+ while [ "$#" -gt 0 ]; do
38
+ case "$1" in
39
+ --preset) preset="${2:-}"; shift 2 ;;
40
+ *) shift ;;
41
+ esac
42
+ done
43
+ if [ -n "${preset}" ]; then
44
+ printf '{"audio":"%s","preset":"%s"}\n' \
45
+ "$(higgsfield_audio_for_preset "${preset}")" "${preset}"
46
+ return 0
47
+ fi
48
+ printf '{"audio":"per-model","presets":["mix","burst","dvd","cinematic","talk"]}\n'
49
+ }
50
+
51
+ aiv_cmd_submit() {
52
+ aiv_assert_dryrun
53
+ aiv_require_cmd curl jq
54
+ aiv_load_provider "${ADAPTER_ID}"
55
+ [ "$(aiv_key_status)" = "present" ] \
56
+ || aiv_die 6 "${ADAPTER_ID}: api key missing in agents/.ai-video.xml"
57
+ aiv_die 9 "${ADAPTER_ID}: live submit not yet wired"
58
+ }
59
+
60
+ aiv_cmd_poll() {
61
+ local job_id="${1:-}"
62
+ [ -n "${job_id}" ] || aiv_die 2 "${ADAPTER_ID}: poll <job_id> required"
63
+ aiv_assert_dryrun
64
+ aiv_die 9 "${ADAPTER_ID}: live poll not yet wired (job=${job_id})"
65
+ }
66
+
67
+ aiv_cmd_fetch() {
68
+ local job_id="${1:-}"
69
+ [ -n "${job_id}" ] || aiv_die 2 "${ADAPTER_ID}: fetch <job_id> required"
70
+ aiv_assert_dryrun
71
+ aiv_die 9 "${ADAPTER_ID}: live fetch not yet wired (job=${job_id})"
72
+ }
73
+
74
+ # Custom dispatch with capability override; falls back to the common
75
+ # router for every other subcommand.
76
+ sub="${1:-}"
77
+ if [ "${sub}" = "capability" ]; then
78
+ shift
79
+ aiv_higgsfield_capability "$@"
80
+ exit 0
81
+ fi
82
+ aiv_dispatch "${ADAPTER_ID}" "per-model" "$@"
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env bash
2
+ # kling.sh — Kuaishou Kling motion-tuned video generation adapter.
3
+ #
4
+ # Capability: audio=none by default (Kling current generation does not
5
+ # emit native audio); the orchestrator muxes operator-supplied dialogue
6
+ # / ambient at stitch time. Max duration is model-dependent; clip-time
7
+ # clamping happens in motion-choreographer (it tunes the prompt to fit).
8
+ #
9
+ # Contract: scripts/ai-video/lib/adapter-contract.md
10
+ # Provider: top-level <provider id="kling" kind="video"> in
11
+ # agents/.ai-video.xml.
12
+
13
+ set -euo pipefail
14
+
15
+ # shellcheck source=../lib/adapter-common.sh
16
+ . "$(dirname "$0")/../lib/adapter-common.sh"
17
+
18
+ ADAPTER_ID="kling"
19
+ KLING_MAX_DURATION="${KLING_MAX_DURATION:-10}"
20
+
21
+ aiv_cmd_submit() {
22
+ aiv_assert_dryrun
23
+ aiv_require_cmd curl jq
24
+ aiv_load_provider "${ADAPTER_ID}"
25
+ [ "$(aiv_key_status)" = "present" ] \
26
+ || aiv_die 6 "${ADAPTER_ID}: api key missing in agents/.ai-video.xml"
27
+
28
+ local stdin_json duration
29
+ stdin_json="$(cat)"
30
+ duration="$(printf '%s' "${stdin_json}" | jq -r '.duration // empty')"
31
+ if [ -n "${duration}" ]; then
32
+ awk -v d="${duration}" -v m="${KLING_MAX_DURATION}" \
33
+ 'BEGIN { if (d+0 > m+0) exit 1; exit 0 }' \
34
+ || aiv_die 3 "${ADAPTER_ID}: duration ${duration}s exceeds model max ${KLING_MAX_DURATION}s"
35
+ fi
36
+
37
+ aiv_die 9 "${ADAPTER_ID}: live submit not yet wired (max duration ${KLING_MAX_DURATION}s honored)"
38
+ }
39
+
40
+ aiv_cmd_poll() {
41
+ local job_id="${1:-}"
42
+ [ -n "${job_id}" ] || aiv_die 2 "${ADAPTER_ID}: poll <job_id> required"
43
+ aiv_assert_dryrun
44
+ aiv_die 9 "${ADAPTER_ID}: live poll not yet wired (job=${job_id})"
45
+ }
46
+
47
+ aiv_cmd_fetch() {
48
+ local job_id="${1:-}"
49
+ [ -n "${job_id}" ] || aiv_die 2 "${ADAPTER_ID}: fetch <job_id> required"
50
+ aiv_assert_dryrun
51
+ aiv_die 9 "${ADAPTER_ID}: live fetch not yet wired (job=${job_id})"
52
+ }
53
+
54
+ aiv_dispatch "${ADAPTER_ID}" "none" "$@"
@@ -0,0 +1,52 @@
1
+ #!/usr/bin/env bash
2
+ # openai-images.sh — image generation adapter (DALL-E / gpt-image-1).
3
+ #
4
+ # Capability: audio=none (still images only — motion handled by a
5
+ # downstream video adapter). Ref-image and seed reuse are passed
6
+ # through verbatim so character-consistency can lock a face across
7
+ # scenes by reusing the same seed.
8
+ #
9
+ # Contract: scripts/ai-video/lib/adapter-contract.md
10
+ # Provider: top-level <provider id="openai-images" kind="image"> in
11
+ # agents/.ai-video.xml.
12
+
13
+ set -euo pipefail
14
+
15
+ # shellcheck source=../lib/adapter-common.sh
16
+ . "$(dirname "$0")/../lib/adapter-common.sh"
17
+
18
+ ADAPTER_ID="openai-images"
19
+
20
+ aiv_cmd_run() {
21
+ aiv_assert_dryrun
22
+ aiv_require_cmd curl jq
23
+ aiv_load_provider "${ADAPTER_ID}"
24
+ [ "$(aiv_key_status)" = "present" ] \
25
+ || aiv_die 6 "${ADAPTER_ID}: api key missing in agents/.ai-video.xml"
26
+
27
+ # Read contract stdin JSON; compose a single text prompt from the
28
+ # eight prose blocks. Ref-image + seed are passed verbatim.
29
+ local stdin_json prompt seed ref_first
30
+ stdin_json="$(cat)"
31
+ prompt="$(printf '%s' "${stdin_json}" | jq -r '
32
+ [.prompt.style, .prompt.subject, .prompt.environment, .prompt.action,
33
+ .prompt.camera, .prompt.lens, .prompt.lighting, .prompt.mood]
34
+ | map(select(. != null and . != ""))
35
+ | join(". ")
36
+ ')"
37
+ seed="$(printf '%s' "${stdin_json}" | jq -r '.seed // empty')"
38
+ ref_first="$(printf '%s' "${stdin_json}" | jq -r '.ref_images[0] // empty')"
39
+
40
+ # Live mode is implementation-scaffolded: we do NOT yet POST to the
41
+ # OpenAI Images API from inside this adapter. The cost-floor gate
42
+ # (Phase 5 Step 6) refuses live mode unless the operator explicitly
43
+ # confirms in-turn; this branch surfaces a clear stub error so the
44
+ # contract surface stays stable while the live path is wired later.
45
+ aiv_die 9 "${ADAPTER_ID}: live mode not yet wired (prompt=${#prompt} chars, seed=${seed:-unset}, ref=${ref_first:-none})"
46
+ }
47
+
48
+ aiv_cmd_submit() { aiv_cmd_run "$@"; }
49
+ aiv_cmd_fetch() { aiv_cmd_run "$@"; }
50
+ aiv_cmd_poll() { printf '{"status":"done"}\n'; }
51
+
52
+ aiv_dispatch "${ADAPTER_ID}" "none" "$@"
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env bash
2
+ # sora.sh — OpenAI Sora structural-prompt video adapter.
3
+ #
4
+ # Capability: audio=native. Sora-class models produce muxed MP4 with
5
+ # dialogue + ambient sound; we pass the audio block straight through.
6
+ # Structural-prompt path informed by upstream `awesome-sora-prompts`
7
+ # (attribution in agents/ai-video/prompts/cinematic-blueprint.md).
8
+ #
9
+ # Contract: scripts/ai-video/lib/adapter-contract.md
10
+ # Provider: top-level <provider id="sora" kind="video"> in
11
+ # agents/.ai-video.xml.
12
+
13
+ set -euo pipefail
14
+
15
+ # shellcheck source=../lib/adapter-common.sh
16
+ . "$(dirname "$0")/../lib/adapter-common.sh"
17
+
18
+ ADAPTER_ID="sora"
19
+
20
+ aiv_cmd_submit() {
21
+ aiv_assert_dryrun
22
+ aiv_require_cmd curl jq
23
+ aiv_load_provider "${ADAPTER_ID}"
24
+ [ "$(aiv_key_status)" = "present" ] \
25
+ || aiv_die 6 "${ADAPTER_ID}: api key missing in agents/.ai-video.xml"
26
+
27
+ local stdin_json
28
+ stdin_json="$(cat)"
29
+ # Sora's structural-prompt path expects all eight blocks present;
30
+ # fail loud if the blueprint parser dropped any.
31
+ printf '%s' "${stdin_json}" \
32
+ | jq -e '.prompt.style and .prompt.subject and .prompt.environment and
33
+ .prompt.action and .prompt.camera and .prompt.lens and
34
+ .prompt.lighting and .prompt.mood' >/dev/null \
35
+ || aiv_die 3 "${ADAPTER_ID}: stdin JSON missing one or more required prompt blocks"
36
+
37
+ aiv_die 9 "${ADAPTER_ID}: live submit not yet wired"
38
+ }
39
+
40
+ aiv_cmd_poll() {
41
+ local job_id="${1:-}"
42
+ [ -n "${job_id}" ] || aiv_die 2 "${ADAPTER_ID}: poll <job_id> required"
43
+ aiv_assert_dryrun
44
+ aiv_die 9 "${ADAPTER_ID}: live poll not yet wired (job=${job_id})"
45
+ }
46
+
47
+ aiv_cmd_fetch() {
48
+ local job_id="${1:-}"
49
+ [ -n "${job_id}" ] || aiv_die 2 "${ADAPTER_ID}: fetch <job_id> required"
50
+ aiv_assert_dryrun
51
+ aiv_die 9 "${ADAPTER_ID}: live fetch not yet wired (job=${job_id})"
52
+ }
53
+
54
+ aiv_dispatch "${ADAPTER_ID}" "native" "$@"
@@ -0,0 +1,116 @@
1
+ #!/usr/bin/env bash
2
+ # adapter-common.sh — shared boilerplate sourced by every adapter under
3
+ # scripts/ai-video/adapters/. Keeps individual adapters thin and makes
4
+ # the contract surface (subcommand dispatch, dry-run plumbing, stdout
5
+ # shape) uniform across providers.
6
+ #
7
+ # Sourced; never executed directly. Strict-mode flags are the caller's
8
+ # responsibility (every adapter starts with `set -euo pipefail`).
9
+
10
+ if [ -n "${AIV_ADAPTER_COMMON_LOADED:-}" ]; then
11
+ return 0 2>/dev/null || exit 0
12
+ fi
13
+ AIV_ADAPTER_COMMON_LOADED=1
14
+
15
+ # Resolve the lib dir from this file's location so adapters can source
16
+ # us via the canonical `$(dirname "$0")/../lib/...` path.
17
+ _aiv_lib_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
18
+ # shellcheck source=/dev/null
19
+ . "${_aiv_lib_dir}/redact.sh"
20
+ # shellcheck source=/dev/null
21
+ . "${_aiv_lib_dir}/load-config.sh"
22
+
23
+ AIV_LIB_DIR="${_aiv_lib_dir}"
24
+ AIV_FIXTURE_ROOT="${_aiv_lib_dir}/fixtures"
25
+ export AIV_LIB_DIR AIV_FIXTURE_ROOT
26
+
27
+ # aiv_die <exit-code> <message> — write redacted message to stderr.
28
+ aiv_die() {
29
+ local code="${1:-1}"; shift || true
30
+ printf 'adapter: %s\n' "$*" | aiv_redact_stream >&2
31
+ exit "${code}"
32
+ }
33
+
34
+ # aiv_require_cmd <cmd> [<cmd> ...] — fail fast on missing dependency.
35
+ aiv_require_cmd() {
36
+ local cmd
37
+ for cmd in "$@"; do
38
+ command -v "${cmd}" >/dev/null 2>&1 \
39
+ || aiv_die 3 "required tool not found: ${cmd}"
40
+ done
41
+ }
42
+
43
+ # aiv_emit_dry_run <adapter-id> — print contract-shaped stdout JSON
44
+ # pointing at the adapter's fixture directory. Used by every adapter's
45
+ # `dry-run` subcommand.
46
+ aiv_emit_dry_run() {
47
+ local adapter="${1:-}"
48
+ [ -n "${adapter}" ] || aiv_die 3 "aiv_emit_dry_run: adapter id required"
49
+ local fixture_dir="${AIV_FIXTURE_ROOT}/${adapter}"
50
+ local result="${fixture_dir}/result.json"
51
+ if [ ! -f "${result}" ]; then
52
+ aiv_die 3 "fixture missing: ${result}"
53
+ fi
54
+ cat "${result}"
55
+ }
56
+
57
+ # aiv_capability <flag> — print the capability JSON for `--help`-style
58
+ # discovery: `{"audio": "native|none|per-model"}`.
59
+ aiv_capability() {
60
+ local flag="${1:-none}"
61
+ printf '{"audio":"%s"}\n' "${flag}"
62
+ }
63
+
64
+ # aiv_assert_dryrun — refuse to run a network path unless the caller
65
+ # explicitly opted in (AIV_DRYRUN=false set in this turn).
66
+ aiv_assert_dryrun() {
67
+ case "${AIV_DRYRUN:-true}" in
68
+ false|FALSE|0|no|NO) return 0 ;;
69
+ *) aiv_die 4 "live call refused: AIV_DRYRUN=${AIV_DRYRUN:-true}; use dry-run subcommand or set AIV_DRYRUN=false" ;;
70
+ esac
71
+ }
72
+
73
+ # aiv_dispatch <adapter-id> <capability> "$@" — generic subcommand router.
74
+ # Adapters override individual subcommands by defining bash functions
75
+ # named `aiv_cmd_submit` / `aiv_cmd_poll` / `aiv_cmd_fetch` / `aiv_cmd_run`
76
+ # BEFORE calling aiv_dispatch. Anything not overridden falls through to
77
+ # a stub that exits non-zero with a clear message.
78
+ aiv_dispatch() {
79
+ local adapter="${1:-}"; shift || true
80
+ local cap="${1:-none}"; shift || true
81
+ local sub="${1:-}"; shift || true
82
+ case "${sub}" in
83
+ capability)
84
+ aiv_capability "${cap}"
85
+ ;;
86
+ dry-run)
87
+ aiv_emit_dry_run "${adapter}"
88
+ ;;
89
+ submit)
90
+ declare -F aiv_cmd_submit >/dev/null \
91
+ && aiv_cmd_submit "$@" \
92
+ || aiv_die 5 "${adapter}: submit not implemented"
93
+ ;;
94
+ poll)
95
+ declare -F aiv_cmd_poll >/dev/null \
96
+ && aiv_cmd_poll "$@" \
97
+ || aiv_die 5 "${adapter}: poll not implemented"
98
+ ;;
99
+ fetch)
100
+ declare -F aiv_cmd_fetch >/dev/null \
101
+ && aiv_cmd_fetch "$@" \
102
+ || aiv_die 5 "${adapter}: fetch not implemented"
103
+ ;;
104
+ run)
105
+ declare -F aiv_cmd_run >/dev/null \
106
+ && aiv_cmd_run "$@" \
107
+ || aiv_die 5 "${adapter}: run not implemented"
108
+ ;;
109
+ "")
110
+ aiv_die 2 "${adapter}: subcommand required (capability|dry-run|submit|poll|fetch|run)"
111
+ ;;
112
+ *)
113
+ aiv_die 2 "${adapter}: unknown subcommand '${sub}'"
114
+ ;;
115
+ esac
116
+ }