@roll-agent/protocol 0.2.0 → 0.4.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.
Files changed (36) hide show
  1. package/README.md +105 -14
  2. package/dist/index.d.ts +9487 -663
  3. package/dist/index.js +1272 -138
  4. package/dist/schema/roll-runtime-protocol-v1.0.schema.json +2657 -0
  5. package/dist/schema/roll-runtime-protocol-v1.1.schema.json +2824 -0
  6. package/dist/schema/roll-runtime-protocol-v1.2.schema.json +4112 -0
  7. package/dist/schema/roll-runtime-protocol-v1.3.schema.json +5695 -0
  8. package/dist/schema/roll-runtime-protocol-v1.schema.json +4061 -1223
  9. package/fixtures/v1/valid-approval-request.json +2 -1
  10. package/fixtures/v1.2/invalid-duplicate-client-capability-method.json +9 -0
  11. package/fixtures/v1.2/invalid-legacy-approval-request.json +15 -0
  12. package/fixtures/v1.2/invalid-legacy-server-request-cancel-notification.json +9 -0
  13. package/fixtures/v1.2/invalid-sensitive-approval-request.json +19 -0
  14. package/fixtures/v1.2/invalid-sensitive-user-input-request.json +20 -0
  15. package/fixtures/v1.2/invalid-thread-snapshot-interaction-payload.json +37 -0
  16. package/fixtures/v1.2/invalid-user-input-request-response.json +13 -0
  17. package/fixtures/v1.2/valid-approval-request.json +22 -0
  18. package/fixtures/v1.2/valid-client-capabilities-set-request.json +9 -0
  19. package/fixtures/v1.2/valid-client-capabilities-set-response.json +8 -0
  20. package/fixtures/v1.2/valid-server-request-cancel-notification.json +8 -0
  21. package/fixtures/v1.2/valid-thread-snapshot-response.json +42 -0
  22. package/fixtures/v1.2/valid-user-input-request-response.json +11 -0
  23. package/fixtures/v1.2/valid-user-input-request.json +35 -0
  24. package/fixtures/v1.3/invalid-durable-delta-event-notification.json +19 -0
  25. package/fixtures/v1.3/invalid-ephemeral-completed-event-notification.json +15 -0
  26. package/fixtures/v1.3/invalid-runtime-events-resume-cursor-request.json +9 -0
  27. package/fixtures/v1.3/invalid-thread-recovery-snapshot-response.json +31 -0
  28. package/fixtures/v1.3/invalid-thread-recovery-snapshot-timestamp-response.json +21 -0
  29. package/fixtures/v1.3/valid-runtime-durable-event-notification.json +20 -0
  30. package/fixtures/v1.3/valid-runtime-ephemeral-event-notification.json +18 -0
  31. package/fixtures/v1.3/valid-runtime-events-resume-request.json +9 -0
  32. package/fixtures/v1.3/valid-runtime-events-resume-response.json +8 -0
  33. package/fixtures/v1.3/valid-thread-recovery-snapshot-request.json +10 -0
  34. package/fixtures/v1.3/valid-thread-recovery-snapshot-response.json +21 -0
  35. package/fixtures/v1.3/valid-thread-snapshot-response.json +20 -0
  36. package/package.json +6 -1
package/dist/index.js CHANGED
@@ -1,26 +1,93 @@
1
1
  import { z } from "zod/v4";
2
- export const SUPPORTED_RUNTIME_PROTOCOL_VERSIONS = ["1.1", "1.0"];
2
+ export const SUPPORTED_RUNTIME_PROTOCOL_VERSIONS_V11 = ["1.1", "1.0"];
3
+ export const SUPPORTED_RUNTIME_PROTOCOL_VERSIONS_V12 = [
4
+ "1.2",
5
+ ...SUPPORTED_RUNTIME_PROTOCOL_VERSIONS_V11,
6
+ ];
7
+ export const SUPPORTED_RUNTIME_PROTOCOL_VERSIONS = [
8
+ "1.3",
9
+ ...SUPPORTED_RUNTIME_PROTOCOL_VERSIONS_V12,
10
+ ];
3
11
  export const RUNTIME_PROTOCOL_VERSION = SUPPORTED_RUNTIME_PROTOCOL_VERSIONS[0];
4
12
  export const RUNTIME_EVENT_NOTIFICATION = "runtime.event";
5
13
  export const RUNTIME_SERVER_REQUEST_CANCEL_NOTIFICATION = "runtime.serverRequest.cancel";
14
+ export const RUNTIME_V13_MAX_DURABLE_EVENT_RECORD_BYTES = 16 * 1_024 * 1_024;
15
+ export const RUNTIME_V13_MAX_DURABLE_EVENT_RECORDS = 10_000;
16
+ /**
17
+ * Advertising Protocol 1.3 is a declaration that the Client accepts at least this many bytes in
18
+ * one Runtime-to-Client NDJSON frame. The margin above the durable record limit covers the bounded
19
+ * Runtime envelope and JSON-RPC notification metadata.
20
+ */
21
+ export const RUNTIME_V13_MIN_CLIENT_FRAME_BYTES = RUNTIME_V13_MAX_DURABLE_EVENT_RECORD_BYTES + 1 * 1_024 * 1_024;
22
+ /** Default bounded window for a complete retained replay batch plus per-envelope metadata. */
23
+ export const RUNTIME_V13_DEFAULT_REPLAY_BUFFER_BYTES = 32 * 1_024 * 1_024;
24
+ /** Recovery Snapshot metadata is clipped because the projection must always fit one Client frame. */
25
+ export const RUNTIME_V13_RECOVERY_SNAPSHOT_METADATA_MAX_CHARS = 1_024;
26
+ export const RUNTIME_V13_RECOVERY_SNAPSHOT_TIMESTAMP_MAX_CHARS = 64;
27
+ export const APPROVAL_EXPLANATION_PREVIEW_KEY = "explanation";
28
+ export const APPROVAL_EXPLANATION_MAX_CHARS = 100;
29
+ export const CLIENT_CAPABILITY_METHOD_MAX_COUNT = 64;
30
+ export const CLIENT_CAPABILITY_METHOD_MAX_CHARS = 100;
31
+ export const USER_INPUT_CONTROL_MAX_COUNT = 16;
32
+ export const USER_INPUT_CONTROL_ID_MAX_CHARS = 64;
33
+ export const USER_INPUT_LABEL_MAX_CHARS = 200;
34
+ export const USER_INPUT_DESCRIPTION_MAX_CHARS = 500;
35
+ export const USER_INPUT_CHOICE_OPTION_MAX_COUNT = 50;
36
+ export const USER_INPUT_TEXT_MAX_CHARS = 10_000;
37
+ export const USER_INPUT_CANCEL_REASON_MAX_CHARS = 500;
38
+ export const INTERACTION_SENSITIVITIES = ["normal"];
6
39
  export const RUNTIME_SERVER_REQUEST_METHODS = {
7
40
  approvalRequest: "approval.request",
41
+ userInputRequest: "userInput.request",
42
+ };
43
+ /** Protocol 1.1 Server Request registry. Keep this list frozen. */
44
+ export const RUNTIME_SERVER_REQUEST_METHOD_VALUES_V11 = [
45
+ RUNTIME_SERVER_REQUEST_METHODS.approvalRequest,
46
+ ];
47
+ export const RUNTIME_SERVER_REQUEST_METHOD_VALUES = [
48
+ ...RUNTIME_SERVER_REQUEST_METHOD_VALUES_V11,
49
+ RUNTIME_SERVER_REQUEST_METHODS.userInputRequest,
50
+ ];
51
+ export const USER_INPUT_CONTROL_TYPES = {
52
+ text: "text",
53
+ multiline: "multiline",
54
+ number: "number",
55
+ boolean: "boolean",
56
+ choice: "choice",
8
57
  };
9
58
  export const RUNTIME_PROTOCOL_CAPABILITIES = {
59
+ "1.2": {
60
+ serverRequests: true,
61
+ serverRequestCapabilityNegotiation: true,
62
+ approvalResolvedEvents: true,
63
+ clientApprovalResponses: false,
64
+ requiredServerRequestMethods: [],
65
+ },
66
+ "1.3": {
67
+ serverRequests: true,
68
+ serverRequestCapabilityNegotiation: true,
69
+ approvalResolvedEvents: true,
70
+ clientApprovalResponses: false,
71
+ requiredServerRequestMethods: [],
72
+ },
10
73
  "1.1": {
11
74
  serverRequests: true,
75
+ serverRequestCapabilityNegotiation: false,
12
76
  approvalResolvedEvents: true,
13
77
  clientApprovalResponses: false,
14
78
  requiredServerRequestMethods: [RUNTIME_SERVER_REQUEST_METHODS.approvalRequest],
15
79
  },
16
80
  "1.0": {
17
81
  serverRequests: false,
82
+ serverRequestCapabilityNegotiation: false,
18
83
  approvalResolvedEvents: false,
19
84
  clientApprovalResponses: true,
20
85
  requiredServerRequestMethods: [],
21
86
  },
22
87
  };
23
88
  export const REQUIRED_RUNTIME_SERVER_REQUEST_METHODS_BY_VERSION = {
89
+ "1.3": RUNTIME_PROTOCOL_CAPABILITIES["1.3"].requiredServerRequestMethods,
90
+ "1.2": RUNTIME_PROTOCOL_CAPABILITIES["1.2"].requiredServerRequestMethods,
24
91
  "1.1": RUNTIME_PROTOCOL_CAPABILITIES["1.1"].requiredServerRequestMethods,
25
92
  "1.0": RUNTIME_PROTOCOL_CAPABILITIES["1.0"].requiredServerRequestMethods,
26
93
  };
@@ -32,10 +99,12 @@ export function isRuntimeServerRequestMethodRequired(version, method) {
32
99
  }
33
100
  export const RUNTIME_METHODS = {
34
101
  initialize: "initialize",
102
+ clientCapabilitiesSet: "client.capabilities.set",
35
103
  threadList: "thread.list",
36
104
  threadCreate: "thread.create",
37
105
  threadOpen: "thread.open",
38
106
  threadSnapshot: "thread.snapshot",
107
+ runtimeEventsResume: "runtime.events.resume",
39
108
  threadRename: "thread.rename",
40
109
  threadDelete: "thread.delete",
41
110
  threadDetach: "thread.detach",
@@ -55,7 +124,7 @@ export const RUNTIME_FEATURES = [
55
124
  "operation-projection",
56
125
  "process-local-sequence",
57
126
  ];
58
- export const RUNTIME_ERROR_CODES = {
127
+ export const RUNTIME_ERROR_CODES_V11 = {
59
128
  protocolVersionUnsupported: "PROTOCOL_VERSION_UNSUPPORTED",
60
129
  initializeRequired: "INITIALIZE_REQUIRED",
61
130
  invalidParams: "INVALID_PARAMS",
@@ -69,6 +138,17 @@ export const RUNTIME_ERROR_CODES = {
69
138
  outcomeUnknown: "OUTCOME_UNKNOWN",
70
139
  internalError: "INTERNAL_ERROR",
71
140
  };
141
+ /** Runtime Protocol 1.2 error registry. Keep this object frozen. */
142
+ export const RUNTIME_ERROR_CODES_V12 = {
143
+ ...RUNTIME_ERROR_CODES_V11,
144
+ capabilityRevisionConflict: "CAPABILITY_REVISION_CONFLICT",
145
+ };
146
+ export const RUNTIME_ERROR_CODES = {
147
+ ...RUNTIME_ERROR_CODES_V12,
148
+ eventCursorExpired: "EVENT_CURSOR_EXPIRED",
149
+ eventCursorGap: "EVENT_CURSOR_GAP",
150
+ };
151
+ export const RUNTIME_ERROR_CODES_V13 = RUNTIME_ERROR_CODES;
72
152
  export const TOOL_OUTCOME_KINDS = [
73
153
  "success",
74
154
  "user_rejected",
@@ -80,14 +160,94 @@ export const TOOL_OUTCOME_KINDS = [
80
160
  export const threadIdSchema = z.string().uuid().brand();
81
161
  export const turnIdSchema = z.string().uuid().brand();
82
162
  export const approvalIdSchema = z.string().uuid().brand();
163
+ export const interactionIdSchema = z.string().uuid().brand();
83
164
  export const runtimeInstanceIdSchema = z.string().uuid().brand();
84
165
  export const requestIdSchema = z.string().uuid().brand();
85
166
  export const streamIdSchema = z.string().uuid().brand();
86
167
  export const operationIdSchema = z.string().uuid().brand();
168
+ export const runtimeEventIdSchema = z.string().uuid().brand();
169
+ export const runtimeEventCursorSchema = z
170
+ .string()
171
+ .max(128)
172
+ .regex(/^rte1:[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}:(?:0|[1-9]\d*):[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/u)
173
+ .brand();
87
174
  export const timestampSchema = z.string().datetime({ offset: true });
88
175
  export const jsonValueSchema = z.json();
89
176
  export const jsonRpcIdSchema = z.union([z.string(), z.number()]);
90
177
  export const runtimeProtocolVersionSchema = z.enum(SUPPORTED_RUNTIME_PROTOCOL_VERSIONS);
178
+ export const runtimeProtocolVersionV12Schema = z.enum(SUPPORTED_RUNTIME_PROTOCOL_VERSIONS_V12);
179
+ export const runtimeProtocolVersionV11Schema = z.enum(SUPPORTED_RUNTIME_PROTOCOL_VERSIONS_V11);
180
+ export const interactionSensitivitySchema = z.enum(INTERACTION_SENSITIVITIES);
181
+ const runtimeInteractionMetadataObjectSchema = z
182
+ .object({
183
+ interactionId: interactionIdSchema,
184
+ threadId: threadIdSchema,
185
+ turnId: turnIdSchema,
186
+ expiresAt: timestampSchema,
187
+ sensitivity: interactionSensitivitySchema,
188
+ })
189
+ .strict();
190
+ export const runtimeInteractionMetadataSchema = runtimeInteractionMetadataObjectSchema.readonly();
191
+ export const approvalExplanationSchema = z
192
+ .string()
193
+ .trim()
194
+ .min(1)
195
+ .max(APPROVAL_EXPLANATION_MAX_CHARS);
196
+ function runtimeEventCursorParts(cursor) {
197
+ const parsed = runtimeEventCursorSchema.parse(cursor);
198
+ const [, eventLogId, threadSequence, eventId] = parsed.split(":");
199
+ if (eventLogId === undefined || threadSequence === undefined || eventId === undefined) {
200
+ throw new Error("Runtime Event cursor has an invalid shape");
201
+ }
202
+ return {
203
+ eventLogId,
204
+ threadSequence: BigInt(threadSequence),
205
+ eventId: runtimeEventIdSchema.parse(eventId),
206
+ };
207
+ }
208
+ function assertComparableRuntimeEventCursors(left, right) {
209
+ if (left.eventLogId !== right.eventLogId) {
210
+ throw new Error("Runtime Event cursors belong to different event logs");
211
+ }
212
+ if (left.threadSequence === right.threadSequence && left.eventId !== right.eventId) {
213
+ throw new Error("Runtime Event cursors conflict at the same Thread sequence");
214
+ }
215
+ }
216
+ /** Compares opaque cursors from one Thread event log without exposing their encoded fields. */
217
+ export function compareRuntimeEventCursors(left, right) {
218
+ if (left === null) {
219
+ return right === null ? 0 : -1;
220
+ }
221
+ if (right === null) {
222
+ return 1;
223
+ }
224
+ const leftParts = runtimeEventCursorParts(left);
225
+ const rightParts = runtimeEventCursorParts(right);
226
+ assertComparableRuntimeEventCursors(leftParts, rightParts);
227
+ if (leftParts.threadSequence < rightParts.threadSequence) {
228
+ return -1;
229
+ }
230
+ if (leftParts.threadSequence > rightParts.threadSequence) {
231
+ return 1;
232
+ }
233
+ return 0;
234
+ }
235
+ /** Returns the signed step distance, treating `null` as the checkpoint before sequence zero. */
236
+ export function runtimeEventCursorDistance(from, to) {
237
+ if (from === null) {
238
+ if (to === null) {
239
+ return 0n;
240
+ }
241
+ return runtimeEventCursorParts(to).threadSequence + 1n;
242
+ }
243
+ if (to === null) {
244
+ return -(runtimeEventCursorParts(from).threadSequence + 1n);
245
+ }
246
+ const fromParts = runtimeEventCursorParts(from);
247
+ const toParts = runtimeEventCursorParts(to);
248
+ assertComparableRuntimeEventCursors(fromParts, toParts);
249
+ return toParts.threadSequence - fromParts.threadSequence;
250
+ }
91
251
  const runtimeClientInfoFields = {
92
252
  name: z.string().trim().min(1).max(100),
93
253
  version: z.string().trim().min(1).max(100),
@@ -100,7 +260,8 @@ export const runtimeServerInfoSchema = z
100
260
  })
101
261
  .strict()
102
262
  .readonly();
103
- export const runtimeLimitsSchema = z
263
+ /** Runtime Protocol 1.2/1.1/1.0 limits. Keep this schema frozen. */
264
+ export const runtimeLimitsV12Schema = z
104
265
  .object({
105
266
  maxFrameBytes: z.number().int().positive(),
106
267
  maxPageSize: z.number().int().positive(),
@@ -109,6 +270,16 @@ export const runtimeLimitsSchema = z
109
270
  })
110
271
  .strict()
111
272
  .readonly();
273
+ export const runtimeLimitsV13Schema = z
274
+ .object({
275
+ maxFrameBytes: z.number().int().positive(),
276
+ maxPageSize: z.number().int().positive(),
277
+ eventReplay: z.literal(true),
278
+ idempotencyCacheEntries: z.number().int().positive(),
279
+ })
280
+ .strict()
281
+ .readonly();
282
+ export const runtimeLimitsSchema = z.union([runtimeLimitsV13Schema, runtimeLimitsV12Schema]);
112
283
  export const initializeParamsSchema = z
113
284
  .object({
114
285
  protocolVersions: z.array(z.string().min(1)).min(1),
@@ -116,13 +287,87 @@ export const initializeParamsSchema = z
116
287
  })
117
288
  .strict()
118
289
  .readonly();
119
- export const initializeResultSchema = z
120
- .object({
121
- protocolVersion: runtimeProtocolVersionSchema,
290
+ const initializeResultCommonFields = {
122
291
  runtimeInstanceId: runtimeInstanceIdSchema,
123
292
  server: runtimeServerInfoSchema,
124
293
  features: z.array(z.enum(RUNTIME_FEATURES)),
125
- limits: runtimeLimitsSchema,
294
+ };
295
+ /** Runtime Protocol 1.1/1.0 initialize result. Keep this schema frozen. */
296
+ export const initializeResultV11Schema = z
297
+ .object({
298
+ protocolVersion: runtimeProtocolVersionV11Schema,
299
+ ...initializeResultCommonFields,
300
+ limits: runtimeLimitsV12Schema,
301
+ })
302
+ .strict()
303
+ .readonly();
304
+ /** Runtime Protocol 1.2 initialize result. */
305
+ export const initializeResultV12Schema = z
306
+ .object({
307
+ protocolVersion: z.literal("1.2"),
308
+ ...initializeResultCommonFields,
309
+ limits: runtimeLimitsV12Schema,
310
+ })
311
+ .strict()
312
+ .readonly();
313
+ export const initializeResultV13Schema = z
314
+ .object({
315
+ protocolVersion: z.literal("1.3"),
316
+ ...initializeResultCommonFields,
317
+ limits: runtimeLimitsV13Schema,
318
+ })
319
+ .strict()
320
+ .readonly();
321
+ /** Any currently supported Runtime Protocol initialize result. */
322
+ export const initializeResultSchema = z.union([
323
+ initializeResultV13Schema,
324
+ initializeResultV12Schema,
325
+ initializeResultV11Schema,
326
+ ]);
327
+ const clientCapabilityMethodNameSchema = z.string().min(1).max(CLIENT_CAPABILITY_METHOD_MAX_CHARS);
328
+ const clientCapabilityMethodNamesSchema = z
329
+ .array(clientCapabilityMethodNameSchema)
330
+ .max(CLIENT_CAPABILITY_METHOD_MAX_COUNT)
331
+ .superRefine((methods, context) => {
332
+ const seen = new Set();
333
+ for (const [index, method] of methods.entries()) {
334
+ if (seen.has(method)) {
335
+ context.addIssue({
336
+ code: "custom",
337
+ message: "serverRequestMethods must not contain duplicates",
338
+ path: [index],
339
+ });
340
+ }
341
+ seen.add(method);
342
+ }
343
+ });
344
+ const acceptedServerRequestMethodsSchema = z
345
+ .array(z.enum(RUNTIME_SERVER_REQUEST_METHODS))
346
+ .max(CLIENT_CAPABILITY_METHOD_MAX_COUNT)
347
+ .superRefine((methods, context) => {
348
+ const seen = new Set();
349
+ for (const [index, method] of methods.entries()) {
350
+ if (seen.has(method)) {
351
+ context.addIssue({
352
+ code: "custom",
353
+ message: "acceptedServerRequestMethods must not contain duplicates",
354
+ path: [index],
355
+ });
356
+ }
357
+ seen.add(method);
358
+ }
359
+ });
360
+ export const clientCapabilitiesSetParamsSchema = z
361
+ .object({
362
+ revision: z.number().int().min(1),
363
+ serverRequestMethods: clientCapabilityMethodNamesSchema,
364
+ })
365
+ .strict()
366
+ .readonly();
367
+ export const clientCapabilitiesSetResultSchema = z
368
+ .object({
369
+ revision: z.number().int().min(1),
370
+ acceptedServerRequestMethods: acceptedServerRequestMethodsSchema,
126
371
  })
127
372
  .strict()
128
373
  .readonly();
@@ -173,7 +418,7 @@ export const operationViewSchema = z
173
418
  })
174
419
  .strict()
175
420
  .readonly();
176
- export const activeTurnSchema = z
421
+ export const activeTurnV11Schema = z
177
422
  .object({
178
423
  id: turnIdSchema,
179
424
  status: z.enum(["running", "cancelling"]),
@@ -181,6 +426,16 @@ export const activeTurnSchema = z
181
426
  })
182
427
  .strict()
183
428
  .readonly();
429
+ export const activeTurnV12Schema = z
430
+ .object({
431
+ id: turnIdSchema,
432
+ status: z.enum(["running", "cancelling", "waiting-for-user"]),
433
+ startedAt: timestampSchema,
434
+ })
435
+ .strict()
436
+ .readonly();
437
+ /** Latest Runtime Protocol active Turn shape. */
438
+ export const activeTurnSchema = activeTurnV12Schema;
184
439
  export const pendingApprovalSchema = z
185
440
  .object({
186
441
  id: approvalIdSchema,
@@ -206,17 +461,337 @@ export const operationPageSchema = z
206
461
  })
207
462
  .strict()
208
463
  .readonly();
209
- export const threadSnapshotSchema = z
210
- .object({
464
+ const threadSnapshotV11Fields = {
211
465
  thread: threadSummarySchema,
212
466
  messages: messagePageSchema,
213
467
  operations: operationPageSchema,
214
- activeTurn: activeTurnSchema.optional(),
468
+ activeTurn: activeTurnV11Schema.optional(),
215
469
  pendingApprovals: z.array(pendingApprovalSchema),
216
470
  transcriptCompleteness: z.enum(["complete", "legacy_snapshot"]),
471
+ };
472
+ /** Protocol 1.1/1.0 wire shape. Keep this schema frozen. */
473
+ export const threadSnapshotV11Schema = z.object(threadSnapshotV11Fields).strict().readonly();
474
+ const userInputIdentifierSchema = z
475
+ .string()
476
+ .min(1)
477
+ .max(USER_INPUT_CONTROL_ID_MAX_CHARS)
478
+ .refine((value) => value.trim().length > 0, { message: "identifier must not be blank" });
479
+ const userInputLabelSchema = z
480
+ .string()
481
+ .min(1)
482
+ .max(USER_INPUT_LABEL_MAX_CHARS)
483
+ .refine((value) => value.trim().length > 0, { message: "label must not be blank" });
484
+ const userInputDescriptionSchema = z.string().min(1).max(USER_INPUT_DESCRIPTION_MAX_CHARS);
485
+ const userInputLengthSchema = z.number().int().min(0).max(USER_INPUT_TEXT_MAX_CHARS);
486
+ const userInputSelectionCountSchema = z
487
+ .number()
488
+ .int()
489
+ .min(0)
490
+ .max(USER_INPUT_CHOICE_OPTION_MAX_COUNT);
491
+ const userInputControlBaseFields = {
492
+ id: userInputIdentifierSchema,
493
+ label: userInputLabelSchema,
494
+ description: userInputDescriptionSchema.optional(),
495
+ required: z.boolean(),
496
+ };
497
+ const userInputTextControlFields = {
498
+ ...userInputControlBaseFields,
499
+ minLength: userInputLengthSchema.optional(),
500
+ maxLength: userInputLengthSchema.optional(),
501
+ };
502
+ export const userInputTextControlSchema = z
503
+ .object({
504
+ type: z.literal(USER_INPUT_CONTROL_TYPES.text),
505
+ ...userInputTextControlFields,
506
+ })
507
+ .strict()
508
+ .superRefine((control, context) => {
509
+ const minimum = Math.max(control.minLength ?? 0, control.required ? 1 : 0);
510
+ const maximum = control.maxLength ?? USER_INPUT_TEXT_MAX_CHARS;
511
+ if (minimum > maximum) {
512
+ context.addIssue({
513
+ code: "custom",
514
+ message: "effective minLength must not exceed maxLength",
515
+ path: ["maxLength"],
516
+ });
517
+ }
518
+ })
519
+ .readonly();
520
+ export const userInputMultilineControlSchema = z
521
+ .object({
522
+ type: z.literal(USER_INPUT_CONTROL_TYPES.multiline),
523
+ ...userInputTextControlFields,
524
+ })
525
+ .strict()
526
+ .superRefine((control, context) => {
527
+ const minimum = Math.max(control.minLength ?? 0, control.required ? 1 : 0);
528
+ const maximum = control.maxLength ?? USER_INPUT_TEXT_MAX_CHARS;
529
+ if (minimum > maximum) {
530
+ context.addIssue({
531
+ code: "custom",
532
+ message: "effective minLength must not exceed maxLength",
533
+ path: ["maxLength"],
534
+ });
535
+ }
536
+ })
537
+ .readonly();
538
+ export const userInputNumberControlSchema = z
539
+ .object({
540
+ type: z.literal(USER_INPUT_CONTROL_TYPES.number),
541
+ ...userInputControlBaseFields,
542
+ min: z.number().finite().optional(),
543
+ max: z.number().finite().optional(),
544
+ integer: z.boolean().optional(),
545
+ })
546
+ .strict()
547
+ .superRefine((control, context) => {
548
+ if (control.min !== undefined && control.max !== undefined && control.min > control.max) {
549
+ context.addIssue({
550
+ code: "custom",
551
+ message: "min must not exceed max",
552
+ path: ["min"],
553
+ });
554
+ }
555
+ if (control.integer === true &&
556
+ Math.ceil(control.min ?? Number.NEGATIVE_INFINITY) >
557
+ Math.floor(control.max ?? Number.POSITIVE_INFINITY)) {
558
+ context.addIssue({
559
+ code: "custom",
560
+ message: "integer bounds must include at least one integer",
561
+ path: ["integer"],
562
+ });
563
+ }
564
+ })
565
+ .readonly();
566
+ export const userInputBooleanControlSchema = z
567
+ .object({
568
+ type: z.literal(USER_INPUT_CONTROL_TYPES.boolean),
569
+ ...userInputControlBaseFields,
570
+ })
571
+ .strict()
572
+ .readonly();
573
+ export const userInputChoiceOptionSchema = z
574
+ .object({
575
+ id: userInputIdentifierSchema,
576
+ label: userInputLabelSchema,
577
+ description: userInputDescriptionSchema.optional(),
578
+ })
579
+ .strict()
580
+ .readonly();
581
+ export const userInputChoiceControlSchema = z
582
+ .object({
583
+ type: z.literal(USER_INPUT_CONTROL_TYPES.choice),
584
+ ...userInputControlBaseFields,
585
+ multiple: z.boolean(),
586
+ options: z.array(userInputChoiceOptionSchema).min(1).max(USER_INPUT_CHOICE_OPTION_MAX_COUNT),
587
+ minSelections: userInputSelectionCountSchema.optional(),
588
+ maxSelections: userInputSelectionCountSchema.min(1).optional(),
589
+ })
590
+ .strict()
591
+ .superRefine((control, context) => {
592
+ const optionIds = new Set();
593
+ for (const [index, option] of control.options.entries()) {
594
+ if (optionIds.has(option.id)) {
595
+ context.addIssue({
596
+ code: "custom",
597
+ message: "choice option ids must be unique",
598
+ path: ["options", index, "id"],
599
+ });
600
+ }
601
+ optionIds.add(option.id);
602
+ }
603
+ const maximum = control.maxSelections ?? (control.multiple ? control.options.length : 1);
604
+ if (control.minSelections !== undefined && control.minSelections > maximum) {
605
+ context.addIssue({
606
+ code: "custom",
607
+ message: "minSelections must not exceed maxSelections",
608
+ path: ["minSelections"],
609
+ });
610
+ }
611
+ if (maximum > control.options.length) {
612
+ context.addIssue({
613
+ code: "custom",
614
+ message: "maxSelections must not exceed the option count",
615
+ path: ["maxSelections"],
616
+ });
617
+ }
618
+ if (!control.multiple &&
619
+ ((control.minSelections !== undefined && control.minSelections > 1) || maximum > 1)) {
620
+ context.addIssue({
621
+ code: "custom",
622
+ message: "single-choice controls allow at most one selection",
623
+ path: [
624
+ control.minSelections !== undefined && control.minSelections > 1
625
+ ? "minSelections"
626
+ : "maxSelections",
627
+ ],
628
+ });
629
+ }
630
+ })
631
+ .readonly();
632
+ export const userInputControlSchema = z.discriminatedUnion("type", [
633
+ userInputTextControlSchema,
634
+ userInputMultilineControlSchema,
635
+ userInputNumberControlSchema,
636
+ userInputBooleanControlSchema,
637
+ userInputChoiceControlSchema,
638
+ ]);
639
+ const userInputControlsSchema = z
640
+ .array(userInputControlSchema)
641
+ .min(1)
642
+ .max(USER_INPUT_CONTROL_MAX_COUNT)
643
+ .superRefine((controls, context) => {
644
+ const controlIds = new Set();
645
+ for (const [index, control] of controls.entries()) {
646
+ if (controlIds.has(control.id)) {
647
+ context.addIssue({
648
+ code: "custom",
649
+ message: "control ids must be unique",
650
+ path: [index, "id"],
651
+ });
652
+ }
653
+ controlIds.add(control.id);
654
+ }
655
+ });
656
+ const userInputFormObjectSchema = z
657
+ .object({
658
+ title: userInputLabelSchema.optional(),
659
+ description: userInputDescriptionSchema.optional(),
660
+ controls: userInputControlsSchema,
661
+ })
662
+ .strict();
663
+ /** Safe model-authored form definition shared by Runtime, clients and first-party UI. */
664
+ export const userInputFormSchema = userInputFormObjectSchema.readonly();
665
+ const userInputRequestParamsV12ObjectSchema = runtimeInteractionMetadataObjectSchema.extend(userInputFormObjectSchema.shape);
666
+ export const userInputRequestParamsV12Schema = userInputRequestParamsV12ObjectSchema.readonly();
667
+ export const userInputValueSchema = z.union([
668
+ z.string().max(USER_INPUT_TEXT_MAX_CHARS),
669
+ z.number().finite(),
670
+ z.boolean(),
671
+ z.array(z.string().max(USER_INPUT_CONTROL_ID_MAX_CHARS)).max(USER_INPUT_CHOICE_OPTION_MAX_COUNT),
672
+ ]);
673
+ export const userInputSubmittedValueSchema = z
674
+ .object({
675
+ id: userInputIdentifierSchema,
676
+ value: userInputValueSchema,
677
+ })
678
+ .strict()
679
+ .readonly();
680
+ export const userInputSubmittedResultSchema = z
681
+ .object({
682
+ status: z.literal("submitted"),
683
+ values: z.array(userInputSubmittedValueSchema).max(USER_INPUT_CONTROL_MAX_COUNT),
684
+ })
685
+ .strict()
686
+ .readonly();
687
+ export const userInputCancelledResultSchema = z
688
+ .object({
689
+ status: z.literal("cancelled"),
690
+ reason: z.string().min(1).max(USER_INPUT_CANCEL_REASON_MAX_CHARS).optional(),
217
691
  })
218
692
  .strict()
219
693
  .readonly();
694
+ export const userInputResultSchema = z.discriminatedUnion("status", [
695
+ userInputSubmittedResultSchema,
696
+ userInputCancelledResultSchema,
697
+ ]);
698
+ export const pendingApprovalInteractionProjectionSchema = z
699
+ .object({
700
+ method: z.literal(RUNTIME_SERVER_REQUEST_METHODS.approvalRequest),
701
+ interactionId: interactionIdSchema,
702
+ threadId: threadIdSchema,
703
+ turnId: turnIdSchema,
704
+ expiresAt: timestampSchema,
705
+ sensitivity: z.literal("normal"),
706
+ approvalId: approvalIdSchema,
707
+ })
708
+ .strict()
709
+ .readonly();
710
+ export const pendingUserInputInteractionProjectionSchema = userInputRequestParamsV12ObjectSchema
711
+ .extend({
712
+ method: z.literal(RUNTIME_SERVER_REQUEST_METHODS.userInputRequest),
713
+ })
714
+ .readonly();
715
+ export const pendingInteractionProjectionSchema = z.discriminatedUnion("method", [
716
+ pendingApprovalInteractionProjectionSchema,
717
+ pendingUserInputInteractionProjectionSchema,
718
+ ]);
719
+ const threadSnapshotV12Fields = {
720
+ ...threadSnapshotV11Fields,
721
+ activeTurn: activeTurnV12Schema.optional(),
722
+ pendingInteractions: z.array(pendingInteractionProjectionSchema),
723
+ };
724
+ /** Runtime Protocol 1.2 snapshot. Keep this schema frozen. */
725
+ export const threadSnapshotV12Schema = z.object(threadSnapshotV12Fields).strict().readonly();
726
+ export const threadSnapshotV13FullSchema = z
727
+ .object({
728
+ ...threadSnapshotV12Fields,
729
+ eventCursor: runtimeEventCursorSchema.nullable(),
730
+ })
731
+ .strict()
732
+ .readonly();
733
+ const recoveryThreadSummarySchema = z
734
+ .object({
735
+ id: threadIdSchema,
736
+ title: z.string().max(RUNTIME_V13_RECOVERY_SNAPSHOT_METADATA_MAX_CHARS).optional(),
737
+ model: z.string().max(RUNTIME_V13_RECOVERY_SNAPSHOT_METADATA_MAX_CHARS).optional(),
738
+ createdAt: z
739
+ .string()
740
+ .max(RUNTIME_V13_RECOVERY_SNAPSHOT_TIMESTAMP_MAX_CHARS)
741
+ .datetime({ offset: true }),
742
+ updatedAt: z
743
+ .string()
744
+ .max(RUNTIME_V13_RECOVERY_SNAPSHOT_TIMESTAMP_MAX_CHARS)
745
+ .datetime({ offset: true }),
746
+ messageCount: z.number().int().nonnegative(),
747
+ })
748
+ .strict()
749
+ .readonly();
750
+ const recoveryMessagePageSchema = z
751
+ .object({
752
+ items: z.array(uiMessageSchema).max(0),
753
+ nextBeforeSequence: z.null(),
754
+ })
755
+ .strict()
756
+ .readonly();
757
+ const recoveryOperationPageSchema = z
758
+ .object({
759
+ items: z.array(operationViewSchema).max(0),
760
+ nextBeforeSequence: z.null(),
761
+ })
762
+ .strict()
763
+ .readonly();
764
+ const recoveryActiveTurnSchema = z
765
+ .object({
766
+ id: turnIdSchema,
767
+ status: z.enum(["running", "cancelling", "waiting-for-user"]),
768
+ startedAt: z
769
+ .string()
770
+ .max(RUNTIME_V13_RECOVERY_SNAPSHOT_TIMESTAMP_MAX_CHARS)
771
+ .datetime({ offset: true }),
772
+ })
773
+ .strict()
774
+ .readonly();
775
+ export const threadRecoverySnapshotV13Schema = z
776
+ .object({
777
+ ...threadSnapshotV12Fields,
778
+ thread: recoveryThreadSummarySchema,
779
+ messages: recoveryMessagePageSchema,
780
+ operations: recoveryOperationPageSchema,
781
+ pendingApprovals: z.array(pendingApprovalSchema).max(0),
782
+ pendingInteractions: z.array(pendingInteractionProjectionSchema).max(0),
783
+ activeTurn: recoveryActiveTurnSchema.optional(),
784
+ eventCursor: runtimeEventCursorSchema.nullable(),
785
+ recoveryProjection: z.literal(true),
786
+ })
787
+ .strict()
788
+ .readonly();
789
+ export const threadSnapshotV13Schema = z.union([
790
+ threadSnapshotV13FullSchema,
791
+ threadRecoverySnapshotV13Schema,
792
+ ]);
793
+ /** Latest Runtime Protocol snapshot. Use versioned schemas for compatibility. */
794
+ export const threadSnapshotSchema = threadSnapshotV13Schema;
220
795
  const pageSizeSchema = z.number().int().min(1).max(500).default(100);
221
796
  const requestFields = { requestId: requestIdSchema };
222
797
  const threadRequestFields = { threadId: threadIdSchema };
@@ -248,17 +823,47 @@ export const threadCreateResultSchema = z
248
823
  .strict()
249
824
  .readonly();
250
825
  export const threadOpenParamsSchema = z.object(threadRequestFields).strict().readonly();
826
+ export const threadOpenResultV11Schema = threadSnapshotV11Schema;
251
827
  export const threadOpenResultSchema = threadSnapshotSchema;
252
- export const threadSnapshotParamsSchema = z
253
- .object({
828
+ const threadSnapshotParamFields = {
254
829
  ...threadRequestFields,
255
830
  messageBeforeSequence: z.number().int().nonnegative().optional(),
256
831
  operationBeforeSequence: z.number().int().nonnegative().optional(),
257
832
  limit: pageSizeSchema,
833
+ };
834
+ /** Runtime Protocol 1.2/1.1/1.0 request shape. Keep this schema frozen. */
835
+ export const threadSnapshotParamsV12Schema = z
836
+ .object({
837
+ ...threadSnapshotParamFields,
258
838
  })
259
839
  .strict()
260
840
  .readonly();
841
+ export const threadSnapshotParamsV13Schema = z
842
+ .object({
843
+ ...threadSnapshotParamFields,
844
+ recovery: z.literal(true).optional(),
845
+ })
846
+ .strict()
847
+ .readonly();
848
+ /** Latest Runtime Protocol request shape. Use the versioned schemas for compatibility. */
849
+ export const threadSnapshotParamsSchema = threadSnapshotParamsV13Schema;
850
+ export const threadSnapshotResultV11Schema = threadSnapshotV11Schema;
851
+ export const threadSnapshotResultV12Schema = threadSnapshotV12Schema;
261
852
  export const threadSnapshotResultSchema = threadSnapshotSchema;
853
+ export const runtimeEventsResumeParamsSchema = z
854
+ .object({
855
+ ...threadRequestFields,
856
+ afterCursor: runtimeEventCursorSchema.nullable(),
857
+ })
858
+ .strict()
859
+ .readonly();
860
+ export const runtimeEventsResumeResultSchema = z
861
+ .object({
862
+ throughCursor: runtimeEventCursorSchema.nullable(),
863
+ replayedCount: z.number().int().nonnegative(),
864
+ })
865
+ .strict()
866
+ .readonly();
262
867
  export const threadRenameParamsSchema = z
263
868
  .object({
264
869
  ...requestFields,
@@ -347,6 +952,28 @@ export const approvalRequestParamsSchema = z
347
952
  })
348
953
  .strict()
349
954
  .readonly();
955
+ /** Protocol 1.1 wire shape. Keep this alias frozen with approvalRequestParamsSchema. */
956
+ export const approvalRequestParamsV11Schema = approvalRequestParamsSchema;
957
+ export const approvalRequestParamsV12Schema = z
958
+ .object({
959
+ interactionId: interactionIdSchema,
960
+ threadId: threadIdSchema,
961
+ turnId: turnIdSchema,
962
+ expiresAt: timestampSchema,
963
+ sensitivity: z.literal("normal"),
964
+ approval: pendingApprovalSchema,
965
+ })
966
+ .strict()
967
+ .superRefine((value, context) => {
968
+ if (value.turnId !== value.approval.turnId) {
969
+ context.addIssue({
970
+ code: "custom",
971
+ message: "approval.turnId must match interaction turnId",
972
+ path: ["approval", "turnId"],
973
+ });
974
+ }
975
+ })
976
+ .readonly();
350
977
  export const approvalRequestResultSchema = z.discriminatedUnion("decision", [
351
978
  z
352
979
  .object({
@@ -370,6 +997,24 @@ export const runtimeServerRequestCancelParamsSchema = z
370
997
  })
371
998
  .strict()
372
999
  .readonly();
1000
+ /** Protocol 1.1 wire shape. Keep this alias frozen with runtimeServerRequestCancelParamsSchema. */
1001
+ export const runtimeServerRequestCancelParamsV11Schema = runtimeServerRequestCancelParamsSchema;
1002
+ export const runtimeServerRequestCancelParamsV12Schema = z
1003
+ .object({
1004
+ interactionId: interactionIdSchema,
1005
+ reason: z.string().min(1),
1006
+ })
1007
+ .strict()
1008
+ .readonly();
1009
+ export const runtimeServerRequestCancelProjectionInputSchema = z
1010
+ .object({
1011
+ interactionId: interactionIdSchema,
1012
+ serverRequestId: jsonRpcIdSchema,
1013
+ approvalId: approvalIdSchema.optional(),
1014
+ reason: z.string().min(1),
1015
+ })
1016
+ .strict()
1017
+ .readonly();
373
1018
  export const operationGetParamsSchema = z
374
1019
  .object({
375
1020
  ...threadRequestFields,
@@ -414,127 +1059,144 @@ export const approvalResolutionSchema = z.union([
414
1059
  .strict()
415
1060
  .readonly(),
416
1061
  ]);
417
- export const runtimeEventSchema = z.discriminatedUnion("type", [
418
- z
419
- .object({ type: z.literal("turn.started") })
420
- .strict()
421
- .readonly(),
422
- z
423
- .object({
424
- type: z.literal("message.started"),
425
- streamId: streamIdSchema,
426
- })
427
- .strict()
428
- .readonly(),
429
- z
430
- .object({
431
- type: z.literal("message.delta"),
432
- streamId: streamIdSchema,
433
- delta: z.string(),
434
- })
435
- .strict()
436
- .readonly(),
437
- z
438
- .object({
439
- type: z.literal("message.completed"),
440
- streamId: streamIdSchema,
441
- text: z.string(),
442
- })
443
- .strict()
444
- .readonly(),
445
- z
446
- .object({
447
- type: z.literal("reasoning.summary.delta"),
448
- reasoningId: z.string().min(1),
449
- delta: z.string(),
450
- })
451
- .strict()
452
- .readonly(),
453
- z
454
- .object({
455
- type: z.literal("tool.started"),
456
- toolCallId: z.string().min(1),
457
- agentName: z.string().min(1),
458
- toolName: z.string().min(1),
459
- input: jsonValueSchema,
460
- })
461
- .strict()
462
- .readonly(),
463
- z
464
- .object({
465
- type: z.literal("tool.output"),
466
- toolCallId: z.string().min(1),
467
- agentName: z.string().min(1),
468
- toolName: z.string().min(1),
469
- stream: z.enum(["stdout", "stderr"]),
470
- delta: z.string(),
471
- })
472
- .strict()
473
- .readonly(),
474
- z
475
- .object({
476
- type: z.literal("tool.completed"),
477
- toolCallId: z.string().min(1),
478
- agentName: z.string().min(1),
479
- toolName: z.string().min(1),
480
- operationId: operationIdSchema.optional(),
481
- outcome: toolOutcomeSchema.optional(),
482
- display: jsonValueSchema,
483
- })
484
- .strict()
485
- .readonly(),
486
- z
487
- .object({
488
- type: z.literal("approval.required"),
489
- approval: pendingApprovalSchema,
490
- })
491
- .strict()
492
- .readonly(),
493
- z
494
- .object({
495
- type: z.literal("approval.resolved"),
496
- approvalId: approvalIdSchema,
497
- resolution: approvalResolutionSchema,
498
- })
499
- .strict()
500
- .readonly(),
501
- z
502
- .object({ type: z.literal("turn.completed") })
503
- .strict()
504
- .readonly(),
505
- z
506
- .object({
507
- type: z.literal("turn.cancelled"),
508
- reason: z.string(),
509
- message: z.string(),
510
- })
511
- .strict()
512
- .readonly(),
513
- z
514
- .object({
515
- type: z.literal("turn.failed"),
516
- stage: z.enum(["bootstrap", "plan", "execute"]),
517
- message: z.string(),
518
- })
519
- .strict()
520
- .readonly(),
521
- z
522
- .object({ type: z.literal("capabilities.changed") })
523
- .strict()
524
- .readonly(),
525
- ]);
526
- export const runtimeEventEnvelopeSchema = z
1062
+ const turnStartedEventSchema = z
1063
+ .object({ type: z.literal("turn.started") })
1064
+ .strict()
1065
+ .readonly();
1066
+ const messageStartedEventSchema = z
1067
+ .object({ type: z.literal("message.started"), streamId: streamIdSchema })
1068
+ .strict()
1069
+ .readonly();
1070
+ const messageDeltaEventSchema = z
1071
+ .object({ type: z.literal("message.delta"), streamId: streamIdSchema, delta: z.string() })
1072
+ .strict()
1073
+ .readonly();
1074
+ const messageCompletedEventSchema = z
1075
+ .object({ type: z.literal("message.completed"), streamId: streamIdSchema, text: z.string() })
1076
+ .strict()
1077
+ .readonly();
1078
+ const reasoningSummaryDeltaEventSchema = z
527
1079
  .object({
528
- protocolVersion: runtimeProtocolVersionSchema,
1080
+ type: z.literal("reasoning.summary.delta"),
1081
+ reasoningId: z.string().min(1),
1082
+ delta: z.string(),
1083
+ })
1084
+ .strict()
1085
+ .readonly();
1086
+ const toolStartedEventSchema = z
1087
+ .object({
1088
+ type: z.literal("tool.started"),
1089
+ toolCallId: z.string().min(1),
1090
+ agentName: z.string().min(1),
1091
+ toolName: z.string().min(1),
1092
+ input: jsonValueSchema,
1093
+ })
1094
+ .strict()
1095
+ .readonly();
1096
+ const toolOutputEventSchema = z
1097
+ .object({
1098
+ type: z.literal("tool.output"),
1099
+ toolCallId: z.string().min(1),
1100
+ agentName: z.string().min(1),
1101
+ toolName: z.string().min(1),
1102
+ stream: z.enum(["stdout", "stderr"]),
1103
+ delta: z.string(),
1104
+ })
1105
+ .strict()
1106
+ .readonly();
1107
+ const toolCompletedEventSchema = z
1108
+ .object({
1109
+ type: z.literal("tool.completed"),
1110
+ toolCallId: z.string().min(1),
1111
+ agentName: z.string().min(1),
1112
+ toolName: z.string().min(1),
1113
+ operationId: operationIdSchema.optional(),
1114
+ outcome: toolOutcomeSchema.optional(),
1115
+ display: jsonValueSchema,
1116
+ })
1117
+ .strict()
1118
+ .readonly();
1119
+ const approvalRequiredEventSchema = z
1120
+ .object({ type: z.literal("approval.required"), approval: pendingApprovalSchema })
1121
+ .strict()
1122
+ .readonly();
1123
+ const approvalResolvedEventSchema = z
1124
+ .object({
1125
+ type: z.literal("approval.resolved"),
1126
+ approvalId: approvalIdSchema,
1127
+ resolution: approvalResolutionSchema,
1128
+ })
1129
+ .strict()
1130
+ .readonly();
1131
+ const turnCompletedEventSchema = z
1132
+ .object({ type: z.literal("turn.completed") })
1133
+ .strict()
1134
+ .readonly();
1135
+ const turnCancelledEventSchema = z
1136
+ .object({ type: z.literal("turn.cancelled"), reason: z.string(), message: z.string() })
1137
+ .strict()
1138
+ .readonly();
1139
+ const turnFailedEventSchema = z
1140
+ .object({
1141
+ type: z.literal("turn.failed"),
1142
+ stage: z.enum(["bootstrap", "plan", "execute"]),
1143
+ message: z.string(),
1144
+ })
1145
+ .strict()
1146
+ .readonly();
1147
+ const capabilitiesChangedEventSchema = z
1148
+ .object({ type: z.literal("capabilities.changed") })
1149
+ .strict()
1150
+ .readonly();
1151
+ /** Runtime Protocol 1.1/1.0 event payloads. Keep this registry and ordering frozen. */
1152
+ export const runtimeEventV11Schema = z.discriminatedUnion("type", [
1153
+ turnStartedEventSchema,
1154
+ messageStartedEventSchema,
1155
+ messageDeltaEventSchema,
1156
+ messageCompletedEventSchema,
1157
+ reasoningSummaryDeltaEventSchema,
1158
+ toolStartedEventSchema,
1159
+ toolOutputEventSchema,
1160
+ toolCompletedEventSchema,
1161
+ approvalRequiredEventSchema,
1162
+ approvalResolvedEventSchema,
1163
+ turnCompletedEventSchema,
1164
+ turnCancelledEventSchema,
1165
+ turnFailedEventSchema,
1166
+ capabilitiesChangedEventSchema,
1167
+ ]);
1168
+ export const runtimeDurableEventV13Schema = z.discriminatedUnion("type", [
1169
+ turnStartedEventSchema,
1170
+ messageCompletedEventSchema,
1171
+ toolCompletedEventSchema,
1172
+ approvalRequiredEventSchema,
1173
+ approvalResolvedEventSchema,
1174
+ turnCompletedEventSchema,
1175
+ turnCancelledEventSchema,
1176
+ turnFailedEventSchema,
1177
+ capabilitiesChangedEventSchema,
1178
+ ]);
1179
+ export const runtimeEphemeralEventV13Schema = z.discriminatedUnion("type", [
1180
+ messageStartedEventSchema,
1181
+ messageDeltaEventSchema,
1182
+ reasoningSummaryDeltaEventSchema,
1183
+ toolStartedEventSchema,
1184
+ toolOutputEventSchema,
1185
+ ]);
1186
+ /** Runtime Protocol 1.2 event payloads. Currently identical to the 1.1 payload registry. */
1187
+ export const runtimeEventV12Schema = runtimeEventV11Schema;
1188
+ /** Runtime Protocol 1.3 retains the event payload registry and versions durability in the envelope. */
1189
+ export const runtimeEventV13Schema = runtimeEventV12Schema;
1190
+ /** Latest Runtime Protocol event payloads. */
1191
+ export const runtimeEventSchema = runtimeEventV13Schema;
1192
+ const runtimeEventEnvelopeFields = {
529
1193
  runtimeInstanceId: runtimeInstanceIdSchema,
530
1194
  sequence: z.number().int().nonnegative(),
531
1195
  timestamp: timestampSchema,
532
1196
  threadId: threadIdSchema,
533
1197
  turnId: turnIdSchema.optional(),
534
- event: runtimeEventSchema,
535
- })
536
- .strict()
537
- .superRefine((value, context) => {
1198
+ };
1199
+ function validateRuntimeEventCapabilities(value, context) {
538
1200
  if (!getRuntimeProtocolCapabilities(value.protocolVersion).approvalResolvedEvents &&
539
1201
  value.event.type === "approval.resolved") {
540
1202
  context.addIssue({
@@ -543,20 +1205,89 @@ export const runtimeEventEnvelopeSchema = z
543
1205
  path: ["event", "type"],
544
1206
  });
545
1207
  }
1208
+ }
1209
+ /** Runtime Protocol 1.1/1.0 event envelope. Keep this schema frozen. */
1210
+ export const runtimeEventEnvelopeV11Schema = z
1211
+ .object({
1212
+ protocolVersion: runtimeProtocolVersionV11Schema,
1213
+ ...runtimeEventEnvelopeFields,
1214
+ event: runtimeEventV11Schema,
546
1215
  })
1216
+ .strict()
1217
+ .superRefine(validateRuntimeEventCapabilities)
1218
+ .readonly();
1219
+ /** Runtime Protocol 1.2 event envelope. Keep this schema frozen. */
1220
+ export const runtimeEventEnvelopeV12Schema = z
1221
+ .object({
1222
+ protocolVersion: z.literal("1.2"),
1223
+ ...runtimeEventEnvelopeFields,
1224
+ event: runtimeEventV12Schema,
1225
+ })
1226
+ .strict()
1227
+ .superRefine(validateRuntimeEventCapabilities)
1228
+ .readonly();
1229
+ export const runtimeDurableEventEnvelopeV13Schema = z
1230
+ .object({
1231
+ protocolVersion: z.literal("1.3"),
1232
+ ...runtimeEventEnvelopeFields,
1233
+ durability: z.literal("durable"),
1234
+ eventId: runtimeEventIdSchema,
1235
+ cursor: runtimeEventCursorSchema,
1236
+ event: runtimeDurableEventV13Schema,
1237
+ })
1238
+ .strict()
1239
+ .superRefine(validateRuntimeEventCapabilities)
547
1240
  .readonly();
1241
+ export const runtimeEphemeralEventEnvelopeV13Schema = z
1242
+ .object({
1243
+ protocolVersion: z.literal("1.3"),
1244
+ ...runtimeEventEnvelopeFields,
1245
+ durability: z.literal("ephemeral"),
1246
+ event: runtimeEphemeralEventV13Schema,
1247
+ })
1248
+ .strict()
1249
+ .superRefine(validateRuntimeEventCapabilities)
1250
+ .readonly();
1251
+ export const runtimeEventEnvelopeV13Schema = z.discriminatedUnion("durability", [
1252
+ runtimeDurableEventEnvelopeV13Schema,
1253
+ runtimeEphemeralEventEnvelopeV13Schema,
1254
+ ]);
1255
+ /** Any currently supported Runtime Event envelope. */
1256
+ export const runtimeEventEnvelopeSchema = z.union([
1257
+ runtimeEventEnvelopeV13Schema,
1258
+ runtimeEventEnvelopeV12Schema,
1259
+ runtimeEventEnvelopeV11Schema,
1260
+ ]);
548
1261
  export const runtimeProtocolErrorDataSchema = z
549
1262
  .object({
550
- rollCode: z.enum(Object.values(RUNTIME_ERROR_CODES)),
1263
+ rollCode: z.enum(Object.values(RUNTIME_ERROR_CODES_V11)),
1264
+ retryable: z.boolean(),
1265
+ details: jsonValueSchema.optional(),
1266
+ })
1267
+ .strict()
1268
+ .readonly();
1269
+ /** Protocol 1.1 wire shape. Keep this alias frozen with runtimeProtocolErrorDataSchema. */
1270
+ export const runtimeProtocolErrorDataV11Schema = runtimeProtocolErrorDataSchema;
1271
+ export const runtimeProtocolErrorDataV12Schema = z
1272
+ .object({
1273
+ rollCode: z.enum(Object.values(RUNTIME_ERROR_CODES_V12)),
1274
+ retryable: z.boolean(),
1275
+ details: jsonValueSchema.optional(),
1276
+ })
1277
+ .strict()
1278
+ .readonly();
1279
+ export const runtimeProtocolErrorDataV13Schema = z
1280
+ .object({
1281
+ rollCode: z.enum(Object.values(RUNTIME_ERROR_CODES_V13)),
551
1282
  retryable: z.boolean(),
552
1283
  details: jsonValueSchema.optional(),
553
1284
  })
554
1285
  .strict()
555
1286
  .readonly();
556
- export const runtimeMethodSchemas = {
1287
+ export const runtimeMethodSchemasV11 = {
557
1288
  [RUNTIME_METHODS.initialize]: {
558
1289
  params: initializeParamsSchema,
559
- result: initializeResultSchema,
1290
+ result: initializeResultV11Schema,
560
1291
  },
561
1292
  [RUNTIME_METHODS.threadList]: {
562
1293
  params: threadListParamsSchema,
@@ -568,11 +1299,11 @@ export const runtimeMethodSchemas = {
568
1299
  },
569
1300
  [RUNTIME_METHODS.threadOpen]: {
570
1301
  params: threadOpenParamsSchema,
571
- result: threadOpenResultSchema,
1302
+ result: threadOpenResultV11Schema,
572
1303
  },
573
1304
  [RUNTIME_METHODS.threadSnapshot]: {
574
- params: threadSnapshotParamsSchema,
575
- result: threadSnapshotResultSchema,
1305
+ params: threadSnapshotParamsV12Schema,
1306
+ result: threadSnapshotResultV11Schema,
576
1307
  },
577
1308
  [RUNTIME_METHODS.threadRename]: {
578
1309
  params: threadRenameParamsSchema,
@@ -607,24 +1338,427 @@ export const runtimeMethodSchemas = {
607
1338
  result: operationGetResultSchema,
608
1339
  },
609
1340
  };
610
- export const runtimeServerRequestSchemas = {
1341
+ export const runtimeMethodSchemasV10 = runtimeMethodSchemasV11;
1342
+ export const runtimeMethodSchemasV12 = {
1343
+ ...runtimeMethodSchemasV11,
1344
+ [RUNTIME_METHODS.initialize]: {
1345
+ params: initializeParamsSchema,
1346
+ result: initializeResultV12Schema,
1347
+ },
1348
+ [RUNTIME_METHODS.threadOpen]: {
1349
+ params: threadOpenParamsSchema,
1350
+ result: threadSnapshotV12Schema,
1351
+ },
1352
+ [RUNTIME_METHODS.threadSnapshot]: {
1353
+ params: threadSnapshotParamsV12Schema,
1354
+ result: threadSnapshotResultV12Schema,
1355
+ },
1356
+ [RUNTIME_METHODS.clientCapabilitiesSet]: {
1357
+ params: clientCapabilitiesSetParamsSchema,
1358
+ result: clientCapabilitiesSetResultSchema,
1359
+ },
1360
+ };
1361
+ export const runtimeMethodSchemasV13 = {
1362
+ ...runtimeMethodSchemasV12,
1363
+ [RUNTIME_METHODS.initialize]: {
1364
+ params: initializeParamsSchema,
1365
+ result: initializeResultV13Schema,
1366
+ },
1367
+ [RUNTIME_METHODS.threadOpen]: {
1368
+ params: threadOpenParamsSchema,
1369
+ result: threadOpenResultSchema,
1370
+ },
1371
+ [RUNTIME_METHODS.threadSnapshot]: {
1372
+ params: threadSnapshotParamsV13Schema,
1373
+ result: threadSnapshotResultSchema,
1374
+ },
1375
+ [RUNTIME_METHODS.runtimeEventsResume]: {
1376
+ params: runtimeEventsResumeParamsSchema,
1377
+ result: runtimeEventsResumeResultSchema,
1378
+ },
1379
+ };
1380
+ /** Latest Runtime method registry. Use the version registry for negotiated availability. */
1381
+ export const runtimeMethodSchemas = runtimeMethodSchemasV13;
1382
+ export const runtimeServerRequestSchemasV10 = {};
1383
+ export const runtimeServerRequestSchemasV11 = {
611
1384
  [RUNTIME_SERVER_REQUEST_METHODS.approvalRequest]: {
612
1385
  params: approvalRequestParamsSchema,
613
1386
  result: approvalRequestResultSchema,
614
1387
  },
615
1388
  };
1389
+ export const runtimeServerRequestSchemasV12 = {
1390
+ [RUNTIME_SERVER_REQUEST_METHODS.approvalRequest]: {
1391
+ params: approvalRequestParamsV12Schema,
1392
+ result: approvalRequestResultSchema,
1393
+ },
1394
+ [RUNTIME_SERVER_REQUEST_METHODS.userInputRequest]: {
1395
+ params: userInputRequestParamsV12Schema,
1396
+ result: userInputResultSchema,
1397
+ },
1398
+ };
1399
+ export const runtimeServerRequestSchemasV13 = runtimeServerRequestSchemasV12;
1400
+ /** Protocol 1.1 compatibility facade. Prefer the version registry in new code. */
1401
+ export const runtimeServerRequestSchemas = runtimeServerRequestSchemasV11;
1402
+ export const RUNTIME_PROTOCOL_REGISTRY = {
1403
+ "1.3": {
1404
+ methods: runtimeMethodSchemasV13,
1405
+ serverRequests: runtimeServerRequestSchemasV13,
1406
+ serverRequestMethods: RUNTIME_SERVER_REQUEST_METHOD_VALUES,
1407
+ serverRequestCancelParamsSchema: runtimeServerRequestCancelParamsV12Schema,
1408
+ eventEnvelopeSchema: runtimeEventEnvelopeV13Schema,
1409
+ errorDataSchema: runtimeProtocolErrorDataV13Schema,
1410
+ },
1411
+ "1.2": {
1412
+ methods: runtimeMethodSchemasV12,
1413
+ serverRequests: runtimeServerRequestSchemasV12,
1414
+ serverRequestMethods: RUNTIME_SERVER_REQUEST_METHOD_VALUES,
1415
+ serverRequestCancelParamsSchema: runtimeServerRequestCancelParamsV12Schema,
1416
+ eventEnvelopeSchema: runtimeEventEnvelopeV12Schema,
1417
+ errorDataSchema: runtimeProtocolErrorDataV12Schema,
1418
+ },
1419
+ "1.1": {
1420
+ methods: runtimeMethodSchemasV11,
1421
+ serverRequests: runtimeServerRequestSchemasV11,
1422
+ serverRequestMethods: RUNTIME_SERVER_REQUEST_METHOD_VALUES_V11,
1423
+ serverRequestCancelParamsSchema: runtimeServerRequestCancelParamsV11Schema,
1424
+ eventEnvelopeSchema: runtimeEventEnvelopeV11Schema,
1425
+ errorDataSchema: runtimeProtocolErrorDataV11Schema,
1426
+ },
1427
+ "1.0": {
1428
+ methods: runtimeMethodSchemasV10,
1429
+ serverRequests: runtimeServerRequestSchemasV10,
1430
+ serverRequestMethods: [],
1431
+ serverRequestCancelParamsSchema: null,
1432
+ eventEnvelopeSchema: runtimeEventEnvelopeV11Schema,
1433
+ errorDataSchema: runtimeProtocolErrorDataV11Schema,
1434
+ },
1435
+ };
1436
+ export function getRuntimeProtocolRegistry(version) {
1437
+ return RUNTIME_PROTOCOL_REGISTRY[version];
1438
+ }
1439
+ export function isRuntimeMethodAvailable(version, method) {
1440
+ return Object.hasOwn(getRuntimeProtocolRegistry(version).methods, method);
1441
+ }
1442
+ export function isRuntimeServerRequestMethodAvailable(version, method) {
1443
+ return Object.hasOwn(getRuntimeProtocolRegistry(version).serverRequests, method);
1444
+ }
1445
+ export function projectClientCapabilitiesSetResult(value) {
1446
+ const params = clientCapabilitiesSetParamsSchema.parse(value);
1447
+ const requested = new Set(params.serverRequestMethods);
1448
+ return clientCapabilitiesSetResultSchema.parse({
1449
+ revision: params.revision,
1450
+ acceptedServerRequestMethods: RUNTIME_PROTOCOL_REGISTRY[RUNTIME_PROTOCOL_VERSION].serverRequestMethods.filter((method) => requested.has(method)),
1451
+ });
1452
+ }
1453
+ export function getApprovalExplanation(approval) {
1454
+ const preview = approval.preview;
1455
+ if (typeof preview !== "object" || preview === null || Array.isArray(preview)) {
1456
+ return undefined;
1457
+ }
1458
+ const parsed = approvalExplanationSchema.safeParse(preview[APPROVAL_EXPLANATION_PREVIEW_KEY]);
1459
+ return parsed.success ? parsed.data : undefined;
1460
+ }
1461
+ function validateUserInputTextValue(control, value, path, addIssue) {
1462
+ if (typeof value !== "string") {
1463
+ addIssue(path, `${control.type} control requires a string value`);
1464
+ return;
1465
+ }
1466
+ const minimum = Math.max(control.minLength ?? 0, control.required ? 1 : 0);
1467
+ const maximum = control.maxLength ?? USER_INPUT_TEXT_MAX_CHARS;
1468
+ if (value.length < minimum) {
1469
+ addIssue(path, `string value must contain at least ${String(minimum)} characters`);
1470
+ }
1471
+ if (value.length > maximum) {
1472
+ addIssue(path, `string value must contain at most ${String(maximum)} characters`);
1473
+ }
1474
+ }
1475
+ const USER_INPUT_VALUE_VALIDATORS = {
1476
+ [USER_INPUT_CONTROL_TYPES.text]: ((control, value, path, addIssue) => {
1477
+ validateUserInputTextValue(userInputTextControlSchema.parse(control), value, path, addIssue);
1478
+ }),
1479
+ [USER_INPUT_CONTROL_TYPES.multiline]: ((control, value, path, addIssue) => {
1480
+ validateUserInputTextValue(userInputMultilineControlSchema.parse(control), value, path, addIssue);
1481
+ }),
1482
+ [USER_INPUT_CONTROL_TYPES.number]: ((control, value, path, addIssue) => {
1483
+ const numberControl = userInputNumberControlSchema.parse(control);
1484
+ if (typeof value !== "number" || !Number.isFinite(value)) {
1485
+ addIssue(path, "number control requires a finite number value");
1486
+ return;
1487
+ }
1488
+ if (numberControl.integer === true && !Number.isInteger(value)) {
1489
+ addIssue(path, "number control requires an integer value");
1490
+ }
1491
+ if (numberControl.min !== undefined && value < numberControl.min) {
1492
+ addIssue(path, `number value must be at least ${String(numberControl.min)}`);
1493
+ }
1494
+ if (numberControl.max !== undefined && value > numberControl.max) {
1495
+ addIssue(path, `number value must be at most ${String(numberControl.max)}`);
1496
+ }
1497
+ }),
1498
+ [USER_INPUT_CONTROL_TYPES.boolean]: ((control, value, path, addIssue) => {
1499
+ userInputBooleanControlSchema.parse(control);
1500
+ if (typeof value !== "boolean") {
1501
+ addIssue(path, "boolean control requires a boolean value");
1502
+ }
1503
+ }),
1504
+ [USER_INPUT_CONTROL_TYPES.choice]: ((control, value, path, addIssue) => {
1505
+ const choiceControl = userInputChoiceControlSchema.parse(control);
1506
+ const optionIds = new Set(choiceControl.options.map((option) => option.id));
1507
+ if (!choiceControl.multiple) {
1508
+ if (typeof value !== "string") {
1509
+ addIssue(path, "single-choice control requires one option id");
1510
+ return;
1511
+ }
1512
+ if (!optionIds.has(value)) {
1513
+ addIssue(path, `unknown choice option id: ${value}`);
1514
+ }
1515
+ return;
1516
+ }
1517
+ if (!Array.isArray(value)) {
1518
+ addIssue(path, "multiple-choice control requires an array of option ids");
1519
+ return;
1520
+ }
1521
+ const selected = new Set();
1522
+ for (const [index, optionId] of value.entries()) {
1523
+ if (selected.has(optionId)) {
1524
+ addIssue([...path, index], `duplicate choice option id: ${optionId}`);
1525
+ }
1526
+ selected.add(optionId);
1527
+ if (!optionIds.has(optionId)) {
1528
+ addIssue([...path, index], `unknown choice option id: ${optionId}`);
1529
+ }
1530
+ }
1531
+ const minimum = Math.max(choiceControl.minSelections ?? 0, choiceControl.required ? 1 : 0);
1532
+ const maximum = choiceControl.maxSelections ?? choiceControl.options.length;
1533
+ if (value.length < minimum) {
1534
+ addIssue(path, `choice value must contain at least ${String(minimum)} selections`);
1535
+ }
1536
+ if (value.length > maximum) {
1537
+ addIssue(path, `choice value must contain at most ${String(maximum)} selections`);
1538
+ }
1539
+ }),
1540
+ };
1541
+ function userInputControlRequiresValue(control) {
1542
+ if (control.required) {
1543
+ return true;
1544
+ }
1545
+ return control.type === USER_INPUT_CONTROL_TYPES.choice && (control.minSelections ?? 0) > 0;
1546
+ }
1547
+ /**
1548
+ * Correlates a structurally valid Client result with the original form and returns values in
1549
+ * form definition order. Unknown, duplicate, missing or type-incompatible values are rejected.
1550
+ */
1551
+ export function normalizeUserInputResultForForm(form, result) {
1552
+ const parsedForm = userInputFormSchema.parse(form);
1553
+ const parsedResult = userInputResultSchema.parse(result);
1554
+ if (parsedResult.status === "cancelled") {
1555
+ return parsedResult;
1556
+ }
1557
+ const controlsById = new Map(parsedForm.controls.map((control) => [control.id, control]));
1558
+ const correlatedResult = userInputSubmittedResultSchema
1559
+ .superRefine((submitted, context) => {
1560
+ const submittedControlIds = new Set();
1561
+ const addIssue = (path, message) => {
1562
+ context.addIssue({ code: "custom", message, path: [...path] });
1563
+ };
1564
+ for (const [index, submittedValue] of submitted.values.entries()) {
1565
+ const path = ["values", index, "value"];
1566
+ if (submittedControlIds.has(submittedValue.id)) {
1567
+ addIssue(["values", index, "id"], `duplicate control id: ${submittedValue.id}`);
1568
+ continue;
1569
+ }
1570
+ submittedControlIds.add(submittedValue.id);
1571
+ const control = controlsById.get(submittedValue.id);
1572
+ if (control === undefined) {
1573
+ addIssue(["values", index, "id"], `unknown control id: ${submittedValue.id}`);
1574
+ continue;
1575
+ }
1576
+ USER_INPUT_VALUE_VALIDATORS[control.type](control, submittedValue.value, path, addIssue);
1577
+ }
1578
+ for (const control of parsedForm.controls) {
1579
+ if (userInputControlRequiresValue(control) && !submittedControlIds.has(control.id)) {
1580
+ addIssue(["values"], `required control is missing: ${control.id}`);
1581
+ }
1582
+ }
1583
+ })
1584
+ .parse(parsedResult);
1585
+ const submittedById = new Map(correlatedResult.values.map((value) => [value.id, value]));
1586
+ return userInputSubmittedResultSchema.parse({
1587
+ status: "submitted",
1588
+ values: parsedForm.controls.flatMap((control) => {
1589
+ const value = submittedById.get(control.id);
1590
+ return value === undefined ? [] : [value];
1591
+ }),
1592
+ });
1593
+ }
1594
+ /**
1595
+ * Correlates a structurally valid Client result with the original request and returns values in
1596
+ * form definition order. Unknown, duplicate, missing or type-incompatible values are rejected.
1597
+ */
1598
+ export function normalizeUserInputResult(params, result) {
1599
+ const parsedParams = userInputRequestParamsV12Schema.parse(params);
1600
+ return normalizeUserInputResultForForm({
1601
+ ...(parsedParams.title === undefined ? {} : { title: parsedParams.title }),
1602
+ ...(parsedParams.description === undefined ? {} : { description: parsedParams.description }),
1603
+ controls: parsedParams.controls,
1604
+ }, result);
1605
+ }
616
1606
  export function isRuntimeMethod(value) {
617
- return Object.hasOwn(runtimeMethodSchemas, value);
1607
+ return Object.hasOwn(runtimeMethodSchemasV11, value);
1608
+ }
1609
+ function runtimeProtocolSchemaUnavailable(version, kind, name) {
1610
+ const suffix = name === undefined ? "" : ` ${name}`;
1611
+ throw new Error(`Runtime Protocol ${version} does not support ${kind}${suffix}`);
1612
+ }
1613
+ export function parseRuntimeMethodParamsForVersion(version, method, value) {
1614
+ const methods = getRuntimeProtocolRegistry(version).methods;
1615
+ const definition = methods[method];
1616
+ if (definition === undefined) {
1617
+ return runtimeProtocolSchemaUnavailable(version, "method", method);
1618
+ }
1619
+ return definition.params.parse(value);
1620
+ }
1621
+ export function parseRuntimeMethodResultForVersion(version, method, value) {
1622
+ const methods = getRuntimeProtocolRegistry(version).methods;
1623
+ const definition = methods[method];
1624
+ if (definition === undefined) {
1625
+ return runtimeProtocolSchemaUnavailable(version, "method", method);
1626
+ }
1627
+ return definition.result.parse(value);
618
1628
  }
619
1629
  export function parseRuntimeMethodParams(method, value) {
620
- return runtimeMethodSchemas[method].params.parse(value);
1630
+ return runtimeMethodSchemasV11[method].params.parse(value);
621
1631
  }
622
1632
  export function parseRuntimeMethodResult(method, value) {
623
- return runtimeMethodSchemas[method].result.parse(value);
1633
+ return runtimeMethodSchemasV11[method].result.parse(value);
1634
+ }
1635
+ export function projectThreadSnapshotForVersion(version, value) {
1636
+ const latest = threadSnapshotV13Schema.safeParse(value);
1637
+ if (version === "1.3") {
1638
+ if (!latest.success) {
1639
+ throw latest.error;
1640
+ }
1641
+ return latest.data;
1642
+ }
1643
+ const v12 = latest.success
1644
+ ? threadSnapshotV12Schema.parse({
1645
+ thread: latest.data.thread,
1646
+ messages: latest.data.messages,
1647
+ operations: latest.data.operations,
1648
+ ...(latest.data.activeTurn === undefined ? {} : { activeTurn: latest.data.activeTurn }),
1649
+ pendingApprovals: latest.data.pendingApprovals,
1650
+ pendingInteractions: latest.data.pendingInteractions,
1651
+ transcriptCompleteness: latest.data.transcriptCompleteness,
1652
+ })
1653
+ : threadSnapshotV12Schema.parse(value);
1654
+ if (version === "1.2") {
1655
+ return v12;
1656
+ }
1657
+ return threadSnapshotV11Schema.parse({
1658
+ thread: v12.thread,
1659
+ messages: v12.messages,
1660
+ operations: v12.operations,
1661
+ ...(v12.activeTurn === undefined
1662
+ ? {}
1663
+ : {
1664
+ activeTurn: {
1665
+ ...v12.activeTurn,
1666
+ status: v12.activeTurn.status === "waiting-for-user" ? "running" : v12.activeTurn.status,
1667
+ },
1668
+ }),
1669
+ pendingApprovals: v12.pendingApprovals,
1670
+ transcriptCompleteness: v12.transcriptCompleteness,
1671
+ });
1672
+ }
1673
+ export function projectRuntimeEventEnvelopeForVersion(version, value) {
1674
+ const source = runtimeEventEnvelopeSchema.parse(value);
1675
+ if (version === "1.3") {
1676
+ return runtimeEventEnvelopeV13Schema.parse(source);
1677
+ }
1678
+ const projectedEnvelopeFields = {
1679
+ runtimeInstanceId: source.runtimeInstanceId,
1680
+ sequence: source.sequence,
1681
+ timestamp: source.timestamp,
1682
+ threadId: source.threadId,
1683
+ ...(source.turnId === undefined ? {} : { turnId: source.turnId }),
1684
+ };
1685
+ if (version === "1.2") {
1686
+ return runtimeEventEnvelopeV12Schema.parse({
1687
+ protocolVersion: version,
1688
+ ...projectedEnvelopeFields,
1689
+ event: runtimeEventV12Schema.parse(source.event),
1690
+ });
1691
+ }
1692
+ return runtimeEventEnvelopeV11Schema.parse({
1693
+ protocolVersion: version,
1694
+ ...projectedEnvelopeFields,
1695
+ event: runtimeEventV11Schema.parse(source.event),
1696
+ });
624
1697
  }
625
1698
  export function isRuntimeServerRequestMethod(value) {
626
1699
  return Object.hasOwn(runtimeServerRequestSchemas, value);
627
1700
  }
1701
+ export function isLatestRuntimeServerRequestMethod(value) {
1702
+ return Object.hasOwn(runtimeServerRequestSchemasV13, value);
1703
+ }
1704
+ export function parseRuntimeServerRequestParamsForVersion(version, method, value) {
1705
+ const serverRequests = getRuntimeProtocolRegistry(version).serverRequests;
1706
+ const definition = serverRequests[method];
1707
+ if (definition === undefined) {
1708
+ return runtimeProtocolSchemaUnavailable(version, "server request", method);
1709
+ }
1710
+ return definition.params.parse(value);
1711
+ }
1712
+ export function parseRuntimeServerRequestResultForVersion(version, method, value) {
1713
+ const serverRequests = getRuntimeProtocolRegistry(version).serverRequests;
1714
+ const definition = serverRequests[method];
1715
+ if (definition === undefined) {
1716
+ return runtimeProtocolSchemaUnavailable(version, "server request", method);
1717
+ }
1718
+ return definition.result.parse(value);
1719
+ }
1720
+ export function parseRuntimeServerRequestCancelParamsForVersion(version, value) {
1721
+ const schema = getRuntimeProtocolRegistry(version).serverRequestCancelParamsSchema;
1722
+ if (schema === null) {
1723
+ return runtimeProtocolSchemaUnavailable(version, "server request cancellation");
1724
+ }
1725
+ return schema.parse(value);
1726
+ }
1727
+ export function parseRuntimeProtocolErrorDataForVersion(version, value) {
1728
+ return getRuntimeProtocolRegistry(version).errorDataSchema.parse(value);
1729
+ }
1730
+ export function projectRuntimeServerRequestParams(version, method, value) {
1731
+ const latest = parseRuntimeServerRequestParamsForVersion("1.3", method, value);
1732
+ if (version === "1.3" || version === "1.2") {
1733
+ return latest;
1734
+ }
1735
+ if (version === "1.1" && method === RUNTIME_SERVER_REQUEST_METHODS.approvalRequest) {
1736
+ const approval = approvalRequestParamsV12Schema.parse(latest);
1737
+ return approvalRequestParamsV11Schema.parse({
1738
+ threadId: approval.threadId,
1739
+ approval: approval.approval,
1740
+ expiresAt: approval.expiresAt,
1741
+ });
1742
+ }
1743
+ return runtimeProtocolSchemaUnavailable(version, "server request", method);
1744
+ }
1745
+ export function projectRuntimeServerRequestCancelParams(version, value) {
1746
+ const input = runtimeServerRequestCancelProjectionInputSchema.parse(value);
1747
+ if (version === "1.3" || version === "1.2") {
1748
+ return runtimeServerRequestCancelParamsV12Schema.parse({
1749
+ interactionId: input.interactionId,
1750
+ reason: input.reason,
1751
+ });
1752
+ }
1753
+ if (version === "1.1") {
1754
+ return runtimeServerRequestCancelParamsV11Schema.parse({
1755
+ serverRequestId: input.serverRequestId,
1756
+ ...(input.approvalId === undefined ? {} : { approvalId: input.approvalId }),
1757
+ reason: input.reason,
1758
+ });
1759
+ }
1760
+ return runtimeProtocolSchemaUnavailable(version, "server request cancellation");
1761
+ }
628
1762
  export function parseRuntimeServerRequestParams(method, value) {
629
1763
  return runtimeServerRequestSchemas[method].params.parse(value);
630
1764
  }