@vertesia/client 1.5.0-dev.20260807.073259Z → 1.5.0-dev.20260901.005903Z
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.
- package/lib/AppsApi.d.ts +9 -8
- package/lib/AppsApi.d.ts.map +1 -1
- package/lib/AppsApi.js +11 -4
- package/lib/AppsApi.js.map +1 -1
- package/lib/GroupsApi.d.ts +4 -11
- package/lib/GroupsApi.d.ts.map +1 -1
- package/lib/GroupsApi.js.map +1 -1
- package/lib/InteractionBase.d.ts +114 -0
- package/lib/InteractionBase.d.ts.map +1 -1
- package/lib/InteractionCatalogApi.d.ts +3 -3
- package/lib/InteractionCatalogApi.d.ts.map +1 -1
- package/lib/InteractionCatalogApi.js +1 -1
- package/lib/InteractionOutput.d.ts +13 -3
- package/lib/InteractionOutput.d.ts.map +1 -1
- package/lib/InteractionOutput.js +33 -3
- package/lib/InteractionOutput.js.map +1 -1
- package/lib/OAuthServerApi.d.ts +1 -1
- package/lib/OAuthServerApi.d.ts.map +1 -1
- package/lib/OAuthServerApi.js +9 -2
- package/lib/OAuthServerApi.js.map +1 -1
- package/lib/ProjectsApi.d.ts +3 -3
- package/lib/ProjectsApi.d.ts.map +1 -1
- package/lib/ProjectsApi.js.map +1 -1
- package/lib/RunsApi.d.ts +6 -28
- package/lib/RunsApi.d.ts.map +1 -1
- package/lib/RunsApi.js +3 -3
- package/lib/RunsApi.js.map +1 -1
- package/lib/ToolsApi.d.ts +2 -1
- package/lib/ToolsApi.d.ts.map +1 -1
- package/lib/ToolsApi.js +9 -0
- package/lib/ToolsApi.js.map +1 -1
- package/lib/ViewsApi.d.ts +1 -1
- package/lib/ViewsApi.js +1 -1
- package/lib/client.d.ts +1 -0
- package/lib/client.d.ts.map +1 -1
- package/lib/client.js +3 -0
- package/lib/client.js.map +1 -1
- package/lib/execute.js +2 -2
- package/lib/execute.js.map +1 -1
- package/lib/store/AgentsApi.d.ts +4 -1
- package/lib/store/AgentsApi.d.ts.map +1 -1
- package/lib/store/AgentsApi.js +6 -4
- package/lib/store/AgentsApi.js.map +1 -1
- package/lib/store/CollectionsApi.d.ts +5 -2
- package/lib/store/CollectionsApi.d.ts.map +1 -1
- package/lib/store/CollectionsApi.js.map +1 -1
- package/lib/store/EmailApi.d.ts +9 -107
- package/lib/store/EmailApi.d.ts.map +1 -1
- package/lib/store/EmailApi.js.map +1 -1
- package/lib/store/FilesApi.d.ts +3 -1
- package/lib/store/FilesApi.d.ts.map +1 -1
- package/lib/store/FilesApi.js +7 -0
- package/lib/store/FilesApi.js.map +1 -1
- package/lib/store/ObjectsApi.d.ts +29 -4
- package/lib/store/ObjectsApi.d.ts.map +1 -1
- package/lib/store/ObjectsApi.js +0 -2
- package/lib/store/ObjectsApi.js.map +1 -1
- package/lib/store/PendingAsksApi.d.ts +2 -53
- package/lib/store/PendingAsksApi.d.ts.map +1 -1
- package/lib/store/PendingAsksApi.js.map +1 -1
- package/lib/store/ProcessApi.d.ts +15 -8
- package/lib/store/ProcessApi.d.ts.map +1 -1
- package/lib/store/ProcessApi.js +27 -1
- package/lib/store/ProcessApi.js.map +1 -1
- package/lib/store/ProcessTestRunApi.d.ts +26 -0
- package/lib/store/ProcessTestRunApi.d.ts.map +1 -0
- package/lib/store/ProcessTestRunApi.js +36 -0
- package/lib/store/ProcessTestRunApi.js.map +1 -0
- package/lib/store/QueryApi.d.ts +9 -51
- package/lib/store/QueryApi.d.ts.map +1 -1
- package/lib/store/QueryApi.js.map +1 -1
- package/lib/store/WorkflowsApi.d.ts +3 -3
- package/lib/store/WorkflowsApi.d.ts.map +1 -1
- package/lib/store/WorkflowsApi.js.map +1 -1
- package/lib/store/client.d.ts +2 -2
- package/lib/store/client.d.ts.map +1 -1
- package/lib/store/client.js +2 -2
- package/lib/store/client.js.map +1 -1
- package/lib/store/index.d.ts +1 -1
- package/lib/store/index.d.ts.map +1 -1
- package/lib/store/index.js +1 -1
- package/lib/store/index.js.map +1 -1
- package/lib/store/stream-termination.d.ts +2 -2
- package/lib/store/stream-termination.d.ts.map +1 -1
- package/lib/store/stream-termination.js +6 -4
- package/lib/store/stream-termination.js.map +1 -1
- package/lib/vertesia-client.js +8 -9
- package/lib/vertesia-client.js.map +1 -1
- package/package.json +7 -7
- package/src/AppsApi.ts +22 -8
- package/src/GroupsApi.ts +4 -10
- package/src/InteractionCatalogApi.ts +3 -3
- package/src/InteractionOutput.test.ts +41 -5
- package/src/InteractionOutput.ts +39 -3
- package/src/OAuthServerApi.test.ts +56 -0
- package/src/OAuthServerApi.ts +12 -2
- package/src/ProjectsApi.ts +4 -2
- package/src/RunsApi.ts +15 -14
- package/src/ToolsApi.ts +10 -0
- package/src/ViewsApi.test.ts +3 -1
- package/src/ViewsApi.ts +1 -1
- package/src/client.ts +4 -0
- package/src/execute.ts +2 -2
- package/src/store/AgentsApi.stream.test.ts +56 -0
- package/src/store/AgentsApi.ts +8 -4
- package/src/store/CollectionsApi.ts +8 -1
- package/src/store/EmailApi.ts +25 -107
- package/src/store/FilesApi.ts +12 -0
- package/src/store/ObjectsApi.ts +28 -4
- package/src/store/PendingAsksApi.ts +15 -57
- package/src/store/ProcessApi.test.ts +24 -0
- package/src/store/ProcessApi.ts +49 -8
- package/src/store/ProcessTestRunApi.ts +41 -0
- package/src/store/QueryApi.ts +9 -45
- package/src/store/WorkflowsApi.ts +4 -3
- package/src/store/client.ts +2 -2
- package/src/store/index.ts +1 -1
- package/src/store/stream-termination.test.ts +24 -0
- package/src/store/stream-termination.ts +10 -4
- package/lib/store/HiveMemoryApi.d.ts +0 -161
- package/lib/store/HiveMemoryApi.d.ts.map +0 -1
- package/lib/store/HiveMemoryApi.js +0 -170
- package/lib/store/HiveMemoryApi.js.map +0 -1
- package/src/store/HiveMemoryApi.ts +0 -220
|
@@ -151,6 +151,62 @@ describe('AgentsApi.streamMessages reconnection', () => {
|
|
|
151
151
|
vi.useRealTimers();
|
|
152
152
|
});
|
|
153
153
|
|
|
154
|
+
it('keeps interactive streams open on root IDLE by default', async () => {
|
|
155
|
+
const harness = createHarness();
|
|
156
|
+
const settled = vi.fn();
|
|
157
|
+
const received: AgentMessage[] = [];
|
|
158
|
+
const done = harness.client.agents
|
|
159
|
+
.streamMessages(AGENT_RUN_ID, (message) => received.push(message))
|
|
160
|
+
.then(settled);
|
|
161
|
+
await settle();
|
|
162
|
+
|
|
163
|
+
FakeEventSource.instances[0].emit({
|
|
164
|
+
t: AgentMessageType.IDLE,
|
|
165
|
+
m: 'Waiting for your command...',
|
|
166
|
+
w: 'main',
|
|
167
|
+
ts: 1_000,
|
|
168
|
+
});
|
|
169
|
+
await settle();
|
|
170
|
+
expect(settled).not.toHaveBeenCalled();
|
|
171
|
+
|
|
172
|
+
FakeEventSource.instances[0].emit({
|
|
173
|
+
t: AgentMessageType.ANSWER,
|
|
174
|
+
m: 'Follow-up response',
|
|
175
|
+
w: 'main',
|
|
176
|
+
ts: 1_500,
|
|
177
|
+
});
|
|
178
|
+
await settle();
|
|
179
|
+
expect(received.map((message) => message.message)).toEqual([
|
|
180
|
+
'Waiting for your command...',
|
|
181
|
+
'Follow-up response',
|
|
182
|
+
]);
|
|
183
|
+
|
|
184
|
+
FakeEventSource.instances[0].emit({
|
|
185
|
+
t: AgentMessageType.COMPLETE,
|
|
186
|
+
m: 'Conversation complete',
|
|
187
|
+
w: 'main',
|
|
188
|
+
ts: 2_000,
|
|
189
|
+
});
|
|
190
|
+
await expect(done).resolves.toBeUndefined();
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
it('lets headless followers opt into closing on root IDLE', async () => {
|
|
194
|
+
const harness = createHarness();
|
|
195
|
+
const done = harness.client.agents.streamMessages(AGENT_RUN_ID, undefined, undefined, undefined, {
|
|
196
|
+
closeOnIdle: true,
|
|
197
|
+
});
|
|
198
|
+
await settle();
|
|
199
|
+
|
|
200
|
+
FakeEventSource.instances[0].emit({
|
|
201
|
+
t: AgentMessageType.IDLE,
|
|
202
|
+
m: 'Waiting for your command...',
|
|
203
|
+
w: 'main',
|
|
204
|
+
ts: 1_000,
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
await expect(done).resolves.toBeNull();
|
|
208
|
+
});
|
|
209
|
+
|
|
154
210
|
it('resolves a fresh auth token for every reconnection attempt', async () => {
|
|
155
211
|
const harness = createHarness();
|
|
156
212
|
const abort = new AbortController();
|
package/src/store/AgentsApi.ts
CHANGED
|
@@ -58,6 +58,8 @@ import { fetchSignedUrl } from './signed-url.js';
|
|
|
58
58
|
import { shouldCloseAgentRunStream, shouldCloseCompactRunStream } from './stream-termination.js';
|
|
59
59
|
|
|
60
60
|
export interface AgentRunStreamMessagesOptions {
|
|
61
|
+
/** Resolve the stream when the root conversation becomes idle. Headless followers should opt in. */
|
|
62
|
+
closeOnIdle?: boolean;
|
|
61
63
|
onHistoryLoaded?: (messages: AgentMessage[]) => void;
|
|
62
64
|
onHistoryError?: (error: unknown) => void;
|
|
63
65
|
}
|
|
@@ -253,7 +255,8 @@ export class AgentsApi extends ApiTopic {
|
|
|
253
255
|
|
|
254
256
|
/**
|
|
255
257
|
* Send a signal to a running agent.
|
|
256
|
-
* Signals
|
|
258
|
+
* Signals include "UserInput", "Stop", "ModelConfigChanged", "FileUploaded", "FileRemoved", and
|
|
259
|
+
* "FileBatchClosed".
|
|
257
260
|
*/
|
|
258
261
|
sendSignal(id: string, signalName: string, payload?: SignalAgentPayload): Promise<SignalAgentResponse> {
|
|
259
262
|
return this.post(`/${id}/signal/${signalName}`, { payload });
|
|
@@ -421,7 +424,7 @@ export class AgentsApi extends ApiTopic {
|
|
|
421
424
|
lastMessageTimestamp = timestamp;
|
|
422
425
|
if (onMessage) onMessage(msg, exit);
|
|
423
426
|
if (isClosed) return;
|
|
424
|
-
if (shouldCloseAgentRunStream(msg, id)) {
|
|
427
|
+
if (shouldCloseAgentRunStream(msg, id, options?.closeOnIdle)) {
|
|
425
428
|
exit(null);
|
|
426
429
|
return;
|
|
427
430
|
}
|
|
@@ -512,7 +515,8 @@ export class AgentsApi extends ApiTopic {
|
|
|
512
515
|
if (onMessage) onMessage(msg, exit);
|
|
513
516
|
if (isClosed) break;
|
|
514
517
|
|
|
515
|
-
shouldCloseAfterHistory =
|
|
518
|
+
shouldCloseAfterHistory =
|
|
519
|
+
index === historical.length - 1 && shouldCloseAgentRunStream(msg, id, options?.closeOnIdle);
|
|
516
520
|
}
|
|
517
521
|
if (shouldCloseAfterHistory) {
|
|
518
522
|
exit(null);
|
|
@@ -598,7 +602,7 @@ export class AgentsApi extends ApiTopic {
|
|
|
598
602
|
onMessage(agentMessage, exit);
|
|
599
603
|
}
|
|
600
604
|
|
|
601
|
-
if (shouldCloseCompactRunStream(compactMessage, id)) {
|
|
605
|
+
if (shouldCloseCompactRunStream(compactMessage, id, options?.closeOnIdle)) {
|
|
602
606
|
exit(null);
|
|
603
607
|
}
|
|
604
608
|
} catch (err) {
|
|
@@ -10,7 +10,9 @@ import type {
|
|
|
10
10
|
ContentObjectStatus,
|
|
11
11
|
CreateCollectionPayload,
|
|
12
12
|
DynamicCollection,
|
|
13
|
+
FullObjectSearchResponse,
|
|
13
14
|
ObjectSearchResponse,
|
|
15
|
+
UpdateCollectionPayload,
|
|
14
16
|
} from '@vertesia/common';
|
|
15
17
|
|
|
16
18
|
export class CollectionsApi extends ApiTopic {
|
|
@@ -53,7 +55,7 @@ export class CollectionsApi extends ApiTopic {
|
|
|
53
55
|
});
|
|
54
56
|
}
|
|
55
57
|
|
|
56
|
-
update(collectionId: string, payload:
|
|
58
|
+
update(collectionId: string, payload: UpdateCollectionPayload): Promise<{ id: string }> {
|
|
57
59
|
return this.put(`/${collectionId}`, {
|
|
58
60
|
payload,
|
|
59
61
|
});
|
|
@@ -90,6 +92,11 @@ export class CollectionsApi extends ApiTopic {
|
|
|
90
92
|
});
|
|
91
93
|
}
|
|
92
94
|
|
|
95
|
+
searchMembers(
|
|
96
|
+
collectionId: string,
|
|
97
|
+
payload: ComplexSearchPayload & { select?: undefined },
|
|
98
|
+
): Promise<FullObjectSearchResponse>;
|
|
99
|
+
searchMembers(collectionId: string, payload: ComplexSearchPayload): Promise<ObjectSearchResponse>;
|
|
93
100
|
searchMembers(collectionId: string, payload: ComplexSearchPayload): Promise<ObjectSearchResponse> {
|
|
94
101
|
return this.post(`/${collectionId}/search`, { payload });
|
|
95
102
|
}
|
package/src/store/EmailApi.ts
CHANGED
|
@@ -1,109 +1,27 @@
|
|
|
1
1
|
import { ApiTopic, type ClientBase } from '@vertesia/api-fetch-client';
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
CreateEmailRouteRequest,
|
|
4
|
+
CreateEmailRouteResponse,
|
|
5
|
+
EmailRouteData,
|
|
6
|
+
EmailRouteResponse,
|
|
7
|
+
ForwardEmailRequest,
|
|
8
|
+
ForwardEmailResponse,
|
|
9
|
+
SendEmailRequest,
|
|
10
|
+
SendEmailResponse,
|
|
11
|
+
UpdateEmailRouteRequest,
|
|
12
|
+
UpdateEmailRouteResponse,
|
|
13
|
+
} from '@vertesia/common';
|
|
3
14
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
/** Email body in markdown format */
|
|
15
|
-
body: string;
|
|
16
|
-
/** Agent/interaction endpoint name (used in from address) */
|
|
17
|
-
agent_name: string;
|
|
18
|
-
/** Display name for the sender (overrides project default) */
|
|
19
|
-
from_name?: string;
|
|
20
|
-
/** Workflow run ID for routing replies */
|
|
21
|
-
run_id: string;
|
|
22
|
-
/** Existing route key (for subsequent emails in same conversation) */
|
|
23
|
-
route_key?: string;
|
|
24
|
-
/** Message ID for In-Reply-To header (email threading) */
|
|
25
|
-
in_reply_to?: string;
|
|
26
|
-
/** Chain of message IDs for References header */
|
|
27
|
-
references?: string[];
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Response from sending an email.
|
|
32
|
-
*/
|
|
33
|
-
export interface SendEmailResponse {
|
|
34
|
-
success: boolean;
|
|
35
|
-
/** Resend email ID */
|
|
36
|
-
email_id?: string;
|
|
37
|
-
/** Message-ID header for threading */
|
|
38
|
-
message_id?: string;
|
|
39
|
-
/** Short route key for reply routing */
|
|
40
|
-
route_key?: string;
|
|
41
|
-
/** Error message if failed */
|
|
42
|
-
error?: string;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Response from creating an email route.
|
|
47
|
-
*/
|
|
48
|
-
export interface CreateRouteResponse {
|
|
49
|
-
/** The generated route key (8-char alphanumeric) */
|
|
50
|
-
route_key: string;
|
|
51
|
-
/** Full reply-to address: r+{route_key}@{email_domain} */
|
|
52
|
-
reply_to: string;
|
|
53
|
-
/** The email domain for sending and receiving */
|
|
54
|
-
email_domain: string;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Request to forward an email to a workflow.
|
|
59
|
-
* Used by external services that handle email reception themselves.
|
|
60
|
-
*/
|
|
61
|
-
export interface ForwardEmailRequest {
|
|
62
|
-
/** Email content received by the external service */
|
|
63
|
-
email: {
|
|
64
|
-
/** Sender email address */
|
|
65
|
-
from: string;
|
|
66
|
-
/** Email subject */
|
|
67
|
-
subject?: string;
|
|
68
|
-
/** Plain text body */
|
|
69
|
-
text: string;
|
|
70
|
-
/** HTML body (optional) */
|
|
71
|
-
html?: string;
|
|
72
|
-
/** Message-ID header for threading */
|
|
73
|
-
message_id?: string;
|
|
74
|
-
};
|
|
75
|
-
/** Custom context data from the external service (e.g., auth tokens, user IDs) */
|
|
76
|
-
context?: Record<string, unknown>;
|
|
77
|
-
/** Attachments with download URLs */
|
|
78
|
-
attachments?: Array<{
|
|
79
|
-
filename: string;
|
|
80
|
-
content_type: string;
|
|
81
|
-
size: number;
|
|
82
|
-
download_url: string;
|
|
83
|
-
}>;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Response from forwarding an email.
|
|
88
|
-
*/
|
|
89
|
-
export interface ForwardEmailResponse {
|
|
90
|
-
success: boolean;
|
|
91
|
-
run_id: string;
|
|
92
|
-
workflow_id: string;
|
|
93
|
-
route_key: string;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
* Request to create an email route.
|
|
98
|
-
*/
|
|
99
|
-
export interface CreateRouteRequest {
|
|
100
|
-
/** Workflow run ID for routing replies */
|
|
101
|
-
run_id: string;
|
|
102
|
-
/** Email address of the user (for context) */
|
|
103
|
-
user_email: string;
|
|
104
|
-
/** Subject of the email thread (optional) */
|
|
105
|
-
thread_subject?: string;
|
|
106
|
-
}
|
|
15
|
+
export type {
|
|
16
|
+
ForwardEmailRequest,
|
|
17
|
+
ForwardEmailResponse,
|
|
18
|
+
SendEmailRequest,
|
|
19
|
+
SendEmailResponse,
|
|
20
|
+
} from '@vertesia/common';
|
|
21
|
+
/** @deprecated Use CreateEmailRouteRequest from @vertesia/common. */
|
|
22
|
+
export type CreateRouteRequest = CreateEmailRouteRequest;
|
|
23
|
+
/** @deprecated Use CreateEmailRouteResponse from @vertesia/common. */
|
|
24
|
+
export type CreateRouteResponse = CreateEmailRouteResponse;
|
|
107
25
|
|
|
108
26
|
/**
|
|
109
27
|
* Email API for sending emails from workflows.
|
|
@@ -150,21 +68,21 @@ export class EmailApi extends ApiTopic {
|
|
|
150
68
|
* // Replies will be routed back to the workflow
|
|
151
69
|
* ```
|
|
152
70
|
*/
|
|
153
|
-
createRoute(request:
|
|
71
|
+
createRoute(request: CreateEmailRouteRequest): Promise<CreateEmailRouteResponse> {
|
|
154
72
|
return this.post('/routes', { payload: request });
|
|
155
73
|
}
|
|
156
74
|
|
|
157
75
|
/**
|
|
158
76
|
* Get an email route by key.
|
|
159
77
|
*/
|
|
160
|
-
getRoute(routeKey: string): Promise<
|
|
78
|
+
getRoute(routeKey: string): Promise<EmailRouteResponse> {
|
|
161
79
|
return this.get(`/routes/${routeKey}`);
|
|
162
80
|
}
|
|
163
81
|
|
|
164
82
|
/**
|
|
165
83
|
* Update an email route (e.g., to update threading info).
|
|
166
84
|
*/
|
|
167
|
-
updateRoute(routeKey: string, updates:
|
|
85
|
+
updateRoute(routeKey: string, updates: UpdateEmailRouteRequest): Promise<UpdateEmailRouteResponse> {
|
|
168
86
|
return this.put(`/routes/${routeKey}`, { payload: updates });
|
|
169
87
|
}
|
|
170
88
|
|
package/src/store/FilesApi.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { ApiTopic, type ClientBase, type IRequestRetryPolicy } from '@vertesia/api-fetch-client';
|
|
2
2
|
import type {
|
|
3
|
+
BucketCreateAccessStatusResponse,
|
|
3
4
|
BucketReadAccessStatusResponse,
|
|
4
5
|
BulkUploadUrlsPayload,
|
|
5
6
|
BulkUploadUrlsResponse,
|
|
6
7
|
DeleteFileResult,
|
|
8
|
+
EnsureBucketCreateAccessPayload,
|
|
9
|
+
EnsureBucketCreateAccessResponse,
|
|
7
10
|
EnsureBucketReadAccessPayload,
|
|
8
11
|
EnsureBucketReadAccessResponse,
|
|
9
12
|
FileBucketResponse,
|
|
@@ -133,6 +136,15 @@ export class FilesApi extends ApiTopic {
|
|
|
133
136
|
return this.get('/bucket/read-access', { query: { principal } });
|
|
134
137
|
}
|
|
135
138
|
|
|
139
|
+
ensureBucketCreateAccess(principal: string): Promise<EnsureBucketCreateAccessResponse> {
|
|
140
|
+
const payload: EnsureBucketCreateAccessPayload = { principal };
|
|
141
|
+
return this.post('/bucket/create-access', { payload });
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
getBucketCreateAccessStatus(principal: string): Promise<BucketCreateAccessStatusResponse> {
|
|
145
|
+
return this.get('/bucket/create-access', { query: { principal } });
|
|
146
|
+
}
|
|
147
|
+
|
|
136
148
|
list(prefix: string): Promise<FileListResponse> {
|
|
137
149
|
return this.get('/list', { query: { prefix } });
|
|
138
150
|
}
|
package/src/store/ObjectsApi.ts
CHANGED
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
type ExportPropertiesPayload,
|
|
27
27
|
type ExportPropertiesResponse,
|
|
28
28
|
type FindPayload,
|
|
29
|
+
type FullObjectSearchResponse,
|
|
29
30
|
type GetFileUrlPayload,
|
|
30
31
|
type GetFileUrlResponse,
|
|
31
32
|
type GetRenditionParams,
|
|
@@ -36,10 +37,12 @@ import {
|
|
|
36
37
|
type ObjectSearchPayload,
|
|
37
38
|
type ObjectSearchQuery,
|
|
38
39
|
type ObjectSearchResponse,
|
|
40
|
+
type ProjectedContentObjectApiResponse,
|
|
39
41
|
type SetObjectEmbeddingsResponse,
|
|
40
42
|
type StartContentObjectExportRequest,
|
|
41
43
|
type StartContentObjectExportResponse,
|
|
42
44
|
type SupportedEmbeddingTypes,
|
|
45
|
+
type UpdateContentObjectPayload,
|
|
43
46
|
type ZenoBulkContentObjectExportComposeRequest,
|
|
44
47
|
type ZenoBulkContentObjectExportPlanRequest,
|
|
45
48
|
type ZenoBulkContentObjectExportPlanResponse,
|
|
@@ -60,10 +63,22 @@ import type { ZenoClient } from './client.js';
|
|
|
60
63
|
import { fetchSignedUrl } from './signed-url.js';
|
|
61
64
|
import { getUploadMimeTypeHint, resolveUploadMimeType } from './uploadMimeType.js';
|
|
62
65
|
|
|
66
|
+
/**
|
|
67
|
+
* The two write payloads, each widened at `content` so callers can hand us a browser `File` or a
|
|
68
|
+
* `StreamSource` and let the method upload it before sending the wire shape.
|
|
69
|
+
*
|
|
70
|
+
* They are separate on purpose: `POST /objects` and `PUT /objects/:id` publish distinct components,
|
|
71
|
+
* so deriving the update signature from the create payload would silently drift the day the two
|
|
72
|
+
* schemas diverge.
|
|
73
|
+
*/
|
|
63
74
|
type ContentObjectWritePayload = Omit<CreateContentObjectPayload, 'content'> & {
|
|
64
75
|
content?: ContentSource | File | StreamSource;
|
|
65
76
|
};
|
|
66
77
|
|
|
78
|
+
type ContentObjectUpdateWritePayload = Omit<UpdateContentObjectPayload, 'content'> & {
|
|
79
|
+
content?: ContentSource | File | StreamSource;
|
|
80
|
+
};
|
|
81
|
+
|
|
67
82
|
export class ObjectsApi extends ApiTopic {
|
|
68
83
|
declare client: ZenoClient;
|
|
69
84
|
|
|
@@ -224,7 +239,11 @@ export class ObjectsApi extends ApiTopic {
|
|
|
224
239
|
}
|
|
225
240
|
|
|
226
241
|
/** Find object based on query */
|
|
227
|
-
find(payload: FindPayload): Promise<ContentObject[]
|
|
242
|
+
find(payload: FindPayload & { select?: undefined }): Promise<ContentObject[]>;
|
|
243
|
+
find(payload: FindPayload & { select: `+${string}` }): Promise<ContentObject[]>;
|
|
244
|
+
find(payload: FindPayload & { select: string }): Promise<ProjectedContentObjectApiResponse[]>;
|
|
245
|
+
find(payload: FindPayload): Promise<ContentObject[] | ProjectedContentObjectApiResponse[]>;
|
|
246
|
+
find(payload: FindPayload): Promise<ContentObject[] | ProjectedContentObjectApiResponse[]> {
|
|
228
247
|
return this.post('/find', {
|
|
229
248
|
payload,
|
|
230
249
|
});
|
|
@@ -238,13 +257,18 @@ export class ObjectsApi extends ApiTopic {
|
|
|
238
257
|
}
|
|
239
258
|
|
|
240
259
|
/** Search object — different from find because allow full text search */
|
|
260
|
+
search(payload: ComplexSearchPayload & { select?: undefined }): Promise<FullObjectSearchResponse>;
|
|
261
|
+
search(payload: ComplexSearchPayload): Promise<ObjectSearchResponse>;
|
|
241
262
|
search(payload: ComplexSearchPayload): Promise<ObjectSearchResponse> {
|
|
242
263
|
return this.post('/search', {
|
|
243
264
|
payload,
|
|
244
265
|
});
|
|
245
266
|
}
|
|
246
267
|
|
|
247
|
-
retrieve(id: string
|
|
268
|
+
retrieve(id: string): Promise<ContentObject>;
|
|
269
|
+
retrieve(id: string, select: `+${string}` | undefined): Promise<ContentObject>;
|
|
270
|
+
retrieve(id: string, select: string): Promise<ProjectedContentObjectApiResponse>;
|
|
271
|
+
retrieve(id: string, select?: string): Promise<ContentObject | ProjectedContentObjectApiResponse> {
|
|
248
272
|
return this.get(`/${id}`, {
|
|
249
273
|
query: {
|
|
250
274
|
select,
|
|
@@ -381,7 +405,7 @@ export class ObjectsApi extends ApiTopic {
|
|
|
381
405
|
*/
|
|
382
406
|
async update(
|
|
383
407
|
id: string,
|
|
384
|
-
payload:
|
|
408
|
+
payload: ContentObjectUpdateWritePayload,
|
|
385
409
|
options?: {
|
|
386
410
|
createRevision?: boolean;
|
|
387
411
|
revisionLabel?: string;
|
|
@@ -393,7 +417,7 @@ export class ObjectsApi extends ApiTopic {
|
|
|
393
417
|
},
|
|
394
418
|
): Promise<ContentObject> {
|
|
395
419
|
const { content, ...payloadWithoutContent } = payload;
|
|
396
|
-
const updatePayload:
|
|
420
|
+
const updatePayload: UpdateContentObjectPayload = {
|
|
397
421
|
...payloadWithoutContent,
|
|
398
422
|
};
|
|
399
423
|
|
|
@@ -1,61 +1,19 @@
|
|
|
1
1
|
import { ApiTopic, type ClientBase } from '@vertesia/api-fetch-client';
|
|
2
|
-
import type {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
timeoutHours?: number;
|
|
18
|
-
/** User communication channels */
|
|
19
|
-
userChannels: UserChannel[];
|
|
20
|
-
/** Durable task fields shown in task inbox */
|
|
21
|
-
taskFields?: TaskField[];
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Response from registering a pending ask.
|
|
26
|
-
*/
|
|
27
|
-
export interface RegisterPendingAskResponse {
|
|
28
|
-
/** Whether registration succeeded */
|
|
29
|
-
success: boolean;
|
|
30
|
-
/** Generated ask ID */
|
|
31
|
-
askId?: string;
|
|
32
|
-
/** Whether webhook was sent */
|
|
33
|
-
webhookSent?: boolean;
|
|
34
|
-
/** Error message if failed */
|
|
35
|
-
error?: string;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Request to resolve a pending ask.
|
|
40
|
-
*/
|
|
41
|
-
export interface ResolvePendingAskRequest {
|
|
42
|
-
/** User's response */
|
|
43
|
-
response: string;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Response from resolving a pending ask.
|
|
48
|
-
*/
|
|
49
|
-
export interface ResolvePendingAskResponse {
|
|
50
|
-
/** Whether resolution succeeded */
|
|
51
|
-
success: boolean;
|
|
52
|
-
/** Whether webhook was sent */
|
|
53
|
-
webhookSent?: boolean;
|
|
54
|
-
/** How long the user took to respond (ms) */
|
|
55
|
-
waitDurationMs?: number;
|
|
56
|
-
/** Error message if failed */
|
|
57
|
-
error?: string;
|
|
58
|
-
}
|
|
2
|
+
import type {
|
|
3
|
+
ListPendingAsksResponse,
|
|
4
|
+
PendingAskData,
|
|
5
|
+
RegisterPendingAskRequest,
|
|
6
|
+
RegisterPendingAskResponse,
|
|
7
|
+
ResolvePendingAskRequest,
|
|
8
|
+
ResolvePendingAskResponse,
|
|
9
|
+
} from '@vertesia/common';
|
|
10
|
+
|
|
11
|
+
export type {
|
|
12
|
+
RegisterPendingAskRequest,
|
|
13
|
+
RegisterPendingAskResponse,
|
|
14
|
+
ResolvePendingAskRequest,
|
|
15
|
+
ResolvePendingAskResponse,
|
|
16
|
+
} from '@vertesia/common';
|
|
59
17
|
|
|
60
18
|
/**
|
|
61
19
|
* Pending Asks API for tracking ask_user requests.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { ZenoClient } from './client.js';
|
|
3
|
+
|
|
4
|
+
function createClient(requests: Request[]) {
|
|
5
|
+
return new ZenoClient({
|
|
6
|
+
serverUrl: 'https://zeno.example.com',
|
|
7
|
+
fetch: vi.fn(async () => Response.json([])),
|
|
8
|
+
onRequest: (request) => requests.push(request),
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
describe('ProcessApi.list', () => {
|
|
13
|
+
it.each([
|
|
14
|
+
['canonical', { all_versions: true }],
|
|
15
|
+
['deprecated', { allVersions: true }],
|
|
16
|
+
])('maps the %s all-versions option to the wire query', async (_name, query) => {
|
|
17
|
+
const requests: Request[] = [];
|
|
18
|
+
const client = createClient(requests);
|
|
19
|
+
|
|
20
|
+
await client.processes.list(query);
|
|
21
|
+
|
|
22
|
+
expect(requests[0]?.url).toBe('https://zeno.example.com/api/v1/processes?all_versions=true');
|
|
23
|
+
});
|
|
24
|
+
});
|
package/src/store/ProcessApi.ts
CHANGED
|
@@ -1,20 +1,23 @@
|
|
|
1
1
|
import { ApiTopic, type ClientBase } from '@vertesia/api-fetch-client';
|
|
2
2
|
import type {
|
|
3
3
|
CreateProcessDefinitionPayload,
|
|
4
|
+
CreateProcessTestSuitePayload,
|
|
5
|
+
ListProcessDefinitionsQuery as ListProcessDefinitionsWireQuery,
|
|
6
|
+
ListProcessTestRunsQuery,
|
|
4
7
|
ProcessDefinition,
|
|
8
|
+
ProcessTestRun,
|
|
9
|
+
ProcessTestSuite,
|
|
5
10
|
PublishProcessDefinitionPayload,
|
|
6
11
|
RevertProcessDefinitionPayload,
|
|
12
|
+
StartProcessTestRunPayload,
|
|
7
13
|
UpdateProcessDefinitionPayload,
|
|
14
|
+
UpdateProcessTestSuitePayload,
|
|
8
15
|
} from '@vertesia/common';
|
|
9
16
|
|
|
10
|
-
export
|
|
11
|
-
|
|
12
|
-
process?: string;
|
|
13
|
-
limit?: number;
|
|
14
|
-
offset?: number;
|
|
15
|
-
/** Include every revision/version instead of only the latest head revision. */
|
|
17
|
+
export type ListProcessDefinitionsQuery = ListProcessDefinitionsWireQuery & {
|
|
18
|
+
/** @deprecated Use the wire-compatible `all_versions` property. */
|
|
16
19
|
allVersions?: boolean;
|
|
17
|
-
}
|
|
20
|
+
};
|
|
18
21
|
|
|
19
22
|
export class ProcessApi extends ApiTopic {
|
|
20
23
|
constructor(parent: ClientBase) {
|
|
@@ -27,7 +30,7 @@ export class ProcessApi extends ApiTopic {
|
|
|
27
30
|
if (query?.process) params.process = query.process;
|
|
28
31
|
if (query?.limit != null) params.limit = String(query.limit);
|
|
29
32
|
if (query?.offset != null) params.offset = String(query.offset);
|
|
30
|
-
if (query?.allVersions) params.all_versions = 'true';
|
|
33
|
+
if (query?.all_versions || query?.allVersions) params.all_versions = 'true';
|
|
31
34
|
return this.get('/', { query: params });
|
|
32
35
|
}
|
|
33
36
|
|
|
@@ -58,4 +61,42 @@ export class ProcessApi extends ApiTopic {
|
|
|
58
61
|
delete(id: string): Promise<{ id: string; count: number }> {
|
|
59
62
|
return this.del(`/${id}`);
|
|
60
63
|
}
|
|
64
|
+
|
|
65
|
+
listTestSuites(processId: string): Promise<ProcessTestSuite[]> {
|
|
66
|
+
return this.get(`/${processId}/test-suites`);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
createTestSuite(processId: string, payload: CreateProcessTestSuitePayload): Promise<ProcessTestSuite> {
|
|
70
|
+
return this.post(`/${processId}/test-suites`, { payload });
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
updateTestSuite(
|
|
74
|
+
processId: string,
|
|
75
|
+
suiteId: string,
|
|
76
|
+
payload: UpdateProcessTestSuitePayload,
|
|
77
|
+
): Promise<ProcessTestSuite> {
|
|
78
|
+
return this.put(`/${processId}/test-suites/${suiteId}`, { payload });
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
deleteTestSuite(processId: string, suiteId: string): Promise<{ id: string; count: number }> {
|
|
82
|
+
return this.del(`/${processId}/test-suites/${suiteId}`);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
startTestRun(processId: string, payload: StartProcessTestRunPayload): Promise<ProcessTestRun> {
|
|
86
|
+
return this.post(`/${processId}/test-runs`, { payload });
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
listTestRuns(processId: string, query?: ListProcessTestRunsQuery): Promise<ProcessTestRun[]> {
|
|
90
|
+
return this.get(`/${processId}/test-runs`, {
|
|
91
|
+
query: query?.limit == null ? undefined : { limit: String(query.limit) },
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
retrieveTestRun(processId: string, runId: string): Promise<ProcessTestRun> {
|
|
96
|
+
return this.get(`/${processId}/test-runs/${runId}`);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
cancelTestRun(processId: string, runId: string): Promise<ProcessTestRun> {
|
|
100
|
+
return this.post(`/${processId}/test-runs/${runId}/cancel`, {});
|
|
101
|
+
}
|
|
61
102
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { ApiTopic, type ClientBase } from '@vertesia/api-fetch-client';
|
|
2
|
+
import type { ProcessTestRun, SubmitProcessTestRunPayload } from '@vertesia/common';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Run-scoped process test operations.
|
|
6
|
+
*
|
|
7
|
+
* Test runs are addressed by their own id here, so these methods work for every run whatever it
|
|
8
|
+
* was started against — a stored process test suite, an in-code `app:`/`sys:` process, or an
|
|
9
|
+
* ephemeral definition submitted inline.
|
|
10
|
+
*/
|
|
11
|
+
export class ProcessTestRunApi extends ApiTopic {
|
|
12
|
+
constructor(parent: ClientBase) {
|
|
13
|
+
super(parent, '/api/v1/process-test-runs');
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Start a test run against an in-code process or an inline definition, with the scenarios
|
|
18
|
+
* supplied in the request instead of a stored suite. Use
|
|
19
|
+
* `client.store.processes.startTestRun()` for stored process definitions and their suites.
|
|
20
|
+
*/
|
|
21
|
+
submit(payload: SubmitProcessTestRunPayload): Promise<ProcessTestRun> {
|
|
22
|
+
// Starting a run is not idempotent and the contract carries no request key, so a replay
|
|
23
|
+
// would create a second run. Opt out of any client-level retry policy explicitly rather
|
|
24
|
+
// than relying on POST being absent from its method list. Rate-limiter pacing retries are
|
|
25
|
+
// unaffected: those happen before the request reaches the handler.
|
|
26
|
+
return this.post('/', { payload, retryPolicy: false });
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
retrieve(runId: string): Promise<ProcessTestRun> {
|
|
30
|
+
return this.get(`/${runId}`);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
cancel(runId: string): Promise<ProcessTestRun> {
|
|
34
|
+
return this.post(`/${runId}/cancel`, {});
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Deletes a run and its snapshot, cancelling it first when it is still active. */
|
|
38
|
+
delete(runId: string): Promise<{ id: string; count: number }> {
|
|
39
|
+
return this.del(`/${runId}`);
|
|
40
|
+
}
|
|
41
|
+
}
|