@roll-agent/protocol 0.4.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -4,10 +4,14 @@ export const SUPPORTED_RUNTIME_PROTOCOL_VERSIONS_V12 = [
4
4
  "1.2",
5
5
  ...SUPPORTED_RUNTIME_PROTOCOL_VERSIONS_V11,
6
6
  ];
7
- export const SUPPORTED_RUNTIME_PROTOCOL_VERSIONS = [
7
+ export const SUPPORTED_RUNTIME_PROTOCOL_VERSIONS_V13 = [
8
8
  "1.3",
9
9
  ...SUPPORTED_RUNTIME_PROTOCOL_VERSIONS_V12,
10
10
  ];
11
+ export const SUPPORTED_RUNTIME_PROTOCOL_VERSIONS = [
12
+ "1.4",
13
+ ...SUPPORTED_RUNTIME_PROTOCOL_VERSIONS_V13,
14
+ ];
11
15
  export const RUNTIME_PROTOCOL_VERSION = SUPPORTED_RUNTIME_PROTOCOL_VERSIONS[0];
12
16
  export const RUNTIME_EVENT_NOTIFICATION = "runtime.event";
13
17
  export const RUNTIME_SERVER_REQUEST_CANCEL_NOTIFICATION = "runtime.serverRequest.cancel";
@@ -26,6 +30,10 @@ export const RUNTIME_V13_RECOVERY_SNAPSHOT_METADATA_MAX_CHARS = 1_024;
26
30
  export const RUNTIME_V13_RECOVERY_SNAPSHOT_TIMESTAMP_MAX_CHARS = 64;
27
31
  export const APPROVAL_EXPLANATION_PREVIEW_KEY = "explanation";
28
32
  export const APPROVAL_EXPLANATION_MAX_CHARS = 100;
33
+ export const APPROVAL_DIFF_PREVIEW_KEY = "diff";
34
+ export const FILE_CHANGE_DIFF_PATH_MAX_CHARS = 4_096;
35
+ export const FILE_CHANGE_DIFF_UNIFIED_MAX_CHARS = 20_000;
36
+ export const FILE_CHANGE_KINDS = ["create", "modify"];
29
37
  export const CLIENT_CAPABILITY_METHOD_MAX_COUNT = 64;
30
38
  export const CLIENT_CAPABILITY_METHOD_MAX_CHARS = 100;
31
39
  export const USER_INPUT_CONTROL_MAX_COUNT = 16;
@@ -35,6 +43,25 @@ export const USER_INPUT_DESCRIPTION_MAX_CHARS = 500;
35
43
  export const USER_INPUT_CHOICE_OPTION_MAX_COUNT = 50;
36
44
  export const USER_INPUT_TEXT_MAX_CHARS = 10_000;
37
45
  export const USER_INPUT_CANCEL_REASON_MAX_CHARS = 500;
46
+ export const RUNTIME_V14_MAX_ATTACHMENT_BYTES = 16 * 1_024 * 1_024;
47
+ export const RUNTIME_V14_MAX_TURN_ATTACHMENTS = 8;
48
+ /**
49
+ * Chunk payloads are raw bytes before base64 framing. 2 MiB of raw data grows to about 2.7 MiB of
50
+ * base64 text, which keeps a full attachment.chunk request inside the 4 MiB stdio frame limit.
51
+ */
52
+ export const RUNTIME_V14_MAX_ATTACHMENT_CHUNK_BYTES = 2 * 1_024 * 1_024;
53
+ export const RUNTIME_V14_MAX_STAGED_ATTACHMENTS = 16;
54
+ export const ATTACHMENT_FILE_NAME_MAX_CHARS = 255;
55
+ export const SUPPORTED_ATTACHMENT_MEDIA_TYPES = [
56
+ "image/png",
57
+ "image/jpeg",
58
+ "image/gif",
59
+ "image/webp",
60
+ "application/pdf",
61
+ "text/plain",
62
+ "text/markdown",
63
+ ];
64
+ export const ATTACHMENT_SOURCES = ["local-path", "chunks"];
38
65
  export const INTERACTION_SENSITIVITIES = ["normal"];
39
66
  export const RUNTIME_SERVER_REQUEST_METHODS = {
40
67
  approvalRequest: "approval.request",
@@ -56,6 +83,13 @@ export const USER_INPUT_CONTROL_TYPES = {
56
83
  choice: "choice",
57
84
  };
58
85
  export const RUNTIME_PROTOCOL_CAPABILITIES = {
86
+ "1.4": {
87
+ serverRequests: true,
88
+ serverRequestCapabilityNegotiation: true,
89
+ approvalResolvedEvents: true,
90
+ clientApprovalResponses: false,
91
+ requiredServerRequestMethods: [],
92
+ },
59
93
  "1.2": {
60
94
  serverRequests: true,
61
95
  serverRequestCapabilityNegotiation: true,
@@ -86,6 +120,7 @@ export const RUNTIME_PROTOCOL_CAPABILITIES = {
86
120
  },
87
121
  };
88
122
  export const REQUIRED_RUNTIME_SERVER_REQUEST_METHODS_BY_VERSION = {
123
+ "1.4": RUNTIME_PROTOCOL_CAPABILITIES["1.4"].requiredServerRequestMethods,
89
124
  "1.3": RUNTIME_PROTOCOL_CAPABILITIES["1.3"].requiredServerRequestMethods,
90
125
  "1.2": RUNTIME_PROTOCOL_CAPABILITIES["1.2"].requiredServerRequestMethods,
91
126
  "1.1": RUNTIME_PROTOCOL_CAPABILITIES["1.1"].requiredServerRequestMethods,
@@ -113,8 +148,12 @@ export const RUNTIME_METHODS = {
113
148
  turnCancel: "turn.cancel",
114
149
  approvalRespond: "approval.respond",
115
150
  operationGet: "operation.get",
151
+ attachmentStage: "attachment.stage",
152
+ attachmentChunk: "attachment.chunk",
153
+ attachmentCommit: "attachment.commit",
154
+ attachmentRelease: "attachment.release",
116
155
  };
117
- export const RUNTIME_FEATURES = [
156
+ export const RUNTIME_FEATURES_V13 = [
118
157
  "thread-management",
119
158
  "snapshots",
120
159
  "turns",
@@ -124,6 +163,8 @@ export const RUNTIME_FEATURES = [
124
163
  "operation-projection",
125
164
  "process-local-sequence",
126
165
  ];
166
+ export const RUNTIME_FEATURES_V14 = [...RUNTIME_FEATURES_V13, "attachments"];
167
+ export const RUNTIME_FEATURES = RUNTIME_FEATURES_V14;
127
168
  export const RUNTIME_ERROR_CODES_V11 = {
128
169
  protocolVersionUnsupported: "PROTOCOL_VERSION_UNSUPPORTED",
129
170
  initializeRequired: "INITIALIZE_REQUIRED",
@@ -143,12 +184,24 @@ export const RUNTIME_ERROR_CODES_V12 = {
143
184
  ...RUNTIME_ERROR_CODES_V11,
144
185
  capabilityRevisionConflict: "CAPABILITY_REVISION_CONFLICT",
145
186
  };
146
- export const RUNTIME_ERROR_CODES = {
187
+ export const RUNTIME_ERROR_CODES_V13 = {
147
188
  ...RUNTIME_ERROR_CODES_V12,
148
189
  eventCursorExpired: "EVENT_CURSOR_EXPIRED",
149
190
  eventCursorGap: "EVENT_CURSOR_GAP",
150
191
  };
151
- export const RUNTIME_ERROR_CODES_V13 = RUNTIME_ERROR_CODES;
192
+ /** Runtime Protocol 1.4 error registry. Keep this object frozen. */
193
+ export const RUNTIME_ERROR_CODES_V14 = {
194
+ ...RUNTIME_ERROR_CODES_V13,
195
+ attachmentNotFound: "ATTACHMENT_NOT_FOUND",
196
+ attachmentNotCommitted: "ATTACHMENT_NOT_COMMITTED",
197
+ attachmentTooLarge: "ATTACHMENT_TOO_LARGE",
198
+ attachmentTypeUnsupported: "ATTACHMENT_TYPE_UNSUPPORTED",
199
+ attachmentHashMismatch: "ATTACHMENT_HASH_MISMATCH",
200
+ attachmentQuotaExceeded: "ATTACHMENT_QUOTA_EXCEEDED",
201
+ attachmentUploadIncomplete: "ATTACHMENT_UPLOAD_INCOMPLETE",
202
+ attachmentPathRejected: "ATTACHMENT_PATH_REJECTED",
203
+ };
204
+ export const RUNTIME_ERROR_CODES = RUNTIME_ERROR_CODES_V14;
152
205
  export const TOOL_OUTCOME_KINDS = [
153
206
  "success",
154
207
  "user_rejected",
@@ -166,6 +219,7 @@ export const requestIdSchema = z.string().uuid().brand();
166
219
  export const streamIdSchema = z.string().uuid().brand();
167
220
  export const operationIdSchema = z.string().uuid().brand();
168
221
  export const runtimeEventIdSchema = z.string().uuid().brand();
222
+ export const attachmentIdSchema = z.string().uuid().brand();
169
223
  export const runtimeEventCursorSchema = z
170
224
  .string()
171
225
  .max(128)
@@ -193,6 +247,23 @@ export const approvalExplanationSchema = z
193
247
  .trim()
194
248
  .min(1)
195
249
  .max(APPROVAL_EXPLANATION_MAX_CHARS);
250
+ export const fileChangeDiffSchema = z
251
+ .object({
252
+ path: z.string().min(1).max(FILE_CHANGE_DIFF_PATH_MAX_CHARS),
253
+ change: z.enum(FILE_CHANGE_KINDS),
254
+ added: z.number().int().nonnegative(),
255
+ removed: z.number().int().nonnegative(),
256
+ hunks: z.number().int().nonnegative(),
257
+ unified: z.string().max(FILE_CHANGE_DIFF_UNIFIED_MAX_CHARS).optional(),
258
+ truncated: z.boolean(),
259
+ })
260
+ .readonly();
261
+ export const fileChangeDisplaySchema = z
262
+ .object({
263
+ text: z.string(),
264
+ diff: fileChangeDiffSchema,
265
+ })
266
+ .readonly();
196
267
  function runtimeEventCursorParts(cursor) {
197
268
  const parsed = runtimeEventCursorSchema.parse(cursor);
198
269
  const [, eventLogId, threadSequence, eventId] = parsed.split(":");
@@ -279,7 +350,24 @@ export const runtimeLimitsV13Schema = z
279
350
  })
280
351
  .strict()
281
352
  .readonly();
282
- export const runtimeLimitsSchema = z.union([runtimeLimitsV13Schema, runtimeLimitsV12Schema]);
353
+ export const runtimeLimitsV14Schema = z
354
+ .object({
355
+ maxFrameBytes: z.number().int().positive(),
356
+ maxPageSize: z.number().int().positive(),
357
+ eventReplay: z.literal(true),
358
+ idempotencyCacheEntries: z.number().int().positive(),
359
+ maxAttachmentBytes: z.number().int().positive(),
360
+ maxAttachmentChunkBytes: z.number().int().positive(),
361
+ maxTurnAttachments: z.number().int().positive(),
362
+ maxStagedAttachments: z.number().int().positive(),
363
+ })
364
+ .strict()
365
+ .readonly();
366
+ export const runtimeLimitsSchema = z.union([
367
+ runtimeLimitsV14Schema,
368
+ runtimeLimitsV13Schema,
369
+ runtimeLimitsV12Schema,
370
+ ]);
283
371
  export const initializeParamsSchema = z
284
372
  .object({
285
373
  protocolVersions: z.array(z.string().min(1)).min(1),
@@ -290,7 +378,12 @@ export const initializeParamsSchema = z
290
378
  const initializeResultCommonFields = {
291
379
  runtimeInstanceId: runtimeInstanceIdSchema,
292
380
  server: runtimeServerInfoSchema,
293
- features: z.array(z.enum(RUNTIME_FEATURES)),
381
+ features: z.array(z.enum(RUNTIME_FEATURES_V13)),
382
+ };
383
+ const initializeResultV14Fields = {
384
+ runtimeInstanceId: runtimeInstanceIdSchema,
385
+ server: runtimeServerInfoSchema,
386
+ features: z.array(z.enum(RUNTIME_FEATURES_V14)),
294
387
  };
295
388
  /** Runtime Protocol 1.1/1.0 initialize result. Keep this schema frozen. */
296
389
  export const initializeResultV11Schema = z
@@ -318,8 +411,17 @@ export const initializeResultV13Schema = z
318
411
  })
319
412
  .strict()
320
413
  .readonly();
414
+ export const initializeResultV14Schema = z
415
+ .object({
416
+ protocolVersion: z.literal("1.4"),
417
+ ...initializeResultV14Fields,
418
+ limits: runtimeLimitsV14Schema,
419
+ })
420
+ .strict()
421
+ .readonly();
321
422
  /** Any currently supported Runtime Protocol initialize result. */
322
423
  export const initializeResultSchema = z.union([
424
+ initializeResultV14Schema,
323
425
  initializeResultV13Schema,
324
426
  initializeResultV12Schema,
325
427
  initializeResultV11Schema,
@@ -389,6 +491,20 @@ export const uiMessagePartSchema = z
389
491
  })
390
492
  .strict()
391
493
  .readonly();
494
+ /**
495
+ * Safe attachment metadata inside a projected message. Carries no binary content and no
496
+ * filesystem path; bytes are derived from the persisted model message.
497
+ */
498
+ export const uiMessageAttachmentPartSchema = z
499
+ .object({
500
+ type: z.literal("attachment"),
501
+ mediaType: z.string().min(1),
502
+ bytes: z.number().int().nonnegative(),
503
+ displayName: z.string().min(1).max(ATTACHMENT_FILE_NAME_MAX_CHARS).optional(),
504
+ })
505
+ .strict()
506
+ .readonly();
507
+ export const uiMessagePartV14Schema = z.union([uiMessagePartSchema, uiMessageAttachmentPartSchema]);
392
508
  export const uiMessageSchema = z
393
509
  .object({
394
510
  sequence: z.number().int().nonnegative(),
@@ -398,6 +514,15 @@ export const uiMessageSchema = z
398
514
  })
399
515
  .strict()
400
516
  .readonly();
517
+ export const uiMessageV14Schema = z
518
+ .object({
519
+ sequence: z.number().int().nonnegative(),
520
+ role: z.enum(["user", "assistant"]),
521
+ createdAt: timestampSchema,
522
+ parts: z.array(uiMessagePartV14Schema),
523
+ })
524
+ .strict()
525
+ .readonly();
401
526
  export const toolOutcomeSchema = z
402
527
  .object({
403
528
  kind: z.enum(TOOL_OUTCOME_KINDS),
@@ -454,6 +579,13 @@ export const messagePageSchema = z
454
579
  })
455
580
  .strict()
456
581
  .readonly();
582
+ export const messagePageV14Schema = z
583
+ .object({
584
+ items: z.array(uiMessageV14Schema),
585
+ nextBeforeSequence: z.number().int().nonnegative().nullable(),
586
+ })
587
+ .strict()
588
+ .readonly();
457
589
  export const operationPageSchema = z
458
590
  .object({
459
591
  items: z.array(operationViewSchema),
@@ -790,8 +922,20 @@ export const threadSnapshotV13Schema = z.union([
790
922
  threadSnapshotV13FullSchema,
791
923
  threadRecoverySnapshotV13Schema,
792
924
  ]);
925
+ export const threadSnapshotV14FullSchema = z
926
+ .object({
927
+ ...threadSnapshotV12Fields,
928
+ messages: messagePageV14Schema,
929
+ eventCursor: runtimeEventCursorSchema.nullable(),
930
+ })
931
+ .strict()
932
+ .readonly();
933
+ export const threadSnapshotV14Schema = z.union([
934
+ threadSnapshotV14FullSchema,
935
+ threadRecoverySnapshotV13Schema,
936
+ ]);
793
937
  /** Latest Runtime Protocol snapshot. Use versioned schemas for compatibility. */
794
- export const threadSnapshotSchema = threadSnapshotV13Schema;
938
+ export const threadSnapshotSchema = threadSnapshotV14Schema;
795
939
  const pageSizeSchema = z.number().int().min(1).max(500).default(100);
796
940
  const requestFields = { requestId: requestIdSchema };
797
941
  const threadRequestFields = { threadId: threadIdSchema };
@@ -898,6 +1042,105 @@ export const threadCapabilitiesResultSchema = z
898
1042
  })
899
1043
  .strict()
900
1044
  .readonly();
1045
+ export const attachmentSourceSchema = z.enum(ATTACHMENT_SOURCES);
1046
+ export const attachmentMediaTypeSchema = z.enum(SUPPORTED_ATTACHMENT_MEDIA_TYPES);
1047
+ export const attachmentSha256Schema = z.string().regex(/^[a-f0-9]{64}$/u);
1048
+ export const attachmentFileNameSchema = z.string().min(1).max(ATTACHMENT_FILE_NAME_MAX_CHARS);
1049
+ export const ATTACHMENT_STATES = ["staged", "committed"];
1050
+ export const attachmentStateSchema = z.enum(ATTACHMENT_STATES);
1051
+ /**
1052
+ * Safe attachment metadata. Never carries client filesystem paths or inline binary content; the
1053
+ * displayName is a server-sanitized rendering of the client-declared fileName.
1054
+ */
1055
+ export const attachmentDescriptorSchema = z
1056
+ .object({
1057
+ attachmentId: attachmentIdSchema,
1058
+ fileName: attachmentFileNameSchema,
1059
+ displayName: attachmentFileNameSchema,
1060
+ mediaType: attachmentMediaTypeSchema,
1061
+ bytes: z.number().int().positive().max(RUNTIME_V14_MAX_ATTACHMENT_BYTES),
1062
+ sha256: attachmentSha256Schema,
1063
+ source: attachmentSourceSchema,
1064
+ createdAt: timestampSchema,
1065
+ })
1066
+ .strict()
1067
+ .readonly();
1068
+ export const attachmentStageParamsSchema = z
1069
+ .object({
1070
+ ...requestFields,
1071
+ ...threadRequestFields,
1072
+ fileName: attachmentFileNameSchema,
1073
+ mediaType: attachmentMediaTypeSchema,
1074
+ bytes: z.number().int().positive().max(RUNTIME_V14_MAX_ATTACHMENT_BYTES),
1075
+ sha256: attachmentSha256Schema,
1076
+ source: attachmentSourceSchema,
1077
+ sourcePath: z.string().min(1).optional(),
1078
+ })
1079
+ .strict()
1080
+ .refine((params) => (params.source === "local-path" ? params.sourcePath !== undefined : true), {
1081
+ message: "source 为 local-path 时必须提供 sourcePath",
1082
+ })
1083
+ .refine((params) => (params.source === "chunks" ? params.sourcePath === undefined : true), {
1084
+ message: "source 为 chunks 时不能提供 sourcePath",
1085
+ })
1086
+ .readonly();
1087
+ export const attachmentStageResultSchema = z
1088
+ .object({
1089
+ attachmentId: attachmentIdSchema,
1090
+ state: attachmentStateSchema,
1091
+ descriptor: attachmentDescriptorSchema.optional(),
1092
+ })
1093
+ .strict()
1094
+ .readonly();
1095
+ export const attachmentChunkParamsSchema = z
1096
+ .object({
1097
+ ...requestFields,
1098
+ ...threadRequestFields,
1099
+ attachmentId: attachmentIdSchema,
1100
+ sequence: z.number().int().nonnegative(),
1101
+ dataBase64: z
1102
+ .string()
1103
+ .min(1)
1104
+ .max(Math.ceil(RUNTIME_V14_MAX_ATTACHMENT_CHUNK_BYTES / 3) * 4 + 4)
1105
+ .regex(/^[A-Za-z0-9+/]+={0,2}$/u),
1106
+ })
1107
+ .strict()
1108
+ .readonly();
1109
+ export const attachmentChunkResultSchema = z
1110
+ .object({
1111
+ receivedBytes: z.number().int().nonnegative(),
1112
+ nextSequence: z.number().int().nonnegative(),
1113
+ })
1114
+ .strict()
1115
+ .readonly();
1116
+ export const attachmentCommitParamsSchema = z
1117
+ .object({
1118
+ ...requestFields,
1119
+ ...threadRequestFields,
1120
+ attachmentId: attachmentIdSchema,
1121
+ })
1122
+ .strict()
1123
+ .readonly();
1124
+ export const attachmentCommitResultSchema = z
1125
+ .object({
1126
+ descriptor: attachmentDescriptorSchema,
1127
+ })
1128
+ .strict()
1129
+ .readonly();
1130
+ export const attachmentReleaseParamsSchema = z
1131
+ .object({
1132
+ ...requestFields,
1133
+ ...threadRequestFields,
1134
+ attachmentId: attachmentIdSchema,
1135
+ })
1136
+ .strict()
1137
+ .readonly();
1138
+ export const attachmentReleaseResultSchema = z
1139
+ .object({
1140
+ released: z.boolean(),
1141
+ })
1142
+ .strict()
1143
+ .readonly();
901
1144
  export const turnStartParamsSchema = z
902
1145
  .object({
903
1146
  ...requestFields,
@@ -912,6 +1155,28 @@ export const turnStartParamsSchema = z
912
1155
  })
913
1156
  .strict()
914
1157
  .readonly();
1158
+ export const turnStartParamsV14Schema = z
1159
+ .object({
1160
+ ...requestFields,
1161
+ ...threadRequestFields,
1162
+ turnId: turnIdSchema,
1163
+ input: z
1164
+ .object({
1165
+ text: z.string(),
1166
+ attachments: z
1167
+ .array(attachmentIdSchema)
1168
+ .min(1)
1169
+ .max(RUNTIME_V14_MAX_TURN_ATTACHMENTS)
1170
+ .optional(),
1171
+ })
1172
+ .strict()
1173
+ .refine((input) => input.text.length > 0 || input.attachments !== undefined, {
1174
+ message: "input.text 为空时必须至少引用一个附件",
1175
+ })
1176
+ .readonly(),
1177
+ })
1178
+ .strict()
1179
+ .readonly();
915
1180
  export const turnStartResultSchema = z
916
1181
  .object({
917
1182
  accepted: z.literal(true),
@@ -1252,8 +1517,35 @@ export const runtimeEventEnvelopeV13Schema = z.discriminatedUnion("durability",
1252
1517
  runtimeDurableEventEnvelopeV13Schema,
1253
1518
  runtimeEphemeralEventEnvelopeV13Schema,
1254
1519
  ]);
1520
+ export const runtimeDurableEventEnvelopeV14Schema = z
1521
+ .object({
1522
+ protocolVersion: z.literal("1.4"),
1523
+ ...runtimeEventEnvelopeFields,
1524
+ durability: z.literal("durable"),
1525
+ eventId: runtimeEventIdSchema,
1526
+ cursor: runtimeEventCursorSchema,
1527
+ event: runtimeDurableEventV13Schema,
1528
+ })
1529
+ .strict()
1530
+ .superRefine(validateRuntimeEventCapabilities)
1531
+ .readonly();
1532
+ export const runtimeEphemeralEventEnvelopeV14Schema = z
1533
+ .object({
1534
+ protocolVersion: z.literal("1.4"),
1535
+ ...runtimeEventEnvelopeFields,
1536
+ durability: z.literal("ephemeral"),
1537
+ event: runtimeEphemeralEventV13Schema,
1538
+ })
1539
+ .strict()
1540
+ .superRefine(validateRuntimeEventCapabilities)
1541
+ .readonly();
1542
+ export const runtimeEventEnvelopeV14Schema = z.discriminatedUnion("durability", [
1543
+ runtimeDurableEventEnvelopeV14Schema,
1544
+ runtimeEphemeralEventEnvelopeV14Schema,
1545
+ ]);
1255
1546
  /** Any currently supported Runtime Event envelope. */
1256
1547
  export const runtimeEventEnvelopeSchema = z.union([
1548
+ runtimeEventEnvelopeV14Schema,
1257
1549
  runtimeEventEnvelopeV13Schema,
1258
1550
  runtimeEventEnvelopeV12Schema,
1259
1551
  runtimeEventEnvelopeV11Schema,
@@ -1284,6 +1576,14 @@ export const runtimeProtocolErrorDataV13Schema = z
1284
1576
  })
1285
1577
  .strict()
1286
1578
  .readonly();
1579
+ export const runtimeProtocolErrorDataV14Schema = z
1580
+ .object({
1581
+ rollCode: z.enum(Object.values(RUNTIME_ERROR_CODES_V14)),
1582
+ retryable: z.boolean(),
1583
+ details: jsonValueSchema.optional(),
1584
+ })
1585
+ .strict()
1586
+ .readonly();
1287
1587
  export const runtimeMethodSchemasV11 = {
1288
1588
  [RUNTIME_METHODS.initialize]: {
1289
1589
  params: initializeParamsSchema,
@@ -1366,19 +1666,54 @@ export const runtimeMethodSchemasV13 = {
1366
1666
  },
1367
1667
  [RUNTIME_METHODS.threadOpen]: {
1368
1668
  params: threadOpenParamsSchema,
1369
- result: threadOpenResultSchema,
1669
+ result: threadSnapshotV13Schema,
1370
1670
  },
1371
1671
  [RUNTIME_METHODS.threadSnapshot]: {
1372
1672
  params: threadSnapshotParamsV13Schema,
1373
- result: threadSnapshotResultSchema,
1673
+ result: threadSnapshotV13Schema,
1374
1674
  },
1375
1675
  [RUNTIME_METHODS.runtimeEventsResume]: {
1376
1676
  params: runtimeEventsResumeParamsSchema,
1377
1677
  result: runtimeEventsResumeResultSchema,
1378
1678
  },
1379
1679
  };
1680
+ export const runtimeMethodSchemasV14 = {
1681
+ ...runtimeMethodSchemasV13,
1682
+ [RUNTIME_METHODS.initialize]: {
1683
+ params: initializeParamsSchema,
1684
+ result: initializeResultV14Schema,
1685
+ },
1686
+ [RUNTIME_METHODS.threadOpen]: {
1687
+ params: threadOpenParamsSchema,
1688
+ result: threadSnapshotV14Schema,
1689
+ },
1690
+ [RUNTIME_METHODS.threadSnapshot]: {
1691
+ params: threadSnapshotParamsV13Schema,
1692
+ result: threadSnapshotV14Schema,
1693
+ },
1694
+ [RUNTIME_METHODS.turnStart]: {
1695
+ params: turnStartParamsV14Schema,
1696
+ result: turnStartResultSchema,
1697
+ },
1698
+ [RUNTIME_METHODS.attachmentStage]: {
1699
+ params: attachmentStageParamsSchema,
1700
+ result: attachmentStageResultSchema,
1701
+ },
1702
+ [RUNTIME_METHODS.attachmentChunk]: {
1703
+ params: attachmentChunkParamsSchema,
1704
+ result: attachmentChunkResultSchema,
1705
+ },
1706
+ [RUNTIME_METHODS.attachmentCommit]: {
1707
+ params: attachmentCommitParamsSchema,
1708
+ result: attachmentCommitResultSchema,
1709
+ },
1710
+ [RUNTIME_METHODS.attachmentRelease]: {
1711
+ params: attachmentReleaseParamsSchema,
1712
+ result: attachmentReleaseResultSchema,
1713
+ },
1714
+ };
1380
1715
  /** Latest Runtime method registry. Use the version registry for negotiated availability. */
1381
- export const runtimeMethodSchemas = runtimeMethodSchemasV13;
1716
+ export const runtimeMethodSchemas = runtimeMethodSchemasV14;
1382
1717
  export const runtimeServerRequestSchemasV10 = {};
1383
1718
  export const runtimeServerRequestSchemasV11 = {
1384
1719
  [RUNTIME_SERVER_REQUEST_METHODS.approvalRequest]: {
@@ -1400,6 +1735,14 @@ export const runtimeServerRequestSchemasV13 = runtimeServerRequestSchemasV12;
1400
1735
  /** Protocol 1.1 compatibility facade. Prefer the version registry in new code. */
1401
1736
  export const runtimeServerRequestSchemas = runtimeServerRequestSchemasV11;
1402
1737
  export const RUNTIME_PROTOCOL_REGISTRY = {
1738
+ "1.4": {
1739
+ methods: runtimeMethodSchemasV14,
1740
+ serverRequests: runtimeServerRequestSchemasV13,
1741
+ serverRequestMethods: RUNTIME_SERVER_REQUEST_METHOD_VALUES,
1742
+ serverRequestCancelParamsSchema: runtimeServerRequestCancelParamsV12Schema,
1743
+ eventEnvelopeSchema: runtimeEventEnvelopeV14Schema,
1744
+ errorDataSchema: runtimeProtocolErrorDataV14Schema,
1745
+ },
1403
1746
  "1.3": {
1404
1747
  methods: runtimeMethodSchemasV13,
1405
1748
  serverRequests: runtimeServerRequestSchemasV13,
@@ -1458,6 +1801,18 @@ export function getApprovalExplanation(approval) {
1458
1801
  const parsed = approvalExplanationSchema.safeParse(preview[APPROVAL_EXPLANATION_PREVIEW_KEY]);
1459
1802
  return parsed.success ? parsed.data : undefined;
1460
1803
  }
1804
+ export function getApprovalDiffPreview(approval) {
1805
+ const preview = approval.preview;
1806
+ if (typeof preview !== "object" || preview === null || Array.isArray(preview)) {
1807
+ return undefined;
1808
+ }
1809
+ const parsed = fileChangeDiffSchema.safeParse(preview[APPROVAL_DIFF_PREVIEW_KEY]);
1810
+ return parsed.success ? parsed.data : undefined;
1811
+ }
1812
+ export function getFileChangeDisplay(display) {
1813
+ const parsed = fileChangeDisplaySchema.safeParse(display);
1814
+ return parsed.success ? parsed.data : undefined;
1815
+ }
1461
1816
  function validateUserInputTextValue(control, value, path, addIssue) {
1462
1817
  if (typeof value !== "string") {
1463
1818
  addIssue(path, `${control.type} control requires a string value`);
@@ -1632,8 +1987,36 @@ export function parseRuntimeMethodParams(method, value) {
1632
1987
  export function parseRuntimeMethodResult(method, value) {
1633
1988
  return runtimeMethodSchemasV11[method].result.parse(value);
1634
1989
  }
1990
+ export function parseLatestRuntimeMethodParams(method, value) {
1991
+ return runtimeMethodSchemas[method].params.parse(value);
1992
+ }
1993
+ export function parseLatestRuntimeMethodResult(method, value) {
1994
+ return runtimeMethodSchemas[method].result.parse(value);
1995
+ }
1996
+ function projectUiMessagePageToTextParts(page) {
1997
+ return {
1998
+ items: page.items.map((message) => ({
1999
+ ...message,
2000
+ parts: message.parts.filter((part) => part.type === "text"),
2001
+ })),
2002
+ nextBeforeSequence: page.nextBeforeSequence,
2003
+ };
2004
+ }
1635
2005
  export function projectThreadSnapshotForVersion(version, value) {
1636
- const latest = threadSnapshotV13Schema.safeParse(value);
2006
+ const latestV14 = threadSnapshotV14Schema.safeParse(value);
2007
+ if (version === "1.4") {
2008
+ if (!latestV14.success) {
2009
+ throw latestV14.error;
2010
+ }
2011
+ return latestV14.data;
2012
+ }
2013
+ const v13Candidate = latestV14.success && !("recoveryProjection" in latestV14.data)
2014
+ ? {
2015
+ ...latestV14.data,
2016
+ messages: projectUiMessagePageToTextParts(latestV14.data.messages),
2017
+ }
2018
+ : value;
2019
+ const latest = threadSnapshotV13Schema.safeParse(v13Candidate);
1637
2020
  if (version === "1.3") {
1638
2021
  if (!latest.success) {
1639
2022
  throw latest.error;
@@ -1650,7 +2033,7 @@ export function projectThreadSnapshotForVersion(version, value) {
1650
2033
  pendingInteractions: latest.data.pendingInteractions,
1651
2034
  transcriptCompleteness: latest.data.transcriptCompleteness,
1652
2035
  })
1653
- : threadSnapshotV12Schema.parse(value);
2036
+ : threadSnapshotV12Schema.parse(v13Candidate);
1654
2037
  if (version === "1.2") {
1655
2038
  return v12;
1656
2039
  }
@@ -1672,8 +2055,17 @@ export function projectThreadSnapshotForVersion(version, value) {
1672
2055
  }
1673
2056
  export function projectRuntimeEventEnvelopeForVersion(version, value) {
1674
2057
  const source = runtimeEventEnvelopeSchema.parse(value);
2058
+ if (version === "1.4") {
2059
+ return runtimeEventEnvelopeV14Schema.parse({
2060
+ ...source,
2061
+ protocolVersion: version,
2062
+ });
2063
+ }
1675
2064
  if (version === "1.3") {
1676
- return runtimeEventEnvelopeV13Schema.parse(source);
2065
+ return runtimeEventEnvelopeV13Schema.parse({
2066
+ ...source,
2067
+ protocolVersion: version,
2068
+ });
1677
2069
  }
1678
2070
  const projectedEnvelopeFields = {
1679
2071
  runtimeInstanceId: source.runtimeInstanceId,