veryfront 0.1.232 → 0.1.234
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/esm/deno.d.ts +2 -0
- package/esm/deno.js +3 -1
- package/esm/src/agent/conversation-bootstrap.d.ts +61 -0
- package/esm/src/agent/conversation-bootstrap.d.ts.map +1 -0
- package/esm/src/agent/conversation-bootstrap.js +131 -0
- package/esm/src/agent/durable.d.ts +84 -0
- package/esm/src/agent/durable.d.ts.map +1 -1
- package/esm/src/agent/durable.js +193 -12
- package/esm/src/agent/index.d.ts +3 -1
- package/esm/src/agent/index.d.ts.map +1 -1
- package/esm/src/agent/index.js +3 -1
- package/esm/src/agent/invoke-agent-child-runs.d.ts +145 -0
- package/esm/src/agent/invoke-agent-child-runs.d.ts.map +1 -0
- package/esm/src/agent/invoke-agent-child-runs.js +101 -0
- package/esm/src/utils/version-constant.d.ts +1 -1
- package/esm/src/utils/version-constant.js +1 -1
- package/package.json +9 -1
- package/src/deno.js +3 -1
- package/src/src/agent/conversation-bootstrap.ts +195 -0
- package/src/src/agent/durable.ts +257 -12
- package/src/src/agent/index.ts +35 -0
- package/src/src/agent/invoke-agent-child-runs.ts +170 -0
- package/src/src/utils/version-constant.ts +1 -1
package/src/src/agent/durable.ts
CHANGED
|
@@ -4,6 +4,34 @@ import { z } from "zod";
|
|
|
4
4
|
|
|
5
5
|
const AGENT_RUN_API_TIMEOUT_MS = 15_000;
|
|
6
6
|
|
|
7
|
+
function createTimedAbortSignal(timeoutMs: number, abortSignal?: AbortSignal) {
|
|
8
|
+
const controller = new AbortController();
|
|
9
|
+
let abortedByCaller = false;
|
|
10
|
+
const timeout = dntShim.setTimeout(() => {
|
|
11
|
+
controller.abort();
|
|
12
|
+
}, timeoutMs);
|
|
13
|
+
|
|
14
|
+
const onAbort = () => {
|
|
15
|
+
abortedByCaller = true;
|
|
16
|
+
controller.abort();
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
if (abortSignal?.aborted) {
|
|
20
|
+
onAbort();
|
|
21
|
+
} else {
|
|
22
|
+
abortSignal?.addEventListener("abort", onAbort, { once: true });
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return {
|
|
26
|
+
signal: controller.signal,
|
|
27
|
+
wasAbortedByCaller: () => abortedByCaller,
|
|
28
|
+
cleanup: () => {
|
|
29
|
+
clearTimeout(timeout);
|
|
30
|
+
abortSignal?.removeEventListener("abort", onAbort);
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
7
35
|
export const ConversationRunTargetsSchema = z.object({
|
|
8
36
|
sourceTargetKind: z.enum(["project", "preview_branch"]).nullable(),
|
|
9
37
|
runtimeTargetKind: z.enum(["production", "preview_branch"]).nullable(),
|
|
@@ -37,6 +65,15 @@ export function resolveConversationRunTargets(input: {
|
|
|
37
65
|
);
|
|
38
66
|
}
|
|
39
67
|
|
|
68
|
+
export const ConversationRunStatusSchema = z.enum([
|
|
69
|
+
"pending",
|
|
70
|
+
"running",
|
|
71
|
+
"waiting_for_tool",
|
|
72
|
+
"completed",
|
|
73
|
+
"failed",
|
|
74
|
+
"cancelled",
|
|
75
|
+
]);
|
|
76
|
+
|
|
40
77
|
export const ConversationRunProjectionSchema = z
|
|
41
78
|
.object({
|
|
42
79
|
runId: z.string().min(1).optional(),
|
|
@@ -49,7 +86,7 @@ export const ConversationRunProjectionSchema = z
|
|
|
49
86
|
latest_event_id: z.number().int().nonnegative().optional(),
|
|
50
87
|
latestExternalEventSequence: z.number().int().nonnegative().optional(),
|
|
51
88
|
latest_external_event_sequence: z.number().int().nonnegative().optional(),
|
|
52
|
-
status:
|
|
89
|
+
status: ConversationRunStatusSchema,
|
|
53
90
|
})
|
|
54
91
|
.passthrough()
|
|
55
92
|
.transform((data) => {
|
|
@@ -112,6 +149,59 @@ export const CompleteConversationRunResponseSchema = z
|
|
|
112
149
|
})
|
|
113
150
|
.passthrough();
|
|
114
151
|
|
|
152
|
+
const AppendConversationRunEventsCamelRunSchema = z
|
|
153
|
+
.object({
|
|
154
|
+
runId: z.string().min(1),
|
|
155
|
+
conversationId: z.string().uuid(),
|
|
156
|
+
latestEventId: z.number().int().nonnegative(),
|
|
157
|
+
latestExternalEventSequence: z.number().int().nonnegative(),
|
|
158
|
+
})
|
|
159
|
+
.passthrough();
|
|
160
|
+
|
|
161
|
+
const AppendConversationRunEventsSnakeRunSchema = z
|
|
162
|
+
.object({
|
|
163
|
+
run_id: z.string().min(1),
|
|
164
|
+
conversation_id: z.string().uuid(),
|
|
165
|
+
latest_event_id: z.number().int().nonnegative(),
|
|
166
|
+
latest_external_event_sequence: z.number().int().nonnegative(),
|
|
167
|
+
})
|
|
168
|
+
.passthrough();
|
|
169
|
+
|
|
170
|
+
export const AppendConversationRunEventsResponseSchema = z.union([
|
|
171
|
+
z.object({
|
|
172
|
+
latestEventId: z.number().int().nonnegative(),
|
|
173
|
+
latestExternalEventSequence: z.number().int().nonnegative(),
|
|
174
|
+
appendedCount: z.number().int().nonnegative(),
|
|
175
|
+
run: AppendConversationRunEventsCamelRunSchema,
|
|
176
|
+
}),
|
|
177
|
+
z.object({
|
|
178
|
+
latest_event_id: z.number().int().nonnegative(),
|
|
179
|
+
latest_external_event_sequence: z.number().int().nonnegative(),
|
|
180
|
+
appended_count: z.number().int().nonnegative(),
|
|
181
|
+
run: AppendConversationRunEventsSnakeRunSchema,
|
|
182
|
+
}).transform((data) => ({
|
|
183
|
+
latestEventId: data.latest_event_id,
|
|
184
|
+
latestExternalEventSequence: data.latest_external_event_sequence,
|
|
185
|
+
appendedCount: data.appended_count,
|
|
186
|
+
run: {
|
|
187
|
+
...data.run,
|
|
188
|
+
runId: data.run.run_id,
|
|
189
|
+
conversationId: data.run.conversation_id,
|
|
190
|
+
latestEventId: data.run.latest_event_id,
|
|
191
|
+
latestExternalEventSequence: data.run.latest_external_event_sequence,
|
|
192
|
+
},
|
|
193
|
+
})),
|
|
194
|
+
]);
|
|
195
|
+
|
|
196
|
+
export type AppendConversationRunEventsResponse = z.infer<
|
|
197
|
+
typeof AppendConversationRunEventsResponseSchema
|
|
198
|
+
>;
|
|
199
|
+
|
|
200
|
+
const ConversationRunErrorSchema = z.object({
|
|
201
|
+
detail: z.string().min(1).optional(),
|
|
202
|
+
error: z.string().min(1).optional(),
|
|
203
|
+
});
|
|
204
|
+
|
|
115
205
|
export interface ConversationAgentRunUsage {
|
|
116
206
|
inputTokens: number;
|
|
117
207
|
outputTokens: number;
|
|
@@ -141,6 +231,71 @@ export interface FinalizeConversationAgentRunInput {
|
|
|
141
231
|
terminalErrorMessage?: string | null;
|
|
142
232
|
}
|
|
143
233
|
|
|
234
|
+
export class AppendConversationRunEventsError extends Error {
|
|
235
|
+
readonly status: number;
|
|
236
|
+
readonly detail: string | null;
|
|
237
|
+
|
|
238
|
+
constructor(input: {
|
|
239
|
+
status: number;
|
|
240
|
+
detail?: string | null;
|
|
241
|
+
statusText?: string;
|
|
242
|
+
}) {
|
|
243
|
+
const detail = input.detail?.trim() || input.statusText || `HTTP ${input.status}`;
|
|
244
|
+
super(`Append conversation run events failed (${input.status}): ${detail}`);
|
|
245
|
+
this.name = "AppendConversationRunEventsError";
|
|
246
|
+
this.status = input.status;
|
|
247
|
+
this.detail = input.detail?.trim() || null;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export function parseAppendConversationRunEventsErrorBody(bodyText: string): string | null {
|
|
252
|
+
if (!bodyText) {
|
|
253
|
+
return null;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
try {
|
|
257
|
+
const parsed = ConversationRunErrorSchema.safeParse(JSON.parse(bodyText));
|
|
258
|
+
if (parsed.success) {
|
|
259
|
+
return parsed.data.detail ?? parsed.data.error ?? null;
|
|
260
|
+
}
|
|
261
|
+
} catch {
|
|
262
|
+
return bodyText;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
return bodyText;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
export function isIgnorableConversationRunAppendError(
|
|
269
|
+
error: unknown,
|
|
270
|
+
): error is AppendConversationRunEventsError {
|
|
271
|
+
if (!(error instanceof AppendConversationRunEventsError)) {
|
|
272
|
+
return false;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
if (error.status === 404) {
|
|
276
|
+
return true;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
if (error.status !== 400) {
|
|
280
|
+
return false;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
return (
|
|
284
|
+
error.detail === "Cannot append external events to a terminal run" ||
|
|
285
|
+
error.detail === "Cannot append external events while the run is waiting for a tool result"
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
export function isCursorMismatchConversationRunAppendError(
|
|
290
|
+
error: unknown,
|
|
291
|
+
): error is AppendConversationRunEventsError {
|
|
292
|
+
return (
|
|
293
|
+
error instanceof AppendConversationRunEventsError &&
|
|
294
|
+
error.status === 400 &&
|
|
295
|
+
error.detail === "External run event cursor mismatch"
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
|
|
144
299
|
async function controlPlaneJson<T>(input: {
|
|
145
300
|
authToken: string;
|
|
146
301
|
url: string;
|
|
@@ -148,11 +303,13 @@ async function controlPlaneJson<T>(input: {
|
|
|
148
303
|
body?: unknown;
|
|
149
304
|
responseSchema: z.ZodSchema<T>;
|
|
150
305
|
operation: string;
|
|
306
|
+
abortSignal?: AbortSignal;
|
|
151
307
|
}): Promise<T> {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
308
|
+
if (input.abortSignal?.aborted) {
|
|
309
|
+
throw new DOMException("This operation was aborted", "AbortError");
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
const timedAbort = createTimedAbortSignal(AGENT_RUN_API_TIMEOUT_MS, input.abortSignal);
|
|
156
313
|
|
|
157
314
|
let response: Response;
|
|
158
315
|
try {
|
|
@@ -163,15 +320,19 @@ async function controlPlaneJson<T>(input: {
|
|
|
163
320
|
"Content-Type": "application/json",
|
|
164
321
|
},
|
|
165
322
|
...(input.body !== undefined ? { body: JSON.stringify(input.body) } : {}),
|
|
166
|
-
signal:
|
|
323
|
+
signal: timedAbort.signal,
|
|
167
324
|
});
|
|
168
325
|
} catch (error) {
|
|
169
|
-
if (
|
|
326
|
+
if (
|
|
327
|
+
error instanceof DOMException &&
|
|
328
|
+
error.name === "AbortError" &&
|
|
329
|
+
!timedAbort.wasAbortedByCaller()
|
|
330
|
+
) {
|
|
170
331
|
throw new Error(`${input.operation} timed out after ${AGENT_RUN_API_TIMEOUT_MS}ms`);
|
|
171
332
|
}
|
|
172
333
|
throw error;
|
|
173
334
|
} finally {
|
|
174
|
-
|
|
335
|
+
timedAbort.cleanup();
|
|
175
336
|
}
|
|
176
337
|
|
|
177
338
|
if (!response.ok) {
|
|
@@ -184,6 +345,90 @@ async function controlPlaneJson<T>(input: {
|
|
|
184
345
|
return input.responseSchema.parse(await response.json());
|
|
185
346
|
}
|
|
186
347
|
|
|
348
|
+
export async function getConversationRun(input: {
|
|
349
|
+
authToken: string;
|
|
350
|
+
apiUrl: string;
|
|
351
|
+
conversationId: string;
|
|
352
|
+
runId: string;
|
|
353
|
+
abortSignal?: AbortSignal;
|
|
354
|
+
}): Promise<ConversationRunProjection> {
|
|
355
|
+
return controlPlaneJson({
|
|
356
|
+
authToken: input.authToken,
|
|
357
|
+
url: `${input.apiUrl}/conversations/${input.conversationId}/runs/${input.runId}`,
|
|
358
|
+
responseSchema: ConversationRunProjectionSchema,
|
|
359
|
+
operation: "Read conversation durable run projection",
|
|
360
|
+
abortSignal: input.abortSignal,
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
export async function appendConversationRunEvents(input: {
|
|
365
|
+
authToken: string;
|
|
366
|
+
apiUrl: string;
|
|
367
|
+
conversationId: string;
|
|
368
|
+
runId: string;
|
|
369
|
+
expectedPreviousEventId?: number;
|
|
370
|
+
expectedPreviousExternalEventSequence?: number;
|
|
371
|
+
events: unknown[];
|
|
372
|
+
abortSignal?: AbortSignal;
|
|
373
|
+
}): Promise<AppendConversationRunEventsResponse> {
|
|
374
|
+
if (input.abortSignal?.aborted) {
|
|
375
|
+
throw new DOMException("This operation was aborted", "AbortError");
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
const timedAbort = createTimedAbortSignal(AGENT_RUN_API_TIMEOUT_MS, input.abortSignal);
|
|
379
|
+
|
|
380
|
+
let response: Response;
|
|
381
|
+
try {
|
|
382
|
+
response = await fetch(
|
|
383
|
+
`${input.apiUrl}/conversations/${input.conversationId}/runs/${input.runId}/events`,
|
|
384
|
+
{
|
|
385
|
+
method: "POST",
|
|
386
|
+
headers: {
|
|
387
|
+
Authorization: `Bearer ${input.authToken}`,
|
|
388
|
+
"Content-Type": "application/json",
|
|
389
|
+
},
|
|
390
|
+
body: JSON.stringify({
|
|
391
|
+
...(input.expectedPreviousEventId !== undefined
|
|
392
|
+
? { expected_previous_event_id: input.expectedPreviousEventId }
|
|
393
|
+
: {}),
|
|
394
|
+
...(input.expectedPreviousExternalEventSequence !== undefined
|
|
395
|
+
? {
|
|
396
|
+
expected_previous_external_event_sequence:
|
|
397
|
+
input.expectedPreviousExternalEventSequence,
|
|
398
|
+
}
|
|
399
|
+
: {}),
|
|
400
|
+
events: input.events,
|
|
401
|
+
}),
|
|
402
|
+
signal: timedAbort.signal,
|
|
403
|
+
},
|
|
404
|
+
);
|
|
405
|
+
} catch (error) {
|
|
406
|
+
if (
|
|
407
|
+
error instanceof DOMException &&
|
|
408
|
+
error.name === "AbortError" &&
|
|
409
|
+
!timedAbort.wasAbortedByCaller()
|
|
410
|
+
) {
|
|
411
|
+
throw new Error(
|
|
412
|
+
`Append conversation run events timed out after ${AGENT_RUN_API_TIMEOUT_MS}ms`,
|
|
413
|
+
);
|
|
414
|
+
}
|
|
415
|
+
throw error;
|
|
416
|
+
} finally {
|
|
417
|
+
timedAbort.cleanup();
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
if (!response.ok) {
|
|
421
|
+
const body = await response.text().catch(() => "");
|
|
422
|
+
throw new AppendConversationRunEventsError({
|
|
423
|
+
status: response.status,
|
|
424
|
+
detail: parseAppendConversationRunEventsErrorBody(body),
|
|
425
|
+
statusText: response.statusText,
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
return AppendConversationRunEventsResponseSchema.parse(await response.json());
|
|
430
|
+
}
|
|
431
|
+
|
|
187
432
|
export async function createConversationAgentRun(
|
|
188
433
|
input: CreateConversationAgentRunInput,
|
|
189
434
|
): Promise<ConversationRunProjection> {
|
|
@@ -222,11 +467,11 @@ export async function createConversationAgentRun(
|
|
|
222
467
|
operation: "Create canonical durable run",
|
|
223
468
|
});
|
|
224
469
|
|
|
225
|
-
return
|
|
470
|
+
return getConversationRun({
|
|
226
471
|
authToken: input.authToken,
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
472
|
+
apiUrl: input.apiUrl,
|
|
473
|
+
conversationId: input.conversationId,
|
|
474
|
+
runId,
|
|
230
475
|
});
|
|
231
476
|
}
|
|
232
477
|
|
package/src/src/agent/index.ts
CHANGED
|
@@ -181,16 +181,51 @@ export {
|
|
|
181
181
|
type CreateAgUiBrowserResponseStreamInput,
|
|
182
182
|
} from "./ag-ui-browser-response-stream.js";
|
|
183
183
|
export {
|
|
184
|
+
bootstrapConversationAgentRun,
|
|
185
|
+
type BootstrapConversationAgentRunResult,
|
|
186
|
+
type ConversationMessageRecord,
|
|
187
|
+
ConversationMessageRecordSchema,
|
|
188
|
+
type ConversationRecord,
|
|
189
|
+
ConversationRecordSchema,
|
|
190
|
+
createConversationMessage,
|
|
191
|
+
createConversationRecord,
|
|
192
|
+
ensureConversationProjectLink,
|
|
193
|
+
fetchConversationRecord,
|
|
194
|
+
} from "./conversation-bootstrap.js";
|
|
195
|
+
export {
|
|
196
|
+
appendConversationRunEvents,
|
|
197
|
+
AppendConversationRunEventsError,
|
|
198
|
+
type AppendConversationRunEventsResponse,
|
|
199
|
+
AppendConversationRunEventsResponseSchema,
|
|
184
200
|
CompleteConversationRunResponseSchema,
|
|
185
201
|
type ConversationAgentRunUsage,
|
|
186
202
|
type ConversationRunProjection,
|
|
187
203
|
ConversationRunProjectionSchema,
|
|
204
|
+
ConversationRunStatusSchema,
|
|
188
205
|
type ConversationRunTargets,
|
|
189
206
|
ConversationRunTargetsSchema,
|
|
190
207
|
createConversationAgentRun,
|
|
191
208
|
finalizeConversationAgentRun,
|
|
209
|
+
getConversationRun,
|
|
210
|
+
isCursorMismatchConversationRunAppendError,
|
|
211
|
+
isIgnorableConversationRunAppendError,
|
|
212
|
+
parseAppendConversationRunEventsErrorBody,
|
|
192
213
|
resolveConversationRunTargets,
|
|
193
214
|
} from "./durable.js";
|
|
215
|
+
export {
|
|
216
|
+
buildInvokeAgentChildRunLifecycleCustomEvent,
|
|
217
|
+
buildInvokeAgentChildRunProgressEvents,
|
|
218
|
+
buildInvokeAgentChildRunStateDelta,
|
|
219
|
+
type InvokeAgentChildRunLifecycleCustomEvent,
|
|
220
|
+
InvokeAgentChildRunLifecycleCustomEventSchema,
|
|
221
|
+
type InvokeAgentChildRunLifecycleValue,
|
|
222
|
+
InvokeAgentChildRunLifecycleValueSchema,
|
|
223
|
+
type InvokeAgentChildRunProgressEvent,
|
|
224
|
+
type InvokeAgentChildRunProgressInput,
|
|
225
|
+
type InvokeAgentChildRunStateDelta,
|
|
226
|
+
InvokeAgentChildRunStateDeltaSchema,
|
|
227
|
+
publishInvokeAgentChildRunProgress,
|
|
228
|
+
} from "./invoke-agent-child-runs.js";
|
|
194
229
|
export {
|
|
195
230
|
type HostedChildLifecycleAdapter,
|
|
196
231
|
type HostedChildLifecycleRunnerOptions,
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import "../../_dnt.polyfills.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { appendConversationRunEvents, isIgnorableConversationRunAppendError } from "./durable.js";
|
|
4
|
+
|
|
5
|
+
const AG_UI_CUSTOM_EVENT_TYPE = "CUSTOM";
|
|
6
|
+
|
|
7
|
+
export const InvokeAgentChildRunLifecycleValueSchema = z.object({
|
|
8
|
+
toolCallId: z.string().min(1),
|
|
9
|
+
childConversationId: z.string().uuid(),
|
|
10
|
+
childRunId: z.string().min(1),
|
|
11
|
+
childMessageId: z.string().uuid(),
|
|
12
|
+
childAgentId: z.string().min(1),
|
|
13
|
+
description: z.string().min(1).optional(),
|
|
14
|
+
status: z.enum(["pending", "running", "waiting_for_tool", "completed", "failed", "cancelled"]),
|
|
15
|
+
sourceTargetKind: z.enum(["project", "production", "environment", "preview_branch"]).nullable()
|
|
16
|
+
.optional(),
|
|
17
|
+
runtimeTargetKind: z.enum(["production", "environment", "preview_branch"]).nullable().optional(),
|
|
18
|
+
targetEnvironmentId: z.string().uuid().nullable().optional(),
|
|
19
|
+
targetBranchId: z.string().uuid().nullable().optional(),
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
export type InvokeAgentChildRunLifecycleValue = z.infer<
|
|
23
|
+
typeof InvokeAgentChildRunLifecycleValueSchema
|
|
24
|
+
>;
|
|
25
|
+
|
|
26
|
+
export const InvokeAgentChildRunStateDeltaSchema = z.object({
|
|
27
|
+
type: z.literal("STATE_DELTA"),
|
|
28
|
+
delta: z.array(
|
|
29
|
+
z.object({
|
|
30
|
+
op: z.enum(["add", "replace"]),
|
|
31
|
+
path: z.string().min(1),
|
|
32
|
+
value: InvokeAgentChildRunLifecycleValueSchema,
|
|
33
|
+
}),
|
|
34
|
+
),
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
export type InvokeAgentChildRunStateDelta = z.infer<typeof InvokeAgentChildRunStateDeltaSchema>;
|
|
38
|
+
|
|
39
|
+
export const InvokeAgentChildRunLifecycleCustomEventSchema = z.object({
|
|
40
|
+
type: z.literal(AG_UI_CUSTOM_EVENT_TYPE),
|
|
41
|
+
name: z.literal("veryfront.invoke_agent.lifecycle"),
|
|
42
|
+
value: InvokeAgentChildRunLifecycleValueSchema,
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
export type InvokeAgentChildRunLifecycleCustomEvent = z.infer<
|
|
46
|
+
typeof InvokeAgentChildRunLifecycleCustomEventSchema
|
|
47
|
+
>;
|
|
48
|
+
|
|
49
|
+
export type InvokeAgentChildRunProgressInput = {
|
|
50
|
+
toolCallId: string;
|
|
51
|
+
childConversationId: string;
|
|
52
|
+
childRunId: string;
|
|
53
|
+
childMessageId: string;
|
|
54
|
+
childAgentId: string;
|
|
55
|
+
description?: string;
|
|
56
|
+
status: "pending" | "running" | "waiting_for_tool" | "completed" | "failed" | "cancelled";
|
|
57
|
+
sourceTargetKind?: "project" | "production" | "environment" | "preview_branch" | null;
|
|
58
|
+
runtimeTargetKind?: "production" | "environment" | "preview_branch" | null;
|
|
59
|
+
targetEnvironmentId?: string | null;
|
|
60
|
+
targetBranchId?: string | null;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export type InvokeAgentChildRunProgressEvent =
|
|
64
|
+
| InvokeAgentChildRunStateDelta
|
|
65
|
+
| InvokeAgentChildRunLifecycleCustomEvent;
|
|
66
|
+
|
|
67
|
+
function buildInvokeAgentChildRunLifecycleValue(
|
|
68
|
+
input: InvokeAgentChildRunProgressInput,
|
|
69
|
+
): InvokeAgentChildRunLifecycleValue {
|
|
70
|
+
return InvokeAgentChildRunLifecycleValueSchema.parse({
|
|
71
|
+
toolCallId: input.toolCallId,
|
|
72
|
+
childConversationId: input.childConversationId,
|
|
73
|
+
childRunId: input.childRunId,
|
|
74
|
+
childMessageId: input.childMessageId,
|
|
75
|
+
childAgentId: input.childAgentId,
|
|
76
|
+
...(input.description ? { description: input.description } : {}),
|
|
77
|
+
status: input.status,
|
|
78
|
+
...(input.sourceTargetKind !== undefined ? { sourceTargetKind: input.sourceTargetKind } : {}),
|
|
79
|
+
...(input.runtimeTargetKind !== undefined
|
|
80
|
+
? { runtimeTargetKind: input.runtimeTargetKind }
|
|
81
|
+
: {}),
|
|
82
|
+
...(input.targetEnvironmentId !== undefined
|
|
83
|
+
? { targetEnvironmentId: input.targetEnvironmentId }
|
|
84
|
+
: {}),
|
|
85
|
+
...(input.targetBranchId !== undefined ? { targetBranchId: input.targetBranchId } : {}),
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function buildInvokeAgentChildRunStateDelta(
|
|
90
|
+
input: InvokeAgentChildRunProgressInput,
|
|
91
|
+
): InvokeAgentChildRunStateDelta {
|
|
92
|
+
const escapedToolCallId = input.toolCallId.replaceAll("~", "~0").replaceAll("/", "~1");
|
|
93
|
+
return InvokeAgentChildRunStateDeltaSchema.parse({
|
|
94
|
+
type: "STATE_DELTA",
|
|
95
|
+
delta: [
|
|
96
|
+
{
|
|
97
|
+
op: input.status === "pending" ? "add" : "replace",
|
|
98
|
+
path: `/invokeAgentChildRuns/${escapedToolCallId}`,
|
|
99
|
+
value: buildInvokeAgentChildRunLifecycleValue(input),
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export function buildInvokeAgentChildRunLifecycleCustomEvent(
|
|
106
|
+
input: InvokeAgentChildRunProgressInput,
|
|
107
|
+
): InvokeAgentChildRunLifecycleCustomEvent {
|
|
108
|
+
return InvokeAgentChildRunLifecycleCustomEventSchema.parse({
|
|
109
|
+
type: AG_UI_CUSTOM_EVENT_TYPE,
|
|
110
|
+
name: "veryfront.invoke_agent.lifecycle",
|
|
111
|
+
value: buildInvokeAgentChildRunLifecycleValue(input),
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export function buildInvokeAgentChildRunProgressEvents(
|
|
116
|
+
input: InvokeAgentChildRunProgressInput,
|
|
117
|
+
): readonly [InvokeAgentChildRunStateDelta, InvokeAgentChildRunLifecycleCustomEvent] {
|
|
118
|
+
return [
|
|
119
|
+
buildInvokeAgentChildRunStateDelta(input),
|
|
120
|
+
buildInvokeAgentChildRunLifecycleCustomEvent(input),
|
|
121
|
+
] as const;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export async function publishInvokeAgentChildRunProgress(input: {
|
|
125
|
+
authToken: string;
|
|
126
|
+
apiUrl: string;
|
|
127
|
+
conversationId: string;
|
|
128
|
+
runId: string;
|
|
129
|
+
expectedPreviousEventId?: number;
|
|
130
|
+
expectedPreviousExternalEventSequence?: number;
|
|
131
|
+
toolCallId: string;
|
|
132
|
+
childAgentId: string;
|
|
133
|
+
childConversationId: string;
|
|
134
|
+
childRunId: string;
|
|
135
|
+
childMessageId: string;
|
|
136
|
+
description?: string;
|
|
137
|
+
status: "pending" | "running" | "waiting_for_tool" | "completed" | "failed" | "cancelled";
|
|
138
|
+
sourceTargetKind?: "project" | "production" | "environment" | "preview_branch" | null;
|
|
139
|
+
runtimeTargetKind?: "production" | "environment" | "preview_branch" | null;
|
|
140
|
+
targetEnvironmentId?: string | null;
|
|
141
|
+
targetBranchId?: string | null;
|
|
142
|
+
publishParentRunEvents?: (events: InvokeAgentChildRunProgressEvent[]) => Promise<void> | void;
|
|
143
|
+
abortSignal?: AbortSignal;
|
|
144
|
+
}): Promise<void> {
|
|
145
|
+
const events = [...buildInvokeAgentChildRunProgressEvents(input)];
|
|
146
|
+
|
|
147
|
+
if (input.publishParentRunEvents) {
|
|
148
|
+
await input.publishParentRunEvents(events);
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
try {
|
|
153
|
+
await appendConversationRunEvents({
|
|
154
|
+
authToken: input.authToken,
|
|
155
|
+
apiUrl: input.apiUrl,
|
|
156
|
+
conversationId: input.conversationId,
|
|
157
|
+
runId: input.runId,
|
|
158
|
+
expectedPreviousEventId: input.expectedPreviousEventId,
|
|
159
|
+
expectedPreviousExternalEventSequence: input.expectedPreviousExternalEventSequence,
|
|
160
|
+
events,
|
|
161
|
+
abortSignal: input.abortSignal,
|
|
162
|
+
});
|
|
163
|
+
} catch (error) {
|
|
164
|
+
if (isIgnorableConversationRunAppendError(error)) {
|
|
165
|
+
return;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
throw error;
|
|
169
|
+
}
|
|
170
|
+
}
|