@roll-agent/protocol 0.3.0 → 0.4.1

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 (35) hide show
  1. package/README.md +93 -14
  2. package/dist/index.d.ts +9482 -663
  3. package/dist/index.js +1257 -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.2/invalid-duplicate-client-capability-method.json +9 -0
  10. package/fixtures/v1.2/invalid-legacy-approval-request.json +15 -0
  11. package/fixtures/v1.2/invalid-legacy-server-request-cancel-notification.json +9 -0
  12. package/fixtures/v1.2/invalid-sensitive-approval-request.json +19 -0
  13. package/fixtures/v1.2/invalid-sensitive-user-input-request.json +20 -0
  14. package/fixtures/v1.2/invalid-thread-snapshot-interaction-payload.json +37 -0
  15. package/fixtures/v1.2/invalid-user-input-request-response.json +13 -0
  16. package/fixtures/v1.2/valid-approval-request.json +22 -0
  17. package/fixtures/v1.2/valid-client-capabilities-set-request.json +9 -0
  18. package/fixtures/v1.2/valid-client-capabilities-set-response.json +8 -0
  19. package/fixtures/v1.2/valid-server-request-cancel-notification.json +8 -0
  20. package/fixtures/v1.2/valid-thread-snapshot-response.json +42 -0
  21. package/fixtures/v1.2/valid-user-input-request-response.json +11 -0
  22. package/fixtures/v1.2/valid-user-input-request.json +35 -0
  23. package/fixtures/v1.3/invalid-durable-delta-event-notification.json +19 -0
  24. package/fixtures/v1.3/invalid-ephemeral-completed-event-notification.json +15 -0
  25. package/fixtures/v1.3/invalid-runtime-events-resume-cursor-request.json +9 -0
  26. package/fixtures/v1.3/invalid-thread-recovery-snapshot-response.json +31 -0
  27. package/fixtures/v1.3/invalid-thread-recovery-snapshot-timestamp-response.json +21 -0
  28. package/fixtures/v1.3/valid-runtime-durable-event-notification.json +20 -0
  29. package/fixtures/v1.3/valid-runtime-ephemeral-event-notification.json +18 -0
  30. package/fixtures/v1.3/valid-runtime-events-resume-request.json +9 -0
  31. package/fixtures/v1.3/valid-runtime-events-resume-response.json +8 -0
  32. package/fixtures/v1.3/valid-thread-recovery-snapshot-request.json +10 -0
  33. package/fixtures/v1.3/valid-thread-recovery-snapshot-response.json +21 -0
  34. package/fixtures/v1.3/valid-thread-snapshot-response.json +20 -0
  35. package/package.json +6 -1
package/dist/index.js CHANGED
@@ -1,28 +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;
6
27
  export const APPROVAL_EXPLANATION_PREVIEW_KEY = "explanation";
7
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"];
8
39
  export const RUNTIME_SERVER_REQUEST_METHODS = {
9
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",
10
57
  };
11
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
+ },
12
73
  "1.1": {
13
74
  serverRequests: true,
75
+ serverRequestCapabilityNegotiation: false,
14
76
  approvalResolvedEvents: true,
15
77
  clientApprovalResponses: false,
16
78
  requiredServerRequestMethods: [RUNTIME_SERVER_REQUEST_METHODS.approvalRequest],
17
79
  },
18
80
  "1.0": {
19
81
  serverRequests: false,
82
+ serverRequestCapabilityNegotiation: false,
20
83
  approvalResolvedEvents: false,
21
84
  clientApprovalResponses: true,
22
85
  requiredServerRequestMethods: [],
23
86
  },
24
87
  };
25
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,
26
91
  "1.1": RUNTIME_PROTOCOL_CAPABILITIES["1.1"].requiredServerRequestMethods,
27
92
  "1.0": RUNTIME_PROTOCOL_CAPABILITIES["1.0"].requiredServerRequestMethods,
28
93
  };
@@ -34,10 +99,12 @@ export function isRuntimeServerRequestMethodRequired(version, method) {
34
99
  }
35
100
  export const RUNTIME_METHODS = {
36
101
  initialize: "initialize",
102
+ clientCapabilitiesSet: "client.capabilities.set",
37
103
  threadList: "thread.list",
38
104
  threadCreate: "thread.create",
39
105
  threadOpen: "thread.open",
40
106
  threadSnapshot: "thread.snapshot",
107
+ runtimeEventsResume: "runtime.events.resume",
41
108
  threadRename: "thread.rename",
42
109
  threadDelete: "thread.delete",
43
110
  threadDetach: "thread.detach",
@@ -57,7 +124,7 @@ export const RUNTIME_FEATURES = [
57
124
  "operation-projection",
58
125
  "process-local-sequence",
59
126
  ];
60
- export const RUNTIME_ERROR_CODES = {
127
+ export const RUNTIME_ERROR_CODES_V11 = {
61
128
  protocolVersionUnsupported: "PROTOCOL_VERSION_UNSUPPORTED",
62
129
  initializeRequired: "INITIALIZE_REQUIRED",
63
130
  invalidParams: "INVALID_PARAMS",
@@ -71,6 +138,17 @@ export const RUNTIME_ERROR_CODES = {
71
138
  outcomeUnknown: "OUTCOME_UNKNOWN",
72
139
  internalError: "INTERNAL_ERROR",
73
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;
74
152
  export const TOOL_OUTCOME_KINDS = [
75
153
  "success",
76
154
  "user_rejected",
@@ -82,19 +160,94 @@ export const TOOL_OUTCOME_KINDS = [
82
160
  export const threadIdSchema = z.string().uuid().brand();
83
161
  export const turnIdSchema = z.string().uuid().brand();
84
162
  export const approvalIdSchema = z.string().uuid().brand();
163
+ export const interactionIdSchema = z.string().uuid().brand();
85
164
  export const runtimeInstanceIdSchema = z.string().uuid().brand();
86
165
  export const requestIdSchema = z.string().uuid().brand();
87
166
  export const streamIdSchema = z.string().uuid().brand();
88
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();
89
174
  export const timestampSchema = z.string().datetime({ offset: true });
90
175
  export const jsonValueSchema = z.json();
91
176
  export const jsonRpcIdSchema = z.union([z.string(), z.number()]);
92
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();
93
191
  export const approvalExplanationSchema = z
94
192
  .string()
95
193
  .trim()
96
194
  .min(1)
97
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
+ }
98
251
  const runtimeClientInfoFields = {
99
252
  name: z.string().trim().min(1).max(100),
100
253
  version: z.string().trim().min(1).max(100),
@@ -107,7 +260,8 @@ export const runtimeServerInfoSchema = z
107
260
  })
108
261
  .strict()
109
262
  .readonly();
110
- export const runtimeLimitsSchema = z
263
+ /** Runtime Protocol 1.2/1.1/1.0 limits. Keep this schema frozen. */
264
+ export const runtimeLimitsV12Schema = z
111
265
  .object({
112
266
  maxFrameBytes: z.number().int().positive(),
113
267
  maxPageSize: z.number().int().positive(),
@@ -116,6 +270,16 @@ export const runtimeLimitsSchema = z
116
270
  })
117
271
  .strict()
118
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]);
119
283
  export const initializeParamsSchema = z
120
284
  .object({
121
285
  protocolVersions: z.array(z.string().min(1)).min(1),
@@ -123,13 +287,87 @@ export const initializeParamsSchema = z
123
287
  })
124
288
  .strict()
125
289
  .readonly();
126
- export const initializeResultSchema = z
127
- .object({
128
- protocolVersion: runtimeProtocolVersionSchema,
290
+ const initializeResultCommonFields = {
129
291
  runtimeInstanceId: runtimeInstanceIdSchema,
130
292
  server: runtimeServerInfoSchema,
131
293
  features: z.array(z.enum(RUNTIME_FEATURES)),
132
- 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,
133
371
  })
134
372
  .strict()
135
373
  .readonly();
@@ -180,7 +418,7 @@ export const operationViewSchema = z
180
418
  })
181
419
  .strict()
182
420
  .readonly();
183
- export const activeTurnSchema = z
421
+ export const activeTurnV11Schema = z
184
422
  .object({
185
423
  id: turnIdSchema,
186
424
  status: z.enum(["running", "cancelling"]),
@@ -188,6 +426,16 @@ export const activeTurnSchema = z
188
426
  })
189
427
  .strict()
190
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;
191
439
  export const pendingApprovalSchema = z
192
440
  .object({
193
441
  id: approvalIdSchema,
@@ -213,17 +461,337 @@ export const operationPageSchema = z
213
461
  })
214
462
  .strict()
215
463
  .readonly();
216
- export const threadSnapshotSchema = z
217
- .object({
464
+ const threadSnapshotV11Fields = {
218
465
  thread: threadSummarySchema,
219
466
  messages: messagePageSchema,
220
467
  operations: operationPageSchema,
221
- activeTurn: activeTurnSchema.optional(),
468
+ activeTurn: activeTurnV11Schema.optional(),
222
469
  pendingApprovals: z.array(pendingApprovalSchema),
223
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(),
224
578
  })
225
579
  .strict()
226
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(),
691
+ })
692
+ .strict()
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;
227
795
  const pageSizeSchema = z.number().int().min(1).max(500).default(100);
228
796
  const requestFields = { requestId: requestIdSchema };
229
797
  const threadRequestFields = { threadId: threadIdSchema };
@@ -255,17 +823,47 @@ export const threadCreateResultSchema = z
255
823
  .strict()
256
824
  .readonly();
257
825
  export const threadOpenParamsSchema = z.object(threadRequestFields).strict().readonly();
826
+ export const threadOpenResultV11Schema = threadSnapshotV11Schema;
258
827
  export const threadOpenResultSchema = threadSnapshotSchema;
259
- export const threadSnapshotParamsSchema = z
260
- .object({
828
+ const threadSnapshotParamFields = {
261
829
  ...threadRequestFields,
262
830
  messageBeforeSequence: z.number().int().nonnegative().optional(),
263
831
  operationBeforeSequence: z.number().int().nonnegative().optional(),
264
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,
838
+ })
839
+ .strict()
840
+ .readonly();
841
+ export const threadSnapshotParamsV13Schema = z
842
+ .object({
843
+ ...threadSnapshotParamFields,
844
+ recovery: z.literal(true).optional(),
265
845
  })
266
846
  .strict()
267
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;
268
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();
269
867
  export const threadRenameParamsSchema = z
270
868
  .object({
271
869
  ...requestFields,
@@ -354,6 +952,28 @@ export const approvalRequestParamsSchema = z
354
952
  })
355
953
  .strict()
356
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();
357
977
  export const approvalRequestResultSchema = z.discriminatedUnion("decision", [
358
978
  z
359
979
  .object({
@@ -377,6 +997,24 @@ export const runtimeServerRequestCancelParamsSchema = z
377
997
  })
378
998
  .strict()
379
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();
380
1018
  export const operationGetParamsSchema = z
381
1019
  .object({
382
1020
  ...threadRequestFields,
@@ -421,127 +1059,144 @@ export const approvalResolutionSchema = z.union([
421
1059
  .strict()
422
1060
  .readonly(),
423
1061
  ]);
424
- export const runtimeEventSchema = z.discriminatedUnion("type", [
425
- z
426
- .object({ type: z.literal("turn.started") })
427
- .strict()
428
- .readonly(),
429
- z
430
- .object({
431
- type: z.literal("message.started"),
432
- streamId: streamIdSchema,
433
- })
434
- .strict()
435
- .readonly(),
436
- z
437
- .object({
438
- type: z.literal("message.delta"),
439
- streamId: streamIdSchema,
440
- delta: z.string(),
441
- })
442
- .strict()
443
- .readonly(),
444
- z
445
- .object({
446
- type: z.literal("message.completed"),
447
- streamId: streamIdSchema,
448
- text: z.string(),
449
- })
450
- .strict()
451
- .readonly(),
452
- z
453
- .object({
454
- type: z.literal("reasoning.summary.delta"),
455
- reasoningId: z.string().min(1),
456
- delta: z.string(),
457
- })
458
- .strict()
459
- .readonly(),
460
- z
461
- .object({
462
- type: z.literal("tool.started"),
463
- toolCallId: z.string().min(1),
464
- agentName: z.string().min(1),
465
- toolName: z.string().min(1),
466
- input: jsonValueSchema,
467
- })
468
- .strict()
469
- .readonly(),
470
- z
471
- .object({
472
- type: z.literal("tool.output"),
473
- toolCallId: z.string().min(1),
474
- agentName: z.string().min(1),
475
- toolName: z.string().min(1),
476
- stream: z.enum(["stdout", "stderr"]),
477
- delta: z.string(),
478
- })
479
- .strict()
480
- .readonly(),
481
- z
482
- .object({
483
- type: z.literal("tool.completed"),
484
- toolCallId: z.string().min(1),
485
- agentName: z.string().min(1),
486
- toolName: z.string().min(1),
487
- operationId: operationIdSchema.optional(),
488
- outcome: toolOutcomeSchema.optional(),
489
- display: jsonValueSchema,
490
- })
491
- .strict()
492
- .readonly(),
493
- z
494
- .object({
495
- type: z.literal("approval.required"),
496
- approval: pendingApprovalSchema,
497
- })
498
- .strict()
499
- .readonly(),
500
- z
501
- .object({
502
- type: z.literal("approval.resolved"),
503
- approvalId: approvalIdSchema,
504
- resolution: approvalResolutionSchema,
505
- })
506
- .strict()
507
- .readonly(),
508
- z
509
- .object({ type: z.literal("turn.completed") })
510
- .strict()
511
- .readonly(),
512
- z
513
- .object({
514
- type: z.literal("turn.cancelled"),
515
- reason: z.string(),
516
- message: z.string(),
517
- })
518
- .strict()
519
- .readonly(),
520
- z
521
- .object({
522
- type: z.literal("turn.failed"),
523
- stage: z.enum(["bootstrap", "plan", "execute"]),
524
- message: z.string(),
525
- })
526
- .strict()
527
- .readonly(),
528
- z
529
- .object({ type: z.literal("capabilities.changed") })
530
- .strict()
531
- .readonly(),
532
- ]);
533
- 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
1079
+ .object({
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
534
1124
  .object({
535
- protocolVersion: runtimeProtocolVersionSchema,
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 = {
536
1193
  runtimeInstanceId: runtimeInstanceIdSchema,
537
1194
  sequence: z.number().int().nonnegative(),
538
1195
  timestamp: timestampSchema,
539
1196
  threadId: threadIdSchema,
540
1197
  turnId: turnIdSchema.optional(),
541
- event: runtimeEventSchema,
542
- })
543
- .strict()
544
- .superRefine((value, context) => {
1198
+ };
1199
+ function validateRuntimeEventCapabilities(value, context) {
545
1200
  if (!getRuntimeProtocolCapabilities(value.protocolVersion).approvalResolvedEvents &&
546
1201
  value.event.type === "approval.resolved") {
547
1202
  context.addIssue({
@@ -550,20 +1205,89 @@ export const runtimeEventEnvelopeSchema = z
550
1205
  path: ["event", "type"],
551
1206
  });
552
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,
553
1215
  })
1216
+ .strict()
1217
+ .superRefine(validateRuntimeEventCapabilities)
554
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)
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
+ ]);
555
1261
  export const runtimeProtocolErrorDataSchema = z
556
1262
  .object({
557
- 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)),
558
1282
  retryable: z.boolean(),
559
1283
  details: jsonValueSchema.optional(),
560
1284
  })
561
1285
  .strict()
562
1286
  .readonly();
563
- export const runtimeMethodSchemas = {
1287
+ export const runtimeMethodSchemasV11 = {
564
1288
  [RUNTIME_METHODS.initialize]: {
565
1289
  params: initializeParamsSchema,
566
- result: initializeResultSchema,
1290
+ result: initializeResultV11Schema,
567
1291
  },
568
1292
  [RUNTIME_METHODS.threadList]: {
569
1293
  params: threadListParamsSchema,
@@ -575,11 +1299,11 @@ export const runtimeMethodSchemas = {
575
1299
  },
576
1300
  [RUNTIME_METHODS.threadOpen]: {
577
1301
  params: threadOpenParamsSchema,
578
- result: threadOpenResultSchema,
1302
+ result: threadOpenResultV11Schema,
579
1303
  },
580
1304
  [RUNTIME_METHODS.threadSnapshot]: {
581
- params: threadSnapshotParamsSchema,
582
- result: threadSnapshotResultSchema,
1305
+ params: threadSnapshotParamsV12Schema,
1306
+ result: threadSnapshotResultV11Schema,
583
1307
  },
584
1308
  [RUNTIME_METHODS.threadRename]: {
585
1309
  params: threadRenameParamsSchema,
@@ -614,12 +1338,118 @@ export const runtimeMethodSchemas = {
614
1338
  result: operationGetResultSchema,
615
1339
  },
616
1340
  };
617
- 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 = {
618
1384
  [RUNTIME_SERVER_REQUEST_METHODS.approvalRequest]: {
619
1385
  params: approvalRequestParamsSchema,
620
1386
  result: approvalRequestResultSchema,
621
1387
  },
622
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
+ }
623
1453
  export function getApprovalExplanation(approval) {
624
1454
  const preview = approval.preview;
625
1455
  if (typeof preview !== "object" || preview === null || Array.isArray(preview)) {
@@ -628,18 +1458,307 @@ export function getApprovalExplanation(approval) {
628
1458
  const parsed = approvalExplanationSchema.safeParse(preview[APPROVAL_EXPLANATION_PREVIEW_KEY]);
629
1459
  return parsed.success ? parsed.data : undefined;
630
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
+ }
631
1606
  export function isRuntimeMethod(value) {
632
- 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);
633
1628
  }
634
1629
  export function parseRuntimeMethodParams(method, value) {
635
- return runtimeMethodSchemas[method].params.parse(value);
1630
+ return runtimeMethodSchemasV11[method].params.parse(value);
636
1631
  }
637
1632
  export function parseRuntimeMethodResult(method, value) {
638
- 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
+ });
639
1697
  }
640
1698
  export function isRuntimeServerRequestMethod(value) {
641
1699
  return Object.hasOwn(runtimeServerRequestSchemas, value);
642
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
+ }
643
1762
  export function parseRuntimeServerRequestParams(method, value) {
644
1763
  return runtimeServerRequestSchemas[method].params.parse(value);
645
1764
  }