@vertesia/client 0.79.0 → 0.80.0-dev-20251118

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 (126) hide show
  1. package/lib/cjs/InteractionCatalogApi.js +64 -0
  2. package/lib/cjs/InteractionCatalogApi.js.map +1 -0
  3. package/lib/cjs/InteractionOutput.js +300 -0
  4. package/lib/cjs/InteractionOutput.js.map +1 -0
  5. package/lib/cjs/InteractionResult.example.js +57 -0
  6. package/lib/cjs/InteractionResult.example.js.map +1 -0
  7. package/lib/cjs/InteractionsApi.js +20 -6
  8. package/lib/cjs/InteractionsApi.js.map +1 -1
  9. package/lib/cjs/ProjectsApi.js +2 -1
  10. package/lib/cjs/ProjectsApi.js.map +1 -1
  11. package/lib/cjs/RunsApi.js +12 -4
  12. package/lib/cjs/RunsApi.js.map +1 -1
  13. package/lib/cjs/client.js +107 -40
  14. package/lib/cjs/client.js.map +1 -1
  15. package/lib/cjs/index.js +6 -0
  16. package/lib/cjs/index.js.map +1 -1
  17. package/lib/cjs/store/CollectionsApi.js +21 -0
  18. package/lib/cjs/store/CollectionsApi.js.map +1 -1
  19. package/lib/cjs/store/FilesApi.js +9 -8
  20. package/lib/cjs/store/FilesApi.js.map +1 -1
  21. package/lib/cjs/store/ObjectsApi.js +5 -4
  22. package/lib/cjs/store/ObjectsApi.js.map +1 -1
  23. package/lib/cjs/store/TypesApi.js +1 -1
  24. package/lib/cjs/store/TypesApi.js.map +1 -1
  25. package/lib/cjs/store/WorkflowsApi.js +151 -2
  26. package/lib/cjs/store/WorkflowsApi.js.map +1 -1
  27. package/lib/cjs/store/client.js.map +1 -1
  28. package/lib/esm/InteractionCatalogApi.js +60 -0
  29. package/lib/esm/InteractionCatalogApi.js.map +1 -0
  30. package/lib/esm/InteractionOutput.js +293 -0
  31. package/lib/esm/InteractionOutput.js.map +1 -0
  32. package/lib/esm/InteractionResult.example.js +55 -0
  33. package/lib/esm/InteractionResult.example.js.map +1 -0
  34. package/lib/esm/InteractionsApi.js +20 -6
  35. package/lib/esm/InteractionsApi.js.map +1 -1
  36. package/lib/esm/ProjectsApi.js +1 -1
  37. package/lib/esm/ProjectsApi.js.map +1 -1
  38. package/lib/esm/RunsApi.js +12 -4
  39. package/lib/esm/RunsApi.js.map +1 -1
  40. package/lib/esm/client.js +106 -39
  41. package/lib/esm/client.js.map +1 -1
  42. package/lib/esm/index.js +3 -0
  43. package/lib/esm/index.js.map +1 -1
  44. package/lib/esm/store/CollectionsApi.js +21 -0
  45. package/lib/esm/store/CollectionsApi.js.map +1 -1
  46. package/lib/esm/store/FilesApi.js +9 -8
  47. package/lib/esm/store/FilesApi.js.map +1 -1
  48. package/lib/esm/store/ObjectsApi.js +5 -4
  49. package/lib/esm/store/ObjectsApi.js.map +1 -1
  50. package/lib/esm/store/TypesApi.js +1 -1
  51. package/lib/esm/store/TypesApi.js.map +1 -1
  52. package/lib/esm/store/WorkflowsApi.js +151 -2
  53. package/lib/esm/store/WorkflowsApi.js.map +1 -1
  54. package/lib/esm/store/client.js.map +1 -1
  55. package/lib/tsconfig.tsbuildinfo +1 -1
  56. package/lib/types/AccountApi.d.ts +1 -0
  57. package/lib/types/AccountsApi.d.ts +1 -0
  58. package/lib/types/AnalyticsApi.d.ts +1 -0
  59. package/lib/types/ApiKeysApi.d.ts +1 -0
  60. package/lib/types/AppsApi.d.ts +1 -0
  61. package/lib/types/CommandsApi.d.ts +1 -0
  62. package/lib/types/EnvironmentsApi.d.ts +1 -0
  63. package/lib/types/GroupsApi.d.ts +1 -0
  64. package/lib/types/IamApi.d.ts +1 -0
  65. package/lib/types/InteractionBase.d.ts +1 -0
  66. package/lib/types/InteractionCatalogApi.d.ts +37 -0
  67. package/lib/types/InteractionCatalogApi.d.ts.map +1 -0
  68. package/lib/types/InteractionOutput.d.ts +175 -0
  69. package/lib/types/InteractionOutput.d.ts.map +1 -0
  70. package/lib/types/InteractionResult.example.d.ts +7 -0
  71. package/lib/types/InteractionResult.example.d.ts.map +1 -0
  72. package/lib/types/InteractionsApi.d.ts +10 -6
  73. package/lib/types/InteractionsApi.d.ts.map +1 -1
  74. package/lib/types/ProjectsApi.d.ts +2 -1
  75. package/lib/types/ProjectsApi.d.ts.map +1 -1
  76. package/lib/types/PromptsApi.d.ts +1 -0
  77. package/lib/types/RefsApi.d.ts +1 -0
  78. package/lib/types/RunsApi.d.ts +7 -4
  79. package/lib/types/RunsApi.d.ts.map +1 -1
  80. package/lib/types/StreamSource.d.ts +1 -0
  81. package/lib/types/TrainingApi.d.ts +1 -0
  82. package/lib/types/UsersApi.d.ts +1 -0
  83. package/lib/types/client.d.ts +10 -5
  84. package/lib/types/client.d.ts.map +1 -1
  85. package/lib/types/execute.d.ts +1 -0
  86. package/lib/types/index.d.ts +6 -1
  87. package/lib/types/index.d.ts.map +1 -1
  88. package/lib/types/nodejs/NodeStreamSource.d.ts +1 -0
  89. package/lib/types/nodejs/index.d.ts +1 -0
  90. package/lib/types/store/AgentsApi.d.ts +1 -0
  91. package/lib/types/store/AnalyzeDocApi.d.ts +1 -0
  92. package/lib/types/store/CollectionsApi.d.ts +8 -0
  93. package/lib/types/store/CollectionsApi.d.ts.map +1 -1
  94. package/lib/types/store/CommandsApi.d.ts +1 -0
  95. package/lib/types/store/EmbeddingsApi.d.ts +1 -0
  96. package/lib/types/store/FilesApi.d.ts +4 -2
  97. package/lib/types/store/FilesApi.d.ts.map +1 -1
  98. package/lib/types/store/ObjectsApi.d.ts +7 -11
  99. package/lib/types/store/ObjectsApi.d.ts.map +1 -1
  100. package/lib/types/store/TypesApi.d.ts +1 -0
  101. package/lib/types/store/WorkflowsApi.d.ts +13 -0
  102. package/lib/types/store/WorkflowsApi.d.ts.map +1 -1
  103. package/lib/types/store/client.d.ts +2 -0
  104. package/lib/types/store/client.d.ts.map +1 -1
  105. package/lib/types/store/errors.d.ts +1 -0
  106. package/lib/types/store/index.d.ts +1 -0
  107. package/lib/types/store/version.d.ts +1 -0
  108. package/lib/vertesia-client.js +1 -1
  109. package/lib/vertesia-client.js.map +1 -1
  110. package/package.json +59 -54
  111. package/src/InteractionCatalogApi.ts +72 -0
  112. package/src/InteractionOutput.test.ts +305 -0
  113. package/src/InteractionOutput.ts +328 -0
  114. package/src/InteractionResult.example.ts +72 -0
  115. package/src/InteractionsApi.ts +34 -9
  116. package/src/ProjectsApi.ts +7 -1
  117. package/src/RunsApi.ts +15 -5
  118. package/src/client.test.ts +2 -0
  119. package/src/client.ts +128 -57
  120. package/src/index.ts +2 -0
  121. package/src/store/CollectionsApi.ts +39 -2
  122. package/src/store/FilesApi.ts +10 -8
  123. package/src/store/ObjectsApi.ts +7 -23
  124. package/src/store/TypesApi.ts +1 -1
  125. package/src/store/WorkflowsApi.ts +171 -2
  126. package/src/store/client.ts +1 -0
@@ -59,12 +59,14 @@ export class FilesApi extends ApiTopic {
59
59
  });
60
60
  }
61
61
 
62
- getDownloadUrl(file: string): Promise<GetFileUrlResponse> {
63
- return this.post("/download-url", {
64
- payload: {
65
- file,
66
- } satisfies GetFileUrlPayload,
67
- });
62
+ // Strictly typed: provide either simple args or a full payload via a separate method
63
+ getDownloadUrl(file: string, name?: string, disposition?: "inline" | "attachment"): Promise<GetFileUrlResponse> {
64
+ const payload: GetFileUrlPayload = { file, name, disposition };
65
+ return this.post("/download-url", { payload });
66
+ }
67
+
68
+ getDownloadUrlWithOptions(payload: GetFileUrlPayload): Promise<GetFileUrlResponse> {
69
+ return this.post("/download-url", { payload });
68
70
  }
69
71
 
70
72
  /**
@@ -120,9 +122,9 @@ export class FilesApi extends ApiTopic {
120
122
  if (res.ok) {
121
123
  return res;
122
124
  } else if (res.status === 404) {
123
- throw new Error(`File ${location} not found`); //TODO: type fetch error better with a fetch error class
125
+ throw new Error(`File at ${url} not found`); //TODO: type fetch error better with a fetch error class
124
126
  } else if (res.status === 403) {
125
- throw new Error(`File ${location} is forbidden`);
127
+ throw new Error(`File at ${url} is forbidden`);
126
128
  } else {
127
129
  console.log(res);
128
130
  throw new Error(
@@ -27,24 +27,6 @@ import { StreamSource } from "../StreamSource.js";
27
27
  import { AnalyzeDocApi } from "./AnalyzeDocApi.js";
28
28
  import { ZenoClient } from "./client.js";
29
29
 
30
- export interface UploadContentObjectPayload
31
- extends Omit<CreateContentObjectPayload, "content"> {
32
- content?:
33
- | StreamSource
34
- | File
35
- | {
36
- // the source URI
37
- source: string;
38
- // the original name of the input file if any
39
- name?: string;
40
- // the mime type of the content source.
41
- type?: string;
42
-
43
- // the target id in the content store
44
- id?: string;
45
- };
46
- }
47
-
48
30
  export interface ComputeFacetsResponse {
49
31
  type?: { _id: string; count: number }[];
50
32
  location?: { _id: string; count: number }[];
@@ -72,14 +54,16 @@ export class ObjectsApi extends ApiTopic {
72
54
  });
73
55
  }
74
56
 
75
- getDownloadUrl(fileUri: string): Promise<{ url: string }> {
57
+ getDownloadUrl(fileUri: string, name?: string, disposition?: "inline" | "attachment"): Promise<{ url: string }> {
76
58
  return this.post("/download-url", {
77
- payload: {
78
- file: fileUri,
79
- } satisfies GetFileUrlPayload,
59
+ payload: { file: fileUri, name, disposition } satisfies GetFileUrlPayload,
80
60
  });
81
61
  }
82
62
 
63
+ getDownloadUrlWithOptions(payload: GetFileUrlPayload): Promise<{ url: string }> {
64
+ return this.post("/download-url", { payload });
65
+ }
66
+
83
67
  getContentSource(objectId: string): Promise<ContentSource> {
84
68
  return this.get(`/${objectId}/content-source`);
85
69
  }
@@ -217,7 +201,7 @@ export class ObjectsApi extends ApiTopic {
217
201
  }
218
202
 
219
203
  async create(
220
- payload: UploadContentObjectPayload,
204
+ payload: CreateContentObjectPayload,
221
205
  options?: {
222
206
  collection_id?: string;
223
207
  processing_priority?: ContentObjectProcessingPriority;
@@ -17,7 +17,7 @@ export class TypesApi extends ApiTopic {
17
17
  * @returns
18
18
  */
19
19
  list(payload: ObjectTypeSearchPayload = {}, options?: { layout?: boolean, schema?: boolean }): Promise<ContentObjectTypeItem[]> {
20
- const limit = payload.limit || 100;
20
+ const limit = payload.limit || 2000;
21
21
  const offset = payload.offset || 0;
22
22
  const query = payload.query || {} as ObjectTypeSearchQuery;
23
23
 
@@ -10,6 +10,9 @@ import {
10
10
  ListWorkflowInteractionsResponse,
11
11
  ListWorkflowRunsPayload,
12
12
  ListWorkflowRunsResponse,
13
+ WebSocketClientMessage,
14
+ WebSocketServerMessage,
15
+ WorkflowActionPayload,
13
16
  WorkflowDefinitionRef,
14
17
  WorkflowRule,
15
18
  WorkflowRuleItem,
@@ -56,11 +59,13 @@ export class WorkflowsApi extends ApiTopic {
56
59
  }
57
60
 
58
61
  terminate(workflowId: string, runId: string, reason?: string): Promise<{ message: string }> {
59
- return this.post(`/runs/${workflowId}/${runId}/actions/terminate`, { payload: { reason } });
62
+ const payload: WorkflowActionPayload = { reason };
63
+ return this.post(`/runs/${workflowId}/${runId}/actions/terminate`, { payload });
60
64
  }
61
65
 
62
66
  cancel(workflowId: string, runId: string, reason?: string): Promise<{ message: string }> {
63
- return this.post(`/runs/${workflowId}/${runId}/actions/cancel`, { payload: { reason } });
67
+ const payload: WorkflowActionPayload = { reason };
68
+ return this.post(`/runs/${workflowId}/${runId}/actions/cancel`, { payload });
64
69
  }
65
70
 
66
71
  execute(
@@ -248,6 +253,170 @@ export class WorkflowsApi extends ApiTopic {
248
253
  });
249
254
  }
250
255
 
256
+ /**
257
+ * Stream workflow messages via WebSocket (for mobile/React Native clients)
258
+ * @param workflowId The workflow ID
259
+ * @param runId The run ID
260
+ * @param onMessage Callback for incoming messages
261
+ * @param since Optional timestamp to resume from
262
+ * @returns Promise that resolves with cleanup function and sendSignal helper
263
+ */
264
+ async streamMessagesWS(
265
+ workflowId: string,
266
+ runId: string,
267
+ onMessage?: (message: AgentMessage) => void,
268
+ since?: number
269
+ ): Promise<{ cleanup: () => void; sendSignal: (signalName: string, data: any) => void }> {
270
+ return new Promise((resolve, reject) => {
271
+ let reconnectAttempts = 0;
272
+ const maxReconnectAttempts = 10;
273
+ const baseDelay = 1000;
274
+ const maxDelay = 30000;
275
+ let ws: WebSocket | null = null;
276
+ let lastMessageTimestamp = since || 0;
277
+ let isClosed = false;
278
+
279
+ const calculateBackoffDelay = (attempts: number): number => {
280
+ const exponentialDelay = Math.min(baseDelay * Math.pow(2, attempts), maxDelay);
281
+ const jitter = Math.random() * 0.1 * exponentialDelay;
282
+ return exponentialDelay + jitter;
283
+ };
284
+
285
+ const connect = async () => {
286
+ if (isClosed) return;
287
+
288
+ try {
289
+ const client = this.client as VertesiaClient;
290
+ const wsUrl = new URL(client.workflows.baseUrl + `/runs/${workflowId}/${runId}/ws`);
291
+
292
+ // Replace http/https with ws/wss
293
+ wsUrl.protocol = wsUrl.protocol.replace('http', 'ws');
294
+
295
+ // Add query parameters
296
+ if (lastMessageTimestamp > 0) {
297
+ wsUrl.searchParams.set('since', lastMessageTimestamp.toString());
298
+ }
299
+
300
+ const bearerToken = client._auth ? await client._auth() : undefined;
301
+ if (!bearerToken) {
302
+ reject(new Error('No auth token available'));
303
+ return;
304
+ }
305
+
306
+ const token = bearerToken.split(' ')[1];
307
+ wsUrl.searchParams.set('access_token', token);
308
+
309
+ if (reconnectAttempts > 0) {
310
+ console.log(`Reconnecting to WebSocket for run ${runId} (attempt ${reconnectAttempts + 1}/${maxReconnectAttempts})`);
311
+ }
312
+
313
+ ws = new WebSocket(wsUrl.href);
314
+
315
+ ws.onopen = () => {
316
+ if (reconnectAttempts > 0) {
317
+ console.log(`Successfully reconnected to WebSocket for run ${runId}`);
318
+ }
319
+ reconnectAttempts = 0;
320
+
321
+ // Resolve with helpers on first successful connection
322
+ if (!isClosed) {
323
+ resolve({
324
+ cleanup: () => {
325
+ isClosed = true;
326
+ if (ws) {
327
+ ws.close();
328
+ ws = null;
329
+ }
330
+ },
331
+ sendSignal: (signalName: string, data: any) => {
332
+ if (ws?.readyState === WebSocket.OPEN) {
333
+ const message: WebSocketClientMessage = {
334
+ type: 'signal',
335
+ signalName,
336
+ data,
337
+ requestId: Date.now()
338
+ };
339
+ ws.send(JSON.stringify(message));
340
+ } else {
341
+ console.warn('WebSocket not open, cannot send signal');
342
+ }
343
+ }
344
+ });
345
+ }
346
+ };
347
+
348
+ ws.onmessage = (event: MessageEvent) => {
349
+ try {
350
+ const message = JSON.parse(event.data) as WebSocketServerMessage;
351
+
352
+ // Handle different message types
353
+ if ('workflow_run_id' in message) {
354
+ // This is an AgentMessage
355
+ const agentMessage = message as AgentMessage;
356
+
357
+ if (agentMessage.timestamp) {
358
+ lastMessageTimestamp = Math.max(lastMessageTimestamp, agentMessage.timestamp);
359
+ }
360
+
361
+ if (onMessage) onMessage(agentMessage);
362
+
363
+ // Check for stream completion
364
+ const streamIsOver =
365
+ agentMessage.type === AgentMessageType.TERMINATED ||
366
+ (agentMessage.type === AgentMessageType.COMPLETE &&
367
+ (!agentMessage.workstream_id || agentMessage.workstream_id === 'main'));
368
+
369
+ if (streamIsOver) {
370
+ console.log('Closing WebSocket due to workflow completion');
371
+ isClosed = true;
372
+ if (ws) {
373
+ ws.close();
374
+ ws = null;
375
+ }
376
+ }
377
+ } else if (message.type === 'pong') {
378
+ // Heartbeat response
379
+ console.debug('Received pong');
380
+ } else if (message.type === 'ack') {
381
+ console.debug('Signal acknowledged', message);
382
+ } else if (message.type === 'error') {
383
+ console.error('WebSocket error message', message);
384
+ }
385
+ } catch (err) {
386
+ console.error('Failed to parse WebSocket message', err);
387
+ }
388
+ };
389
+
390
+ ws.onerror = (err) => {
391
+ console.error('WebSocket error', err);
392
+ };
393
+
394
+ ws.onclose = () => {
395
+ if (!isClosed && reconnectAttempts < maxReconnectAttempts) {
396
+ const delay = calculateBackoffDelay(reconnectAttempts);
397
+ console.log(`WebSocket closed, reconnecting in ${delay}ms (attempt ${reconnectAttempts + 1}/${maxReconnectAttempts})`);
398
+ reconnectAttempts++;
399
+ setTimeout(connect, delay);
400
+ } else if (reconnectAttempts >= maxReconnectAttempts) {
401
+ reject(new Error(`WebSocket connection failed after ${maxReconnectAttempts} attempts`));
402
+ }
403
+ };
404
+ } catch (err) {
405
+ console.error('Error setting up WebSocket', err);
406
+ if (reconnectAttempts < maxReconnectAttempts) {
407
+ const delay = calculateBackoffDelay(reconnectAttempts);
408
+ reconnectAttempts++;
409
+ setTimeout(connect, delay);
410
+ } else {
411
+ reject(err);
412
+ }
413
+ }
414
+ };
415
+
416
+ connect();
417
+ });
418
+ }
419
+
251
420
  rules = new WorkflowsRulesApi(this);
252
421
  definitions = new WorkflowsDefinitionApi(this);
253
422
  }
@@ -13,6 +13,7 @@ import { WorkflowsApi } from "./WorkflowsApi.js";
13
13
 
14
14
  export interface ZenoClientProps {
15
15
  serverUrl?: string;
16
+ tokenServerUrl?: string;
16
17
  apikey?: string;
17
18
  onRequest?: (request: Request) => void;
18
19
  onResponse?: (response: Response) => void;