@gea-ai/agent-sdk 0.1.261012-alpha.0 → 0.1.261016-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-ai.d.ts +1 -0
- package/dist/agent-ai.js +11 -4
- package/dist/agent-call.d.ts +175 -3
- package/dist/agent-call.js +197 -24
- package/dist/agent-channel-api.js +81 -31
- package/dist/agent-channel-author-runtime.d.ts +15 -15
- package/dist/agent-channel-author-runtime.js +59 -11
- package/dist/agent-channel-control.d.ts +4 -0
- package/dist/agent-channel-control.js +336 -0
- package/dist/agent-channel-receiver.js +24 -8
- package/dist/agent-channel-runtime.d.ts +1 -1
- package/dist/agent-channel-runtime.js +221 -136
- package/dist/agent-channel-session-transport.d.ts +3 -0
- package/dist/agent-channel-session-transport.js +26 -0
- package/dist/agent-channel-worker.js +2 -1
- package/dist/agent-client-tool.d.ts +3 -0
- package/dist/agent-client-tool.js +79 -0
- package/dist/agent-computer-http.d.ts +6 -2
- package/dist/agent-computer-http.js +33 -14
- package/dist/agent-computer-protocol.d.ts +8 -0
- package/dist/agent-computer-protocol.js +126 -0
- package/dist/agent-computer-scope.d.ts +1 -0
- package/dist/agent-computer-scope.js +18 -1
- package/dist/agent-computer-session.d.ts +5 -0
- package/dist/agent-computer-session.js +149 -25
- package/dist/agent-core.wasm +0 -0
- package/dist/agent-remote-run.d.ts +2 -2
- package/dist/agent-run-host.d.ts +10 -7
- package/dist/agent-run-host.js +15 -9
- package/dist/agent-session-execution.d.ts +33 -1
- package/dist/agent-session-execution.js +215 -28
- package/dist/agent-session-inbox.d.ts +9 -2
- package/dist/agent-session-inbox.js +419 -33
- package/dist/agent-session-stale-run.d.ts +33 -0
- package/dist/agent-session-stale-run.js +44 -0
- package/dist/agent-session.d.ts +24 -0
- package/dist/agent-session.js +25 -5
- package/dist/agent-stream-coalescing.d.ts +11 -0
- package/dist/agent-stream-coalescing.js +159 -0
- package/dist/agent-worker-attachments.d.ts +2 -2
- package/dist/agent-worker.d.ts +9 -1
- package/dist/agent-worker.js +210 -221
- package/dist/artifacts.d.ts +4 -4
- package/dist/artifacts.js +2 -2
- package/dist/channels/index.d.ts +13 -3
- package/dist/channels/index.js +3 -0
- package/dist/context-runtime.d.ts +1 -0
- package/dist/context-runtime.js +1 -0
- package/dist/evals.d.ts +8 -0
- package/dist/evals.js +96 -2
- package/dist/experimental/agent-core-ui.js +1 -0
- package/dist/index.d.ts +10 -4
- package/dist/index.js +6 -0
- package/dist/session-authority.d.ts +6 -1
- package/dist/tool-model-output.d.ts +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +10 -8
- package/dist/channels/feishu-codec.d.ts +0 -17
- package/dist/channels/feishu-codec.js +0 -108
- package/dist/channels/feishu-inbound.d.ts +0 -34
- package/dist/channels/feishu-inbound.js +0 -135
- package/dist/channels/feishu-output.d.ts +0 -427
- package/dist/channels/feishu-output.js +0 -852
- package/dist/channels/feishu-websocket.d.ts +0 -4
- package/dist/channels/feishu-websocket.js +0 -423
- package/dist/channels/feishu.d.ts +0 -145
- package/dist/channels/feishu.js +0 -85
package/dist/agent-ai.d.ts
CHANGED
package/dist/agent-ai.js
CHANGED
|
@@ -29,9 +29,9 @@ export function createAgentAI(input) {
|
|
|
29
29
|
};
|
|
30
30
|
// The binding owns the model span. Forward the active SDK parent so generic
|
|
31
31
|
// native calls and Agent-owned calls share the same trace without two model spans.
|
|
32
|
-
const observe = (options, result) => result.then((value) => {
|
|
32
|
+
const observe = (options, result, callId) => result.then((value) => {
|
|
33
33
|
input.recordUsage({
|
|
34
|
-
callId: value.callId,
|
|
34
|
+
callId: callId ?? value.callId,
|
|
35
35
|
model: value.model,
|
|
36
36
|
label: options.label,
|
|
37
37
|
usage: value.usage,
|
|
@@ -40,6 +40,7 @@ export function createAgentAI(input) {
|
|
|
40
40
|
return value;
|
|
41
41
|
}, (error) => {
|
|
42
42
|
input.recordUsage({
|
|
43
|
+
callId,
|
|
43
44
|
model: options.model,
|
|
44
45
|
label: options.label,
|
|
45
46
|
usage: null,
|
|
@@ -53,20 +54,26 @@ export function createAgentAI(input) {
|
|
|
53
54
|
return {
|
|
54
55
|
async generateText(options) {
|
|
55
56
|
const parameters = prepare(options);
|
|
57
|
+
const callId = input.startUsage ? crypto.randomUUID() : undefined;
|
|
58
|
+
if (callId)
|
|
59
|
+
await input.startUsage(callId, parameters.model);
|
|
56
60
|
return observe(parameters, (async () => {
|
|
57
61
|
if (!input.binding.generateText)
|
|
58
62
|
throw new Error("AI generation binding is unavailable. Update Worker Runtime.");
|
|
59
63
|
return input.binding.generateText(parameters);
|
|
60
|
-
})());
|
|
64
|
+
})(), callId);
|
|
61
65
|
},
|
|
62
66
|
async streamText(options) {
|
|
63
67
|
const parameters = prepare(options);
|
|
68
|
+
const callId = input.startUsage ? crypto.randomUUID() : undefined;
|
|
69
|
+
if (callId)
|
|
70
|
+
await input.startUsage(callId, parameters.model);
|
|
64
71
|
const opened = (async () => {
|
|
65
72
|
if (!input.binding.streamText)
|
|
66
73
|
throw new Error("AI generation binding is unavailable. Update Worker Runtime.");
|
|
67
74
|
return input.binding.streamText(parameters);
|
|
68
75
|
})();
|
|
69
|
-
const result = observe(parameters, opened.then((call) => call.result));
|
|
76
|
+
const result = observe(parameters, opened.then((call) => call.result), callId);
|
|
70
77
|
result.catch(() => { });
|
|
71
78
|
const call = await opened;
|
|
72
79
|
return { stream: call.stream, result };
|
package/dist/agent-call.d.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { type AgentWorkerToolInitialization } from "@gea-ai/contract/agent-worker-tools";
|
|
3
3
|
import type { AgentHostBinding } from "./agent-worker.js";
|
|
4
|
-
import type {
|
|
4
|
+
import type { BuilderArtifactScope } from "@gea-ai/contract/builder-artifacts";
|
|
5
5
|
/** Fresh Sessions keep the declared-target rule. A resume only needs sessionId. */
|
|
6
6
|
export declare function workerAgentToolInputSchema(input: {
|
|
7
7
|
agents: NonNullable<AgentWorkerToolInitialization["agents"]>;
|
|
8
8
|
canCopy?: boolean;
|
|
9
|
-
artifactScope?:
|
|
9
|
+
artifactScope?: BuilderArtifactScope;
|
|
10
10
|
}): z.ZodObject<{
|
|
11
11
|
sessionId: z.ZodOptional<z.ZodUUID>;
|
|
12
12
|
target: z.ZodOptional<z.ZodString>;
|
|
@@ -31,8 +31,9 @@ export declare function workerAgentToolInputSchema(input: {
|
|
|
31
31
|
export declare function createWorkerAgentTool(input: {
|
|
32
32
|
agents: NonNullable<AgentWorkerToolInitialization["agents"]>;
|
|
33
33
|
host: AgentHostBinding;
|
|
34
|
+
runId?: string;
|
|
34
35
|
canCopy?: boolean;
|
|
35
|
-
artifactScope?:
|
|
36
|
+
artifactScope?: BuilderArtifactScope;
|
|
36
37
|
}): ({
|
|
37
38
|
deferLoading?: boolean;
|
|
38
39
|
title?: string;
|
|
@@ -146,6 +147,16 @@ export declare function createWorkerAgentTool(input: {
|
|
|
146
147
|
} | {
|
|
147
148
|
error: string;
|
|
148
149
|
message: string;
|
|
150
|
+
} | {
|
|
151
|
+
code: "UPSTREAM_HTTP_ERROR";
|
|
152
|
+
status: number;
|
|
153
|
+
message: string;
|
|
154
|
+
} | {
|
|
155
|
+
code: string;
|
|
156
|
+
reason: string;
|
|
157
|
+
status: number;
|
|
158
|
+
requestId?: string | undefined;
|
|
159
|
+
message: string;
|
|
149
160
|
}>;
|
|
150
161
|
}) => import("@ai-sdk/provider-utils").ToolResultOutput | PromiseLike<import("@ai-sdk/provider-utils").ToolResultOutput>) | undefined;
|
|
151
162
|
} & {
|
|
@@ -168,6 +179,16 @@ export declare function createWorkerAgentTool(input: {
|
|
|
168
179
|
} | {
|
|
169
180
|
error: string;
|
|
170
181
|
message: string;
|
|
182
|
+
} | {
|
|
183
|
+
code: "UPSTREAM_HTTP_ERROR";
|
|
184
|
+
status: number;
|
|
185
|
+
message: string;
|
|
186
|
+
} | {
|
|
187
|
+
code: string;
|
|
188
|
+
reason: string;
|
|
189
|
+
status: number;
|
|
190
|
+
requestId?: string | undefined;
|
|
191
|
+
message: string;
|
|
171
192
|
}> | undefined;
|
|
172
193
|
execute: import("ai").ToolExecuteFunction<{
|
|
173
194
|
sessionId?: string | undefined;
|
|
@@ -207,6 +228,16 @@ export declare function createWorkerAgentTool(input: {
|
|
|
207
228
|
} | {
|
|
208
229
|
error: string;
|
|
209
230
|
message: string;
|
|
231
|
+
} | {
|
|
232
|
+
code: "UPSTREAM_HTTP_ERROR";
|
|
233
|
+
status: number;
|
|
234
|
+
message: string;
|
|
235
|
+
} | {
|
|
236
|
+
code: string;
|
|
237
|
+
reason: string;
|
|
238
|
+
status: number;
|
|
239
|
+
requestId?: string | undefined;
|
|
240
|
+
message: string;
|
|
210
241
|
}, NoInfer<import("@ai-sdk/provider-utils").Context>>;
|
|
211
242
|
} & {
|
|
212
243
|
description?: string | ((options: {
|
|
@@ -281,6 +312,16 @@ export declare function createWorkerAgentTool(input: {
|
|
|
281
312
|
} | {
|
|
282
313
|
error: string;
|
|
283
314
|
message: string;
|
|
315
|
+
} | {
|
|
316
|
+
code: "UPSTREAM_HTTP_ERROR";
|
|
317
|
+
status: number;
|
|
318
|
+
message: string;
|
|
319
|
+
} | {
|
|
320
|
+
code: string;
|
|
321
|
+
reason: string;
|
|
322
|
+
status: number;
|
|
323
|
+
requestId?: string | undefined;
|
|
324
|
+
message: string;
|
|
284
325
|
}, NoInfer<import("@ai-sdk/provider-utils").Context>>;
|
|
285
326
|
}) | ({
|
|
286
327
|
deferLoading?: boolean;
|
|
@@ -395,6 +436,16 @@ export declare function createWorkerAgentTool(input: {
|
|
|
395
436
|
} | {
|
|
396
437
|
error: string;
|
|
397
438
|
message: string;
|
|
439
|
+
} | {
|
|
440
|
+
code: "UPSTREAM_HTTP_ERROR";
|
|
441
|
+
status: number;
|
|
442
|
+
message: string;
|
|
443
|
+
} | {
|
|
444
|
+
code: string;
|
|
445
|
+
reason: string;
|
|
446
|
+
status: number;
|
|
447
|
+
requestId?: string | undefined;
|
|
448
|
+
message: string;
|
|
398
449
|
}>;
|
|
399
450
|
}) => import("@ai-sdk/provider-utils").ToolResultOutput | PromiseLike<import("@ai-sdk/provider-utils").ToolResultOutput>) | undefined;
|
|
400
451
|
} & {
|
|
@@ -417,6 +468,16 @@ export declare function createWorkerAgentTool(input: {
|
|
|
417
468
|
} | {
|
|
418
469
|
error: string;
|
|
419
470
|
message: string;
|
|
471
|
+
} | {
|
|
472
|
+
code: "UPSTREAM_HTTP_ERROR";
|
|
473
|
+
status: number;
|
|
474
|
+
message: string;
|
|
475
|
+
} | {
|
|
476
|
+
code: string;
|
|
477
|
+
reason: string;
|
|
478
|
+
status: number;
|
|
479
|
+
requestId?: string | undefined;
|
|
480
|
+
message: string;
|
|
420
481
|
}> | undefined;
|
|
421
482
|
execute: import("ai").ToolExecuteFunction<{
|
|
422
483
|
sessionId?: string | undefined;
|
|
@@ -456,6 +517,16 @@ export declare function createWorkerAgentTool(input: {
|
|
|
456
517
|
} | {
|
|
457
518
|
error: string;
|
|
458
519
|
message: string;
|
|
520
|
+
} | {
|
|
521
|
+
code: "UPSTREAM_HTTP_ERROR";
|
|
522
|
+
status: number;
|
|
523
|
+
message: string;
|
|
524
|
+
} | {
|
|
525
|
+
code: string;
|
|
526
|
+
reason: string;
|
|
527
|
+
status: number;
|
|
528
|
+
requestId?: string | undefined;
|
|
529
|
+
message: string;
|
|
459
530
|
}, NoInfer<import("@ai-sdk/provider-utils").Context>>;
|
|
460
531
|
} & {
|
|
461
532
|
description?: string | ((options: {
|
|
@@ -530,6 +601,16 @@ export declare function createWorkerAgentTool(input: {
|
|
|
530
601
|
} | {
|
|
531
602
|
error: string;
|
|
532
603
|
message: string;
|
|
604
|
+
} | {
|
|
605
|
+
code: "UPSTREAM_HTTP_ERROR";
|
|
606
|
+
status: number;
|
|
607
|
+
message: string;
|
|
608
|
+
} | {
|
|
609
|
+
code: string;
|
|
610
|
+
reason: string;
|
|
611
|
+
status: number;
|
|
612
|
+
requestId?: string | undefined;
|
|
613
|
+
message: string;
|
|
533
614
|
}, NoInfer<import("@ai-sdk/provider-utils").Context>>;
|
|
534
615
|
}) | ({
|
|
535
616
|
deferLoading?: boolean;
|
|
@@ -644,6 +725,16 @@ export declare function createWorkerAgentTool(input: {
|
|
|
644
725
|
} | {
|
|
645
726
|
error: string;
|
|
646
727
|
message: string;
|
|
728
|
+
} | {
|
|
729
|
+
code: "UPSTREAM_HTTP_ERROR";
|
|
730
|
+
status: number;
|
|
731
|
+
message: string;
|
|
732
|
+
} | {
|
|
733
|
+
code: string;
|
|
734
|
+
reason: string;
|
|
735
|
+
status: number;
|
|
736
|
+
requestId?: string | undefined;
|
|
737
|
+
message: string;
|
|
647
738
|
}>;
|
|
648
739
|
}) => import("@ai-sdk/provider-utils").ToolResultOutput | PromiseLike<import("@ai-sdk/provider-utils").ToolResultOutput>) | undefined;
|
|
649
740
|
} & {
|
|
@@ -666,6 +757,16 @@ export declare function createWorkerAgentTool(input: {
|
|
|
666
757
|
} | {
|
|
667
758
|
error: string;
|
|
668
759
|
message: string;
|
|
760
|
+
} | {
|
|
761
|
+
code: "UPSTREAM_HTTP_ERROR";
|
|
762
|
+
status: number;
|
|
763
|
+
message: string;
|
|
764
|
+
} | {
|
|
765
|
+
code: string;
|
|
766
|
+
reason: string;
|
|
767
|
+
status: number;
|
|
768
|
+
requestId?: string | undefined;
|
|
769
|
+
message: string;
|
|
669
770
|
}> | undefined;
|
|
670
771
|
execute: import("ai").ToolExecuteFunction<{
|
|
671
772
|
sessionId?: string | undefined;
|
|
@@ -705,6 +806,16 @@ export declare function createWorkerAgentTool(input: {
|
|
|
705
806
|
} | {
|
|
706
807
|
error: string;
|
|
707
808
|
message: string;
|
|
809
|
+
} | {
|
|
810
|
+
code: "UPSTREAM_HTTP_ERROR";
|
|
811
|
+
status: number;
|
|
812
|
+
message: string;
|
|
813
|
+
} | {
|
|
814
|
+
code: string;
|
|
815
|
+
reason: string;
|
|
816
|
+
status: number;
|
|
817
|
+
requestId?: string | undefined;
|
|
818
|
+
message: string;
|
|
708
819
|
}, NoInfer<import("@ai-sdk/provider-utils").Context>>;
|
|
709
820
|
} & {
|
|
710
821
|
type: 'provider';
|
|
@@ -755,6 +866,16 @@ export declare function createWorkerAgentTool(input: {
|
|
|
755
866
|
} | {
|
|
756
867
|
error: string;
|
|
757
868
|
message: string;
|
|
869
|
+
} | {
|
|
870
|
+
code: "UPSTREAM_HTTP_ERROR";
|
|
871
|
+
status: number;
|
|
872
|
+
message: string;
|
|
873
|
+
} | {
|
|
874
|
+
code: string;
|
|
875
|
+
reason: string;
|
|
876
|
+
status: number;
|
|
877
|
+
requestId?: string | undefined;
|
|
878
|
+
message: string;
|
|
758
879
|
}, NoInfer<import("@ai-sdk/provider-utils").Context>>;
|
|
759
880
|
}) | ({
|
|
760
881
|
deferLoading?: boolean;
|
|
@@ -869,6 +990,16 @@ export declare function createWorkerAgentTool(input: {
|
|
|
869
990
|
} | {
|
|
870
991
|
error: string;
|
|
871
992
|
message: string;
|
|
993
|
+
} | {
|
|
994
|
+
code: "UPSTREAM_HTTP_ERROR";
|
|
995
|
+
status: number;
|
|
996
|
+
message: string;
|
|
997
|
+
} | {
|
|
998
|
+
code: string;
|
|
999
|
+
reason: string;
|
|
1000
|
+
status: number;
|
|
1001
|
+
requestId?: string | undefined;
|
|
1002
|
+
message: string;
|
|
872
1003
|
}>;
|
|
873
1004
|
}) => import("@ai-sdk/provider-utils").ToolResultOutput | PromiseLike<import("@ai-sdk/provider-utils").ToolResultOutput>) | undefined;
|
|
874
1005
|
} & {
|
|
@@ -891,6 +1022,16 @@ export declare function createWorkerAgentTool(input: {
|
|
|
891
1022
|
} | {
|
|
892
1023
|
error: string;
|
|
893
1024
|
message: string;
|
|
1025
|
+
} | {
|
|
1026
|
+
code: "UPSTREAM_HTTP_ERROR";
|
|
1027
|
+
status: number;
|
|
1028
|
+
message: string;
|
|
1029
|
+
} | {
|
|
1030
|
+
code: string;
|
|
1031
|
+
reason: string;
|
|
1032
|
+
status: number;
|
|
1033
|
+
requestId?: string | undefined;
|
|
1034
|
+
message: string;
|
|
894
1035
|
}> | undefined;
|
|
895
1036
|
execute: import("ai").ToolExecuteFunction<{
|
|
896
1037
|
sessionId?: string | undefined;
|
|
@@ -930,6 +1071,16 @@ export declare function createWorkerAgentTool(input: {
|
|
|
930
1071
|
} | {
|
|
931
1072
|
error: string;
|
|
932
1073
|
message: string;
|
|
1074
|
+
} | {
|
|
1075
|
+
code: "UPSTREAM_HTTP_ERROR";
|
|
1076
|
+
status: number;
|
|
1077
|
+
message: string;
|
|
1078
|
+
} | {
|
|
1079
|
+
code: string;
|
|
1080
|
+
reason: string;
|
|
1081
|
+
status: number;
|
|
1082
|
+
requestId?: string | undefined;
|
|
1083
|
+
message: string;
|
|
933
1084
|
}, NoInfer<import("@ai-sdk/provider-utils").Context>>;
|
|
934
1085
|
} & {
|
|
935
1086
|
type: 'provider';
|
|
@@ -980,6 +1131,16 @@ export declare function createWorkerAgentTool(input: {
|
|
|
980
1131
|
} | {
|
|
981
1132
|
error: string;
|
|
982
1133
|
message: string;
|
|
1134
|
+
} | {
|
|
1135
|
+
code: "UPSTREAM_HTTP_ERROR";
|
|
1136
|
+
status: number;
|
|
1137
|
+
message: string;
|
|
1138
|
+
} | {
|
|
1139
|
+
code: string;
|
|
1140
|
+
reason: string;
|
|
1141
|
+
status: number;
|
|
1142
|
+
requestId?: string | undefined;
|
|
1143
|
+
message: string;
|
|
983
1144
|
}, NoInfer<import("@ai-sdk/provider-utils").Context>>;
|
|
984
1145
|
});
|
|
985
1146
|
export declare function createWorkerRunCancelTool({ host, }: {
|
|
@@ -1251,7 +1412,18 @@ export declare function createWorkerRunCancelTool({ host, }: {
|
|
|
1251
1412
|
status: "abort_requested" | "not_running";
|
|
1252
1413
|
}, NoInfer<import("@ai-sdk/provider-utils").Context>>;
|
|
1253
1414
|
});
|
|
1415
|
+
export declare function readChildHttpRejection(response: Response): Promise<{
|
|
1416
|
+
body: unknown;
|
|
1417
|
+
bodyPrefix: string;
|
|
1418
|
+
bodyState: string;
|
|
1419
|
+
logReason: string;
|
|
1420
|
+
code: string;
|
|
1421
|
+
reason: string;
|
|
1422
|
+
requestId: string | undefined;
|
|
1423
|
+
}>;
|
|
1254
1424
|
export declare function readWorkerAgentResponse(response: Response, options?: {
|
|
1425
|
+
runId?: string;
|
|
1426
|
+
requestPath?: string;
|
|
1255
1427
|
persistedSessionWaiting?: () => Promise<boolean>;
|
|
1256
1428
|
}): Promise<{
|
|
1257
1429
|
status: "completed" | "suspended";
|
package/dist/agent-call.js
CHANGED
|
@@ -59,9 +59,9 @@ export function createWorkerAgentTool(input) {
|
|
|
59
59
|
signal: options.abortSignal,
|
|
60
60
|
});
|
|
61
61
|
if (!response.ok) {
|
|
62
|
-
const
|
|
63
|
-
if (body
|
|
64
|
-
const value = body
|
|
62
|
+
const rejection = await readChildHttpRejection(response);
|
|
63
|
+
if (rejection.body !== undefined) {
|
|
64
|
+
const value = rejection.body;
|
|
65
65
|
const limit = agentSubagentConcurrencyErrorSchema.safeParse(value);
|
|
66
66
|
if (limit.success)
|
|
67
67
|
return {
|
|
@@ -95,25 +95,14 @@ export function createWorkerAgentTool(input) {
|
|
|
95
95
|
error: "child_busy",
|
|
96
96
|
message: "This child Session has unfinished work. Wait for its Run before continuing the Session.",
|
|
97
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
|
-
}
|
|
115
98
|
}
|
|
116
|
-
|
|
99
|
+
logChildHttpRejection(response, rejection, {
|
|
100
|
+
path: "/internal/agent-worker-host/v1/agents/runs",
|
|
101
|
+
...(input.runId ? { runId: input.runId } : {}),
|
|
102
|
+
});
|
|
103
|
+
// Return the rejection instead of throwing. A thrown tool error is
|
|
104
|
+
// replaced by a generic execution message before it reaches the model.
|
|
105
|
+
return agentToolRejectionResult(response.status, rejection);
|
|
117
106
|
}
|
|
118
107
|
return agentRunCallResultSchema.parse(await response.json());
|
|
119
108
|
},
|
|
@@ -149,18 +138,202 @@ function childDiagnosticIdentifier(value) {
|
|
|
149
138
|
? value
|
|
150
139
|
: undefined;
|
|
151
140
|
}
|
|
141
|
+
// Only fixed protocol vocabulary may appear outside the shape-redacted prefix.
|
|
142
|
+
// Identifier-shaped strings can still be tokens, so a character regex is insufficient.
|
|
143
|
+
const childHttpLogReasonSchema = z.enum([
|
|
144
|
+
"UPSTREAM_HTTP_ERROR",
|
|
145
|
+
"BAD_REQUEST",
|
|
146
|
+
"UNAUTHORIZED",
|
|
147
|
+
"FORBIDDEN",
|
|
148
|
+
"NOT_FOUND",
|
|
149
|
+
"CONFLICT",
|
|
150
|
+
"NESTED_RESUME_REQUIRES_NEW_SDK",
|
|
151
|
+
"CHILD_SESSION_AUTHORITY_MISMATCH",
|
|
152
|
+
"invalid_request",
|
|
153
|
+
"invalid_child_request",
|
|
154
|
+
"invalid_json",
|
|
155
|
+
"unknown_child_session",
|
|
156
|
+
"child_busy",
|
|
157
|
+
"session_identity_conflict",
|
|
158
|
+
"subagent_concurrency_limit",
|
|
159
|
+
"runtime_unavailable",
|
|
160
|
+
"empty_error_response",
|
|
161
|
+
"invalid_error_response",
|
|
162
|
+
"unreadable_error_response",
|
|
163
|
+
"error_response_too_large",
|
|
164
|
+
"error_response_timeout",
|
|
165
|
+
]);
|
|
166
|
+
// Both admission and dispatch consume untrusted HTTP failures. Bound diagnostics
|
|
167
|
+
// independently of a streaming Run: a stalled error body must never hold its slot.
|
|
168
|
+
export async function readChildHttpRejection(response) {
|
|
169
|
+
let bodyPrefix = "";
|
|
170
|
+
let reason = "empty_error_response";
|
|
171
|
+
let body;
|
|
172
|
+
if (response.body) {
|
|
173
|
+
reason = "unreadable_error_response";
|
|
174
|
+
const reader = response.body.getReader();
|
|
175
|
+
let timer;
|
|
176
|
+
const read = await Result.tryPromise(() => Promise.race([
|
|
177
|
+
(async () => {
|
|
178
|
+
const chunks = [];
|
|
179
|
+
let size = 0;
|
|
180
|
+
let reads = 0;
|
|
181
|
+
while (true) {
|
|
182
|
+
if (++reads > 8192) {
|
|
183
|
+
reason = "error_response_too_large";
|
|
184
|
+
return undefined;
|
|
185
|
+
}
|
|
186
|
+
const next = await reader.read();
|
|
187
|
+
if (next.done)
|
|
188
|
+
break;
|
|
189
|
+
// Shape-only redaction: arbitrary error text may contain credentials or
|
|
190
|
+
// user content under any key. Never guess which strings are safe.
|
|
191
|
+
const prefix = next.value.subarray(0, Math.max(0, 512 - bodyPrefix.length));
|
|
192
|
+
bodyPrefix += Array.from(prefix, (byte) => [123, 125, 91, 93, 34, 58, 44, 32].includes(byte)
|
|
193
|
+
? String.fromCharCode(byte)
|
|
194
|
+
: "*").join("");
|
|
195
|
+
size += next.value.byteLength;
|
|
196
|
+
if (size > 8192) {
|
|
197
|
+
reason = "error_response_too_large";
|
|
198
|
+
return undefined;
|
|
199
|
+
}
|
|
200
|
+
chunks.push(next.value);
|
|
201
|
+
}
|
|
202
|
+
if (!size) {
|
|
203
|
+
reason = "empty_error_response";
|
|
204
|
+
return undefined;
|
|
205
|
+
}
|
|
206
|
+
reason = "invalid_error_response";
|
|
207
|
+
const bytes = new Uint8Array(size);
|
|
208
|
+
let offset = 0;
|
|
209
|
+
for (const chunk of chunks) {
|
|
210
|
+
bytes.set(chunk, offset);
|
|
211
|
+
offset += chunk.byteLength;
|
|
212
|
+
}
|
|
213
|
+
const parsed = JSON.parse(new TextDecoder().decode(bytes));
|
|
214
|
+
reason = "complete";
|
|
215
|
+
return parsed;
|
|
216
|
+
})(),
|
|
217
|
+
new Promise((resolve) => {
|
|
218
|
+
timer = setTimeout(() => {
|
|
219
|
+
reason = "error_response_timeout";
|
|
220
|
+
resolve(undefined);
|
|
221
|
+
}, 1000);
|
|
222
|
+
}),
|
|
223
|
+
]));
|
|
224
|
+
clearTimeout(timer);
|
|
225
|
+
// Do not await a peer's cancellation acknowledgement on the rejection path.
|
|
226
|
+
void reader.cancel().catch(() => { });
|
|
227
|
+
reader.releaseLock();
|
|
228
|
+
if (read.isOk())
|
|
229
|
+
body = read.value;
|
|
230
|
+
}
|
|
231
|
+
const bodyState = reason;
|
|
232
|
+
const identifier = z
|
|
233
|
+
.string()
|
|
234
|
+
.max(80)
|
|
235
|
+
.regex(/^[A-Za-z0-9_.-]+$/);
|
|
236
|
+
const parsed = z
|
|
237
|
+
.object({
|
|
238
|
+
code: identifier.optional(),
|
|
239
|
+
requestId: z.uuid().optional(),
|
|
240
|
+
reason: z.string().max(1000).optional(),
|
|
241
|
+
error: z
|
|
242
|
+
.union([
|
|
243
|
+
identifier,
|
|
244
|
+
z.object({
|
|
245
|
+
code: identifier,
|
|
246
|
+
reason: z.string().max(1000).optional(),
|
|
247
|
+
}),
|
|
248
|
+
])
|
|
249
|
+
.optional(),
|
|
250
|
+
})
|
|
251
|
+
.safeParse(body);
|
|
252
|
+
if (parsed.success) {
|
|
253
|
+
const error = parsed.data.error;
|
|
254
|
+
const code = typeof error === "string" ? error : (error?.code ?? parsed.data.code);
|
|
255
|
+
const detail = (typeof error === "object" ? error.reason : undefined) ??
|
|
256
|
+
parsed.data.reason;
|
|
257
|
+
if (code || detail)
|
|
258
|
+
return {
|
|
259
|
+
body,
|
|
260
|
+
bodyPrefix,
|
|
261
|
+
bodyState,
|
|
262
|
+
logReason: childHttpLogReasonSchema.safeParse(detail).data ??
|
|
263
|
+
childHttpLogReasonSchema.safeParse(code).data ??
|
|
264
|
+
"unclassified_upstream_error",
|
|
265
|
+
code: code ?? "UPSTREAM_HTTP_ERROR",
|
|
266
|
+
reason: detail ?? code,
|
|
267
|
+
requestId: parsed.data.requestId,
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
return {
|
|
271
|
+
body,
|
|
272
|
+
bodyPrefix,
|
|
273
|
+
bodyState,
|
|
274
|
+
logReason: reason === "complete" ? "invalid_error_response" : reason,
|
|
275
|
+
code: "UPSTREAM_HTTP_ERROR",
|
|
276
|
+
reason: reason === "complete" ? "invalid_error_response" : reason,
|
|
277
|
+
requestId: undefined,
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
function agentToolRejectionResult(status, rejection) {
|
|
281
|
+
const recognized = rejection.bodyState === "complete" &&
|
|
282
|
+
!(rejection.code === "UPSTREAM_HTTP_ERROR" &&
|
|
283
|
+
rejection.reason === "invalid_error_response");
|
|
284
|
+
if (!recognized) {
|
|
285
|
+
return {
|
|
286
|
+
code: "UPSTREAM_HTTP_ERROR",
|
|
287
|
+
status,
|
|
288
|
+
message: `Agent invocation was rejected (${status}). The server did not return a readable error.`,
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
const request = rejection.requestId
|
|
292
|
+
? ` (request ${rejection.requestId})`
|
|
293
|
+
: "";
|
|
294
|
+
return {
|
|
295
|
+
code: rejection.code,
|
|
296
|
+
reason: rejection.reason,
|
|
297
|
+
status,
|
|
298
|
+
...(rejection.requestId ? { requestId: rejection.requestId } : {}),
|
|
299
|
+
message: `Agent invocation was rejected (${status}) ${rejection.code}: ${rejection.reason}${request}`,
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
function logChildHttpRejection(response, rejection, identity) {
|
|
303
|
+
const requestId = rejection.requestId ??
|
|
304
|
+
z.uuid().safeParse(response.headers.get("x-gea-request-id")).data;
|
|
305
|
+
// JSON stays readable in native console forwarding as well as Node/Nitro.
|
|
306
|
+
console.error(JSON.stringify({
|
|
307
|
+
event: "agent.child_http.rejected",
|
|
308
|
+
...identity,
|
|
309
|
+
status: response.status,
|
|
310
|
+
bodyState: rejection.bodyState,
|
|
311
|
+
reason: rejection.logReason,
|
|
312
|
+
bodyPrefix: rejection.bodyPrefix,
|
|
313
|
+
...(requestId ? { requestId } : {}),
|
|
314
|
+
}));
|
|
315
|
+
}
|
|
152
316
|
export async function readWorkerAgentResponse(response, options) {
|
|
153
317
|
if (response.status === 409 &&
|
|
154
318
|
response.headers.get("x-gea-session-execution") === "already-started") {
|
|
155
|
-
|
|
319
|
+
void response.body?.cancel().catch(() => { });
|
|
156
320
|
return { status: "suspended", text: "" };
|
|
157
321
|
}
|
|
158
322
|
if (!response.ok || !response.body) {
|
|
159
|
-
await response
|
|
323
|
+
const rejection = await readChildHttpRejection(response);
|
|
324
|
+
logChildHttpRejection(response, rejection, {
|
|
325
|
+
path: response.url
|
|
326
|
+
? new URL(response.url).pathname
|
|
327
|
+
: (options?.requestPath?.split(/[?#]/, 1)[0] ?? "unknown"),
|
|
328
|
+
...(options?.runId ? { runId: options.runId } : {}),
|
|
329
|
+
});
|
|
160
330
|
throw new AgentChildRunResponseError({
|
|
161
331
|
code: "child_http_error",
|
|
162
332
|
status: response.status,
|
|
163
|
-
|
|
333
|
+
data: {
|
|
334
|
+
reason: rejection.logReason,
|
|
335
|
+
},
|
|
336
|
+
message: `Child Agent invocation failed (${response.status}) ${rejection.code}: ${rejection.reason}`,
|
|
164
337
|
});
|
|
165
338
|
}
|
|
166
339
|
let text = "";
|