@markusylisiurunen/tau 0.3.23 → 0.3.24

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.
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- export const SESSION_PROTOCOL_VERSION = 1;
2
+ export const SESSION_PROTOCOL_VERSION = 2;
3
3
  export const SESSION_PROTOCOL_METHODS = [
4
4
  "initialize",
5
5
  "session.create",
@@ -13,6 +13,7 @@ export const SESSION_PROTOCOL_METHODS = [
13
13
  "session.cancelPendingMessages",
14
14
  "session.retry",
15
15
  "session.exec",
16
+ "session.sample",
16
17
  "session.interrupt",
17
18
  "session.snapshot",
18
19
  "session.setReasoning",
@@ -82,7 +83,116 @@ const nonEmptyStringSchema = z
82
83
  .refine((value) => value.trim().length > 0);
83
84
  const sessionProtocolRequestIdSchema = nonEmptyStringSchema;
84
85
  const nullableSessionProtocolRequestIdSchema = sessionProtocolRequestIdSchema.nullable();
85
- const messageSchema = z.custom(isMessage);
86
+ const modelTextContentSchema = z
87
+ .object({
88
+ type: z.literal("text"),
89
+ text: z.string(),
90
+ textSignature: z.string().optional(),
91
+ })
92
+ .strip();
93
+ const modelImageContentSchema = z
94
+ .object({
95
+ type: z.literal("image"),
96
+ data: z.string(),
97
+ mimeType: nonEmptyStringSchema,
98
+ })
99
+ .strip();
100
+ const modelThinkingContentSchema = z
101
+ .object({
102
+ type: z.literal("thinking"),
103
+ thinking: z.string(),
104
+ thinkingSignature: z.string().optional(),
105
+ redacted: z.boolean().optional(),
106
+ })
107
+ .strip();
108
+ const modelToolCallSchema = z
109
+ .object({
110
+ type: z.literal("toolCall"),
111
+ id: nonEmptyStringSchema,
112
+ name: nonEmptyStringSchema,
113
+ arguments: z.record(z.string(), z.unknown()),
114
+ thoughtSignature: z.string().optional(),
115
+ })
116
+ .strip();
117
+ const modelUsageSchema = z
118
+ .object({
119
+ input: z.number().int().nonnegative(),
120
+ output: z.number().int().nonnegative(),
121
+ cacheRead: z.number().int().nonnegative(),
122
+ cacheWrite: z.number().int().nonnegative(),
123
+ cacheWrite1h: z.number().int().nonnegative().optional(),
124
+ reasoning: z.number().int().nonnegative().optional(),
125
+ totalTokens: z.number().int().nonnegative(),
126
+ cost: z
127
+ .object({
128
+ input: z.number().nonnegative(),
129
+ output: z.number().nonnegative(),
130
+ cacheRead: z.number().nonnegative(),
131
+ cacheWrite: z.number().nonnegative(),
132
+ total: z.number().nonnegative(),
133
+ })
134
+ .strip(),
135
+ })
136
+ .strip();
137
+ const modelUserMessageSchema = z
138
+ .object({
139
+ role: z.literal("user"),
140
+ content: z.union([
141
+ z.string(),
142
+ z.array(z.union([modelTextContentSchema, modelImageContentSchema])),
143
+ ]),
144
+ timestamp: z.number().finite(),
145
+ })
146
+ .strip();
147
+ const modelDiagnosticErrorSchema = z
148
+ .object({
149
+ name: z.string().optional(),
150
+ message: z.string(),
151
+ stack: z.string().optional(),
152
+ code: z.union([z.string(), z.number()]).optional(),
153
+ })
154
+ .strip();
155
+ const modelDiagnosticSchema = z
156
+ .object({
157
+ type: z.string(),
158
+ timestamp: z.number().finite(),
159
+ error: modelDiagnosticErrorSchema.optional(),
160
+ details: z.record(z.string(), z.unknown()).optional(),
161
+ })
162
+ .strip();
163
+ const modelAssistantMessageSchema = z
164
+ .object({
165
+ role: z.literal("assistant"),
166
+ content: z.array(z.union([modelTextContentSchema, modelThinkingContentSchema, modelToolCallSchema])),
167
+ api: nonEmptyStringSchema,
168
+ provider: nonEmptyStringSchema,
169
+ model: nonEmptyStringSchema,
170
+ responseModel: nonEmptyStringSchema.optional(),
171
+ responseId: nonEmptyStringSchema.optional(),
172
+ diagnostics: z.array(modelDiagnosticSchema).optional(),
173
+ usage: modelUsageSchema,
174
+ stopReason: z.enum(["stop", "length", "toolUse", "error", "aborted"]),
175
+ errorMessage: z.string().optional(),
176
+ timestamp: z.number().finite(),
177
+ })
178
+ .strip();
179
+ const modelToolResultMessageSchema = z
180
+ .object({
181
+ role: z.literal("toolResult"),
182
+ toolCallId: nonEmptyStringSchema,
183
+ toolName: nonEmptyStringSchema,
184
+ content: z.array(z.union([modelTextContentSchema, modelImageContentSchema])),
185
+ details: z.unknown().optional(),
186
+ addedToolNames: z.array(nonEmptyStringSchema).optional(),
187
+ isError: z.boolean(),
188
+ timestamp: z.number().finite(),
189
+ })
190
+ .strip();
191
+ const modelMessageSchema = z.union([
192
+ modelUserMessageSchema,
193
+ modelAssistantMessageSchema,
194
+ modelToolResultMessageSchema,
195
+ ]);
86
196
  const sessionProtocolReadyMessageSchema = z
87
197
  .object({
88
198
  version: z.literal(SESSION_PROTOCOL_VERSION),
@@ -201,11 +311,6 @@ const sessionProtocolExecParamsSchema = z
201
311
  timeoutMs: z.number().int().positive().optional(),
202
312
  })
203
313
  .strip();
204
- const sessionProtocolSessionIdParamsSchema = z
205
- .object({
206
- sessionId: nonEmptyStringSchema,
207
- })
208
- .strip();
209
314
  const sessionProtocolReasoningEffortSchema = z.enum([
210
315
  "none",
211
316
  "minimal",
@@ -215,6 +320,36 @@ const sessionProtocolReasoningEffortSchema = z.enum([
215
320
  "xhigh",
216
321
  "max",
217
322
  ]);
323
+ const sessionProtocolSampleToolSchema = z
324
+ .object({
325
+ name: nonEmptyStringSchema,
326
+ description: z.string(),
327
+ parameters: z.record(z.string(), z.unknown()),
328
+ })
329
+ .strip();
330
+ const sessionProtocolSampleParamsSchema = z
331
+ .object({
332
+ sessionId: nonEmptyStringSchema,
333
+ context: z
334
+ .object({
335
+ systemPrompt: z.string(),
336
+ messages: z.array(modelMessageSchema),
337
+ tools: z.array(sessionProtocolSampleToolSchema).optional(),
338
+ })
339
+ .strip(),
340
+ options: z
341
+ .object({
342
+ reasoning: sessionProtocolReasoningEffortSchema.optional(),
343
+ maxTokens: z.number().int().positive().optional(),
344
+ })
345
+ .strip(),
346
+ })
347
+ .strip();
348
+ const sessionProtocolSessionIdParamsSchema = z
349
+ .object({
350
+ sessionId: nonEmptyStringSchema,
351
+ })
352
+ .strip();
218
353
  const sessionProtocolSetReasoningParamsSchema = z
219
354
  .object({
220
355
  sessionId: nonEmptyStringSchema,
@@ -516,15 +651,44 @@ const sessionProtocolDraftAssistantMessageSchema = z
516
651
  .strip();
517
652
  const sessionProtocolMessagePayloadSchema = z.union([
518
653
  sessionProtocolSystemMessageSchema,
519
- messageSchema,
654
+ modelMessageSchema,
520
655
  sessionProtocolDraftAssistantMessageSchema,
521
656
  ]);
657
+ const sessionProtocolTurnOutcomeSchema = z.discriminatedUnion("status", [
658
+ z
659
+ .object({
660
+ status: z.literal("completed"),
661
+ stopReason: z.enum(["stop", "length", "toolUse"]),
662
+ })
663
+ .strip(),
664
+ z
665
+ .object({
666
+ status: z.literal("failed"),
667
+ stopReason: z.literal("error"),
668
+ errorMessage: z.string().optional(),
669
+ })
670
+ .strip(),
671
+ z
672
+ .object({
673
+ status: z.literal("aborted"),
674
+ stopReason: z.literal("aborted"),
675
+ })
676
+ .strip(),
677
+ z
678
+ .object({
679
+ status: z.literal("blocked"),
680
+ reason: z.literal("auto-compaction-failed"),
681
+ message: z.string(),
682
+ })
683
+ .strip(),
684
+ ]);
522
685
  const sessionProtocolMessageSchema = z
523
686
  .object({
524
687
  id: nonEmptyStringSchema,
525
688
  state: z.enum(["draft", "committed", "interrupted", "discarded"]),
526
689
  modelVisible: z.boolean(),
527
690
  message: sessionProtocolMessagePayloadSchema,
691
+ turn: sessionProtocolTurnOutcomeSchema.optional(),
528
692
  })
529
693
  .strip();
530
694
  const sessionProtocolNoticeSchema = z
@@ -660,6 +824,13 @@ const sessionProtocolSnapshotSchema = z
660
824
  message: `duplicate message id '${message.id}'`,
661
825
  });
662
826
  }
827
+ if (message.turn && message.message.role !== "user") {
828
+ ctx.addIssue({
829
+ code: "custom",
830
+ path: ["messages"],
831
+ message: `turn outcome belongs to non-user message '${message.id}'`,
832
+ });
833
+ }
663
834
  messagesById.set(message.id, message);
664
835
  }
665
836
  const timelineIds = new Set();
@@ -1034,18 +1205,7 @@ const sessionProtocolListResultSchema = z
1034
1205
  .strip();
1035
1206
  const sessionProtocolSubmitResultSchema = z
1036
1207
  .object({
1037
- turn: z
1038
- .object({
1039
- aborted: z.boolean(),
1040
- blocked: z
1041
- .object({
1042
- reason: z.literal("auto-compaction-failed"),
1043
- message: z.string(),
1044
- })
1045
- .strip()
1046
- .optional(),
1047
- })
1048
- .strip(),
1208
+ turn: sessionProtocolTurnOutcomeSchema,
1049
1209
  })
1050
1210
  .strip();
1051
1211
  const sessionProtocolTurnResultSchema = sessionProtocolSubmitResultSchema;
@@ -1075,6 +1235,11 @@ const sessionProtocolExecResultSchema = z
1075
1235
  truncated: z.boolean(),
1076
1236
  })
1077
1237
  .strip();
1238
+ const sessionProtocolSampleResultSchema = z
1239
+ .object({
1240
+ message: modelAssistantMessageSchema,
1241
+ })
1242
+ .strip();
1078
1243
  const sessionProtocolInterruptResultSchema = z
1079
1244
  .object({
1080
1245
  interrupted: z.boolean(),
@@ -1679,6 +1844,8 @@ export function validateSessionProtocolParams(method, params) {
1679
1844
  return validateUserMessageParams(method, params);
1680
1845
  case "session.exec":
1681
1846
  return validateExecParams(params);
1847
+ case "session.sample":
1848
+ return validateSampleParams(params);
1682
1849
  case "session.list":
1683
1850
  return validateNoParams(method, params);
1684
1851
  case "session.cancelPendingMessages":
@@ -1768,6 +1935,8 @@ export function validateSessionProtocolResult(method, result) {
1768
1935
  return validateResult(method, result, sessionProtocolRetryResultSchema);
1769
1936
  case "session.exec":
1770
1937
  return validateResult(method, result, sessionProtocolExecResultSchema);
1938
+ case "session.sample":
1939
+ return validateResult(method, result, sessionProtocolSampleResultSchema);
1771
1940
  case "session.interrupt":
1772
1941
  return validateResult(method, result, sessionProtocolInterruptResultSchema);
1773
1942
  }
@@ -1890,6 +2059,22 @@ function validateExecParams(params) {
1890
2059
  },
1891
2060
  };
1892
2061
  }
2062
+ function validateSampleParams(params) {
2063
+ const parsed = sessionProtocolSampleParamsSchema.safeParse(params);
2064
+ if (!parsed.success) {
2065
+ const message = hasIssue(parsed.error, [], "invalid_type")
2066
+ ? "session.sample params must be an object"
2067
+ : hasIssue(parsed.error, ["sessionId"])
2068
+ ? "session.sample params.sessionId must be a non-empty string"
2069
+ : hasIssue(parsed.error, ["context"])
2070
+ ? "session.sample params.context must include a system prompt and messages"
2071
+ : hasIssue(parsed.error, ["options"])
2072
+ ? "session.sample params.options must be an object"
2073
+ : `session.sample params are invalid: ${formatZodError(parsed.error)}`;
2074
+ return invalidParams(message);
2075
+ }
2076
+ return { ok: true, value: parsed.data };
2077
+ }
1893
2078
  function validateSetReasoningParams(params) {
1894
2079
  const parsed = sessionProtocolSetReasoningParamsSchema.safeParse(params);
1895
2080
  if (!parsed.success) {
@@ -2375,24 +2560,6 @@ function invalidParams(message) {
2375
2560
  error: createSessionProtocolError(SESSION_PROTOCOL_ERROR_CODES.invalidParams, message),
2376
2561
  };
2377
2562
  }
2378
- function isMessage(value) {
2379
- if (!isRecord(value)) {
2380
- return false;
2381
- }
2382
- switch (value.role) {
2383
- case "user":
2384
- return typeof value.content === "string" || Array.isArray(value.content);
2385
- case "assistant":
2386
- return Array.isArray(value.content);
2387
- case "toolResult":
2388
- return (typeof value.toolCallId === "string" &&
2389
- typeof value.toolName === "string" &&
2390
- typeof value.isError === "boolean" &&
2391
- Array.isArray(value.content));
2392
- default:
2393
- return false;
2394
- }
2395
- }
2396
2563
  function isRecord(value) {
2397
2564
  return typeof value === "object" && value !== null && !Array.isArray(value);
2398
2565
  }