@agentmedia/schema 0.3.0 → 0.4.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 (54) hide show
  1. package/.memory/cursor.json +3 -0
  2. package/.memory/memories.json +1 -0
  3. package/.memory/project.json +5 -0
  4. package/CLAUDE.md +7 -0
  5. package/dist/__tests__/character-pipeline.test.d.ts +2 -0
  6. package/dist/__tests__/character-pipeline.test.d.ts.map +1 -0
  7. package/dist/__tests__/character-pipeline.test.js +296 -0
  8. package/dist/__tests__/character-pipeline.test.js.map +1 -0
  9. package/dist/__tests__/text-to-video.test.d.ts +2 -0
  10. package/dist/__tests__/text-to-video.test.d.ts.map +1 -0
  11. package/dist/__tests__/text-to-video.test.js +67 -0
  12. package/dist/__tests__/text-to-video.test.js.map +1 -0
  13. package/dist/generators.d.ts +67 -0
  14. package/dist/generators.d.ts.map +1 -1
  15. package/dist/generators.js +11 -1
  16. package/dist/generators.js.map +1 -1
  17. package/dist/v2/character.d.ts +32 -0
  18. package/dist/v2/character.d.ts.map +1 -0
  19. package/dist/v2/character.js +29 -0
  20. package/dist/v2/character.js.map +1 -0
  21. package/dist/v2/generators.d.ts +69 -0
  22. package/dist/v2/generators.d.ts.map +1 -0
  23. package/dist/v2/generators.js +105 -0
  24. package/dist/v2/generators.js.map +1 -0
  25. package/dist/v2/index.d.ts +13 -0
  26. package/dist/v2/index.d.ts.map +1 -0
  27. package/dist/v2/index.js +14 -0
  28. package/dist/v2/index.js.map +1 -0
  29. package/dist/v2/selfie.d.ts +78 -0
  30. package/dist/v2/selfie.d.ts.map +1 -0
  31. package/dist/v2/selfie.js +87 -0
  32. package/dist/v2/selfie.js.map +1 -0
  33. package/dist/v2/subtitle.d.ts +31 -0
  34. package/dist/v2/subtitle.d.ts.map +1 -0
  35. package/dist/v2/subtitle.js +53 -0
  36. package/dist/v2/subtitle.js.map +1 -0
  37. package/dist/video.d.ts +171 -0
  38. package/dist/video.d.ts.map +1 -1
  39. package/dist/video.js +89 -0
  40. package/dist/video.js.map +1 -1
  41. package/package.json +6 -1
  42. package/scripts/generate-v2-docs.ts +328 -0
  43. package/src/__tests__/character-pipeline.test.ts +356 -0
  44. package/src/__tests__/text-to-video.test.ts +79 -0
  45. package/src/generators.ts +12 -0
  46. package/src/v2/character.ts +39 -0
  47. package/src/v2/generators.ts +186 -0
  48. package/src/v2/index.ts +15 -0
  49. package/src/v2/selfie.ts +103 -0
  50. package/src/v2/subtitle.ts +62 -0
  51. package/src/video.ts +164 -0
  52. package/.turbo/turbo-build.log +0 -4
  53. package/.turbo/turbo-test.log +0 -14
  54. package/.turbo/turbo-typecheck.log +0 -4
@@ -0,0 +1,3 @@
1
+ {
2
+ "c3784218-2e4c-49fe-80c7-7c0c22a22622": 7988
3
+ }
@@ -0,0 +1 @@
1
+ []
@@ -0,0 +1,5 @@
1
+ {
2
+ "name": "schema",
3
+ "description": "",
4
+ "extractionCount": 3
5
+ }
package/CLAUDE.md ADDED
@@ -0,0 +1,7 @@
1
+ <!-- MEMORY:START -->
2
+ # schema
3
+
4
+ _Last updated: 2026-05-22 | 0 active memories, 0 total_
5
+
6
+ _For deeper context, use memory_search, memory_related, or memory_ask tools._
7
+ <!-- MEMORY:END -->
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=character-pipeline.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"character-pipeline.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/character-pipeline.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,296 @@
1
+ // Copyright 2026 agent-media contributors. Apache-2.0 license.
2
+ /**
3
+ * Validation parity tests for the 3-step Content Machine character
4
+ * pipeline schemas:
5
+ * - CharacterSheetSchema (POST /v1/character/sheet-generate)
6
+ * - CharacterStoryboardSchema (POST /v1/character/storyboard-generate)
7
+ * - StoryboardSuggestSchema (POST /v1/character/storyboard-suggest)
8
+ * - CharacterVideoSchema (POST /v1/generate/character_video)
9
+ *
10
+ * These exercise mutually-exclusive sources, length bounds, enum and
11
+ * UUID validation, and default application — exactly the constraints
12
+ * the api-v2 routes also enforce. If a route's schema diverges from
13
+ * server-side validation in the future, this is where it gets caught
14
+ * before shipping.
15
+ */
16
+ import { describe, it, expect } from 'vitest';
17
+ import { CharacterSheetSchema, CharacterStoryboardSchema, StoryboardSuggestSchema, CharacterVideoSchema, } from '../video.js';
18
+ const SHEET_URL = 'https://pub-16e2ed8f6be84691845e91436920ce0a.r2.dev/x/character-sheet.png';
19
+ const STORYBOARD_URL = 'https://pub-16e2ed8f6be84691845e91436920ce0a.r2.dev/x/storyboard.png';
20
+ const REF_URL = 'https://example.com/portrait.png';
21
+ const SESSION = '00000000-0000-4000-8000-000000000000';
22
+ // ── CharacterSheetSchema ─────────────────────────────────────────────────────
23
+ describe('CharacterSheetSchema', () => {
24
+ it('accepts description-only', () => {
25
+ const r = CharacterSheetSchema.safeParse({ description: 'Marco the chef' });
26
+ expect(r.success).toBe(true);
27
+ });
28
+ it('accepts actor_slug-only', () => {
29
+ const r = CharacterSheetSchema.safeParse({ actor_slug: 'mei' });
30
+ expect(r.success).toBe(true);
31
+ });
32
+ it('accepts reference_image_url-only', () => {
33
+ const r = CharacterSheetSchema.safeParse({ reference_image_url: REF_URL });
34
+ expect(r.success).toBe(true);
35
+ });
36
+ it('accepts description + actor_slug (description adds context)', () => {
37
+ const r = CharacterSheetSchema.safeParse({
38
+ description: 'Marco the chef',
39
+ actor_slug: 'mei',
40
+ });
41
+ expect(r.success).toBe(true);
42
+ });
43
+ it('accepts description + reference_image_url', () => {
44
+ const r = CharacterSheetSchema.safeParse({
45
+ description: 'Marco the chef',
46
+ reference_image_url: REF_URL,
47
+ });
48
+ expect(r.success).toBe(true);
49
+ });
50
+ it('accepts session_id alongside any source', () => {
51
+ const r = CharacterSheetSchema.safeParse({
52
+ description: 'Marco',
53
+ session_id: SESSION,
54
+ });
55
+ expect(r.success).toBe(true);
56
+ });
57
+ it('rejects empty body (no source)', () => {
58
+ const r = CharacterSheetSchema.safeParse({});
59
+ expect(r.success).toBe(false);
60
+ });
61
+ it('rejects actor_slug + reference_image_url (mutex)', () => {
62
+ const r = CharacterSheetSchema.safeParse({
63
+ actor_slug: 'mei',
64
+ reference_image_url: REF_URL,
65
+ });
66
+ expect(r.success).toBe(false);
67
+ if (!r.success) {
68
+ expect(JSON.stringify(r.error.issues)).toMatch(/mutually exclusive/i);
69
+ }
70
+ });
71
+ it('rejects description shorter than 3 chars', () => {
72
+ const r = CharacterSheetSchema.safeParse({ description: 'ab' });
73
+ expect(r.success).toBe(false);
74
+ });
75
+ it('rejects description longer than 400 chars', () => {
76
+ const r = CharacterSheetSchema.safeParse({ description: 'x'.repeat(401) });
77
+ expect(r.success).toBe(false);
78
+ });
79
+ it('rejects non-URL reference_image_url', () => {
80
+ const r = CharacterSheetSchema.safeParse({ reference_image_url: 'not-a-url' });
81
+ expect(r.success).toBe(false);
82
+ });
83
+ it('rejects non-uuid session_id', () => {
84
+ const r = CharacterSheetSchema.safeParse({ description: 'Marco', session_id: 'nope' });
85
+ expect(r.success).toBe(false);
86
+ });
87
+ });
88
+ // ── CharacterStoryboardSchema ────────────────────────────────────────────────
89
+ describe('CharacterStoryboardSchema', () => {
90
+ const ok = (extra) => ({
91
+ character_sheet_url: SHEET_URL,
92
+ ...extra,
93
+ });
94
+ it('accepts beats[]', () => {
95
+ const r = CharacterStoryboardSchema.safeParse(ok({
96
+ beats: ['walks in', 'takes a bite', 'thumbs up'],
97
+ }));
98
+ expect(r.success).toBe(true);
99
+ });
100
+ it('accepts script', () => {
101
+ const r = CharacterStoryboardSchema.safeParse(ok({
102
+ script: 'Marco walks in, takes a bite, gives a thumbs up.',
103
+ }));
104
+ expect(r.success).toBe(true);
105
+ });
106
+ it('applies default ratio 9:16', () => {
107
+ const r = CharacterStoryboardSchema.parse(ok({
108
+ beats: ['a', 'bb', 'ccc'].map((s) => s.repeat(3)),
109
+ }));
110
+ expect(r.ratio).toBe('9:16');
111
+ });
112
+ it('accepts ratio overrides', () => {
113
+ for (const ratio of ['9:16', '16:9', '1:1']) {
114
+ const r = CharacterStoryboardSchema.safeParse(ok({
115
+ script: 'enough chars to pass min length',
116
+ ratio,
117
+ }));
118
+ expect(r.success).toBe(true);
119
+ }
120
+ });
121
+ it('rejects body with both beats and script (mutex)', () => {
122
+ const r = CharacterStoryboardSchema.safeParse(ok({
123
+ beats: ['walks in', 'takes a bite', 'thumbs up'],
124
+ script: 'a script over ten chars',
125
+ }));
126
+ expect(r.success).toBe(false);
127
+ if (!r.success) {
128
+ expect(JSON.stringify(r.error.issues)).toMatch(/exactly one/i);
129
+ }
130
+ });
131
+ it('rejects body with neither beats nor script', () => {
132
+ const r = CharacterStoryboardSchema.safeParse(ok({}));
133
+ expect(r.success).toBe(false);
134
+ });
135
+ it('rejects beats with fewer than 3 entries', () => {
136
+ const r = CharacterStoryboardSchema.safeParse(ok({ beats: ['a', 'bb'] }));
137
+ expect(r.success).toBe(false);
138
+ });
139
+ it('rejects beats with more than 10 entries', () => {
140
+ const r = CharacterStoryboardSchema.safeParse(ok({
141
+ beats: Array.from({ length: 11 }, (_, i) => `beat ${i}`),
142
+ }));
143
+ expect(r.success).toBe(false);
144
+ });
145
+ it('rejects beat shorter than 3 chars', () => {
146
+ const r = CharacterStoryboardSchema.safeParse(ok({
147
+ beats: ['ab', 'walks in', 'thumbs up'],
148
+ }));
149
+ expect(r.success).toBe(false);
150
+ });
151
+ it('rejects script shorter than 10 chars', () => {
152
+ const r = CharacterStoryboardSchema.safeParse(ok({ script: 'too short' }));
153
+ expect(r.success).toBe(false);
154
+ });
155
+ it('rejects script longer than 1500 chars', () => {
156
+ const r = CharacterStoryboardSchema.safeParse(ok({ script: 'x'.repeat(1501) }));
157
+ expect(r.success).toBe(false);
158
+ });
159
+ it('rejects bad ratio', () => {
160
+ const r = CharacterStoryboardSchema.safeParse(ok({
161
+ script: 'a script over ten chars',
162
+ ratio: '4:3',
163
+ }));
164
+ expect(r.success).toBe(false);
165
+ });
166
+ it('rejects missing character_sheet_url', () => {
167
+ const r = CharacterStoryboardSchema.safeParse({
168
+ script: 'a script over ten chars',
169
+ });
170
+ expect(r.success).toBe(false);
171
+ });
172
+ it('rejects non-uuid session_id', () => {
173
+ const r = CharacterStoryboardSchema.safeParse(ok({
174
+ script: 'a script over ten chars',
175
+ session_id: 'nope',
176
+ }));
177
+ expect(r.success).toBe(false);
178
+ });
179
+ });
180
+ // ── StoryboardSuggestSchema ──────────────────────────────────────────────────
181
+ describe('StoryboardSuggestSchema', () => {
182
+ it('accepts actor_slug only', () => {
183
+ const r = StoryboardSuggestSchema.safeParse({ actor_slug: 'mei' });
184
+ expect(r.success).toBe(true);
185
+ });
186
+ it('accepts character_description only', () => {
187
+ const r = StoryboardSuggestSchema.safeParse({
188
+ character_description: 'Marco the Italian chef',
189
+ });
190
+ expect(r.success).toBe(true);
191
+ });
192
+ it('applies default duration=10 and n_panels=6', () => {
193
+ const r = StoryboardSuggestSchema.parse({ actor_slug: 'mei' });
194
+ expect(r.duration).toBe(10);
195
+ expect(r.n_panels).toBe(6);
196
+ });
197
+ it('accepts vibe + duration + n_panels overrides', () => {
198
+ const r = StoryboardSuggestSchema.safeParse({
199
+ actor_slug: 'mei', vibe: 'wholesome', duration: 5, n_panels: 4,
200
+ });
201
+ expect(r.success).toBe(true);
202
+ });
203
+ it('rejects both actor_slug and character_description (mutex)', () => {
204
+ const r = StoryboardSuggestSchema.safeParse({
205
+ actor_slug: 'mei', character_description: 'Marco',
206
+ });
207
+ expect(r.success).toBe(false);
208
+ });
209
+ it('rejects neither', () => {
210
+ const r = StoryboardSuggestSchema.safeParse({});
211
+ expect(r.success).toBe(false);
212
+ });
213
+ it('rejects character_description longer than 200 chars', () => {
214
+ const r = StoryboardSuggestSchema.safeParse({
215
+ character_description: 'x'.repeat(201),
216
+ });
217
+ expect(r.success).toBe(false);
218
+ });
219
+ it('rejects duration not in {5, 10}', () => {
220
+ const r = StoryboardSuggestSchema.safeParse({ actor_slug: 'mei', duration: 7 });
221
+ expect(r.success).toBe(false);
222
+ });
223
+ it('rejects n_panels < 4', () => {
224
+ const r = StoryboardSuggestSchema.safeParse({ actor_slug: 'mei', n_panels: 3 });
225
+ expect(r.success).toBe(false);
226
+ });
227
+ it('rejects n_panels > 10', () => {
228
+ const r = StoryboardSuggestSchema.safeParse({ actor_slug: 'mei', n_panels: 11 });
229
+ expect(r.success).toBe(false);
230
+ });
231
+ });
232
+ // ── CharacterVideoSchema ─────────────────────────────────────────────────────
233
+ describe('CharacterVideoSchema', () => {
234
+ const minimal = {
235
+ character_sheet_url: SHEET_URL,
236
+ storyboard_url: STORYBOARD_URL,
237
+ };
238
+ it('accepts minimal body and applies defaults', () => {
239
+ const r = CharacterVideoSchema.parse(minimal);
240
+ expect(r.duration).toBe(10);
241
+ expect(r.aspect_ratio).toBe('9:16');
242
+ expect(r.generate_audio).toBe(true);
243
+ });
244
+ it('accepts full body', () => {
245
+ const r = CharacterVideoSchema.safeParse({
246
+ ...minimal,
247
+ action_prompt: 'Scene: Marco in his Brooklyn kitchen at golden hour',
248
+ duration: 5,
249
+ aspect_ratio: '16:9',
250
+ generate_audio: false,
251
+ session_id: SESSION,
252
+ webhook_url: 'https://hooks.example.com/cb',
253
+ });
254
+ expect(r.success).toBe(true);
255
+ });
256
+ it('rejects missing character_sheet_url', () => {
257
+ const r = CharacterVideoSchema.safeParse({ storyboard_url: STORYBOARD_URL });
258
+ expect(r.success).toBe(false);
259
+ });
260
+ it('rejects missing storyboard_url', () => {
261
+ const r = CharacterVideoSchema.safeParse({ character_sheet_url: SHEET_URL });
262
+ expect(r.success).toBe(false);
263
+ });
264
+ it('rejects non-URL character_sheet_url', () => {
265
+ const r = CharacterVideoSchema.safeParse({
266
+ character_sheet_url: 'not a url',
267
+ storyboard_url: STORYBOARD_URL,
268
+ });
269
+ expect(r.success).toBe(false);
270
+ });
271
+ it('rejects empty action_prompt', () => {
272
+ const r = CharacterVideoSchema.safeParse({ ...minimal, action_prompt: '' });
273
+ expect(r.success).toBe(false);
274
+ });
275
+ it('rejects action_prompt longer than 2000 chars', () => {
276
+ const r = CharacterVideoSchema.safeParse({ ...minimal, action_prompt: 'x'.repeat(2001) });
277
+ expect(r.success).toBe(false);
278
+ });
279
+ it('rejects duration not in {5, 10}', () => {
280
+ const r = CharacterVideoSchema.safeParse({ ...minimal, duration: 7 });
281
+ expect(r.success).toBe(false);
282
+ });
283
+ it('rejects bad aspect_ratio', () => {
284
+ const r = CharacterVideoSchema.safeParse({ ...minimal, aspect_ratio: '4:3' });
285
+ expect(r.success).toBe(false);
286
+ });
287
+ it('rejects non-uuid session_id', () => {
288
+ const r = CharacterVideoSchema.safeParse({ ...minimal, session_id: 'not-a-uuid' });
289
+ expect(r.success).toBe(false);
290
+ });
291
+ it('rejects non-https webhook_url style invalid URL', () => {
292
+ const r = CharacterVideoSchema.safeParse({ ...minimal, webhook_url: 'not a url' });
293
+ expect(r.success).toBe(false);
294
+ });
295
+ });
296
+ //# sourceMappingURL=character-pipeline.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"character-pipeline.test.js","sourceRoot":"","sources":["../../src/__tests__/character-pipeline.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=text-to-video.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text-to-video.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/text-to-video.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,67 @@
1
+ // Copyright 2026 agent-media contributors. Apache-2.0 license.
2
+ /**
3
+ * Validation tests for TextToVideoSchema — the pure-prompt generator
4
+ * used by the "Use prompts" batch mode and the one-shot
5
+ * POST /v1/generate/text_to_video endpoint.
6
+ *
7
+ * The schema is intentionally simple: prompt (20-1000 chars), duration
8
+ * (5/10/15), aspect_ratio (9:16/16:9/1:1), generate_audio (default true).
9
+ */
10
+ import { describe, it, expect } from 'vitest';
11
+ import { TextToVideoSchema, TEXT_TO_VIDEO_DURATIONS, TEXT_TO_VIDEO_RATIOS } from '../video.js';
12
+ const VALID_PROMPT = 'Handcrafted stylized stop-motion aesthetic with miniature practical sets, animation on 2s, warm magical lighting.';
13
+ describe('TextToVideoSchema', () => {
14
+ it('accepts minimum valid input (prompt only — defaults fill in)', () => {
15
+ const r = TextToVideoSchema.safeParse({ prompt: VALID_PROMPT });
16
+ expect(r.success).toBe(true);
17
+ if (r.success) {
18
+ expect(r.data.duration).toBe(10);
19
+ expect(r.data.aspect_ratio).toBe('9:16');
20
+ expect(r.data.generate_audio).toBe(true);
21
+ }
22
+ });
23
+ it('rejects prompt shorter than 20 characters', () => {
24
+ const r = TextToVideoSchema.safeParse({ prompt: 'too short' });
25
+ expect(r.success).toBe(false);
26
+ });
27
+ it('rejects prompt longer than 1000 characters', () => {
28
+ const r = TextToVideoSchema.safeParse({ prompt: 'A'.repeat(1001) });
29
+ expect(r.success).toBe(false);
30
+ });
31
+ it('accepts each supported duration', () => {
32
+ for (const d of TEXT_TO_VIDEO_DURATIONS) {
33
+ const r = TextToVideoSchema.safeParse({ prompt: VALID_PROMPT, duration: d });
34
+ expect(r.success).toBe(true);
35
+ }
36
+ });
37
+ it('rejects duration outside the allowed set', () => {
38
+ const r = TextToVideoSchema.safeParse({ prompt: VALID_PROMPT, duration: 7 });
39
+ expect(r.success).toBe(false);
40
+ });
41
+ it('accepts each supported aspect_ratio', () => {
42
+ for (const a of TEXT_TO_VIDEO_RATIOS) {
43
+ const r = TextToVideoSchema.safeParse({ prompt: VALID_PROMPT, aspect_ratio: a });
44
+ expect(r.success).toBe(true);
45
+ }
46
+ });
47
+ it('rejects unsupported aspect_ratio', () => {
48
+ const r = TextToVideoSchema.safeParse({ prompt: VALID_PROMPT, aspect_ratio: '21:9' });
49
+ expect(r.success).toBe(false);
50
+ });
51
+ it('accepts generate_audio=false', () => {
52
+ const r = TextToVideoSchema.safeParse({ prompt: VALID_PROMPT, generate_audio: false });
53
+ expect(r.success).toBe(true);
54
+ });
55
+ it('accepts a webhook_url that is HTTPS', () => {
56
+ const r = TextToVideoSchema.safeParse({
57
+ prompt: VALID_PROMPT,
58
+ webhook_url: 'https://example.com/hook',
59
+ });
60
+ expect(r.success).toBe(true);
61
+ });
62
+ it('rejects an invalid webhook_url', () => {
63
+ const r = TextToVideoSchema.safeParse({ prompt: VALID_PROMPT, webhook_url: 'not-a-url' });
64
+ expect(r.success).toBe(false);
65
+ });
66
+ });
67
+ //# sourceMappingURL=text-to-video.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text-to-video.test.js","sourceRoot":"","sources":["../../src/__tests__/text-to-video.test.ts"],"names":[],"mappings":"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"}
@@ -807,6 +807,73 @@ export declare const GENERATORS: {
807
807
  }>;
808
808
  readonly output: "video_url";
809
809
  };
810
+ readonly character_video: {
811
+ readonly description: "Generate a video of a character. Pick an actor by slug, OR pass a short description and we generate a character sheet via gpt-image-2 behind the scenes. Then Seedance 2.0 animates the reference image with your storyboard text.";
812
+ readonly inputSchema: import("zod").ZodObject<{
813
+ character_sheet_url: import("zod").ZodString;
814
+ storyboard_url: import("zod").ZodString;
815
+ action_prompt: import("zod").ZodOptional<import("zod").ZodString>;
816
+ duration: import("zod").ZodDefault<import("zod").ZodOptional<import("zod").ZodEffects<import("zod").ZodNumber, number, number>>>;
817
+ aspect_ratio: import("zod").ZodDefault<import("zod").ZodOptional<import("zod").ZodEnum<["9:16", "16:9", "1:1"]>>>;
818
+ generate_audio: import("zod").ZodDefault<import("zod").ZodOptional<import("zod").ZodBoolean>>;
819
+ session_id: import("zod").ZodOptional<import("zod").ZodString>;
820
+ webhook_url: import("zod").ZodOptional<import("zod").ZodString>;
821
+ }, "strip", import("zod").ZodTypeAny, {
822
+ duration: number;
823
+ aspect_ratio: "9:16" | "16:9" | "1:1";
824
+ character_sheet_url: string;
825
+ storyboard_url: string;
826
+ generate_audio: boolean;
827
+ webhook_url?: string | undefined;
828
+ action_prompt?: string | undefined;
829
+ session_id?: string | undefined;
830
+ }, {
831
+ character_sheet_url: string;
832
+ storyboard_url: string;
833
+ duration?: number | undefined;
834
+ aspect_ratio?: "9:16" | "16:9" | "1:1" | undefined;
835
+ webhook_url?: string | undefined;
836
+ action_prompt?: string | undefined;
837
+ generate_audio?: boolean | undefined;
838
+ session_id?: string | undefined;
839
+ }>;
840
+ readonly output: "video_url";
841
+ };
842
+ readonly text_to_video: {
843
+ readonly description: "Pure text-to-video via Seedance 2.0 — no character, no storyboard, no actor. The prompt IS the whole creative (style, subject, mood, composition). Best for stylistic / scene-driven content where you want the model to invent everything from the prompt text alone.";
844
+ readonly inputSchema: import("zod").ZodObject<{
845
+ prompt: import("zod").ZodString;
846
+ duration: import("zod").ZodDefault<import("zod").ZodOptional<import("zod").ZodEffects<import("zod").ZodNumber, number, number>>>;
847
+ aspect_ratio: import("zod").ZodDefault<import("zod").ZodOptional<import("zod").ZodEnum<["9:16", "16:9", "1:1"]>>>;
848
+ generate_audio: import("zod").ZodDefault<import("zod").ZodOptional<import("zod").ZodBoolean>>;
849
+ webhook_url: import("zod").ZodOptional<import("zod").ZodString>;
850
+ postiz_integration_ids: import("zod").ZodOptional<import("zod").ZodArray<import("zod").ZodString, "many">>;
851
+ caption_mode: import("zod").ZodDefault<import("zod").ZodOptional<import("zod").ZodEnum<["ai", "static"]>>>;
852
+ caption: import("zod").ZodOptional<import("zod").ZodString>;
853
+ caption_guidance: import("zod").ZodOptional<import("zod").ZodString>;
854
+ }, "strip", import("zod").ZodTypeAny, {
855
+ duration: number;
856
+ aspect_ratio: "9:16" | "16:9" | "1:1";
857
+ prompt: string;
858
+ generate_audio: boolean;
859
+ caption_mode: "ai" | "static";
860
+ webhook_url?: string | undefined;
861
+ postiz_integration_ids?: string[] | undefined;
862
+ caption?: string | undefined;
863
+ caption_guidance?: string | undefined;
864
+ }, {
865
+ prompt: string;
866
+ duration?: number | undefined;
867
+ aspect_ratio?: "9:16" | "16:9" | "1:1" | undefined;
868
+ webhook_url?: string | undefined;
869
+ generate_audio?: boolean | undefined;
870
+ postiz_integration_ids?: string[] | undefined;
871
+ caption_mode?: "ai" | "static" | undefined;
872
+ caption?: string | undefined;
873
+ caption_guidance?: string | undefined;
874
+ }>;
875
+ readonly output: "video_url";
876
+ };
810
877
  };
811
878
  export type GeneratorId = keyof typeof GENERATORS;
812
879
  export declare const GENERATOR_IDS: GeneratorId[];
@@ -1 +1 @@
1
- {"version":3,"file":"generators.d.ts","sourceRoot":"","sources":["../src/generators.ts"],"names":[],"mappings":"AAoBA,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqCb,CAAC;AAEX,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,UAAU,CAAC;AAElD,eAAO,MAAM,aAAa,EAErB,WAAW,EAAE,CAAC"}
1
+ {"version":3,"file":"generators.d.ts","sourceRoot":"","sources":["../src/generators.ts"],"names":[],"mappings":"AAsBA,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+Cb,CAAC;AAEX,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,UAAU,CAAC;AAElD,eAAO,MAAM,aAAa,EAErB,WAAW,EAAE,CAAC"}
@@ -6,7 +6,7 @@
6
6
  * contract and a predictable output. Users and integrations never see
7
7
  * internals (models, pipelines, rendering).
8
8
  */
9
- import { CreateVideoSchema, LaptopUgcSchema, ProductActingSchema, ProductReviewSchema, SaasReviewSchema, ShowYourAppSchema, SubtitleSchema, } from './video.js';
9
+ import { CharacterVideoSchema, CreateVideoSchema, LaptopUgcSchema, ProductActingSchema, ProductReviewSchema, SaasReviewSchema, ShowYourAppSchema, SubtitleSchema, TextToVideoSchema, } from './video.js';
10
10
  export const GENERATORS = {
11
11
  ugc_video: {
12
12
  description: 'Generate a UGC-style video from a script or prompt',
@@ -44,6 +44,16 @@ export const GENERATORS = {
44
44
  inputSchema: LaptopUgcSchema,
45
45
  output: 'video_url',
46
46
  },
47
+ character_video: {
48
+ description: 'Generate a video of a character. Pick an actor by slug, OR pass a short description and we generate a character sheet via gpt-image-2 behind the scenes. Then Seedance 2.0 animates the reference image with your storyboard text.',
49
+ inputSchema: CharacterVideoSchema,
50
+ output: 'video_url',
51
+ },
52
+ text_to_video: {
53
+ description: 'Pure text-to-video via Seedance 2.0 — no character, no storyboard, no actor. The prompt IS the whole creative (style, subject, mood, composition). Best for stylistic / scene-driven content where you want the model to invent everything from the prompt text alone.',
54
+ inputSchema: TextToVideoSchema,
55
+ output: 'video_url',
56
+ },
47
57
  };
48
58
  export const GENERATOR_IDS = Object.keys(GENERATORS).filter((id) => !GENERATORS[id].legacy);
49
59
  //# sourceMappingURL=generators.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"generators.js","sourceRoot":"","sources":["../src/generators.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAE/D;;;;;;GAMG;AAEH,OAAO,EACL,iBAAiB,EACjB,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,GACf,MAAM,YAAY,CAAC;AAEpB,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,SAAS,EAAE;QACT,WAAW,EAAE,oDAAoD;QACjE,WAAW,EAAE,iBAAiB;QAC9B,MAAM,EAAE,WAAoB;KAC7B;IACD,WAAW,EAAE;QACX,WAAW,EAAE,sDAAsD;QACnE,WAAW,EAAE,gBAAgB;QAC7B,MAAM,EAAE,WAAoB;KAC7B;IACD,cAAc,EAAE;QACd,WAAW,EAAE,+CAA+C;QAC5D,WAAW,EAAE,mBAAmB;QAChC,MAAM,EAAE,WAAoB;QAC5B,MAAM,EAAE,IAAI;KACb;IACD,QAAQ,EAAE;QACR,WAAW,EAAE,2CAA2C;QACxD,WAAW,EAAE,cAAc;QAC3B,MAAM,EAAE,WAAoB;KAC7B;IACD,aAAa,EAAE;QACb,WAAW,EAAE,oEAAoE;QACjF,WAAW,EAAE,iBAAiB;QAC9B,MAAM,EAAE,WAAoB;KAC7B;IACD,kBAAkB,EAAE;QAClB,WAAW,EAAE,+EAA+E;QAC5F,WAAW,EAAE,mBAAmB;QAChC,MAAM,EAAE,WAAoB;KAC7B;IACD,UAAU,EAAE;QACV,WAAW,EAAE,wHAAwH;QACrI,WAAW,EAAE,eAAe;QAC5B,MAAM,EAAE,WAAoB;KAC7B;CACO,CAAC;AAIX,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,CACzD,CAAC,EAAE,EAAE,EAAE,CAAC,CAAE,UAAU,CAAC,EAAiB,CAA0B,CAAC,MAAM,CACvD,CAAC"}
1
+ {"version":3,"file":"generators.js","sourceRoot":"","sources":["../src/generators.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAE/D;;;;;;GAMG;AAEH,OAAO,EACL,oBAAoB,EACpB,iBAAiB,EACjB,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,iBAAiB,EACjB,cAAc,EACd,iBAAiB,GAClB,MAAM,YAAY,CAAC;AAEpB,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,SAAS,EAAE;QACT,WAAW,EAAE,oDAAoD;QACjE,WAAW,EAAE,iBAAiB;QAC9B,MAAM,EAAE,WAAoB;KAC7B;IACD,WAAW,EAAE;QACX,WAAW,EAAE,sDAAsD;QACnE,WAAW,EAAE,gBAAgB;QAC7B,MAAM,EAAE,WAAoB;KAC7B;IACD,cAAc,EAAE;QACd,WAAW,EAAE,+CAA+C;QAC5D,WAAW,EAAE,mBAAmB;QAChC,MAAM,EAAE,WAAoB;QAC5B,MAAM,EAAE,IAAI;KACb;IACD,QAAQ,EAAE;QACR,WAAW,EAAE,2CAA2C;QACxD,WAAW,EAAE,cAAc;QAC3B,MAAM,EAAE,WAAoB;KAC7B;IACD,aAAa,EAAE;QACb,WAAW,EAAE,oEAAoE;QACjF,WAAW,EAAE,iBAAiB;QAC9B,MAAM,EAAE,WAAoB;KAC7B;IACD,kBAAkB,EAAE;QAClB,WAAW,EAAE,+EAA+E;QAC5F,WAAW,EAAE,mBAAmB;QAChC,MAAM,EAAE,WAAoB;KAC7B;IACD,UAAU,EAAE;QACV,WAAW,EAAE,wHAAwH;QACrI,WAAW,EAAE,eAAe;QAC5B,MAAM,EAAE,WAAoB;KAC7B;IACD,eAAe,EAAE;QACf,WAAW,EAAE,oOAAoO;QACjP,WAAW,EAAE,oBAAoB;QACjC,MAAM,EAAE,WAAoB;KAC7B;IACD,aAAa,EAAE;QACb,WAAW,EAAE,wQAAwQ;QACrR,WAAW,EAAE,iBAAiB;QAC9B,MAAM,EAAE,WAAoB;KAC7B;CACO,CAAC;AAIX,MAAM,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,CACzD,CAAC,EAAE,EAAE,EAAE,CAAC,CAAE,UAAU,CAAC,EAAiB,CAA0B,CAAC,MAAM,CACvD,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * v2 · Character create input schema.
3
+ *
4
+ * Persists a reusable AI character. The user uploads a single photo;
5
+ * we generate a portrait + multi-pose character sheet (gpt-image-2),
6
+ * pin a Seedance seed, store everything in `user_characters`.
7
+ *
8
+ * Returns: { character_id: "char_xxxxxxxxxx" } that the user can pass
9
+ * to any v2 video generator (Selfie, then Product-in-hands, etc).
10
+ */
11
+ import { z } from 'zod';
12
+ export declare const CharacterCreateSchema: z.ZodObject<{
13
+ photo_url: z.ZodString;
14
+ display_name: z.ZodString;
15
+ description: z.ZodString;
16
+ voice_brief: z.ZodOptional<z.ZodString>;
17
+ preset_default: z.ZodOptional<z.ZodEnum<["bedroom-morning-ritual", "getting-ready-mirror-edge", "bathroom-skincare-routine", "bedside-lamp-evening", "kitchen-glow-up", "backyard-morning-coffee", "picnic-blanket-outdoor", "car-quick-honest-review", "car-passenger-honest", "outdoor-walking-talking", "couch-haul-show-off", "closet-fit-check", "studio-apartment-tour", "balcony-evening-vibes", "desk-wfh-quick-pitch", "cafe-window-seat", "office-bathroom-discreet", "gym-post-workout", "salon-mirror-result", "travel-hotel-room-review"]>>;
18
+ }, "strip", z.ZodTypeAny, {
19
+ description: string;
20
+ photo_url: string;
21
+ display_name: string;
22
+ voice_brief?: string | undefined;
23
+ preset_default?: "bedroom-morning-ritual" | "getting-ready-mirror-edge" | "bathroom-skincare-routine" | "bedside-lamp-evening" | "kitchen-glow-up" | "backyard-morning-coffee" | "picnic-blanket-outdoor" | "car-quick-honest-review" | "car-passenger-honest" | "outdoor-walking-talking" | "couch-haul-show-off" | "closet-fit-check" | "studio-apartment-tour" | "balcony-evening-vibes" | "desk-wfh-quick-pitch" | "cafe-window-seat" | "office-bathroom-discreet" | "gym-post-workout" | "salon-mirror-result" | "travel-hotel-room-review" | undefined;
24
+ }, {
25
+ description: string;
26
+ photo_url: string;
27
+ display_name: string;
28
+ voice_brief?: string | undefined;
29
+ preset_default?: "bedroom-morning-ritual" | "getting-ready-mirror-edge" | "bathroom-skincare-routine" | "bedside-lamp-evening" | "kitchen-glow-up" | "backyard-morning-coffee" | "picnic-blanket-outdoor" | "car-quick-honest-review" | "car-passenger-honest" | "outdoor-walking-talking" | "couch-haul-show-off" | "closet-fit-check" | "studio-apartment-tour" | "balcony-evening-vibes" | "desk-wfh-quick-pitch" | "cafe-window-seat" | "office-bathroom-discreet" | "gym-post-workout" | "salon-mirror-result" | "travel-hotel-room-review" | undefined;
30
+ }>;
31
+ export type CharacterCreateInput = z.infer<typeof CharacterCreateSchema>;
32
+ //# sourceMappingURL=character.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"character.d.ts","sourceRoot":"","sources":["../../src/v2/character.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;EAoBhC,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC"}
@@ -0,0 +1,29 @@
1
+ // Copyright 2026 agent-media contributors. Apache-2.0 license.
2
+ /**
3
+ * v2 · Character create input schema.
4
+ *
5
+ * Persists a reusable AI character. The user uploads a single photo;
6
+ * we generate a portrait + multi-pose character sheet (gpt-image-2),
7
+ * pin a Seedance seed, store everything in `user_characters`.
8
+ *
9
+ * Returns: { character_id: "char_xxxxxxxxxx" } that the user can pass
10
+ * to any v2 video generator (Selfie, then Product-in-hands, etc).
11
+ */
12
+ import { z } from 'zod';
13
+ import { V2_SHOT_PRESETS } from './selfie.js';
14
+ export const CharacterCreateSchema = z.object({
15
+ // Source photo — single file, frontal-ish, daylight ideally.
16
+ photo_url: z.string().url(),
17
+ // Required identity
18
+ display_name: z
19
+ .string()
20
+ .trim()
21
+ .min(2)
22
+ .max(40)
23
+ .regex(/^[A-Za-z0-9 _-]+$/, 'display_name may only contain letters, digits, spaces, underscores, or hyphens'),
24
+ description: z.string().min(8).max(400),
25
+ // Optional — defaults applied per-character if missing
26
+ voice_brief: z.string().min(4).max(240).optional(),
27
+ preset_default: z.enum(V2_SHOT_PRESETS).optional(),
28
+ });
29
+ //# sourceMappingURL=character.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"character.js","sourceRoot":"","sources":["../../src/v2/character.ts"],"names":[],"mappings":"AAAA,+DAA+D;AAE/D;;;;;;;;;GASG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5C,6DAA6D;IAC7D,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE;IAE3B,oBAAoB;IACpB,YAAY,EAAE,CAAC;SACZ,MAAM,EAAE;SACR,IAAI,EAAE;SACN,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,EAAE,CAAC;SACP,KAAK,CACJ,mBAAmB,EACnB,gFAAgF,CACjF;IAEH,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;IAEvC,uDAAuD;IACvD,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE;IAClD,cAAc,EAAE,CAAC,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,QAAQ,EAAE;CACnD,CAAC,CAAC"}