@marlinjai/studio-mcp 0.1.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.
@@ -0,0 +1,2443 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { z } from 'zod';
3
+ import { IncomingMessage, ServerResponse } from 'node:http';
4
+
5
+ /**
6
+ * The one notion of "a JSON value" the workflow package stores: literal
7
+ * bindings, node settings, input defaults. Recursive and exact (finite numbers,
8
+ * no undefined, no class instances), so a value that parses here survives a
9
+ * JSON round trip unchanged.
10
+ */
11
+
12
+ type JsonValue = string | number | boolean | null | JsonValue[] | {
13
+ [key: string]: JsonValue;
14
+ };
15
+ /** A JSON value that is not `null` at the top level. Settings values and input
16
+ * defaults use it so that `null` in an op can mean "unset" unambiguously and
17
+ * every inverse is exact. */
18
+ type JsonNonNullValue = Exclude<JsonValue, null>;
19
+ declare const DocNodeSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
20
+ id: z.ZodString;
21
+ kind: z.ZodLiteral<"task">;
22
+ task: z.ZodEnum<{
23
+ "text-to-image": "text-to-image";
24
+ "image-to-image": "image-to-image";
25
+ "image-edit": "image-edit";
26
+ "virtual-try-on": "virtual-try-on";
27
+ "text-to-video": "text-to-video";
28
+ "image-to-video": "image-to-video";
29
+ "video-to-video": "video-to-video";
30
+ "video-enhance": "video-enhance";
31
+ "text-to-3d": "text-to-3d";
32
+ "image-to-3d": "image-to-3d";
33
+ "multiview-to-3d": "multiview-to-3d";
34
+ remesh: "remesh";
35
+ texture: "texture";
36
+ "text-to-audio": "text-to-audio";
37
+ "text-to-speech": "text-to-speech";
38
+ "speech-to-text": "speech-to-text";
39
+ "speech-to-speech": "speech-to-speech";
40
+ "image-to-text": "image-to-text";
41
+ "image-to-json": "image-to-json";
42
+ judge: "judge";
43
+ "text-generation": "text-generation";
44
+ upscale: "upscale";
45
+ "background-remove": "background-remove";
46
+ segmentation: "segmentation";
47
+ }>;
48
+ model: z.ZodDefault<z.ZodString>;
49
+ prompt: z.ZodDefault<z.ZodString>;
50
+ settings: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodType<JsonNonNullValue, unknown, z.core.$ZodTypeInternals<JsonNonNullValue, unknown>>>>;
51
+ bakedInputs: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
52
+ kind: z.ZodLiteral<"literal">;
53
+ value: z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>;
54
+ }, z.core.$strip>>>;
55
+ activeGeneration: z.ZodOptional<z.ZodString>;
56
+ label: z.ZodOptional<z.ZodString>;
57
+ }, z.core.$strip>, z.ZodObject<{
58
+ id: z.ZodString;
59
+ kind: z.ZodLiteral<"prompt-source">;
60
+ text: z.ZodDefault<z.ZodString>;
61
+ label: z.ZodOptional<z.ZodString>;
62
+ }, z.core.$strip>, z.ZodObject<{
63
+ id: z.ZodString;
64
+ kind: z.ZodLiteral<"image-source">;
65
+ imageUrl: z.ZodDefault<z.ZodString>;
66
+ assetId: z.ZodOptional<z.ZodString>;
67
+ label: z.ZodOptional<z.ZodString>;
68
+ }, z.core.$strip>, z.ZodObject<{
69
+ id: z.ZodString;
70
+ kind: z.ZodLiteral<"input">;
71
+ name: z.ZodString;
72
+ type: z.ZodEnum<{
73
+ image: "image";
74
+ video: "video";
75
+ audio: "audio";
76
+ text: "text";
77
+ mesh3d: "mesh3d";
78
+ json: "json";
79
+ }>;
80
+ required: z.ZodDefault<z.ZodBoolean>;
81
+ cardinality: z.ZodOptional<z.ZodEnum<{
82
+ one: "one";
83
+ many: "many";
84
+ }>>;
85
+ default: z.ZodOptional<z.ZodType<JsonNonNullValue, unknown, z.core.$ZodTypeInternals<JsonNonNullValue, unknown>>>;
86
+ label: z.ZodOptional<z.ZodString>;
87
+ description: z.ZodOptional<z.ZodString>;
88
+ }, z.core.$strip>], "kind">;
89
+ type DocNode = z.infer<typeof DocNodeSchema>;
90
+ type DocNodeKind = DocNode["kind"];
91
+ declare const WorkflowDocumentSchema: z.ZodObject<{
92
+ schema: z.ZodNumber;
93
+ id: z.ZodString;
94
+ label: z.ZodDefault<z.ZodString>;
95
+ nodes: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
96
+ id: z.ZodString;
97
+ kind: z.ZodLiteral<"task">;
98
+ task: z.ZodEnum<{
99
+ "text-to-image": "text-to-image";
100
+ "image-to-image": "image-to-image";
101
+ "image-edit": "image-edit";
102
+ "virtual-try-on": "virtual-try-on";
103
+ "text-to-video": "text-to-video";
104
+ "image-to-video": "image-to-video";
105
+ "video-to-video": "video-to-video";
106
+ "video-enhance": "video-enhance";
107
+ "text-to-3d": "text-to-3d";
108
+ "image-to-3d": "image-to-3d";
109
+ "multiview-to-3d": "multiview-to-3d";
110
+ remesh: "remesh";
111
+ texture: "texture";
112
+ "text-to-audio": "text-to-audio";
113
+ "text-to-speech": "text-to-speech";
114
+ "speech-to-text": "speech-to-text";
115
+ "speech-to-speech": "speech-to-speech";
116
+ "image-to-text": "image-to-text";
117
+ "image-to-json": "image-to-json";
118
+ judge: "judge";
119
+ "text-generation": "text-generation";
120
+ upscale: "upscale";
121
+ "background-remove": "background-remove";
122
+ segmentation: "segmentation";
123
+ }>;
124
+ model: z.ZodDefault<z.ZodString>;
125
+ prompt: z.ZodDefault<z.ZodString>;
126
+ settings: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodType<JsonNonNullValue, unknown, z.core.$ZodTypeInternals<JsonNonNullValue, unknown>>>>;
127
+ bakedInputs: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
128
+ kind: z.ZodLiteral<"literal">;
129
+ value: z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>;
130
+ }, z.core.$strip>>>;
131
+ activeGeneration: z.ZodOptional<z.ZodString>;
132
+ label: z.ZodOptional<z.ZodString>;
133
+ }, z.core.$strip>, z.ZodObject<{
134
+ id: z.ZodString;
135
+ kind: z.ZodLiteral<"prompt-source">;
136
+ text: z.ZodDefault<z.ZodString>;
137
+ label: z.ZodOptional<z.ZodString>;
138
+ }, z.core.$strip>, z.ZodObject<{
139
+ id: z.ZodString;
140
+ kind: z.ZodLiteral<"image-source">;
141
+ imageUrl: z.ZodDefault<z.ZodString>;
142
+ assetId: z.ZodOptional<z.ZodString>;
143
+ label: z.ZodOptional<z.ZodString>;
144
+ }, z.core.$strip>, z.ZodObject<{
145
+ id: z.ZodString;
146
+ kind: z.ZodLiteral<"input">;
147
+ name: z.ZodString;
148
+ type: z.ZodEnum<{
149
+ image: "image";
150
+ video: "video";
151
+ audio: "audio";
152
+ text: "text";
153
+ mesh3d: "mesh3d";
154
+ json: "json";
155
+ }>;
156
+ required: z.ZodDefault<z.ZodBoolean>;
157
+ cardinality: z.ZodOptional<z.ZodEnum<{
158
+ one: "one";
159
+ many: "many";
160
+ }>>;
161
+ default: z.ZodOptional<z.ZodType<JsonNonNullValue, unknown, z.core.$ZodTypeInternals<JsonNonNullValue, unknown>>>;
162
+ label: z.ZodOptional<z.ZodString>;
163
+ description: z.ZodOptional<z.ZodString>;
164
+ }, z.core.$strip>], "kind">>;
165
+ edges: z.ZodArray<z.ZodObject<{
166
+ source: z.ZodString;
167
+ target: z.ZodString;
168
+ port: z.ZodEnum<{
169
+ image: "image";
170
+ video: "video";
171
+ audio: "audio";
172
+ text: "text";
173
+ mask: "mask";
174
+ mesh3d: "mesh3d";
175
+ json: "json";
176
+ }>;
177
+ }, z.core.$strip>>;
178
+ layout: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
179
+ x: z.ZodNumber;
180
+ y: z.ZodNumber;
181
+ }, z.core.$strip>>>;
182
+ groups: z.ZodDefault<z.ZodArray<z.ZodObject<{
183
+ id: z.ZodString;
184
+ label: z.ZodOptional<z.ZodString>;
185
+ nodeIds: z.ZodArray<z.ZodString>;
186
+ }, z.core.$strip>>>;
187
+ }, z.core.$strip>;
188
+ type WorkflowDocument = z.infer<typeof WorkflowDocumentSchema>;
189
+ declare const OpSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
190
+ type: z.ZodLiteral<"addNode">;
191
+ node: z.ZodDiscriminatedUnion<[z.ZodObject<{
192
+ id: z.ZodString;
193
+ kind: z.ZodLiteral<"task">;
194
+ task: z.ZodEnum<{
195
+ "text-to-image": "text-to-image";
196
+ "image-to-image": "image-to-image";
197
+ "image-edit": "image-edit";
198
+ "virtual-try-on": "virtual-try-on";
199
+ "text-to-video": "text-to-video";
200
+ "image-to-video": "image-to-video";
201
+ "video-to-video": "video-to-video";
202
+ "video-enhance": "video-enhance";
203
+ "text-to-3d": "text-to-3d";
204
+ "image-to-3d": "image-to-3d";
205
+ "multiview-to-3d": "multiview-to-3d";
206
+ remesh: "remesh";
207
+ texture: "texture";
208
+ "text-to-audio": "text-to-audio";
209
+ "text-to-speech": "text-to-speech";
210
+ "speech-to-text": "speech-to-text";
211
+ "speech-to-speech": "speech-to-speech";
212
+ "image-to-text": "image-to-text";
213
+ "image-to-json": "image-to-json";
214
+ judge: "judge";
215
+ "text-generation": "text-generation";
216
+ upscale: "upscale";
217
+ "background-remove": "background-remove";
218
+ segmentation: "segmentation";
219
+ }>;
220
+ model: z.ZodDefault<z.ZodString>;
221
+ prompt: z.ZodDefault<z.ZodString>;
222
+ settings: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodType<JsonNonNullValue, unknown, z.core.$ZodTypeInternals<JsonNonNullValue, unknown>>>>;
223
+ bakedInputs: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
224
+ kind: z.ZodLiteral<"literal">;
225
+ value: z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>;
226
+ }, z.core.$strip>>>;
227
+ activeGeneration: z.ZodOptional<z.ZodString>;
228
+ label: z.ZodOptional<z.ZodString>;
229
+ }, z.core.$strip>, z.ZodObject<{
230
+ id: z.ZodString;
231
+ kind: z.ZodLiteral<"prompt-source">;
232
+ text: z.ZodDefault<z.ZodString>;
233
+ label: z.ZodOptional<z.ZodString>;
234
+ }, z.core.$strip>, z.ZodObject<{
235
+ id: z.ZodString;
236
+ kind: z.ZodLiteral<"image-source">;
237
+ imageUrl: z.ZodDefault<z.ZodString>;
238
+ assetId: z.ZodOptional<z.ZodString>;
239
+ label: z.ZodOptional<z.ZodString>;
240
+ }, z.core.$strip>, z.ZodObject<{
241
+ id: z.ZodString;
242
+ kind: z.ZodLiteral<"input">;
243
+ name: z.ZodString;
244
+ type: z.ZodEnum<{
245
+ image: "image";
246
+ video: "video";
247
+ audio: "audio";
248
+ text: "text";
249
+ mesh3d: "mesh3d";
250
+ json: "json";
251
+ }>;
252
+ required: z.ZodDefault<z.ZodBoolean>;
253
+ cardinality: z.ZodOptional<z.ZodEnum<{
254
+ one: "one";
255
+ many: "many";
256
+ }>>;
257
+ default: z.ZodOptional<z.ZodType<JsonNonNullValue, unknown, z.core.$ZodTypeInternals<JsonNonNullValue, unknown>>>;
258
+ label: z.ZodOptional<z.ZodString>;
259
+ description: z.ZodOptional<z.ZodString>;
260
+ }, z.core.$strip>], "kind">;
261
+ position: z.ZodOptional<z.ZodObject<{
262
+ x: z.ZodNumber;
263
+ y: z.ZodNumber;
264
+ }, z.core.$strip>>;
265
+ index: z.ZodOptional<z.ZodNumber>;
266
+ }, z.core.$strip>, z.ZodObject<{
267
+ type: z.ZodLiteral<"removeNode">;
268
+ id: z.ZodString;
269
+ }, z.core.$strip>, z.ZodDiscriminatedUnion<[z.ZodObject<{
270
+ type: z.ZodLiteral<"setNodeProps">;
271
+ kind: z.ZodLiteral<"task">;
272
+ id: z.ZodString;
273
+ props: z.ZodObject<{
274
+ task: z.ZodOptional<z.ZodEnum<{
275
+ "text-to-image": "text-to-image";
276
+ "image-to-image": "image-to-image";
277
+ "image-edit": "image-edit";
278
+ "virtual-try-on": "virtual-try-on";
279
+ "text-to-video": "text-to-video";
280
+ "image-to-video": "image-to-video";
281
+ "video-to-video": "video-to-video";
282
+ "video-enhance": "video-enhance";
283
+ "text-to-3d": "text-to-3d";
284
+ "image-to-3d": "image-to-3d";
285
+ "multiview-to-3d": "multiview-to-3d";
286
+ remesh: "remesh";
287
+ texture: "texture";
288
+ "text-to-audio": "text-to-audio";
289
+ "text-to-speech": "text-to-speech";
290
+ "speech-to-text": "speech-to-text";
291
+ "speech-to-speech": "speech-to-speech";
292
+ "image-to-text": "image-to-text";
293
+ "image-to-json": "image-to-json";
294
+ judge: "judge";
295
+ "text-generation": "text-generation";
296
+ upscale: "upscale";
297
+ "background-remove": "background-remove";
298
+ segmentation: "segmentation";
299
+ }>>;
300
+ model: z.ZodOptional<z.ZodString>;
301
+ prompt: z.ZodOptional<z.ZodString>;
302
+ label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
303
+ }, z.core.$strict>;
304
+ }, z.core.$strip>, z.ZodObject<{
305
+ type: z.ZodLiteral<"setNodeProps">;
306
+ kind: z.ZodLiteral<"prompt-source">;
307
+ id: z.ZodString;
308
+ props: z.ZodObject<{
309
+ text: z.ZodOptional<z.ZodString>;
310
+ label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
311
+ }, z.core.$strict>;
312
+ }, z.core.$strip>, z.ZodObject<{
313
+ type: z.ZodLiteral<"setNodeProps">;
314
+ kind: z.ZodLiteral<"image-source">;
315
+ id: z.ZodString;
316
+ props: z.ZodObject<{
317
+ imageUrl: z.ZodOptional<z.ZodString>;
318
+ assetId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
319
+ label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
320
+ }, z.core.$strict>;
321
+ }, z.core.$strip>, z.ZodObject<{
322
+ type: z.ZodLiteral<"setNodeProps">;
323
+ kind: z.ZodLiteral<"input">;
324
+ id: z.ZodString;
325
+ props: z.ZodObject<{
326
+ name: z.ZodOptional<z.ZodString>;
327
+ type: z.ZodOptional<z.ZodEnum<{
328
+ image: "image";
329
+ video: "video";
330
+ audio: "audio";
331
+ text: "text";
332
+ mesh3d: "mesh3d";
333
+ json: "json";
334
+ }>>;
335
+ required: z.ZodOptional<z.ZodBoolean>;
336
+ cardinality: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
337
+ one: "one";
338
+ many: "many";
339
+ }>>>;
340
+ default: z.ZodOptional<z.ZodNullable<z.ZodType<JsonNonNullValue, unknown, z.core.$ZodTypeInternals<JsonNonNullValue, unknown>>>>;
341
+ label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
342
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
343
+ }, z.core.$strict>;
344
+ }, z.core.$strip>], "kind">, z.ZodObject<{
345
+ type: z.ZodLiteral<"setNodeSetting">;
346
+ id: z.ZodString;
347
+ key: z.ZodString;
348
+ value: z.ZodNullable<z.ZodType<JsonNonNullValue, unknown, z.core.$ZodTypeInternals<JsonNonNullValue, unknown>>>;
349
+ }, z.core.$strip>, z.ZodObject<{
350
+ type: z.ZodLiteral<"setBakedInput">;
351
+ id: z.ZodString;
352
+ key: z.ZodString;
353
+ binding: z.ZodNullable<z.ZodObject<{
354
+ kind: z.ZodLiteral<"literal">;
355
+ value: z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>;
356
+ }, z.core.$strip>>;
357
+ }, z.core.$strip>, z.ZodObject<{
358
+ type: z.ZodLiteral<"connect">;
359
+ source: z.ZodString;
360
+ target: z.ZodString;
361
+ port: z.ZodEnum<{
362
+ image: "image";
363
+ video: "video";
364
+ audio: "audio";
365
+ text: "text";
366
+ mask: "mask";
367
+ mesh3d: "mesh3d";
368
+ json: "json";
369
+ }>;
370
+ index: z.ZodOptional<z.ZodNumber>;
371
+ }, z.core.$strip>, z.ZodObject<{
372
+ type: z.ZodLiteral<"disconnect">;
373
+ source: z.ZodString;
374
+ target: z.ZodString;
375
+ port: z.ZodEnum<{
376
+ image: "image";
377
+ video: "video";
378
+ audio: "audio";
379
+ text: "text";
380
+ mask: "mask";
381
+ mesh3d: "mesh3d";
382
+ json: "json";
383
+ }>;
384
+ }, z.core.$strip>, z.ZodObject<{
385
+ type: z.ZodLiteral<"exposeAsInput">;
386
+ id: z.ZodString;
387
+ name: z.ZodString;
388
+ required: z.ZodOptional<z.ZodBoolean>;
389
+ label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
390
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
391
+ default: z.ZodOptional<z.ZodNullable<z.ZodType<JsonNonNullValue, unknown, z.core.$ZodTypeInternals<JsonNonNullValue, unknown>>>>;
392
+ }, z.core.$strip>, z.ZodObject<{
393
+ type: z.ZodLiteral<"freezeInput">;
394
+ id: z.ZodString;
395
+ value: z.ZodString;
396
+ assetId: z.ZodOptional<z.ZodString>;
397
+ label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
398
+ }, z.core.$strip>, z.ZodObject<{
399
+ type: z.ZodLiteral<"setActiveGeneration">;
400
+ id: z.ZodString;
401
+ generationId: z.ZodNullable<z.ZodString>;
402
+ }, z.core.$strip>, z.ZodObject<{
403
+ type: z.ZodLiteral<"setLayout">;
404
+ id: z.ZodString;
405
+ position: z.ZodNullable<z.ZodObject<{
406
+ x: z.ZodNumber;
407
+ y: z.ZodNumber;
408
+ }, z.core.$strip>>;
409
+ }, z.core.$strip>, z.ZodObject<{
410
+ type: z.ZodLiteral<"group">;
411
+ id: z.ZodString;
412
+ label: z.ZodOptional<z.ZodString>;
413
+ nodeIds: z.ZodArray<z.ZodString>;
414
+ index: z.ZodOptional<z.ZodNumber>;
415
+ }, z.core.$strip>, z.ZodObject<{
416
+ type: z.ZodLiteral<"ungroup">;
417
+ id: z.ZodString;
418
+ }, z.core.$strip>, z.ZodObject<{
419
+ type: z.ZodLiteral<"setGroupProps">;
420
+ id: z.ZodString;
421
+ props: z.ZodObject<{
422
+ label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
423
+ nodeIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
424
+ }, z.core.$strict>;
425
+ }, z.core.$strip>, z.ZodObject<{
426
+ type: z.ZodLiteral<"setDocumentProps">;
427
+ props: z.ZodObject<{
428
+ label: z.ZodOptional<z.ZodString>;
429
+ }, z.core.$strict>;
430
+ }, z.core.$strip>], "type">;
431
+ type Op = z.infer<typeof OpSchema>;
432
+ /** The shape every write shares (S1 adds the revision and idempotency
433
+ * semantics on the server). */
434
+ declare const PatchSchema: z.ZodObject<{
435
+ baseRevision: z.ZodNumber;
436
+ ops: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
437
+ type: z.ZodLiteral<"addNode">;
438
+ node: z.ZodDiscriminatedUnion<[z.ZodObject<{
439
+ id: z.ZodString;
440
+ kind: z.ZodLiteral<"task">;
441
+ task: z.ZodEnum<{
442
+ "text-to-image": "text-to-image";
443
+ "image-to-image": "image-to-image";
444
+ "image-edit": "image-edit";
445
+ "virtual-try-on": "virtual-try-on";
446
+ "text-to-video": "text-to-video";
447
+ "image-to-video": "image-to-video";
448
+ "video-to-video": "video-to-video";
449
+ "video-enhance": "video-enhance";
450
+ "text-to-3d": "text-to-3d";
451
+ "image-to-3d": "image-to-3d";
452
+ "multiview-to-3d": "multiview-to-3d";
453
+ remesh: "remesh";
454
+ texture: "texture";
455
+ "text-to-audio": "text-to-audio";
456
+ "text-to-speech": "text-to-speech";
457
+ "speech-to-text": "speech-to-text";
458
+ "speech-to-speech": "speech-to-speech";
459
+ "image-to-text": "image-to-text";
460
+ "image-to-json": "image-to-json";
461
+ judge: "judge";
462
+ "text-generation": "text-generation";
463
+ upscale: "upscale";
464
+ "background-remove": "background-remove";
465
+ segmentation: "segmentation";
466
+ }>;
467
+ model: z.ZodDefault<z.ZodString>;
468
+ prompt: z.ZodDefault<z.ZodString>;
469
+ settings: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodType<JsonNonNullValue, unknown, z.core.$ZodTypeInternals<JsonNonNullValue, unknown>>>>;
470
+ bakedInputs: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
471
+ kind: z.ZodLiteral<"literal">;
472
+ value: z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>;
473
+ }, z.core.$strip>>>;
474
+ activeGeneration: z.ZodOptional<z.ZodString>;
475
+ label: z.ZodOptional<z.ZodString>;
476
+ }, z.core.$strip>, z.ZodObject<{
477
+ id: z.ZodString;
478
+ kind: z.ZodLiteral<"prompt-source">;
479
+ text: z.ZodDefault<z.ZodString>;
480
+ label: z.ZodOptional<z.ZodString>;
481
+ }, z.core.$strip>, z.ZodObject<{
482
+ id: z.ZodString;
483
+ kind: z.ZodLiteral<"image-source">;
484
+ imageUrl: z.ZodDefault<z.ZodString>;
485
+ assetId: z.ZodOptional<z.ZodString>;
486
+ label: z.ZodOptional<z.ZodString>;
487
+ }, z.core.$strip>, z.ZodObject<{
488
+ id: z.ZodString;
489
+ kind: z.ZodLiteral<"input">;
490
+ name: z.ZodString;
491
+ type: z.ZodEnum<{
492
+ image: "image";
493
+ video: "video";
494
+ audio: "audio";
495
+ text: "text";
496
+ mesh3d: "mesh3d";
497
+ json: "json";
498
+ }>;
499
+ required: z.ZodDefault<z.ZodBoolean>;
500
+ cardinality: z.ZodOptional<z.ZodEnum<{
501
+ one: "one";
502
+ many: "many";
503
+ }>>;
504
+ default: z.ZodOptional<z.ZodType<JsonNonNullValue, unknown, z.core.$ZodTypeInternals<JsonNonNullValue, unknown>>>;
505
+ label: z.ZodOptional<z.ZodString>;
506
+ description: z.ZodOptional<z.ZodString>;
507
+ }, z.core.$strip>], "kind">;
508
+ position: z.ZodOptional<z.ZodObject<{
509
+ x: z.ZodNumber;
510
+ y: z.ZodNumber;
511
+ }, z.core.$strip>>;
512
+ index: z.ZodOptional<z.ZodNumber>;
513
+ }, z.core.$strip>, z.ZodObject<{
514
+ type: z.ZodLiteral<"removeNode">;
515
+ id: z.ZodString;
516
+ }, z.core.$strip>, z.ZodDiscriminatedUnion<[z.ZodObject<{
517
+ type: z.ZodLiteral<"setNodeProps">;
518
+ kind: z.ZodLiteral<"task">;
519
+ id: z.ZodString;
520
+ props: z.ZodObject<{
521
+ task: z.ZodOptional<z.ZodEnum<{
522
+ "text-to-image": "text-to-image";
523
+ "image-to-image": "image-to-image";
524
+ "image-edit": "image-edit";
525
+ "virtual-try-on": "virtual-try-on";
526
+ "text-to-video": "text-to-video";
527
+ "image-to-video": "image-to-video";
528
+ "video-to-video": "video-to-video";
529
+ "video-enhance": "video-enhance";
530
+ "text-to-3d": "text-to-3d";
531
+ "image-to-3d": "image-to-3d";
532
+ "multiview-to-3d": "multiview-to-3d";
533
+ remesh: "remesh";
534
+ texture: "texture";
535
+ "text-to-audio": "text-to-audio";
536
+ "text-to-speech": "text-to-speech";
537
+ "speech-to-text": "speech-to-text";
538
+ "speech-to-speech": "speech-to-speech";
539
+ "image-to-text": "image-to-text";
540
+ "image-to-json": "image-to-json";
541
+ judge: "judge";
542
+ "text-generation": "text-generation";
543
+ upscale: "upscale";
544
+ "background-remove": "background-remove";
545
+ segmentation: "segmentation";
546
+ }>>;
547
+ model: z.ZodOptional<z.ZodString>;
548
+ prompt: z.ZodOptional<z.ZodString>;
549
+ label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
550
+ }, z.core.$strict>;
551
+ }, z.core.$strip>, z.ZodObject<{
552
+ type: z.ZodLiteral<"setNodeProps">;
553
+ kind: z.ZodLiteral<"prompt-source">;
554
+ id: z.ZodString;
555
+ props: z.ZodObject<{
556
+ text: z.ZodOptional<z.ZodString>;
557
+ label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
558
+ }, z.core.$strict>;
559
+ }, z.core.$strip>, z.ZodObject<{
560
+ type: z.ZodLiteral<"setNodeProps">;
561
+ kind: z.ZodLiteral<"image-source">;
562
+ id: z.ZodString;
563
+ props: z.ZodObject<{
564
+ imageUrl: z.ZodOptional<z.ZodString>;
565
+ assetId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
566
+ label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
567
+ }, z.core.$strict>;
568
+ }, z.core.$strip>, z.ZodObject<{
569
+ type: z.ZodLiteral<"setNodeProps">;
570
+ kind: z.ZodLiteral<"input">;
571
+ id: z.ZodString;
572
+ props: z.ZodObject<{
573
+ name: z.ZodOptional<z.ZodString>;
574
+ type: z.ZodOptional<z.ZodEnum<{
575
+ image: "image";
576
+ video: "video";
577
+ audio: "audio";
578
+ text: "text";
579
+ mesh3d: "mesh3d";
580
+ json: "json";
581
+ }>>;
582
+ required: z.ZodOptional<z.ZodBoolean>;
583
+ cardinality: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
584
+ one: "one";
585
+ many: "many";
586
+ }>>>;
587
+ default: z.ZodOptional<z.ZodNullable<z.ZodType<JsonNonNullValue, unknown, z.core.$ZodTypeInternals<JsonNonNullValue, unknown>>>>;
588
+ label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
589
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
590
+ }, z.core.$strict>;
591
+ }, z.core.$strip>], "kind">, z.ZodObject<{
592
+ type: z.ZodLiteral<"setNodeSetting">;
593
+ id: z.ZodString;
594
+ key: z.ZodString;
595
+ value: z.ZodNullable<z.ZodType<JsonNonNullValue, unknown, z.core.$ZodTypeInternals<JsonNonNullValue, unknown>>>;
596
+ }, z.core.$strip>, z.ZodObject<{
597
+ type: z.ZodLiteral<"setBakedInput">;
598
+ id: z.ZodString;
599
+ key: z.ZodString;
600
+ binding: z.ZodNullable<z.ZodObject<{
601
+ kind: z.ZodLiteral<"literal">;
602
+ value: z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>;
603
+ }, z.core.$strip>>;
604
+ }, z.core.$strip>, z.ZodObject<{
605
+ type: z.ZodLiteral<"connect">;
606
+ source: z.ZodString;
607
+ target: z.ZodString;
608
+ port: z.ZodEnum<{
609
+ image: "image";
610
+ video: "video";
611
+ audio: "audio";
612
+ text: "text";
613
+ mask: "mask";
614
+ mesh3d: "mesh3d";
615
+ json: "json";
616
+ }>;
617
+ index: z.ZodOptional<z.ZodNumber>;
618
+ }, z.core.$strip>, z.ZodObject<{
619
+ type: z.ZodLiteral<"disconnect">;
620
+ source: z.ZodString;
621
+ target: z.ZodString;
622
+ port: z.ZodEnum<{
623
+ image: "image";
624
+ video: "video";
625
+ audio: "audio";
626
+ text: "text";
627
+ mask: "mask";
628
+ mesh3d: "mesh3d";
629
+ json: "json";
630
+ }>;
631
+ }, z.core.$strip>, z.ZodObject<{
632
+ type: z.ZodLiteral<"exposeAsInput">;
633
+ id: z.ZodString;
634
+ name: z.ZodString;
635
+ required: z.ZodOptional<z.ZodBoolean>;
636
+ label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
637
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
638
+ default: z.ZodOptional<z.ZodNullable<z.ZodType<JsonNonNullValue, unknown, z.core.$ZodTypeInternals<JsonNonNullValue, unknown>>>>;
639
+ }, z.core.$strip>, z.ZodObject<{
640
+ type: z.ZodLiteral<"freezeInput">;
641
+ id: z.ZodString;
642
+ value: z.ZodString;
643
+ assetId: z.ZodOptional<z.ZodString>;
644
+ label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
645
+ }, z.core.$strip>, z.ZodObject<{
646
+ type: z.ZodLiteral<"setActiveGeneration">;
647
+ id: z.ZodString;
648
+ generationId: z.ZodNullable<z.ZodString>;
649
+ }, z.core.$strip>, z.ZodObject<{
650
+ type: z.ZodLiteral<"setLayout">;
651
+ id: z.ZodString;
652
+ position: z.ZodNullable<z.ZodObject<{
653
+ x: z.ZodNumber;
654
+ y: z.ZodNumber;
655
+ }, z.core.$strip>>;
656
+ }, z.core.$strip>, z.ZodObject<{
657
+ type: z.ZodLiteral<"group">;
658
+ id: z.ZodString;
659
+ label: z.ZodOptional<z.ZodString>;
660
+ nodeIds: z.ZodArray<z.ZodString>;
661
+ index: z.ZodOptional<z.ZodNumber>;
662
+ }, z.core.$strip>, z.ZodObject<{
663
+ type: z.ZodLiteral<"ungroup">;
664
+ id: z.ZodString;
665
+ }, z.core.$strip>, z.ZodObject<{
666
+ type: z.ZodLiteral<"setGroupProps">;
667
+ id: z.ZodString;
668
+ props: z.ZodObject<{
669
+ label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
670
+ nodeIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
671
+ }, z.core.$strict>;
672
+ }, z.core.$strip>, z.ZodObject<{
673
+ type: z.ZodLiteral<"setDocumentProps">;
674
+ props: z.ZodObject<{
675
+ label: z.ZodOptional<z.ZodString>;
676
+ }, z.core.$strict>;
677
+ }, z.core.$strip>], "type">>;
678
+ idempotencyKey: z.ZodOptional<z.ZodString>;
679
+ }, z.core.$strip>;
680
+ type Patch = z.infer<typeof PatchSchema>;
681
+ type OpErrorCode = "invalid" | "not_found" | "conflict" | "invalid_port" | "cardinality" | "cycle" | "unsupported" | "limit" | "integrity" | "schema";
682
+ interface ApplyError {
683
+ /** Index into the submitted ops of the op that failed. */
684
+ opIndex: number;
685
+ code: OpErrorCode;
686
+ message: string;
687
+ }
688
+
689
+ /**
690
+ * The projection pair between the canvas-facing WorkflowDocument and the
691
+ * executor-facing WorkflowDefinition (plan `2026-08-23-workflow-command-model.md`,
692
+ * D2 and D3).
693
+ *
694
+ * documentToDefinition: the RUNNABILITY gate. A document is a legal editing
695
+ * state even when incomplete (E12); projecting it is where "no model", "a
696
+ * required prompt is empty", "that image is still uploading" become per-node
697
+ * issues a run dialog or an API `validate` can list. Input nodes become the
698
+ * definition's `params`, wires from them become `param` bindings, wires from
699
+ * literal sources bake to literals, wires from task nodes become `ref`
700
+ * bindings, settings bake through `settingsBindings`, baked literals merge in
701
+ * for keys nothing else produced.
702
+ *
703
+ * definitionToDocument: the legacy import. Every saved holder, curated
704
+ * definition and API-created definition converts to a document, LOSSLESSLY
705
+ * for what the document can represent, loudly for what it cannot: a `param`
706
+ * binding on a key that is not a wireable port fails the import instead of
707
+ * being dropped (the `params: []` loss this plan exists to end), a second
708
+ * binding on a key that is not the port's canonical key (`endImageUrl` next
709
+ * to `inputImageUrl`) is kept as the definition's binding and reported
710
+ * `lossy` (S2 adds named slots). A layout snapshot adds geometry, source
711
+ * nodes and authoring fields on top of the definition; it never removes a
712
+ * definition node or dependency (a stale snapshot is noted, not trusted).
713
+ *
714
+ * Pure: no database, no provider, no DOM.
715
+ */
716
+
717
+ type ProjectionIssueCode = "no_task_nodes" | "not_runnable" | "no_model" | "prompt_required" | "source_uploading" | "no_inputs" | "param_unmappable" | "param_type_conflict" | "integrity";
718
+ interface ProjectionIssue {
719
+ code: ProjectionIssueCode;
720
+ /** The node the issue is about, when it is about one. */
721
+ nodeId?: string;
722
+ message: string;
723
+ }
724
+
725
+ /**
726
+ * Server configuration, resolved from the environment once at startup.
727
+ *
728
+ * `LUMITRA_STUDIO_API_KEY` is the bearer token. The legacy name
729
+ * `LUMITRA_STUDIO_SERVICE_TOKEN` (the batch skill + lola-stories backend) is
730
+ * accepted as a fallback so an existing cc.sh-injected environment works
731
+ * unchanged. The token is held in memory only: nothing in this package ever
732
+ * logs, echoes, or serializes it (see `redactSecret` in errors.ts).
733
+ *
734
+ * Placeholder handling: the Agent Plugins spec only guarantees expansion of
735
+ * `${PLUGIN_ROOT}` / `${PLUGIN_DATA}` in a plugin's `.mcp.json`, so some
736
+ * clients hand the server the literal string "${LUMITRA_STUDIO_API_KEY}" as the
737
+ * env value. Any value that still looks like an unexpanded `${...}` reference is
738
+ * treated as UNSET and the variable is read from `process.env` instead.
739
+ */
740
+ declare const DEFAULT_BASE_URL = "https://studio.lumitra.co";
741
+ interface StudioConfig {
742
+ /** Studio origin, no trailing slash. */
743
+ baseUrl: string;
744
+ /** Bearer token. */
745
+ apiKey: string;
746
+ }
747
+ declare class ConfigError extends Error {
748
+ constructor(message: string);
749
+ }
750
+ declare function resolveConfig(env?: Readonly<Record<string, string | undefined>>): StudioConfig;
751
+
752
+ /**
753
+ * Thin typed client over the Lumitra Studio HTTP API. Pure `fetch`: no Prisma,
754
+ * no server imports. Every method mirrors one route in `src/app/api/**` of the
755
+ * Studio app; the request shapes here ARE the contract the tool layer relies on.
756
+ */
757
+
758
+ type FetchLike = (input: string, init?: RequestInit) => Promise<Response>;
759
+ interface ProjectSummary {
760
+ id: string;
761
+ slug: string;
762
+ name: string;
763
+ }
764
+ type JobStatus = 'queued' | 'running' | 'succeeded' | 'failed' | 'canceled' | (string & {});
765
+ interface JobResponse {
766
+ job: {
767
+ id: string;
768
+ status: JobStatus;
769
+ kind?: string;
770
+ model?: string | null;
771
+ costUsd?: number | null;
772
+ errorMessage?: string | null;
773
+ [k: string]: unknown;
774
+ };
775
+ resultAsset: {
776
+ id?: string;
777
+ url: string;
778
+ mimeType?: string | null;
779
+ [k: string]: unknown;
780
+ } | null;
781
+ resultAssets?: Array<{
782
+ id?: string;
783
+ url: string;
784
+ [k: string]: unknown;
785
+ }>;
786
+ }
787
+ interface CharacterSummary {
788
+ slug: string;
789
+ name: string;
790
+ descriptorPrompt: string;
791
+ negativePrompt?: string | null;
792
+ defaultModel?: string | null;
793
+ }
794
+ interface CharacterReference {
795
+ id: string;
796
+ category: string;
797
+ url: string;
798
+ label?: string | null;
799
+ sortOrder?: number;
800
+ [k: string]: unknown;
801
+ }
802
+ /** `awaiting_decision` (P3 J2) is a run PARKED on a human decision at a judge
803
+ * node: not terminal, not a failure, and polling will never clear it. */
804
+ type RunStatus = 'pending' | 'running' | 'succeeded' | 'failed' | 'partial' | 'awaiting_decision' | (string & {});
805
+ type NodeStatus = 'pending' | 'running' | 'succeeded' | 'failed' | 'awaiting_decision' | (string & {});
806
+ /** One candidate a parked judge node is waiting on a decision about. The url
807
+ * is signed per response; `generationId` is what a decision names. */
808
+ interface JudgeCandidate {
809
+ url: string;
810
+ kind?: string;
811
+ mime?: string | null;
812
+ assetId?: string | null;
813
+ generationId: string;
814
+ index: number;
815
+ nodeId: string;
816
+ }
817
+ interface NodeRun {
818
+ nodeId: string;
819
+ status: NodeStatus;
820
+ jobId?: string | null;
821
+ resultUrl?: string | null;
822
+ results?: Array<{
823
+ url: string;
824
+ kind?: string;
825
+ mime?: string | null;
826
+ text?: string;
827
+ json?: unknown;
828
+ }>;
829
+ costUsd?: number | null;
830
+ errorMessage?: string | null;
831
+ /** Present only while this node is `awaiting_decision`: what a person is
832
+ * being asked to choose between. */
833
+ candidates?: JudgeCandidate[];
834
+ [k: string]: unknown;
835
+ }
836
+ interface RunResponse {
837
+ run: {
838
+ id: string;
839
+ status: RunStatus;
840
+ definition?: unknown;
841
+ params?: unknown;
842
+ savedId?: string | null;
843
+ /** Run-level failure text. Carries a recipe run's post-run EFFECT failure
844
+ * (S10): the generation can succeed while a declared effect, e.g. minting
845
+ * the character, did not. Distinct from a node's own errorMessage. */
846
+ errorMessage?: string | null;
847
+ [k: string]: unknown;
848
+ };
849
+ nodeRuns: NodeRun[];
850
+ }
851
+ interface RunStartResponse {
852
+ runId: string;
853
+ runIds: string[];
854
+ status: RunStatus;
855
+ }
856
+ interface NodeResultResponse {
857
+ url: string;
858
+ kind?: string;
859
+ mime?: string | null;
860
+ assetId?: string;
861
+ }
862
+ interface SpendLedger {
863
+ summary: {
864
+ today: {
865
+ totalUsd: number;
866
+ jobCount: number;
867
+ };
868
+ sevenDay: {
869
+ totalUsd: number;
870
+ jobCount: number;
871
+ };
872
+ thirtyDay: {
873
+ totalUsd: number;
874
+ jobCount: number;
875
+ };
876
+ };
877
+ recent: unknown[];
878
+ }
879
+ interface UploadFile {
880
+ data: Blob;
881
+ filename: string;
882
+ }
883
+ /** One model's realized spend + job count within the tenant's current month. */
884
+ interface UsageByModel {
885
+ model: string;
886
+ usedUsd: number;
887
+ jobs: number;
888
+ }
889
+ /** One tenant's row in the cross-tenant admin view (`AllTenantsUsageResponse`):
890
+ * realized spend only, no per-tenant plan lookup. Note `usedUsd` here means
891
+ * something narrower than `TenantUsageResponse.usedUsd` below (realized only,
892
+ * no in-flight estimate): this view has no per-job estimate to add, only the
893
+ * settled ledger, so the two fields are not directly comparable across the
894
+ * two response shapes despite sharing a name. */
895
+ interface TenantSpendSummary {
896
+ tenantId: string | null;
897
+ month: string;
898
+ usedUsd: number;
899
+ jobs: number;
900
+ byModel: UsageByModel[];
901
+ }
902
+ /** `GET /api/v1/usage` for a scoped caller (own tenant, or the dev bypass's
903
+ * zeroed shape when it has no active company). No `tenants` field at all
904
+ * (not even optional-undefined): that is what lets `'tenants' in result`
905
+ * correctly narrow the `UsageResponse` union below. */
906
+ interface TenantUsageResponse {
907
+ tenantId?: string;
908
+ month: string;
909
+ plan: string;
910
+ capUsd: number | null;
911
+ rpm: number | null;
912
+ /** Realized + in-flight estimated: the same total the quota guard checks
913
+ * against and a 402 body's `usedUsd` reports. */
914
+ usedUsd: number;
915
+ realizedUsd: number;
916
+ inFlightEstimatedUsd: number;
917
+ jobs: number;
918
+ byModel: UsageByModel[];
919
+ }
920
+ /** `GET /api/v1/usage` for the dev bypass: the cross-tenant admin variant
921
+ * (docs/plans/2026-08-21-studio-api-keys-and-quotas.md, scope item 2). */
922
+ interface AllTenantsUsageResponse {
923
+ month: string;
924
+ tenants: TenantSpendSummary[];
925
+ }
926
+ type UsageResponse = TenantUsageResponse | AllTenantsUsageResponse;
927
+ /** One task type as `GET /api/v1/node-types` describes it. */
928
+ interface TaskDescriptor {
929
+ task: string;
930
+ label: string;
931
+ family: string;
932
+ modality: string;
933
+ jobKind: string | null;
934
+ runnable: boolean;
935
+ output: string;
936
+ inputs: Array<{
937
+ port: string;
938
+ wireable: boolean;
939
+ cardinality: 'one' | 'none';
940
+ binding: {
941
+ key: string;
942
+ path: string;
943
+ wrap?: string;
944
+ } | null;
945
+ }>;
946
+ prompt: {
947
+ needed: boolean;
948
+ required: boolean;
949
+ key: string;
950
+ } | null;
951
+ settings: unknown[];
952
+ models: Array<{
953
+ id: string;
954
+ label?: string;
955
+ provider?: string;
956
+ }>;
957
+ }
958
+ interface NodeTypesResponse {
959
+ tasks: TaskDescriptor[];
960
+ inputTypes: string[];
961
+ opTypes: string[];
962
+ limits: {
963
+ maxPatchOps: number;
964
+ };
965
+ }
966
+ /** The runnability verdict of a document: ok, or the per-node issue list. */
967
+ interface Projection {
968
+ ok: boolean;
969
+ issues: ProjectionIssue[];
970
+ }
971
+ /**
972
+ * `GET /api/v1/workflows/:savedId`. A workflow whose stored definition binds a
973
+ * run param the canvas cannot wire is served READ-ONLY: `readOnly: true`,
974
+ * `document: null`, and the legacy `definition` + `canvasLayout` instead. It
975
+ * stays readable and runnable, it just cannot be patched.
976
+ */
977
+ interface WorkflowDocumentResponse {
978
+ savedId: string;
979
+ revision: number;
980
+ document: WorkflowDocument | null;
981
+ projection: Projection;
982
+ label: string;
983
+ readOnly?: boolean;
984
+ /** Legacy revision alias the older readers use. */
985
+ version?: number;
986
+ /** The executor-facing projection (read-only reads carry the stored one). */
987
+ definition?: unknown;
988
+ canvasLayout?: unknown;
989
+ /** False until the first patch materializes an imported legacy holder. */
990
+ materialized?: boolean;
991
+ /** Set when the stored definition could not be imported losslessly. */
992
+ lossy?: boolean;
993
+ notes?: unknown;
994
+ }
995
+ /** `POST /api/v1/workflows` with `{ ops }`: 201. */
996
+ interface WorkflowCreateResponse {
997
+ savedId: string;
998
+ revision: number;
999
+ document: WorkflowDocument;
1000
+ projection?: Projection;
1001
+ }
1002
+ /** `PATCH /api/v1/workflows/:savedId`: 200. */
1003
+ interface WorkflowApplyResponse {
1004
+ revision: number;
1005
+ /** The ops as applied (cascades expanded), exactly replayable. */
1006
+ applied: Op[];
1007
+ /** The exact inverse, in undo order. */
1008
+ inverse: Op[];
1009
+ document: WorkflowDocument;
1010
+ projection?: Projection;
1011
+ /** True when an idempotency key replayed an earlier result (E3). */
1012
+ replayed?: boolean;
1013
+ }
1014
+ /** `POST /api/v1/workflows/validate`: 200, returned to the agent as-is. */
1015
+ interface WorkflowValidateResponse {
1016
+ apply: {
1017
+ ok: boolean;
1018
+ error?: ApplyError;
1019
+ } | null;
1020
+ document: {
1021
+ ok: boolean;
1022
+ code?: string;
1023
+ message?: string;
1024
+ };
1025
+ projection: {
1026
+ ok: boolean;
1027
+ issues: ProjectionIssue[];
1028
+ params?: unknown;
1029
+ };
1030
+ run: {
1031
+ ok: boolean;
1032
+ issues: unknown[];
1033
+ optionalEmpty?: unknown;
1034
+ } | null;
1035
+ }
1036
+ interface StudioClientOptions {
1037
+ fetch?: FetchLike;
1038
+ /** Per-request timeout for plain API calls (uploads get 4x). */
1039
+ requestTimeoutMs?: number;
1040
+ userAgent?: string;
1041
+ }
1042
+ declare class StudioClient {
1043
+ #private;
1044
+ readonly baseUrl: string;
1045
+ constructor(config: StudioConfig, opts?: StudioClientOptions);
1046
+ /** Strip the bearer token from any string before it can reach a caller. */
1047
+ redact(text: string): string;
1048
+ listProjects(): Promise<{
1049
+ projects: ProjectSummary[];
1050
+ }>;
1051
+ generate(body: {
1052
+ brandSlug: string;
1053
+ brandMode?: string;
1054
+ prompt: string;
1055
+ characterSlug?: string;
1056
+ settings?: Record<string, unknown>;
1057
+ }): Promise<{
1058
+ jobId: string;
1059
+ kind: string;
1060
+ }>;
1061
+ getJob(jobId: string): Promise<JobResponse>;
1062
+ listCharacters(): Promise<{
1063
+ characters: CharacterSummary[];
1064
+ }>;
1065
+ getCharacter(slug: string): Promise<{
1066
+ character: CharacterSummary & {
1067
+ references?: CharacterReference[];
1068
+ [k: string]: unknown;
1069
+ };
1070
+ }>;
1071
+ createCharacter(body: {
1072
+ name: string;
1073
+ slug: string;
1074
+ descriptorPrompt: string;
1075
+ negativePrompt?: string;
1076
+ defaultModel?: string;
1077
+ }): Promise<{
1078
+ character: CharacterSummary;
1079
+ }>;
1080
+ uploadCharacterReference(slug: string, input: {
1081
+ file: UploadFile;
1082
+ category: string;
1083
+ label?: string;
1084
+ }): Promise<{
1085
+ reference: CharacterReference;
1086
+ }>;
1087
+ createBrand(body: {
1088
+ name: string;
1089
+ slug: string;
1090
+ stylePrefix?: string;
1091
+ context?: string;
1092
+ defaultModel?: string;
1093
+ maxReferenceImages?: number;
1094
+ }): Promise<{
1095
+ config: Record<string, unknown>;
1096
+ }>;
1097
+ uploadBrandReference(slug: string, input: {
1098
+ file: UploadFile;
1099
+ category?: string;
1100
+ label?: string;
1101
+ tags?: string[];
1102
+ score?: number;
1103
+ }): Promise<{
1104
+ reference: Record<string, unknown>;
1105
+ }>;
1106
+ runWorkflow(body: {
1107
+ projectId: string;
1108
+ definition?: unknown;
1109
+ definitionId?: string;
1110
+ params?: Record<string, unknown>;
1111
+ nodeIds?: string[];
1112
+ runs?: number;
1113
+ savedId?: string;
1114
+ visibility?: 'listed' | 'unlisted';
1115
+ /** S6b: hard cap on the run's estimated cost; a 400 { code: "budget_exceeded" }
1116
+ * refuses before anything is created. See the run route's own doc comment. */
1117
+ budgetUsd?: number;
1118
+ /** S6b: bypasses a per-key confirmation threshold for this one request. */
1119
+ confirm?: boolean;
1120
+ }): Promise<RunStartResponse>;
1121
+ getRun(runId: string): Promise<RunResponse>;
1122
+ /** Submit a human decision on a parked judge node (P3 J2). Approving
1123
+ * resumes the run from that node; rejecting fails it and stops the branch. */
1124
+ decideJudgeNode(runId: string, nodeId: string, body: {
1125
+ verdict: 'approved' | 'rejected';
1126
+ candidate?: {
1127
+ generationId: string;
1128
+ index?: number;
1129
+ };
1130
+ reason?: string;
1131
+ }): Promise<{
1132
+ nodeId: string;
1133
+ status: string;
1134
+ runStatus: string;
1135
+ }>;
1136
+ getRunNodeUrl(runId: string, nodeId: string): Promise<NodeResultResponse>;
1137
+ /** S9: a rendered diagram of a saved workflow's document, so an agent can
1138
+ * see the graph it just built. */
1139
+ getWorkflowScreenshot(savedId: string): Promise<{
1140
+ url: string;
1141
+ width: number;
1142
+ height: number;
1143
+ }>;
1144
+ publishWorkflow(savedId: string, body: {
1145
+ slug: string;
1146
+ effects?: unknown[];
1147
+ }): Promise<{
1148
+ slug: string;
1149
+ revision: number;
1150
+ }>;
1151
+ unpublishWorkflow(savedId: string): Promise<{
1152
+ ok: true;
1153
+ }>;
1154
+ listPublished(): Promise<{
1155
+ recipes: Array<{
1156
+ slug: string;
1157
+ label: string;
1158
+ publishedRevision: number | null;
1159
+ updatedAt: string;
1160
+ hasEffects: boolean;
1161
+ }>;
1162
+ }>;
1163
+ describePublished(slug: string): Promise<{
1164
+ slug: string;
1165
+ definition: unknown;
1166
+ hasEffects: boolean;
1167
+ }>;
1168
+ runPublished(slug: string, body: {
1169
+ projectId: string;
1170
+ params?: Record<string, unknown>;
1171
+ /** Same S6b hard cap as runWorkflow's; a 400 { code: "budget_exceeded" }
1172
+ * refuses before anything is created. */
1173
+ budgetUsd?: number;
1174
+ /** Bypasses the $10 confirmation threshold for this one request. */
1175
+ confirm?: boolean;
1176
+ }): Promise<{
1177
+ runId: string;
1178
+ status: string;
1179
+ optionalEmpty?: string[];
1180
+ }>;
1181
+ saveWorkflow(body: {
1182
+ definition: unknown;
1183
+ canvasLayout: unknown;
1184
+ label: string;
1185
+ savedId?: string;
1186
+ }): Promise<Record<string, unknown>>;
1187
+ describeNodeTypes(): Promise<NodeTypesResponse>;
1188
+ /** `savedId` carries a `saved:` prefix; the colon is URL-encoded. */
1189
+ getWorkflowDocument(savedId: string): Promise<WorkflowDocumentResponse>;
1190
+ /** Create a document by applying `ops` to an empty one (the same code path as apply). */
1191
+ createWorkflow(body: {
1192
+ ops: Op[];
1193
+ label?: string;
1194
+ projectId?: string;
1195
+ }): Promise<WorkflowCreateResponse>;
1196
+ /**
1197
+ * Apply a patch atomically on top of `patch.baseRevision`. 409 on a stale
1198
+ * base; 422 when the workflow is not editable, imports with loss and has not
1199
+ * been acknowledged, or the idempotency key belongs to a different patch.
1200
+ */
1201
+ applyWorkflowPatch(savedId: string, patch: Patch & {
1202
+ acknowledgeLossy?: boolean;
1203
+ }): Promise<WorkflowApplyResponse>;
1204
+ /** Stateless dry-run of ops and run params against a document. No side effects. */
1205
+ validateWorkflow(body: {
1206
+ document: WorkflowDocument;
1207
+ ops?: Op[];
1208
+ params?: Record<string, unknown>;
1209
+ }): Promise<WorkflowValidateResponse>;
1210
+ getSpend(tzOffsetMinutes?: number): Promise<SpendLedger>;
1211
+ /**
1212
+ * The metering read model (docs/plans/2026-08-21-studio-api-keys-and-quotas.md,
1213
+ * scope item 2): this key's month-to-date usage against its tenant's plan
1214
+ * (cap, rpm), broken down by model.
1215
+ */
1216
+ getUsage(): Promise<UsageResponse>;
1217
+ /**
1218
+ * Download a (signed) asset URL to bytes. Goes through the same fetch so tests
1219
+ * can intercept it; no auth header is sent to a foreign host.
1220
+ */
1221
+ downloadUrl(url: string): Promise<UploadFile>;
1222
+ private json;
1223
+ }
1224
+ declare function filenameFromUrl(url: string, mime: string): string;
1225
+ declare function extensionForMime(mime: string): string | null;
1226
+ declare function mimeForFilename(name: string): string;
1227
+
1228
+ /**
1229
+ * Polling with a wall-clock timeout and exponential backoff. Injected clock +
1230
+ * sleep so tests run instantly. Jobs and runs are long-lived server-side, so a
1231
+ * timeout here never cancels anything: it returns control to the agent with the
1232
+ * id to poll again.
1233
+ */
1234
+
1235
+ interface PollOptions {
1236
+ /** Overall budget in ms. Default 600s. */
1237
+ timeoutMs?: number;
1238
+ /** First wait. Default 2s. */
1239
+ initialDelayMs?: number;
1240
+ /** Cap on the wait between polls. Default 15s. */
1241
+ maxDelayMs?: number;
1242
+ /** Multiplier per poll. Default 1.5. */
1243
+ factor?: number;
1244
+ sleep?: (ms: number) => Promise<void>;
1245
+ now?: () => number;
1246
+ }
1247
+ declare const DEFAULT_TIMEOUT_MS = 600000;
1248
+ /**
1249
+ * Call `fetchState` until `isDone(state)` is true or the budget is exhausted.
1250
+ * Throws PollTimeoutError (carrying the last observed state) on timeout.
1251
+ */
1252
+ declare function pollUntil<T>(what: string, fetchState: () => Promise<T>, isDone: (state: T) => boolean, opts?: PollOptions): Promise<T>;
1253
+ declare function waitForJob(client: StudioClient, jobId: string, opts?: PollOptions): Promise<JobResponse>;
1254
+ declare function waitForRun(client: StudioClient, runId: string, opts?: PollOptions): Promise<RunResponse>;
1255
+
1256
+ /**
1257
+ * The shape of one tool in the catalog, shared by `tools.ts` (the recipe and
1258
+ * entity tools) and `workflowTools.ts` (the workflow command-model primitives)
1259
+ * so neither module has to import the other for its types.
1260
+ */
1261
+
1262
+ interface ToolContext {
1263
+ client: StudioClient;
1264
+ /** Poll tuning (tests inject a zero-delay sleep). */
1265
+ poll?: Omit<PollOptions, 'timeoutMs'>;
1266
+ }
1267
+ interface ToolDef<Shape extends z.ZodRawShape = z.ZodRawShape> {
1268
+ name: string;
1269
+ description: string;
1270
+ inputSchema: Shape;
1271
+ annotations?: {
1272
+ readOnlyHint?: boolean;
1273
+ destructiveHint?: boolean;
1274
+ idempotentHint?: boolean;
1275
+ };
1276
+ handler: (args: z.infer<z.ZodObject<Shape>>, ctx: ToolContext) => Promise<unknown>;
1277
+ }
1278
+
1279
+ /**
1280
+ * The full catalog in registration order. Names are a contract with the plugin.
1281
+ * The workflow command-model primitives (`studio_workflow_*`, plan
1282
+ * `2026-08-23-workflow-command-model.md` S4) follow the recipe and entity tools.
1283
+ */
1284
+ declare const TOOLS: readonly ToolDef<z.ZodRawShape>[];
1285
+ declare const TOOL_NAMES: readonly string[];
1286
+ /** What `invokeTool` hands back: the MCP result envelope, with `isError` set on a failure only. */
1287
+ type ToolResult = {
1288
+ isError?: undefined;
1289
+ content: Array<{
1290
+ type: 'text';
1291
+ text: string;
1292
+ }>;
1293
+ structuredContent: Record<string, unknown>;
1294
+ } | {
1295
+ isError: true;
1296
+ content: Array<{
1297
+ type: 'text';
1298
+ text: string;
1299
+ }>;
1300
+ };
1301
+ /**
1302
+ * Invoke a tool by definition with the error policy applied: any throw becomes
1303
+ * an MCP tool error whose text is the API's own message, redacted of the key.
1304
+ */
1305
+ declare function invokeTool<Shape extends z.ZodRawShape>(def: ToolDef<Shape>, args: unknown, ctx: ToolContext): Promise<ToolResult>;
1306
+ declare function registerTools(server: McpServer, ctx: ToolContext): void;
1307
+
1308
+ /**
1309
+ * Build an McpServer with the Studio tool catalog registered. Transport-agnostic:
1310
+ * cli.ts attaches stdio or Streamable HTTP.
1311
+ */
1312
+
1313
+ declare const SERVER_NAME = "lumitra-studio";
1314
+ declare const SERVER_VERSION = "0.1.0";
1315
+ interface CreateServerOptions {
1316
+ config?: StudioConfig;
1317
+ env?: NodeJS.ProcessEnv;
1318
+ fetch?: FetchLike;
1319
+ poll?: ToolContext['poll'];
1320
+ }
1321
+ interface StudioMcp {
1322
+ server: McpServer;
1323
+ client: StudioClient;
1324
+ }
1325
+ declare function createStudioMcpServer(opts?: CreateServerOptions): StudioMcp;
1326
+
1327
+ /**
1328
+ * Error types surfaced to MCP clients, plus the one redaction helper that
1329
+ * guarantees the bearer token can never leak through an error message, a log
1330
+ * line, or a tool result (a provider could echo request headers back in a 4xx
1331
+ * body; a misconfigured proxy could put them in a URL).
1332
+ */
1333
+ declare class StudioApiError extends Error {
1334
+ readonly status: number;
1335
+ readonly method: string;
1336
+ readonly path: string;
1337
+ readonly body: unknown;
1338
+ constructor(opts: {
1339
+ status: number;
1340
+ method: string;
1341
+ path: string;
1342
+ message: string;
1343
+ body?: unknown;
1344
+ });
1345
+ }
1346
+ declare class PollTimeoutError extends Error {
1347
+ readonly lastState: unknown;
1348
+ constructor(what: string, timeoutMs: number, lastState: unknown);
1349
+ }
1350
+ declare class ToolInputError extends Error {
1351
+ constructor(message: string);
1352
+ }
1353
+ /** Replace every occurrence of `secret` in `text` with a fixed marker. */
1354
+ declare function redactSecret(text: string, secret: string | undefined): string;
1355
+
1356
+ declare const studioWorkflowDescribe: ToolDef<{
1357
+ tasks: z.ZodOptional<z.ZodArray<z.ZodString>>;
1358
+ includeSettings: z.ZodDefault<z.ZodBoolean>;
1359
+ includeModels: z.ZodDefault<z.ZodBoolean>;
1360
+ }>;
1361
+ declare const studioWorkflowGet: ToolDef<{
1362
+ savedId: z.ZodString;
1363
+ full: z.ZodDefault<z.ZodBoolean>;
1364
+ }>;
1365
+ declare const studioWorkflowCreate: ToolDef<{
1366
+ ops: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
1367
+ type: z.ZodLiteral<"addNode">;
1368
+ node: z.ZodDiscriminatedUnion<[z.ZodObject<{
1369
+ id: z.ZodString;
1370
+ kind: z.ZodLiteral<"task">;
1371
+ task: z.ZodEnum<{
1372
+ "text-to-image": "text-to-image";
1373
+ "image-to-image": "image-to-image";
1374
+ "image-edit": "image-edit";
1375
+ "virtual-try-on": "virtual-try-on";
1376
+ "text-to-video": "text-to-video";
1377
+ "image-to-video": "image-to-video";
1378
+ "video-to-video": "video-to-video";
1379
+ "video-enhance": "video-enhance";
1380
+ "text-to-3d": "text-to-3d";
1381
+ "image-to-3d": "image-to-3d";
1382
+ "multiview-to-3d": "multiview-to-3d";
1383
+ remesh: "remesh";
1384
+ texture: "texture";
1385
+ "text-to-audio": "text-to-audio";
1386
+ "text-to-speech": "text-to-speech";
1387
+ "speech-to-text": "speech-to-text";
1388
+ "speech-to-speech": "speech-to-speech";
1389
+ "image-to-text": "image-to-text";
1390
+ "image-to-json": "image-to-json";
1391
+ judge: "judge";
1392
+ "text-generation": "text-generation";
1393
+ upscale: "upscale";
1394
+ "background-remove": "background-remove";
1395
+ segmentation: "segmentation";
1396
+ }>;
1397
+ model: z.ZodDefault<z.ZodString>;
1398
+ prompt: z.ZodDefault<z.ZodString>;
1399
+ settings: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodType<JsonNonNullValue, unknown, z.core.$ZodTypeInternals<JsonNonNullValue, unknown>>>>;
1400
+ bakedInputs: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
1401
+ kind: z.ZodLiteral<"literal">;
1402
+ value: z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>;
1403
+ }, z.core.$strip>>>;
1404
+ activeGeneration: z.ZodOptional<z.ZodString>;
1405
+ label: z.ZodOptional<z.ZodString>;
1406
+ }, z.core.$strip>, z.ZodObject<{
1407
+ id: z.ZodString;
1408
+ kind: z.ZodLiteral<"prompt-source">;
1409
+ text: z.ZodDefault<z.ZodString>;
1410
+ label: z.ZodOptional<z.ZodString>;
1411
+ }, z.core.$strip>, z.ZodObject<{
1412
+ id: z.ZodString;
1413
+ kind: z.ZodLiteral<"image-source">;
1414
+ imageUrl: z.ZodDefault<z.ZodString>;
1415
+ assetId: z.ZodOptional<z.ZodString>;
1416
+ label: z.ZodOptional<z.ZodString>;
1417
+ }, z.core.$strip>, z.ZodObject<{
1418
+ id: z.ZodString;
1419
+ kind: z.ZodLiteral<"input">;
1420
+ name: z.ZodString;
1421
+ type: z.ZodEnum<{
1422
+ image: "image";
1423
+ video: "video";
1424
+ audio: "audio";
1425
+ text: "text";
1426
+ mesh3d: "mesh3d";
1427
+ json: "json";
1428
+ }>;
1429
+ required: z.ZodDefault<z.ZodBoolean>;
1430
+ cardinality: z.ZodOptional<z.ZodEnum<{
1431
+ one: "one";
1432
+ many: "many";
1433
+ }>>;
1434
+ default: z.ZodOptional<z.ZodType<JsonNonNullValue, unknown, z.core.$ZodTypeInternals<JsonNonNullValue, unknown>>>;
1435
+ label: z.ZodOptional<z.ZodString>;
1436
+ description: z.ZodOptional<z.ZodString>;
1437
+ }, z.core.$strip>], "kind">;
1438
+ position: z.ZodOptional<z.ZodObject<{
1439
+ x: z.ZodNumber;
1440
+ y: z.ZodNumber;
1441
+ }, z.core.$strip>>;
1442
+ index: z.ZodOptional<z.ZodNumber>;
1443
+ }, z.core.$strip>, z.ZodObject<{
1444
+ type: z.ZodLiteral<"removeNode">;
1445
+ id: z.ZodString;
1446
+ }, z.core.$strip>, z.ZodDiscriminatedUnion<[z.ZodObject<{
1447
+ type: z.ZodLiteral<"setNodeProps">;
1448
+ kind: z.ZodLiteral<"task">;
1449
+ id: z.ZodString;
1450
+ props: z.ZodObject<{
1451
+ task: z.ZodOptional<z.ZodEnum<{
1452
+ "text-to-image": "text-to-image";
1453
+ "image-to-image": "image-to-image";
1454
+ "image-edit": "image-edit";
1455
+ "virtual-try-on": "virtual-try-on";
1456
+ "text-to-video": "text-to-video";
1457
+ "image-to-video": "image-to-video";
1458
+ "video-to-video": "video-to-video";
1459
+ "video-enhance": "video-enhance";
1460
+ "text-to-3d": "text-to-3d";
1461
+ "image-to-3d": "image-to-3d";
1462
+ "multiview-to-3d": "multiview-to-3d";
1463
+ remesh: "remesh";
1464
+ texture: "texture";
1465
+ "text-to-audio": "text-to-audio";
1466
+ "text-to-speech": "text-to-speech";
1467
+ "speech-to-text": "speech-to-text";
1468
+ "speech-to-speech": "speech-to-speech";
1469
+ "image-to-text": "image-to-text";
1470
+ "image-to-json": "image-to-json";
1471
+ judge: "judge";
1472
+ "text-generation": "text-generation";
1473
+ upscale: "upscale";
1474
+ "background-remove": "background-remove";
1475
+ segmentation: "segmentation";
1476
+ }>>;
1477
+ model: z.ZodOptional<z.ZodString>;
1478
+ prompt: z.ZodOptional<z.ZodString>;
1479
+ label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1480
+ }, z.core.$strict>;
1481
+ }, z.core.$strip>, z.ZodObject<{
1482
+ type: z.ZodLiteral<"setNodeProps">;
1483
+ kind: z.ZodLiteral<"prompt-source">;
1484
+ id: z.ZodString;
1485
+ props: z.ZodObject<{
1486
+ text: z.ZodOptional<z.ZodString>;
1487
+ label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1488
+ }, z.core.$strict>;
1489
+ }, z.core.$strip>, z.ZodObject<{
1490
+ type: z.ZodLiteral<"setNodeProps">;
1491
+ kind: z.ZodLiteral<"image-source">;
1492
+ id: z.ZodString;
1493
+ props: z.ZodObject<{
1494
+ imageUrl: z.ZodOptional<z.ZodString>;
1495
+ assetId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1496
+ label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1497
+ }, z.core.$strict>;
1498
+ }, z.core.$strip>, z.ZodObject<{
1499
+ type: z.ZodLiteral<"setNodeProps">;
1500
+ kind: z.ZodLiteral<"input">;
1501
+ id: z.ZodString;
1502
+ props: z.ZodObject<{
1503
+ name: z.ZodOptional<z.ZodString>;
1504
+ type: z.ZodOptional<z.ZodEnum<{
1505
+ image: "image";
1506
+ video: "video";
1507
+ audio: "audio";
1508
+ text: "text";
1509
+ mesh3d: "mesh3d";
1510
+ json: "json";
1511
+ }>>;
1512
+ required: z.ZodOptional<z.ZodBoolean>;
1513
+ cardinality: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
1514
+ one: "one";
1515
+ many: "many";
1516
+ }>>>;
1517
+ default: z.ZodOptional<z.ZodNullable<z.ZodType<JsonNonNullValue, unknown, z.core.$ZodTypeInternals<JsonNonNullValue, unknown>>>>;
1518
+ label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1519
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1520
+ }, z.core.$strict>;
1521
+ }, z.core.$strip>], "kind">, z.ZodObject<{
1522
+ type: z.ZodLiteral<"setNodeSetting">;
1523
+ id: z.ZodString;
1524
+ key: z.ZodString;
1525
+ value: z.ZodNullable<z.ZodType<JsonNonNullValue, unknown, z.core.$ZodTypeInternals<JsonNonNullValue, unknown>>>;
1526
+ }, z.core.$strip>, z.ZodObject<{
1527
+ type: z.ZodLiteral<"setBakedInput">;
1528
+ id: z.ZodString;
1529
+ key: z.ZodString;
1530
+ binding: z.ZodNullable<z.ZodObject<{
1531
+ kind: z.ZodLiteral<"literal">;
1532
+ value: z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>;
1533
+ }, z.core.$strip>>;
1534
+ }, z.core.$strip>, z.ZodObject<{
1535
+ type: z.ZodLiteral<"connect">;
1536
+ source: z.ZodString;
1537
+ target: z.ZodString;
1538
+ port: z.ZodEnum<{
1539
+ image: "image";
1540
+ video: "video";
1541
+ audio: "audio";
1542
+ text: "text";
1543
+ mask: "mask";
1544
+ mesh3d: "mesh3d";
1545
+ json: "json";
1546
+ }>;
1547
+ index: z.ZodOptional<z.ZodNumber>;
1548
+ }, z.core.$strip>, z.ZodObject<{
1549
+ type: z.ZodLiteral<"disconnect">;
1550
+ source: z.ZodString;
1551
+ target: z.ZodString;
1552
+ port: z.ZodEnum<{
1553
+ image: "image";
1554
+ video: "video";
1555
+ audio: "audio";
1556
+ text: "text";
1557
+ mask: "mask";
1558
+ mesh3d: "mesh3d";
1559
+ json: "json";
1560
+ }>;
1561
+ }, z.core.$strip>, z.ZodObject<{
1562
+ type: z.ZodLiteral<"exposeAsInput">;
1563
+ id: z.ZodString;
1564
+ name: z.ZodString;
1565
+ required: z.ZodOptional<z.ZodBoolean>;
1566
+ label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1567
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1568
+ default: z.ZodOptional<z.ZodNullable<z.ZodType<JsonNonNullValue, unknown, z.core.$ZodTypeInternals<JsonNonNullValue, unknown>>>>;
1569
+ }, z.core.$strip>, z.ZodObject<{
1570
+ type: z.ZodLiteral<"freezeInput">;
1571
+ id: z.ZodString;
1572
+ value: z.ZodString;
1573
+ assetId: z.ZodOptional<z.ZodString>;
1574
+ label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1575
+ }, z.core.$strip>, z.ZodObject<{
1576
+ type: z.ZodLiteral<"setActiveGeneration">;
1577
+ id: z.ZodString;
1578
+ generationId: z.ZodNullable<z.ZodString>;
1579
+ }, z.core.$strip>, z.ZodObject<{
1580
+ type: z.ZodLiteral<"setLayout">;
1581
+ id: z.ZodString;
1582
+ position: z.ZodNullable<z.ZodObject<{
1583
+ x: z.ZodNumber;
1584
+ y: z.ZodNumber;
1585
+ }, z.core.$strip>>;
1586
+ }, z.core.$strip>, z.ZodObject<{
1587
+ type: z.ZodLiteral<"group">;
1588
+ id: z.ZodString;
1589
+ label: z.ZodOptional<z.ZodString>;
1590
+ nodeIds: z.ZodArray<z.ZodString>;
1591
+ index: z.ZodOptional<z.ZodNumber>;
1592
+ }, z.core.$strip>, z.ZodObject<{
1593
+ type: z.ZodLiteral<"ungroup">;
1594
+ id: z.ZodString;
1595
+ }, z.core.$strip>, z.ZodObject<{
1596
+ type: z.ZodLiteral<"setGroupProps">;
1597
+ id: z.ZodString;
1598
+ props: z.ZodObject<{
1599
+ label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1600
+ nodeIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
1601
+ }, z.core.$strict>;
1602
+ }, z.core.$strip>, z.ZodObject<{
1603
+ type: z.ZodLiteral<"setDocumentProps">;
1604
+ props: z.ZodObject<{
1605
+ label: z.ZodOptional<z.ZodString>;
1606
+ }, z.core.$strict>;
1607
+ }, z.core.$strip>], "type">>;
1608
+ label: z.ZodOptional<z.ZodString>;
1609
+ projectId: z.ZodOptional<z.ZodString>;
1610
+ }>;
1611
+ declare const studioWorkflowApply: ToolDef<{
1612
+ savedId: z.ZodString;
1613
+ baseRevision: z.ZodNumber;
1614
+ ops: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
1615
+ type: z.ZodLiteral<"addNode">;
1616
+ node: z.ZodDiscriminatedUnion<[z.ZodObject<{
1617
+ id: z.ZodString;
1618
+ kind: z.ZodLiteral<"task">;
1619
+ task: z.ZodEnum<{
1620
+ "text-to-image": "text-to-image";
1621
+ "image-to-image": "image-to-image";
1622
+ "image-edit": "image-edit";
1623
+ "virtual-try-on": "virtual-try-on";
1624
+ "text-to-video": "text-to-video";
1625
+ "image-to-video": "image-to-video";
1626
+ "video-to-video": "video-to-video";
1627
+ "video-enhance": "video-enhance";
1628
+ "text-to-3d": "text-to-3d";
1629
+ "image-to-3d": "image-to-3d";
1630
+ "multiview-to-3d": "multiview-to-3d";
1631
+ remesh: "remesh";
1632
+ texture: "texture";
1633
+ "text-to-audio": "text-to-audio";
1634
+ "text-to-speech": "text-to-speech";
1635
+ "speech-to-text": "speech-to-text";
1636
+ "speech-to-speech": "speech-to-speech";
1637
+ "image-to-text": "image-to-text";
1638
+ "image-to-json": "image-to-json";
1639
+ judge: "judge";
1640
+ "text-generation": "text-generation";
1641
+ upscale: "upscale";
1642
+ "background-remove": "background-remove";
1643
+ segmentation: "segmentation";
1644
+ }>;
1645
+ model: z.ZodDefault<z.ZodString>;
1646
+ prompt: z.ZodDefault<z.ZodString>;
1647
+ settings: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodType<JsonNonNullValue, unknown, z.core.$ZodTypeInternals<JsonNonNullValue, unknown>>>>;
1648
+ bakedInputs: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
1649
+ kind: z.ZodLiteral<"literal">;
1650
+ value: z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>;
1651
+ }, z.core.$strip>>>;
1652
+ activeGeneration: z.ZodOptional<z.ZodString>;
1653
+ label: z.ZodOptional<z.ZodString>;
1654
+ }, z.core.$strip>, z.ZodObject<{
1655
+ id: z.ZodString;
1656
+ kind: z.ZodLiteral<"prompt-source">;
1657
+ text: z.ZodDefault<z.ZodString>;
1658
+ label: z.ZodOptional<z.ZodString>;
1659
+ }, z.core.$strip>, z.ZodObject<{
1660
+ id: z.ZodString;
1661
+ kind: z.ZodLiteral<"image-source">;
1662
+ imageUrl: z.ZodDefault<z.ZodString>;
1663
+ assetId: z.ZodOptional<z.ZodString>;
1664
+ label: z.ZodOptional<z.ZodString>;
1665
+ }, z.core.$strip>, z.ZodObject<{
1666
+ id: z.ZodString;
1667
+ kind: z.ZodLiteral<"input">;
1668
+ name: z.ZodString;
1669
+ type: z.ZodEnum<{
1670
+ image: "image";
1671
+ video: "video";
1672
+ audio: "audio";
1673
+ text: "text";
1674
+ mesh3d: "mesh3d";
1675
+ json: "json";
1676
+ }>;
1677
+ required: z.ZodDefault<z.ZodBoolean>;
1678
+ cardinality: z.ZodOptional<z.ZodEnum<{
1679
+ one: "one";
1680
+ many: "many";
1681
+ }>>;
1682
+ default: z.ZodOptional<z.ZodType<JsonNonNullValue, unknown, z.core.$ZodTypeInternals<JsonNonNullValue, unknown>>>;
1683
+ label: z.ZodOptional<z.ZodString>;
1684
+ description: z.ZodOptional<z.ZodString>;
1685
+ }, z.core.$strip>], "kind">;
1686
+ position: z.ZodOptional<z.ZodObject<{
1687
+ x: z.ZodNumber;
1688
+ y: z.ZodNumber;
1689
+ }, z.core.$strip>>;
1690
+ index: z.ZodOptional<z.ZodNumber>;
1691
+ }, z.core.$strip>, z.ZodObject<{
1692
+ type: z.ZodLiteral<"removeNode">;
1693
+ id: z.ZodString;
1694
+ }, z.core.$strip>, z.ZodDiscriminatedUnion<[z.ZodObject<{
1695
+ type: z.ZodLiteral<"setNodeProps">;
1696
+ kind: z.ZodLiteral<"task">;
1697
+ id: z.ZodString;
1698
+ props: z.ZodObject<{
1699
+ task: z.ZodOptional<z.ZodEnum<{
1700
+ "text-to-image": "text-to-image";
1701
+ "image-to-image": "image-to-image";
1702
+ "image-edit": "image-edit";
1703
+ "virtual-try-on": "virtual-try-on";
1704
+ "text-to-video": "text-to-video";
1705
+ "image-to-video": "image-to-video";
1706
+ "video-to-video": "video-to-video";
1707
+ "video-enhance": "video-enhance";
1708
+ "text-to-3d": "text-to-3d";
1709
+ "image-to-3d": "image-to-3d";
1710
+ "multiview-to-3d": "multiview-to-3d";
1711
+ remesh: "remesh";
1712
+ texture: "texture";
1713
+ "text-to-audio": "text-to-audio";
1714
+ "text-to-speech": "text-to-speech";
1715
+ "speech-to-text": "speech-to-text";
1716
+ "speech-to-speech": "speech-to-speech";
1717
+ "image-to-text": "image-to-text";
1718
+ "image-to-json": "image-to-json";
1719
+ judge: "judge";
1720
+ "text-generation": "text-generation";
1721
+ upscale: "upscale";
1722
+ "background-remove": "background-remove";
1723
+ segmentation: "segmentation";
1724
+ }>>;
1725
+ model: z.ZodOptional<z.ZodString>;
1726
+ prompt: z.ZodOptional<z.ZodString>;
1727
+ label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1728
+ }, z.core.$strict>;
1729
+ }, z.core.$strip>, z.ZodObject<{
1730
+ type: z.ZodLiteral<"setNodeProps">;
1731
+ kind: z.ZodLiteral<"prompt-source">;
1732
+ id: z.ZodString;
1733
+ props: z.ZodObject<{
1734
+ text: z.ZodOptional<z.ZodString>;
1735
+ label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1736
+ }, z.core.$strict>;
1737
+ }, z.core.$strip>, z.ZodObject<{
1738
+ type: z.ZodLiteral<"setNodeProps">;
1739
+ kind: z.ZodLiteral<"image-source">;
1740
+ id: z.ZodString;
1741
+ props: z.ZodObject<{
1742
+ imageUrl: z.ZodOptional<z.ZodString>;
1743
+ assetId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1744
+ label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1745
+ }, z.core.$strict>;
1746
+ }, z.core.$strip>, z.ZodObject<{
1747
+ type: z.ZodLiteral<"setNodeProps">;
1748
+ kind: z.ZodLiteral<"input">;
1749
+ id: z.ZodString;
1750
+ props: z.ZodObject<{
1751
+ name: z.ZodOptional<z.ZodString>;
1752
+ type: z.ZodOptional<z.ZodEnum<{
1753
+ image: "image";
1754
+ video: "video";
1755
+ audio: "audio";
1756
+ text: "text";
1757
+ mesh3d: "mesh3d";
1758
+ json: "json";
1759
+ }>>;
1760
+ required: z.ZodOptional<z.ZodBoolean>;
1761
+ cardinality: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
1762
+ one: "one";
1763
+ many: "many";
1764
+ }>>>;
1765
+ default: z.ZodOptional<z.ZodNullable<z.ZodType<JsonNonNullValue, unknown, z.core.$ZodTypeInternals<JsonNonNullValue, unknown>>>>;
1766
+ label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1767
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1768
+ }, z.core.$strict>;
1769
+ }, z.core.$strip>], "kind">, z.ZodObject<{
1770
+ type: z.ZodLiteral<"setNodeSetting">;
1771
+ id: z.ZodString;
1772
+ key: z.ZodString;
1773
+ value: z.ZodNullable<z.ZodType<JsonNonNullValue, unknown, z.core.$ZodTypeInternals<JsonNonNullValue, unknown>>>;
1774
+ }, z.core.$strip>, z.ZodObject<{
1775
+ type: z.ZodLiteral<"setBakedInput">;
1776
+ id: z.ZodString;
1777
+ key: z.ZodString;
1778
+ binding: z.ZodNullable<z.ZodObject<{
1779
+ kind: z.ZodLiteral<"literal">;
1780
+ value: z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>;
1781
+ }, z.core.$strip>>;
1782
+ }, z.core.$strip>, z.ZodObject<{
1783
+ type: z.ZodLiteral<"connect">;
1784
+ source: z.ZodString;
1785
+ target: z.ZodString;
1786
+ port: z.ZodEnum<{
1787
+ image: "image";
1788
+ video: "video";
1789
+ audio: "audio";
1790
+ text: "text";
1791
+ mask: "mask";
1792
+ mesh3d: "mesh3d";
1793
+ json: "json";
1794
+ }>;
1795
+ index: z.ZodOptional<z.ZodNumber>;
1796
+ }, z.core.$strip>, z.ZodObject<{
1797
+ type: z.ZodLiteral<"disconnect">;
1798
+ source: z.ZodString;
1799
+ target: z.ZodString;
1800
+ port: z.ZodEnum<{
1801
+ image: "image";
1802
+ video: "video";
1803
+ audio: "audio";
1804
+ text: "text";
1805
+ mask: "mask";
1806
+ mesh3d: "mesh3d";
1807
+ json: "json";
1808
+ }>;
1809
+ }, z.core.$strip>, z.ZodObject<{
1810
+ type: z.ZodLiteral<"exposeAsInput">;
1811
+ id: z.ZodString;
1812
+ name: z.ZodString;
1813
+ required: z.ZodOptional<z.ZodBoolean>;
1814
+ label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1815
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1816
+ default: z.ZodOptional<z.ZodNullable<z.ZodType<JsonNonNullValue, unknown, z.core.$ZodTypeInternals<JsonNonNullValue, unknown>>>>;
1817
+ }, z.core.$strip>, z.ZodObject<{
1818
+ type: z.ZodLiteral<"freezeInput">;
1819
+ id: z.ZodString;
1820
+ value: z.ZodString;
1821
+ assetId: z.ZodOptional<z.ZodString>;
1822
+ label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1823
+ }, z.core.$strip>, z.ZodObject<{
1824
+ type: z.ZodLiteral<"setActiveGeneration">;
1825
+ id: z.ZodString;
1826
+ generationId: z.ZodNullable<z.ZodString>;
1827
+ }, z.core.$strip>, z.ZodObject<{
1828
+ type: z.ZodLiteral<"setLayout">;
1829
+ id: z.ZodString;
1830
+ position: z.ZodNullable<z.ZodObject<{
1831
+ x: z.ZodNumber;
1832
+ y: z.ZodNumber;
1833
+ }, z.core.$strip>>;
1834
+ }, z.core.$strip>, z.ZodObject<{
1835
+ type: z.ZodLiteral<"group">;
1836
+ id: z.ZodString;
1837
+ label: z.ZodOptional<z.ZodString>;
1838
+ nodeIds: z.ZodArray<z.ZodString>;
1839
+ index: z.ZodOptional<z.ZodNumber>;
1840
+ }, z.core.$strip>, z.ZodObject<{
1841
+ type: z.ZodLiteral<"ungroup">;
1842
+ id: z.ZodString;
1843
+ }, z.core.$strip>, z.ZodObject<{
1844
+ type: z.ZodLiteral<"setGroupProps">;
1845
+ id: z.ZodString;
1846
+ props: z.ZodObject<{
1847
+ label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
1848
+ nodeIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
1849
+ }, z.core.$strict>;
1850
+ }, z.core.$strip>, z.ZodObject<{
1851
+ type: z.ZodLiteral<"setDocumentProps">;
1852
+ props: z.ZodObject<{
1853
+ label: z.ZodOptional<z.ZodString>;
1854
+ }, z.core.$strict>;
1855
+ }, z.core.$strip>], "type">>;
1856
+ idempotencyKey: z.ZodOptional<z.ZodString>;
1857
+ acknowledgeLossy: z.ZodOptional<z.ZodBoolean>;
1858
+ }>;
1859
+ declare const studioWorkflowValidate: ToolDef<{
1860
+ document: z.ZodOptional<z.ZodObject<{
1861
+ schema: z.ZodNumber;
1862
+ id: z.ZodString;
1863
+ label: z.ZodDefault<z.ZodString>;
1864
+ nodes: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
1865
+ id: z.ZodString;
1866
+ kind: z.ZodLiteral<"task">;
1867
+ task: z.ZodEnum<{
1868
+ "text-to-image": "text-to-image";
1869
+ "image-to-image": "image-to-image";
1870
+ "image-edit": "image-edit";
1871
+ "virtual-try-on": "virtual-try-on";
1872
+ "text-to-video": "text-to-video";
1873
+ "image-to-video": "image-to-video";
1874
+ "video-to-video": "video-to-video";
1875
+ "video-enhance": "video-enhance";
1876
+ "text-to-3d": "text-to-3d";
1877
+ "image-to-3d": "image-to-3d";
1878
+ "multiview-to-3d": "multiview-to-3d";
1879
+ remesh: "remesh";
1880
+ texture: "texture";
1881
+ "text-to-audio": "text-to-audio";
1882
+ "text-to-speech": "text-to-speech";
1883
+ "speech-to-text": "speech-to-text";
1884
+ "speech-to-speech": "speech-to-speech";
1885
+ "image-to-text": "image-to-text";
1886
+ "image-to-json": "image-to-json";
1887
+ judge: "judge";
1888
+ "text-generation": "text-generation";
1889
+ upscale: "upscale";
1890
+ "background-remove": "background-remove";
1891
+ segmentation: "segmentation";
1892
+ }>;
1893
+ model: z.ZodDefault<z.ZodString>;
1894
+ prompt: z.ZodDefault<z.ZodString>;
1895
+ settings: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodType<JsonNonNullValue, unknown, z.core.$ZodTypeInternals<JsonNonNullValue, unknown>>>>;
1896
+ bakedInputs: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
1897
+ kind: z.ZodLiteral<"literal">;
1898
+ value: z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>;
1899
+ }, z.core.$strip>>>;
1900
+ activeGeneration: z.ZodOptional<z.ZodString>;
1901
+ label: z.ZodOptional<z.ZodString>;
1902
+ }, z.core.$strip>, z.ZodObject<{
1903
+ id: z.ZodString;
1904
+ kind: z.ZodLiteral<"prompt-source">;
1905
+ text: z.ZodDefault<z.ZodString>;
1906
+ label: z.ZodOptional<z.ZodString>;
1907
+ }, z.core.$strip>, z.ZodObject<{
1908
+ id: z.ZodString;
1909
+ kind: z.ZodLiteral<"image-source">;
1910
+ imageUrl: z.ZodDefault<z.ZodString>;
1911
+ assetId: z.ZodOptional<z.ZodString>;
1912
+ label: z.ZodOptional<z.ZodString>;
1913
+ }, z.core.$strip>, z.ZodObject<{
1914
+ id: z.ZodString;
1915
+ kind: z.ZodLiteral<"input">;
1916
+ name: z.ZodString;
1917
+ type: z.ZodEnum<{
1918
+ image: "image";
1919
+ video: "video";
1920
+ audio: "audio";
1921
+ text: "text";
1922
+ mesh3d: "mesh3d";
1923
+ json: "json";
1924
+ }>;
1925
+ required: z.ZodDefault<z.ZodBoolean>;
1926
+ cardinality: z.ZodOptional<z.ZodEnum<{
1927
+ one: "one";
1928
+ many: "many";
1929
+ }>>;
1930
+ default: z.ZodOptional<z.ZodType<JsonNonNullValue, unknown, z.core.$ZodTypeInternals<JsonNonNullValue, unknown>>>;
1931
+ label: z.ZodOptional<z.ZodString>;
1932
+ description: z.ZodOptional<z.ZodString>;
1933
+ }, z.core.$strip>], "kind">>;
1934
+ edges: z.ZodArray<z.ZodObject<{
1935
+ source: z.ZodString;
1936
+ target: z.ZodString;
1937
+ port: z.ZodEnum<{
1938
+ image: "image";
1939
+ video: "video";
1940
+ audio: "audio";
1941
+ text: "text";
1942
+ mask: "mask";
1943
+ mesh3d: "mesh3d";
1944
+ json: "json";
1945
+ }>;
1946
+ }, z.core.$strip>>;
1947
+ layout: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
1948
+ x: z.ZodNumber;
1949
+ y: z.ZodNumber;
1950
+ }, z.core.$strip>>>;
1951
+ groups: z.ZodDefault<z.ZodArray<z.ZodObject<{
1952
+ id: z.ZodString;
1953
+ label: z.ZodOptional<z.ZodString>;
1954
+ nodeIds: z.ZodArray<z.ZodString>;
1955
+ }, z.core.$strip>>>;
1956
+ }, z.core.$strip>>;
1957
+ savedId: z.ZodOptional<z.ZodString>;
1958
+ ops: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
1959
+ type: z.ZodLiteral<"addNode">;
1960
+ node: z.ZodDiscriminatedUnion<[z.ZodObject<{
1961
+ id: z.ZodString;
1962
+ kind: z.ZodLiteral<"task">;
1963
+ task: z.ZodEnum<{
1964
+ "text-to-image": "text-to-image";
1965
+ "image-to-image": "image-to-image";
1966
+ "image-edit": "image-edit";
1967
+ "virtual-try-on": "virtual-try-on";
1968
+ "text-to-video": "text-to-video";
1969
+ "image-to-video": "image-to-video";
1970
+ "video-to-video": "video-to-video";
1971
+ "video-enhance": "video-enhance";
1972
+ "text-to-3d": "text-to-3d";
1973
+ "image-to-3d": "image-to-3d";
1974
+ "multiview-to-3d": "multiview-to-3d";
1975
+ remesh: "remesh";
1976
+ texture: "texture";
1977
+ "text-to-audio": "text-to-audio";
1978
+ "text-to-speech": "text-to-speech";
1979
+ "speech-to-text": "speech-to-text";
1980
+ "speech-to-speech": "speech-to-speech";
1981
+ "image-to-text": "image-to-text";
1982
+ "image-to-json": "image-to-json";
1983
+ judge: "judge";
1984
+ "text-generation": "text-generation";
1985
+ upscale: "upscale";
1986
+ "background-remove": "background-remove";
1987
+ segmentation: "segmentation";
1988
+ }>;
1989
+ model: z.ZodDefault<z.ZodString>;
1990
+ prompt: z.ZodDefault<z.ZodString>;
1991
+ settings: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodType<JsonNonNullValue, unknown, z.core.$ZodTypeInternals<JsonNonNullValue, unknown>>>>;
1992
+ bakedInputs: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
1993
+ kind: z.ZodLiteral<"literal">;
1994
+ value: z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>;
1995
+ }, z.core.$strip>>>;
1996
+ activeGeneration: z.ZodOptional<z.ZodString>;
1997
+ label: z.ZodOptional<z.ZodString>;
1998
+ }, z.core.$strip>, z.ZodObject<{
1999
+ id: z.ZodString;
2000
+ kind: z.ZodLiteral<"prompt-source">;
2001
+ text: z.ZodDefault<z.ZodString>;
2002
+ label: z.ZodOptional<z.ZodString>;
2003
+ }, z.core.$strip>, z.ZodObject<{
2004
+ id: z.ZodString;
2005
+ kind: z.ZodLiteral<"image-source">;
2006
+ imageUrl: z.ZodDefault<z.ZodString>;
2007
+ assetId: z.ZodOptional<z.ZodString>;
2008
+ label: z.ZodOptional<z.ZodString>;
2009
+ }, z.core.$strip>, z.ZodObject<{
2010
+ id: z.ZodString;
2011
+ kind: z.ZodLiteral<"input">;
2012
+ name: z.ZodString;
2013
+ type: z.ZodEnum<{
2014
+ image: "image";
2015
+ video: "video";
2016
+ audio: "audio";
2017
+ text: "text";
2018
+ mesh3d: "mesh3d";
2019
+ json: "json";
2020
+ }>;
2021
+ required: z.ZodDefault<z.ZodBoolean>;
2022
+ cardinality: z.ZodOptional<z.ZodEnum<{
2023
+ one: "one";
2024
+ many: "many";
2025
+ }>>;
2026
+ default: z.ZodOptional<z.ZodType<JsonNonNullValue, unknown, z.core.$ZodTypeInternals<JsonNonNullValue, unknown>>>;
2027
+ label: z.ZodOptional<z.ZodString>;
2028
+ description: z.ZodOptional<z.ZodString>;
2029
+ }, z.core.$strip>], "kind">;
2030
+ position: z.ZodOptional<z.ZodObject<{
2031
+ x: z.ZodNumber;
2032
+ y: z.ZodNumber;
2033
+ }, z.core.$strip>>;
2034
+ index: z.ZodOptional<z.ZodNumber>;
2035
+ }, z.core.$strip>, z.ZodObject<{
2036
+ type: z.ZodLiteral<"removeNode">;
2037
+ id: z.ZodString;
2038
+ }, z.core.$strip>, z.ZodDiscriminatedUnion<[z.ZodObject<{
2039
+ type: z.ZodLiteral<"setNodeProps">;
2040
+ kind: z.ZodLiteral<"task">;
2041
+ id: z.ZodString;
2042
+ props: z.ZodObject<{
2043
+ task: z.ZodOptional<z.ZodEnum<{
2044
+ "text-to-image": "text-to-image";
2045
+ "image-to-image": "image-to-image";
2046
+ "image-edit": "image-edit";
2047
+ "virtual-try-on": "virtual-try-on";
2048
+ "text-to-video": "text-to-video";
2049
+ "image-to-video": "image-to-video";
2050
+ "video-to-video": "video-to-video";
2051
+ "video-enhance": "video-enhance";
2052
+ "text-to-3d": "text-to-3d";
2053
+ "image-to-3d": "image-to-3d";
2054
+ "multiview-to-3d": "multiview-to-3d";
2055
+ remesh: "remesh";
2056
+ texture: "texture";
2057
+ "text-to-audio": "text-to-audio";
2058
+ "text-to-speech": "text-to-speech";
2059
+ "speech-to-text": "speech-to-text";
2060
+ "speech-to-speech": "speech-to-speech";
2061
+ "image-to-text": "image-to-text";
2062
+ "image-to-json": "image-to-json";
2063
+ judge: "judge";
2064
+ "text-generation": "text-generation";
2065
+ upscale: "upscale";
2066
+ "background-remove": "background-remove";
2067
+ segmentation: "segmentation";
2068
+ }>>;
2069
+ model: z.ZodOptional<z.ZodString>;
2070
+ prompt: z.ZodOptional<z.ZodString>;
2071
+ label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
2072
+ }, z.core.$strict>;
2073
+ }, z.core.$strip>, z.ZodObject<{
2074
+ type: z.ZodLiteral<"setNodeProps">;
2075
+ kind: z.ZodLiteral<"prompt-source">;
2076
+ id: z.ZodString;
2077
+ props: z.ZodObject<{
2078
+ text: z.ZodOptional<z.ZodString>;
2079
+ label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
2080
+ }, z.core.$strict>;
2081
+ }, z.core.$strip>, z.ZodObject<{
2082
+ type: z.ZodLiteral<"setNodeProps">;
2083
+ kind: z.ZodLiteral<"image-source">;
2084
+ id: z.ZodString;
2085
+ props: z.ZodObject<{
2086
+ imageUrl: z.ZodOptional<z.ZodString>;
2087
+ assetId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
2088
+ label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
2089
+ }, z.core.$strict>;
2090
+ }, z.core.$strip>, z.ZodObject<{
2091
+ type: z.ZodLiteral<"setNodeProps">;
2092
+ kind: z.ZodLiteral<"input">;
2093
+ id: z.ZodString;
2094
+ props: z.ZodObject<{
2095
+ name: z.ZodOptional<z.ZodString>;
2096
+ type: z.ZodOptional<z.ZodEnum<{
2097
+ image: "image";
2098
+ video: "video";
2099
+ audio: "audio";
2100
+ text: "text";
2101
+ mesh3d: "mesh3d";
2102
+ json: "json";
2103
+ }>>;
2104
+ required: z.ZodOptional<z.ZodBoolean>;
2105
+ cardinality: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
2106
+ one: "one";
2107
+ many: "many";
2108
+ }>>>;
2109
+ default: z.ZodOptional<z.ZodNullable<z.ZodType<JsonNonNullValue, unknown, z.core.$ZodTypeInternals<JsonNonNullValue, unknown>>>>;
2110
+ label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
2111
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
2112
+ }, z.core.$strict>;
2113
+ }, z.core.$strip>], "kind">, z.ZodObject<{
2114
+ type: z.ZodLiteral<"setNodeSetting">;
2115
+ id: z.ZodString;
2116
+ key: z.ZodString;
2117
+ value: z.ZodNullable<z.ZodType<JsonNonNullValue, unknown, z.core.$ZodTypeInternals<JsonNonNullValue, unknown>>>;
2118
+ }, z.core.$strip>, z.ZodObject<{
2119
+ type: z.ZodLiteral<"setBakedInput">;
2120
+ id: z.ZodString;
2121
+ key: z.ZodString;
2122
+ binding: z.ZodNullable<z.ZodObject<{
2123
+ kind: z.ZodLiteral<"literal">;
2124
+ value: z.ZodType<JsonValue, unknown, z.core.$ZodTypeInternals<JsonValue, unknown>>;
2125
+ }, z.core.$strip>>;
2126
+ }, z.core.$strip>, z.ZodObject<{
2127
+ type: z.ZodLiteral<"connect">;
2128
+ source: z.ZodString;
2129
+ target: z.ZodString;
2130
+ port: z.ZodEnum<{
2131
+ image: "image";
2132
+ video: "video";
2133
+ audio: "audio";
2134
+ text: "text";
2135
+ mask: "mask";
2136
+ mesh3d: "mesh3d";
2137
+ json: "json";
2138
+ }>;
2139
+ index: z.ZodOptional<z.ZodNumber>;
2140
+ }, z.core.$strip>, z.ZodObject<{
2141
+ type: z.ZodLiteral<"disconnect">;
2142
+ source: z.ZodString;
2143
+ target: z.ZodString;
2144
+ port: z.ZodEnum<{
2145
+ image: "image";
2146
+ video: "video";
2147
+ audio: "audio";
2148
+ text: "text";
2149
+ mask: "mask";
2150
+ mesh3d: "mesh3d";
2151
+ json: "json";
2152
+ }>;
2153
+ }, z.core.$strip>, z.ZodObject<{
2154
+ type: z.ZodLiteral<"exposeAsInput">;
2155
+ id: z.ZodString;
2156
+ name: z.ZodString;
2157
+ required: z.ZodOptional<z.ZodBoolean>;
2158
+ label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
2159
+ description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
2160
+ default: z.ZodOptional<z.ZodNullable<z.ZodType<JsonNonNullValue, unknown, z.core.$ZodTypeInternals<JsonNonNullValue, unknown>>>>;
2161
+ }, z.core.$strip>, z.ZodObject<{
2162
+ type: z.ZodLiteral<"freezeInput">;
2163
+ id: z.ZodString;
2164
+ value: z.ZodString;
2165
+ assetId: z.ZodOptional<z.ZodString>;
2166
+ label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
2167
+ }, z.core.$strip>, z.ZodObject<{
2168
+ type: z.ZodLiteral<"setActiveGeneration">;
2169
+ id: z.ZodString;
2170
+ generationId: z.ZodNullable<z.ZodString>;
2171
+ }, z.core.$strip>, z.ZodObject<{
2172
+ type: z.ZodLiteral<"setLayout">;
2173
+ id: z.ZodString;
2174
+ position: z.ZodNullable<z.ZodObject<{
2175
+ x: z.ZodNumber;
2176
+ y: z.ZodNumber;
2177
+ }, z.core.$strip>>;
2178
+ }, z.core.$strip>, z.ZodObject<{
2179
+ type: z.ZodLiteral<"group">;
2180
+ id: z.ZodString;
2181
+ label: z.ZodOptional<z.ZodString>;
2182
+ nodeIds: z.ZodArray<z.ZodString>;
2183
+ index: z.ZodOptional<z.ZodNumber>;
2184
+ }, z.core.$strip>, z.ZodObject<{
2185
+ type: z.ZodLiteral<"ungroup">;
2186
+ id: z.ZodString;
2187
+ }, z.core.$strip>, z.ZodObject<{
2188
+ type: z.ZodLiteral<"setGroupProps">;
2189
+ id: z.ZodString;
2190
+ props: z.ZodObject<{
2191
+ label: z.ZodOptional<z.ZodNullable<z.ZodString>>;
2192
+ nodeIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
2193
+ }, z.core.$strict>;
2194
+ }, z.core.$strip>, z.ZodObject<{
2195
+ type: z.ZodLiteral<"setDocumentProps">;
2196
+ props: z.ZodObject<{
2197
+ label: z.ZodOptional<z.ZodString>;
2198
+ }, z.core.$strict>;
2199
+ }, z.core.$strip>], "type">>>;
2200
+ params: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
2201
+ }>;
2202
+ declare const studioWorkflowScreenshot: ToolDef<{
2203
+ savedId: z.ZodString;
2204
+ }>;
2205
+ /** The six primitives, in registration order. */
2206
+ declare const WORKFLOW_TOOLS: readonly ToolDef<z.ZodRawShape>[];
2207
+
2208
+ /**
2209
+ * What an agent gets back from the workflow primitives instead of a whole
2210
+ * document: node and document summaries, the runnability projection, and the
2211
+ * footprint of a patch. Pure functions over the package's own types
2212
+ * (`@marlinjai/studio-core/workflow`, bundled into the published server, see
2213
+ * tsup.config.ts), so nothing here re-types or re-implements a document rule.
2214
+ *
2215
+ * Summaries are deliberately compact (token economy): long texts are clipped
2216
+ * to `SUMMARY_TEXT_CHARS` with the full length alongside, and only the fields
2217
+ * that matter per node kind appear. `studio_workflow_get` with `full: true`
2218
+ * is the way to the whole document.
2219
+ */
2220
+
2221
+ /** Prompts and urls in a summary carry at most this many characters. */
2222
+ declare const SUMMARY_TEXT_CHARS = 80;
2223
+ interface NodeSummary {
2224
+ id: string;
2225
+ kind: DocNodeKind;
2226
+ label?: string;
2227
+ /** Task nodes. */
2228
+ task?: string;
2229
+ model?: string;
2230
+ activeGeneration?: string;
2231
+ /** Task nodes (their inline prompt) and prompt-source nodes (their text):
2232
+ * the first `SUMMARY_TEXT_CHARS` characters, plus the full length. */
2233
+ prompt?: string;
2234
+ promptLength?: number;
2235
+ /** Image-source nodes: the url clipped; empty means still uploading. */
2236
+ imageUrl?: string;
2237
+ /** Input nodes (declared run parameters). */
2238
+ name?: string;
2239
+ type?: string;
2240
+ required?: boolean;
2241
+ cardinality?: 'one' | 'many';
2242
+ /** Wires into and out of the node. */
2243
+ wires: {
2244
+ in: number;
2245
+ out: number;
2246
+ };
2247
+ }
2248
+ interface DocumentSummary {
2249
+ savedId: string;
2250
+ revision: number;
2251
+ label: string;
2252
+ nodes: NodeSummary[];
2253
+ edgeCount: number;
2254
+ groupCount: number;
2255
+ projection: Projection;
2256
+ lossy?: boolean;
2257
+ notes?: unknown;
2258
+ }
2259
+ /** A node a patch touched that no longer exists after it. */
2260
+ interface RemovedNode {
2261
+ id: string;
2262
+ removed: true;
2263
+ }
2264
+ /** A response field this version of the server cannot read: version skew
2265
+ * between the Studio and this package, reported loudly instead of guessed at. */
2266
+ declare class ContractError extends Error {
2267
+ constructor(message: string);
2268
+ }
2269
+ /** Parse a document the Studio returned. */
2270
+ declare function parseDocument(raw: unknown, what: string): WorkflowDocument;
2271
+ /** Parse an op list the Studio returned (`applied`, `inverse`). */
2272
+ declare function parseOps(raw: unknown, what: string): Op[];
2273
+ /** The runnability verdict, computed with the same projection the Studio
2274
+ * runs (`documentToDefinition`); the server's own verdict wins when a
2275
+ * response carries one. */
2276
+ declare function projectionOf(doc: WorkflowDocument): Projection;
2277
+ declare function summarizeNode(node: DocNode, wires: {
2278
+ in: number;
2279
+ out: number;
2280
+ }): NodeSummary;
2281
+ interface SummaryMeta {
2282
+ savedId: string;
2283
+ revision: number;
2284
+ /** The saved row's label; defaults to the document's. */
2285
+ label?: string;
2286
+ /** The Studio's verdict when the response carried one; computed otherwise. */
2287
+ projection?: Projection;
2288
+ lossy?: boolean;
2289
+ notes?: unknown;
2290
+ }
2291
+ declare function summarizeDocument(doc: WorkflowDocument, meta: SummaryMeta): DocumentSummary;
2292
+ /**
2293
+ * The node ids a patch touched, cascades included, in document order with
2294
+ * removed ids last. `opTouches` reads group membership and wire peers from
2295
+ * the document it is given; against the POST-patch document an `ungroup` or a
2296
+ * `removeNode` can no longer see what it dissolved, so the exact inverse
2297
+ * (which names those nodes: the `group` that restores the membership, the
2298
+ * `addNode` that restores the node) is folded in too. The union is complete
2299
+ * and adds nothing a patch did not change.
2300
+ */
2301
+ declare function touchedNodeIds(doc: WorkflowDocument, applied: readonly Op[], inverse: readonly Op[]): string[];
2302
+ /** Summaries for `ids`: a present node's summary, or `{ id, removed: true }`. */
2303
+ declare function affectedNodes(doc: WorkflowDocument, ids: readonly string[]): Array<NodeSummary | RemovedNode>;
2304
+
2305
+ /**
2306
+ * The curated `character-sheet` workflow and its prompt builder, ported as plain
2307
+ * data + pure functions from the Studio app (`src/lib/workflow/curated.ts` and
2308
+ * `src/lib/character/characterSheetRun.ts`) and `@marlinjai/studio-core/character`.
2309
+ *
2310
+ * Why a port and not an import: `@marlinjai/studio-core` is a private workspace
2311
+ * package and this server is meant to be published standalone. The port is kept
2312
+ * byte-identical to the source; the parity spec in `__tests__/characterSheet.spec.ts`
2313
+ * imports studio-core as a dev dependency and asserts the prompts match, so the
2314
+ * two can never drift silently.
2315
+ *
2316
+ * Why inline at all: the hosted Studio build does not resolve curated
2317
+ * `definitionId`s on `POST /api/v1/workflows/run`, so the mint tool must POST
2318
+ * the full inline definition.
2319
+ */
2320
+ type Binding = {
2321
+ kind: 'literal';
2322
+ value: unknown;
2323
+ } | {
2324
+ kind: 'param';
2325
+ name: string;
2326
+ } | {
2327
+ kind: 'ref';
2328
+ node: string;
2329
+ path: string;
2330
+ wrap?: 'array';
2331
+ };
2332
+ interface WorkflowNode {
2333
+ id: string;
2334
+ task: string;
2335
+ model: string;
2336
+ inputs: Record<string, Binding>;
2337
+ retry?: {
2338
+ maxAttempts: number;
2339
+ backoffMs: number;
2340
+ };
2341
+ }
2342
+ interface WorkflowParamSpec {
2343
+ name: string;
2344
+ type: 'string' | 'number' | 'boolean' | 'json';
2345
+ required: boolean;
2346
+ label?: string;
2347
+ }
2348
+ interface WorkflowDefinition {
2349
+ version: {
2350
+ schema: number;
2351
+ };
2352
+ id: string;
2353
+ label?: string;
2354
+ params: WorkflowParamSpec[];
2355
+ nodes: WorkflowNode[];
2356
+ }
2357
+ type TurnaroundView = 'three-quarter' | 'profile' | 'full-body' | 'close-up' | 'lighting-warm' | 'lighting-cool';
2358
+ declare function seedFacePrompt(description: string): string;
2359
+ declare function turnaroundViewPrompt(view: TurnaroundView, seedDescription: string): string;
2360
+ interface CharacterSheetNode {
2361
+ nodeId: string;
2362
+ param: string;
2363
+ /** The CharacterReference `category` this node's output freezes into. */
2364
+ category: string;
2365
+ label: string;
2366
+ view?: TurnaroundView;
2367
+ }
2368
+ /**
2369
+ * Seed + six turnaround nodes in graph order. The `category` values are the
2370
+ * Studio's canonical reference categories (the same ones the in-app mint flow
2371
+ * freezes and the try-on ranker keys off): the lighting views are
2372
+ * `lighting-warm` / `lighting-cool`, not the shorthand `warm` / `cool`.
2373
+ */
2374
+ declare const CHARACTER_SHEET_NODES: readonly CharacterSheetNode[];
2375
+ /** nodeId -> reference category, the mapping the mint tool uploads with. */
2376
+ declare const MINT_REFERENCE_CATEGORIES: Readonly<Record<string, string>>;
2377
+ declare function categoryForNode(nodeId: string): string | null;
2378
+ /** Run params for one seed description: one prompt per sheet node. Pure. */
2379
+ declare function buildCharacterSheetParams(description: string): Record<string, string>;
2380
+ declare const CHARACTER_SHEET_DEFINITION: WorkflowDefinition;
2381
+ /** A deep copy so a caller can mutate (e.g. swap models) without touching the constant. */
2382
+ declare function characterSheetDefinition(overrides?: {
2383
+ seedModel?: string;
2384
+ viewModel?: string;
2385
+ }): WorkflowDefinition;
2386
+
2387
+ /**
2388
+ * Inline workflow definitions for the proven recipes (composed here, posted
2389
+ * inline because the hosted run route does not resolve curated ids).
2390
+ */
2391
+
2392
+ declare const DEFAULT_SWAP_EDIT_MODEL = "fal/nano-banana-2-edit";
2393
+ /** Single start-frame animation. */
2394
+ declare const DEFAULT_SWAP_VIDEO_MODEL = "fal/seedance-pro-image-to-video";
2395
+ declare const DEFAULT_SWAP_PROMPT = "Replace the person in the first image with the person from the second image. Keep the pose, framing, camera angle, clothing fit, lighting, background, and every other pixel of the scene identical. Match the face, hair, and body of the second image exactly. Photorealistic, no artifacts.";
2396
+ declare const DEFAULT_MOTION_PROMPT = "Natural, subtle motion that continues the scene: gentle camera movement, realistic body motion, consistent lighting. Keep the person identical to the still.";
2397
+ interface CharacterSwapInput {
2398
+ sceneFrameUrl: string;
2399
+ characterImageUrl: string;
2400
+ /** A second, already-swapped keyframe for the END of the clip (Kling start+end). */
2401
+ endFrameUrl?: string;
2402
+ swapPrompt?: string;
2403
+ motionPrompt?: string;
2404
+ editModel?: string;
2405
+ /** Explicit video model; when absent, Seedance for one frame, Kling when endFrameUrl is set. */
2406
+ videoModel?: string;
2407
+ aspectRatio?: string;
2408
+ }
2409
+ /**
2410
+ * The two-node "swap the person in a still, then animate the still" graph:
2411
+ * edit (image-edit, inputImages [sceneFrame, character]) -> still
2412
+ * video (image-to-video, inputImageUrl ref edit.url) -> clip
2413
+ * With `endFrameUrl` the video node also binds `endImageUrl` (a literal) so the
2414
+ * clip lands on the approved end keyframe instead of drifting.
2415
+ */
2416
+ declare function buildCharacterSwapDefinition(input: CharacterSwapInput): WorkflowDefinition;
2417
+
2418
+ /**
2419
+ * `studio-mcp` stdio transport (Claude Code, Cursor, Claude Desktop)
2420
+ * `studio-mcp --http [--port 3939]` Streamable HTTP transport on /mcp (remote / shared)
2421
+ *
2422
+ * Config: LUMITRA_STUDIO_BASE_URL (default https://studio.lumitra.co) and
2423
+ * LUMITRA_STUDIO_API_KEY (or legacy LUMITRA_STUDIO_SERVICE_TOKEN). The token is
2424
+ * never printed. All diagnostics go to stderr (stdout is the stdio transport).
2425
+ */
2426
+
2427
+ interface CliArgs {
2428
+ http: boolean;
2429
+ port: number;
2430
+ host: string;
2431
+ help: boolean;
2432
+ version: boolean;
2433
+ }
2434
+ declare function parseArgs(argv: string[]): CliArgs;
2435
+ /**
2436
+ * Stateless Streamable HTTP: one server + transport per request, no session
2437
+ * bookkeeping to leak or expire. GET (server-initiated streams) is 405 by
2438
+ * design in this mode; clients use POST.
2439
+ */
2440
+ declare function createHttpHandler(): (req: IncomingMessage, res: ServerResponse) => Promise<void>;
2441
+ declare function main(argv?: string[]): Promise<void>;
2442
+
2443
+ export { type AllTenantsUsageResponse, type Binding, CHARACTER_SHEET_DEFINITION, CHARACTER_SHEET_NODES, type CharacterReference, type CharacterSummary, type CharacterSwapInput, ConfigError, ContractError, type CreateServerOptions, DEFAULT_BASE_URL, DEFAULT_MOTION_PROMPT, DEFAULT_SWAP_EDIT_MODEL, DEFAULT_SWAP_PROMPT, DEFAULT_SWAP_VIDEO_MODEL, DEFAULT_TIMEOUT_MS, type DocumentSummary, type FetchLike, type JobResponse, type JobStatus, type JudgeCandidate, MINT_REFERENCE_CATEGORIES, type NodeResultResponse, type NodeRun, type NodeStatus, type NodeSummary, type NodeTypesResponse, type PollOptions, PollTimeoutError, type ProjectSummary, type Projection, type RemovedNode, type RunResponse, type RunStartResponse, type RunStatus, SERVER_NAME, SERVER_VERSION, SUMMARY_TEXT_CHARS, type SpendLedger, StudioApiError, StudioClient, type StudioClientOptions, type StudioConfig, type StudioMcp, type SummaryMeta, TOOLS, TOOL_NAMES, type TaskDescriptor, type TenantSpendSummary, type TenantUsageResponse, type ToolContext, type ToolDef, ToolInputError, type ToolResult, type TurnaroundView, type UploadFile, type UsageByModel, type UsageResponse, WORKFLOW_TOOLS, type WorkflowApplyResponse, type WorkflowCreateResponse, type WorkflowDefinition, type WorkflowDocumentResponse, type WorkflowNode, type WorkflowValidateResponse, affectedNodes, buildCharacterSheetParams, buildCharacterSwapDefinition, categoryForNode, characterSheetDefinition, createHttpHandler, createStudioMcpServer, extensionForMime, filenameFromUrl, invokeTool, main, mimeForFilename, parseArgs, parseDocument, parseOps, pollUntil, projectionOf, redactSecret, registerTools, resolveConfig, seedFacePrompt, studioWorkflowApply, studioWorkflowCreate, studioWorkflowDescribe, studioWorkflowGet, studioWorkflowScreenshot, studioWorkflowValidate, summarizeDocument, summarizeNode, touchedNodeIds, turnaroundViewPrompt, waitForJob, waitForRun };