vidspotai-shared 1.0.95 → 1.0.96

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 (125) hide show
  1. package/lib/globals/aiModels/enums.d.ts +2 -0
  2. package/lib/globals/aiModels/enums.d.ts.map +1 -1
  3. package/lib/globals/aiModels/enums.js +5 -0
  4. package/lib/globals/aiModels/index.d.ts.map +1 -1
  5. package/lib/globals/aiModels/index.js +2 -0
  6. package/lib/globals/aiModels/providers/hostedAvatars.d.ts +22 -0
  7. package/lib/globals/aiModels/providers/hostedAvatars.d.ts.map +1 -0
  8. package/lib/globals/aiModels/providers/hostedAvatars.js +129 -0
  9. package/lib/globals/types.d.ts +58 -1
  10. package/lib/globals/types.d.ts.map +1 -1
  11. package/lib/globals/types.js +61 -1
  12. package/lib/models/demoVideoProject.model.d.ts +244 -0
  13. package/lib/models/demoVideoProject.model.d.ts.map +1 -0
  14. package/lib/models/demoVideoProject.model.js +2 -0
  15. package/lib/models/githubConnection.model.d.ts +35 -0
  16. package/lib/models/githubConnection.model.d.ts.map +1 -0
  17. package/lib/models/githubConnection.model.js +2 -0
  18. package/lib/models/index.d.ts +3 -0
  19. package/lib/models/index.d.ts.map +1 -1
  20. package/lib/models/index.js +3 -0
  21. package/lib/models/outreach.model.d.ts +175 -0
  22. package/lib/models/outreach.model.d.ts.map +1 -0
  23. package/lib/models/outreach.model.js +2 -0
  24. package/lib/models/video.model.d.ts +4 -0
  25. package/lib/models/video.model.d.ts.map +1 -1
  26. package/lib/schemas/brandKit.schema.d.ts +4 -0
  27. package/lib/schemas/brandKit.schema.d.ts.map +1 -1
  28. package/lib/schemas/brandKit.schema.js +10 -0
  29. package/lib/schemas/demoQuestion.schema.d.ts +286 -0
  30. package/lib/schemas/demoQuestion.schema.d.ts.map +1 -0
  31. package/lib/schemas/demoQuestion.schema.js +210 -0
  32. package/lib/schemas/demoSpec.schema.d.ts +109 -6
  33. package/lib/schemas/demoSpec.schema.d.ts.map +1 -1
  34. package/lib/schemas/demoSpec.schema.js +95 -7
  35. package/lib/schemas/index.d.ts +1 -0
  36. package/lib/schemas/index.d.ts.map +1 -1
  37. package/lib/schemas/index.js +1 -0
  38. package/lib/services/agent/providerFallback/chains.d.ts.map +1 -1
  39. package/lib/services/agent/providerFallback/chains.js +9 -1
  40. package/lib/services/agent/taskPoller.d.ts.map +1 -1
  41. package/lib/services/agent/taskPoller.js +17 -6
  42. package/lib/services/agent/tools/generateAvatarVideo.tool.d.ts +21 -9
  43. package/lib/services/agent/tools/generateAvatarVideo.tool.d.ts.map +1 -1
  44. package/lib/services/agent/tools/generateAvatarVideo.tool.js +135 -39
  45. package/lib/services/aiGen/aiGenFactory.service.d.ts +1 -1
  46. package/lib/services/aiGen/aiGenFactory.service.d.ts.map +1 -1
  47. package/lib/services/aiGen/aiGenFactory.service.js +10 -2
  48. package/lib/services/avatarGen/IAvatarVideoProvider.d.ts +136 -0
  49. package/lib/services/avatarGen/IAvatarVideoProvider.d.ts.map +1 -0
  50. package/lib/services/avatarGen/IAvatarVideoProvider.js +42 -0
  51. package/lib/services/avatarGen/avatarProviderFactory.d.ts +18 -0
  52. package/lib/services/avatarGen/avatarProviderFactory.d.ts.map +1 -0
  53. package/lib/services/avatarGen/avatarProviderFactory.js +54 -0
  54. package/lib/services/avatarGen/index.d.ts +6 -0
  55. package/lib/services/avatarGen/index.d.ts.map +1 -0
  56. package/lib/services/avatarGen/index.js +21 -0
  57. package/lib/services/avatarGen/providers/heygenAvatarProvider.d.ts +45 -0
  58. package/lib/services/avatarGen/providers/heygenAvatarProvider.d.ts.map +1 -0
  59. package/lib/services/avatarGen/providers/heygenAvatarProvider.js +190 -0
  60. package/lib/services/avatarGen/providers/klingAvatarProvider.d.ts +32 -0
  61. package/lib/services/avatarGen/providers/klingAvatarProvider.d.ts.map +1 -0
  62. package/lib/services/avatarGen/providers/klingAvatarProvider.js +69 -0
  63. package/lib/services/avatarGen/providers/tavusAvatarProvider.d.ts +56 -0
  64. package/lib/services/avatarGen/providers/tavusAvatarProvider.d.ts.map +1 -0
  65. package/lib/services/avatarGen/providers/tavusAvatarProvider.js +183 -0
  66. package/lib/services/demo/demoAuthor.d.ts +45 -0
  67. package/lib/services/demo/demoAuthor.d.ts.map +1 -0
  68. package/lib/services/demo/demoAuthor.js +75 -0
  69. package/lib/services/demo/demoAuthorNormalize.d.ts +49 -0
  70. package/lib/services/demo/demoAuthorNormalize.d.ts.map +1 -0
  71. package/lib/services/demo/demoAuthorNormalize.js +327 -0
  72. package/lib/services/demo/demoAuthorPrompt.d.ts +102 -0
  73. package/lib/services/demo/demoAuthorPrompt.d.ts.map +1 -0
  74. package/lib/services/demo/demoAuthorPrompt.js +243 -0
  75. package/lib/services/demo/demoCredits.d.ts +20 -0
  76. package/lib/services/demo/demoCredits.d.ts.map +1 -0
  77. package/lib/services/demo/demoCredits.js +51 -0
  78. package/lib/services/demo/demoMediaGuard.d.ts +43 -0
  79. package/lib/services/demo/demoMediaGuard.d.ts.map +1 -0
  80. package/lib/services/demo/demoMediaGuard.js +207 -0
  81. package/lib/services/demo/demoMusic.d.ts +13 -0
  82. package/lib/services/demo/demoMusic.d.ts.map +1 -0
  83. package/lib/services/demo/demoMusic.js +93 -0
  84. package/lib/services/demo/demoPrefill.d.ts +76 -0
  85. package/lib/services/demo/demoPrefill.d.ts.map +1 -0
  86. package/lib/services/demo/demoPrefill.js +435 -0
  87. package/lib/services/demo/demoRevisePrompt.d.ts +17 -0
  88. package/lib/services/demo/demoRevisePrompt.d.ts.map +1 -0
  89. package/lib/services/demo/demoRevisePrompt.js +85 -0
  90. package/lib/services/demo/demoReviser.d.ts +63 -0
  91. package/lib/services/demo/demoReviser.d.ts.map +1 -0
  92. package/lib/services/demo/demoReviser.js +81 -0
  93. package/lib/services/demo/demoScriptPrompt.d.ts +63 -0
  94. package/lib/services/demo/demoScriptPrompt.d.ts.map +1 -0
  95. package/lib/services/demo/demoScriptPrompt.js +234 -0
  96. package/lib/services/demo/demoScriptWriter.d.ts +65 -0
  97. package/lib/services/demo/demoScriptWriter.d.ts.map +1 -0
  98. package/lib/services/demo/demoScriptWriter.js +211 -0
  99. package/lib/services/demo/demoTriage.d.ts +65 -0
  100. package/lib/services/demo/demoTriage.d.ts.map +1 -0
  101. package/lib/services/demo/demoTriage.js +130 -0
  102. package/lib/services/demo/githubOAuth.d.ts +78 -0
  103. package/lib/services/demo/githubOAuth.d.ts.map +1 -0
  104. package/lib/services/demo/githubOAuth.js +209 -0
  105. package/lib/services/demo/githubOAuthState.d.ts +10 -0
  106. package/lib/services/demo/githubOAuthState.d.ts.map +1 -0
  107. package/lib/services/demo/githubOAuthState.js +63 -0
  108. package/lib/services/demo/index.d.ts +24 -0
  109. package/lib/services/demo/index.d.ts.map +1 -0
  110. package/lib/services/demo/index.js +39 -0
  111. package/lib/services/firestore.service.d.ts +11 -0
  112. package/lib/services/firestore.service.d.ts.map +1 -1
  113. package/lib/services/firestore.service.js +24 -0
  114. package/lib/services/index.d.ts +2 -0
  115. package/lib/services/index.d.ts.map +1 -1
  116. package/lib/services/index.js +2 -0
  117. package/lib/services/tts/providers/elevenlabs.service.d.ts.map +1 -1
  118. package/lib/services/tts/providers/elevenlabs.service.js +16 -8
  119. package/lib/utils/index.d.ts +1 -0
  120. package/lib/utils/index.d.ts.map +1 -1
  121. package/lib/utils/index.js +1 -0
  122. package/lib/utils/outreachTemplate.d.ts +46 -0
  123. package/lib/utils/outreachTemplate.d.ts.map +1 -0
  124. package/lib/utils/outreachTemplate.js +174 -0
  125. package/package.json +1 -1
@@ -0,0 +1,286 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * DemoQuestion — the contract for the demo generator's DYNAMIC clarifying
4
+ * questions (the "agent asks only when it needs to" loop, plan §clarification).
5
+ *
6
+ * ONE contract, TWO surfaces:
7
+ * - PRE-GEN triage: on Generate, a cheap LLM pass inspects the website + inputs
8
+ * and, only if it genuinely helps, returns questions the wizard renders inline
9
+ * before any real spend.
10
+ * - MID-RUN pause: the worker may pause (status AWAITING_INPUT) and surface the
11
+ * same shape on the result page, resuming on answer (modeled on the agent
12
+ * approval gate — worker returns + a user action re-enqueues).
13
+ *
14
+ * The frontend has ONE renderer for all of this; the value of every answer is
15
+ * `string | string[] | boolean` (see IDemoClarifyAnswerValue), so a single
16
+ * `Record<questionId, value>` map round-trips every kind.
17
+ *
18
+ * The LLM triage MUST emit output matching `DemoQuestionsSchema`; the answer
19
+ * endpoints validate the returned map is well-formed against the pending set.
20
+ */
21
+ /** One selectable option for a single/multi-select question. */
22
+ export declare const DemoQuestionOptionSchema: z.ZodObject<{
23
+ value: z.ZodString;
24
+ label: z.ZodString;
25
+ description: z.ZodOptional<z.ZodString>;
26
+ }, z.core.$strip>;
27
+ export type DemoQuestionOption = z.infer<typeof DemoQuestionOptionSchema>;
28
+ /** Pick exactly one option. */
29
+ export declare const SingleSelectQuestionSchema: z.ZodObject<{
30
+ options: z.ZodArray<z.ZodObject<{
31
+ value: z.ZodString;
32
+ label: z.ZodString;
33
+ description: z.ZodOptional<z.ZodString>;
34
+ }, z.core.$strip>>;
35
+ allowOther: z.ZodDefault<z.ZodBoolean>;
36
+ id: z.ZodString;
37
+ prompt: z.ZodString;
38
+ help: z.ZodOptional<z.ZodString>;
39
+ required: z.ZodDefault<z.ZodBoolean>;
40
+ kind: z.ZodLiteral<"single">;
41
+ }, z.core.$strip>;
42
+ /** Pick any number of options. */
43
+ export declare const MultiSelectQuestionSchema: z.ZodObject<{
44
+ options: z.ZodArray<z.ZodObject<{
45
+ value: z.ZodString;
46
+ label: z.ZodString;
47
+ description: z.ZodOptional<z.ZodString>;
48
+ }, z.core.$strip>>;
49
+ min: z.ZodOptional<z.ZodNumber>;
50
+ max: z.ZodOptional<z.ZodNumber>;
51
+ allowOther: z.ZodDefault<z.ZodBoolean>;
52
+ id: z.ZodString;
53
+ prompt: z.ZodString;
54
+ help: z.ZodOptional<z.ZodString>;
55
+ required: z.ZodDefault<z.ZodBoolean>;
56
+ kind: z.ZodLiteral<"multi">;
57
+ }, z.core.$strip>;
58
+ /** A yes/no toggle. The answer is a boolean. */
59
+ export declare const ToggleQuestionSchema: z.ZodObject<{
60
+ default: z.ZodDefault<z.ZodBoolean>;
61
+ onLabel: z.ZodOptional<z.ZodString>;
62
+ offLabel: z.ZodOptional<z.ZodString>;
63
+ id: z.ZodString;
64
+ prompt: z.ZodString;
65
+ help: z.ZodOptional<z.ZodString>;
66
+ required: z.ZodDefault<z.ZodBoolean>;
67
+ kind: z.ZodLiteral<"toggle">;
68
+ }, z.core.$strip>;
69
+ /** A typed free-text answer (short line or paragraph). */
70
+ export declare const TextQuestionSchema: z.ZodObject<{
71
+ placeholder: z.ZodOptional<z.ZodString>;
72
+ multiline: z.ZodDefault<z.ZodBoolean>;
73
+ maxLength: z.ZodDefault<z.ZodNumber>;
74
+ id: z.ZodString;
75
+ prompt: z.ZodString;
76
+ help: z.ZodOptional<z.ZodString>;
77
+ required: z.ZodDefault<z.ZodBoolean>;
78
+ kind: z.ZodLiteral<"text">;
79
+ }, z.core.$strip>;
80
+ /**
81
+ * A file-upload ask (the answer is the uploaded file's public URL, or an array
82
+ * of URLs when `multiple`). Used by the worker's deterministic asset asks —
83
+ * "we couldn't find your logo / any screenshots, add them?" — always optional:
84
+ * a skip means "generate with what we have" (asset asks never block a run).
85
+ * The frontend uploads via /v1/media/single-upload and answers with the URLs.
86
+ */
87
+ export declare const UploadQuestionSchema: z.ZodObject<{
88
+ accept: z.ZodDefault<z.ZodLiteral<"image">>;
89
+ multiple: z.ZodDefault<z.ZodBoolean>;
90
+ maxFiles: z.ZodDefault<z.ZodNumber>;
91
+ id: z.ZodString;
92
+ prompt: z.ZodString;
93
+ help: z.ZodOptional<z.ZodString>;
94
+ required: z.ZodDefault<z.ZodBoolean>;
95
+ kind: z.ZodLiteral<"upload">;
96
+ }, z.core.$strip>;
97
+ export declare const DemoQuestionSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
98
+ options: z.ZodArray<z.ZodObject<{
99
+ value: z.ZodString;
100
+ label: z.ZodString;
101
+ description: z.ZodOptional<z.ZodString>;
102
+ }, z.core.$strip>>;
103
+ allowOther: z.ZodDefault<z.ZodBoolean>;
104
+ id: z.ZodString;
105
+ prompt: z.ZodString;
106
+ help: z.ZodOptional<z.ZodString>;
107
+ required: z.ZodDefault<z.ZodBoolean>;
108
+ kind: z.ZodLiteral<"single">;
109
+ }, z.core.$strip>, z.ZodObject<{
110
+ options: z.ZodArray<z.ZodObject<{
111
+ value: z.ZodString;
112
+ label: z.ZodString;
113
+ description: z.ZodOptional<z.ZodString>;
114
+ }, z.core.$strip>>;
115
+ min: z.ZodOptional<z.ZodNumber>;
116
+ max: z.ZodOptional<z.ZodNumber>;
117
+ allowOther: z.ZodDefault<z.ZodBoolean>;
118
+ id: z.ZodString;
119
+ prompt: z.ZodString;
120
+ help: z.ZodOptional<z.ZodString>;
121
+ required: z.ZodDefault<z.ZodBoolean>;
122
+ kind: z.ZodLiteral<"multi">;
123
+ }, z.core.$strip>, z.ZodObject<{
124
+ default: z.ZodDefault<z.ZodBoolean>;
125
+ onLabel: z.ZodOptional<z.ZodString>;
126
+ offLabel: z.ZodOptional<z.ZodString>;
127
+ id: z.ZodString;
128
+ prompt: z.ZodString;
129
+ help: z.ZodOptional<z.ZodString>;
130
+ required: z.ZodDefault<z.ZodBoolean>;
131
+ kind: z.ZodLiteral<"toggle">;
132
+ }, z.core.$strip>, z.ZodObject<{
133
+ placeholder: z.ZodOptional<z.ZodString>;
134
+ multiline: z.ZodDefault<z.ZodBoolean>;
135
+ maxLength: z.ZodDefault<z.ZodNumber>;
136
+ id: z.ZodString;
137
+ prompt: z.ZodString;
138
+ help: z.ZodOptional<z.ZodString>;
139
+ required: z.ZodDefault<z.ZodBoolean>;
140
+ kind: z.ZodLiteral<"text">;
141
+ }, z.core.$strip>, z.ZodObject<{
142
+ accept: z.ZodDefault<z.ZodLiteral<"image">>;
143
+ multiple: z.ZodDefault<z.ZodBoolean>;
144
+ maxFiles: z.ZodDefault<z.ZodNumber>;
145
+ id: z.ZodString;
146
+ prompt: z.ZodString;
147
+ help: z.ZodOptional<z.ZodString>;
148
+ required: z.ZodDefault<z.ZodBoolean>;
149
+ kind: z.ZodLiteral<"upload">;
150
+ }, z.core.$strip>], "kind">;
151
+ export type DemoQuestion = z.infer<typeof DemoQuestionSchema>;
152
+ export type DemoQuestionKind = DemoQuestion["kind"];
153
+ /** The full set the agent asks in one round. Capped so we never wall the user. */
154
+ export declare const DemoQuestionsSchema: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
155
+ options: z.ZodArray<z.ZodObject<{
156
+ value: z.ZodString;
157
+ label: z.ZodString;
158
+ description: z.ZodOptional<z.ZodString>;
159
+ }, z.core.$strip>>;
160
+ allowOther: z.ZodDefault<z.ZodBoolean>;
161
+ id: z.ZodString;
162
+ prompt: z.ZodString;
163
+ help: z.ZodOptional<z.ZodString>;
164
+ required: z.ZodDefault<z.ZodBoolean>;
165
+ kind: z.ZodLiteral<"single">;
166
+ }, z.core.$strip>, z.ZodObject<{
167
+ options: z.ZodArray<z.ZodObject<{
168
+ value: z.ZodString;
169
+ label: z.ZodString;
170
+ description: z.ZodOptional<z.ZodString>;
171
+ }, z.core.$strip>>;
172
+ min: z.ZodOptional<z.ZodNumber>;
173
+ max: z.ZodOptional<z.ZodNumber>;
174
+ allowOther: z.ZodDefault<z.ZodBoolean>;
175
+ id: z.ZodString;
176
+ prompt: z.ZodString;
177
+ help: z.ZodOptional<z.ZodString>;
178
+ required: z.ZodDefault<z.ZodBoolean>;
179
+ kind: z.ZodLiteral<"multi">;
180
+ }, z.core.$strip>, z.ZodObject<{
181
+ default: z.ZodDefault<z.ZodBoolean>;
182
+ onLabel: z.ZodOptional<z.ZodString>;
183
+ offLabel: z.ZodOptional<z.ZodString>;
184
+ id: z.ZodString;
185
+ prompt: z.ZodString;
186
+ help: z.ZodOptional<z.ZodString>;
187
+ required: z.ZodDefault<z.ZodBoolean>;
188
+ kind: z.ZodLiteral<"toggle">;
189
+ }, z.core.$strip>, z.ZodObject<{
190
+ placeholder: z.ZodOptional<z.ZodString>;
191
+ multiline: z.ZodDefault<z.ZodBoolean>;
192
+ maxLength: z.ZodDefault<z.ZodNumber>;
193
+ id: z.ZodString;
194
+ prompt: z.ZodString;
195
+ help: z.ZodOptional<z.ZodString>;
196
+ required: z.ZodDefault<z.ZodBoolean>;
197
+ kind: z.ZodLiteral<"text">;
198
+ }, z.core.$strip>, z.ZodObject<{
199
+ accept: z.ZodDefault<z.ZodLiteral<"image">>;
200
+ multiple: z.ZodDefault<z.ZodBoolean>;
201
+ maxFiles: z.ZodDefault<z.ZodNumber>;
202
+ id: z.ZodString;
203
+ prompt: z.ZodString;
204
+ help: z.ZodOptional<z.ZodString>;
205
+ required: z.ZodDefault<z.ZodBoolean>;
206
+ kind: z.ZodLiteral<"upload">;
207
+ }, z.core.$strip>], "kind">>;
208
+ export type DemoQuestions = z.infer<typeof DemoQuestionsSchema>;
209
+ /**
210
+ * The triage LLM's decision: whether to ask at all, and if so what. `ask:false`
211
+ * (the common case for a clear brief) means "no questions — just generate".
212
+ */
213
+ export declare const DemoTriageResultSchema: z.ZodObject<{
214
+ ask: z.ZodBoolean;
215
+ reason: z.ZodOptional<z.ZodString>;
216
+ questions: z.ZodDefault<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
217
+ options: z.ZodArray<z.ZodObject<{
218
+ value: z.ZodString;
219
+ label: z.ZodString;
220
+ description: z.ZodOptional<z.ZodString>;
221
+ }, z.core.$strip>>;
222
+ allowOther: z.ZodDefault<z.ZodBoolean>;
223
+ id: z.ZodString;
224
+ prompt: z.ZodString;
225
+ help: z.ZodOptional<z.ZodString>;
226
+ required: z.ZodDefault<z.ZodBoolean>;
227
+ kind: z.ZodLiteral<"single">;
228
+ }, z.core.$strip>, z.ZodObject<{
229
+ options: z.ZodArray<z.ZodObject<{
230
+ value: z.ZodString;
231
+ label: z.ZodString;
232
+ description: z.ZodOptional<z.ZodString>;
233
+ }, z.core.$strip>>;
234
+ min: z.ZodOptional<z.ZodNumber>;
235
+ max: z.ZodOptional<z.ZodNumber>;
236
+ allowOther: z.ZodDefault<z.ZodBoolean>;
237
+ id: z.ZodString;
238
+ prompt: z.ZodString;
239
+ help: z.ZodOptional<z.ZodString>;
240
+ required: z.ZodDefault<z.ZodBoolean>;
241
+ kind: z.ZodLiteral<"multi">;
242
+ }, z.core.$strip>, z.ZodObject<{
243
+ default: z.ZodDefault<z.ZodBoolean>;
244
+ onLabel: z.ZodOptional<z.ZodString>;
245
+ offLabel: z.ZodOptional<z.ZodString>;
246
+ id: z.ZodString;
247
+ prompt: z.ZodString;
248
+ help: z.ZodOptional<z.ZodString>;
249
+ required: z.ZodDefault<z.ZodBoolean>;
250
+ kind: z.ZodLiteral<"toggle">;
251
+ }, z.core.$strip>, z.ZodObject<{
252
+ placeholder: z.ZodOptional<z.ZodString>;
253
+ multiline: z.ZodDefault<z.ZodBoolean>;
254
+ maxLength: z.ZodDefault<z.ZodNumber>;
255
+ id: z.ZodString;
256
+ prompt: z.ZodString;
257
+ help: z.ZodOptional<z.ZodString>;
258
+ required: z.ZodDefault<z.ZodBoolean>;
259
+ kind: z.ZodLiteral<"text">;
260
+ }, z.core.$strip>, z.ZodObject<{
261
+ accept: z.ZodDefault<z.ZodLiteral<"image">>;
262
+ multiple: z.ZodDefault<z.ZodBoolean>;
263
+ maxFiles: z.ZodDefault<z.ZodNumber>;
264
+ id: z.ZodString;
265
+ prompt: z.ZodString;
266
+ help: z.ZodOptional<z.ZodString>;
267
+ required: z.ZodDefault<z.ZodBoolean>;
268
+ kind: z.ZodLiteral<"upload">;
269
+ }, z.core.$strip>], "kind">>>;
270
+ }, z.core.$strip>;
271
+ export type DemoTriageResult = z.infer<typeof DemoTriageResultSchema>;
272
+ /**
273
+ * Validate a raw answer map (questionId → value) against a pending question set:
274
+ * drops answers with no matching question, coerces each value to the shape its
275
+ * question expects, and enforces `required`. Returns the cleaned map (safe to
276
+ * persist) or a list of problems. Kept dependency-free so both the Cloud Function
277
+ * endpoint and the worker can call it.
278
+ */
279
+ export declare function validateClarifyAnswers(questions: DemoQuestion[], raw: Record<string, unknown>): {
280
+ ok: true;
281
+ answers: Record<string, string | string[] | boolean>;
282
+ } | {
283
+ ok: false;
284
+ errors: string[];
285
+ };
286
+ //# sourceMappingURL=demoQuestion.schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"demoQuestion.schema.d.ts","sourceRoot":"","sources":["../../src/schemas/demoQuestion.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;;;;;;;;;GAkBG;AAEH,gEAAgE;AAChE,eAAO,MAAM,wBAAwB;;;;iBAOnC,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC;AAc1E,+BAA+B;AAC/B,eAAO,MAAM,0BAA0B;;;;;;;;;;;;iBAMrC,CAAC;AAEH,kCAAkC;AAClC,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;iBAQpC,CAAC;AAEH,gDAAgD;AAChD,eAAO,MAAM,oBAAoB;;;;;;;;;iBAQ/B,CAAC;AAEH,0DAA0D;AAC1D,eAAO,MAAM,kBAAkB;;;;;;;;;iBAO7B,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;iBAS/B,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2BAM7B,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAC9D,MAAM,MAAM,gBAAgB,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;AAEpD,kFAAkF;AAClF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BAAqC,CAAC;AACtE,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE;;;GAGG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAOjC,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,SAAS,EAAE,YAAY,EAAE,EACzB,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC3B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,CAmFtG"}
@@ -0,0 +1,210 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DemoTriageResultSchema = exports.DemoQuestionsSchema = exports.DemoQuestionSchema = exports.UploadQuestionSchema = exports.TextQuestionSchema = exports.ToggleQuestionSchema = exports.MultiSelectQuestionSchema = exports.SingleSelectQuestionSchema = exports.DemoQuestionOptionSchema = void 0;
4
+ exports.validateClarifyAnswers = validateClarifyAnswers;
5
+ const zod_1 = require("zod");
6
+ /**
7
+ * DemoQuestion — the contract for the demo generator's DYNAMIC clarifying
8
+ * questions (the "agent asks only when it needs to" loop, plan §clarification).
9
+ *
10
+ * ONE contract, TWO surfaces:
11
+ * - PRE-GEN triage: on Generate, a cheap LLM pass inspects the website + inputs
12
+ * and, only if it genuinely helps, returns questions the wizard renders inline
13
+ * before any real spend.
14
+ * - MID-RUN pause: the worker may pause (status AWAITING_INPUT) and surface the
15
+ * same shape on the result page, resuming on answer (modeled on the agent
16
+ * approval gate — worker returns + a user action re-enqueues).
17
+ *
18
+ * The frontend has ONE renderer for all of this; the value of every answer is
19
+ * `string | string[] | boolean` (see IDemoClarifyAnswerValue), so a single
20
+ * `Record<questionId, value>` map round-trips every kind.
21
+ *
22
+ * The LLM triage MUST emit output matching `DemoQuestionsSchema`; the answer
23
+ * endpoints validate the returned map is well-formed against the pending set.
24
+ */
25
+ /** One selectable option for a single/multi-select question. */
26
+ exports.DemoQuestionOptionSchema = zod_1.z.object({
27
+ /** Stable machine value stored in the answer (e.g. "premium"). */
28
+ value: zod_1.z.string().min(1).max(120),
29
+ /** Human label shown on the chip/button (e.g. "Premium & cinematic"). */
30
+ label: zod_1.z.string().min(1).max(120),
31
+ /** Optional one-line helper under the label. */
32
+ description: zod_1.z.string().max(240).optional(),
33
+ });
34
+ /** Fields every question shares regardless of kind. */
35
+ const QuestionBase = {
36
+ /** Stable id — the key the answer is stored under. */
37
+ id: zod_1.z.string().min(1).max(64),
38
+ /** The question text shown to the user. */
39
+ prompt: zod_1.z.string().min(1).max(400),
40
+ /** Optional secondary help / why-we're-asking line. */
41
+ help: zod_1.z.string().max(400).optional(),
42
+ /** If false (default), the user may skip it → the planner decides. */
43
+ required: zod_1.z.boolean().default(false),
44
+ };
45
+ /** Pick exactly one option. */
46
+ exports.SingleSelectQuestionSchema = zod_1.z.object({
47
+ kind: zod_1.z.literal("single"),
48
+ ...QuestionBase,
49
+ options: zod_1.z.array(exports.DemoQuestionOptionSchema).min(2).max(8),
50
+ /** Allow a free-text "Other" answer beyond the listed options. */
51
+ allowOther: zod_1.z.boolean().default(false),
52
+ });
53
+ /** Pick any number of options. */
54
+ exports.MultiSelectQuestionSchema = zod_1.z.object({
55
+ kind: zod_1.z.literal("multi"),
56
+ ...QuestionBase,
57
+ options: zod_1.z.array(exports.DemoQuestionOptionSchema).min(2).max(12),
58
+ /** Optional selection bounds for UI validation. */
59
+ min: zod_1.z.number().int().min(0).optional(),
60
+ max: zod_1.z.number().int().min(1).optional(),
61
+ allowOther: zod_1.z.boolean().default(false),
62
+ });
63
+ /** A yes/no toggle. The answer is a boolean. */
64
+ exports.ToggleQuestionSchema = zod_1.z.object({
65
+ kind: zod_1.z.literal("toggle"),
66
+ ...QuestionBase,
67
+ /** Pre-checked state. */
68
+ default: zod_1.z.boolean().default(false),
69
+ /** Optional labels for the on/off states (default "Yes"/"No"). */
70
+ onLabel: zod_1.z.string().max(60).optional(),
71
+ offLabel: zod_1.z.string().max(60).optional(),
72
+ });
73
+ /** A typed free-text answer (short line or paragraph). */
74
+ exports.TextQuestionSchema = zod_1.z.object({
75
+ kind: zod_1.z.literal("text"),
76
+ ...QuestionBase,
77
+ placeholder: zod_1.z.string().max(160).optional(),
78
+ /** Render a multi-line textarea instead of a single input. */
79
+ multiline: zod_1.z.boolean().default(false),
80
+ maxLength: zod_1.z.number().int().min(1).max(2000).default(500),
81
+ });
82
+ /**
83
+ * A file-upload ask (the answer is the uploaded file's public URL, or an array
84
+ * of URLs when `multiple`). Used by the worker's deterministic asset asks —
85
+ * "we couldn't find your logo / any screenshots, add them?" — always optional:
86
+ * a skip means "generate with what we have" (asset asks never block a run).
87
+ * The frontend uploads via /v1/media/single-upload and answers with the URLs.
88
+ */
89
+ exports.UploadQuestionSchema = zod_1.z.object({
90
+ kind: zod_1.z.literal("upload"),
91
+ ...QuestionBase,
92
+ /** What the picker should accept. Only images are needed so far. */
93
+ accept: zod_1.z.literal("image").default("image"),
94
+ /** Allow more than one file (answer becomes string[]). */
95
+ multiple: zod_1.z.boolean().default(false),
96
+ /** Upper bound when `multiple`. */
97
+ maxFiles: zod_1.z.number().int().min(1).max(6).default(1),
98
+ });
99
+ exports.DemoQuestionSchema = zod_1.z.discriminatedUnion("kind", [
100
+ exports.SingleSelectQuestionSchema,
101
+ exports.MultiSelectQuestionSchema,
102
+ exports.ToggleQuestionSchema,
103
+ exports.TextQuestionSchema,
104
+ exports.UploadQuestionSchema,
105
+ ]);
106
+ /** The full set the agent asks in one round. Capped so we never wall the user. */
107
+ exports.DemoQuestionsSchema = zod_1.z.array(exports.DemoQuestionSchema).max(6);
108
+ /**
109
+ * The triage LLM's decision: whether to ask at all, and if so what. `ask:false`
110
+ * (the common case for a clear brief) means "no questions — just generate".
111
+ */
112
+ exports.DemoTriageResultSchema = zod_1.z.object({
113
+ /** Whether the agent has anything worth clarifying. */
114
+ ask: zod_1.z.boolean(),
115
+ /** One-line rationale shown above the questions ("A few quick calls to nail the vibe"). */
116
+ reason: zod_1.z.string().max(240).optional(),
117
+ /** The questions to ask; empty/omitted when `ask` is false. */
118
+ questions: exports.DemoQuestionsSchema.default([]),
119
+ });
120
+ /**
121
+ * Validate a raw answer map (questionId → value) against a pending question set:
122
+ * drops answers with no matching question, coerces each value to the shape its
123
+ * question expects, and enforces `required`. Returns the cleaned map (safe to
124
+ * persist) or a list of problems. Kept dependency-free so both the Cloud Function
125
+ * endpoint and the worker can call it.
126
+ */
127
+ function validateClarifyAnswers(questions, raw) {
128
+ const errors = [];
129
+ const answers = {};
130
+ const byId = new Map(questions.map((q) => [q.id, q]));
131
+ for (const q of questions) {
132
+ const v = raw[q.id];
133
+ const missing = v === undefined || v === null || v === "" || (Array.isArray(v) && v.length === 0);
134
+ if (missing) {
135
+ if (q.required)
136
+ errors.push(`"${q.prompt}" is required.`);
137
+ continue;
138
+ }
139
+ switch (q.kind) {
140
+ case "single": {
141
+ if (typeof v !== "string") {
142
+ errors.push(`"${q.prompt}" expects a single choice.`);
143
+ break;
144
+ }
145
+ const known = q.options.some((o) => o.value === v);
146
+ if (!known && !q.allowOther) {
147
+ errors.push(`"${v}" is not a valid option for "${q.prompt}".`);
148
+ break;
149
+ }
150
+ answers[q.id] = v;
151
+ break;
152
+ }
153
+ case "multi": {
154
+ const arr = Array.isArray(v) ? v.filter((x) => typeof x === "string") : [];
155
+ if (arr.length === 0) {
156
+ errors.push(`"${q.prompt}" expects one or more choices.`);
157
+ break;
158
+ }
159
+ const clean = q.allowOther ? arr : arr.filter((x) => q.options.some((o) => o.value === x));
160
+ if (typeof q.min === "number" && clean.length < q.min) {
161
+ errors.push(`Pick at least ${q.min} for "${q.prompt}".`);
162
+ break;
163
+ }
164
+ if (typeof q.max === "number" && clean.length > q.max) {
165
+ errors.push(`Pick at most ${q.max} for "${q.prompt}".`);
166
+ break;
167
+ }
168
+ answers[q.id] = clean;
169
+ break;
170
+ }
171
+ case "toggle": {
172
+ answers[q.id] = Boolean(v);
173
+ break;
174
+ }
175
+ case "text": {
176
+ if (typeof v !== "string") {
177
+ errors.push(`"${q.prompt}" expects text.`);
178
+ break;
179
+ }
180
+ answers[q.id] = v.slice(0, q.maxLength);
181
+ break;
182
+ }
183
+ case "upload": {
184
+ const isUrl = (x) => typeof x === "string" && /^https?:\/\//i.test(x);
185
+ if (q.multiple) {
186
+ const arr = Array.isArray(v) ? v.filter(isUrl) : isUrl(v) ? [v] : [];
187
+ if (arr.length === 0) {
188
+ errors.push(`"${q.prompt}" expects uploaded file URL(s).`);
189
+ break;
190
+ }
191
+ answers[q.id] = arr.slice(0, q.maxFiles);
192
+ }
193
+ else {
194
+ const one = isUrl(v) ? v : Array.isArray(v) && isUrl(v[0]) ? v[0] : undefined;
195
+ if (!one) {
196
+ errors.push(`"${q.prompt}" expects an uploaded file URL.`);
197
+ break;
198
+ }
199
+ answers[q.id] = one;
200
+ }
201
+ break;
202
+ }
203
+ }
204
+ }
205
+ // Ignore any answers for ids we never asked (defensive against stale clients).
206
+ void byId;
207
+ if (errors.length > 0)
208
+ return { ok: false, errors };
209
+ return { ok: true, answers };
210
+ }