@event4u/agent-config 2.23.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.
- package/.agent-src/commands/video/from-script.md +123 -0
- package/.agent-src/commands/video/scene.md +92 -0
- package/.agent-src/commands/video/stitch.md +83 -0
- package/.agent-src/commands/video/storyboard.md +95 -0
- package/.agent-src/commands/video.md +59 -0
- package/.agent-src/personas/README.md +3 -0
- package/.agent-src/personas/ai-video-technical-director.md +81 -0
- package/.agent-src/personas/hollywood-director.md +99 -0
- package/.agent-src/personas/pixar-storyboard-artist.md +98 -0
- package/.agent-src/skills/character-consistency/SKILL.md +120 -0
- package/.agent-src/skills/motion-choreographer/SKILL.md +149 -0
- package/.agent-src/skills/pixar-storyteller/SKILL.md +107 -0
- package/.agent-src/skills/scene-expander/SKILL.md +122 -0
- package/.agent-src/skills/scene-expander/scene-blueprint.schema.yaml +108 -0
- package/.agent-src/skills/subagent-orchestration/SKILL.md +17 -15
- package/.agent-src/skills/video-director/SKILL.md +113 -0
- package/.agent-src/templates/agent-settings.md +19 -0
- package/.agent-src/templates/agents/agent-project-settings.example.yml +1 -1
- package/.claude-plugin/marketplace.json +11 -1
- package/CHANGELOG.md +22 -0
- package/README.md +4 -4
- package/config/agent-settings.template.yml +28 -0
- package/docs/adrs/caveman/0001-default-off-until-bench.md +2 -2
- package/docs/adrs/cost/0001-hard-stop-hook.md +1 -1
- package/docs/adrs/smoke/0001-per-tier-smoke-scripts.md +2 -2
- package/docs/architecture.md +2 -2
- package/docs/catalog.md +14 -4
- package/docs/contracts/command-clusters.md +1 -0
- package/docs/contracts/compression-default-kill-criterion.md +1 -1
- package/docs/contracts/file-ownership-matrix.json +337 -0
- package/docs/getting-started.md +1 -1
- package/docs/parity/ruflo.md +3 -3
- package/package.json +1 -1
- package/scripts/ai-video/adapters/gemini-veo.sh +57 -0
- package/scripts/ai-video/adapters/higgsfield.sh +82 -0
- package/scripts/ai-video/adapters/kling.sh +54 -0
- package/scripts/ai-video/adapters/openai-images.sh +52 -0
- package/scripts/ai-video/adapters/sora.sh +54 -0
- package/scripts/ai-video/lib/adapter-common.sh +116 -0
- package/scripts/ai-video/lib/adapter-contract.md +163 -0
- package/scripts/ai-video/lib/fixtures/gemini-veo/result.json +1 -0
- package/scripts/ai-video/lib/fixtures/gemini-veo/scene-0001.mp4 +1 -0
- package/scripts/ai-video/lib/fixtures/higgsfield/result.json +1 -0
- package/scripts/ai-video/lib/fixtures/higgsfield/scene-0001.mp4 +1 -0
- package/scripts/ai-video/lib/fixtures/kling/result.json +1 -0
- package/scripts/ai-video/lib/fixtures/kling/scene-0001.mp4 +1 -0
- package/scripts/ai-video/lib/fixtures/openai-images/result.json +1 -0
- package/scripts/ai-video/lib/fixtures/openai-images/scene-0001.png +3 -0
- package/scripts/ai-video/lib/fixtures/sora/result.json +1 -0
- package/scripts/ai-video/lib/fixtures/sora/scene-0001.mp4 +1 -0
- package/scripts/ai-video/lib/load-config.sh +140 -0
- package/scripts/ai-video/lib/operator-pick.sh +119 -0
- package/scripts/ai-video/lib/parse-blueprint.sh +122 -0
- package/scripts/ai-video/lib/redact.sh +85 -0
- package/scripts/ai-video/lib/validate-deps.sh +132 -0
- package/scripts/ai-video/stitch.sh +154 -0
- package/scripts/ai-video/test-pipeline.sh +169 -0
- package/scripts/schemas/command.schema.json +8 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# test-pipeline.sh — offline smoke test for /video:* against
|
|
3
|
+
# agents/ai-video/examples/banana-arc/. Dry-run only; no network.
|
|
4
|
+
#
|
|
5
|
+
# Asserts (per agents/roadmaps/ai-video-pipeline.md Phase 6 Step 3):
|
|
6
|
+
# 1. parse-blueprint.sh output matches the committed expected.json
|
|
7
|
+
# per scene (3 scenes, 3 tiers).
|
|
8
|
+
# 2. character.json descriptor tokens (silhouette, palette, wardrobe,
|
|
9
|
+
# prop) appear verbatim in each scene's prompt.subject — the
|
|
10
|
+
# load-bearing character-lock substring assertion.
|
|
11
|
+
# 3. audio.* branching is correct: scene 2 → enable_native_audio=true,
|
|
12
|
+
# scenes 1+3 → false.
|
|
13
|
+
# 4. native-audio-capable adapter (gemini-veo) advertises capability
|
|
14
|
+
# audio=native; non-audio adapter (openai-images) advertises
|
|
15
|
+
# audio=none; stitch.sh sees audio_embedded per scene.
|
|
16
|
+
# 5. stitch.sh dry-run returns the committed manifest's stitch_output
|
|
17
|
+
# path without invoking ffmpeg or any network.
|
|
18
|
+
# 6. visual regression: each scene's locked.png is non-empty + has
|
|
19
|
+
# PNG magic; pairwise NCC ≥ 0.95 when `compare` is available.
|
|
20
|
+
# When unavailable, asserts byte-identity (the three frames are
|
|
21
|
+
# committed identical for the offline path).
|
|
22
|
+
#
|
|
23
|
+
# Exit 0 = all assertions pass; 1 = at least one failure (counted +
|
|
24
|
+
# summarized at the end).
|
|
25
|
+
|
|
26
|
+
set -uo pipefail
|
|
27
|
+
|
|
28
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
29
|
+
ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
30
|
+
PROJECT="$ROOT/agents/ai-video/examples/banana-arc"
|
|
31
|
+
|
|
32
|
+
PASS=0
|
|
33
|
+
FAIL=0
|
|
34
|
+
FAILS=""
|
|
35
|
+
|
|
36
|
+
ok() { PASS=$((PASS+1)); printf ' ✅ %s\n' "$1"; }
|
|
37
|
+
fail() { FAIL=$((FAIL+1)); FAILS="$FAILS\n ❌ $1"; printf ' ❌ %s\n' "$1"; }
|
|
38
|
+
|
|
39
|
+
require() {
|
|
40
|
+
if command -v "$1" >/dev/null 2>&1; then return 0; fi
|
|
41
|
+
fail "required tool missing: $1"
|
|
42
|
+
return 1
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
require jq || exit 1
|
|
46
|
+
|
|
47
|
+
printf '\n== test-pipeline.sh — banana-arc golden run (offline) ==\n\n'
|
|
48
|
+
|
|
49
|
+
# ---------------------------------------------------------------- 1
|
|
50
|
+
printf '[1/6] parse-blueprint vs. expected.json\n'
|
|
51
|
+
SCENES="01-simple 02-dialogue-native-audio 03-edge-duration"
|
|
52
|
+
for s in $SCENES; do
|
|
53
|
+
actual="$(bash "$ROOT/scripts/ai-video/lib/parse-blueprint.sh" "$PROJECT/scenes/$s/blueprint.txt" 2>/dev/null \
|
|
54
|
+
| jq -S . 2>/dev/null || true)"
|
|
55
|
+
expected="$(jq -S . "$PROJECT/scenes/$s/expected.json" 2>/dev/null || true)"
|
|
56
|
+
if [ -z "$actual" ]; then
|
|
57
|
+
fail "$s: parse-blueprint produced no output"
|
|
58
|
+
elif [ "$actual" = "$expected" ]; then
|
|
59
|
+
ok "$s: parse-blueprint matches expected.json"
|
|
60
|
+
else
|
|
61
|
+
fail "$s: parse-blueprint mismatch (diff actual vs. expected.json)"
|
|
62
|
+
fi
|
|
63
|
+
done
|
|
64
|
+
|
|
65
|
+
# ---------------------------------------------------------------- 2
|
|
66
|
+
printf '\n[2/6] character.json descriptors verbatim in prompt.subject\n'
|
|
67
|
+
SILHOUETTE="$(jq -r '.characters[0].silhouette' "$PROJECT/character.json")"
|
|
68
|
+
PALETTE="$(jq -r '.characters[0].palette' "$PROJECT/character.json")"
|
|
69
|
+
WARDROBE="$(jq -r '.characters[0].wardrobe' "$PROJECT/character.json")"
|
|
70
|
+
PROP="$(jq -r '.characters[0].prop' "$PROJECT/character.json")"
|
|
71
|
+
|
|
72
|
+
for s in $SCENES; do
|
|
73
|
+
subj="$(jq -r '.prompt.subject' "$PROJECT/scenes/$s/expected.json")"
|
|
74
|
+
miss=""
|
|
75
|
+
case "$subj" in *"$SILHOUETTE"*) :;; *) miss="$miss silhouette";; esac
|
|
76
|
+
case "$subj" in *"$PALETTE"*) :;; *) miss="$miss palette";; esac
|
|
77
|
+
case "$subj" in *"$WARDROBE"*) :;; *) miss="$miss wardrobe";; esac
|
|
78
|
+
case "$subj" in *"$PROP"*) :;; *) miss="$miss prop";; esac
|
|
79
|
+
if [ -z "$miss" ]; then
|
|
80
|
+
ok "$s: silhouette + palette + wardrobe + prop verbatim in prompt.subject"
|
|
81
|
+
else
|
|
82
|
+
fail "$s: missing verbatim tokens in prompt.subject:$miss"
|
|
83
|
+
fi
|
|
84
|
+
done
|
|
85
|
+
|
|
86
|
+
# ---------------------------------------------------------------- 3
|
|
87
|
+
printf '\n[3/6] audio.* branching matches manifest\n'
|
|
88
|
+
for entry in 01-simple:false 02-dialogue-native-audio:true 03-edge-duration:false; do
|
|
89
|
+
s="${entry%%:*}"
|
|
90
|
+
want="${entry##*:}"
|
|
91
|
+
got="$(jq -r '.audio.enable_native_audio' "$PROJECT/scenes/$s/expected.json")"
|
|
92
|
+
manifest_got="$(jq -r --arg id "$s" '.scenes[] | select(.id==$id) | .audio_embedded' "$PROJECT/manifest.json")"
|
|
93
|
+
if [ "$got" = "$want" ] && [ "$manifest_got" = "$want" ]; then
|
|
94
|
+
ok "$s: enable_native_audio=$got, manifest.audio_embedded=$manifest_got"
|
|
95
|
+
else
|
|
96
|
+
fail "$s: audio branching drift (expected=$want, blueprint=$got, manifest=$manifest_got)"
|
|
97
|
+
fi
|
|
98
|
+
done
|
|
99
|
+
|
|
100
|
+
# ---------------------------------------------------------------- 4
|
|
101
|
+
printf '\n[4/6] adapter capability declarations\n'
|
|
102
|
+
declare_caps() {
|
|
103
|
+
local adapter="$1"; local expected="$2"
|
|
104
|
+
local out got
|
|
105
|
+
out="$(AIV_DRYRUN=true bash "$ROOT/scripts/ai-video/adapters/$adapter.sh" capability 2>/dev/null || true)"
|
|
106
|
+
got="$(printf '%s' "$out" | jq -r '.audio // empty' 2>/dev/null || true)"
|
|
107
|
+
if [ "$got" = "$expected" ]; then
|
|
108
|
+
ok "$adapter: capability.audio=$got"
|
|
109
|
+
else
|
|
110
|
+
fail "$adapter: capability mismatch (want audio=$expected, got: ${got:-<unparseable: $out>})"
|
|
111
|
+
fi
|
|
112
|
+
}
|
|
113
|
+
declare_caps gemini-veo "native"
|
|
114
|
+
declare_caps openai-images "none"
|
|
115
|
+
declare_caps sora "native"
|
|
116
|
+
declare_caps kling "none"
|
|
117
|
+
|
|
118
|
+
# ---------------------------------------------------------------- 5
|
|
119
|
+
printf '\n[5/6] stitch.sh dry-run returns manifest output path\n'
|
|
120
|
+
STITCH_OUT="$(jq -r '.stitch_output' "$PROJECT/manifest.json")"
|
|
121
|
+
stitch_log="$(AIV_DRYRUN=true bash "$ROOT/scripts/ai-video/stitch.sh" \
|
|
122
|
+
"$PROJECT/manifest.json" "$PROJECT/$STITCH_OUT" 2>&1 || true)"
|
|
123
|
+
case "$stitch_log" in
|
|
124
|
+
*"$STITCH_OUT"*) ok "stitch.sh dry-run referenced $STITCH_OUT";;
|
|
125
|
+
*) fail "stitch.sh dry-run did not reference $STITCH_OUT (log: $stitch_log)";;
|
|
126
|
+
esac
|
|
127
|
+
|
|
128
|
+
# ---------------------------------------------------------------- 6
|
|
129
|
+
printf '\n[6/6] visual regression (locked.png pairwise)\n'
|
|
130
|
+
PNG_MAGIC="$(printf '\x89PNG\r\n\x1a\n')"
|
|
131
|
+
prev=""
|
|
132
|
+
have_compare=0
|
|
133
|
+
command -v compare >/dev/null 2>&1 && have_compare=1
|
|
134
|
+
for s in $SCENES; do
|
|
135
|
+
f="$PROJECT/scenes/$s/fixtures/frames/locked.png"
|
|
136
|
+
if [ ! -s "$f" ]; then
|
|
137
|
+
fail "$s: locked.png missing or empty"
|
|
138
|
+
continue
|
|
139
|
+
fi
|
|
140
|
+
head -c 8 "$f" | od -An -c | tr -d ' \n' | grep -q '211PNG' \
|
|
141
|
+
&& ok "$s: locked.png is a valid PNG ($(wc -c < "$f" | tr -d ' ') bytes)" \
|
|
142
|
+
|| fail "$s: locked.png lacks PNG magic"
|
|
143
|
+
if [ -n "$prev" ]; then
|
|
144
|
+
if [ "$have_compare" -eq 1 ]; then
|
|
145
|
+
ncc="$(compare -metric NCC "$prev" "$f" null: 2>&1 || true)"
|
|
146
|
+
awk_ok="$(awk -v v="$ncc" 'BEGIN { exit !(v+0 >= 0.95) }' && echo yes || echo no)"
|
|
147
|
+
if [ "$awk_ok" = "yes" ]; then
|
|
148
|
+
ok "$s: NCC vs. previous = $ncc (≥ 0.95)"
|
|
149
|
+
else
|
|
150
|
+
fail "$s: NCC vs. previous = $ncc (< 0.95)"
|
|
151
|
+
fi
|
|
152
|
+
else
|
|
153
|
+
if cmp -s "$prev" "$f"; then
|
|
154
|
+
ok "$s: byte-identical to previous (compare unavailable; offline fallback)"
|
|
155
|
+
else
|
|
156
|
+
fail "$s: differs from previous frame and compare is unavailable"
|
|
157
|
+
fi
|
|
158
|
+
fi
|
|
159
|
+
fi
|
|
160
|
+
prev="$f"
|
|
161
|
+
done
|
|
162
|
+
|
|
163
|
+
# ----------------------------------------------------------------
|
|
164
|
+
printf '\n----------------\nresult: %d passed · %d failed\n' "$PASS" "$FAIL"
|
|
165
|
+
if [ "$FAIL" -gt 0 ]; then
|
|
166
|
+
printf '%b\n' "$FAILS"
|
|
167
|
+
exit 1
|
|
168
|
+
fi
|
|
169
|
+
exit 0
|
|
@@ -34,6 +34,14 @@
|
|
|
34
34
|
"pattern": "^[a-z][a-z0-9-]*$"
|
|
35
35
|
}
|
|
36
36
|
},
|
|
37
|
+
"personas": {
|
|
38
|
+
"type": "array",
|
|
39
|
+
"items": {
|
|
40
|
+
"type": "string",
|
|
41
|
+
"pattern": "^[a-z][a-z0-9-]*$"
|
|
42
|
+
},
|
|
43
|
+
"description": "Personas this command invokes (see .agent-src.uncompressed/personas/). Mirrors `skills:`; each entry must match a persona slug."
|
|
44
|
+
},
|
|
37
45
|
"cluster": {
|
|
38
46
|
"type": "string",
|
|
39
47
|
"pattern": "^[a-z][a-z0-9-]*$",
|