runline 0.31.0 → 0.33.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/plugin/schema.d.ts +2 -4
  2. package/dist/plugin/schema.js +47 -12
  3. package/dist/plugins/_shared/{imageFile.js → mediaFile.js} +33 -12
  4. package/dist/plugins/_shared/provider.js +22 -16
  5. package/dist/plugins/_shared/shiftCloud.js +34 -10
  6. package/dist/plugins/_shared/shiftUpload.js +1 -1
  7. package/dist/plugins/elevenlabs/src/index.js +277 -0
  8. package/dist/plugins/elevenlabs/src/schemas.js +115 -0
  9. package/dist/plugins/elevenlabs/src/shared.js +272 -0
  10. package/dist/plugins/elevenlabs/src/workflows.js +191 -0
  11. package/dist/plugins/fal/src/index.js +181 -0
  12. package/dist/plugins/fal/src/shared.js +303 -0
  13. package/dist/plugins/googleImage/src/index.js +1 -1
  14. package/dist/plugins/openai/src/index.js +1 -1
  15. package/dist/plugins/recraft/src/index.js +1 -1
  16. package/dist/plugins/replicate/src/index.js +5 -6
  17. package/dist/plugins/shiftBwm/src/collections.js +201 -0
  18. package/dist/plugins/shiftBwm/src/index.js +33 -0
  19. package/dist/plugins/shiftBwm/src/records.js +180 -0
  20. package/dist/plugins/shiftBwm/src/shared.js +143 -0
  21. package/dist/plugins/shiftBwm/src/vendor/client.js +227 -0
  22. package/dist/plugins/shiftBwm/src/vendor/contracts.js +59 -0
  23. package/dist/plugins/shiftBwm/src/vendor/models.js +525 -0
  24. package/dist/plugins/shiftObjects/src/objects.js +1 -2
  25. package/dist/plugins/shiftOcr/src/index.js +3 -1
  26. package/dist/plugins/shiftTranscription/src/shared.js +1 -1
  27. package/dist/plugins/shiftTranscription/src/transcription.js +4 -3
  28. package/dist/plugins/together/src/index.js +1 -1
  29. package/dist/plugins/xai/src/index.js +1 -1
  30. package/package.json +3 -2
@@ -0,0 +1,525 @@
1
+ /**
2
+ * SYNCED_FROM shift-labs-ai/cloud@42c9f13
3
+ * packages/business-world-model-service/src/models.ts
4
+ *
5
+ * Verbatim copy; only the import paths are rewritten. Do not edit here.
6
+ */
7
+ /**
8
+ * Public API shape: record envelopes, definitions, write inputs, queries.
9
+ * Browser-safe (Zod only).
10
+ */
11
+ import { BWM_CARDINALITIES, BWM_HISTORY_DEFAULT_LIMIT, BWM_HISTORY_MAX_LIMIT, BWM_LIST_DEFAULT_LIMIT, BWM_LIST_MAX_LIMIT, BWM_SOCIAL_HANDLE_SERVICES, BWM_VALUE_TYPES, BWM_VISIBILITY_MODES, } from "./contracts.js";
12
+ import { z } from "zod";
13
+ export const BwmValueType = z.enum(BWM_VALUE_TYPES);
14
+ export const BwmCardinality = z.enum(BWM_CARDINALITIES);
15
+ export const BwmVisibilityMode = z.enum(BWM_VISIBILITY_MODES);
16
+ export const BwmSocialHandleService = z.enum(BWM_SOCIAL_HANDLE_SERVICES);
17
+ export const BwmPrincipalType = z.enum(["user", "service"]);
18
+ export const BwmPrincipalRef = z.object({
19
+ type: BwmPrincipalType,
20
+ id: z.string().min(1),
21
+ });
22
+ const slug = z
23
+ .string()
24
+ .regex(/^[a-z][a-z0-9_]*$/)
25
+ .max(100);
26
+ /** `$system` or bare custom slug. */
27
+ const fieldKey = z.string().regex(/^\$?[a-zA-Z][a-zA-Z0-9_-]*$/);
28
+ export const BwmSelectOption = z.object({
29
+ id: z.string(),
30
+ label: z.string(),
31
+ description: z.string().nullable(),
32
+ parentId: z.string().optional(),
33
+ });
34
+ export const BwmTypeConfiguration = z.object({
35
+ currency: z.string().optional(),
36
+ handleService: BwmSocialHandleService.optional(),
37
+ multipleValues: z.boolean().optional(),
38
+ unique: z.boolean().optional(),
39
+ options: z.array(BwmSelectOption).optional(),
40
+ parentFieldKey: z.string().optional(),
41
+ });
42
+ export const BwmFieldDefinition = z.object({
43
+ id: z.string().nullable(),
44
+ slug: z.string(),
45
+ label: z.string(),
46
+ description: z.string().nullable(),
47
+ valueType: BwmValueType,
48
+ system: z.boolean(),
49
+ readOnly: z.boolean(),
50
+ required: z.boolean(),
51
+ typeConfiguration: BwmTypeConfiguration,
52
+ });
53
+ export const BwmRelationshipDefinition = z.object({
54
+ id: z.string().nullable(),
55
+ slug: z.string(),
56
+ label: z.string(),
57
+ description: z.string().nullable(),
58
+ system: z.boolean(),
59
+ readOnly: z.boolean(),
60
+ cardinality: BwmCardinality,
61
+ objectType: z.string(),
62
+ inverseKey: z.string().nullable(),
63
+ });
64
+ export const BwmDefinitions = z.object({
65
+ objectType: z.string(),
66
+ fieldDefinitions: z.record(z.string(), BwmFieldDefinition),
67
+ relationshipDefinitions: z.record(z.string(), BwmRelationshipDefinition),
68
+ });
69
+ export const BwmObjectType = z.object({
70
+ slug: z.string(),
71
+ label: z.string(),
72
+ pluralLabel: z.string(),
73
+ description: z.string().nullable(),
74
+ system: z.boolean(),
75
+ path: z.string(),
76
+ });
77
+ export const BwmVisibility = z.object({
78
+ mode: BwmVisibilityMode,
79
+ groups: z.array(z.string()),
80
+ principals: z.array(BwmPrincipalRef),
81
+ });
82
+ export const BwmFieldValue = z.object({
83
+ value: z.unknown(),
84
+ valueType: BwmValueType,
85
+ });
86
+ export const BwmRelationshipValue = z.object({
87
+ cardinality: BwmCardinality,
88
+ objectType: z.string(),
89
+ values: z.array(z.string()),
90
+ });
91
+ export const BwmRecord = z.object({
92
+ id: z.string(),
93
+ objectType: z.string(),
94
+ createdAt: z.string().datetime(),
95
+ updatedAt: z.string().datetime(),
96
+ archivedAt: z.string().datetime().nullable(),
97
+ mergedIntoId: z.string().nullable(),
98
+ externalId: z.string().nullable(),
99
+ visibility: BwmVisibility,
100
+ fields: z.record(z.string(), BwmFieldValue),
101
+ relationships: z.record(z.string(), BwmRelationshipValue),
102
+ });
103
+ export const BwmRecordPage = z.object({
104
+ data: z.array(BwmRecord),
105
+ object: z.literal("list"),
106
+ totalCount: z.number().int().nonnegative(),
107
+ });
108
+ // ─── writes ──────────────────────────────────────────────────────
109
+ const idOrIds = z.union([z.string().min(1), z.array(z.string().min(1))]);
110
+ export const BwmRelationshipOps = z
111
+ .object({
112
+ add: idOrIds.optional(),
113
+ remove: idOrIds.optional(),
114
+ replace: idOrIds.nullable().optional(),
115
+ })
116
+ .strict();
117
+ export const BwmVisibilityInput = z.object({
118
+ mode: BwmVisibilityMode,
119
+ groups: z.array(z.string().min(1)).default([]),
120
+ principals: z.array(BwmPrincipalRef).default([]),
121
+ });
122
+ export const BwmCreateRecordInput = z.object({
123
+ fields: z.record(fieldKey, z.unknown()).default({}),
124
+ relationships: z.record(fieldKey, idOrIds).default({}),
125
+ externalId: z.string().trim().min(1).max(500).optional(),
126
+ visibility: BwmVisibilityInput.optional(),
127
+ });
128
+ export const BwmUpdateRecordInput = z.object({
129
+ fields: z.record(fieldKey, z.unknown()).optional(),
130
+ relationships: z
131
+ .record(fieldKey, z.union([idOrIds, z.null(), BwmRelationshipOps]))
132
+ .optional(),
133
+ externalId: z.string().trim().max(500).nullish(),
134
+ visibility: BwmVisibilityInput.optional(),
135
+ archived: z.boolean().optional(),
136
+ });
137
+ export const BwmCreateObjectTypeInput = z.object({
138
+ slug,
139
+ label: z.string().trim().min(1).max(200),
140
+ pluralLabel: z.string().trim().min(1).max(200).optional(),
141
+ description: z.string().trim().min(1).max(2_000).optional(),
142
+ });
143
+ export const BwmCreateFieldInput = z
144
+ .object({
145
+ key: slug,
146
+ label: z.string().trim().min(1).max(200),
147
+ description: z.string().trim().min(1).max(2_000).optional(),
148
+ valueType: BwmValueType,
149
+ options: z
150
+ .array(z.object({
151
+ id: z.string().trim().min(1).max(200).optional(),
152
+ label: z.string().trim().min(1).max(500),
153
+ description: z.string().trim().max(2_000).optional(),
154
+ }))
155
+ .default([]),
156
+ validation: z
157
+ .object({
158
+ minLength: z.number().int().nonnegative().optional(),
159
+ maxLength: z.number().int().nonnegative().optional(),
160
+ minimum: z.number().finite().optional(),
161
+ maximum: z.number().finite().optional(),
162
+ pattern: z.string().max(1_000).optional(),
163
+ })
164
+ .strict()
165
+ .default({}),
166
+ typeConfiguration: z
167
+ .object({
168
+ currency: z.string().trim().length(3).optional(),
169
+ handleService: BwmSocialHandleService.optional(),
170
+ multipleValues: z.boolean().optional(),
171
+ unique: z.boolean().optional(),
172
+ })
173
+ .strict()
174
+ .default({}),
175
+ filterable: z.boolean().default(true),
176
+ })
177
+ .superRefine((input, context) => {
178
+ const isSelect = input.valueType === "SINGLE_SELECT" || input.valueType === "MULTI_SELECT";
179
+ if (isSelect && input.options.length === 0) {
180
+ context.addIssue({ code: "custom", message: "select_options_required" });
181
+ }
182
+ if (!isSelect && input.options.length > 0) {
183
+ context.addIssue({
184
+ code: "custom",
185
+ message: "select_options_not_allowed",
186
+ });
187
+ }
188
+ const labels = input.options.map((option) => option.label);
189
+ if (new Set(labels).size !== labels.length) {
190
+ context.addIssue({ code: "custom", message: "duplicate_select_option" });
191
+ }
192
+ if (input.validation.pattern !== undefined) {
193
+ try {
194
+ new RegExp(input.validation.pattern);
195
+ }
196
+ catch {
197
+ context.addIssue({ code: "custom", message: "pattern_invalid" });
198
+ }
199
+ }
200
+ const { minLength: minL, maxLength: maxL, minimum, maximum, } = input.validation;
201
+ if (minL !== undefined && maxL !== undefined && minL > maxL) {
202
+ context.addIssue({ code: "custom", message: "length_range_invalid" });
203
+ }
204
+ if (minimum !== undefined && maximum !== undefined && minimum > maximum) {
205
+ context.addIssue({ code: "custom", message: "number_range_invalid" });
206
+ }
207
+ const textual = input.valueType === "TEXT" || input.valueType === "MARKDOWN";
208
+ if (!textual &&
209
+ (minL !== undefined || maxL !== undefined || input.validation.pattern)) {
210
+ context.addIssue({
211
+ code: "custom",
212
+ message: "string_validation_not_allowed",
213
+ });
214
+ }
215
+ const numeric = input.valueType === "NUMBER" || input.valueType === "CURRENCY";
216
+ if (!numeric && (minimum !== undefined || maximum !== undefined)) {
217
+ context.addIssue({
218
+ code: "custom",
219
+ message: "number_validation_not_allowed",
220
+ });
221
+ }
222
+ if (input.valueType === "SOCIAL_HANDLE" &&
223
+ !input.typeConfiguration.handleService) {
224
+ context.addIssue({ code: "custom", message: "handle_service_required" });
225
+ }
226
+ });
227
+ export const BwmCreateRelationshipDefinitionInput = z.object({
228
+ key: slug,
229
+ label: z.string().trim().min(1).max(200),
230
+ description: z.string().trim().min(1).max(2_000).optional(),
231
+ objectType: slug,
232
+ cardinality: BwmCardinality.default("HAS_MANY"),
233
+ /** Read-only `HAS_MANY` key exposed on the target type. */
234
+ inverseKey: slug.optional(),
235
+ });
236
+ export const BwmCreatePipelineInput = z
237
+ .object({
238
+ name: z.string().trim().min(1).max(200),
239
+ isDefault: z.boolean().default(false),
240
+ stages: z
241
+ .array(z.object({
242
+ key: slug,
243
+ name: z.string().trim().min(1).max(200),
244
+ position: z.number().int().nonnegative(),
245
+ outcome: z.enum(["open", "won", "lost"]).default("open"),
246
+ defaultProbability: z.number().int().min(0).max(100).optional(),
247
+ }))
248
+ .min(1),
249
+ })
250
+ .superRefine((input, context) => {
251
+ const keys = input.stages.map((stage) => stage.key);
252
+ if (new Set(keys).size !== keys.length) {
253
+ context.addIssue({ code: "custom", message: "duplicate_stage_key" });
254
+ }
255
+ const positions = input.stages.map((stage) => stage.position);
256
+ if (new Set(positions).size !== positions.length) {
257
+ context.addIssue({ code: "custom", message: "duplicate_stage_position" });
258
+ }
259
+ });
260
+ export const BwmPipeline = z.object({
261
+ id: z.string(),
262
+ name: z.string(),
263
+ isDefault: z.boolean(),
264
+ stages: z.array(z.object({
265
+ id: z.string(),
266
+ key: z.string(),
267
+ name: z.string(),
268
+ position: z.number().int(),
269
+ outcome: z.enum(["open", "won", "lost"]),
270
+ defaultProbability: z.number().int().nullable(),
271
+ })),
272
+ createdAt: z.string().datetime(),
273
+ updatedAt: z.string().datetime(),
274
+ });
275
+ // ─── queries ─────────────────────────────────────────────────────
276
+ export const BwmFilterOperator = z.enum([
277
+ "equal",
278
+ "startsWith",
279
+ "contains",
280
+ "greaterThan",
281
+ "greaterThanOrEqual",
282
+ "lessThan",
283
+ "lessThanOrEqual",
284
+ ]);
285
+ export const BwmFilter = z.object({
286
+ key: z.string().min(1),
287
+ operator: BwmFilterOperator.optional(),
288
+ negate: z.boolean().default(false),
289
+ value: z.string(),
290
+ });
291
+ export const BwmListQuery = z.object({
292
+ limit: z.coerce
293
+ .number()
294
+ .int()
295
+ .min(1)
296
+ .max(BWM_LIST_MAX_LIMIT)
297
+ .default(BWM_LIST_DEFAULT_LIMIT),
298
+ offset: z.coerce.number().int().nonnegative().default(0),
299
+ includeArchived: z.boolean().default(false),
300
+ filters: z.array(BwmFilter).default([]),
301
+ });
302
+ export const BwmHistoryQuery = z.object({
303
+ limit: z.coerce
304
+ .number()
305
+ .int()
306
+ .min(1)
307
+ .max(BWM_HISTORY_MAX_LIMIT)
308
+ .default(BWM_HISTORY_DEFAULT_LIMIT),
309
+ after: z.string().min(1).optional(),
310
+ });
311
+ export const BwmFieldHistoryEntry = z.object({
312
+ value: z.unknown(),
313
+ valueType: BwmValueType,
314
+ displayValue: z.string(),
315
+ recordedAt: z.string().datetime(),
316
+ isCreate: z.boolean(),
317
+ });
318
+ export const BwmFieldHistory = z.object({
319
+ data: z.array(BwmFieldHistoryEntry),
320
+ hasMore: z.boolean(),
321
+ nextCursor: z.string().nullable(),
322
+ });
323
+ export const BwmLinkDirection = z.enum(["in", "out", "both"]);
324
+ // ─── lists, groups, merges, members ──────────────────────────────
325
+ export const BwmList = z.object({
326
+ id: z.string(),
327
+ createdAt: z.string().datetime(),
328
+ updatedAt: z.string().datetime(),
329
+ archivedAt: z.string().datetime().nullable(),
330
+ fields: z.object({
331
+ $name: BwmFieldValue,
332
+ $objectType: BwmFieldValue,
333
+ $description: BwmFieldValue,
334
+ }),
335
+ relationships: z.object({ $records: BwmRelationshipValue }),
336
+ });
337
+ export const BwmCreateListInput = z.object({
338
+ fields: z.object({
339
+ $name: z.string().trim().min(1).max(200),
340
+ $objectType: z.string().min(1),
341
+ $description: z.string().trim().max(2_000).nullish(),
342
+ }),
343
+ relationships: z.object({ $records: idOrIds.optional() }).default({}),
344
+ });
345
+ export const BwmUpdateListInput = z.object({
346
+ fields: z
347
+ .object({
348
+ $name: z.string().trim().min(1).max(200).optional(),
349
+ $description: z.string().trim().max(2_000).nullish(),
350
+ })
351
+ .optional(),
352
+ relationships: z
353
+ .object({ $records: z.union([idOrIds, BwmRelationshipOps]).optional() })
354
+ .optional(),
355
+ archived: z.boolean().optional(),
356
+ });
357
+ export const BwmGroup = z.object({
358
+ id: z.string(),
359
+ slug: z.string(),
360
+ name: z.string(),
361
+ description: z.string().nullable(),
362
+ members: z.array(BwmPrincipalRef),
363
+ createdAt: z.string().datetime(),
364
+ updatedAt: z.string().datetime(),
365
+ });
366
+ export const BwmCreateGroupInput = z.object({
367
+ slug,
368
+ name: z.string().trim().min(1).max(200),
369
+ description: z.string().trim().min(1).max(2_000).optional(),
370
+ members: z.array(BwmPrincipalRef).default([]),
371
+ });
372
+ export const BwmUpdateGroupInput = z.object({
373
+ name: z.string().trim().min(1).max(200).optional(),
374
+ description: z.string().trim().max(2_000).nullish(),
375
+ });
376
+ export const BwmGroupMembersInput = z
377
+ .object({
378
+ add: z.array(BwmPrincipalRef).default([]),
379
+ remove: z.array(BwmPrincipalRef).default([]),
380
+ })
381
+ .refine((input) => input.add.length > 0 || input.remove.length > 0, "group_members_empty");
382
+ export const BwmMergeInput = z.object({
383
+ primaryId: z.string().min(1),
384
+ duplicateId: z.string().min(1),
385
+ fieldResolutions: z
386
+ .record(fieldKey, z.union([
387
+ z.literal("primary"),
388
+ z.literal("duplicate"),
389
+ z.object({ value: z.unknown() }),
390
+ ]))
391
+ .default({}),
392
+ options: z.object({ multiSelectUnion: z.boolean().default(true) }).default({
393
+ multiSelectUnion: true,
394
+ }),
395
+ });
396
+ export const BwmMerge = z.object({
397
+ id: z.string(),
398
+ createdAt: z.string().datetime(),
399
+ objectType: z.string(),
400
+ primaryId: z.string(),
401
+ duplicateId: z.string(),
402
+ status: z.enum(["done", "failed"]),
403
+ summary: z.object({
404
+ fieldWriteCount: z.number().int(),
405
+ repointedCount: z.number().int(),
406
+ warnings: z.array(z.string()),
407
+ }),
408
+ });
409
+ export const BwmMergeResult = z.object({
410
+ merge: BwmMerge,
411
+ primary: BwmRecord,
412
+ summary: BwmMerge.shape.summary,
413
+ });
414
+ export const BwmMember = z.object({
415
+ id: z.string(),
416
+ createdAt: z.string().datetime(),
417
+ fields: z.object({
418
+ $name: BwmFieldValue,
419
+ $email: BwmFieldValue,
420
+ $role: BwmFieldValue,
421
+ }),
422
+ });
423
+ export const BwmMemberPage = z.object({
424
+ data: z.array(BwmMember),
425
+ object: z.literal("list"),
426
+ totalCount: z.number().int(),
427
+ });
428
+ export const BwmChangeEvent = z.object({
429
+ id: z.string(),
430
+ recordId: z.string(),
431
+ actor: BwmPrincipalRef,
432
+ action: z.enum(["created", "updated"]),
433
+ before: z.unknown().optional(),
434
+ after: z.unknown(),
435
+ importRunId: z.string().nullable(),
436
+ createdAt: z.string().datetime(),
437
+ });
438
+ export const BwmLink = z.object({
439
+ id: z.string(),
440
+ fromRecordId: z.string(),
441
+ toRecordId: z.string(),
442
+ fromObjectType: z.string(),
443
+ toObjectType: z.string(),
444
+ key: z.string(),
445
+ role: z.string().nullable(),
446
+ attributes: z.record(z.string(), z.unknown()),
447
+ declared: z.boolean(),
448
+ createdAt: z.string().datetime(),
449
+ });
450
+ export const BwmLinks = z.object({
451
+ outbound: z.array(BwmLink),
452
+ inbound: z.array(BwmLink),
453
+ });
454
+ export const BwmFileUploadInput = z.object({
455
+ filename: z.string().trim().min(1).max(500),
456
+ mimeType: z.string().trim().min(1).max(200),
457
+ sizeBytes: z.number().int().positive(),
458
+ });
459
+ export const BwmFile = z.object({
460
+ id: z.string(),
461
+ filename: z.string().nullable(),
462
+ mimeType: z.string(),
463
+ sizeBytes: z.number().int(),
464
+ status: z.enum(["PENDING", "COMPLETED", "ARCHIVED"]),
465
+ createdAt: z.string().datetime(),
466
+ completedAt: z.string().datetime().nullable(),
467
+ });
468
+ /** A file plus its one-time upload grant; `expiresAt` is the grant's. */
469
+ export const BwmFileUpload = BwmFile.extend({
470
+ uploadUrl: z.string(),
471
+ uploadMethod: z.string(),
472
+ uploadHeaders: z.record(z.string(), z.string()),
473
+ expiresAt: z.string().datetime(),
474
+ });
475
+ export const BwmFileUrl = z.object({
476
+ url: z.string(),
477
+ expiresAt: z.string().datetime(),
478
+ });
479
+ // ─── imports (Shift protocol, unchanged) ─────────────────────────
480
+ export const BwmCreateImportRunInput = z.object({
481
+ sourceSystem: z.string().trim().min(1).max(100),
482
+ });
483
+ export const BwmStageImportRowsInput = z.object({
484
+ rows: z
485
+ .array(z.object({
486
+ sourceId: z.string().trim().min(1).max(500),
487
+ objectType: slug,
488
+ rawPayload: z.json(),
489
+ }))
490
+ .min(1)
491
+ .max(500),
492
+ });
493
+ export const BwmCommitImportRowInput = z.object({
494
+ transformedPayload: z.json(),
495
+ });
496
+ /**
497
+ * Parses `key[op]=value` / `key[-op]=value` / `key=value` query pairs into
498
+ * filters. Reserved pagination keys are skipped.
499
+ */
500
+ export function parseFilterQuery(entries) {
501
+ const reserved = new Set(["limit", "offset", "includeArchived"]);
502
+ const filters = [];
503
+ for (const [rawKey, value] of entries) {
504
+ if (reserved.has(rawKey))
505
+ continue;
506
+ const match = /^(.+?)(?:\[(-?)([a-zA-Z]+)\])?$/.exec(rawKey);
507
+ if (!match)
508
+ continue;
509
+ const [, key, minus, operator] = match;
510
+ if (!key)
511
+ continue;
512
+ const parsedOperator = operator
513
+ ? BwmFilterOperator.safeParse(operator)
514
+ : undefined;
515
+ if (parsedOperator && !parsedOperator.success)
516
+ continue;
517
+ filters.push({
518
+ key,
519
+ operator: parsedOperator?.data,
520
+ negate: minus === "-",
521
+ value,
522
+ });
523
+ }
524
+ return filters;
525
+ }
@@ -1,7 +1,7 @@
1
1
  import { writeFile } from "node:fs/promises";
2
2
  import { basename } from "node:path";
3
3
  import * as t from "typebox";
4
- import { enumSchema, listParams, pathSegment, request, withQuery, } from "../../_shared/shiftCloud.js";
4
+ import { enumSchema, listParams, pathSegment, request, STRICT_OBJECT, withQuery, } from "../../_shared/shiftCloud.js";
5
5
  import { GENERAL_MEDIA_TYPES, mediaTypeFromPath, putThroughGrant, SIGNED_UPLOAD_MAX_BYTES, statUploadFile, } from "../../_shared/shiftUpload.js";
6
6
  const OBJECTS_BASE = "/v1/services/objects";
7
7
  export const OBJECT_STATUS = ["pending_upload", "ready", "archived"];
@@ -11,7 +11,6 @@ export const OBJECT_LINK_TARGET = [
11
11
  "eval_case",
12
12
  "db_record",
13
13
  ];
14
- const STRICT_OBJECT = { additionalProperties: false };
15
14
  const Id = t.String({ minLength: 1, pattern: "\\S" });
16
15
  function linkSchema() {
17
16
  return t.Object({
@@ -30,6 +30,8 @@ const DOCUMENT_TYPES = {
30
30
  * anything larger uploads to the object bucket instead.
31
31
  */
32
32
  const MAX_INLINE_BYTES = 20 * 1024 * 1024;
33
+ /** Extraction runs synchronously; a long multi-page PDF takes minutes, not seconds. */
34
+ const EXTRACT_TIMEOUT_MS = 5 * 60_000;
33
35
  async function documentFromPath(ctx, path) {
34
36
  const extension = extname(path).slice(1).toLowerCase();
35
37
  const imageType = IMAGE_TYPES[extension];
@@ -175,7 +177,7 @@ export default function shiftOcr(rl) {
175
177
  }
176
178
  : {}),
177
179
  }),
178
- });
180
+ }, EXTRACT_TIMEOUT_MS);
179
181
  },
180
182
  });
181
183
  rl.registerAction("ocr.providers", {
@@ -1,3 +1,3 @@
1
- export { enumSchema, pathSegment, request, } from "../../_shared/shiftCloud.js";
1
+ export { enumSchema, pathSegment, request, SHIFT_REQUEST_TIMEOUT_MS, STRICT_OBJECT, } from "../../_shared/shiftCloud.js";
2
2
  export const TRANSCRIPTION_LANGUAGE = ["auto", "en", "he"];
3
3
  export const TRANSCRIPT_FORMAT = ["txt", "srt", "vtt", "json"];
@@ -1,9 +1,8 @@
1
1
  import * as t from "typebox";
2
2
  import { AUDIO_VIDEO_MEDIA_TYPES, putThroughGrant, requireMediaType, SIGNED_UPLOAD_MAX_BYTES, statUploadFile, } from "../../_shared/shiftUpload.js";
3
- import { enumSchema, pathSegment, request, TRANSCRIPT_FORMAT, TRANSCRIPTION_LANGUAGE, } from "./shared.js";
3
+ import { enumSchema, pathSegment, request, SHIFT_REQUEST_TIMEOUT_MS, STRICT_OBJECT, TRANSCRIPT_FORMAT, TRANSCRIPTION_LANGUAGE, } from "./shared.js";
4
4
  /** Transcript previews returned into the sandbox are capped, not truncated silently. */
5
5
  const MAX_TRANSCRIPT_BYTES = 2 * 1024 * 1024;
6
- const STRICT_OBJECT = { additionalProperties: false };
7
6
  const Id = t.String({ minLength: 1, pattern: "\\S" });
8
7
  export function registerTranscriptionActions(rl) {
9
8
  rl.registerAction("transcription.transcribe", {
@@ -64,7 +63,9 @@ export function registerTranscriptionActions(rl) {
64
63
  if (!fields.waitSeconds)
65
64
  return job;
66
65
  const timeoutMs = Math.min(Math.max(fields.waitSeconds, 1), 120) * 1000;
67
- return request(ctx, `/v1/services/transcription/jobs/${pathSegment(job.id)}/await?timeoutMs=${timeoutMs}`, { method: "POST" });
66
+ // The server holds the request open for up to timeoutMs, so the
67
+ // client deadline is that wait plus the ordinary allowance.
68
+ return request(ctx, `/v1/services/transcription/jobs/${pathSegment(job.id)}/await?timeoutMs=${timeoutMs}`, { method: "POST" }, timeoutMs + SHIFT_REQUEST_TIMEOUT_MS);
68
69
  },
69
70
  });
70
71
  rl.registerAction("transcription.job.list", {
@@ -12,7 +12,7 @@
12
12
  * fidelity switch to FLUX.1-dev / Ideogram / Qwen-Image and bump
13
13
  * `steps` accordingly (20–30 is typical for non-schnell models).
14
14
  */
15
- import { readImageInput, SEND_FILE_NOTE, writeImageFile } from "../../_shared/imageFile.js";
15
+ import { readImageInput, SEND_FILE_NOTE, writeImageFile } from "../../_shared/mediaFile.js";
16
16
  import { parseSize } from "../../_shared/parseSize.js";
17
17
  const ENDPOINT = "https://api.together.xyz/v1/images/generations";
18
18
  export default function together(rl) {
@@ -8,7 +8,7 @@
8
8
  * text rendering well. Sized via aspect_ratio rather than W×H —
9
9
  * the API does the math.
10
10
  */
11
- import { readImageInput, SEND_FILE_NOTE, writeImageFile } from "../../_shared/imageFile.js";
11
+ import { readImageInput, SEND_FILE_NOTE, writeImageFile } from "../../_shared/mediaFile.js";
12
12
  const ENDPOINT = "https://api.x.ai/v1/images/generations";
13
13
  const EDIT_ENDPOINT = "https://api.x.ai/v1/images/edits";
14
14
  const MODEL = "grok-imagine-image";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "runline",
3
- "version": "0.31.0",
3
+ "version": "0.33.0",
4
4
  "description": "Code mode for agents \u2014 turn any API or command into a callable action",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -95,6 +95,7 @@
95
95
  "jiti": "^2.7.0",
96
96
  "proper-lockfile": "^4.1.2",
97
97
  "rrule": "^2.8.1",
98
- "typebox": "^1.1.35"
98
+ "typebox": "^1.1.35",
99
+ "zod": "^4.2.1"
99
100
  }
100
101
  }