@agent-native/agentkit 0.1.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/ARCHITECTURE.md +290 -0
- package/README.md +822 -0
- package/dist/adapters/http.d.ts +56 -0
- package/dist/adapters/http.d.ts.map +1 -0
- package/dist/adapters/http.js +950 -0
- package/dist/adapters/http.js.map +1 -0
- package/dist/adapters/index.d.ts +2 -0
- package/dist/adapters/index.d.ts.map +1 -0
- package/dist/adapters/index.js +2 -0
- package/dist/adapters/index.js.map +1 -0
- package/dist/client/client.d.ts +240 -0
- package/dist/client/client.d.ts.map +1 -0
- package/dist/client/client.js +1605 -0
- package/dist/client/client.js.map +1 -0
- package/dist/client/index.d.ts +3 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +3 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/state.d.ts +72 -0
- package/dist/client/state.d.ts.map +1 -0
- package/dist/client/state.js +385 -0
- package/dist/client/state.js.map +1 -0
- package/dist/conformance/index.d.ts +41 -0
- package/dist/conformance/index.d.ts.map +1 -0
- package/dist/conformance/index.js +924 -0
- package/dist/conformance/index.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/protocol/agui-codec.d.ts +28 -0
- package/dist/protocol/agui-codec.d.ts.map +1 -0
- package/dist/protocol/agui-codec.js +250 -0
- package/dist/protocol/agui-codec.js.map +1 -0
- package/dist/protocol/agui.d.ts +144 -0
- package/dist/protocol/agui.d.ts.map +1 -0
- package/dist/protocol/agui.js +253 -0
- package/dist/protocol/agui.js.map +1 -0
- package/dist/protocol/compatibility.d.ts +35 -0
- package/dist/protocol/compatibility.d.ts.map +1 -0
- package/dist/protocol/compatibility.js +160 -0
- package/dist/protocol/compatibility.js.map +1 -0
- package/dist/protocol/errors.d.ts +24 -0
- package/dist/protocol/errors.d.ts.map +1 -0
- package/dist/protocol/errors.js +77 -0
- package/dist/protocol/errors.js.map +1 -0
- package/dist/protocol/index.d.ts +982 -0
- package/dist/protocol/index.d.ts.map +1 -0
- package/dist/protocol/index.js +56 -0
- package/dist/protocol/index.js.map +1 -0
- package/dist/protocol/validation.d.ts +94 -0
- package/dist/protocol/validation.d.ts.map +1 -0
- package/dist/protocol/validation.js +1871 -0
- package/dist/protocol/validation.js.map +1 -0
- package/dist/protocol/version.d.ts +7 -0
- package/dist/protocol/version.d.ts.map +1 -0
- package/dist/protocol/version.js +9 -0
- package/dist/protocol/version.js.map +1 -0
- package/dist/react/chat.d.ts +34 -0
- package/dist/react/chat.d.ts.map +1 -0
- package/dist/react/chat.js +23 -0
- package/dist/react/chat.js.map +1 -0
- package/dist/react/components.d.ts +96 -0
- package/dist/react/components.d.ts.map +1 -0
- package/dist/react/components.js +1300 -0
- package/dist/react/components.js.map +1 -0
- package/dist/react/context.d.ts +259 -0
- package/dist/react/context.d.ts.map +1 -0
- package/dist/react/context.js +359 -0
- package/dist/react/context.js.map +1 -0
- package/dist/react/headless.d.ts +3 -0
- package/dist/react/headless.d.ts.map +1 -0
- package/dist/react/headless.js +3 -0
- package/dist/react/headless.js.map +1 -0
- package/dist/react/index.d.ts +6 -0
- package/dist/react/index.d.ts.map +1 -0
- package/dist/react/index.js +6 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/root.d.ts +58 -0
- package/dist/react/root.d.ts.map +1 -0
- package/dist/react/root.js +151 -0
- package/dist/react/root.js.map +1 -0
- package/dist/react/streaming-text.d.ts +19 -0
- package/dist/react/streaming-text.d.ts.map +1 -0
- package/dist/react/streaming-text.js +259 -0
- package/dist/react/streaming-text.js.map +1 -0
- package/dist/react/styles.css +1477 -0
- package/package.json +112 -0
|
@@ -0,0 +1,1871 @@
|
|
|
1
|
+
import { AGENTKIT_PROTOCOL_NAME, AGENTKIT_PROTOCOL_VERSION, isAgentKitProtocolVersion, } from "./version.js";
|
|
2
|
+
export class AgentProtocolValidationError extends Error {
|
|
3
|
+
path;
|
|
4
|
+
constructor(path, message) {
|
|
5
|
+
super(`${path}: ${message}`);
|
|
6
|
+
this.name = "AgentProtocolValidationError";
|
|
7
|
+
this.path = path;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
function record(value, path) {
|
|
11
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
12
|
+
throw new AgentProtocolValidationError(path, "expected an object");
|
|
13
|
+
}
|
|
14
|
+
return value;
|
|
15
|
+
}
|
|
16
|
+
function knownKeys(value, allowed, path) {
|
|
17
|
+
const allowedKeys = new Set(allowed);
|
|
18
|
+
for (const key of Object.keys(value)) {
|
|
19
|
+
if (!allowedKeys.has(key)) {
|
|
20
|
+
throw new AgentProtocolValidationError(`${path}.${key}`, "is not defined by this protocol version");
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function string(value, path) {
|
|
25
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
26
|
+
throw new AgentProtocolValidationError(path, "expected a non-empty string");
|
|
27
|
+
}
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
function optionalString(value, path) {
|
|
31
|
+
if (value !== undefined && typeof value !== "string") {
|
|
32
|
+
throw new AgentProtocolValidationError(path, "expected a string");
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
function boolean(value, path) {
|
|
36
|
+
if (typeof value !== "boolean") {
|
|
37
|
+
throw new AgentProtocolValidationError(path, "expected a boolean");
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function finiteNumber(value, path) {
|
|
41
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
42
|
+
throw new AgentProtocolValidationError(path, "expected a finite number");
|
|
43
|
+
}
|
|
44
|
+
return value;
|
|
45
|
+
}
|
|
46
|
+
function nonNegativeSafeInteger(value, path) {
|
|
47
|
+
if (!Number.isSafeInteger(value) || Number(value) < 0) {
|
|
48
|
+
throw new AgentProtocolValidationError(path, "expected a non-negative safe integer");
|
|
49
|
+
}
|
|
50
|
+
return Number(value);
|
|
51
|
+
}
|
|
52
|
+
function positiveSafeInteger(value, path) {
|
|
53
|
+
if (!Number.isSafeInteger(value) || Number(value) < 1) {
|
|
54
|
+
throw new AgentProtocolValidationError(path, "expected a positive safe integer");
|
|
55
|
+
}
|
|
56
|
+
return Number(value);
|
|
57
|
+
}
|
|
58
|
+
function timestamp(value, path) {
|
|
59
|
+
const parsed = string(value, path);
|
|
60
|
+
if (!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?(?:Z|[+-]\d{2}:\d{2})$/.test(parsed) ||
|
|
61
|
+
Number.isNaN(Date.parse(parsed))) {
|
|
62
|
+
throw new AgentProtocolValidationError(path, "expected an RFC 3339 timestamp");
|
|
63
|
+
}
|
|
64
|
+
return parsed;
|
|
65
|
+
}
|
|
66
|
+
function optionalTimestamp(value, path) {
|
|
67
|
+
if (value !== undefined)
|
|
68
|
+
timestamp(value, path);
|
|
69
|
+
}
|
|
70
|
+
function validateJsonValue(value, path, ancestors = new Set(), depth = 0) {
|
|
71
|
+
if (depth > 64) {
|
|
72
|
+
throw new AgentProtocolValidationError(path, "exceeded maximum JSON depth");
|
|
73
|
+
}
|
|
74
|
+
if (value === null ||
|
|
75
|
+
typeof value === "string" ||
|
|
76
|
+
typeof value === "boolean") {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
if (typeof value === "number") {
|
|
80
|
+
finiteNumber(value, path);
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (typeof value !== "object") {
|
|
84
|
+
throw new AgentProtocolValidationError(path, "expected a JSON value");
|
|
85
|
+
}
|
|
86
|
+
if (ancestors.has(value)) {
|
|
87
|
+
throw new AgentProtocolValidationError(path, "must not contain cycles");
|
|
88
|
+
}
|
|
89
|
+
if (!Array.isArray(value) &&
|
|
90
|
+
Object.prototype.toString.call(value) !== "[object Object]") {
|
|
91
|
+
throw new AgentProtocolValidationError(path, "expected a plain JSON object");
|
|
92
|
+
}
|
|
93
|
+
ancestors.add(value);
|
|
94
|
+
if (Array.isArray(value)) {
|
|
95
|
+
value.forEach((entry, index) => validateJsonValue(entry, `${path}[${index}]`, ancestors, depth + 1));
|
|
96
|
+
}
|
|
97
|
+
else {
|
|
98
|
+
for (const [key, entry] of Object.entries(value)) {
|
|
99
|
+
validateJsonValue(entry, `${path}.${key}`, ancestors, depth + 1);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
ancestors.delete(value);
|
|
103
|
+
}
|
|
104
|
+
function validateProtocolReference(value, path) {
|
|
105
|
+
const reference = record(value, path);
|
|
106
|
+
string(reference.id, `${path}.id`);
|
|
107
|
+
optionalString(reference.kind, `${path}.kind`);
|
|
108
|
+
optionalString(reference.label, `${path}.label`);
|
|
109
|
+
optionalString(reference.uri, `${path}.uri`);
|
|
110
|
+
}
|
|
111
|
+
export function parseAgentProtocolMetadata(value, path = "metadata") {
|
|
112
|
+
const metadata = record(value, path);
|
|
113
|
+
validateJsonValue(metadata, path);
|
|
114
|
+
if (metadata.actor !== undefined) {
|
|
115
|
+
validateProtocolReference(metadata.actor, `${path}.actor`);
|
|
116
|
+
}
|
|
117
|
+
if (metadata.workspace !== undefined) {
|
|
118
|
+
validateProtocolReference(metadata.workspace, `${path}.workspace`);
|
|
119
|
+
}
|
|
120
|
+
if (metadata.access !== undefined) {
|
|
121
|
+
array(metadata.access, `${path}.access`).forEach((reference, index) => validateProtocolReference(reference, `${path}.access[${index}]`));
|
|
122
|
+
}
|
|
123
|
+
if (metadata.audit !== undefined) {
|
|
124
|
+
validateProtocolReference(metadata.audit, `${path}.audit`);
|
|
125
|
+
}
|
|
126
|
+
if (metadata.trace !== undefined) {
|
|
127
|
+
const trace = record(metadata.trace, `${path}.trace`);
|
|
128
|
+
string(trace.traceId, `${path}.trace.traceId`);
|
|
129
|
+
optionalString(trace.spanId, `${path}.trace.spanId`);
|
|
130
|
+
optionalString(trace.parentSpanId, `${path}.trace.parentSpanId`);
|
|
131
|
+
optionalString(trace.traceState, `${path}.trace.traceState`);
|
|
132
|
+
}
|
|
133
|
+
if (metadata.context !== undefined) {
|
|
134
|
+
array(metadata.context, `${path}.context`).forEach((reference, index) => validateProtocolReference(reference, `${path}.context[${index}]`));
|
|
135
|
+
}
|
|
136
|
+
return value;
|
|
137
|
+
}
|
|
138
|
+
function optionalMetadata(value, path) {
|
|
139
|
+
if (value !== undefined)
|
|
140
|
+
parseAgentProtocolMetadata(value, path);
|
|
141
|
+
}
|
|
142
|
+
function validateObjectReference(value, path) {
|
|
143
|
+
const object = record(value, path);
|
|
144
|
+
string(object.id, `${path}.id`);
|
|
145
|
+
string(object.kind, `${path}.kind`);
|
|
146
|
+
string(object.label, `${path}.label`);
|
|
147
|
+
optionalString(object.uri, `${path}.uri`);
|
|
148
|
+
optionalMetadata(object.metadata, `${path}.metadata`);
|
|
149
|
+
}
|
|
150
|
+
export function parseAgentObjectReference(value, path = "objectReference") {
|
|
151
|
+
validateObjectReference(value, path);
|
|
152
|
+
return value;
|
|
153
|
+
}
|
|
154
|
+
function array(value, path) {
|
|
155
|
+
if (!Array.isArray(value)) {
|
|
156
|
+
throw new AgentProtocolValidationError(path, "expected an array");
|
|
157
|
+
}
|
|
158
|
+
return value;
|
|
159
|
+
}
|
|
160
|
+
function identifierFields(value, path) {
|
|
161
|
+
string(value.id, `${path}.id`);
|
|
162
|
+
string(value.threadId, `${path}.threadId`);
|
|
163
|
+
string(value.runId, `${path}.runId`);
|
|
164
|
+
}
|
|
165
|
+
function validateAnnotation(value, path) {
|
|
166
|
+
const annotation = record(value, path);
|
|
167
|
+
string(annotation.id, `${path}.id`);
|
|
168
|
+
string(annotation.kind, `${path}.kind`);
|
|
169
|
+
string(annotation.label, `${path}.label`);
|
|
170
|
+
optionalString(annotation.url, `${path}.url`);
|
|
171
|
+
if (annotation.start !== undefined) {
|
|
172
|
+
nonNegativeSafeInteger(annotation.start, `${path}.start`);
|
|
173
|
+
}
|
|
174
|
+
if (annotation.end !== undefined) {
|
|
175
|
+
nonNegativeSafeInteger(annotation.end, `${path}.end`);
|
|
176
|
+
}
|
|
177
|
+
if (annotation.start !== undefined &&
|
|
178
|
+
annotation.end !== undefined &&
|
|
179
|
+
Number(annotation.start) > Number(annotation.end)) {
|
|
180
|
+
throw new AgentProtocolValidationError(path, "annotation start must not exceed end");
|
|
181
|
+
}
|
|
182
|
+
optionalMetadata(annotation.metadata, `${path}.metadata`);
|
|
183
|
+
}
|
|
184
|
+
export function parseAgentAnnotation(value, path = "annotation") {
|
|
185
|
+
validateAnnotation(value, path);
|
|
186
|
+
return value;
|
|
187
|
+
}
|
|
188
|
+
export function parseAgentWidget(value, path = "widget") {
|
|
189
|
+
const widget = record(value, path);
|
|
190
|
+
string(widget.id, `${path}.id`);
|
|
191
|
+
string(widget.kind, `${path}.kind`);
|
|
192
|
+
if (!("data" in widget)) {
|
|
193
|
+
throw new AgentProtocolValidationError(`${path}.data`, "is required");
|
|
194
|
+
}
|
|
195
|
+
validateJsonValue(widget.data, `${path}.data`);
|
|
196
|
+
optionalString(widget.title, `${path}.title`);
|
|
197
|
+
if (widget.actions !== undefined) {
|
|
198
|
+
array(widget.actions, `${path}.actions`).forEach((value, index) => {
|
|
199
|
+
const action = record(value, `${path}.actions[${index}]`);
|
|
200
|
+
string(action.id, `${path}.actions[${index}].id`);
|
|
201
|
+
string(action.label, `${path}.actions[${index}].label`);
|
|
202
|
+
optionalString(action.action, `${path}.actions[${index}].action`);
|
|
203
|
+
if (action.kind !== undefined &&
|
|
204
|
+
!new Set(["primary", "secondary", "danger"]).has(String(action.kind))) {
|
|
205
|
+
throw new AgentProtocolValidationError(`${path}.actions[${index}].kind`, "unsupported widget action kind");
|
|
206
|
+
}
|
|
207
|
+
if (action.payload !== undefined) {
|
|
208
|
+
validateJsonValue(action.payload, `${path}.actions[${index}].payload`);
|
|
209
|
+
}
|
|
210
|
+
if (action.disabled !== undefined) {
|
|
211
|
+
boolean(action.disabled, `${path}.actions[${index}].disabled`);
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
if (widget.state !== undefined &&
|
|
216
|
+
!new Set(["active", "submitted", "dismissed", "expired"]).has(String(widget.state))) {
|
|
217
|
+
throw new AgentProtocolValidationError(`${path}.state`, "unsupported widget state");
|
|
218
|
+
}
|
|
219
|
+
optionalMetadata(widget.metadata, `${path}.metadata`);
|
|
220
|
+
return value;
|
|
221
|
+
}
|
|
222
|
+
function validateMessagePart(value, path) {
|
|
223
|
+
const part = record(value, path);
|
|
224
|
+
const type = string(part.type, `${path}.type`);
|
|
225
|
+
switch (type) {
|
|
226
|
+
case "text":
|
|
227
|
+
if (typeof part.text !== "string") {
|
|
228
|
+
throw new AgentProtocolValidationError(`${path}.text`, "expected a string");
|
|
229
|
+
}
|
|
230
|
+
if (part.format !== undefined &&
|
|
231
|
+
part.format !== "plain" &&
|
|
232
|
+
part.format !== "markdown") {
|
|
233
|
+
throw new AgentProtocolValidationError(`${path}.format`, "expected plain or markdown");
|
|
234
|
+
}
|
|
235
|
+
return;
|
|
236
|
+
case "reasoning":
|
|
237
|
+
if (typeof part.text !== "string") {
|
|
238
|
+
throw new AgentProtocolValidationError(`${path}.text`, "expected a string");
|
|
239
|
+
}
|
|
240
|
+
optionalString(part.label, `${path}.label`);
|
|
241
|
+
if (part.visibility !== undefined &&
|
|
242
|
+
!new Set(["visible", "summary", "hidden"]).has(String(part.visibility))) {
|
|
243
|
+
throw new AgentProtocolValidationError(`${path}.visibility`, "unsupported reasoning visibility");
|
|
244
|
+
}
|
|
245
|
+
return;
|
|
246
|
+
case "citation":
|
|
247
|
+
string(part.title, `${path}.title`);
|
|
248
|
+
optionalString(part.url, `${path}.url`);
|
|
249
|
+
optionalString(part.sourceId, `${path}.sourceId`);
|
|
250
|
+
return;
|
|
251
|
+
case "annotation": {
|
|
252
|
+
validateAnnotation(part.annotation, `${path}.annotation`);
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
case "file":
|
|
256
|
+
string(part.name, `${path}.name`);
|
|
257
|
+
optionalString(part.url, `${path}.url`);
|
|
258
|
+
optionalString(part.fileId, `${path}.fileId`);
|
|
259
|
+
optionalString(part.mediaType, `${path}.mediaType`);
|
|
260
|
+
if (part.url === undefined && part.fileId === undefined) {
|
|
261
|
+
throw new AgentProtocolValidationError(path, "a file part requires either url or fileId");
|
|
262
|
+
}
|
|
263
|
+
return;
|
|
264
|
+
case "widget": {
|
|
265
|
+
parseAgentWidget(part.widget, `${path}.widget`);
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
case "data":
|
|
269
|
+
if (!("data" in part)) {
|
|
270
|
+
throw new AgentProtocolValidationError(`${path}.data`, "is required");
|
|
271
|
+
}
|
|
272
|
+
validateJsonValue(part.data, `${path}.data`);
|
|
273
|
+
optionalString(part.mediaType, `${path}.mediaType`);
|
|
274
|
+
optionalString(part.title, `${path}.title`);
|
|
275
|
+
return;
|
|
276
|
+
default:
|
|
277
|
+
if (type.startsWith("x-") && type.length > 2) {
|
|
278
|
+
validateJsonValue(part, path);
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
throw new AgentProtocolValidationError(`${path}.type`, `unsupported message part type ${JSON.stringify(type)}`);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
export function parseAgentMessage(value, path = "message") {
|
|
285
|
+
const message = record(value, path);
|
|
286
|
+
string(message.id, `${path}.id`);
|
|
287
|
+
const role = string(message.role, `${path}.role`);
|
|
288
|
+
if (!new Set(["user", "assistant", "system", "tool"]).has(role)) {
|
|
289
|
+
throw new AgentProtocolValidationError(`${path}.role`, `unsupported role ${JSON.stringify(role)}`);
|
|
290
|
+
}
|
|
291
|
+
array(message.parts, `${path}.parts`).forEach((part, index) => validateMessagePart(part, `${path}.parts[${index}]`));
|
|
292
|
+
optionalTimestamp(message.createdAt, `${path}.createdAt`);
|
|
293
|
+
if (message.status !== undefined &&
|
|
294
|
+
!new Set(["streaming", "complete", "error"]).has(String(message.status))) {
|
|
295
|
+
throw new AgentProtocolValidationError(`${path}.status`, "unsupported message status");
|
|
296
|
+
}
|
|
297
|
+
optionalMetadata(message.metadata, `${path}.metadata`);
|
|
298
|
+
return value;
|
|
299
|
+
}
|
|
300
|
+
export function parseFilePart(value, path = "file") {
|
|
301
|
+
validateMessagePart(value, path);
|
|
302
|
+
if (record(value, path).type !== "file") {
|
|
303
|
+
throw new AgentProtocolValidationError(`${path}.type`, "expected file");
|
|
304
|
+
}
|
|
305
|
+
return value;
|
|
306
|
+
}
|
|
307
|
+
export function parseAgentThread(value, path = "thread") {
|
|
308
|
+
const thread = record(value, path);
|
|
309
|
+
string(thread.id, `${path}.id`);
|
|
310
|
+
optionalString(thread.title, `${path}.title`);
|
|
311
|
+
timestamp(thread.createdAt, `${path}.createdAt`);
|
|
312
|
+
timestamp(thread.updatedAt, `${path}.updatedAt`);
|
|
313
|
+
if (thread.status !== undefined &&
|
|
314
|
+
!new Set(["active", "archived", "deleted"]).has(String(thread.status))) {
|
|
315
|
+
throw new AgentProtocolValidationError(`${path}.status`, "unsupported thread status");
|
|
316
|
+
}
|
|
317
|
+
optionalMetadata(thread.metadata, `${path}.metadata`);
|
|
318
|
+
return value;
|
|
319
|
+
}
|
|
320
|
+
export function parseNullableAgentThread(value, path = "thread") {
|
|
321
|
+
return value === null ? null : parseAgentThread(value, path);
|
|
322
|
+
}
|
|
323
|
+
export function parseAgentQueuedMessage(value, path = "queuedMessage") {
|
|
324
|
+
const message = record(value, path);
|
|
325
|
+
string(message.id, `${path}.id`);
|
|
326
|
+
string(message.threadId, `${path}.threadId`);
|
|
327
|
+
if (typeof message.text !== "string") {
|
|
328
|
+
throw new AgentProtocolValidationError(`${path}.text`, "expected a string");
|
|
329
|
+
}
|
|
330
|
+
timestamp(message.createdAt, `${path}.createdAt`);
|
|
331
|
+
if (message.attachments !== undefined) {
|
|
332
|
+
array(message.attachments, `${path}.attachments`).forEach((attachment, index) => parseFilePart(attachment, `${path}.attachments[${index}]`));
|
|
333
|
+
}
|
|
334
|
+
optionalMetadata(message.metadata, `${path}.metadata`);
|
|
335
|
+
return value;
|
|
336
|
+
}
|
|
337
|
+
export function parseAgentQueuedMessages(value, path = "queuedMessages") {
|
|
338
|
+
return array(value, path).map((message, index) => parseAgentQueuedMessage(message, `${path}[${index}]`));
|
|
339
|
+
}
|
|
340
|
+
const KNOWN_CAPABILITY_IDS = new Set([
|
|
341
|
+
"actions",
|
|
342
|
+
"activities",
|
|
343
|
+
"approvals",
|
|
344
|
+
"artifacts",
|
|
345
|
+
"attachments",
|
|
346
|
+
"citations",
|
|
347
|
+
"clientEffects",
|
|
348
|
+
"codeExecution",
|
|
349
|
+
"connectionRequests",
|
|
350
|
+
"durableThreadSnapshots",
|
|
351
|
+
"feedback",
|
|
352
|
+
"messageQueue",
|
|
353
|
+
"modelSelection",
|
|
354
|
+
"multiAgentActivity",
|
|
355
|
+
"reasoning",
|
|
356
|
+
"resumableRuns",
|
|
357
|
+
"smartObjects",
|
|
358
|
+
"suggestions",
|
|
359
|
+
"taskGroups",
|
|
360
|
+
"threadForking",
|
|
361
|
+
"threadHistory",
|
|
362
|
+
"toolSelection",
|
|
363
|
+
"uploads",
|
|
364
|
+
"widgets",
|
|
365
|
+
]);
|
|
366
|
+
function capabilityId(value, path) {
|
|
367
|
+
const id = string(value, path);
|
|
368
|
+
if (!KNOWN_CAPABILITY_IDS.has(id) &&
|
|
369
|
+
!(id.startsWith("x-") && id.length > 2)) {
|
|
370
|
+
throw new AgentProtocolValidationError(path, "unknown capabilities must use an x- namespace");
|
|
371
|
+
}
|
|
372
|
+
return id;
|
|
373
|
+
}
|
|
374
|
+
export function parseAgentError(value, path = "error") {
|
|
375
|
+
const error = record(value, path);
|
|
376
|
+
const code = string(error.code, `${path}.code`);
|
|
377
|
+
string(error.message, `${path}.message`);
|
|
378
|
+
if (error.retryable !== undefined) {
|
|
379
|
+
boolean(error.retryable, `${path}.retryable`);
|
|
380
|
+
}
|
|
381
|
+
optionalString(error.correlationId, `${path}.correlationId`);
|
|
382
|
+
if (error.details !== undefined) {
|
|
383
|
+
validateJsonValue(error.details, `${path}.details`);
|
|
384
|
+
}
|
|
385
|
+
optionalMetadata(error.metadata, `${path}.metadata`);
|
|
386
|
+
if (code === "capability_unsupported" || code === "capability_unavailable") {
|
|
387
|
+
capabilityId(error.capability, `${path}.capability`);
|
|
388
|
+
if (typeof error.retryable !== "boolean") {
|
|
389
|
+
throw new AgentProtocolValidationError(`${path}.retryable`, "is required for capability errors");
|
|
390
|
+
}
|
|
391
|
+
if (code === "capability_unsupported" && error.retryable !== false) {
|
|
392
|
+
throw new AgentProtocolValidationError(`${path}.retryable`, "unsupported capabilities are not retryable");
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
if (code === "operation_unsupported") {
|
|
396
|
+
string(error.operation, `${path}.operation`);
|
|
397
|
+
if (error.retryable !== false) {
|
|
398
|
+
throw new AgentProtocolValidationError(`${path}.retryable`, "unsupported operations are not retryable");
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
if (code === "protocol_version_unsupported") {
|
|
402
|
+
const supportedVersions = array(error.supportedVersions, `${path}.supportedVersions`);
|
|
403
|
+
supportedVersions.forEach((version, index) => {
|
|
404
|
+
positiveSafeInteger(version, `${path}.supportedVersions[${index}]`);
|
|
405
|
+
if (!isAgentKitProtocolVersion(version)) {
|
|
406
|
+
throw new AgentProtocolValidationError(`${path}.supportedVersions[${index}]`, "is not supported by this package");
|
|
407
|
+
}
|
|
408
|
+
});
|
|
409
|
+
array(error.receivedVersions, `${path}.receivedVersions`).forEach((version, index) => positiveSafeInteger(version, `${path}.receivedVersions[${index}]`));
|
|
410
|
+
if (error.retryable !== false) {
|
|
411
|
+
throw new AgentProtocolValidationError(`${path}.retryable`, "protocol incompatibility is not retryable");
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
return value;
|
|
415
|
+
}
|
|
416
|
+
export function isAgentProtocolError(value) {
|
|
417
|
+
try {
|
|
418
|
+
parseAgentError(value);
|
|
419
|
+
return true;
|
|
420
|
+
}
|
|
421
|
+
catch (error) {
|
|
422
|
+
if (error instanceof AgentProtocolValidationError)
|
|
423
|
+
return false;
|
|
424
|
+
throw error;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
function validateUsage(value, path) {
|
|
428
|
+
const usage = record(value, path);
|
|
429
|
+
for (const key of ["inputTokens", "outputTokens", "totalTokens"]) {
|
|
430
|
+
if (usage[key] !== undefined) {
|
|
431
|
+
nonNegativeSafeInteger(usage[key], `${path}.${key}`);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
if (usage.cost !== undefined &&
|
|
435
|
+
finiteNumber(usage.cost, `${path}.cost`) < 0) {
|
|
436
|
+
throw new AgentProtocolValidationError(`${path}.cost`, "must not be negative");
|
|
437
|
+
}
|
|
438
|
+
optionalString(usage.currency, `${path}.currency`);
|
|
439
|
+
}
|
|
440
|
+
export function parseAgentUsage(value, path = "usage") {
|
|
441
|
+
validateUsage(value, path);
|
|
442
|
+
return value;
|
|
443
|
+
}
|
|
444
|
+
export function parseAgentToolCall(value, path = "toolCall") {
|
|
445
|
+
const toolCall = record(value, path);
|
|
446
|
+
string(toolCall.id, `${path}.id`);
|
|
447
|
+
string(toolCall.name, `${path}.name`);
|
|
448
|
+
if (toolCall.input !== undefined) {
|
|
449
|
+
validateJsonValue(toolCall.input, `${path}.input`);
|
|
450
|
+
}
|
|
451
|
+
if (toolCall.output !== undefined) {
|
|
452
|
+
validateJsonValue(toolCall.output, `${path}.output`);
|
|
453
|
+
}
|
|
454
|
+
const status = string(toolCall.status, `${path}.status`);
|
|
455
|
+
if (!new Set(["running", "completed", "failed", "cancelled"]).has(status)) {
|
|
456
|
+
throw new AgentProtocolValidationError(`${path}.status`, "unsupported tool status");
|
|
457
|
+
}
|
|
458
|
+
if (toolCall.error !== undefined) {
|
|
459
|
+
parseAgentError(toolCall.error, `${path}.error`);
|
|
460
|
+
}
|
|
461
|
+
optionalString(toolCall.runId, `${path}.runId`);
|
|
462
|
+
optionalString(toolCall.messageId, `${path}.messageId`);
|
|
463
|
+
optionalString(toolCall.agentId, `${path}.agentId`);
|
|
464
|
+
optionalMetadata(toolCall.metadata, `${path}.metadata`);
|
|
465
|
+
return value;
|
|
466
|
+
}
|
|
467
|
+
export function parseAgentParticipant(value, path = "agent") {
|
|
468
|
+
const agent = record(value, path);
|
|
469
|
+
string(agent.id, `${path}.id`);
|
|
470
|
+
string(agent.name, `${path}.name`);
|
|
471
|
+
const status = string(agent.status, `${path}.status`);
|
|
472
|
+
if (!new Set([
|
|
473
|
+
"idle",
|
|
474
|
+
"working",
|
|
475
|
+
"waiting",
|
|
476
|
+
"paused",
|
|
477
|
+
"completed",
|
|
478
|
+
"failed",
|
|
479
|
+
"closed",
|
|
480
|
+
]).has(status)) {
|
|
481
|
+
throw new AgentProtocolValidationError(`${path}.status`, "unsupported participant status");
|
|
482
|
+
}
|
|
483
|
+
optionalString(agent.kind, `${path}.kind`);
|
|
484
|
+
optionalString(agent.parentAgentId, `${path}.parentAgentId`);
|
|
485
|
+
optionalString(agent.activeTaskId, `${path}.activeTaskId`);
|
|
486
|
+
optionalString(agent.description, `${path}.description`);
|
|
487
|
+
optionalString(agent.avatarUrl, `${path}.avatarUrl`);
|
|
488
|
+
if (agent.origin !== undefined) {
|
|
489
|
+
validateObjectReference(agent.origin, `${path}.origin`);
|
|
490
|
+
}
|
|
491
|
+
optionalTimestamp(agent.startedAt, `${path}.startedAt`);
|
|
492
|
+
optionalTimestamp(agent.updatedAt, `${path}.updatedAt`);
|
|
493
|
+
optionalTimestamp(agent.completedAt, `${path}.completedAt`);
|
|
494
|
+
optionalMetadata(agent.metadata, `${path}.metadata`);
|
|
495
|
+
return value;
|
|
496
|
+
}
|
|
497
|
+
function validateWorkScope(value, path) {
|
|
498
|
+
if (value !== undefined &&
|
|
499
|
+
!new Set(["thread", "workspace", "external"]).has(String(value))) {
|
|
500
|
+
throw new AgentProtocolValidationError(path, "unsupported work scope");
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
export function parseAgentInteraction(value, path = "interaction") {
|
|
504
|
+
const interaction = record(value, path);
|
|
505
|
+
string(interaction.id, `${path}.id`);
|
|
506
|
+
string(interaction.kind, `${path}.kind`);
|
|
507
|
+
string(interaction.agentId, `${path}.agentId`);
|
|
508
|
+
optionalString(interaction.targetAgentId, `${path}.targetAgentId`);
|
|
509
|
+
optionalString(interaction.label, `${path}.label`);
|
|
510
|
+
optionalString(interaction.detail, `${path}.detail`);
|
|
511
|
+
validateWorkScope(interaction.scope, `${path}.scope`);
|
|
512
|
+
if (interaction.object !== undefined) {
|
|
513
|
+
validateObjectReference(interaction.object, `${path}.object`);
|
|
514
|
+
}
|
|
515
|
+
if (interaction.source !== undefined) {
|
|
516
|
+
validateObjectReference(interaction.source, `${path}.source`);
|
|
517
|
+
}
|
|
518
|
+
optionalTimestamp(interaction.occurredAt, `${path}.occurredAt`);
|
|
519
|
+
optionalMetadata(interaction.metadata, `${path}.metadata`);
|
|
520
|
+
return value;
|
|
521
|
+
}
|
|
522
|
+
export function parseAgentActivity(value, path = "activity") {
|
|
523
|
+
const activity = record(value, path);
|
|
524
|
+
string(activity.id, `${path}.id`);
|
|
525
|
+
string(activity.kind, `${path}.kind`);
|
|
526
|
+
string(activity.label, `${path}.label`);
|
|
527
|
+
optionalString(activity.detail, `${path}.detail`);
|
|
528
|
+
const status = string(activity.status, `${path}.status`);
|
|
529
|
+
if (!new Set(["running", "completed", "failed", "cancelled"]).has(status)) {
|
|
530
|
+
throw new AgentProtocolValidationError(`${path}.status`, "unsupported activity status");
|
|
531
|
+
}
|
|
532
|
+
optionalString(activity.agentId, `${path}.agentId`);
|
|
533
|
+
optionalString(activity.runId, `${path}.runId`);
|
|
534
|
+
validateWorkScope(activity.scope, `${path}.scope`);
|
|
535
|
+
if (activity.object !== undefined) {
|
|
536
|
+
validateObjectReference(activity.object, `${path}.object`);
|
|
537
|
+
}
|
|
538
|
+
if (activity.source !== undefined) {
|
|
539
|
+
validateObjectReference(activity.source, `${path}.source`);
|
|
540
|
+
}
|
|
541
|
+
if (activity.summary !== undefined) {
|
|
542
|
+
array(activity.summary, `${path}.summary`).forEach((part, index) => validateMessagePart(part, `${path}.summary[${index}]`));
|
|
543
|
+
}
|
|
544
|
+
optionalTimestamp(activity.startedAt, `${path}.startedAt`);
|
|
545
|
+
optionalTimestamp(activity.completedAt, `${path}.completedAt`);
|
|
546
|
+
optionalMetadata(activity.metadata, `${path}.metadata`);
|
|
547
|
+
return value;
|
|
548
|
+
}
|
|
549
|
+
export function parseAgentTask(value, path = "task") {
|
|
550
|
+
const task = record(value, path);
|
|
551
|
+
string(task.id, `${path}.id`);
|
|
552
|
+
string(task.title, `${path}.title`);
|
|
553
|
+
const status = string(task.status, `${path}.status`);
|
|
554
|
+
if (!new Set([
|
|
555
|
+
"pending",
|
|
556
|
+
"running",
|
|
557
|
+
"awaiting_input",
|
|
558
|
+
"completed",
|
|
559
|
+
"failed",
|
|
560
|
+
"cancelled",
|
|
561
|
+
]).has(status)) {
|
|
562
|
+
throw new AgentProtocolValidationError(`${path}.status`, "unsupported task status");
|
|
563
|
+
}
|
|
564
|
+
optionalString(task.kind, `${path}.kind`);
|
|
565
|
+
optionalString(task.parentTaskId, `${path}.parentTaskId`);
|
|
566
|
+
optionalString(task.assignedAgentId, `${path}.assignedAgentId`);
|
|
567
|
+
optionalString(task.runId, `${path}.runId`);
|
|
568
|
+
optionalString(task.detail, `${path}.detail`);
|
|
569
|
+
if (task.progress !== undefined) {
|
|
570
|
+
const progress = record(task.progress, `${path}.progress`);
|
|
571
|
+
const completed = nonNegativeSafeInteger(progress.completed, `${path}.progress.completed`);
|
|
572
|
+
const total = nonNegativeSafeInteger(progress.total, `${path}.progress.total`);
|
|
573
|
+
if (completed > total) {
|
|
574
|
+
throw new AgentProtocolValidationError(`${path}.progress`, "completed and total must be non-negative integers with completed no greater than total");
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
if (task.object !== undefined) {
|
|
578
|
+
validateObjectReference(task.object, `${path}.object`);
|
|
579
|
+
}
|
|
580
|
+
if (task.source !== undefined) {
|
|
581
|
+
validateObjectReference(task.source, `${path}.source`);
|
|
582
|
+
}
|
|
583
|
+
if (task.summary !== undefined) {
|
|
584
|
+
array(task.summary, `${path}.summary`).forEach((part, index) => validateMessagePart(part, `${path}.summary[${index}]`));
|
|
585
|
+
}
|
|
586
|
+
optionalTimestamp(task.createdAt, `${path}.createdAt`);
|
|
587
|
+
optionalTimestamp(task.updatedAt, `${path}.updatedAt`);
|
|
588
|
+
optionalTimestamp(task.completedAt, `${path}.completedAt`);
|
|
589
|
+
optionalMetadata(task.metadata, `${path}.metadata`);
|
|
590
|
+
return value;
|
|
591
|
+
}
|
|
592
|
+
export function parseAgentTaskGroup(value, path = "taskGroup") {
|
|
593
|
+
const taskGroup = record(value, path);
|
|
594
|
+
string(taskGroup.id, `${path}.id`);
|
|
595
|
+
const taskIds = new Set();
|
|
596
|
+
array(taskGroup.taskIds, `${path}.taskIds`).forEach((taskId, index) => {
|
|
597
|
+
const parsed = string(taskId, `${path}.taskIds[${index}]`);
|
|
598
|
+
if (taskIds.has(parsed)) {
|
|
599
|
+
throw new AgentProtocolValidationError(`${path}.taskIds[${index}]`, "must be unique within the task group");
|
|
600
|
+
}
|
|
601
|
+
taskIds.add(parsed);
|
|
602
|
+
});
|
|
603
|
+
optionalString(taskGroup.title, `${path}.title`);
|
|
604
|
+
if (taskGroup.status !== undefined) {
|
|
605
|
+
const status = string(taskGroup.status, `${path}.status`);
|
|
606
|
+
if (!new Set([
|
|
607
|
+
"pending",
|
|
608
|
+
"running",
|
|
609
|
+
"awaiting_input",
|
|
610
|
+
"completed",
|
|
611
|
+
"failed",
|
|
612
|
+
"cancelled",
|
|
613
|
+
]).has(status)) {
|
|
614
|
+
throw new AgentProtocolValidationError(`${path}.status`, "unsupported task group status");
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
optionalString(taskGroup.runId, `${path}.runId`);
|
|
618
|
+
if (taskGroup.object !== undefined) {
|
|
619
|
+
validateObjectReference(taskGroup.object, `${path}.object`);
|
|
620
|
+
}
|
|
621
|
+
if (taskGroup.source !== undefined) {
|
|
622
|
+
validateObjectReference(taskGroup.source, `${path}.source`);
|
|
623
|
+
}
|
|
624
|
+
optionalTimestamp(taskGroup.createdAt, `${path}.createdAt`);
|
|
625
|
+
optionalTimestamp(taskGroup.updatedAt, `${path}.updatedAt`);
|
|
626
|
+
optionalTimestamp(taskGroup.completedAt, `${path}.completedAt`);
|
|
627
|
+
optionalMetadata(taskGroup.metadata, `${path}.metadata`);
|
|
628
|
+
return value;
|
|
629
|
+
}
|
|
630
|
+
export function parseAgentApprovalRequest(value, path = "approval") {
|
|
631
|
+
const request = record(value, path);
|
|
632
|
+
string(request.id, `${path}.id`);
|
|
633
|
+
string(request.title, `${path}.title`);
|
|
634
|
+
optionalString(request.description, `${path}.description`);
|
|
635
|
+
if (request.kind !== undefined &&
|
|
636
|
+
!new Set(["approval", "choice", "input"]).has(String(request.kind))) {
|
|
637
|
+
throw new AgentProtocolValidationError(`${path}.kind`, "unsupported approval kind");
|
|
638
|
+
}
|
|
639
|
+
if (request.allowMultiple !== undefined) {
|
|
640
|
+
boolean(request.allowMultiple, `${path}.allowMultiple`);
|
|
641
|
+
}
|
|
642
|
+
if (request.allowOther !== undefined) {
|
|
643
|
+
boolean(request.allowOther, `${path}.allowOther`);
|
|
644
|
+
}
|
|
645
|
+
if (request.options !== undefined) {
|
|
646
|
+
const seen = new Set();
|
|
647
|
+
array(request.options, `${path}.options`).forEach((value, index) => {
|
|
648
|
+
const option = record(value, `${path}.options[${index}]`);
|
|
649
|
+
const id = string(option.id, `${path}.options[${index}].id`);
|
|
650
|
+
if (seen.has(id)) {
|
|
651
|
+
throw new AgentProtocolValidationError(`${path}.options[${index}].id`, "must be unique");
|
|
652
|
+
}
|
|
653
|
+
seen.add(id);
|
|
654
|
+
string(option.label, `${path}.options[${index}].label`);
|
|
655
|
+
optionalString(option.description, `${path}.options[${index}].description`);
|
|
656
|
+
if (option.kind !== undefined &&
|
|
657
|
+
!new Set(["primary", "secondary", "danger"]).has(String(option.kind))) {
|
|
658
|
+
throw new AgentProtocolValidationError(`${path}.options[${index}].kind`, "unsupported approval option kind");
|
|
659
|
+
}
|
|
660
|
+
});
|
|
661
|
+
}
|
|
662
|
+
if (request.input !== undefined) {
|
|
663
|
+
const input = record(request.input, `${path}.input`);
|
|
664
|
+
string(input.id, `${path}.input.id`);
|
|
665
|
+
optionalString(input.label, `${path}.input.label`);
|
|
666
|
+
optionalString(input.placeholder, `${path}.input.placeholder`);
|
|
667
|
+
if (input.type !== undefined &&
|
|
668
|
+
!new Set(["text", "number", "url"]).has(String(input.type))) {
|
|
669
|
+
throw new AgentProtocolValidationError(`${path}.input.type`, "unsupported input type");
|
|
670
|
+
}
|
|
671
|
+
if (input.required !== undefined) {
|
|
672
|
+
boolean(input.required, `${path}.input.required`);
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
optionalTimestamp(request.expiresAt, `${path}.expiresAt`);
|
|
676
|
+
optionalMetadata(request.metadata, `${path}.metadata`);
|
|
677
|
+
return value;
|
|
678
|
+
}
|
|
679
|
+
function validateApprovalResponse(value, path) {
|
|
680
|
+
const response = record(value, path);
|
|
681
|
+
const decision = string(response.decision, `${path}.decision`);
|
|
682
|
+
if (decision !== "approve" && decision !== "deny") {
|
|
683
|
+
throw new AgentProtocolValidationError(`${path}.decision`, 'expected "approve" or "deny"');
|
|
684
|
+
}
|
|
685
|
+
if (response.optionIds !== undefined) {
|
|
686
|
+
array(response.optionIds, `${path}.optionIds`).forEach((optionId, index) => string(optionId, `${path}.optionIds[${index}]`));
|
|
687
|
+
}
|
|
688
|
+
if (response.other !== undefined) {
|
|
689
|
+
string(response.other, `${path}.other`);
|
|
690
|
+
}
|
|
691
|
+
if (response.input !== undefined) {
|
|
692
|
+
record(response.input, `${path}.input`);
|
|
693
|
+
validateJsonValue(response.input, `${path}.input`);
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
export function parseAgentApprovalResponse(value, path = "approvalResponse") {
|
|
697
|
+
validateApprovalResponse(value, path);
|
|
698
|
+
return value;
|
|
699
|
+
}
|
|
700
|
+
export function parseAgentApprovalSnapshot(value, path = "approvalSnapshot") {
|
|
701
|
+
const snapshot = record(value, path);
|
|
702
|
+
parseAgentApprovalRequest(snapshot.request, `${path}.request`);
|
|
703
|
+
const status = string(snapshot.status, `${path}.status`);
|
|
704
|
+
if (!new Set(["pending", "approved", "denied", "expired", "cancelled"]).has(status)) {
|
|
705
|
+
throw new AgentProtocolValidationError(`${path}.status`, "unsupported approval snapshot status");
|
|
706
|
+
}
|
|
707
|
+
optionalString(snapshot.runId, `${path}.runId`);
|
|
708
|
+
if (status === "approved" || status === "denied") {
|
|
709
|
+
validateApprovalResponse(snapshot.response, `${path}.response`);
|
|
710
|
+
const response = record(snapshot.response, `${path}.response`);
|
|
711
|
+
const expectedDecision = status === "approved" ? "approve" : "deny";
|
|
712
|
+
if (response.decision !== expectedDecision) {
|
|
713
|
+
throw new AgentProtocolValidationError(`${path}.response.decision`, `must be ${expectedDecision} when status is ${status}`);
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
else if (snapshot.response !== undefined) {
|
|
717
|
+
validateApprovalResponse(snapshot.response, `${path}.response`);
|
|
718
|
+
}
|
|
719
|
+
optionalTimestamp(snapshot.resolvedAt, `${path}.resolvedAt`);
|
|
720
|
+
optionalMetadata(snapshot.metadata, `${path}.metadata`);
|
|
721
|
+
return value;
|
|
722
|
+
}
|
|
723
|
+
export function parseAgentConnectionRequest(value, path = "connectionRequest") {
|
|
724
|
+
const request = record(value, path);
|
|
725
|
+
knownKeys(request, [
|
|
726
|
+
"id",
|
|
727
|
+
"provider",
|
|
728
|
+
"reason",
|
|
729
|
+
"status",
|
|
730
|
+
"appId",
|
|
731
|
+
"detail",
|
|
732
|
+
"source",
|
|
733
|
+
"createdAt",
|
|
734
|
+
"updatedAt",
|
|
735
|
+
"metadata",
|
|
736
|
+
], path);
|
|
737
|
+
string(request.id, `${path}.id`);
|
|
738
|
+
string(request.provider, `${path}.provider`);
|
|
739
|
+
const reason = string(request.reason, `${path}.reason`);
|
|
740
|
+
if (!new Set(["connect", "grant", "reauthorize", "admin_required"]).has(reason)) {
|
|
741
|
+
throw new AgentProtocolValidationError(`${path}.reason`, "unsupported connection request reason");
|
|
742
|
+
}
|
|
743
|
+
const status = string(request.status, `${path}.status`);
|
|
744
|
+
if (!new Set([
|
|
745
|
+
"requested",
|
|
746
|
+
"connecting",
|
|
747
|
+
"connected",
|
|
748
|
+
"declined",
|
|
749
|
+
"failed",
|
|
750
|
+
]).has(status)) {
|
|
751
|
+
throw new AgentProtocolValidationError(`${path}.status`, "unsupported connection request status");
|
|
752
|
+
}
|
|
753
|
+
optionalString(request.appId, `${path}.appId`);
|
|
754
|
+
optionalString(request.detail, `${path}.detail`);
|
|
755
|
+
if (request.source !== undefined) {
|
|
756
|
+
validateProtocolReference(request.source, `${path}.source`);
|
|
757
|
+
}
|
|
758
|
+
optionalTimestamp(request.createdAt, `${path}.createdAt`);
|
|
759
|
+
optionalTimestamp(request.updatedAt, `${path}.updatedAt`);
|
|
760
|
+
optionalMetadata(request.metadata, `${path}.metadata`);
|
|
761
|
+
return value;
|
|
762
|
+
}
|
|
763
|
+
export function parseAgentConnectionResponse(value, path = "connectionResponse") {
|
|
764
|
+
const response = record(value, path);
|
|
765
|
+
knownKeys(response, ["status", "connectionId", "message"], path);
|
|
766
|
+
const status = string(response.status, `${path}.status`);
|
|
767
|
+
if (!new Set(["connected", "declined", "failed"]).has(status)) {
|
|
768
|
+
throw new AgentProtocolValidationError(`${path}.status`, "unsupported connection response status");
|
|
769
|
+
}
|
|
770
|
+
optionalString(response.connectionId, `${path}.connectionId`);
|
|
771
|
+
optionalString(response.message, `${path}.message`);
|
|
772
|
+
return value;
|
|
773
|
+
}
|
|
774
|
+
export function parseAgentConnectionRequestSnapshot(value, path = "connectionRequestSnapshot") {
|
|
775
|
+
const snapshot = record(value, path);
|
|
776
|
+
parseAgentConnectionRequest(snapshot.request, `${path}.request`);
|
|
777
|
+
optionalString(snapshot.runId, `${path}.runId`);
|
|
778
|
+
return value;
|
|
779
|
+
}
|
|
780
|
+
export function parseAgentArtifactReference(value, path = "artifact") {
|
|
781
|
+
const artifact = record(value, path);
|
|
782
|
+
string(artifact.id, `${path}.id`);
|
|
783
|
+
string(artifact.kind, `${path}.kind`);
|
|
784
|
+
optionalString(artifact.title, `${path}.title`);
|
|
785
|
+
optionalString(artifact.url, `${path}.url`);
|
|
786
|
+
optionalString(artifact.runId, `${path}.runId`);
|
|
787
|
+
optionalTimestamp(artifact.createdAt, `${path}.createdAt`);
|
|
788
|
+
optionalMetadata(artifact.metadata, `${path}.metadata`);
|
|
789
|
+
return value;
|
|
790
|
+
}
|
|
791
|
+
export function parseAgentSuggestion(value, path = "suggestion") {
|
|
792
|
+
const suggestion = record(value, path);
|
|
793
|
+
string(suggestion.id, `${path}.id`);
|
|
794
|
+
string(suggestion.label, `${path}.label`);
|
|
795
|
+
optionalString(suggestion.prompt, `${path}.prompt`);
|
|
796
|
+
optionalString(suggestion.runId, `${path}.runId`);
|
|
797
|
+
optionalTimestamp(suggestion.updatedAt, `${path}.updatedAt`);
|
|
798
|
+
optionalMetadata(suggestion.metadata, `${path}.metadata`);
|
|
799
|
+
return value;
|
|
800
|
+
}
|
|
801
|
+
export function parseAgentWidgetSnapshot(value, path = "widgetSnapshot") {
|
|
802
|
+
const snapshot = record(value, path);
|
|
803
|
+
string(snapshot.messageId, `${path}.messageId`);
|
|
804
|
+
parseAgentWidget(snapshot.widget, `${path}.widget`);
|
|
805
|
+
return value;
|
|
806
|
+
}
|
|
807
|
+
export function parseAgentAnnotationSnapshot(value, path = "annotationSnapshot") {
|
|
808
|
+
const snapshot = record(value, path);
|
|
809
|
+
string(snapshot.messageId, `${path}.messageId`);
|
|
810
|
+
validateAnnotation(snapshot.annotation, `${path}.annotation`);
|
|
811
|
+
return value;
|
|
812
|
+
}
|
|
813
|
+
export function parseAgentReplayCheckpoint(value, path = "checkpoint") {
|
|
814
|
+
const checkpoint = record(value, path);
|
|
815
|
+
string(checkpoint.id, `${path}.id`);
|
|
816
|
+
timestamp(checkpoint.capturedAt, `${path}.capturedAt`);
|
|
817
|
+
const sequenceByRun = record(checkpoint.sequenceByRun, `${path}.sequenceByRun`);
|
|
818
|
+
for (const [runId, sequence] of Object.entries(sequenceByRun)) {
|
|
819
|
+
string(runId, `${path}.sequenceByRun key`);
|
|
820
|
+
nonNegativeSafeInteger(sequence, `${path}.sequenceByRun.${runId}`);
|
|
821
|
+
}
|
|
822
|
+
optionalString(checkpoint.cursor, `${path}.cursor`);
|
|
823
|
+
optionalMetadata(checkpoint.metadata, `${path}.metadata`);
|
|
824
|
+
return value;
|
|
825
|
+
}
|
|
826
|
+
export function parseAgentThreadSnapshot(value, path = "threadSnapshot") {
|
|
827
|
+
const snapshot = record(parseAgentThread(value, path), path);
|
|
828
|
+
const threadId = string(snapshot.id, `${path}.id`);
|
|
829
|
+
const messageIds = new Set();
|
|
830
|
+
array(snapshot.messages, `${path}.messages`).forEach((message, index) => {
|
|
831
|
+
const parsed = parseAgentMessage(message, `${path}.messages[${index}]`);
|
|
832
|
+
if (messageIds.has(parsed.id)) {
|
|
833
|
+
throw new AgentProtocolValidationError(`${path}.messages[${index}].id`, "must be unique within the snapshot");
|
|
834
|
+
}
|
|
835
|
+
messageIds.add(parsed.id);
|
|
836
|
+
});
|
|
837
|
+
if (snapshot.queuedMessages !== undefined) {
|
|
838
|
+
parseAgentQueuedMessages(snapshot.queuedMessages, `${path}.queuedMessages`).forEach((message, index) => {
|
|
839
|
+
if (message.threadId !== threadId) {
|
|
840
|
+
throw new AgentProtocolValidationError(`${path}.queuedMessages[${index}].threadId`, "must match the snapshot thread");
|
|
841
|
+
}
|
|
842
|
+
});
|
|
843
|
+
}
|
|
844
|
+
const lastSequenceByRun = new Map();
|
|
845
|
+
if (snapshot.events !== undefined) {
|
|
846
|
+
const eventIds = new Set();
|
|
847
|
+
array(snapshot.events, `${path}.events`).forEach((event, index) => {
|
|
848
|
+
const parsed = parseAgentEvent(event, `${path}.events[${index}]`);
|
|
849
|
+
if (parsed.threadId !== threadId) {
|
|
850
|
+
throw new AgentProtocolValidationError(`${path}.events[${index}].threadId`, "must match the snapshot thread");
|
|
851
|
+
}
|
|
852
|
+
const previous = lastSequenceByRun.get(parsed.runId) ?? 0;
|
|
853
|
+
const expectedSequence = previous + 1;
|
|
854
|
+
if (parsed.sequence !== expectedSequence) {
|
|
855
|
+
throw new AgentProtocolValidationError(`${path}.events[${index}].sequence`, `must be contiguous within each run; expected ${expectedSequence}`);
|
|
856
|
+
}
|
|
857
|
+
if (eventIds.has(parsed.id)) {
|
|
858
|
+
throw new AgentProtocolValidationError(`${path}.events[${index}].id`, "must be unique within the snapshot");
|
|
859
|
+
}
|
|
860
|
+
eventIds.add(parsed.id);
|
|
861
|
+
lastSequenceByRun.set(parsed.runId, parsed.sequence);
|
|
862
|
+
});
|
|
863
|
+
}
|
|
864
|
+
const runIds = new Set();
|
|
865
|
+
const runsById = new Map();
|
|
866
|
+
if (snapshot.runs !== undefined) {
|
|
867
|
+
array(snapshot.runs, `${path}.runs`).forEach((run, index) => {
|
|
868
|
+
const parsed = parseAgentRunSnapshot(run, `${path}.runs[${index}]`);
|
|
869
|
+
if (parsed.threadId !== threadId) {
|
|
870
|
+
throw new AgentProtocolValidationError(`${path}.runs[${index}].threadId`, "must match the snapshot thread");
|
|
871
|
+
}
|
|
872
|
+
if (runIds.has(parsed.id)) {
|
|
873
|
+
throw new AgentProtocolValidationError(`${path}.runs[${index}].id`, "must be unique within the snapshot");
|
|
874
|
+
}
|
|
875
|
+
runIds.add(parsed.id);
|
|
876
|
+
runsById.set(parsed.id, parsed);
|
|
877
|
+
});
|
|
878
|
+
}
|
|
879
|
+
if (snapshot.activeRunIds !== undefined) {
|
|
880
|
+
const activeRunIds = new Set();
|
|
881
|
+
array(snapshot.activeRunIds, `${path}.activeRunIds`).forEach((runId, index) => {
|
|
882
|
+
const parsed = string(runId, `${path}.activeRunIds[${index}]`);
|
|
883
|
+
if (activeRunIds.has(parsed)) {
|
|
884
|
+
throw new AgentProtocolValidationError(`${path}.activeRunIds[${index}]`, "must be unique within the snapshot");
|
|
885
|
+
}
|
|
886
|
+
activeRunIds.add(parsed);
|
|
887
|
+
if (snapshot.runs !== undefined && !runIds.has(parsed)) {
|
|
888
|
+
throw new AgentProtocolValidationError(`${path}.activeRunIds[${index}]`, "must reference a run included in the snapshot");
|
|
889
|
+
}
|
|
890
|
+
const run = runsById.get(parsed);
|
|
891
|
+
if (run &&
|
|
892
|
+
(run.status === "completed" ||
|
|
893
|
+
run.status === "failed" ||
|
|
894
|
+
run.status === "cancelled")) {
|
|
895
|
+
throw new AgentProtocolValidationError(`${path}.activeRunIds[${index}]`, "must not reference a terminal run");
|
|
896
|
+
}
|
|
897
|
+
});
|
|
898
|
+
}
|
|
899
|
+
if (snapshot.checkpoint !== undefined) {
|
|
900
|
+
const checkpoint = parseAgentReplayCheckpoint(snapshot.checkpoint, `${path}.checkpoint`);
|
|
901
|
+
for (const [runId, lastSequence] of lastSequenceByRun) {
|
|
902
|
+
const checkpointSequence = checkpoint.sequenceByRun[runId];
|
|
903
|
+
if (checkpointSequence === undefined ||
|
|
904
|
+
checkpointSequence < lastSequence) {
|
|
905
|
+
throw new AgentProtocolValidationError(`${path}.checkpoint.sequenceByRun.${runId}`, "must include every replayed event sequence");
|
|
906
|
+
}
|
|
907
|
+
}
|
|
908
|
+
for (const run of runsById.values()) {
|
|
909
|
+
if (checkpoint.sequenceByRun[run.id] !== run.lastSequence) {
|
|
910
|
+
throw new AgentProtocolValidationError(`${path}.checkpoint.sequenceByRun.${run.id}`, "must equal the run lastSequence");
|
|
911
|
+
}
|
|
912
|
+
}
|
|
913
|
+
}
|
|
914
|
+
const projectionParsers = [
|
|
915
|
+
["toolCalls", parseAgentToolCall],
|
|
916
|
+
["activities", parseAgentActivity],
|
|
917
|
+
["tasks", parseAgentTask],
|
|
918
|
+
["taskGroups", parseAgentTaskGroup],
|
|
919
|
+
["agents", parseAgentParticipant],
|
|
920
|
+
["interactions", parseAgentInteraction],
|
|
921
|
+
["artifacts", parseAgentArtifactReference],
|
|
922
|
+
["suggestions", parseAgentSuggestion],
|
|
923
|
+
];
|
|
924
|
+
for (const [key, parse] of projectionParsers) {
|
|
925
|
+
if (snapshot[key] === undefined)
|
|
926
|
+
continue;
|
|
927
|
+
const ids = new Set();
|
|
928
|
+
array(snapshot[key], `${path}.${key}`).forEach((entry, index) => {
|
|
929
|
+
const parsed = parse(entry, `${path}.${key}[${index}]`);
|
|
930
|
+
if (ids.has(parsed.id)) {
|
|
931
|
+
throw new AgentProtocolValidationError(`${path}.${key}[${index}].id`, "must be unique within the snapshot");
|
|
932
|
+
}
|
|
933
|
+
ids.add(parsed.id);
|
|
934
|
+
});
|
|
935
|
+
}
|
|
936
|
+
if (snapshot.approvals !== undefined) {
|
|
937
|
+
const ids = new Set();
|
|
938
|
+
array(snapshot.approvals, `${path}.approvals`).forEach((entry, index) => {
|
|
939
|
+
const parsed = parseAgentApprovalSnapshot(entry, `${path}.approvals[${index}]`);
|
|
940
|
+
if (ids.has(parsed.request.id)) {
|
|
941
|
+
throw new AgentProtocolValidationError(`${path}.approvals[${index}].request.id`, "must be unique within the snapshot");
|
|
942
|
+
}
|
|
943
|
+
ids.add(parsed.request.id);
|
|
944
|
+
});
|
|
945
|
+
}
|
|
946
|
+
if (snapshot.connectionRequests !== undefined) {
|
|
947
|
+
const ids = new Set();
|
|
948
|
+
array(snapshot.connectionRequests, `${path}.connectionRequests`).forEach((entry, index) => {
|
|
949
|
+
const parsed = parseAgentConnectionRequestSnapshot(entry, `${path}.connectionRequests[${index}]`);
|
|
950
|
+
if (ids.has(parsed.request.id)) {
|
|
951
|
+
throw new AgentProtocolValidationError(`${path}.connectionRequests[${index}].request.id`, "must be unique within the snapshot");
|
|
952
|
+
}
|
|
953
|
+
ids.add(parsed.request.id);
|
|
954
|
+
});
|
|
955
|
+
}
|
|
956
|
+
if (snapshot.widgets !== undefined) {
|
|
957
|
+
const ids = new Set();
|
|
958
|
+
array(snapshot.widgets, `${path}.widgets`).forEach((entry, index) => {
|
|
959
|
+
const parsed = parseAgentWidgetSnapshot(entry, `${path}.widgets[${index}]`);
|
|
960
|
+
if (!messageIds.has(parsed.messageId)) {
|
|
961
|
+
throw new AgentProtocolValidationError(`${path}.widgets[${index}].messageId`, "must reference a message included in the snapshot");
|
|
962
|
+
}
|
|
963
|
+
if (ids.has(parsed.widget.id)) {
|
|
964
|
+
throw new AgentProtocolValidationError(`${path}.widgets[${index}].widget.id`, "must be unique within the snapshot");
|
|
965
|
+
}
|
|
966
|
+
ids.add(parsed.widget.id);
|
|
967
|
+
});
|
|
968
|
+
}
|
|
969
|
+
if (snapshot.annotations !== undefined) {
|
|
970
|
+
const ids = new Set();
|
|
971
|
+
array(snapshot.annotations, `${path}.annotations`).forEach((entry, index) => {
|
|
972
|
+
const parsed = parseAgentAnnotationSnapshot(entry, `${path}.annotations[${index}]`);
|
|
973
|
+
if (!messageIds.has(parsed.messageId)) {
|
|
974
|
+
throw new AgentProtocolValidationError(`${path}.annotations[${index}].messageId`, "must reference a message included in the snapshot");
|
|
975
|
+
}
|
|
976
|
+
if (ids.has(parsed.annotation.id)) {
|
|
977
|
+
throw new AgentProtocolValidationError(`${path}.annotations[${index}].annotation.id`, "must be unique within the snapshot");
|
|
978
|
+
}
|
|
979
|
+
ids.add(parsed.annotation.id);
|
|
980
|
+
});
|
|
981
|
+
}
|
|
982
|
+
return value;
|
|
983
|
+
}
|
|
984
|
+
export function parseAgentDurableThreadSnapshot(value, path = "durableThreadSnapshot") {
|
|
985
|
+
const snapshot = record(parseAgentThreadSnapshot(value, path), path);
|
|
986
|
+
const requiredArrays = [
|
|
987
|
+
"queuedMessages",
|
|
988
|
+
"events",
|
|
989
|
+
"runs",
|
|
990
|
+
"activeRunIds",
|
|
991
|
+
"toolCalls",
|
|
992
|
+
"activities",
|
|
993
|
+
"tasks",
|
|
994
|
+
"taskGroups",
|
|
995
|
+
"approvals",
|
|
996
|
+
"widgets",
|
|
997
|
+
"annotations",
|
|
998
|
+
"agents",
|
|
999
|
+
"interactions",
|
|
1000
|
+
"artifacts",
|
|
1001
|
+
"suggestions",
|
|
1002
|
+
];
|
|
1003
|
+
for (const key of requiredArrays) {
|
|
1004
|
+
if (snapshot[key] === undefined) {
|
|
1005
|
+
throw new AgentProtocolValidationError(`${path}.${key}`, "is required for a durable snapshot");
|
|
1006
|
+
}
|
|
1007
|
+
array(snapshot[key], `${path}.${key}`);
|
|
1008
|
+
}
|
|
1009
|
+
if (snapshot.checkpoint === undefined) {
|
|
1010
|
+
throw new AgentProtocolValidationError(`${path}.checkpoint`, "is required for a durable snapshot");
|
|
1011
|
+
}
|
|
1012
|
+
const checkpoint = parseAgentReplayCheckpoint(snapshot.checkpoint, `${path}.checkpoint`);
|
|
1013
|
+
const runs = snapshot.runs;
|
|
1014
|
+
const runIds = new Set(runs.map((run) => run.id));
|
|
1015
|
+
for (const runId of Object.keys(checkpoint.sequenceByRun)) {
|
|
1016
|
+
if (!runIds.has(runId)) {
|
|
1017
|
+
throw new AgentProtocolValidationError(`${path}.checkpoint.sequenceByRun.${runId}`, "must reference a run included in the snapshot");
|
|
1018
|
+
}
|
|
1019
|
+
}
|
|
1020
|
+
for (const run of runs) {
|
|
1021
|
+
if (!(run.id in checkpoint.sequenceByRun)) {
|
|
1022
|
+
throw new AgentProtocolValidationError(`${path}.checkpoint.sequenceByRun.${run.id}`, "must include every run in the snapshot");
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
return value;
|
|
1026
|
+
}
|
|
1027
|
+
export function parseNullableAgentThreadSnapshot(value, path = "threadSnapshot") {
|
|
1028
|
+
return value === null ? null : parseAgentThreadSnapshot(value, path);
|
|
1029
|
+
}
|
|
1030
|
+
export function parseNullableAgentDurableThreadSnapshot(value, path = "durableThreadSnapshot") {
|
|
1031
|
+
return value === null ? null : parseAgentDurableThreadSnapshot(value, path);
|
|
1032
|
+
}
|
|
1033
|
+
export function parseListThreadsResult(value, path = "threads") {
|
|
1034
|
+
const result = record(value, path);
|
|
1035
|
+
array(result.threads, `${path}.threads`).forEach((thread, index) => parseAgentThread(thread, `${path}.threads[${index}]`));
|
|
1036
|
+
optionalString(result.nextCursor, `${path}.nextCursor`);
|
|
1037
|
+
return value;
|
|
1038
|
+
}
|
|
1039
|
+
export function parseQueueMessageResult(value, path = "queueMessageResult") {
|
|
1040
|
+
const result = record(value, path);
|
|
1041
|
+
parseAgentQueuedMessage(result.message, `${path}.message`);
|
|
1042
|
+
return value;
|
|
1043
|
+
}
|
|
1044
|
+
export function parseStartRunResult(value, path = "startRunResult") {
|
|
1045
|
+
const result = record(value, path);
|
|
1046
|
+
string(result.runId, `${path}.runId`);
|
|
1047
|
+
if (result.capabilities !== undefined) {
|
|
1048
|
+
parseAgentCapabilities(result.capabilities, `${path}.capabilities`);
|
|
1049
|
+
}
|
|
1050
|
+
return value;
|
|
1051
|
+
}
|
|
1052
|
+
export function parseSteerQueuedMessageResult(value, path = "steerQueuedMessageResult") {
|
|
1053
|
+
if (value === null || value === undefined)
|
|
1054
|
+
return undefined;
|
|
1055
|
+
return parseStartRunResult(value, path);
|
|
1056
|
+
}
|
|
1057
|
+
export function parseAgentRunSnapshot(value, path = "runSnapshot") {
|
|
1058
|
+
const run = record(value, path);
|
|
1059
|
+
string(run.id, `${path}.id`);
|
|
1060
|
+
string(run.threadId, `${path}.threadId`);
|
|
1061
|
+
const status = string(run.status, `${path}.status`);
|
|
1062
|
+
if (!new Set([
|
|
1063
|
+
"queued",
|
|
1064
|
+
"running",
|
|
1065
|
+
"awaiting_approval",
|
|
1066
|
+
"awaiting_input",
|
|
1067
|
+
"completed",
|
|
1068
|
+
"failed",
|
|
1069
|
+
"cancelled",
|
|
1070
|
+
]).has(status)) {
|
|
1071
|
+
throw new AgentProtocolValidationError(`${path}.status`, "unsupported run status");
|
|
1072
|
+
}
|
|
1073
|
+
nonNegativeSafeInteger(run.lastSequence, `${path}.lastSequence`);
|
|
1074
|
+
optionalTimestamp(run.startedAt, `${path}.startedAt`);
|
|
1075
|
+
optionalTimestamp(run.completedAt, `${path}.completedAt`);
|
|
1076
|
+
if (run.usage !== undefined)
|
|
1077
|
+
validateUsage(run.usage, `${path}.usage`);
|
|
1078
|
+
if (run.error !== undefined)
|
|
1079
|
+
parseAgentError(run.error, `${path}.error`);
|
|
1080
|
+
optionalMetadata(run.metadata, `${path}.metadata`);
|
|
1081
|
+
return value;
|
|
1082
|
+
}
|
|
1083
|
+
export function parseNullableAgentRunSnapshot(value, path = "runSnapshot") {
|
|
1084
|
+
return value === null ? null : parseAgentRunSnapshot(value, path);
|
|
1085
|
+
}
|
|
1086
|
+
export function parseAgentActionResult(value, path = "actionResult") {
|
|
1087
|
+
const result = record(value, path);
|
|
1088
|
+
string(result.invocationId, `${path}.invocationId`);
|
|
1089
|
+
if (result.status !== "completed" &&
|
|
1090
|
+
result.status !== "failed" &&
|
|
1091
|
+
result.status !== "cancelled") {
|
|
1092
|
+
throw new AgentProtocolValidationError(`${path}.status`, "unsupported action status");
|
|
1093
|
+
}
|
|
1094
|
+
if (result.data !== undefined) {
|
|
1095
|
+
validateJsonValue(result.data, `${path}.data`);
|
|
1096
|
+
}
|
|
1097
|
+
if (result.error !== undefined) {
|
|
1098
|
+
parseAgentError(result.error, `${path}.error`);
|
|
1099
|
+
}
|
|
1100
|
+
if (result.status === "failed" && result.error === undefined) {
|
|
1101
|
+
throw new AgentProtocolValidationError(`${path}.error`, "is required when an action failed");
|
|
1102
|
+
}
|
|
1103
|
+
optionalMetadata(result.metadata, `${path}.metadata`);
|
|
1104
|
+
return value;
|
|
1105
|
+
}
|
|
1106
|
+
export function parseAgentUploadTarget(value, path = "uploadTarget") {
|
|
1107
|
+
const target = record(value, path);
|
|
1108
|
+
string(target.uploadId, `${path}.uploadId`);
|
|
1109
|
+
if (target.method !== "POST" && target.method !== "PUT") {
|
|
1110
|
+
throw new AgentProtocolValidationError(`${path}.method`, "expected POST or PUT");
|
|
1111
|
+
}
|
|
1112
|
+
string(target.url, `${path}.url`);
|
|
1113
|
+
for (const key of ["headers", "fields"]) {
|
|
1114
|
+
if (target[key] === undefined)
|
|
1115
|
+
continue;
|
|
1116
|
+
const entries = record(target[key], `${path}.${key}`);
|
|
1117
|
+
for (const [name, entry] of Object.entries(entries)) {
|
|
1118
|
+
string(name, `${path}.${key} key`);
|
|
1119
|
+
if (typeof entry !== "string") {
|
|
1120
|
+
throw new AgentProtocolValidationError(`${path}.${key}.${name}`, "expected a string");
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
optionalTimestamp(target.expiresAt, `${path}.expiresAt`);
|
|
1125
|
+
return value;
|
|
1126
|
+
}
|
|
1127
|
+
export function parseVoidResponse(value, path = "response") {
|
|
1128
|
+
if (value !== null) {
|
|
1129
|
+
throw new AgentProtocolValidationError(path, "expected null");
|
|
1130
|
+
}
|
|
1131
|
+
return undefined;
|
|
1132
|
+
}
|
|
1133
|
+
function validateEventPayload(event, path) {
|
|
1134
|
+
const type = string(event.type, `${path}.type`);
|
|
1135
|
+
switch (type) {
|
|
1136
|
+
case "run.started":
|
|
1137
|
+
optionalString(event.agentId, `${path}.agentId`);
|
|
1138
|
+
return;
|
|
1139
|
+
case "run.status":
|
|
1140
|
+
if (!new Set([
|
|
1141
|
+
"queued",
|
|
1142
|
+
"running",
|
|
1143
|
+
"awaiting_approval",
|
|
1144
|
+
"awaiting_input",
|
|
1145
|
+
"completed",
|
|
1146
|
+
"failed",
|
|
1147
|
+
"cancelled",
|
|
1148
|
+
]).has(string(event.status, `${path}.status`))) {
|
|
1149
|
+
throw new AgentProtocolValidationError(`${path}.status`, "unsupported run status");
|
|
1150
|
+
}
|
|
1151
|
+
return;
|
|
1152
|
+
case "agent.registered":
|
|
1153
|
+
case "agent.updated":
|
|
1154
|
+
case "agent.unregistered": {
|
|
1155
|
+
parseAgentParticipant(event.agent, `${path}.agent`);
|
|
1156
|
+
return;
|
|
1157
|
+
}
|
|
1158
|
+
case "agent.interaction": {
|
|
1159
|
+
parseAgentInteraction(event.interaction, `${path}.interaction`);
|
|
1160
|
+
return;
|
|
1161
|
+
}
|
|
1162
|
+
case "message.created":
|
|
1163
|
+
case "message.completed":
|
|
1164
|
+
parseAgentMessage(event.message, `${path}.message`);
|
|
1165
|
+
return;
|
|
1166
|
+
case "message.delta":
|
|
1167
|
+
string(event.messageId, `${path}.messageId`);
|
|
1168
|
+
if (typeof event.text !== "string") {
|
|
1169
|
+
throw new AgentProtocolValidationError(`${path}.text`, "expected a string");
|
|
1170
|
+
}
|
|
1171
|
+
if (event.format !== undefined &&
|
|
1172
|
+
event.format !== "plain" &&
|
|
1173
|
+
event.format !== "markdown") {
|
|
1174
|
+
throw new AgentProtocolValidationError(`${path}.format`, "expected plain or markdown");
|
|
1175
|
+
}
|
|
1176
|
+
return;
|
|
1177
|
+
case "reasoning.delta":
|
|
1178
|
+
string(event.messageId, `${path}.messageId`);
|
|
1179
|
+
if (typeof event.text !== "string") {
|
|
1180
|
+
throw new AgentProtocolValidationError(`${path}.text`, "expected a string");
|
|
1181
|
+
}
|
|
1182
|
+
return;
|
|
1183
|
+
case "tool.started":
|
|
1184
|
+
case "tool.updated": {
|
|
1185
|
+
const toolCall = parseAgentToolCall(event.toolCall, `${path}.toolCall`);
|
|
1186
|
+
if (toolCall.runId !== undefined && toolCall.runId !== event.runId) {
|
|
1187
|
+
throw new AgentProtocolValidationError(`${path}.toolCall.runId`, "must match the event run");
|
|
1188
|
+
}
|
|
1189
|
+
return;
|
|
1190
|
+
}
|
|
1191
|
+
case "tool.delta":
|
|
1192
|
+
string(event.toolCallId, `${path}.toolCallId`);
|
|
1193
|
+
optionalString(event.inputTextDelta, `${path}.inputTextDelta`);
|
|
1194
|
+
optionalString(event.outputTextDelta, `${path}.outputTextDelta`);
|
|
1195
|
+
if (event.inputTextDelta === undefined &&
|
|
1196
|
+
event.outputTextDelta === undefined) {
|
|
1197
|
+
throw new AgentProtocolValidationError(path, "a tool delta requires inputTextDelta or outputTextDelta");
|
|
1198
|
+
}
|
|
1199
|
+
return;
|
|
1200
|
+
case "activity.started":
|
|
1201
|
+
case "activity.updated":
|
|
1202
|
+
case "activity.completed": {
|
|
1203
|
+
const activity = parseAgentActivity(event.activity, `${path}.activity`);
|
|
1204
|
+
if (activity.runId !== undefined && activity.runId !== event.runId) {
|
|
1205
|
+
throw new AgentProtocolValidationError(`${path}.activity.runId`, "must match the event run");
|
|
1206
|
+
}
|
|
1207
|
+
return;
|
|
1208
|
+
}
|
|
1209
|
+
case "task.created":
|
|
1210
|
+
case "task.updated":
|
|
1211
|
+
case "task.completed": {
|
|
1212
|
+
const task = parseAgentTask(event.task, `${path}.task`);
|
|
1213
|
+
if (task.runId !== undefined && task.runId !== event.runId) {
|
|
1214
|
+
throw new AgentProtocolValidationError(`${path}.task.runId`, "must match the event run");
|
|
1215
|
+
}
|
|
1216
|
+
return;
|
|
1217
|
+
}
|
|
1218
|
+
case "task-group.created":
|
|
1219
|
+
case "task-group.updated":
|
|
1220
|
+
case "task-group.completed": {
|
|
1221
|
+
const taskGroup = parseAgentTaskGroup(event.taskGroup, `${path}.taskGroup`);
|
|
1222
|
+
if (taskGroup.runId !== undefined && taskGroup.runId !== event.runId) {
|
|
1223
|
+
throw new AgentProtocolValidationError(`${path}.taskGroup.runId`, "must match the event run");
|
|
1224
|
+
}
|
|
1225
|
+
return;
|
|
1226
|
+
}
|
|
1227
|
+
case "task-group.removed":
|
|
1228
|
+
string(event.taskGroupId, `${path}.taskGroupId`);
|
|
1229
|
+
return;
|
|
1230
|
+
case "approval.requested": {
|
|
1231
|
+
parseAgentApprovalRequest(event.request, `${path}.request`);
|
|
1232
|
+
return;
|
|
1233
|
+
}
|
|
1234
|
+
case "approval.resolved":
|
|
1235
|
+
string(event.approvalId, `${path}.approvalId`);
|
|
1236
|
+
optionalString(event.optionId, `${path}.optionId`);
|
|
1237
|
+
validateApprovalResponse(event.response, `${path}.response`);
|
|
1238
|
+
return;
|
|
1239
|
+
case "connection.requested":
|
|
1240
|
+
case "connection.updated":
|
|
1241
|
+
parseAgentConnectionRequest(event.request, `${path}.request`);
|
|
1242
|
+
return;
|
|
1243
|
+
case "artifact.created": {
|
|
1244
|
+
const artifact = parseAgentArtifactReference(event.artifact, `${path}.artifact`);
|
|
1245
|
+
if (artifact.runId !== undefined && artifact.runId !== event.runId) {
|
|
1246
|
+
throw new AgentProtocolValidationError(`${path}.artifact.runId`, "must match the event run");
|
|
1247
|
+
}
|
|
1248
|
+
return;
|
|
1249
|
+
}
|
|
1250
|
+
case "widget.created":
|
|
1251
|
+
case "widget.updated": {
|
|
1252
|
+
optionalString(event.messageId, `${path}.messageId`);
|
|
1253
|
+
parseAgentWidget(event.widget, `${path}.widget`);
|
|
1254
|
+
return;
|
|
1255
|
+
}
|
|
1256
|
+
case "widget.removed":
|
|
1257
|
+
string(event.widgetId, `${path}.widgetId`);
|
|
1258
|
+
return;
|
|
1259
|
+
case "annotation.created":
|
|
1260
|
+
case "annotation.updated": {
|
|
1261
|
+
optionalString(event.messageId, `${path}.messageId`);
|
|
1262
|
+
validateAnnotation(event.annotation, `${path}.annotation`);
|
|
1263
|
+
return;
|
|
1264
|
+
}
|
|
1265
|
+
case "annotation.removed":
|
|
1266
|
+
string(event.annotationId, `${path}.annotationId`);
|
|
1267
|
+
return;
|
|
1268
|
+
case "suggestions.updated":
|
|
1269
|
+
array(event.suggestions, `${path}.suggestions`).forEach((suggestion, index) => {
|
|
1270
|
+
const parsed = parseAgentSuggestion(suggestion, `${path}.suggestions[${index}]`);
|
|
1271
|
+
if (parsed.runId !== undefined && parsed.runId !== event.runId) {
|
|
1272
|
+
throw new AgentProtocolValidationError(`${path}.suggestions[${index}].runId`, "must match the event run");
|
|
1273
|
+
}
|
|
1274
|
+
});
|
|
1275
|
+
return;
|
|
1276
|
+
case "action.started": {
|
|
1277
|
+
const invocation = record(event.invocation, `${path}.invocation`);
|
|
1278
|
+
string(invocation.id, `${path}.invocation.id`);
|
|
1279
|
+
string(invocation.action, `${path}.invocation.action`);
|
|
1280
|
+
string(invocation.threadId, `${path}.invocation.threadId`);
|
|
1281
|
+
if (invocation.threadId !== event.threadId) {
|
|
1282
|
+
throw new AgentProtocolValidationError(`${path}.invocation.threadId`, "must match the event thread");
|
|
1283
|
+
}
|
|
1284
|
+
optionalString(invocation.runId, `${path}.invocation.runId`);
|
|
1285
|
+
optionalString(invocation.messageId, `${path}.invocation.messageId`);
|
|
1286
|
+
optionalString(invocation.widgetId, `${path}.invocation.widgetId`);
|
|
1287
|
+
optionalString(invocation.itemId, `${path}.invocation.itemId`);
|
|
1288
|
+
if (invocation.payload !== undefined) {
|
|
1289
|
+
validateJsonValue(invocation.payload, `${path}.invocation.payload`);
|
|
1290
|
+
}
|
|
1291
|
+
optionalMetadata(invocation.metadata, `${path}.invocation.metadata`);
|
|
1292
|
+
return;
|
|
1293
|
+
}
|
|
1294
|
+
case "action.completed":
|
|
1295
|
+
case "action.failed": {
|
|
1296
|
+
parseAgentActionResult(event.result, `${path}.result`);
|
|
1297
|
+
return;
|
|
1298
|
+
}
|
|
1299
|
+
case "upload.progress": {
|
|
1300
|
+
const progress = record(event.progress, `${path}.progress`);
|
|
1301
|
+
string(progress.uploadId, `${path}.progress.uploadId`);
|
|
1302
|
+
const loaded = finiteNumber(progress.loaded, `${path}.progress.loaded`);
|
|
1303
|
+
const total = finiteNumber(progress.total, `${path}.progress.total`);
|
|
1304
|
+
if (loaded < 0 || total < 0 || loaded > total) {
|
|
1305
|
+
throw new AgentProtocolValidationError(`${path}.progress`, "loaded and total must be non-negative with loaded no greater than total");
|
|
1306
|
+
}
|
|
1307
|
+
return;
|
|
1308
|
+
}
|
|
1309
|
+
case "client.effect":
|
|
1310
|
+
case "client.deeplink":
|
|
1311
|
+
string(event.name, `${path}.name`);
|
|
1312
|
+
if (event.data !== undefined) {
|
|
1313
|
+
record(event.data, `${path}.data`);
|
|
1314
|
+
validateJsonValue(event.data, `${path}.data`);
|
|
1315
|
+
}
|
|
1316
|
+
return;
|
|
1317
|
+
case "thread.updated": {
|
|
1318
|
+
const thread = parseAgentThread(event.thread, `${path}.thread`);
|
|
1319
|
+
if (thread.id !== event.threadId) {
|
|
1320
|
+
throw new AgentProtocolValidationError(`${path}.thread.id`, "must match the event thread");
|
|
1321
|
+
}
|
|
1322
|
+
return;
|
|
1323
|
+
}
|
|
1324
|
+
case "queue.updated":
|
|
1325
|
+
parseAgentQueuedMessages(event.messages, `${path}.messages`).forEach((message, index) => {
|
|
1326
|
+
if (message.threadId !== event.threadId) {
|
|
1327
|
+
throw new AgentProtocolValidationError(`${path}.messages[${index}].threadId`, "must match the event thread");
|
|
1328
|
+
}
|
|
1329
|
+
});
|
|
1330
|
+
return;
|
|
1331
|
+
case "run.completed":
|
|
1332
|
+
if (event.usage !== undefined)
|
|
1333
|
+
validateUsage(event.usage, `${path}.usage`);
|
|
1334
|
+
return;
|
|
1335
|
+
case "run.failed": {
|
|
1336
|
+
parseAgentError(event.error, `${path}.error`);
|
|
1337
|
+
return;
|
|
1338
|
+
}
|
|
1339
|
+
case "run.cancelled":
|
|
1340
|
+
return;
|
|
1341
|
+
default:
|
|
1342
|
+
if (type.startsWith("x-") && type.length > 2) {
|
|
1343
|
+
if (!("payload" in event)) {
|
|
1344
|
+
throw new AgentProtocolValidationError(`${path}.payload`, "is required for extension events");
|
|
1345
|
+
}
|
|
1346
|
+
validateJsonValue(event.payload, `${path}.payload`);
|
|
1347
|
+
return;
|
|
1348
|
+
}
|
|
1349
|
+
throw new AgentProtocolValidationError(`${path}.type`, `unsupported event type ${JSON.stringify(type)}`);
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
export function parseAgentEvent(value, path = "event") {
|
|
1353
|
+
const event = record(value, path);
|
|
1354
|
+
identifierFields(event, path);
|
|
1355
|
+
positiveSafeInteger(event.sequence, `${path}.sequence`);
|
|
1356
|
+
timestamp(event.occurredAt, `${path}.occurredAt`);
|
|
1357
|
+
optionalMetadata(event.metadata, `${path}.metadata`);
|
|
1358
|
+
validateEventPayload(event, path);
|
|
1359
|
+
return value;
|
|
1360
|
+
}
|
|
1361
|
+
/**
|
|
1362
|
+
* Validates a complete replay batch before a consumer advances its cursor.
|
|
1363
|
+
* Returning only after the entire batch is contiguous prevents a later event
|
|
1364
|
+
* from making an earlier missing event permanently unreachable.
|
|
1365
|
+
*/
|
|
1366
|
+
export function parseAgentEventSequence(value, options = {}) {
|
|
1367
|
+
const path = options.path ?? "events";
|
|
1368
|
+
const afterSequence = options.afterSequence ?? 0;
|
|
1369
|
+
nonNegativeSafeInteger(afterSequence, `${path}.afterSequence`);
|
|
1370
|
+
const parsed = array(value, path).map((event, index) => parseAgentEvent(event, `${path}[${index}]`));
|
|
1371
|
+
parsed.forEach((event, index) => {
|
|
1372
|
+
const expectedSequence = afterSequence + index + 1;
|
|
1373
|
+
if (event.sequence !== expectedSequence) {
|
|
1374
|
+
throw new AgentProtocolValidationError(`${path}[${index}].sequence`, `must be contiguous; expected ${expectedSequence}`);
|
|
1375
|
+
}
|
|
1376
|
+
if (options.threadId !== undefined && event.threadId !== options.threadId) {
|
|
1377
|
+
throw new AgentProtocolValidationError(`${path}[${index}].threadId`, `must match ${JSON.stringify(options.threadId)}`);
|
|
1378
|
+
}
|
|
1379
|
+
if (options.runId !== undefined && event.runId !== options.runId) {
|
|
1380
|
+
throw new AgentProtocolValidationError(`${path}[${index}].runId`, `must match ${JSON.stringify(options.runId)}`);
|
|
1381
|
+
}
|
|
1382
|
+
});
|
|
1383
|
+
return parsed;
|
|
1384
|
+
}
|
|
1385
|
+
export function isAgentEvent(value) {
|
|
1386
|
+
try {
|
|
1387
|
+
parseAgentEvent(value);
|
|
1388
|
+
return true;
|
|
1389
|
+
}
|
|
1390
|
+
catch (error) {
|
|
1391
|
+
if (error instanceof AgentProtocolValidationError)
|
|
1392
|
+
return false;
|
|
1393
|
+
throw error;
|
|
1394
|
+
}
|
|
1395
|
+
}
|
|
1396
|
+
export function parseAgentCapabilities(value, path = "capabilities") {
|
|
1397
|
+
const capabilities = record(value, path);
|
|
1398
|
+
const booleanCapabilities = new Set([
|
|
1399
|
+
"actions",
|
|
1400
|
+
"activities",
|
|
1401
|
+
"approvals",
|
|
1402
|
+
"artifacts",
|
|
1403
|
+
"attachments",
|
|
1404
|
+
"citations",
|
|
1405
|
+
"codeExecution",
|
|
1406
|
+
"connectionRequests",
|
|
1407
|
+
"durableThreadSnapshots",
|
|
1408
|
+
"feedback",
|
|
1409
|
+
"widgets",
|
|
1410
|
+
"uploads",
|
|
1411
|
+
"clientEffects",
|
|
1412
|
+
"modelSelection",
|
|
1413
|
+
"toolSelection",
|
|
1414
|
+
"threadHistory",
|
|
1415
|
+
"threadForking",
|
|
1416
|
+
"messageQueue",
|
|
1417
|
+
"multiAgentActivity",
|
|
1418
|
+
"resumableRuns",
|
|
1419
|
+
"taskGroups",
|
|
1420
|
+
"suggestions",
|
|
1421
|
+
"smartObjects",
|
|
1422
|
+
]);
|
|
1423
|
+
for (const [key, entry] of Object.entries(capabilities)) {
|
|
1424
|
+
if (key === "reasoning") {
|
|
1425
|
+
if (!new Set(["none", "summary", "full"]).has(String(entry))) {
|
|
1426
|
+
throw new AgentProtocolValidationError(`${path}.${key}`, "expected none, summary, or full");
|
|
1427
|
+
}
|
|
1428
|
+
continue;
|
|
1429
|
+
}
|
|
1430
|
+
if (key === "protocolVersion") {
|
|
1431
|
+
if (!isAgentKitProtocolVersion(entry)) {
|
|
1432
|
+
throw new AgentProtocolValidationError(`${path}.${key}`, `unsupported protocol version ${JSON.stringify(entry)}`);
|
|
1433
|
+
}
|
|
1434
|
+
continue;
|
|
1435
|
+
}
|
|
1436
|
+
if (key.startsWith("x-") && key.length > 2) {
|
|
1437
|
+
validateJsonValue(entry, `${path}.${key}`);
|
|
1438
|
+
continue;
|
|
1439
|
+
}
|
|
1440
|
+
if (!booleanCapabilities.has(key)) {
|
|
1441
|
+
throw new AgentProtocolValidationError(`${path}.${key}`, "unknown capabilities must use an x- namespace");
|
|
1442
|
+
}
|
|
1443
|
+
boolean(entry, `${path}.${key}`);
|
|
1444
|
+
}
|
|
1445
|
+
return value;
|
|
1446
|
+
}
|
|
1447
|
+
export function parseAgentProtocolVersionOffer(value, path = "protocolOffer") {
|
|
1448
|
+
const offer = record(value, path);
|
|
1449
|
+
if (offer.protocol !== AGENTKIT_PROTOCOL_NAME) {
|
|
1450
|
+
throw new AgentProtocolValidationError(`${path}.protocol`, `expected ${AGENTKIT_PROTOCOL_NAME}`);
|
|
1451
|
+
}
|
|
1452
|
+
const seen = new Set();
|
|
1453
|
+
const versions = array(offer.versions, `${path}.versions`);
|
|
1454
|
+
if (versions.length === 0) {
|
|
1455
|
+
throw new AgentProtocolValidationError(`${path}.versions`, "must contain at least one version");
|
|
1456
|
+
}
|
|
1457
|
+
versions.forEach((version, index) => {
|
|
1458
|
+
const parsed = positiveSafeInteger(version, `${path}.versions[${index}]`);
|
|
1459
|
+
if (seen.has(parsed)) {
|
|
1460
|
+
throw new AgentProtocolValidationError(`${path}.versions[${index}]`, "must be unique");
|
|
1461
|
+
}
|
|
1462
|
+
seen.add(parsed);
|
|
1463
|
+
});
|
|
1464
|
+
return value;
|
|
1465
|
+
}
|
|
1466
|
+
export function parseAgentProtocolCompatibility(value, path = "compatibility") {
|
|
1467
|
+
const compatibility = record(value, path);
|
|
1468
|
+
const status = string(compatibility.status, `${path}.status`);
|
|
1469
|
+
if (status !== "compatible" && status !== "incompatible") {
|
|
1470
|
+
throw new AgentProtocolValidationError(`${path}.status`, "expected compatible or incompatible");
|
|
1471
|
+
}
|
|
1472
|
+
const localVersions = array(compatibility.localVersions, `${path}.localVersions`);
|
|
1473
|
+
if (localVersions.length === 0) {
|
|
1474
|
+
throw new AgentProtocolValidationError(`${path}.localVersions`, "must contain at least one version");
|
|
1475
|
+
}
|
|
1476
|
+
const seenLocalVersions = new Set();
|
|
1477
|
+
localVersions.forEach((version, index) => {
|
|
1478
|
+
if (!isAgentKitProtocolVersion(version)) {
|
|
1479
|
+
throw new AgentProtocolValidationError(`${path}.localVersions[${index}]`, "is not supported by this package");
|
|
1480
|
+
}
|
|
1481
|
+
if (seenLocalVersions.has(version)) {
|
|
1482
|
+
throw new AgentProtocolValidationError(`${path}.localVersions[${index}]`, "must be unique");
|
|
1483
|
+
}
|
|
1484
|
+
seenLocalVersions.add(version);
|
|
1485
|
+
});
|
|
1486
|
+
const peerVersions = array(compatibility.peerVersions, `${path}.peerVersions`);
|
|
1487
|
+
if (peerVersions.length === 0) {
|
|
1488
|
+
throw new AgentProtocolValidationError(`${path}.peerVersions`, "must contain at least one version");
|
|
1489
|
+
}
|
|
1490
|
+
const seenPeerVersions = new Set();
|
|
1491
|
+
peerVersions.forEach((version, index) => {
|
|
1492
|
+
const parsed = positiveSafeInteger(version, `${path}.peerVersions[${index}]`);
|
|
1493
|
+
if (seenPeerVersions.has(parsed)) {
|
|
1494
|
+
throw new AgentProtocolValidationError(`${path}.peerVersions[${index}]`, "must be unique");
|
|
1495
|
+
}
|
|
1496
|
+
seenPeerVersions.add(parsed);
|
|
1497
|
+
});
|
|
1498
|
+
if (status === "compatible") {
|
|
1499
|
+
if (!isAgentKitProtocolVersion(compatibility.selectedVersion)) {
|
|
1500
|
+
throw new AgentProtocolValidationError(`${path}.selectedVersion`, "is not supported by this package");
|
|
1501
|
+
}
|
|
1502
|
+
if (!localVersions.includes(compatibility.selectedVersion)) {
|
|
1503
|
+
throw new AgentProtocolValidationError(`${path}.selectedVersion`, "must be included in localVersions");
|
|
1504
|
+
}
|
|
1505
|
+
if (!compatibility.peerVersions.includes(compatibility.selectedVersion)) {
|
|
1506
|
+
throw new AgentProtocolValidationError(`${path}.selectedVersion`, "must be included in peerVersions");
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1509
|
+
else {
|
|
1510
|
+
const error = record(parseAgentError(compatibility.error, `${path}.error`), `${path}.error`);
|
|
1511
|
+
if (error.code !== "protocol_version_unsupported") {
|
|
1512
|
+
throw new AgentProtocolValidationError(`${path}.error.code`, "expected protocol_version_unsupported");
|
|
1513
|
+
}
|
|
1514
|
+
if (JSON.stringify(error.supportedVersions) !== JSON.stringify(localVersions)) {
|
|
1515
|
+
throw new AgentProtocolValidationError(`${path}.error.supportedVersions`, "must match localVersions");
|
|
1516
|
+
}
|
|
1517
|
+
if (JSON.stringify(error.receivedVersions) !== JSON.stringify(peerVersions)) {
|
|
1518
|
+
throw new AgentProtocolValidationError(`${path}.error.receivedVersions`, "must match peerVersions");
|
|
1519
|
+
}
|
|
1520
|
+
}
|
|
1521
|
+
return value;
|
|
1522
|
+
}
|
|
1523
|
+
export function parseAgentCapabilityDescriptor(value, path = "capability") {
|
|
1524
|
+
const descriptor = record(value, path);
|
|
1525
|
+
const id = capabilityId(descriptor.id, `${path}.id`);
|
|
1526
|
+
const state = string(descriptor.state, `${path}.state`);
|
|
1527
|
+
if (!new Set(["available", "degraded", "unavailable", "unsupported"]).has(state)) {
|
|
1528
|
+
throw new AgentProtocolValidationError(`${path}.state`, "unsupported capability state");
|
|
1529
|
+
}
|
|
1530
|
+
optionalString(descriptor.description, `${path}.description`);
|
|
1531
|
+
if (descriptor.error !== undefined) {
|
|
1532
|
+
const error = record(parseAgentError(descriptor.error, `${path}.error`), `${path}.error`);
|
|
1533
|
+
if (error.capability !== id) {
|
|
1534
|
+
throw new AgentProtocolValidationError(`${path}.error.capability`, "must match the descriptor id");
|
|
1535
|
+
}
|
|
1536
|
+
if ((state === "unsupported" && error.code !== "capability_unsupported") ||
|
|
1537
|
+
((state === "unavailable" || state === "degraded") &&
|
|
1538
|
+
error.code !== "capability_unavailable")) {
|
|
1539
|
+
throw new AgentProtocolValidationError(`${path}.error.code`, "must match the capability state");
|
|
1540
|
+
}
|
|
1541
|
+
}
|
|
1542
|
+
if (state !== "available" && descriptor.error === undefined) {
|
|
1543
|
+
throw new AgentProtocolValidationError(`${path}.error`, "is required for every non-available capability");
|
|
1544
|
+
}
|
|
1545
|
+
if (state === "available" && descriptor.error !== undefined) {
|
|
1546
|
+
throw new AgentProtocolValidationError(`${path}.error`, "must be omitted for an available capability");
|
|
1547
|
+
}
|
|
1548
|
+
optionalMetadata(descriptor.metadata, `${path}.metadata`);
|
|
1549
|
+
return value;
|
|
1550
|
+
}
|
|
1551
|
+
export function parseDiscoverCapabilitiesInput(value, path = "discoverCapabilities") {
|
|
1552
|
+
const input = record(value, path);
|
|
1553
|
+
parseAgentProtocolVersionOffer(input.protocol, `${path}.protocol`);
|
|
1554
|
+
if (input.requested !== undefined) {
|
|
1555
|
+
const seen = new Set();
|
|
1556
|
+
array(input.requested, `${path}.requested`).forEach((entry, index) => {
|
|
1557
|
+
const id = capabilityId(entry, `${path}.requested[${index}]`);
|
|
1558
|
+
if (seen.has(id)) {
|
|
1559
|
+
throw new AgentProtocolValidationError(`${path}.requested[${index}]`, "must be unique");
|
|
1560
|
+
}
|
|
1561
|
+
seen.add(id);
|
|
1562
|
+
});
|
|
1563
|
+
}
|
|
1564
|
+
optionalMetadata(input.metadata, `${path}.metadata`);
|
|
1565
|
+
return value;
|
|
1566
|
+
}
|
|
1567
|
+
export function parseAgentCapabilitiesDiscovery(value, path = "capabilitiesDiscovery") {
|
|
1568
|
+
const discovery = record(value, path);
|
|
1569
|
+
const compatibility = parseAgentProtocolCompatibility(discovery.protocol, `${path}.protocol`);
|
|
1570
|
+
const seen = new Set();
|
|
1571
|
+
const capabilities = array(discovery.capabilities, `${path}.capabilities`);
|
|
1572
|
+
if (compatibility.status === "incompatible" && capabilities.length > 0) {
|
|
1573
|
+
throw new AgentProtocolValidationError(`${path}.capabilities`, "must be empty when protocol versions are incompatible");
|
|
1574
|
+
}
|
|
1575
|
+
capabilities.forEach((entry, index) => {
|
|
1576
|
+
const parsed = parseAgentCapabilityDescriptor(entry, `${path}.capabilities[${index}]`);
|
|
1577
|
+
if (seen.has(parsed.id)) {
|
|
1578
|
+
throw new AgentProtocolValidationError(`${path}.capabilities[${index}].id`, "must be unique");
|
|
1579
|
+
}
|
|
1580
|
+
seen.add(parsed.id);
|
|
1581
|
+
});
|
|
1582
|
+
const discoveredAt = timestamp(discovery.discoveredAt, `${path}.discoveredAt`);
|
|
1583
|
+
optionalTimestamp(discovery.expiresAt, `${path}.expiresAt`);
|
|
1584
|
+
if (discovery.expiresAt !== undefined &&
|
|
1585
|
+
Date.parse(String(discovery.expiresAt)) <= Date.parse(discoveredAt)) {
|
|
1586
|
+
throw new AgentProtocolValidationError(`${path}.expiresAt`, "must be later than discoveredAt");
|
|
1587
|
+
}
|
|
1588
|
+
if (discovery.legacy !== undefined) {
|
|
1589
|
+
parseAgentCapabilities(discovery.legacy, `${path}.legacy`);
|
|
1590
|
+
}
|
|
1591
|
+
optionalMetadata(discovery.metadata, `${path}.metadata`);
|
|
1592
|
+
return value;
|
|
1593
|
+
}
|
|
1594
|
+
export function parseAgentRunOptions(value, path = "runOptions") {
|
|
1595
|
+
const options = record(value, path);
|
|
1596
|
+
optionalString(options.agentId, `${path}.agentId`);
|
|
1597
|
+
optionalString(options.model, `${path}.model`);
|
|
1598
|
+
optionalString(options.locale, `${path}.locale`);
|
|
1599
|
+
optionalString(options.mode, `${path}.mode`);
|
|
1600
|
+
optionalMetadata(options.metadata, `${path}.metadata`);
|
|
1601
|
+
if (options.reasoningEffort !== undefined &&
|
|
1602
|
+
!new Set(["none", "minimal", "low", "medium", "high", "xhigh"]).has(String(options.reasoningEffort))) {
|
|
1603
|
+
throw new AgentProtocolValidationError(`${path}.reasoningEffort`, "unsupported reasoning effort");
|
|
1604
|
+
}
|
|
1605
|
+
if (options.toolChoice !== undefined) {
|
|
1606
|
+
if (typeof options.toolChoice === "string") {
|
|
1607
|
+
if (!new Set(["auto", "none", "required"]).has(options.toolChoice)) {
|
|
1608
|
+
throw new AgentProtocolValidationError(`${path}.toolChoice`, "unsupported tool choice");
|
|
1609
|
+
}
|
|
1610
|
+
}
|
|
1611
|
+
else {
|
|
1612
|
+
const choice = record(options.toolChoice, `${path}.toolChoice`);
|
|
1613
|
+
string(choice.name, `${path}.toolChoice.name`);
|
|
1614
|
+
}
|
|
1615
|
+
}
|
|
1616
|
+
if (options.temperature !== undefined &&
|
|
1617
|
+
(typeof options.temperature !== "number" ||
|
|
1618
|
+
!Number.isFinite(options.temperature))) {
|
|
1619
|
+
throw new AgentProtocolValidationError(`${path}.temperature`, "expected a number");
|
|
1620
|
+
}
|
|
1621
|
+
if (options.parallelToolCalls !== undefined &&
|
|
1622
|
+
typeof options.parallelToolCalls !== "boolean") {
|
|
1623
|
+
throw new AgentProtocolValidationError(`${path}.parallelToolCalls`, "expected a boolean");
|
|
1624
|
+
}
|
|
1625
|
+
return value;
|
|
1626
|
+
}
|
|
1627
|
+
export function parseStartRunInput(value, path = "startRun") {
|
|
1628
|
+
const input = record(value, path);
|
|
1629
|
+
string(input.threadId, `${path}.threadId`);
|
|
1630
|
+
array(input.messages, `${path}.messages`).forEach((message, index) => parseAgentMessage(message, `${path}.messages[${index}]`));
|
|
1631
|
+
if (input.options !== undefined) {
|
|
1632
|
+
parseAgentRunOptions(input.options, `${path}.options`);
|
|
1633
|
+
}
|
|
1634
|
+
if (input.resume !== undefined) {
|
|
1635
|
+
parseAgentResumeEntries(input.resume, `${path}.resume`);
|
|
1636
|
+
}
|
|
1637
|
+
optionalMetadata(input.metadata, `${path}.metadata`);
|
|
1638
|
+
return value;
|
|
1639
|
+
}
|
|
1640
|
+
function parseAgentResumeEntries(value, path) {
|
|
1641
|
+
array(value, path).forEach((entry, index) => {
|
|
1642
|
+
const resume = record(entry, `${path}[${index}]`);
|
|
1643
|
+
knownKeys(resume, ["interruptId", "status", "payload", "metadata"], `${path}[${index}]`);
|
|
1644
|
+
string(resume.interruptId, `${path}[${index}].interruptId`);
|
|
1645
|
+
const status = string(resume.status, `${path}[${index}].status`);
|
|
1646
|
+
if (status !== "resolved" && status !== "cancelled") {
|
|
1647
|
+
throw new AgentProtocolValidationError(`${path}[${index}].status`, "expected resolved or cancelled");
|
|
1648
|
+
}
|
|
1649
|
+
optionalMetadata(resume.metadata, `${path}[${index}].metadata`);
|
|
1650
|
+
});
|
|
1651
|
+
return value;
|
|
1652
|
+
}
|
|
1653
|
+
export function parseResumeRunInput(value, path = "resumeRun") {
|
|
1654
|
+
const input = record(value, path);
|
|
1655
|
+
knownKeys(input, ["threadId", "runId", "resume"], path);
|
|
1656
|
+
string(input.threadId, `${path}.threadId`);
|
|
1657
|
+
string(input.runId, `${path}.runId`);
|
|
1658
|
+
const entries = parseAgentResumeEntries(input.resume, `${path}.resume`);
|
|
1659
|
+
if (entries.length === 0) {
|
|
1660
|
+
throw new AgentProtocolValidationError(`${path}.resume`, "expected at least one interrupt resolution");
|
|
1661
|
+
}
|
|
1662
|
+
return value;
|
|
1663
|
+
}
|
|
1664
|
+
export function parseSubscribeToRunInput(value, path = "subscribeToRun") {
|
|
1665
|
+
const input = record(value, path);
|
|
1666
|
+
string(input.threadId, `${path}.threadId`);
|
|
1667
|
+
string(input.runId, `${path}.runId`);
|
|
1668
|
+
if (input.afterSequence !== undefined) {
|
|
1669
|
+
nonNegativeSafeInteger(input.afterSequence, `${path}.afterSequence`);
|
|
1670
|
+
}
|
|
1671
|
+
if (input.signal !== undefined) {
|
|
1672
|
+
const signal = record(input.signal, `${path}.signal`);
|
|
1673
|
+
if (typeof signal.aborted !== "boolean" ||
|
|
1674
|
+
typeof signal.addEventListener !== "function" ||
|
|
1675
|
+
typeof signal.removeEventListener !== "function") {
|
|
1676
|
+
throw new AgentProtocolValidationError(`${path}.signal`, "expected an AbortSignal-compatible value");
|
|
1677
|
+
}
|
|
1678
|
+
}
|
|
1679
|
+
return value;
|
|
1680
|
+
}
|
|
1681
|
+
export function parseAgentRequestContext(value, path = "requestContext") {
|
|
1682
|
+
const context = record(value, path);
|
|
1683
|
+
knownKeys(context, ["signal", "correlationId"], path);
|
|
1684
|
+
optionalString(context.correlationId, `${path}.correlationId`);
|
|
1685
|
+
if (context.signal !== undefined) {
|
|
1686
|
+
const signal = record(context.signal, `${path}.signal`);
|
|
1687
|
+
if (typeof signal.aborted !== "boolean" ||
|
|
1688
|
+
typeof signal.addEventListener !== "function" ||
|
|
1689
|
+
typeof signal.removeEventListener !== "function") {
|
|
1690
|
+
throw new AgentProtocolValidationError(`${path}.signal`, "expected an AbortSignal-compatible value");
|
|
1691
|
+
}
|
|
1692
|
+
}
|
|
1693
|
+
return value;
|
|
1694
|
+
}
|
|
1695
|
+
export function parseThreadIdInput(value, path = "thread") {
|
|
1696
|
+
const input = record(value, path);
|
|
1697
|
+
string(input.threadId, `${path}.threadId`);
|
|
1698
|
+
return value;
|
|
1699
|
+
}
|
|
1700
|
+
export function parseThreadMessageInput(value, path = "threadMessage") {
|
|
1701
|
+
const input = record(parseThreadIdInput(value, path), path);
|
|
1702
|
+
string(input.messageId, `${path}.messageId`);
|
|
1703
|
+
return value;
|
|
1704
|
+
}
|
|
1705
|
+
export function parseGetRunInput(value, path = "getRun") {
|
|
1706
|
+
const input = record(parseThreadIdInput(value, path), path);
|
|
1707
|
+
string(input.runId, `${path}.runId`);
|
|
1708
|
+
return value;
|
|
1709
|
+
}
|
|
1710
|
+
export function parseListThreadsInput(value, path = "listThreads") {
|
|
1711
|
+
const input = record(value, path);
|
|
1712
|
+
if (input.limit !== undefined) {
|
|
1713
|
+
positiveSafeInteger(input.limit, `${path}.limit`);
|
|
1714
|
+
}
|
|
1715
|
+
optionalString(input.cursor, `${path}.cursor`);
|
|
1716
|
+
optionalMetadata(input.metadata, `${path}.metadata`);
|
|
1717
|
+
return value;
|
|
1718
|
+
}
|
|
1719
|
+
export function parseCreateThreadInput(value, path = "createThread") {
|
|
1720
|
+
const input = record(value, path);
|
|
1721
|
+
optionalString(input.id, `${path}.id`);
|
|
1722
|
+
optionalString(input.title, `${path}.title`);
|
|
1723
|
+
optionalMetadata(input.metadata, `${path}.metadata`);
|
|
1724
|
+
return value;
|
|
1725
|
+
}
|
|
1726
|
+
export function parseUpdateThreadInput(value, path = "updateThread") {
|
|
1727
|
+
const input = record(parseThreadIdInput(value, path), path);
|
|
1728
|
+
optionalString(input.title, `${path}.title`);
|
|
1729
|
+
optionalMetadata(input.metadata, `${path}.metadata`);
|
|
1730
|
+
if (input.status !== undefined &&
|
|
1731
|
+
input.status !== "active" &&
|
|
1732
|
+
input.status !== "archived") {
|
|
1733
|
+
throw new AgentProtocolValidationError(`${path}.status`, "expected active or archived");
|
|
1734
|
+
}
|
|
1735
|
+
return value;
|
|
1736
|
+
}
|
|
1737
|
+
export function parseForkThreadInput(value, path = "forkThread") {
|
|
1738
|
+
const input = record(parseThreadIdInput(value, path), path);
|
|
1739
|
+
optionalString(input.fromMessageId, `${path}.fromMessageId`);
|
|
1740
|
+
optionalString(input.title, `${path}.title`);
|
|
1741
|
+
optionalMetadata(input.metadata, `${path}.metadata`);
|
|
1742
|
+
return value;
|
|
1743
|
+
}
|
|
1744
|
+
export function parseQueueMessageInput(value, path = "queueMessage") {
|
|
1745
|
+
const input = record(parseThreadIdInput(value, path), path);
|
|
1746
|
+
if (typeof input.text !== "string") {
|
|
1747
|
+
throw new AgentProtocolValidationError(`${path}.text`, "expected a string");
|
|
1748
|
+
}
|
|
1749
|
+
if (input.attachments !== undefined) {
|
|
1750
|
+
array(input.attachments, `${path}.attachments`).forEach((attachment, index) => {
|
|
1751
|
+
validateMessagePart(attachment, `${path}.attachments[${index}]`);
|
|
1752
|
+
if (record(attachment, `${path}.attachments[${index}]`).type !== "file") {
|
|
1753
|
+
throw new AgentProtocolValidationError(`${path}.attachments[${index}].type`, "expected file");
|
|
1754
|
+
}
|
|
1755
|
+
});
|
|
1756
|
+
}
|
|
1757
|
+
optionalMetadata(input.metadata, `${path}.metadata`);
|
|
1758
|
+
return value;
|
|
1759
|
+
}
|
|
1760
|
+
export function parseCancelRunInput(value, path = "cancelRun") {
|
|
1761
|
+
const input = record(parseThreadIdInput(value, path), path);
|
|
1762
|
+
string(input.runId, `${path}.runId`);
|
|
1763
|
+
return value;
|
|
1764
|
+
}
|
|
1765
|
+
/** @deprecated Validation bridge for the protocol-v1 approval command. */
|
|
1766
|
+
export function parseResolveApprovalInput(value, path = "resolveApproval") {
|
|
1767
|
+
const input = record(parseCancelRunInput(value, path), path);
|
|
1768
|
+
string(input.approvalId, `${path}.approvalId`);
|
|
1769
|
+
optionalString(input.optionId, `${path}.optionId`);
|
|
1770
|
+
validateApprovalResponse(input.response, `${path}.response`);
|
|
1771
|
+
return value;
|
|
1772
|
+
}
|
|
1773
|
+
export function parseResolveConnectionRequestInput(value, path = "resolveConnectionRequest") {
|
|
1774
|
+
const input = record(parseCancelRunInput(value, path), path);
|
|
1775
|
+
string(input.requestId, `${path}.requestId`);
|
|
1776
|
+
parseAgentConnectionResponse(input.response, `${path}.response`);
|
|
1777
|
+
return value;
|
|
1778
|
+
}
|
|
1779
|
+
export function parseInvokeActionInput(value, path = "invokeAction") {
|
|
1780
|
+
const input = record(value, path);
|
|
1781
|
+
const invocation = record(input.invocation, `${path}.invocation`);
|
|
1782
|
+
string(invocation.id, `${path}.invocation.id`);
|
|
1783
|
+
string(invocation.action, `${path}.invocation.action`);
|
|
1784
|
+
string(invocation.threadId, `${path}.invocation.threadId`);
|
|
1785
|
+
optionalString(invocation.runId, `${path}.invocation.runId`);
|
|
1786
|
+
optionalString(invocation.messageId, `${path}.invocation.messageId`);
|
|
1787
|
+
optionalString(invocation.widgetId, `${path}.invocation.widgetId`);
|
|
1788
|
+
optionalString(invocation.itemId, `${path}.invocation.itemId`);
|
|
1789
|
+
if (invocation.payload !== undefined) {
|
|
1790
|
+
validateJsonValue(invocation.payload, `${path}.invocation.payload`);
|
|
1791
|
+
}
|
|
1792
|
+
optionalMetadata(invocation.metadata, `${path}.invocation.metadata`);
|
|
1793
|
+
return value;
|
|
1794
|
+
}
|
|
1795
|
+
export function parseCreateUploadInput(value, path = "createUpload") {
|
|
1796
|
+
const input = record(parseThreadIdInput(value, path), path);
|
|
1797
|
+
const descriptor = record(input.descriptor, `${path}.descriptor`);
|
|
1798
|
+
string(descriptor.name, `${path}.descriptor.name`);
|
|
1799
|
+
string(descriptor.mediaType, `${path}.descriptor.mediaType`);
|
|
1800
|
+
nonNegativeSafeInteger(descriptor.size, `${path}.descriptor.size`);
|
|
1801
|
+
optionalString(descriptor.checksum, `${path}.descriptor.checksum`);
|
|
1802
|
+
optionalString(descriptor.purpose, `${path}.descriptor.purpose`);
|
|
1803
|
+
optionalMetadata(descriptor.metadata, `${path}.descriptor.metadata`);
|
|
1804
|
+
return value;
|
|
1805
|
+
}
|
|
1806
|
+
export function parseCompleteUploadInput(value, path = "completeUpload") {
|
|
1807
|
+
const input = record(parseThreadIdInput(value, path), path);
|
|
1808
|
+
string(input.uploadId, `${path}.uploadId`);
|
|
1809
|
+
return value;
|
|
1810
|
+
}
|
|
1811
|
+
export function parseSubmitFeedbackInput(value, path = "submitFeedback") {
|
|
1812
|
+
const input = record(parseThreadIdInput(value, path), path);
|
|
1813
|
+
string(input.messageId, `${path}.messageId`);
|
|
1814
|
+
if (input.value !== "positive" &&
|
|
1815
|
+
input.value !== "negative" &&
|
|
1816
|
+
input.value !== "dismissed") {
|
|
1817
|
+
throw new AgentProtocolValidationError(`${path}.value`, "expected positive, negative, or dismissed");
|
|
1818
|
+
}
|
|
1819
|
+
optionalString(input.reason, `${path}.reason`);
|
|
1820
|
+
optionalMetadata(input.metadata, `${path}.metadata`);
|
|
1821
|
+
return value;
|
|
1822
|
+
}
|
|
1823
|
+
export function parseAgentProtocolEnvelope(value, parsePayload, path = "envelope") {
|
|
1824
|
+
const envelope = record(value, path);
|
|
1825
|
+
knownKeys(envelope, ["protocol", "version", "kind", "correlationId", "metadata", "payload"], path);
|
|
1826
|
+
if (envelope.protocol !== AGENTKIT_PROTOCOL_NAME) {
|
|
1827
|
+
throw new AgentProtocolValidationError(`${path}.protocol`, `expected ${AGENTKIT_PROTOCOL_NAME}`);
|
|
1828
|
+
}
|
|
1829
|
+
if (!isAgentKitProtocolVersion(envelope.version)) {
|
|
1830
|
+
throw new AgentProtocolValidationError(`${path}.version`, `unsupported protocol version ${JSON.stringify(envelope.version)}`);
|
|
1831
|
+
}
|
|
1832
|
+
const kind = string(envelope.kind, `${path}.kind`);
|
|
1833
|
+
if (!new Set(["request", "response", "event", "error"]).has(kind)) {
|
|
1834
|
+
throw new AgentProtocolValidationError(`${path}.kind`, `unsupported envelope kind ${JSON.stringify(kind)}`);
|
|
1835
|
+
}
|
|
1836
|
+
if (!("payload" in envelope)) {
|
|
1837
|
+
throw new AgentProtocolValidationError(`${path}.payload`, "is required");
|
|
1838
|
+
}
|
|
1839
|
+
optionalString(envelope.correlationId, `${path}.correlationId`);
|
|
1840
|
+
optionalMetadata(envelope.metadata, `${path}.metadata`);
|
|
1841
|
+
validateJsonValue(envelope.payload, `${path}.payload`);
|
|
1842
|
+
const payload = parsePayload
|
|
1843
|
+
? parsePayload(envelope.payload, `${path}.payload`)
|
|
1844
|
+
: kind === "error"
|
|
1845
|
+
? parseAgentError(envelope.payload, `${path}.payload`)
|
|
1846
|
+
: envelope.payload;
|
|
1847
|
+
return {
|
|
1848
|
+
protocol: AGENTKIT_PROTOCOL_NAME,
|
|
1849
|
+
version: AGENTKIT_PROTOCOL_VERSION,
|
|
1850
|
+
kind: kind,
|
|
1851
|
+
correlationId: envelope.correlationId,
|
|
1852
|
+
metadata: envelope.metadata,
|
|
1853
|
+
payload,
|
|
1854
|
+
};
|
|
1855
|
+
}
|
|
1856
|
+
export function createAgentProtocolEnvelope(kind, payload, correlationId, metadata) {
|
|
1857
|
+
return {
|
|
1858
|
+
protocol: AGENTKIT_PROTOCOL_NAME,
|
|
1859
|
+
version: AGENTKIT_PROTOCOL_VERSION,
|
|
1860
|
+
kind,
|
|
1861
|
+
correlationId,
|
|
1862
|
+
metadata,
|
|
1863
|
+
payload,
|
|
1864
|
+
};
|
|
1865
|
+
}
|
|
1866
|
+
/** Narrows a message part after validating it at a transport boundary. */
|
|
1867
|
+
export function parseAgentMessagePart(value, path = "part") {
|
|
1868
|
+
validateMessagePart(value, path);
|
|
1869
|
+
return value;
|
|
1870
|
+
}
|
|
1871
|
+
//# sourceMappingURL=validation.js.map
|