@gea-ai/agent-sdk 0.1.261009-alpha.1 → 0.1.261012-alpha.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.
- package/dist/agent-call.d.ts +55 -27
- package/dist/agent-call.js +101 -16
- package/dist/agent-channel-api.js +3 -3
- package/dist/agent-channel-author-runtime.d.ts +13 -13
- package/dist/agent-remote-run.js +35 -6
- package/dist/agent-run-host.d.ts +12 -0
- package/dist/agent-run-host.js +144 -13
- package/dist/agent-session-children.js +38 -10
- package/dist/agent-session-execution.d.ts +87 -1
- package/dist/agent-session-execution.js +227 -44
- package/dist/agent-session-inbox.d.ts +160 -0
- package/dist/agent-session-inbox.js +1043 -47
- package/dist/agent-session-runner.d.ts +3 -0
- package/dist/agent-session-runner.js +10 -0
- package/dist/agent-session.js +152 -8
- package/dist/agent-worker-context.d.ts +4 -0
- package/dist/agent-worker-context.js +18 -0
- package/dist/agent-worker.js +303 -88
- package/dist/gea-ai.js +2 -1
- package/dist/host-rejection.d.ts +12 -0
- package/dist/host-rejection.js +78 -0
- package/dist/session-authority.d.ts +44 -1
- package/dist/session-authority.js +2 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
package/dist/agent-call.d.ts
CHANGED
|
@@ -1,6 +1,32 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
1
2
|
import { type AgentWorkerToolInitialization } from "@gea-ai/contract/agent-worker-tools";
|
|
2
3
|
import type { AgentHostBinding } from "./agent-worker.js";
|
|
3
4
|
import type { StudioArtifactScope } from "@gea-ai/contract/studio-artifacts";
|
|
5
|
+
/** Fresh Sessions keep the declared-target rule. A resume only needs sessionId. */
|
|
6
|
+
export declare function workerAgentToolInputSchema(input: {
|
|
7
|
+
agents: NonNullable<AgentWorkerToolInitialization["agents"]>;
|
|
8
|
+
canCopy?: boolean;
|
|
9
|
+
artifactScope?: StudioArtifactScope;
|
|
10
|
+
}): z.ZodObject<{
|
|
11
|
+
sessionId: z.ZodOptional<z.ZodUUID>;
|
|
12
|
+
target: z.ZodOptional<z.ZodString>;
|
|
13
|
+
message: z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
14
|
+
role: z.ZodLiteral<"user">;
|
|
15
|
+
parts: z.ZodArray<z.ZodObject<{
|
|
16
|
+
type: z.ZodLiteral<"text">;
|
|
17
|
+
text: z.ZodString;
|
|
18
|
+
}, z.core.$strict>>;
|
|
19
|
+
}, z.core.$strict>]> | z.ZodUnion<readonly [z.ZodString, z.ZodObject<{
|
|
20
|
+
role: z.ZodLiteral<"user">;
|
|
21
|
+
parts: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
|
|
22
|
+
type: z.ZodLiteral<"text">;
|
|
23
|
+
text: z.ZodString;
|
|
24
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
25
|
+
type: z.ZodLiteral<"file">;
|
|
26
|
+
file_id: z.ZodUUID;
|
|
27
|
+
}, z.core.$strict>]>>;
|
|
28
|
+
}, z.core.$strict>]>;
|
|
29
|
+
}, z.core.$strip>;
|
|
4
30
|
/** The host opens a fresh Worker invocation; only its visible answer returns to the caller. */
|
|
5
31
|
export declare function createWorkerAgentTool(input: {
|
|
6
32
|
agents: NonNullable<AgentWorkerToolInitialization["agents"]>;
|
|
@@ -14,7 +40,7 @@ export declare function createWorkerAgentTool(input: {
|
|
|
14
40
|
metadata?: import("@ai-sdk/provider").JSONObject;
|
|
15
41
|
inputSchema: import("ai").FlexibleSchema<{
|
|
16
42
|
sessionId?: string | undefined;
|
|
17
|
-
target
|
|
43
|
+
target?: string | undefined;
|
|
18
44
|
message: string | {
|
|
19
45
|
role: "user";
|
|
20
46
|
parts: ({
|
|
@@ -35,7 +61,7 @@ export declare function createWorkerAgentTool(input: {
|
|
|
35
61
|
contextSchema?: import("ai").FlexibleSchema<import("@ai-sdk/provider-utils").Context> | undefined;
|
|
36
62
|
needsApproval?: boolean | import("@ai-sdk/provider-utils").ToolNeedsApprovalFunction<{
|
|
37
63
|
sessionId?: string | undefined;
|
|
38
|
-
target
|
|
64
|
+
target?: string | undefined;
|
|
39
65
|
message: string | {
|
|
40
66
|
role: "user";
|
|
41
67
|
parts: ({
|
|
@@ -60,7 +86,7 @@ export declare function createWorkerAgentTool(input: {
|
|
|
60
86
|
onInputAvailable?: ((options: {
|
|
61
87
|
input: {
|
|
62
88
|
sessionId?: string | undefined;
|
|
63
|
-
target
|
|
89
|
+
target?: string | undefined;
|
|
64
90
|
message: string | {
|
|
65
91
|
role: "user";
|
|
66
92
|
parts: ({
|
|
@@ -83,7 +109,7 @@ export declare function createWorkerAgentTool(input: {
|
|
|
83
109
|
toolCallId: string;
|
|
84
110
|
input: {
|
|
85
111
|
sessionId?: string | undefined;
|
|
86
|
-
target
|
|
112
|
+
target?: string | undefined;
|
|
87
113
|
message: string | {
|
|
88
114
|
role: "user";
|
|
89
115
|
parts: ({
|
|
@@ -145,7 +171,7 @@ export declare function createWorkerAgentTool(input: {
|
|
|
145
171
|
}> | undefined;
|
|
146
172
|
execute: import("ai").ToolExecuteFunction<{
|
|
147
173
|
sessionId?: string | undefined;
|
|
148
|
-
target
|
|
174
|
+
target?: string | undefined;
|
|
149
175
|
message: string | {
|
|
150
176
|
role: "user";
|
|
151
177
|
parts: ({
|
|
@@ -191,7 +217,7 @@ export declare function createWorkerAgentTool(input: {
|
|
|
191
217
|
inputExamples?: {
|
|
192
218
|
input: NoInfer<{
|
|
193
219
|
sessionId?: string | undefined;
|
|
194
|
-
target
|
|
220
|
+
target?: string | undefined;
|
|
195
221
|
message: string | {
|
|
196
222
|
role: "user";
|
|
197
223
|
parts: ({
|
|
@@ -219,7 +245,7 @@ export declare function createWorkerAgentTool(input: {
|
|
|
219
245
|
} & {
|
|
220
246
|
execute: import("ai").ToolExecuteFunction<{
|
|
221
247
|
sessionId?: string | undefined;
|
|
222
|
-
target
|
|
248
|
+
target?: string | undefined;
|
|
223
249
|
message: string | {
|
|
224
250
|
role: "user";
|
|
225
251
|
parts: ({
|
|
@@ -263,7 +289,7 @@ export declare function createWorkerAgentTool(input: {
|
|
|
263
289
|
metadata?: import("@ai-sdk/provider").JSONObject;
|
|
264
290
|
inputSchema: import("ai").FlexibleSchema<{
|
|
265
291
|
sessionId?: string | undefined;
|
|
266
|
-
target
|
|
292
|
+
target?: string | undefined;
|
|
267
293
|
message: string | {
|
|
268
294
|
role: "user";
|
|
269
295
|
parts: ({
|
|
@@ -284,7 +310,7 @@ export declare function createWorkerAgentTool(input: {
|
|
|
284
310
|
contextSchema?: import("ai").FlexibleSchema<import("@ai-sdk/provider-utils").Context> | undefined;
|
|
285
311
|
needsApproval?: boolean | import("@ai-sdk/provider-utils").ToolNeedsApprovalFunction<{
|
|
286
312
|
sessionId?: string | undefined;
|
|
287
|
-
target
|
|
313
|
+
target?: string | undefined;
|
|
288
314
|
message: string | {
|
|
289
315
|
role: "user";
|
|
290
316
|
parts: ({
|
|
@@ -309,7 +335,7 @@ export declare function createWorkerAgentTool(input: {
|
|
|
309
335
|
onInputAvailable?: ((options: {
|
|
310
336
|
input: {
|
|
311
337
|
sessionId?: string | undefined;
|
|
312
|
-
target
|
|
338
|
+
target?: string | undefined;
|
|
313
339
|
message: string | {
|
|
314
340
|
role: "user";
|
|
315
341
|
parts: ({
|
|
@@ -332,7 +358,7 @@ export declare function createWorkerAgentTool(input: {
|
|
|
332
358
|
toolCallId: string;
|
|
333
359
|
input: {
|
|
334
360
|
sessionId?: string | undefined;
|
|
335
|
-
target
|
|
361
|
+
target?: string | undefined;
|
|
336
362
|
message: string | {
|
|
337
363
|
role: "user";
|
|
338
364
|
parts: ({
|
|
@@ -394,7 +420,7 @@ export declare function createWorkerAgentTool(input: {
|
|
|
394
420
|
}> | undefined;
|
|
395
421
|
execute: import("ai").ToolExecuteFunction<{
|
|
396
422
|
sessionId?: string | undefined;
|
|
397
|
-
target
|
|
423
|
+
target?: string | undefined;
|
|
398
424
|
message: string | {
|
|
399
425
|
role: "user";
|
|
400
426
|
parts: ({
|
|
@@ -440,7 +466,7 @@ export declare function createWorkerAgentTool(input: {
|
|
|
440
466
|
inputExamples?: {
|
|
441
467
|
input: NoInfer<{
|
|
442
468
|
sessionId?: string | undefined;
|
|
443
|
-
target
|
|
469
|
+
target?: string | undefined;
|
|
444
470
|
message: string | {
|
|
445
471
|
role: "user";
|
|
446
472
|
parts: ({
|
|
@@ -468,7 +494,7 @@ export declare function createWorkerAgentTool(input: {
|
|
|
468
494
|
} & {
|
|
469
495
|
execute: import("ai").ToolExecuteFunction<{
|
|
470
496
|
sessionId?: string | undefined;
|
|
471
|
-
target
|
|
497
|
+
target?: string | undefined;
|
|
472
498
|
message: string | {
|
|
473
499
|
role: "user";
|
|
474
500
|
parts: ({
|
|
@@ -512,7 +538,7 @@ export declare function createWorkerAgentTool(input: {
|
|
|
512
538
|
metadata?: import("@ai-sdk/provider").JSONObject;
|
|
513
539
|
inputSchema: import("ai").FlexibleSchema<{
|
|
514
540
|
sessionId?: string | undefined;
|
|
515
|
-
target
|
|
541
|
+
target?: string | undefined;
|
|
516
542
|
message: string | {
|
|
517
543
|
role: "user";
|
|
518
544
|
parts: ({
|
|
@@ -533,7 +559,7 @@ export declare function createWorkerAgentTool(input: {
|
|
|
533
559
|
contextSchema?: import("ai").FlexibleSchema<import("@ai-sdk/provider-utils").Context> | undefined;
|
|
534
560
|
needsApproval?: boolean | import("@ai-sdk/provider-utils").ToolNeedsApprovalFunction<{
|
|
535
561
|
sessionId?: string | undefined;
|
|
536
|
-
target
|
|
562
|
+
target?: string | undefined;
|
|
537
563
|
message: string | {
|
|
538
564
|
role: "user";
|
|
539
565
|
parts: ({
|
|
@@ -558,7 +584,7 @@ export declare function createWorkerAgentTool(input: {
|
|
|
558
584
|
onInputAvailable?: ((options: {
|
|
559
585
|
input: {
|
|
560
586
|
sessionId?: string | undefined;
|
|
561
|
-
target
|
|
587
|
+
target?: string | undefined;
|
|
562
588
|
message: string | {
|
|
563
589
|
role: "user";
|
|
564
590
|
parts: ({
|
|
@@ -581,7 +607,7 @@ export declare function createWorkerAgentTool(input: {
|
|
|
581
607
|
toolCallId: string;
|
|
582
608
|
input: {
|
|
583
609
|
sessionId?: string | undefined;
|
|
584
|
-
target
|
|
610
|
+
target?: string | undefined;
|
|
585
611
|
message: string | {
|
|
586
612
|
role: "user";
|
|
587
613
|
parts: ({
|
|
@@ -643,7 +669,7 @@ export declare function createWorkerAgentTool(input: {
|
|
|
643
669
|
}> | undefined;
|
|
644
670
|
execute: import("ai").ToolExecuteFunction<{
|
|
645
671
|
sessionId?: string | undefined;
|
|
646
|
-
target
|
|
672
|
+
target?: string | undefined;
|
|
647
673
|
message: string | {
|
|
648
674
|
role: "user";
|
|
649
675
|
parts: ({
|
|
@@ -693,7 +719,7 @@ export declare function createWorkerAgentTool(input: {
|
|
|
693
719
|
} & {
|
|
694
720
|
execute: import("ai").ToolExecuteFunction<{
|
|
695
721
|
sessionId?: string | undefined;
|
|
696
|
-
target
|
|
722
|
+
target?: string | undefined;
|
|
697
723
|
message: string | {
|
|
698
724
|
role: "user";
|
|
699
725
|
parts: ({
|
|
@@ -737,7 +763,7 @@ export declare function createWorkerAgentTool(input: {
|
|
|
737
763
|
metadata?: import("@ai-sdk/provider").JSONObject;
|
|
738
764
|
inputSchema: import("ai").FlexibleSchema<{
|
|
739
765
|
sessionId?: string | undefined;
|
|
740
|
-
target
|
|
766
|
+
target?: string | undefined;
|
|
741
767
|
message: string | {
|
|
742
768
|
role: "user";
|
|
743
769
|
parts: ({
|
|
@@ -758,7 +784,7 @@ export declare function createWorkerAgentTool(input: {
|
|
|
758
784
|
contextSchema?: import("ai").FlexibleSchema<import("@ai-sdk/provider-utils").Context> | undefined;
|
|
759
785
|
needsApproval?: boolean | import("@ai-sdk/provider-utils").ToolNeedsApprovalFunction<{
|
|
760
786
|
sessionId?: string | undefined;
|
|
761
|
-
target
|
|
787
|
+
target?: string | undefined;
|
|
762
788
|
message: string | {
|
|
763
789
|
role: "user";
|
|
764
790
|
parts: ({
|
|
@@ -783,7 +809,7 @@ export declare function createWorkerAgentTool(input: {
|
|
|
783
809
|
onInputAvailable?: ((options: {
|
|
784
810
|
input: {
|
|
785
811
|
sessionId?: string | undefined;
|
|
786
|
-
target
|
|
812
|
+
target?: string | undefined;
|
|
787
813
|
message: string | {
|
|
788
814
|
role: "user";
|
|
789
815
|
parts: ({
|
|
@@ -806,7 +832,7 @@ export declare function createWorkerAgentTool(input: {
|
|
|
806
832
|
toolCallId: string;
|
|
807
833
|
input: {
|
|
808
834
|
sessionId?: string | undefined;
|
|
809
|
-
target
|
|
835
|
+
target?: string | undefined;
|
|
810
836
|
message: string | {
|
|
811
837
|
role: "user";
|
|
812
838
|
parts: ({
|
|
@@ -868,7 +894,7 @@ export declare function createWorkerAgentTool(input: {
|
|
|
868
894
|
}> | undefined;
|
|
869
895
|
execute: import("ai").ToolExecuteFunction<{
|
|
870
896
|
sessionId?: string | undefined;
|
|
871
|
-
target
|
|
897
|
+
target?: string | undefined;
|
|
872
898
|
message: string | {
|
|
873
899
|
role: "user";
|
|
874
900
|
parts: ({
|
|
@@ -918,7 +944,7 @@ export declare function createWorkerAgentTool(input: {
|
|
|
918
944
|
} & {
|
|
919
945
|
execute: import("ai").ToolExecuteFunction<{
|
|
920
946
|
sessionId?: string | undefined;
|
|
921
|
-
target
|
|
947
|
+
target?: string | undefined;
|
|
922
948
|
message: string | {
|
|
923
949
|
role: "user";
|
|
924
950
|
parts: ({
|
|
@@ -1225,7 +1251,9 @@ export declare function createWorkerRunCancelTool({ host, }: {
|
|
|
1225
1251
|
status: "abort_requested" | "not_running";
|
|
1226
1252
|
}, NoInfer<import("@ai-sdk/provider-utils").Context>>;
|
|
1227
1253
|
});
|
|
1228
|
-
export declare function readWorkerAgentResponse(response: Response
|
|
1254
|
+
export declare function readWorkerAgentResponse(response: Response, options?: {
|
|
1255
|
+
persistedSessionWaiting?: () => Promise<boolean>;
|
|
1256
|
+
}): Promise<{
|
|
1229
1257
|
status: "completed" | "suspended";
|
|
1230
1258
|
text: string;
|
|
1231
1259
|
}>;
|
package/dist/agent-call.js
CHANGED
|
@@ -5,20 +5,45 @@ import { parseJsonEventStream } from "@ai-sdk/provider-utils";
|
|
|
5
5
|
import { tool, uiMessageChunkSchema } from "ai";
|
|
6
6
|
import { agentSubagentConcurrencyErrorSchema, agentRemoteAdmissionErrorSchema, agentCallInputSchema, agentCallTextMessageSchema, agentRunCallResultSchema, getAgentCallFileIds, } from "@gea-ai/contract/agent-worker-tools";
|
|
7
7
|
import { captureTraceContext } from "./trace-context.js";
|
|
8
|
+
/** Fresh Sessions keep the declared-target rule. A resume only needs sessionId. */
|
|
9
|
+
export function workerAgentToolInputSchema(input) {
|
|
10
|
+
const message = input.artifactScope
|
|
11
|
+
? agentCallInputSchema.shape.message
|
|
12
|
+
: agentCallTextMessageSchema;
|
|
13
|
+
const keys = new Set(input.agents.map((agent) => agent.key));
|
|
14
|
+
return z
|
|
15
|
+
.object({
|
|
16
|
+
sessionId: z.uuid().optional(),
|
|
17
|
+
target: z.string().trim().min(1).max(80).optional(),
|
|
18
|
+
message,
|
|
19
|
+
})
|
|
20
|
+
.superRefine((value, context) => {
|
|
21
|
+
if (value.sessionId)
|
|
22
|
+
return;
|
|
23
|
+
if (value.target === undefined) {
|
|
24
|
+
if (keys.size > 0 && !input.canCopy) {
|
|
25
|
+
context.addIssue({
|
|
26
|
+
code: "custom",
|
|
27
|
+
path: ["target"],
|
|
28
|
+
message: "A new Session requires a declared target.",
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
if (!keys.has(value.target)) {
|
|
34
|
+
context.addIssue({
|
|
35
|
+
code: "custom",
|
|
36
|
+
path: ["target"],
|
|
37
|
+
message: "Select a declared target for a new Session.",
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
}
|
|
8
42
|
/** The host opens a fresh Worker invocation; only its visible answer returns to the caller. */
|
|
9
43
|
export function createWorkerAgentTool(input) {
|
|
10
44
|
return tool({
|
|
11
|
-
description: `Start an Agent Run in a new or idle child Session. Use runWait with returned runIds and runCancel to cancel. Use sessionId to continue the same Session. ${input.canCopy ? "Omit target to create a copy of yourself." : "Select a declared target."} Available targets: ${JSON.stringify(input.agents)}. Supply context in message.${input.artifactScope ? " To send selected files, use a user message with file parts containing immutable Artifact file_id values. Refer to attachments by filename or order in task text; remote transfer may assign new IDs, exposed to the child in Attached Artifact metadata. IDs hardcoded in text are not rewritten." : ""}`,
|
|
12
|
-
inputSchema:
|
|
13
|
-
target: input.agents.length
|
|
14
|
-
? input.canCopy
|
|
15
|
-
? z.enum(input.agents.map((agent) => agent.key)).optional()
|
|
16
|
-
: z.enum(input.agents.map((agent) => agent.key))
|
|
17
|
-
: z.never().optional(),
|
|
18
|
-
message: input.artifactScope
|
|
19
|
-
? agentCallInputSchema.shape.message
|
|
20
|
-
: agentCallTextMessageSchema,
|
|
21
|
-
}),
|
|
45
|
+
description: `Start an Agent Run in a new or idle child Session. Use runWait with returned runIds and runCancel to cancel. Use sessionId to continue the same Session; target may be omitted or name the recorded Agent. ${input.canCopy ? "Omit target to create a copy of yourself." : "Select a declared target for a new Session."} Available targets: ${JSON.stringify(input.agents)}. Supply context in message.${input.artifactScope ? " To send selected files, use a user message with file parts containing immutable Artifact file_id values. Refer to attachments by filename or order in task text; remote transfer may assign new IDs, exposed to the child in Attached Artifact metadata. IDs hardcoded in text are not rewritten." : ""}`,
|
|
46
|
+
inputSchema: workerAgentToolInputSchema(input),
|
|
22
47
|
execute: async (value, options) => {
|
|
23
48
|
const fileIds = getAgentCallFileIds(value.message);
|
|
24
49
|
const response = await input.host.fetch("/internal/agent-worker-host/v1/agents/runs", {
|
|
@@ -70,6 +95,23 @@ export function createWorkerAgentTool(input) {
|
|
|
70
95
|
error: "child_busy",
|
|
71
96
|
message: "This child Session has unfinished work. Wait for its Run before continuing the Session.",
|
|
72
97
|
};
|
|
98
|
+
if (response.status === 403) {
|
|
99
|
+
const rejection = z
|
|
100
|
+
.object({
|
|
101
|
+
error: z
|
|
102
|
+
.string()
|
|
103
|
+
.max(80)
|
|
104
|
+
.regex(/^[A-Za-z0-9_.-]+$/),
|
|
105
|
+
})
|
|
106
|
+
.safeParse(value);
|
|
107
|
+
if (rejection.success) {
|
|
108
|
+
console.error("Child run rejected", {
|
|
109
|
+
status: 403,
|
|
110
|
+
error: rejection.data.error,
|
|
111
|
+
});
|
|
112
|
+
throw new Error(`Agent invocation was rejected (403 ${rejection.data.error}).`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
73
115
|
}
|
|
74
116
|
throw new Error(`Agent invocation was rejected (${response.status}).`);
|
|
75
117
|
}
|
|
@@ -99,7 +141,15 @@ export function createWorkerRunCancelTool({ host, }) {
|
|
|
99
141
|
}
|
|
100
142
|
class AgentChildRunResponseError extends TaggedError("AgentChildRunResponseError")() {
|
|
101
143
|
}
|
|
102
|
-
|
|
144
|
+
const childDiagnosticIdentifierPattern = /^[A-Za-z0-9_.-]+$/;
|
|
145
|
+
function childDiagnosticIdentifier(value) {
|
|
146
|
+
return typeof value === "string" &&
|
|
147
|
+
value.length <= 80 &&
|
|
148
|
+
childDiagnosticIdentifierPattern.test(value)
|
|
149
|
+
? value
|
|
150
|
+
: undefined;
|
|
151
|
+
}
|
|
152
|
+
export async function readWorkerAgentResponse(response, options) {
|
|
103
153
|
if (response.status === 409 &&
|
|
104
154
|
response.headers.get("x-gea-session-execution") === "already-started") {
|
|
105
155
|
await response.body?.cancel();
|
|
@@ -117,6 +167,9 @@ export async function readWorkerAgentResponse(response) {
|
|
|
117
167
|
let completed = false;
|
|
118
168
|
let suspended = false;
|
|
119
169
|
let failure;
|
|
170
|
+
let legacyToolCalls = false;
|
|
171
|
+
let otherUnacceptableFinish = false;
|
|
172
|
+
let sawStreamFailure = false;
|
|
120
173
|
const reader = parseJsonEventStream({
|
|
121
174
|
stream: response.body,
|
|
122
175
|
schema: uiMessageChunkSchema,
|
|
@@ -133,26 +186,46 @@ export async function readWorkerAgentResponse(response) {
|
|
|
133
186
|
const chunk = event.value;
|
|
134
187
|
if (chunk.type === "text-delta")
|
|
135
188
|
text += chunk.delta;
|
|
136
|
-
if (chunk.type === "error")
|
|
189
|
+
if (chunk.type === "error") {
|
|
190
|
+
sawStreamFailure = true;
|
|
137
191
|
failure ??= new AgentChildRunResponseError({
|
|
138
192
|
code: "child_stream_error",
|
|
139
193
|
message: chunk.errorText,
|
|
140
194
|
});
|
|
141
|
-
|
|
195
|
+
}
|
|
196
|
+
if (chunk.type === "abort") {
|
|
197
|
+
sawStreamFailure = true;
|
|
142
198
|
failure ??= new AgentChildRunResponseError({
|
|
143
199
|
code: "child_stream_aborted",
|
|
144
200
|
message: "Child Agent was cancelled.",
|
|
145
201
|
});
|
|
202
|
+
}
|
|
146
203
|
if (chunk.type === "finish") {
|
|
147
204
|
suspended = z
|
|
148
205
|
.object({ sessionStatus: z.literal("waiting") })
|
|
149
206
|
.safeParse(chunk.messageMetadata).success;
|
|
150
|
-
|
|
151
|
-
!(suspended && chunk.finishReason === "tool-calls")
|
|
207
|
+
const unacceptable = chunk.finishReason !== "stop" &&
|
|
208
|
+
!(suspended && chunk.finishReason === "tool-calls");
|
|
209
|
+
if (unacceptable) {
|
|
210
|
+
if (chunk.finishReason === "tool-calls" && !suspended)
|
|
211
|
+
legacyToolCalls = true;
|
|
212
|
+
else
|
|
213
|
+
otherUnacceptableFinish = true;
|
|
214
|
+
const parsedSession = z
|
|
215
|
+
.object({ sessionStatus: z.unknown() })
|
|
216
|
+
.safeParse(chunk.messageMetadata);
|
|
217
|
+
const rawSessionStatus = parsedSession.success
|
|
218
|
+
? parsedSession.data.sessionStatus
|
|
219
|
+
: undefined;
|
|
220
|
+
const sessionStatus = childDiagnosticIdentifier(rawSessionStatus);
|
|
152
221
|
failure ??= new AgentChildRunResponseError({
|
|
153
222
|
code: "child_finish_reason",
|
|
154
223
|
message: `Child Agent did not complete (${chunk.finishReason ?? "unknown"}).`,
|
|
224
|
+
finishReason: childDiagnosticIdentifier(chunk.finishReason) ?? "unknown",
|
|
225
|
+
hasSessionStatus: rawSessionStatus !== undefined,
|
|
226
|
+
...(sessionStatus ? { sessionStatus } : {}),
|
|
155
227
|
});
|
|
228
|
+
}
|
|
156
229
|
completed = true;
|
|
157
230
|
}
|
|
158
231
|
}
|
|
@@ -161,6 +234,18 @@ export async function readWorkerAgentResponse(response) {
|
|
|
161
234
|
await reader.cancel();
|
|
162
235
|
reader.releaseLock();
|
|
163
236
|
}
|
|
237
|
+
if (options?.persistedSessionWaiting &&
|
|
238
|
+
legacyToolCalls &&
|
|
239
|
+
!otherUnacceptableFinish &&
|
|
240
|
+
!sawStreamFailure &&
|
|
241
|
+
failure instanceof AgentChildRunResponseError &&
|
|
242
|
+
failure.code === "child_finish_reason") {
|
|
243
|
+
const waiting = await Result.tryPromise(() => options.persistedSessionWaiting());
|
|
244
|
+
if (waiting.isOk() && waiting.value) {
|
|
245
|
+
failure = undefined;
|
|
246
|
+
suspended = true;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
164
249
|
if (failure)
|
|
165
250
|
throw failure;
|
|
166
251
|
if (!completed)
|
|
@@ -40,7 +40,7 @@ export function extractChannelReply(messageValue, responseMessageId) {
|
|
|
40
40
|
}
|
|
41
41
|
/** Channel owns delivery; ordinary Agents API owns admission, execution and history. */
|
|
42
42
|
export async function executeChannelAgentRun(input) {
|
|
43
|
-
const fetchApi = async (path, body) => {
|
|
43
|
+
const fetchApi = async (path, body, headers) => {
|
|
44
44
|
input.signal.throwIfAborted();
|
|
45
45
|
const response = await input.binding.fetch(`/api/v1${path}`, {
|
|
46
46
|
method: body === undefined ? "GET" : "POST",
|
|
@@ -48,7 +48,7 @@ export async function executeChannelAgentRun(input) {
|
|
|
48
48
|
...(body === undefined
|
|
49
49
|
? {}
|
|
50
50
|
: {
|
|
51
|
-
headers: { "content-type": "application/json" },
|
|
51
|
+
headers: { "content-type": "application/json", ...headers },
|
|
52
52
|
body: JSON.stringify(body),
|
|
53
53
|
}),
|
|
54
54
|
});
|
|
@@ -67,7 +67,7 @@ export async function executeChannelAgentRun(input) {
|
|
|
67
67
|
id: input.runId,
|
|
68
68
|
input: input.message,
|
|
69
69
|
stream: false,
|
|
70
|
-
})).body?.cancel();
|
|
70
|
+
}, { "idempotency-key": input.runId })).body?.cancel();
|
|
71
71
|
let stream = true;
|
|
72
72
|
for (;;) {
|
|
73
73
|
const current = runSchema.parse(await (await fetchApi(`/runs/${input.runId}`)).json());
|
|
@@ -19,19 +19,6 @@ export declare function executeChannelBehavior(input: {
|
|
|
19
19
|
environment: AgentChannelFetchEnvironment;
|
|
20
20
|
signal: AbortSignal;
|
|
21
21
|
}): Promise<{
|
|
22
|
-
sequence: number;
|
|
23
|
-
duplicate: boolean;
|
|
24
|
-
} | {
|
|
25
|
-
state: AgentChannelJson;
|
|
26
|
-
intents: {
|
|
27
|
-
key: string;
|
|
28
|
-
payload: AgentChannelJson;
|
|
29
|
-
eventId: string;
|
|
30
|
-
operationId: string;
|
|
31
|
-
}[];
|
|
32
|
-
cursor: number;
|
|
33
|
-
idempotencyWindowMs?: number | undefined;
|
|
34
|
-
} | {
|
|
35
22
|
status: "sent";
|
|
36
23
|
receipt?: AgentChannelJson | undefined;
|
|
37
24
|
} | {
|
|
@@ -56,6 +43,19 @@ export declare function executeChannelBehavior(input: {
|
|
|
56
43
|
message: string;
|
|
57
44
|
retryable: boolean;
|
|
58
45
|
};
|
|
46
|
+
} | {
|
|
47
|
+
sequence: number;
|
|
48
|
+
duplicate: boolean;
|
|
49
|
+
} | {
|
|
50
|
+
state: AgentChannelJson;
|
|
51
|
+
intents: {
|
|
52
|
+
key: string;
|
|
53
|
+
payload: AgentChannelJson;
|
|
54
|
+
eventId: string;
|
|
55
|
+
operationId: string;
|
|
56
|
+
}[];
|
|
57
|
+
cursor: number;
|
|
58
|
+
idempotencyWindowMs?: number | undefined;
|
|
59
59
|
} | {
|
|
60
60
|
events: {
|
|
61
61
|
id: string;
|
package/dist/agent-remote-run.js
CHANGED
|
@@ -62,13 +62,42 @@ export async function submitRemoteRun(fetch, input, options = {}) {
|
|
|
62
62
|
}))).id;
|
|
63
63
|
signal.throwIfAborted();
|
|
64
64
|
submitting = true;
|
|
65
|
-
//
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
65
|
+
// One key per logical submission. Retries reuse it so a lost 202 cannot
|
|
66
|
+
// start a second Run. A later call to submitRemoteRun is a new request.
|
|
67
|
+
const idempotencyKey = crypto.randomUUID();
|
|
68
|
+
const runBody = JSON.stringify({
|
|
69
|
+
id: idempotencyKey,
|
|
70
|
+
input: message,
|
|
71
|
+
stream: false,
|
|
71
72
|
});
|
|
73
|
+
const runHeaders = {
|
|
74
|
+
"content-type": "application/json",
|
|
75
|
+
"idempotency-key": idempotencyKey,
|
|
76
|
+
};
|
|
77
|
+
let response;
|
|
78
|
+
for (let attempt = 0; attempt < 3; attempt++) {
|
|
79
|
+
signal.throwIfAborted();
|
|
80
|
+
try {
|
|
81
|
+
response = await fetch(`/sessions/${sessionId}/runs`, {
|
|
82
|
+
method: "POST",
|
|
83
|
+
headers: runHeaders,
|
|
84
|
+
signal,
|
|
85
|
+
body: runBody,
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
if (signal.aborted || attempt === 2)
|
|
90
|
+
throw error;
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
const retryable = [502, 503, 504].includes(response.status);
|
|
94
|
+
const admitted = response.headers.has("x-gea-agent-run-id");
|
|
95
|
+
if (!retryable || admitted || attempt === 2)
|
|
96
|
+
break;
|
|
97
|
+
await response.body?.cancel();
|
|
98
|
+
}
|
|
99
|
+
if (!response)
|
|
100
|
+
throw new Error("Remote Run was not submitted.");
|
|
72
101
|
rejected = [400, 401, 403, 404, 405, 409, 413, 415, 422, 429].includes(response.status);
|
|
73
102
|
const run = agentHttpRunSchema.parse(await responseJson(response));
|
|
74
103
|
if (run.session_id !== sessionId)
|
package/dist/agent-run-host.d.ts
CHANGED
|
@@ -7,21 +7,33 @@ export type { RemoteRunFetch, RemoteRunDestination, RemoteInputFiles, RemoteFile
|
|
|
7
7
|
export { readWorkerAgentResponse } from "./agent-call.js";
|
|
8
8
|
export { streamManagedAgentSessionRun } from "./agent-session-stream.js";
|
|
9
9
|
export type AgentChildRunSession = (operation: string, body: unknown, traceContext?: TraceContext) => Promise<Response>;
|
|
10
|
+
/**
|
|
11
|
+
* Renders child Run updates for a parent model turn. Upstream dropped the task-era
|
|
12
|
+
* helper without a replacement; App Server adapters still need one summary shape.
|
|
13
|
+
* JSON escaping can expand each character sixfold; leave room for Run identities.
|
|
14
|
+
*/
|
|
15
|
+
export declare function formatAgentChildRunUpdates(runs: Pick<AgentChildRun, "id" | "sessionId" | "agentKey" | "target" | "outcome">[]): string;
|
|
10
16
|
/** Invocation transport only. SDK Sessions own Run state, waits, completion and wakeups. */
|
|
11
17
|
export declare class AgentRunHost {
|
|
12
18
|
private readonly host;
|
|
13
19
|
private readonly executions;
|
|
20
|
+
private readonly executionDone;
|
|
14
21
|
private readonly work;
|
|
15
22
|
private closed;
|
|
16
23
|
private readonly shutdown;
|
|
17
24
|
constructor(host: {
|
|
18
25
|
session: AgentChildRunSession;
|
|
26
|
+
/** Native App Server owns Worker handles; this callback only admits the resolved target. */
|
|
27
|
+
dispatch?(run: AgentChildRun, execution?: AgentSessionInboxExecution): Promise<void>;
|
|
28
|
+
/** Authorize against the root Session and return its retained child binding. */
|
|
29
|
+
resolveSession?(sessionId: string): Promise<Response>;
|
|
19
30
|
remoteFetch?(destination: RemoteRunDestination, path: string, init?: RequestInit): Promise<Response>;
|
|
20
31
|
transferRemoteInputs?(destination: RemoteRunDestination, files: RemoteInputFiles, scope: StudioArtifactScope | undefined, signal: AbortSignal): Promise<RemoteFileMapping>;
|
|
21
32
|
register(run: AgentChildRun): Promise<string>;
|
|
22
33
|
invoke(run: AgentChildRun, signal: AbortSignal, continuation?: TraceContinuation, inboxExecution?: AgentSessionInboxExecution): Promise<{
|
|
23
34
|
response: Response;
|
|
24
35
|
dispose?: () => void;
|
|
36
|
+
persistedSessionWaiting?: () => Promise<boolean>;
|
|
25
37
|
}>;
|
|
26
38
|
cancelChild(run: AgentChildRun): Promise<boolean | void>;
|
|
27
39
|
onError(error: unknown, identity?: {
|