ai-sdk-provider-claude-code 3.5.3 → 4.0.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/README.md +223 -136
- package/dist/index.d.ts +238 -55
- package/dist/index.js +963 -295
- package/dist/index.js.map +1 -1
- package/docs/sessions.md +4 -4
- package/package.json +12 -14
- package/dist/index.cjs +0 -4085
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -1331
package/dist/index.js
CHANGED
|
@@ -3,11 +3,21 @@ import { NoSuchModelError as NoSuchModelError2 } from "@ai-sdk/provider";
|
|
|
3
3
|
|
|
4
4
|
// src/claude-code-language-model.ts
|
|
5
5
|
import { NoSuchModelError, APICallError as APICallError2, LoadAPIKeyError as LoadAPIKeyError2 } from "@ai-sdk/provider";
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
generateId,
|
|
8
|
+
isCustomReasoning,
|
|
9
|
+
mapReasoningToProviderEffort
|
|
10
|
+
} from "@ai-sdk/provider-utils";
|
|
7
11
|
|
|
8
12
|
// src/convert-to-claude-code-messages.ts
|
|
13
|
+
import { detectMediaType } from "@ai-sdk/provider-utils";
|
|
9
14
|
var IMAGE_URL_WARNING = "Image URLs are not supported by this provider; supply base64/data URLs.";
|
|
10
15
|
var IMAGE_CONVERSION_WARNING = "Unable to convert image content; supply base64/data URLs.";
|
|
16
|
+
var FILE_REFERENCE_WARNING = "Provider file references are not supported by this provider; supply inline file data.";
|
|
17
|
+
function createUnsupportedFilePartWarning(mediaType) {
|
|
18
|
+
const mediaTypeLabel = mediaType && mediaType.trim() ? mediaType : "unknown";
|
|
19
|
+
return `Unsupported file part (${mediaTypeLabel}) was ignored; this provider forwards only image file parts inline.`;
|
|
20
|
+
}
|
|
11
21
|
var MAX_TOOL_CALL_INPUT_LENGTH = 1e3;
|
|
12
22
|
function serializeToolCallInput(input) {
|
|
13
23
|
let serialized;
|
|
@@ -25,42 +35,75 @@ function serializeToolCallInput(input) {
|
|
|
25
35
|
}
|
|
26
36
|
return serialized;
|
|
27
37
|
}
|
|
28
|
-
function
|
|
29
|
-
|
|
38
|
+
function getVariantName(value, discriminator) {
|
|
39
|
+
if (typeof value === "object" && value !== null) {
|
|
40
|
+
const candidate = value[discriminator];
|
|
41
|
+
if (typeof candidate === "string" && candidate) {
|
|
42
|
+
return candidate;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return String(value);
|
|
46
|
+
}
|
|
47
|
+
function createUnknownPromptVariantWarning(value, context, discriminator = "type") {
|
|
48
|
+
return `Unsupported ${context} ${discriminator} '${getVariantName(
|
|
49
|
+
value,
|
|
50
|
+
discriminator
|
|
51
|
+
)}' was skipped.`;
|
|
52
|
+
}
|
|
53
|
+
function extractMimeType(candidate) {
|
|
54
|
+
if (typeof candidate === "string" && candidate.trim()) {
|
|
55
|
+
return candidate.trim();
|
|
56
|
+
}
|
|
57
|
+
return void 0;
|
|
58
|
+
}
|
|
59
|
+
function normalizeMediaType(mediaType) {
|
|
60
|
+
return mediaType.trim().toLowerCase();
|
|
61
|
+
}
|
|
62
|
+
function isImageMimeType(mediaType) {
|
|
63
|
+
if (!mediaType) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
const normalized = normalizeMediaType(mediaType);
|
|
67
|
+
return normalized === "image" || normalized === "image/*" || normalized.startsWith("image/");
|
|
30
68
|
}
|
|
31
|
-
function
|
|
32
|
-
|
|
69
|
+
function isConcreteImageMimeType(mediaType) {
|
|
70
|
+
const normalized = normalizeMediaType(mediaType);
|
|
71
|
+
return normalized.startsWith("image/") && !normalized.endsWith("/*");
|
|
72
|
+
}
|
|
73
|
+
function resolveImageMediaType(mediaType, data) {
|
|
74
|
+
const normalizedMediaType = normalizeMediaType(mediaType);
|
|
75
|
+
if (isConcreteImageMimeType(normalizedMediaType)) {
|
|
76
|
+
return normalizedMediaType;
|
|
77
|
+
}
|
|
78
|
+
if ((normalizedMediaType === "image" || normalizedMediaType === "image/*") && data) {
|
|
79
|
+
try {
|
|
80
|
+
const detectedMediaType = detectMediaType({ data, topLevelType: "image" });
|
|
81
|
+
if (detectedMediaType && isConcreteImageMimeType(detectedMediaType)) {
|
|
82
|
+
return detectedMediaType;
|
|
83
|
+
}
|
|
84
|
+
} catch {
|
|
85
|
+
return void 0;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
return void 0;
|
|
33
89
|
}
|
|
34
90
|
function createImageContent(mediaType, data) {
|
|
35
|
-
const
|
|
36
|
-
const trimmedData =
|
|
37
|
-
if (!
|
|
91
|
+
const normalizedType = normalizeMediaType(mediaType);
|
|
92
|
+
const trimmedData = data.trim().replace(/\s+/g, "");
|
|
93
|
+
if (!isConcreteImageMimeType(normalizedType) || !trimmedData) {
|
|
38
94
|
return void 0;
|
|
39
95
|
}
|
|
40
96
|
return {
|
|
41
97
|
type: "image",
|
|
42
98
|
source: {
|
|
43
99
|
type: "base64",
|
|
44
|
-
media_type:
|
|
100
|
+
media_type: normalizedType,
|
|
45
101
|
data: trimmedData
|
|
46
102
|
}
|
|
47
103
|
};
|
|
48
104
|
}
|
|
49
|
-
function
|
|
50
|
-
|
|
51
|
-
return candidate.trim();
|
|
52
|
-
}
|
|
53
|
-
return void 0;
|
|
54
|
-
}
|
|
55
|
-
function parseObjectImage(imageObj, fallbackMimeType) {
|
|
56
|
-
const data = typeof imageObj.data === "string" ? imageObj.data : void 0;
|
|
57
|
-
const mimeType = extractMimeType(
|
|
58
|
-
imageObj.mimeType ?? imageObj.mediaType ?? imageObj.media_type ?? fallbackMimeType
|
|
59
|
-
);
|
|
60
|
-
if (!data || !mimeType) {
|
|
61
|
-
return void 0;
|
|
62
|
-
}
|
|
63
|
-
return createImageContent(mimeType, data);
|
|
105
|
+
function resolveStringImageMediaType(mediaType, data, fallbackMimeType) {
|
|
106
|
+
return resolveImageMediaType(mediaType, data) ?? (fallbackMimeType ? resolveImageMediaType(fallbackMimeType, data) : void 0);
|
|
64
107
|
}
|
|
65
108
|
function parseStringImage(value, fallbackMimeType) {
|
|
66
109
|
const trimmed = value.trim();
|
|
@@ -70,41 +113,31 @@ function parseStringImage(value, fallbackMimeType) {
|
|
|
70
113
|
const dataUrlMatch = trimmed.match(/^data:([^;]+);base64,(.+)$/i);
|
|
71
114
|
if (dataUrlMatch) {
|
|
72
115
|
const [, mediaType, data] = dataUrlMatch;
|
|
73
|
-
const
|
|
116
|
+
const resolvedMediaType = resolveStringImageMediaType(mediaType, data, fallbackMimeType);
|
|
117
|
+
const content = resolvedMediaType ? createImageContent(resolvedMediaType, data) : void 0;
|
|
74
118
|
return content ? { content } : { warning: IMAGE_CONVERSION_WARNING };
|
|
75
119
|
}
|
|
76
120
|
const base64Match = trimmed.match(/^base64:([^,]+),(.+)$/i);
|
|
77
121
|
if (base64Match) {
|
|
78
122
|
const [, explicitMimeType, data] = base64Match;
|
|
79
|
-
const
|
|
123
|
+
const resolvedMediaType = resolveStringImageMediaType(explicitMimeType, data, fallbackMimeType);
|
|
124
|
+
const content = resolvedMediaType ? createImageContent(resolvedMediaType, data) : void 0;
|
|
80
125
|
return content ? { content } : { warning: IMAGE_CONVERSION_WARNING };
|
|
81
126
|
}
|
|
82
127
|
if (fallbackMimeType) {
|
|
83
|
-
const
|
|
84
|
-
if (
|
|
85
|
-
|
|
128
|
+
const resolvedMediaType = resolveImageMediaType(fallbackMimeType, trimmed);
|
|
129
|
+
if (resolvedMediaType) {
|
|
130
|
+
const content = createImageContent(resolvedMediaType, trimmed);
|
|
131
|
+
if (content) {
|
|
132
|
+
return { content };
|
|
133
|
+
}
|
|
86
134
|
}
|
|
87
135
|
}
|
|
88
136
|
return { warning: IMAGE_CONVERSION_WARNING };
|
|
89
137
|
}
|
|
90
|
-
function parseImagePart(part) {
|
|
91
|
-
if (!part || typeof part !== "object") {
|
|
92
|
-
return { warning: IMAGE_CONVERSION_WARNING };
|
|
93
|
-
}
|
|
94
|
-
const imageValue = part.image;
|
|
95
|
-
const mimeType = extractMimeType(part.mimeType);
|
|
96
|
-
if (typeof imageValue === "string") {
|
|
97
|
-
return parseStringImage(imageValue, mimeType);
|
|
98
|
-
}
|
|
99
|
-
if (imageValue && typeof imageValue === "object") {
|
|
100
|
-
const content = parseObjectImage(imageValue, mimeType);
|
|
101
|
-
return content ? { content } : { warning: IMAGE_CONVERSION_WARNING };
|
|
102
|
-
}
|
|
103
|
-
return { warning: IMAGE_CONVERSION_WARNING };
|
|
104
|
-
}
|
|
105
138
|
function convertBinaryToBase64(data) {
|
|
106
139
|
if (typeof Buffer !== "undefined") {
|
|
107
|
-
const buffer = data instanceof Uint8Array ? Buffer.from(data) : Buffer.from(
|
|
140
|
+
const buffer = data instanceof Uint8Array ? Buffer.from(data.buffer, data.byteOffset, data.byteLength) : Buffer.from(data);
|
|
108
141
|
return buffer.toString("base64");
|
|
109
142
|
}
|
|
110
143
|
if (typeof btoa === "function") {
|
|
@@ -120,24 +153,102 @@ function convertBinaryToBase64(data) {
|
|
|
120
153
|
return void 0;
|
|
121
154
|
}
|
|
122
155
|
function parseFilePart(part) {
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
|
|
156
|
+
const mediaType = extractMimeType(part.mediaType);
|
|
157
|
+
const fileData = part.data;
|
|
158
|
+
switch (fileData.type) {
|
|
159
|
+
case "data": {
|
|
160
|
+
if (!mediaType || !isImageMimeType(mediaType)) {
|
|
161
|
+
return { warning: createUnsupportedFilePartWarning(mediaType) };
|
|
162
|
+
}
|
|
163
|
+
if (typeof fileData.data === "string") {
|
|
164
|
+
return parseStringImage(fileData.data, mediaType);
|
|
165
|
+
}
|
|
166
|
+
const resolvedMediaType = resolveImageMediaType(mediaType, fileData.data);
|
|
167
|
+
if (!resolvedMediaType) {
|
|
168
|
+
return { warning: IMAGE_CONVERSION_WARNING };
|
|
169
|
+
}
|
|
170
|
+
const base64 = convertBinaryToBase64(fileData.data);
|
|
171
|
+
if (!base64) {
|
|
172
|
+
return { warning: IMAGE_CONVERSION_WARNING };
|
|
173
|
+
}
|
|
174
|
+
const content = createImageContent(resolvedMediaType, base64);
|
|
175
|
+
return content ? { content } : { warning: IMAGE_CONVERSION_WARNING };
|
|
176
|
+
}
|
|
177
|
+
case "url": {
|
|
178
|
+
if (!mediaType || !isImageMimeType(mediaType)) {
|
|
179
|
+
return { warning: createUnsupportedFilePartWarning(mediaType) };
|
|
180
|
+
}
|
|
181
|
+
const url = fileData.url.toString();
|
|
182
|
+
if (!/^data:/i.test(url.trim())) {
|
|
183
|
+
return { warning: IMAGE_URL_WARNING };
|
|
184
|
+
}
|
|
185
|
+
return parseStringImage(url, mediaType);
|
|
186
|
+
}
|
|
187
|
+
case "text":
|
|
188
|
+
return fileData.text ? { text: fileData.text } : {};
|
|
189
|
+
case "reference":
|
|
190
|
+
return { warning: FILE_REFERENCE_WARNING };
|
|
191
|
+
default: {
|
|
192
|
+
const unknownFileData = fileData;
|
|
193
|
+
return {
|
|
194
|
+
warning: createUnknownPromptVariantWarning(unknownFileData, "prompt file data")
|
|
195
|
+
};
|
|
196
|
+
}
|
|
126
197
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
198
|
+
}
|
|
199
|
+
function serializeToolResultFilePart(part, warnings) {
|
|
200
|
+
const fileData = part.data;
|
|
201
|
+
const fileLabel = part.filename ? `File ${part.filename}` : "File";
|
|
202
|
+
switch (fileData.type) {
|
|
203
|
+
case "data":
|
|
204
|
+
return `[${fileLabel}: ${part.mediaType}]`;
|
|
205
|
+
case "url":
|
|
206
|
+
return `[${fileLabel}: ${part.mediaType}: ${fileData.url.toString()}]`;
|
|
207
|
+
case "text":
|
|
208
|
+
return fileData.text;
|
|
209
|
+
case "reference":
|
|
210
|
+
warnings.push(FILE_REFERENCE_WARNING);
|
|
211
|
+
return void 0;
|
|
212
|
+
default: {
|
|
213
|
+
const unknownFileData = fileData;
|
|
214
|
+
warnings.push(createUnknownPromptVariantWarning(unknownFileData, "tool result file data"));
|
|
215
|
+
return void 0;
|
|
216
|
+
}
|
|
131
217
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
218
|
+
}
|
|
219
|
+
function serializeToolResultContentPart(part, warnings) {
|
|
220
|
+
switch (part.type) {
|
|
221
|
+
case "text":
|
|
222
|
+
return part.text;
|
|
223
|
+
case "file":
|
|
224
|
+
return serializeToolResultFilePart(part, warnings);
|
|
225
|
+
case "custom":
|
|
226
|
+
return void 0;
|
|
227
|
+
default: {
|
|
228
|
+
const unknownPart = part;
|
|
229
|
+
warnings.push(createUnknownPromptVariantWarning(unknownPart, "tool result content part"));
|
|
230
|
+
return void 0;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
function serializeToolResultOutput(output, warnings) {
|
|
235
|
+
switch (output.type) {
|
|
236
|
+
case "text":
|
|
237
|
+
case "error-text":
|
|
238
|
+
return output.value;
|
|
239
|
+
case "json":
|
|
240
|
+
case "error-json":
|
|
241
|
+
return JSON.stringify(output.value) ?? String(output.value);
|
|
242
|
+
case "execution-denied":
|
|
243
|
+
return `[Execution denied${output.reason ? `: ${output.reason}` : ""}]`;
|
|
244
|
+
case "content":
|
|
245
|
+
return output.value.map((part) => serializeToolResultContentPart(part, warnings)).filter((text) => typeof text === "string" && text.length > 0).join("\n");
|
|
246
|
+
default: {
|
|
247
|
+
const unknownOutput = output;
|
|
248
|
+
warnings.push(createUnknownPromptVariantWarning(unknownOutput, "tool result output"));
|
|
249
|
+
return void 0;
|
|
136
250
|
}
|
|
137
|
-
const content = createImageContent(mimeType, base64);
|
|
138
|
-
return content ? { content } : { warning: IMAGE_CONVERSION_WARNING };
|
|
139
251
|
}
|
|
140
|
-
return { warning: IMAGE_CONVERSION_WARNING };
|
|
141
252
|
}
|
|
142
253
|
function convertToClaudeCodeMessages(prompt) {
|
|
143
254
|
const messages = [];
|
|
@@ -157,89 +268,149 @@ function convertToClaudeCodeMessages(prompt) {
|
|
|
157
268
|
}
|
|
158
269
|
imageMap.get(segmentIndex)?.push(content);
|
|
159
270
|
};
|
|
271
|
+
const addWarning = (warning) => {
|
|
272
|
+
if (warning) {
|
|
273
|
+
warnings.push(warning);
|
|
274
|
+
}
|
|
275
|
+
};
|
|
160
276
|
for (const message of prompt) {
|
|
161
277
|
switch (message.role) {
|
|
162
278
|
case "system":
|
|
163
|
-
systemPrompt = message.content
|
|
164
|
-
|
|
279
|
+
systemPrompt = systemPrompt === void 0 ? message.content : `${systemPrompt}
|
|
280
|
+
|
|
281
|
+
${message.content}`;
|
|
282
|
+
if (message.content.trim().length > 0) {
|
|
165
283
|
addSegment(message.content);
|
|
166
284
|
} else {
|
|
167
285
|
addSegment("");
|
|
168
286
|
}
|
|
169
287
|
break;
|
|
170
|
-
case "user":
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
addImageForSegment(segmentIndex, content);
|
|
185
|
-
} else if (warning) {
|
|
186
|
-
warnings.push(warning);
|
|
288
|
+
case "user": {
|
|
289
|
+
const textParts = [];
|
|
290
|
+
const imageParts = [];
|
|
291
|
+
for (const part of message.content) {
|
|
292
|
+
switch (part.type) {
|
|
293
|
+
case "text":
|
|
294
|
+
if (typeof part.text === "string") {
|
|
295
|
+
textParts.push(part.text);
|
|
296
|
+
}
|
|
297
|
+
break;
|
|
298
|
+
case "file": {
|
|
299
|
+
const { content, text, warning } = parseFilePart(part);
|
|
300
|
+
if (typeof text === "string") {
|
|
301
|
+
textParts.push(text);
|
|
187
302
|
}
|
|
188
|
-
} else if (part.type === "file") {
|
|
189
|
-
const { content, warning } = parseFilePart(part);
|
|
190
303
|
if (content) {
|
|
191
|
-
|
|
192
|
-
} else if (warning) {
|
|
193
|
-
warnings.push(warning);
|
|
304
|
+
imageParts.push(content);
|
|
194
305
|
}
|
|
306
|
+
addWarning(warning);
|
|
307
|
+
break;
|
|
308
|
+
}
|
|
309
|
+
default: {
|
|
310
|
+
const unknownPart = part;
|
|
311
|
+
addWarning(
|
|
312
|
+
createUnknownPromptVariantWarning(unknownPart, "prompt user content part")
|
|
313
|
+
);
|
|
314
|
+
break;
|
|
195
315
|
}
|
|
196
316
|
}
|
|
197
317
|
}
|
|
318
|
+
const textContent = textParts.join("\n");
|
|
319
|
+
const segmentIndex = addSegment(textContent ? `Human: ${textContent}` : "");
|
|
320
|
+
if (textContent) {
|
|
321
|
+
messages.push(`Human: ${textContent}`);
|
|
322
|
+
}
|
|
323
|
+
for (const imagePart of imageParts) {
|
|
324
|
+
addImageForSegment(segmentIndex, imagePart);
|
|
325
|
+
}
|
|
198
326
|
break;
|
|
327
|
+
}
|
|
199
328
|
case "assistant": {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
329
|
+
const assistantParts = [];
|
|
330
|
+
const imageParts = [];
|
|
331
|
+
for (const part of message.content) {
|
|
332
|
+
switch (part.type) {
|
|
333
|
+
case "text":
|
|
334
|
+
if (typeof part.text === "string") {
|
|
335
|
+
assistantParts.push(part.text);
|
|
336
|
+
}
|
|
337
|
+
break;
|
|
338
|
+
case "tool-call":
|
|
339
|
+
assistantParts.push(
|
|
340
|
+
`[Tool call: ${part.toolName}(${serializeToolCallInput(part.input)})]`
|
|
341
|
+
);
|
|
342
|
+
break;
|
|
343
|
+
case "tool-result": {
|
|
344
|
+
const output = serializeToolResultOutput(part.output, warnings);
|
|
345
|
+
if (output !== void 0) {
|
|
346
|
+
assistantParts.push(`Tool Result (${part.toolName}): ${output}`);
|
|
347
|
+
}
|
|
348
|
+
break;
|
|
349
|
+
}
|
|
350
|
+
case "file": {
|
|
351
|
+
const { content, text, warning } = parseFilePart(part);
|
|
352
|
+
if (typeof text === "string") {
|
|
353
|
+
assistantParts.push(text);
|
|
354
|
+
}
|
|
355
|
+
if (content) {
|
|
356
|
+
imageParts.push(content);
|
|
357
|
+
}
|
|
358
|
+
addWarning(warning);
|
|
359
|
+
break;
|
|
360
|
+
}
|
|
361
|
+
case "reasoning":
|
|
362
|
+
break;
|
|
363
|
+
case "reasoning-file":
|
|
364
|
+
break;
|
|
365
|
+
case "custom":
|
|
366
|
+
break;
|
|
367
|
+
default: {
|
|
368
|
+
const unknownPart = part;
|
|
369
|
+
addWarning(
|
|
370
|
+
createUnknownPromptVariantWarning(unknownPart, "prompt assistant content part")
|
|
371
|
+
);
|
|
372
|
+
break;
|
|
373
|
+
}
|
|
213
374
|
}
|
|
214
375
|
}
|
|
376
|
+
const assistantContent = assistantParts.join("\n");
|
|
215
377
|
const formattedAssistant = `Assistant: ${assistantContent}`;
|
|
216
378
|
messages.push(formattedAssistant);
|
|
217
|
-
addSegment(formattedAssistant);
|
|
379
|
+
const segmentIndex = addSegment(formattedAssistant);
|
|
380
|
+
for (const imagePart of imageParts) {
|
|
381
|
+
addImageForSegment(segmentIndex, imagePart);
|
|
382
|
+
}
|
|
218
383
|
break;
|
|
219
384
|
}
|
|
220
385
|
case "tool":
|
|
221
386
|
for (const tool3 of message.content) {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
387
|
+
switch (tool3.type) {
|
|
388
|
+
case "tool-result": {
|
|
389
|
+
const output = serializeToolResultOutput(tool3.output, warnings);
|
|
390
|
+
if (output !== void 0) {
|
|
391
|
+
const formattedToolResult = `Tool Result (${tool3.toolName}): ${output}`;
|
|
392
|
+
messages.push(formattedToolResult);
|
|
393
|
+
addSegment(formattedToolResult);
|
|
394
|
+
}
|
|
395
|
+
break;
|
|
396
|
+
}
|
|
397
|
+
case "tool-approval-response":
|
|
398
|
+
break;
|
|
399
|
+
default: {
|
|
400
|
+
const unknownPart = tool3;
|
|
401
|
+
addWarning(
|
|
402
|
+
createUnknownPromptVariantWarning(unknownPart, "prompt tool content part")
|
|
403
|
+
);
|
|
404
|
+
break;
|
|
405
|
+
}
|
|
237
406
|
}
|
|
238
|
-
const formattedToolResult = `Tool Result (${tool3.toolName}): ${resultText}`;
|
|
239
|
-
messages.push(formattedToolResult);
|
|
240
|
-
addSegment(formattedToolResult);
|
|
241
407
|
}
|
|
242
408
|
break;
|
|
409
|
+
default: {
|
|
410
|
+
const unknownMessage = message;
|
|
411
|
+
addWarning(createUnknownPromptVariantWarning(unknownMessage, "prompt message", "role"));
|
|
412
|
+
break;
|
|
413
|
+
}
|
|
243
414
|
}
|
|
244
415
|
}
|
|
245
416
|
let finalPrompt = "";
|
|
@@ -249,12 +420,7 @@ ${serializedCalls}` : serializedCalls;
|
|
|
249
420
|
if (messages.length > 0) {
|
|
250
421
|
const formattedMessages = [];
|
|
251
422
|
for (let i = 0; i < messages.length; i++) {
|
|
252
|
-
|
|
253
|
-
if (msg.startsWith("Assistant:") || msg.startsWith("Tool Result")) {
|
|
254
|
-
formattedMessages.push(msg);
|
|
255
|
-
} else {
|
|
256
|
-
formattedMessages.push(`Human: ${msg}`);
|
|
257
|
-
}
|
|
423
|
+
formattedMessages.push(messages[i]);
|
|
258
424
|
}
|
|
259
425
|
if (finalPrompt) {
|
|
260
426
|
const joinedMessages = formattedMessages.join("\n\n");
|
|
@@ -322,21 +488,6 @@ ${segmentText}`;
|
|
|
322
488
|
|
|
323
489
|
// src/errors.ts
|
|
324
490
|
import { APICallError, LoadAPIKeyError } from "@ai-sdk/provider";
|
|
325
|
-
var STDERR_TAIL_MARKER = " | stderr (tail):";
|
|
326
|
-
var ANSI_ESCAPE_SEQUENCE = (
|
|
327
|
-
// eslint-disable-next-line no-control-regex
|
|
328
|
-
/\x1b(?:\][^\x07\x1b]*(?:\x07|\x1b\\)|\[[0-?]*[ -/]*[@-~])/g
|
|
329
|
-
);
|
|
330
|
-
function stderrTail(raw) {
|
|
331
|
-
const withoutAnsi = raw.replace(ANSI_ESCAPE_SEQUENCE, "");
|
|
332
|
-
const withoutControlCharacters = Array.from(withoutAnsi).filter((character) => {
|
|
333
|
-
const codePoint = character.codePointAt(0) ?? 0;
|
|
334
|
-
return character === "\r" || character === "\n" || codePoint === 8232 || codePoint === 8233 || codePoint >= 32 && codePoint < 127 || codePoint > 159;
|
|
335
|
-
}).join("");
|
|
336
|
-
const tail = withoutControlCharacters.split(/\r\n|\r|\n|\u2028|\u2029/).map((line) => line.trim()).filter((line) => line.length > 0).slice(-5).join("; ");
|
|
337
|
-
const codePoints = Array.from(tail);
|
|
338
|
-
return codePoints.length > 600 ? `\u2026${codePoints.slice(-599).join("")}` : tail;
|
|
339
|
-
}
|
|
340
491
|
function createAPICallError({
|
|
341
492
|
message,
|
|
342
493
|
code,
|
|
@@ -351,37 +502,26 @@ function createAPICallError({
|
|
|
351
502
|
stderr,
|
|
352
503
|
promptExcerpt
|
|
353
504
|
};
|
|
354
|
-
const tail = typeof stderr === "string" && stderr.length > 0 ? stderrTail(stderr) : "";
|
|
355
|
-
const enrichedMessage = tail && !message.includes(STDERR_TAIL_MARKER) ? `${message}${STDERR_TAIL_MARKER} ${tail}` : message;
|
|
356
505
|
return new APICallError({
|
|
357
|
-
message
|
|
506
|
+
message,
|
|
358
507
|
isRetryable,
|
|
359
508
|
url: "claude-code-cli://command",
|
|
360
509
|
requestBodyValues: promptExcerpt ? { prompt: promptExcerpt } : void 0,
|
|
361
510
|
data: metadata
|
|
362
511
|
});
|
|
363
512
|
}
|
|
364
|
-
function createAuthenticationError({
|
|
365
|
-
|
|
366
|
-
stderr
|
|
367
|
-
}) {
|
|
368
|
-
const error = new LoadAPIKeyError({
|
|
513
|
+
function createAuthenticationError({ message }) {
|
|
514
|
+
return new LoadAPIKeyError({
|
|
369
515
|
message: message || "Authentication failed. Please ensure Claude Code SDK is properly authenticated."
|
|
370
516
|
});
|
|
371
|
-
if (stderr) {
|
|
372
|
-
error.data = { stderr };
|
|
373
|
-
}
|
|
374
|
-
return error;
|
|
375
517
|
}
|
|
376
518
|
function createTimeoutError({
|
|
377
519
|
message,
|
|
378
|
-
stderr,
|
|
379
520
|
promptExcerpt,
|
|
380
521
|
timeoutMs
|
|
381
522
|
}) {
|
|
382
523
|
const metadata = {
|
|
383
524
|
code: "TIMEOUT",
|
|
384
|
-
stderr,
|
|
385
525
|
promptExcerpt
|
|
386
526
|
};
|
|
387
527
|
return new APICallError({
|
|
@@ -407,9 +547,6 @@ function getErrorMetadata(error) {
|
|
|
407
547
|
if (error instanceof APICallError && error.data) {
|
|
408
548
|
return error.data;
|
|
409
549
|
}
|
|
410
|
-
if (error instanceof LoadAPIKeyError && error.data) {
|
|
411
|
-
return error.data;
|
|
412
|
-
}
|
|
413
550
|
return void 0;
|
|
414
551
|
}
|
|
415
552
|
|
|
@@ -561,6 +698,18 @@ var claudeCodeSettingsSchema = z.object({
|
|
|
561
698
|
forwardSubagentText: z.boolean().optional(),
|
|
562
699
|
agentProgressSummaries: z.boolean().optional(),
|
|
563
700
|
includeHookEvents: z.boolean().optional(),
|
|
701
|
+
onSdkMessage: z.any().refine((v) => v === void 0 || typeof v === "function", {
|
|
702
|
+
message: "onSdkMessage must be a function"
|
|
703
|
+
}).optional(),
|
|
704
|
+
onTaskEvent: z.any().refine((v) => v === void 0 || typeof v === "function", {
|
|
705
|
+
message: "onTaskEvent must be a function"
|
|
706
|
+
}).optional(),
|
|
707
|
+
onHookEvent: z.any().refine((v) => v === void 0 || typeof v === "function", {
|
|
708
|
+
message: "onHookEvent must be a function"
|
|
709
|
+
}).optional(),
|
|
710
|
+
onMcpStatusChange: z.any().refine((v) => v === void 0 || typeof v === "function", {
|
|
711
|
+
message: "onMcpStatusChange must be a function"
|
|
712
|
+
}).optional(),
|
|
564
713
|
taskBudget: z.object({ total: z.number().positive() }).strict().optional(),
|
|
565
714
|
sessionStore: z.any().refine(
|
|
566
715
|
(val) => val === void 0 || typeof val === "object" && val !== null && typeof val.append === "function" && typeof val.load === "function",
|
|
@@ -577,6 +726,9 @@ var claudeCodeSettingsSchema = z.object({
|
|
|
577
726
|
onUserDialog: z.any().refine((v) => v === void 0 || typeof v === "function", {
|
|
578
727
|
message: "onUserDialog must be a function"
|
|
579
728
|
}).optional(),
|
|
729
|
+
onElicitation: z.any().refine((v) => v === void 0 || typeof v === "function", {
|
|
730
|
+
message: "onElicitation must be a function"
|
|
731
|
+
}).optional(),
|
|
580
732
|
supportedDialogKinds: z.array(z.string()).optional(),
|
|
581
733
|
hooks: z.record(
|
|
582
734
|
z.string(),
|
|
@@ -623,6 +775,7 @@ var claudeCodeSettingsSchema = z.object({
|
|
|
623
775
|
logger: z.union([z.literal(false), loggerFunctionSchema]).optional(),
|
|
624
776
|
env: z.record(z.string(), z.string().optional()).optional(),
|
|
625
777
|
additionalDirectories: z.array(z.string()).optional(),
|
|
778
|
+
agent: z.string().optional(),
|
|
626
779
|
agents: z.record(
|
|
627
780
|
z.string(),
|
|
628
781
|
z.object({
|
|
@@ -660,10 +813,13 @@ var claudeCodeSettingsSchema = z.object({
|
|
|
660
813
|
onQueryCreated: z.any().refine((val) => val === void 0 || typeof val === "function", {
|
|
661
814
|
message: "onQueryCreated must be a function"
|
|
662
815
|
}).optional(),
|
|
816
|
+
onQueryControllerCreated: z.any().refine((val) => val === void 0 || typeof val === "function", {
|
|
817
|
+
message: "onQueryControllerCreated must be a function"
|
|
818
|
+
}).optional(),
|
|
663
819
|
onStreamStart: z.any().refine((val) => val === void 0 || typeof val === "function", {
|
|
664
820
|
message: "onStreamStart must be a function"
|
|
665
821
|
}).optional(),
|
|
666
|
-
// Callback invoked with the predicted next user prompt (
|
|
822
|
+
// Callback invoked with the predicted next user prompt (requires promptSuggestions: true)
|
|
667
823
|
onPromptSuggestion: z.any().refine((val) => val === void 0 || typeof val === "function", {
|
|
668
824
|
message: "onPromptSuggestion must be a function"
|
|
669
825
|
}).optional()
|
|
@@ -748,6 +904,11 @@ function validateSettings(settings) {
|
|
|
748
904
|
`Very high maxThinkingTokens (${validSettings.maxThinkingTokens}) may increase response time`
|
|
749
905
|
);
|
|
750
906
|
}
|
|
907
|
+
if (validSettings.onPromptSuggestion !== void 0 && effective("promptSuggestions") !== true) {
|
|
908
|
+
warnings.push(
|
|
909
|
+
"onPromptSuggestion is registered but promptSuggestions is not enabled. The CLI only emits prompt_suggestion messages when promptSuggestions is true, so the callback will never fire. Set promptSuggestions: true."
|
|
910
|
+
);
|
|
911
|
+
}
|
|
751
912
|
if (validSettings.allowedTools && validSettings.disallowedTools) {
|
|
752
913
|
warnings.push(
|
|
753
914
|
"Both allowedTools and disallowedTools are specified. Only allowedTools will be used."
|
|
@@ -985,18 +1146,41 @@ function createVerboseLogger(logger, verbose = false) {
|
|
|
985
1146
|
};
|
|
986
1147
|
}
|
|
987
1148
|
|
|
1149
|
+
// src/query-controller.ts
|
|
1150
|
+
function createClaudeCodeQueryController(query2) {
|
|
1151
|
+
const controller = {
|
|
1152
|
+
rawQuery: query2,
|
|
1153
|
+
// SDK 0.3.205 returns the control-protocol response; the public contract stays Promise<void>.
|
|
1154
|
+
interrupt: async () => {
|
|
1155
|
+
await query2.interrupt();
|
|
1156
|
+
},
|
|
1157
|
+
setPermissionMode: (mode) => query2.setPermissionMode(mode),
|
|
1158
|
+
setMcpPermissionModeOverride: (serverName, mode) => query2.setMcpPermissionModeOverride(serverName, mode),
|
|
1159
|
+
setModel: (model) => query2.setModel(model),
|
|
1160
|
+
setMaxThinkingTokens: (maxThinkingTokens, thinkingDisplay) => query2.setMaxThinkingTokens(maxThinkingTokens, thinkingDisplay),
|
|
1161
|
+
applyFlagSettings: (settings) => query2.applyFlagSettings(settings),
|
|
1162
|
+
mcpServerStatus: () => query2.mcpServerStatus(),
|
|
1163
|
+
reconnectMcpServer: (serverName) => query2.reconnectMcpServer(serverName),
|
|
1164
|
+
toggleMcpServer: (serverName, enabled) => query2.toggleMcpServer(serverName, enabled),
|
|
1165
|
+
setMcpServers: (servers) => query2.setMcpServers(servers),
|
|
1166
|
+
getContextUsage: () => query2.getContextUsage(),
|
|
1167
|
+
rewindFiles: (userMessageId, options) => query2.rewindFiles(userMessageId, options),
|
|
1168
|
+
stopTask: (taskId) => query2.stopTask(taskId),
|
|
1169
|
+
backgroundTasks: (toolUseId) => toolUseId === void 0 ? query2.backgroundTasks() : query2.backgroundTasks(toolUseId)
|
|
1170
|
+
};
|
|
1171
|
+
const streamInput = query2.streamInput;
|
|
1172
|
+
if (typeof streamInput === "function") {
|
|
1173
|
+
controller.streamInput = (stream) => streamInput.call(query2, stream);
|
|
1174
|
+
}
|
|
1175
|
+
return controller;
|
|
1176
|
+
}
|
|
1177
|
+
|
|
988
1178
|
// src/claude-code-language-model.ts
|
|
989
1179
|
import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
990
|
-
var PROVIDER_VERSION = "
|
|
1180
|
+
var PROVIDER_VERSION = "4.0.0";
|
|
991
1181
|
var DEFAULT_CLIENT_APP = `ai-sdk-provider-claude-code/${PROVIDER_VERSION}`;
|
|
992
1182
|
var CLAUDE_CODE_TRUNCATION_WARNING = "Claude Code SDK output ended unexpectedly; returning truncated response from buffered text. Await upstream fix to avoid data loss.";
|
|
993
1183
|
var MIN_TRUNCATION_LENGTH = 512;
|
|
994
|
-
function capStderr(raw) {
|
|
995
|
-
if (raw.length <= 4e3) {
|
|
996
|
-
return raw;
|
|
997
|
-
}
|
|
998
|
-
return Array.from(raw).slice(-4e3).join("");
|
|
999
|
-
}
|
|
1000
1184
|
function isClaudeCodeTruncationError(error, bufferedText) {
|
|
1001
1185
|
const isSyntaxError = error instanceof SyntaxError || // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
1002
1186
|
typeof error?.name === "string" && // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -1027,6 +1211,13 @@ function isClaudeCodeTruncationError(error, bufferedText) {
|
|
|
1027
1211
|
return true;
|
|
1028
1212
|
}
|
|
1029
1213
|
var MISSING_STRUCTURED_OUTPUT_ERROR_MESSAGE = "Structured output was requested (responseFormat with a JSON schema) but the Claude Code CLI returned no structured_output, and the prose response could not be parsed as JSON. This usually means the schema contains constructs the CLI cannot enforce (e.g. complex regex patterns with lookaheads/backreferences), causing it to silently fall back to prose. Simplify the generation schema and validate strictly client-side. See the 'Structured Outputs' section of the ai-sdk-provider-claude-code README for the list of known limitations.";
|
|
1214
|
+
var INTERNAL_STRUCTURED_OUTPUT_TOOL_NAME = "StructuredOutput";
|
|
1215
|
+
function isInternalStructuredOutputTool(toolName, options) {
|
|
1216
|
+
return options.responseFormat?.type === "json" && toolName === INTERNAL_STRUCTURED_OUTPUT_TOOL_NAME;
|
|
1217
|
+
}
|
|
1218
|
+
function isNonTextToolUseContentBlockType(type) {
|
|
1219
|
+
return type === "server_tool_use" || type === "mcp_tool_use";
|
|
1220
|
+
}
|
|
1030
1221
|
function extractJsonObjectText(text) {
|
|
1031
1222
|
const trimmed = text.trim();
|
|
1032
1223
|
if (!trimmed) {
|
|
@@ -1120,7 +1311,7 @@ function getBaseProcessEnv() {
|
|
|
1120
1311
|
}
|
|
1121
1312
|
return env;
|
|
1122
1313
|
}
|
|
1123
|
-
var STREAMING_FEATURE_WARNING = "Claude Agent SDK
|
|
1314
|
+
var STREAMING_FEATURE_WARNING = "Claude Agent SDK image input requires streaming input. Set `streamingInput: 'auto'` or `streamingInput: 'always'`; `streamingInput: 'off'` disables streaming image input.";
|
|
1124
1315
|
var SDK_OPTIONS_BLOCKLIST = /* @__PURE__ */ new Set(["model", "abortController", "prompt", "outputFormat"]);
|
|
1125
1316
|
var SUBAGENT_TOOL_NAMES = /* @__PURE__ */ new Set(["Task", "Agent"]);
|
|
1126
1317
|
function isSubagentToolName(name) {
|
|
@@ -1143,7 +1334,7 @@ function computeRetractedToolCallIds(retracted, descriptors) {
|
|
|
1143
1334
|
function applySupersede(message, evict, logger, guard = "array") {
|
|
1144
1335
|
const supersedes = message.supersedes;
|
|
1145
1336
|
const triggered = guard === "truthy" ? Boolean(supersedes && supersedes.length > 0) : Array.isArray(supersedes) && supersedes.length > 0;
|
|
1146
|
-
if (!triggered) {
|
|
1337
|
+
if (!triggered || supersedes === void 0) {
|
|
1147
1338
|
return false;
|
|
1148
1339
|
}
|
|
1149
1340
|
logger.debug(`[claude-code] Assistant message supersedes ${supersedes.length} prior message(s)`);
|
|
@@ -1156,12 +1347,126 @@ function buildRetractionEvictor(evict) {
|
|
|
1156
1347
|
var INFORMATIONAL_SYSTEM_SUBTYPES = /* @__PURE__ */ new Set([
|
|
1157
1348
|
"notification",
|
|
1158
1349
|
"status",
|
|
1159
|
-
"task_updated",
|
|
1160
1350
|
"session_state_changed",
|
|
1161
1351
|
"commands_changed",
|
|
1162
1352
|
"memory_recall",
|
|
1163
|
-
"plugin_install"
|
|
1353
|
+
"plugin_install",
|
|
1354
|
+
"informational"
|
|
1164
1355
|
]);
|
|
1356
|
+
var CLAUDE_REASONING_EFFORT_MAP = {
|
|
1357
|
+
minimal: "low",
|
|
1358
|
+
low: "low",
|
|
1359
|
+
medium: "medium",
|
|
1360
|
+
high: "high",
|
|
1361
|
+
xhigh: "xhigh"
|
|
1362
|
+
};
|
|
1363
|
+
var CLAUDE_EFFORT_LEVELS = /* @__PURE__ */ new Set(["low", "medium", "high", "xhigh", "max"]);
|
|
1364
|
+
function isObjectRecord(value) {
|
|
1365
|
+
return typeof value === "object" && value !== null;
|
|
1366
|
+
}
|
|
1367
|
+
function toJsonSafeValue(value) {
|
|
1368
|
+
if (value === void 0) {
|
|
1369
|
+
return void 0;
|
|
1370
|
+
}
|
|
1371
|
+
try {
|
|
1372
|
+
const serialized = JSON.stringify(value);
|
|
1373
|
+
return serialized === void 0 ? void 0 : JSON.parse(serialized);
|
|
1374
|
+
} catch {
|
|
1375
|
+
return String(value);
|
|
1376
|
+
}
|
|
1377
|
+
}
|
|
1378
|
+
function deepFreezeJsonValue(value) {
|
|
1379
|
+
if (Array.isArray(value)) {
|
|
1380
|
+
for (const nested of value) {
|
|
1381
|
+
deepFreezeJsonValue(nested);
|
|
1382
|
+
}
|
|
1383
|
+
return Object.freeze(value);
|
|
1384
|
+
}
|
|
1385
|
+
if (!isObjectRecord(value)) {
|
|
1386
|
+
return value;
|
|
1387
|
+
}
|
|
1388
|
+
const objectValue = value;
|
|
1389
|
+
for (const nested of Object.values(objectValue)) {
|
|
1390
|
+
if (nested !== void 0) {
|
|
1391
|
+
deepFreezeJsonValue(nested);
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1394
|
+
return Object.freeze(objectValue);
|
|
1395
|
+
}
|
|
1396
|
+
function toJsonSafeClone(value) {
|
|
1397
|
+
const clone = toJsonSafeValue(value);
|
|
1398
|
+
if (clone === void 0) {
|
|
1399
|
+
return void 0;
|
|
1400
|
+
}
|
|
1401
|
+
return clone;
|
|
1402
|
+
}
|
|
1403
|
+
function toImmutableJsonSafeClone(value) {
|
|
1404
|
+
const clone = toJsonSafeValue(value);
|
|
1405
|
+
if (clone === void 0) {
|
|
1406
|
+
return void 0;
|
|
1407
|
+
}
|
|
1408
|
+
return deepFreezeJsonValue(clone);
|
|
1409
|
+
}
|
|
1410
|
+
function hasValidThinkingDisplay(value) {
|
|
1411
|
+
return value === void 0 || value === "summarized" || value === "omitted";
|
|
1412
|
+
}
|
|
1413
|
+
function isClaudeEffortLevel(value) {
|
|
1414
|
+
return typeof value === "string" && CLAUDE_EFFORT_LEVELS.has(value);
|
|
1415
|
+
}
|
|
1416
|
+
function isClaudeThinkingConfig(value) {
|
|
1417
|
+
if (!isObjectRecord(value)) {
|
|
1418
|
+
return false;
|
|
1419
|
+
}
|
|
1420
|
+
if (value.type === "disabled") {
|
|
1421
|
+
return true;
|
|
1422
|
+
}
|
|
1423
|
+
if (value.type === "adaptive") {
|
|
1424
|
+
return hasValidThinkingDisplay(value.display);
|
|
1425
|
+
}
|
|
1426
|
+
if (value.type === "enabled") {
|
|
1427
|
+
const budgetTokens = value.budgetTokens;
|
|
1428
|
+
return (budgetTokens === void 0 || typeof budgetTokens === "number") && hasValidThinkingDisplay(value.display);
|
|
1429
|
+
}
|
|
1430
|
+
return false;
|
|
1431
|
+
}
|
|
1432
|
+
function addInvalidClaudeReasoningProviderOptionWarning(warnings, key) {
|
|
1433
|
+
warnings?.push({
|
|
1434
|
+
type: "other",
|
|
1435
|
+
message: `Invalid providerOptions['claude-code'].${key} value was ignored.`
|
|
1436
|
+
});
|
|
1437
|
+
}
|
|
1438
|
+
function extractClaudeReasoningProviderOptions(providerOptions, warnings) {
|
|
1439
|
+
const options = providerOptions?.["claude-code"];
|
|
1440
|
+
if (options === void 0) {
|
|
1441
|
+
return { hasClaudeReasoningSettings: false };
|
|
1442
|
+
}
|
|
1443
|
+
const result = { hasClaudeReasoningSettings: false };
|
|
1444
|
+
if (options.thinking !== void 0) {
|
|
1445
|
+
if (isClaudeThinkingConfig(options.thinking)) {
|
|
1446
|
+
result.thinking = options.thinking;
|
|
1447
|
+
result.hasClaudeReasoningSettings = true;
|
|
1448
|
+
} else {
|
|
1449
|
+
addInvalidClaudeReasoningProviderOptionWarning(warnings, "thinking");
|
|
1450
|
+
}
|
|
1451
|
+
}
|
|
1452
|
+
if (options.effort !== void 0) {
|
|
1453
|
+
if (isClaudeEffortLevel(options.effort)) {
|
|
1454
|
+
result.effort = options.effort;
|
|
1455
|
+
result.hasClaudeReasoningSettings = true;
|
|
1456
|
+
} else {
|
|
1457
|
+
addInvalidClaudeReasoningProviderOptionWarning(warnings, "effort");
|
|
1458
|
+
}
|
|
1459
|
+
}
|
|
1460
|
+
if (options.maxThinkingTokens !== void 0) {
|
|
1461
|
+
if (typeof options.maxThinkingTokens === "number") {
|
|
1462
|
+
result.maxThinkingTokens = options.maxThinkingTokens;
|
|
1463
|
+
result.hasClaudeReasoningSettings = true;
|
|
1464
|
+
} else {
|
|
1465
|
+
addInvalidClaudeReasoningProviderOptionWarning(warnings, "maxThinkingTokens");
|
|
1466
|
+
}
|
|
1467
|
+
}
|
|
1468
|
+
return result;
|
|
1469
|
+
}
|
|
1165
1470
|
function isContentBlock(item) {
|
|
1166
1471
|
return typeof item === "object" && item !== null && "type" in item;
|
|
1167
1472
|
}
|
|
@@ -1322,6 +1627,7 @@ function toAsyncIterablePrompt(messagesPrompt, outputStreamEnded, sessionId, con
|
|
|
1322
1627
|
};
|
|
1323
1628
|
}
|
|
1324
1629
|
var modelMap = {
|
|
1630
|
+
fable: "fable",
|
|
1325
1631
|
opus: "opus",
|
|
1326
1632
|
sonnet: "sonnet",
|
|
1327
1633
|
haiku: "haiku"
|
|
@@ -1370,7 +1676,7 @@ function truncateToolResultForStream(result, maxSize = MAX_TOOL_RESULT_SIZE) {
|
|
|
1370
1676
|
return result;
|
|
1371
1677
|
}
|
|
1372
1678
|
var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
1373
|
-
specificationVersion = "
|
|
1679
|
+
specificationVersion = "v4";
|
|
1374
1680
|
defaultObjectGenerationMode = "json";
|
|
1375
1681
|
supportsImageUrls = false;
|
|
1376
1682
|
supportedUrls = {};
|
|
@@ -1441,6 +1747,81 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1441
1747
|
}
|
|
1442
1748
|
return void 0;
|
|
1443
1749
|
}
|
|
1750
|
+
invokeObservabilityCallback(callbackName, callback, value) {
|
|
1751
|
+
if (!callback) {
|
|
1752
|
+
return;
|
|
1753
|
+
}
|
|
1754
|
+
const logError = (error) => {
|
|
1755
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1756
|
+
this.logger.warn(`[claude-code] ${callbackName} callback failed; ignoring error: ${message}`);
|
|
1757
|
+
if (error instanceof Error && error.stack) {
|
|
1758
|
+
this.logger.debug(`[claude-code] ${callbackName} callback stack: ${error.stack}`);
|
|
1759
|
+
}
|
|
1760
|
+
};
|
|
1761
|
+
try {
|
|
1762
|
+
const result = callback(value);
|
|
1763
|
+
if (result && typeof result.then === "function") {
|
|
1764
|
+
void Promise.resolve(result).catch(logError);
|
|
1765
|
+
}
|
|
1766
|
+
} catch (error) {
|
|
1767
|
+
logError(error);
|
|
1768
|
+
}
|
|
1769
|
+
}
|
|
1770
|
+
invokeSdkMessageCallback(message) {
|
|
1771
|
+
const onSdkMessage = this.settings.onSdkMessage;
|
|
1772
|
+
if (onSdkMessage === void 0) {
|
|
1773
|
+
return;
|
|
1774
|
+
}
|
|
1775
|
+
this.invokeObservabilityCallback(
|
|
1776
|
+
"onSdkMessage",
|
|
1777
|
+
onSdkMessage,
|
|
1778
|
+
toImmutableJsonSafeClone(message)
|
|
1779
|
+
);
|
|
1780
|
+
}
|
|
1781
|
+
notifyQueryCreated(response) {
|
|
1782
|
+
this.settings.onQueryCreated?.(response);
|
|
1783
|
+
const onQueryControllerCreated = this.settings.onQueryControllerCreated;
|
|
1784
|
+
if (onQueryControllerCreated !== void 0) {
|
|
1785
|
+
this.invokeObservabilityCallback(
|
|
1786
|
+
"onQueryControllerCreated",
|
|
1787
|
+
onQueryControllerCreated,
|
|
1788
|
+
createClaudeCodeQueryController(response)
|
|
1789
|
+
);
|
|
1790
|
+
}
|
|
1791
|
+
}
|
|
1792
|
+
trackTaskEvent(event, tracking) {
|
|
1793
|
+
tracking.taskEvents.push(toJsonSafeClone(event));
|
|
1794
|
+
const onTaskEvent = this.settings.onTaskEvent;
|
|
1795
|
+
if (onTaskEvent !== void 0) {
|
|
1796
|
+
this.invokeObservabilityCallback("onTaskEvent", onTaskEvent, toImmutableJsonSafeClone(event));
|
|
1797
|
+
}
|
|
1798
|
+
}
|
|
1799
|
+
trackHookEvent(event, tracking) {
|
|
1800
|
+
tracking.hookEvents.push(toJsonSafeClone(event));
|
|
1801
|
+
const onHookEvent = this.settings.onHookEvent;
|
|
1802
|
+
if (onHookEvent !== void 0) {
|
|
1803
|
+
this.invokeObservabilityCallback("onHookEvent", onHookEvent, toImmutableJsonSafeClone(event));
|
|
1804
|
+
}
|
|
1805
|
+
}
|
|
1806
|
+
trackMcpStatusFromInit(message, tracking) {
|
|
1807
|
+
const servers = message.mcp_servers;
|
|
1808
|
+
tracking.mcpServers = toJsonSafeClone(servers);
|
|
1809
|
+
const statusEvent = {
|
|
1810
|
+
subtype: "init",
|
|
1811
|
+
sessionId: message.session_id,
|
|
1812
|
+
uuid: message.uuid,
|
|
1813
|
+
servers,
|
|
1814
|
+
raw: message
|
|
1815
|
+
};
|
|
1816
|
+
const onMcpStatusChange = this.settings.onMcpStatusChange;
|
|
1817
|
+
if (onMcpStatusChange !== void 0) {
|
|
1818
|
+
this.invokeObservabilityCallback(
|
|
1819
|
+
"onMcpStatusChange",
|
|
1820
|
+
onMcpStatusChange,
|
|
1821
|
+
toImmutableJsonSafeClone(statusEvent)
|
|
1822
|
+
);
|
|
1823
|
+
}
|
|
1824
|
+
}
|
|
1444
1825
|
/**
|
|
1445
1826
|
* Single source of truth for the CLI's `--session-id` exclusivity rule.
|
|
1446
1827
|
*
|
|
@@ -1605,7 +1986,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1605
1986
|
input,
|
|
1606
1987
|
providerExecuted: true,
|
|
1607
1988
|
dynamic: true,
|
|
1608
|
-
//
|
|
1989
|
+
// V4 field: indicates tool is provider-defined (not in user's tools map)
|
|
1609
1990
|
providerMetadata: {
|
|
1610
1991
|
"claude-code": {
|
|
1611
1992
|
// rawInput preserves the original serialized format before AI SDK normalization.
|
|
@@ -1645,12 +2026,11 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1645
2026
|
toolName,
|
|
1646
2027
|
// `?? ''`: absent `content` (undefined) and string results that
|
|
1647
2028
|
// normalize to JSON null (e.g. the string "null") must not violate the
|
|
1648
|
-
// NonNullable<JSONValue> contract of
|
|
2029
|
+
// NonNullable<JSONValue> contract of LanguageModelV4ToolResult.result.
|
|
1649
2030
|
result: truncatedResult ?? "",
|
|
1650
2031
|
isError,
|
|
1651
|
-
providerExecuted: true,
|
|
1652
2032
|
dynamic: true,
|
|
1653
|
-
//
|
|
2033
|
+
// V4 field: indicates tool is provider-defined
|
|
1654
2034
|
providerMetadata: {
|
|
1655
2035
|
"claude-code": {
|
|
1656
2036
|
// rawResult preserves the original CLI output string before JSON parsing.
|
|
@@ -1673,37 +2053,12 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1673
2053
|
})() : String(error);
|
|
1674
2054
|
}
|
|
1675
2055
|
/**
|
|
1676
|
-
* Builds a provider
|
|
1677
|
-
* `tool_error` block
|
|
1678
|
-
*
|
|
2056
|
+
* Builds a V4 provider `tool-result` part with `isError: true` from a
|
|
2057
|
+
* user-message `tool_error` block. V4 has no provider-level `tool-error`
|
|
2058
|
+
* content or stream part; AI SDK core derives user-facing tool-error
|
|
2059
|
+
* semantics from this result while preserving providerMetadata.
|
|
1679
2060
|
*/
|
|
1680
|
-
|
|
1681
|
-
const rawError = this.serializeToolError(error);
|
|
1682
|
-
return {
|
|
1683
|
-
type: "tool-error",
|
|
1684
|
-
toolCallId,
|
|
1685
|
-
toolName,
|
|
1686
|
-
error: rawError,
|
|
1687
|
-
providerExecuted: true,
|
|
1688
|
-
dynamic: true,
|
|
1689
|
-
// V3 field: indicates tool is provider-defined
|
|
1690
|
-
providerMetadata: {
|
|
1691
|
-
"claude-code": {
|
|
1692
|
-
rawError,
|
|
1693
|
-
parentToolCallId: parentToolCallId ?? null
|
|
1694
|
-
}
|
|
1695
|
-
}
|
|
1696
|
-
};
|
|
1697
|
-
}
|
|
1698
|
-
/**
|
|
1699
|
-
* Builds a V3 `tool-result` CONTENT part with `isError: true` from a
|
|
1700
|
-
* user-message `tool_error` block (doGenerate only). The V3 content union
|
|
1701
|
-
* has no `tool-error` member and AI SDK core's asContent() silently drops
|
|
1702
|
-
* unknown content part types, so an extension tool-error part would never
|
|
1703
|
-
* reach `generateText` users — an isError tool-result, by contrast,
|
|
1704
|
-
* round-trips into a proper tool-error part in steps content.
|
|
1705
|
-
*/
|
|
1706
|
-
buildToolErrorResultPart(toolCallId, toolName, error, parentToolCallId) {
|
|
2061
|
+
buildErroredToolResultPart(toolCallId, toolName, error, parentToolCallId) {
|
|
1707
2062
|
const rawError = this.serializeToolError(error);
|
|
1708
2063
|
return {
|
|
1709
2064
|
type: "tool-result",
|
|
@@ -1711,9 +2066,8 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1711
2066
|
toolName,
|
|
1712
2067
|
result: rawError,
|
|
1713
2068
|
isError: true,
|
|
1714
|
-
providerExecuted: true,
|
|
1715
2069
|
dynamic: true,
|
|
1716
|
-
//
|
|
2070
|
+
// V4 field: indicates tool is provider-defined
|
|
1717
2071
|
providerMetadata: {
|
|
1718
2072
|
"claude-code": {
|
|
1719
2073
|
rawError,
|
|
@@ -1739,7 +2093,33 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1739
2093
|
);
|
|
1740
2094
|
return true;
|
|
1741
2095
|
}
|
|
1742
|
-
|
|
2096
|
+
resolvePortableReasoningOptions(options, sdkOptions, claudeProviderOptions, warnings) {
|
|
2097
|
+
const hasClaudeSpecificReasoning = this.settings.thinking !== void 0 || this.settings.effort !== void 0 || this.settings.maxThinkingTokens !== void 0 || sdkOptions?.thinking !== void 0 || sdkOptions?.effort !== void 0 || sdkOptions?.maxThinkingTokens !== void 0 || claudeProviderOptions.hasClaudeReasoningSettings;
|
|
2098
|
+
if (hasClaudeSpecificReasoning || !isCustomReasoning(options.reasoning)) {
|
|
2099
|
+
return {};
|
|
2100
|
+
}
|
|
2101
|
+
if (options.reasoning === "none") {
|
|
2102
|
+
return { thinking: { type: "disabled" } };
|
|
2103
|
+
}
|
|
2104
|
+
const effort = mapReasoningToProviderEffort({
|
|
2105
|
+
reasoning: options.reasoning,
|
|
2106
|
+
effortMap: CLAUDE_REASONING_EFFORT_MAP,
|
|
2107
|
+
warnings: warnings ?? []
|
|
2108
|
+
});
|
|
2109
|
+
return effort === void 0 ? {} : { effort };
|
|
2110
|
+
}
|
|
2111
|
+
applyClaudeReasoningProviderOptions(opts, claudeProviderOptions) {
|
|
2112
|
+
if (claudeProviderOptions.thinking !== void 0) {
|
|
2113
|
+
opts.thinking = claudeProviderOptions.thinking;
|
|
2114
|
+
}
|
|
2115
|
+
if (claudeProviderOptions.effort !== void 0) {
|
|
2116
|
+
opts.effort = claudeProviderOptions.effort;
|
|
2117
|
+
}
|
|
2118
|
+
if (claudeProviderOptions.maxThinkingTokens !== void 0) {
|
|
2119
|
+
opts.maxThinkingTokens = claudeProviderOptions.maxThinkingTokens;
|
|
2120
|
+
}
|
|
2121
|
+
}
|
|
2122
|
+
generateAllWarnings(options, prompt, sdkOptions) {
|
|
1743
2123
|
const warnings = [];
|
|
1744
2124
|
const unsupportedParams = [];
|
|
1745
2125
|
if (options.temperature !== void 0) unsupportedParams.push("temperature");
|
|
@@ -1806,9 +2186,18 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1806
2186
|
message: promptWarning
|
|
1807
2187
|
});
|
|
1808
2188
|
}
|
|
2189
|
+
this.resolvePortableReasoningOptions(
|
|
2190
|
+
options,
|
|
2191
|
+
sdkOptions,
|
|
2192
|
+
extractClaudeReasoningProviderOptions(options.providerOptions, warnings),
|
|
2193
|
+
warnings
|
|
2194
|
+
);
|
|
1809
2195
|
return warnings;
|
|
1810
2196
|
}
|
|
1811
|
-
createQueryOptions(abortController,
|
|
2197
|
+
createQueryOptions(abortController, options, stderrCollector, sdkOptions, effectiveResume) {
|
|
2198
|
+
const claudeReasoningProviderOptions = extractClaudeReasoningProviderOptions(
|
|
2199
|
+
options.providerOptions
|
|
2200
|
+
);
|
|
1812
2201
|
const opts = {
|
|
1813
2202
|
model: this.getModel(),
|
|
1814
2203
|
abortController,
|
|
@@ -1836,8 +2225,14 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1836
2225
|
sandbox: this.settings.sandbox,
|
|
1837
2226
|
tools: this.settings.tools,
|
|
1838
2227
|
mcpServers: this.settings.mcpServers,
|
|
1839
|
-
canUseTool: this.settings.canUseTool
|
|
2228
|
+
canUseTool: this.settings.canUseTool,
|
|
2229
|
+
onElicitation: this.settings.onElicitation,
|
|
2230
|
+
agent: this.settings.agent
|
|
1840
2231
|
};
|
|
2232
|
+
Object.assign(
|
|
2233
|
+
opts,
|
|
2234
|
+
this.resolvePortableReasoningOptions(options, sdkOptions, claudeReasoningProviderOptions)
|
|
2235
|
+
);
|
|
1841
2236
|
if (this.settings.onUserDialog !== void 0) {
|
|
1842
2237
|
opts.onUserDialog = this.settings.onUserDialog;
|
|
1843
2238
|
}
|
|
@@ -1966,6 +2361,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1966
2361
|
}
|
|
1967
2362
|
}
|
|
1968
2363
|
}
|
|
2364
|
+
this.applyClaudeReasoningProviderOptions(opts, claudeReasoningProviderOptions);
|
|
1969
2365
|
this.applySessionResolution(opts, effectiveResume);
|
|
1970
2366
|
if (typeof opts.fallbackModel === "string" && opts.fallbackModel === opts.model) {
|
|
1971
2367
|
throw new Error(
|
|
@@ -1988,9 +2384,9 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1988
2384
|
mergedEnv.CLAUDE_AGENT_SDK_CLIENT_APP = DEFAULT_CLIENT_APP;
|
|
1989
2385
|
}
|
|
1990
2386
|
opts.env = mergedEnv;
|
|
1991
|
-
if (responseFormat?.type === "json" && responseFormat.schema) {
|
|
2387
|
+
if (options.responseFormat?.type === "json" && options.responseFormat.schema) {
|
|
1992
2388
|
const { schema: sanitizedSchema, strippedFormatPaths } = sanitizeJsonSchemaForOutputFormat(
|
|
1993
|
-
responseFormat.schema
|
|
2389
|
+
options.responseFormat.schema
|
|
1994
2390
|
);
|
|
1995
2391
|
if (strippedFormatPaths.length > 0) {
|
|
1996
2392
|
this.logger.debug(
|
|
@@ -2005,18 +2401,12 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2005
2401
|
return opts;
|
|
2006
2402
|
}
|
|
2007
2403
|
handleClaudeCodeError(error, messagesPrompt, collectedStderr) {
|
|
2008
|
-
if (error instanceof APICallError2 || error instanceof LoadAPIKeyError2) {
|
|
2009
|
-
return error;
|
|
2010
|
-
}
|
|
2011
|
-
const rawSdkStderr = typeof error === "object" && error !== null && "stderr" in error && typeof error.stderr === "string" ? error.stderr : void 0;
|
|
2012
|
-
const cappedSdkStderr = rawSdkStderr !== void 0 ? capStderr(rawSdkStderr) : void 0;
|
|
2013
|
-
const selectedStderr = cappedSdkStderr !== void 0 && stderrTail(cappedSdkStderr) ? cappedSdkStderr : collectedStderr ? capStderr(collectedStderr) : void 0;
|
|
2014
|
-
const stderr = selectedStderr || void 0;
|
|
2015
|
-
const tail = stderr ? stderrTail(stderr) : "";
|
|
2016
|
-
const appendStderrTail = (message) => tail && !message.includes(STDERR_TAIL_MARKER) ? `${message}${STDERR_TAIL_MARKER} ${tail}` : message;
|
|
2017
2404
|
if (isAbortError(error)) {
|
|
2018
2405
|
throw error;
|
|
2019
2406
|
}
|
|
2407
|
+
if (error instanceof APICallError2 || error instanceof LoadAPIKeyError2) {
|
|
2408
|
+
return error;
|
|
2409
|
+
}
|
|
2020
2410
|
const isErrorWithMessage = (err) => {
|
|
2021
2411
|
return typeof err === "object" && err !== null && "message" in err;
|
|
2022
2412
|
};
|
|
@@ -2037,43 +2427,26 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2037
2427
|
"oauth_org_not_allowed"
|
|
2038
2428
|
// SDK 0.3.x assistant error kind: OAuth org not permitted
|
|
2039
2429
|
];
|
|
2040
|
-
const stderrAuthPatterns = [
|
|
2041
|
-
"not logged in",
|
|
2042
|
-
"not authenticated",
|
|
2043
|
-
"auth failed",
|
|
2044
|
-
"please login",
|
|
2045
|
-
"please run /login",
|
|
2046
|
-
"claude login",
|
|
2047
|
-
"claude auth login",
|
|
2048
|
-
"invalid api key",
|
|
2049
|
-
"oauth token revoked",
|
|
2050
|
-
"oauth_org_not_allowed"
|
|
2051
|
-
];
|
|
2052
2430
|
const errorMessage = isErrorWithMessage(error) && error.message ? error.message.toLowerCase() : "";
|
|
2053
|
-
const stderrMessage = stderr?.toLowerCase() ?? "";
|
|
2054
2431
|
const errorKind = getStructuredErrorKind(error);
|
|
2055
2432
|
const exitCode = isErrorWithCode(error) && typeof error.exitCode === "number" ? error.exitCode : void 0;
|
|
2056
|
-
const isAuthError = errorKind === "authentication_failed" || errorKind === "oauth_org_not_allowed" || authErrorPatterns.some((pattern) => errorMessage.includes(pattern)) ||
|
|
2433
|
+
const isAuthError = errorKind === "authentication_failed" || errorKind === "oauth_org_not_allowed" || authErrorPatterns.some((pattern) => errorMessage.includes(pattern)) || exitCode === 401;
|
|
2057
2434
|
if (isAuthError) {
|
|
2058
2435
|
return createAuthenticationError({
|
|
2059
|
-
message:
|
|
2060
|
-
isErrorWithMessage(error) && error.message ? error.message : "Authentication failed. Please ensure Claude Code SDK is properly authenticated."
|
|
2061
|
-
),
|
|
2062
|
-
stderr
|
|
2436
|
+
message: isErrorWithMessage(error) && error.message ? error.message : "Authentication failed. Please ensure Claude Code SDK is properly authenticated."
|
|
2063
2437
|
});
|
|
2064
2438
|
}
|
|
2065
2439
|
const errorCode = isErrorWithCode(error) && typeof error.code === "string" ? error.code : "";
|
|
2066
|
-
if (errorCode === "ETIMEDOUT" || errorMessage.includes("timeout")
|
|
2440
|
+
if (errorCode === "ETIMEDOUT" || errorMessage.includes("timeout")) {
|
|
2067
2441
|
return createTimeoutError({
|
|
2068
|
-
message:
|
|
2069
|
-
isErrorWithMessage(error) && error.message ? error.message : "Request timed out"
|
|
2070
|
-
),
|
|
2071
|
-
stderr,
|
|
2442
|
+
message: isErrorWithMessage(error) && error.message ? error.message : "Request timed out",
|
|
2072
2443
|
promptExcerpt: messagesPrompt.substring(0, 200)
|
|
2073
2444
|
// Don't specify timeoutMs since we don't know the actual timeout value
|
|
2074
2445
|
// It's controlled by the consumer via AbortSignal
|
|
2075
2446
|
});
|
|
2076
2447
|
}
|
|
2448
|
+
const stderrFromError = isErrorWithCode(error) && typeof error.stderr === "string" ? error.stderr : void 0;
|
|
2449
|
+
const stderr = stderrFromError || collectedStderr || void 0;
|
|
2077
2450
|
if (errorKind === "overloaded" || errorKind === "rate_limit" || errorMessage.includes("overloaded")) {
|
|
2078
2451
|
return createAPICallError({
|
|
2079
2452
|
message: isErrorWithMessage(error) && error.message ? error.message : "Anthropic API is overloaded. Please retry.",
|
|
@@ -2087,7 +2460,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2087
2460
|
if (errorKind === "model_not_found" || errorMessage.includes("model_not_found") || errorMessage.includes("no such model")) {
|
|
2088
2461
|
const originalMessage = isErrorWithMessage(error) && error.message ? error.message : "Model not found";
|
|
2089
2462
|
return createAPICallError({
|
|
2090
|
-
message: `${originalMessage}. The requested model was not found. Verify the model id passed to the provider (e.g. 'opus', 'sonnet', 'haiku', or a full model name) and that your account has access to it.`,
|
|
2463
|
+
message: `${originalMessage}. The requested model was not found. Verify the model id passed to the provider (e.g. 'fable', 'opus', 'sonnet', 'haiku', or a full model name) and that your account has access to it.`,
|
|
2091
2464
|
code: errorCode || void 0,
|
|
2092
2465
|
exitCode,
|
|
2093
2466
|
stderr,
|
|
@@ -2157,16 +2530,159 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2157
2530
|
break;
|
|
2158
2531
|
case "permission_denied": {
|
|
2159
2532
|
const reason = message.decision_reason ?? message.message;
|
|
2533
|
+
const raw = toJsonSafeValue(message);
|
|
2160
2534
|
tracking.permissionDenials.push({
|
|
2161
2535
|
toolName: message.tool_name,
|
|
2162
2536
|
toolUseId: message.tool_use_id,
|
|
2163
|
-
...
|
|
2537
|
+
...message.agent_id !== void 0 && { agentId: message.agent_id },
|
|
2538
|
+
...message.decision_reason_type !== void 0 && {
|
|
2539
|
+
decisionReasonType: message.decision_reason_type
|
|
2540
|
+
},
|
|
2541
|
+
...reason !== void 0 && { reason },
|
|
2542
|
+
...raw !== void 0 && { raw }
|
|
2164
2543
|
});
|
|
2165
2544
|
this.logger.warn(
|
|
2166
2545
|
`[claude-code] Permission denied - Tool: ${message.tool_name}${reason ? `, Reason: ${reason}` : ""}`
|
|
2167
2546
|
);
|
|
2168
2547
|
break;
|
|
2169
2548
|
}
|
|
2549
|
+
case "task_started":
|
|
2550
|
+
this.trackTaskEvent(
|
|
2551
|
+
{
|
|
2552
|
+
subtype: "task_started",
|
|
2553
|
+
taskId: message.task_id,
|
|
2554
|
+
...message.tool_use_id !== void 0 && { toolUseId: message.tool_use_id },
|
|
2555
|
+
description: message.description,
|
|
2556
|
+
...message.subagent_type !== void 0 && { subagentType: message.subagent_type },
|
|
2557
|
+
...message.task_type !== void 0 && { taskType: message.task_type },
|
|
2558
|
+
...message.workflow_name !== void 0 && { workflowName: message.workflow_name },
|
|
2559
|
+
...message.prompt !== void 0 && { prompt: message.prompt },
|
|
2560
|
+
...message.skip_transcript !== void 0 && {
|
|
2561
|
+
skipTranscript: message.skip_transcript
|
|
2562
|
+
},
|
|
2563
|
+
uuid: message.uuid,
|
|
2564
|
+
sessionId: message.session_id,
|
|
2565
|
+
raw: message
|
|
2566
|
+
},
|
|
2567
|
+
tracking
|
|
2568
|
+
);
|
|
2569
|
+
this.logger.debug(`[claude-code] Task started - ID: ${message.task_id}`);
|
|
2570
|
+
break;
|
|
2571
|
+
case "task_progress":
|
|
2572
|
+
this.trackTaskEvent(
|
|
2573
|
+
{
|
|
2574
|
+
subtype: "task_progress",
|
|
2575
|
+
taskId: message.task_id,
|
|
2576
|
+
...message.tool_use_id !== void 0 && { toolUseId: message.tool_use_id },
|
|
2577
|
+
description: message.description,
|
|
2578
|
+
...message.subagent_type !== void 0 && { subagentType: message.subagent_type },
|
|
2579
|
+
usage: message.usage,
|
|
2580
|
+
...message.last_tool_name !== void 0 && { lastToolName: message.last_tool_name },
|
|
2581
|
+
...message.summary !== void 0 && { summary: message.summary },
|
|
2582
|
+
uuid: message.uuid,
|
|
2583
|
+
sessionId: message.session_id,
|
|
2584
|
+
raw: message
|
|
2585
|
+
},
|
|
2586
|
+
tracking
|
|
2587
|
+
);
|
|
2588
|
+
this.logger.debug(`[claude-code] Task progress - ID: ${message.task_id}`);
|
|
2589
|
+
break;
|
|
2590
|
+
case "task_updated":
|
|
2591
|
+
this.trackTaskEvent(
|
|
2592
|
+
{
|
|
2593
|
+
subtype: "task_updated",
|
|
2594
|
+
taskId: message.task_id,
|
|
2595
|
+
patch: message.patch,
|
|
2596
|
+
uuid: message.uuid,
|
|
2597
|
+
sessionId: message.session_id,
|
|
2598
|
+
raw: message
|
|
2599
|
+
},
|
|
2600
|
+
tracking
|
|
2601
|
+
);
|
|
2602
|
+
this.logger.debug(`[claude-code] Task updated - ID: ${message.task_id}`);
|
|
2603
|
+
break;
|
|
2604
|
+
case "task_notification":
|
|
2605
|
+
this.trackTaskEvent(
|
|
2606
|
+
{
|
|
2607
|
+
subtype: "task_notification",
|
|
2608
|
+
taskId: message.task_id,
|
|
2609
|
+
...message.tool_use_id !== void 0 && { toolUseId: message.tool_use_id },
|
|
2610
|
+
status: message.status,
|
|
2611
|
+
outputFile: message.output_file,
|
|
2612
|
+
summary: message.summary,
|
|
2613
|
+
...message.usage !== void 0 && { usage: message.usage },
|
|
2614
|
+
...message.skip_transcript !== void 0 && {
|
|
2615
|
+
skipTranscript: message.skip_transcript
|
|
2616
|
+
},
|
|
2617
|
+
uuid: message.uuid,
|
|
2618
|
+
sessionId: message.session_id,
|
|
2619
|
+
raw: message
|
|
2620
|
+
},
|
|
2621
|
+
tracking
|
|
2622
|
+
);
|
|
2623
|
+
this.logger.debug(
|
|
2624
|
+
`[claude-code] Task notification - ID: ${message.task_id}, Status: ${message.status}`
|
|
2625
|
+
);
|
|
2626
|
+
break;
|
|
2627
|
+
case "hook_started":
|
|
2628
|
+
this.trackHookEvent(
|
|
2629
|
+
{
|
|
2630
|
+
subtype: "hook_started",
|
|
2631
|
+
hookId: message.hook_id,
|
|
2632
|
+
hookName: message.hook_name,
|
|
2633
|
+
hookEvent: message.hook_event,
|
|
2634
|
+
uuid: message.uuid,
|
|
2635
|
+
sessionId: message.session_id,
|
|
2636
|
+
raw: message
|
|
2637
|
+
},
|
|
2638
|
+
tracking
|
|
2639
|
+
);
|
|
2640
|
+
this.logger.debug(
|
|
2641
|
+
`[claude-code] Hook started - ID: ${message.hook_id}, Event: ${message.hook_event}`
|
|
2642
|
+
);
|
|
2643
|
+
break;
|
|
2644
|
+
case "hook_progress":
|
|
2645
|
+
this.trackHookEvent(
|
|
2646
|
+
{
|
|
2647
|
+
subtype: "hook_progress",
|
|
2648
|
+
hookId: message.hook_id,
|
|
2649
|
+
hookName: message.hook_name,
|
|
2650
|
+
hookEvent: message.hook_event,
|
|
2651
|
+
stdout: message.stdout,
|
|
2652
|
+
stderr: message.stderr,
|
|
2653
|
+
output: message.output,
|
|
2654
|
+
uuid: message.uuid,
|
|
2655
|
+
sessionId: message.session_id,
|
|
2656
|
+
raw: message
|
|
2657
|
+
},
|
|
2658
|
+
tracking
|
|
2659
|
+
);
|
|
2660
|
+
this.logger.debug(
|
|
2661
|
+
`[claude-code] Hook progress - ID: ${message.hook_id}, Event: ${message.hook_event}`
|
|
2662
|
+
);
|
|
2663
|
+
break;
|
|
2664
|
+
case "hook_response":
|
|
2665
|
+
this.trackHookEvent(
|
|
2666
|
+
{
|
|
2667
|
+
subtype: "hook_response",
|
|
2668
|
+
hookId: message.hook_id,
|
|
2669
|
+
hookName: message.hook_name,
|
|
2670
|
+
hookEvent: message.hook_event,
|
|
2671
|
+
output: message.output,
|
|
2672
|
+
stdout: message.stdout,
|
|
2673
|
+
stderr: message.stderr,
|
|
2674
|
+
...message.exit_code !== void 0 && { exitCode: message.exit_code },
|
|
2675
|
+
outcome: message.outcome,
|
|
2676
|
+
uuid: message.uuid,
|
|
2677
|
+
sessionId: message.session_id,
|
|
2678
|
+
raw: message
|
|
2679
|
+
},
|
|
2680
|
+
tracking
|
|
2681
|
+
);
|
|
2682
|
+
this.logger.debug(
|
|
2683
|
+
`[claude-code] Hook response - ID: ${message.hook_id}, Outcome: ${message.outcome}`
|
|
2684
|
+
);
|
|
2685
|
+
break;
|
|
2170
2686
|
case "mirror_error": {
|
|
2171
2687
|
const mirrorError = message.error ?? "unknown error";
|
|
2172
2688
|
const mirrorSessionId = message.key?.sessionId ?? message.session_id ?? "unknown";
|
|
@@ -2219,12 +2735,21 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2219
2735
|
const alreadyTracked = tracking.permissionDenials.some(
|
|
2220
2736
|
(d) => d.toolUseId !== void 0 && d.toolUseId === denial.tool_use_id
|
|
2221
2737
|
);
|
|
2222
|
-
if (
|
|
2223
|
-
|
|
2224
|
-
toolName: denial.tool_name,
|
|
2225
|
-
toolUseId: denial.tool_use_id
|
|
2226
|
-
});
|
|
2738
|
+
if (alreadyTracked) {
|
|
2739
|
+
continue;
|
|
2227
2740
|
}
|
|
2741
|
+
const agentId = typeof denial.agent_id === "string" ? denial.agent_id : typeof denial.agentId === "string" ? denial.agentId : void 0;
|
|
2742
|
+
const decisionReasonType = typeof denial.decision_reason_type === "string" ? denial.decision_reason_type : typeof denial.decisionReasonType === "string" ? denial.decisionReasonType : void 0;
|
|
2743
|
+
const reason = typeof denial.decision_reason === "string" ? denial.decision_reason : typeof denial.reason === "string" ? denial.reason : typeof denial.message === "string" ? denial.message : void 0;
|
|
2744
|
+
const raw = toJsonSafeValue(denial);
|
|
2745
|
+
tracking.permissionDenials.push({
|
|
2746
|
+
toolName: denial.tool_name,
|
|
2747
|
+
toolUseId: denial.tool_use_id,
|
|
2748
|
+
...agentId !== void 0 && { agentId },
|
|
2749
|
+
...decisionReasonType !== void 0 && { decisionReasonType },
|
|
2750
|
+
...reason !== void 0 && { reason },
|
|
2751
|
+
...raw !== void 0 && { raw }
|
|
2752
|
+
});
|
|
2228
2753
|
}
|
|
2229
2754
|
}
|
|
2230
2755
|
/**
|
|
@@ -2233,11 +2758,10 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2233
2758
|
* suggestion arrives AFTER the result message; the SDK emits at most one
|
|
2234
2759
|
* per turn, so stop once it is delivered, and a timeout closes the
|
|
2235
2760
|
* iterator (tearing down the subprocess) if the CLI lingers after the
|
|
2236
|
-
* result without emitting one.
|
|
2237
|
-
*
|
|
2761
|
+
* result without emitting one. Drained messages still pass through the
|
|
2762
|
+
* generic raw SDK callback before prompt-specific handling.
|
|
2238
2763
|
*/
|
|
2239
|
-
async drainPromptSuggestion(
|
|
2240
|
-
const iterator = response[Symbol.asyncIterator]();
|
|
2764
|
+
async drainPromptSuggestion(iterator, onPromptSuggestion) {
|
|
2241
2765
|
let drainTimer;
|
|
2242
2766
|
const drainTimeout = new Promise((resolve) => {
|
|
2243
2767
|
drainTimer = setTimeout(
|
|
@@ -2260,8 +2784,9 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2260
2784
|
}
|
|
2261
2785
|
const trailingMessage = winner.value;
|
|
2262
2786
|
this.logger.debug(`[claude-code] Post-result message type: ${trailingMessage.type}`);
|
|
2787
|
+
this.invokeSdkMessageCallback(trailingMessage);
|
|
2263
2788
|
if (trailingMessage.type === "prompt_suggestion") {
|
|
2264
|
-
onPromptSuggestion(trailingMessage.suggestion);
|
|
2789
|
+
onPromptSuggestion?.(trailingMessage.suggestion);
|
|
2265
2790
|
void iterator.return?.().catch(() => {
|
|
2266
2791
|
});
|
|
2267
2792
|
break;
|
|
@@ -2297,13 +2822,12 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2297
2822
|
let collectedStderr = "";
|
|
2298
2823
|
const stderrCollector = (data) => {
|
|
2299
2824
|
collectedStderr += data;
|
|
2300
|
-
collectedStderr = capStderr(collectedStderr);
|
|
2301
2825
|
};
|
|
2302
2826
|
const sdkOptions = this.getSanitizedSdkOptions();
|
|
2303
2827
|
const effectiveResume = this.getEffectiveResume(sdkOptions);
|
|
2304
2828
|
const queryOptions = this.createQueryOptions(
|
|
2305
2829
|
abortController,
|
|
2306
|
-
options
|
|
2830
|
+
options,
|
|
2307
2831
|
stderrCollector,
|
|
2308
2832
|
sdkOptions,
|
|
2309
2833
|
effectiveResume
|
|
@@ -2377,9 +2901,15 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2377
2901
|
apiRetries: 0,
|
|
2378
2902
|
permissionDenials: [],
|
|
2379
2903
|
mirrorErrors: [],
|
|
2380
|
-
estimatedThinkingTokens: 0
|
|
2904
|
+
estimatedThinkingTokens: 0,
|
|
2905
|
+
taskEvents: [],
|
|
2906
|
+
hookEvents: []
|
|
2381
2907
|
};
|
|
2382
|
-
const warnings = this.generateAllWarnings(
|
|
2908
|
+
const warnings = this.generateAllWarnings(
|
|
2909
|
+
options,
|
|
2910
|
+
messagesPrompt,
|
|
2911
|
+
sdkOptions
|
|
2912
|
+
);
|
|
2383
2913
|
if (messageWarnings) {
|
|
2384
2914
|
messageWarnings.forEach((warning) => {
|
|
2385
2915
|
warnings.push({
|
|
@@ -2391,7 +2921,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2391
2921
|
const modeSetting = this.settings.streamingInput ?? "auto";
|
|
2392
2922
|
const effectiveCanUseTool = sdkOptions?.canUseTool ?? this.settings.canUseTool;
|
|
2393
2923
|
const effectivePermissionPromptToolName = sdkOptions?.permissionPromptToolName ?? this.settings.permissionPromptToolName;
|
|
2394
|
-
const wantsStreamInput = modeSetting === "always" || modeSetting === "auto" && !!effectiveCanUseTool;
|
|
2924
|
+
const wantsStreamInput = modeSetting === "always" || modeSetting === "auto" && (!!effectiveCanUseTool || hasImageParts);
|
|
2395
2925
|
if (!wantsStreamInput && hasImageParts) {
|
|
2396
2926
|
warnings.push({
|
|
2397
2927
|
type: "other",
|
|
@@ -2423,7 +2953,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2423
2953
|
prompt: sdkPrompt,
|
|
2424
2954
|
options: queryOptions
|
|
2425
2955
|
});
|
|
2426
|
-
this.
|
|
2956
|
+
this.notifyQueryCreated(response);
|
|
2427
2957
|
let lastAssistantErrorKind;
|
|
2428
2958
|
const sdkIterator = response[Symbol.asyncIterator]();
|
|
2429
2959
|
const detachableResponse = {
|
|
@@ -2438,6 +2968,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2438
2968
|
};
|
|
2439
2969
|
for await (const message of detachableResponse) {
|
|
2440
2970
|
this.logger.debug(`[claude-code] Received message type: ${message.type}`);
|
|
2971
|
+
this.invokeSdkMessageCallback(message);
|
|
2441
2972
|
if (message.type === "assistant") {
|
|
2442
2973
|
if (typeof message.error === "string") {
|
|
2443
2974
|
lastAssistantErrorKind = message.error;
|
|
@@ -2466,6 +2997,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2466
2997
|
} else if (block.type === "tool_use") {
|
|
2467
2998
|
const [tool3] = this.extractToolUses([block]);
|
|
2468
2999
|
if (!tool3) continue;
|
|
3000
|
+
if (isInternalStructuredOutputTool(tool3.name, options)) continue;
|
|
2469
3001
|
const parentToolCallId = isSubagentToolName(tool3.name) ? null : resolveToolParentId(
|
|
2470
3002
|
sdkParentToolUseId,
|
|
2471
3003
|
tool3.parentToolUseId,
|
|
@@ -2576,7 +3108,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2576
3108
|
kind: "tool-error",
|
|
2577
3109
|
...resultMessageUuid !== void 0 && { uuid: resultMessageUuid },
|
|
2578
3110
|
toolCallId: error.id,
|
|
2579
|
-
part: this.
|
|
3111
|
+
part: this.buildErroredToolResultPart(
|
|
2580
3112
|
error.id,
|
|
2581
3113
|
toolName,
|
|
2582
3114
|
error.error,
|
|
@@ -2634,14 +3166,19 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2634
3166
|
}
|
|
2635
3167
|
const stopReason = "stop_reason" in message ? message.stop_reason : void 0;
|
|
2636
3168
|
finishReason = mapClaudeCodeFinishReason(message.subtype, stopReason);
|
|
3169
|
+
if (structuredOutput !== void 0 && finishReason.unified === "tool-calls") {
|
|
3170
|
+
finishReason = { unified: "stop", raw: finishReason.raw };
|
|
3171
|
+
}
|
|
2637
3172
|
this.logger.debug(`[claude-code] Finish reason: ${finishReason.unified}`);
|
|
2638
3173
|
const effectivePromptSuggestions = sdkOptions?.promptSuggestions ?? this.settings.promptSuggestions;
|
|
2639
|
-
|
|
2640
|
-
|
|
3174
|
+
const shouldDrainPromptSuggestion = effectivePromptSuggestions !== false && (this.settings.onPromptSuggestion !== void 0 || this.settings.onSdkMessage !== void 0);
|
|
3175
|
+
if (shouldDrainPromptSuggestion) {
|
|
3176
|
+
await this.drainPromptSuggestion(sdkIterator, this.settings.onPromptSuggestion);
|
|
2641
3177
|
}
|
|
2642
3178
|
break;
|
|
2643
3179
|
} else if (message.type === "system" && message.subtype === "init") {
|
|
2644
3180
|
this.logMcpConnectionIssues(message.mcp_servers);
|
|
3181
|
+
this.trackMcpStatusFromInit(message, metadataTracking);
|
|
2645
3182
|
this.setSessionId(message.session_id);
|
|
2646
3183
|
this.logger.info(`[claude-code] Session initialized: ${message.session_id}`);
|
|
2647
3184
|
} else if (message.type === "system") {
|
|
@@ -2744,6 +3281,15 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2744
3281
|
...metadataTracking.permissionDenials.length > 0 && {
|
|
2745
3282
|
permissionDenials: metadataTracking.permissionDenials
|
|
2746
3283
|
},
|
|
3284
|
+
...metadataTracking.taskEvents.length > 0 && {
|
|
3285
|
+
taskEvents: metadataTracking.taskEvents
|
|
3286
|
+
},
|
|
3287
|
+
...metadataTracking.hookEvents.length > 0 && {
|
|
3288
|
+
hookEvents: metadataTracking.hookEvents
|
|
3289
|
+
},
|
|
3290
|
+
...metadataTracking.mcpServers !== void 0 && {
|
|
3291
|
+
mcpServers: metadataTracking.mcpServers
|
|
3292
|
+
},
|
|
2747
3293
|
...metadataTracking.mirrorErrors.length > 0 && {
|
|
2748
3294
|
mirrorErrors: metadataTracking.mirrorErrors
|
|
2749
3295
|
},
|
|
@@ -2776,13 +3322,12 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2776
3322
|
let collectedStderr = "";
|
|
2777
3323
|
const stderrCollector = (data) => {
|
|
2778
3324
|
collectedStderr += data;
|
|
2779
|
-
collectedStderr = capStderr(collectedStderr);
|
|
2780
3325
|
};
|
|
2781
3326
|
const sdkOptions = this.getSanitizedSdkOptions();
|
|
2782
3327
|
const effectiveResume = this.getEffectiveResume(sdkOptions);
|
|
2783
3328
|
const queryOptions = this.createQueryOptions(
|
|
2784
3329
|
abortController,
|
|
2785
|
-
options
|
|
3330
|
+
options,
|
|
2786
3331
|
stderrCollector,
|
|
2787
3332
|
sdkOptions,
|
|
2788
3333
|
effectiveResume
|
|
@@ -2794,7 +3339,11 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2794
3339
|
if (queryOptions.includePartialMessages === void 0) {
|
|
2795
3340
|
queryOptions.includePartialMessages = true;
|
|
2796
3341
|
}
|
|
2797
|
-
const warnings = this.generateAllWarnings(
|
|
3342
|
+
const warnings = this.generateAllWarnings(
|
|
3343
|
+
options,
|
|
3344
|
+
messagesPrompt,
|
|
3345
|
+
sdkOptions
|
|
3346
|
+
);
|
|
2798
3347
|
if (messageWarnings) {
|
|
2799
3348
|
messageWarnings.forEach((warning) => {
|
|
2800
3349
|
warnings.push({
|
|
@@ -2806,7 +3355,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2806
3355
|
const modeSetting = this.settings.streamingInput ?? "auto";
|
|
2807
3356
|
const effectiveCanUseTool = sdkOptions?.canUseTool ?? this.settings.canUseTool;
|
|
2808
3357
|
const effectivePermissionPromptToolName = sdkOptions?.permissionPromptToolName ?? this.settings.permissionPromptToolName;
|
|
2809
|
-
const wantsStreamInput = modeSetting === "always" || modeSetting === "auto" && !!effectiveCanUseTool;
|
|
3358
|
+
const wantsStreamInput = modeSetting === "always" || modeSetting === "auto" && (!!effectiveCanUseTool || hasImageParts);
|
|
2810
3359
|
if (!wantsStreamInput && hasImageParts) {
|
|
2811
3360
|
warnings.push({
|
|
2812
3361
|
type: "other",
|
|
@@ -2873,9 +3422,13 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2873
3422
|
apiRetries: 0,
|
|
2874
3423
|
permissionDenials: [],
|
|
2875
3424
|
mirrorErrors: [],
|
|
2876
|
-
estimatedThinkingTokens: 0
|
|
3425
|
+
estimatedThinkingTokens: 0,
|
|
3426
|
+
taskEvents: [],
|
|
3427
|
+
hookEvents: []
|
|
2877
3428
|
};
|
|
2878
3429
|
const toolBlocksByIndex = /* @__PURE__ */ new Map();
|
|
3430
|
+
const structuredOutputBlockIndexes = /* @__PURE__ */ new Set();
|
|
3431
|
+
const nonTextToolBlockIndexes = /* @__PURE__ */ new Set();
|
|
2879
3432
|
const toolInputAccumulators = /* @__PURE__ */ new Map();
|
|
2880
3433
|
const textBlocksByIndex = /* @__PURE__ */ new Map();
|
|
2881
3434
|
let textStreamedViaContentBlock = false;
|
|
@@ -2938,9 +3491,24 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2938
3491
|
prompt: sdkPrompt,
|
|
2939
3492
|
options: queryOptions
|
|
2940
3493
|
});
|
|
2941
|
-
this.
|
|
2942
|
-
|
|
3494
|
+
this.notifyQueryCreated(response);
|
|
3495
|
+
const sdkIterator = response[Symbol.asyncIterator]();
|
|
3496
|
+
const detachableResponse = {
|
|
3497
|
+
[Symbol.asyncIterator]: () => ({
|
|
3498
|
+
next: () => sdkIterator.next(),
|
|
3499
|
+
return: () => {
|
|
3500
|
+
void sdkIterator.return?.().catch(() => {
|
|
3501
|
+
});
|
|
3502
|
+
return Promise.resolve({ done: true, value: void 0 });
|
|
3503
|
+
}
|
|
3504
|
+
})
|
|
3505
|
+
};
|
|
3506
|
+
for await (const message of detachableResponse) {
|
|
2943
3507
|
this.logger.debug(`[claude-code] Stream received message type: ${message.type}`);
|
|
3508
|
+
this.invokeSdkMessageCallback(message);
|
|
3509
|
+
if (options.includeRawChunks) {
|
|
3510
|
+
controller.enqueue({ type: "raw", rawValue: message });
|
|
3511
|
+
}
|
|
2944
3512
|
if (message.type === "stream_event") {
|
|
2945
3513
|
const streamEvent = message;
|
|
2946
3514
|
const event = streamEvent.event;
|
|
@@ -2972,7 +3540,8 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2972
3540
|
const jsonDelta = event.delta.partial_json;
|
|
2973
3541
|
hasReceivedStreamEvents = true;
|
|
2974
3542
|
const blockIndex = "index" in event ? event.index : -1;
|
|
2975
|
-
|
|
3543
|
+
const isStructuredOutputDelta = structuredOutputBlockIndexes.has(blockIndex) || !toolBlocksByIndex.has(blockIndex) && !nonTextToolBlockIndexes.has(blockIndex);
|
|
3544
|
+
if (options.responseFormat?.type === "json" && isStructuredOutputDelta) {
|
|
2976
3545
|
if (!textPartId) {
|
|
2977
3546
|
textPartId = generateId();
|
|
2978
3547
|
controller.enqueue({
|
|
@@ -3002,12 +3571,25 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
3002
3571
|
continue;
|
|
3003
3572
|
}
|
|
3004
3573
|
}
|
|
3574
|
+
if (event.type === "content_block_start" && "content_block" in event && isNonTextToolUseContentBlockType(event.content_block?.type)) {
|
|
3575
|
+
const blockIndex = "index" in event ? event.index : -1;
|
|
3576
|
+
hasReceivedStreamEvents = true;
|
|
3577
|
+
nonTextToolBlockIndexes.add(blockIndex);
|
|
3578
|
+
structuredOutputBlockIndexes.delete(blockIndex);
|
|
3579
|
+
continue;
|
|
3580
|
+
}
|
|
3005
3581
|
if (event.type === "content_block_start" && "content_block" in event && event.content_block?.type === "tool_use") {
|
|
3006
3582
|
const blockIndex = "index" in event ? event.index : -1;
|
|
3007
3583
|
const toolBlock = event.content_block;
|
|
3008
3584
|
const toolId = typeof toolBlock.id === "string" && toolBlock.id.length > 0 ? toolBlock.id : generateId();
|
|
3009
3585
|
const toolName = typeof toolBlock.name === "string" && toolBlock.name.length > 0 ? toolBlock.name : _ClaudeCodeLanguageModel.UNKNOWN_TOOL_NAME;
|
|
3010
3586
|
hasReceivedStreamEvents = true;
|
|
3587
|
+
nonTextToolBlockIndexes.delete(blockIndex);
|
|
3588
|
+
if (isInternalStructuredOutputTool(toolName, options)) {
|
|
3589
|
+
structuredOutputBlockIndexes.add(blockIndex);
|
|
3590
|
+
continue;
|
|
3591
|
+
}
|
|
3592
|
+
structuredOutputBlockIndexes.delete(blockIndex);
|
|
3011
3593
|
if (textPartId) {
|
|
3012
3594
|
const closedTextId = textPartId;
|
|
3013
3595
|
controller.enqueue({
|
|
@@ -3154,6 +3736,12 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
3154
3736
|
toolInputAccumulators.delete(toolId);
|
|
3155
3737
|
continue;
|
|
3156
3738
|
}
|
|
3739
|
+
if (structuredOutputBlockIndexes.delete(blockIndex)) {
|
|
3740
|
+
continue;
|
|
3741
|
+
}
|
|
3742
|
+
if (nonTextToolBlockIndexes.delete(blockIndex)) {
|
|
3743
|
+
continue;
|
|
3744
|
+
}
|
|
3157
3745
|
const textId = textBlocksByIndex.get(blockIndex);
|
|
3158
3746
|
if (textId) {
|
|
3159
3747
|
this.logger.debug(
|
|
@@ -3200,7 +3788,9 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
3200
3788
|
}
|
|
3201
3789
|
const sdkParentToolUseId = message.parent_tool_use_id;
|
|
3202
3790
|
const content = message.message.content;
|
|
3203
|
-
const tools = this.extractToolUses(content)
|
|
3791
|
+
const tools = this.extractToolUses(content).filter(
|
|
3792
|
+
(tool3) => !isInternalStructuredOutputTool(tool3.name, options)
|
|
3793
|
+
);
|
|
3204
3794
|
if (textPartId && tools.length > 0) {
|
|
3205
3795
|
const closedTextId = textPartId;
|
|
3206
3796
|
controller.enqueue({
|
|
@@ -3253,7 +3843,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
3253
3843
|
toolName: tool3.name,
|
|
3254
3844
|
providerExecuted: true,
|
|
3255
3845
|
dynamic: true,
|
|
3256
|
-
//
|
|
3846
|
+
// V4 field: indicates tool is provider-defined
|
|
3257
3847
|
providerMetadata: {
|
|
3258
3848
|
"claude-code": {
|
|
3259
3849
|
parentToolCallId: state.parentToolCallId ?? null
|
|
@@ -3458,7 +4048,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
3458
4048
|
toolName,
|
|
3459
4049
|
providerExecuted: true,
|
|
3460
4050
|
dynamic: true,
|
|
3461
|
-
//
|
|
4051
|
+
// V4 field: indicates tool is provider-defined
|
|
3462
4052
|
providerMetadata: {
|
|
3463
4053
|
"claude-code": {
|
|
3464
4054
|
parentToolCallId: state.parentToolCallId ?? null
|
|
@@ -3510,19 +4100,47 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
3510
4100
|
);
|
|
3511
4101
|
state = {
|
|
3512
4102
|
name: toolName,
|
|
3513
|
-
inputStarted:
|
|
3514
|
-
inputClosed:
|
|
4103
|
+
inputStarted: false,
|
|
4104
|
+
inputClosed: false,
|
|
3515
4105
|
callEmitted: false,
|
|
3516
4106
|
parentToolCallId: errorResolvedParentId
|
|
3517
4107
|
};
|
|
3518
4108
|
toolStates.set(error.id, state);
|
|
4109
|
+
if (!state.inputStarted) {
|
|
4110
|
+
controller.enqueue({
|
|
4111
|
+
type: "tool-input-start",
|
|
4112
|
+
id: error.id,
|
|
4113
|
+
toolName,
|
|
4114
|
+
providerExecuted: true,
|
|
4115
|
+
dynamic: true,
|
|
4116
|
+
// V4 field: indicates tool is provider-defined
|
|
4117
|
+
providerMetadata: {
|
|
4118
|
+
"claude-code": {
|
|
4119
|
+
parentToolCallId: state.parentToolCallId ?? null
|
|
4120
|
+
}
|
|
4121
|
+
}
|
|
4122
|
+
});
|
|
4123
|
+
state.inputStarted = true;
|
|
4124
|
+
}
|
|
4125
|
+
if (!state.inputClosed) {
|
|
4126
|
+
controller.enqueue({
|
|
4127
|
+
type: "tool-input-end",
|
|
4128
|
+
id: error.id
|
|
4129
|
+
});
|
|
4130
|
+
state.inputClosed = true;
|
|
4131
|
+
}
|
|
3519
4132
|
}
|
|
3520
4133
|
emitToolCall(error.id, state);
|
|
3521
4134
|
if (isSubagentToolName(toolName)) {
|
|
3522
4135
|
activeTaskTools.delete(error.id);
|
|
3523
4136
|
}
|
|
3524
4137
|
controller.enqueue(
|
|
3525
|
-
this.
|
|
4138
|
+
this.buildErroredToolResultPart(
|
|
4139
|
+
error.id,
|
|
4140
|
+
toolName,
|
|
4141
|
+
error.error,
|
|
4142
|
+
state.parentToolCallId
|
|
4143
|
+
)
|
|
3526
4144
|
);
|
|
3527
4145
|
}
|
|
3528
4146
|
} else if (message.type === "result") {
|
|
@@ -3552,13 +4170,16 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
3552
4170
|
);
|
|
3553
4171
|
}
|
|
3554
4172
|
const stopReason = "stop_reason" in message ? message.stop_reason : void 0;
|
|
3555
|
-
|
|
4173
|
+
let finishReason = mapClaudeCodeFinishReason(
|
|
3556
4174
|
message.subtype,
|
|
3557
4175
|
stopReason
|
|
3558
4176
|
);
|
|
3559
|
-
this.logger.debug(`[claude-code] Stream finish reason: ${finishReason.unified}`);
|
|
3560
4177
|
this.setSessionId(message.session_id);
|
|
3561
4178
|
const structuredOutput = "structured_output" in message ? message.structured_output : void 0;
|
|
4179
|
+
if (structuredOutput !== void 0 && finishReason.unified === "tool-calls") {
|
|
4180
|
+
finishReason = { unified: "stop", raw: finishReason.raw };
|
|
4181
|
+
}
|
|
4182
|
+
this.logger.debug(`[claude-code] Stream finish reason: ${finishReason.unified}`);
|
|
3562
4183
|
const alreadyStreamedJson = hasStreamedJson && options.responseFormat?.type === "json" && hasReceivedStreamEvents;
|
|
3563
4184
|
if (alreadyStreamedJson) {
|
|
3564
4185
|
if (textPartId) {
|
|
@@ -3672,6 +4293,15 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
3672
4293
|
...metadataTracking.permissionDenials.length > 0 && {
|
|
3673
4294
|
permissionDenials: metadataTracking.permissionDenials
|
|
3674
4295
|
},
|
|
4296
|
+
...metadataTracking.taskEvents.length > 0 && {
|
|
4297
|
+
taskEvents: metadataTracking.taskEvents
|
|
4298
|
+
},
|
|
4299
|
+
...metadataTracking.hookEvents.length > 0 && {
|
|
4300
|
+
hookEvents: metadataTracking.hookEvents
|
|
4301
|
+
},
|
|
4302
|
+
...metadataTracking.mcpServers !== void 0 && {
|
|
4303
|
+
mcpServers: metadataTracking.mcpServers
|
|
4304
|
+
},
|
|
3675
4305
|
...metadataTracking.mirrorErrors.length > 0 && {
|
|
3676
4306
|
mirrorErrors: metadataTracking.mirrorErrors
|
|
3677
4307
|
},
|
|
@@ -3689,12 +4319,14 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
3689
4319
|
});
|
|
3690
4320
|
controller.close();
|
|
3691
4321
|
const effectivePromptSuggestions = sdkOptions?.promptSuggestions ?? this.settings.promptSuggestions;
|
|
3692
|
-
|
|
3693
|
-
|
|
4322
|
+
const shouldDrainPromptSuggestion = effectivePromptSuggestions !== false && (this.settings.onPromptSuggestion !== void 0 || this.settings.onSdkMessage !== void 0);
|
|
4323
|
+
if (shouldDrainPromptSuggestion) {
|
|
4324
|
+
await this.drainPromptSuggestion(sdkIterator, this.settings.onPromptSuggestion);
|
|
3694
4325
|
}
|
|
3695
4326
|
return;
|
|
3696
4327
|
} else if (message.type === "system" && message.subtype === "init") {
|
|
3697
4328
|
this.logMcpConnectionIssues(message.mcp_servers);
|
|
4329
|
+
this.trackMcpStatusFromInit(message, metadataTracking);
|
|
3698
4330
|
this.setSessionId(message.session_id);
|
|
3699
4331
|
this.logger.info(`[claude-code] Stream session initialized: ${message.session_id}`);
|
|
3700
4332
|
controller.enqueue({
|
|
@@ -3768,6 +4400,15 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
3768
4400
|
...metadataTracking.permissionDenials.length > 0 && {
|
|
3769
4401
|
permissionDenials: metadataTracking.permissionDenials
|
|
3770
4402
|
},
|
|
4403
|
+
...metadataTracking.taskEvents.length > 0 && {
|
|
4404
|
+
taskEvents: metadataTracking.taskEvents
|
|
4405
|
+
},
|
|
4406
|
+
...metadataTracking.hookEvents.length > 0 && {
|
|
4407
|
+
hookEvents: metadataTracking.hookEvents
|
|
4408
|
+
},
|
|
4409
|
+
...metadataTracking.mcpServers !== void 0 && {
|
|
4410
|
+
mcpServers: metadataTracking.mcpServers
|
|
4411
|
+
},
|
|
3771
4412
|
...metadataTracking.mirrorErrors.length > 0 && {
|
|
3772
4413
|
mirrorErrors: metadataTracking.mirrorErrors
|
|
3773
4414
|
},
|
|
@@ -3815,19 +4456,23 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
3815
4456
|
};
|
|
3816
4457
|
}
|
|
3817
4458
|
serializeWarningsForMetadata(warnings) {
|
|
3818
|
-
const result = warnings.map((
|
|
3819
|
-
const base = { type:
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
|
|
3827
|
-
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
4459
|
+
const result = warnings.map((warning) => {
|
|
4460
|
+
const base = { type: warning.type };
|
|
4461
|
+
switch (warning.type) {
|
|
4462
|
+
case "unsupported":
|
|
4463
|
+
case "compatibility":
|
|
4464
|
+
base.feature = warning.feature;
|
|
4465
|
+
if (warning.details !== void 0) {
|
|
4466
|
+
base.details = warning.details;
|
|
4467
|
+
}
|
|
4468
|
+
break;
|
|
4469
|
+
case "deprecated":
|
|
4470
|
+
base.setting = warning.setting;
|
|
4471
|
+
base.message = warning.message;
|
|
4472
|
+
break;
|
|
4473
|
+
case "other":
|
|
4474
|
+
base.message = warning.message;
|
|
4475
|
+
break;
|
|
3831
4476
|
}
|
|
3832
4477
|
return base;
|
|
3833
4478
|
});
|
|
@@ -3870,7 +4515,7 @@ function createClaudeCode(options = {}) {
|
|
|
3870
4515
|
};
|
|
3871
4516
|
provider.languageModel = createModel;
|
|
3872
4517
|
provider.chat = createModel;
|
|
3873
|
-
provider.specificationVersion = "
|
|
4518
|
+
provider.specificationVersion = "v4";
|
|
3874
4519
|
provider.embeddingModel = (modelId) => {
|
|
3875
4520
|
throw new NoSuchModelError2({
|
|
3876
4521
|
modelId,
|
|
@@ -3894,7 +4539,9 @@ import {
|
|
|
3894
4539
|
SYSTEM_PROMPT_DYNAMIC_BOUNDARY,
|
|
3895
4540
|
InMemorySessionStore,
|
|
3896
4541
|
HOOK_EVENTS,
|
|
3897
|
-
AbortError
|
|
4542
|
+
AbortError,
|
|
4543
|
+
resolveSettings,
|
|
4544
|
+
filterEscalatingDefaultMode
|
|
3898
4545
|
} from "@anthropic-ai/claude-agent-sdk";
|
|
3899
4546
|
import {
|
|
3900
4547
|
listSessions,
|
|
@@ -3914,6 +4561,16 @@ import { startup } from "@anthropic-ai/claude-agent-sdk";
|
|
|
3914
4561
|
// src/mcp-helpers.ts
|
|
3915
4562
|
import { createSdkMcpServer, tool } from "@anthropic-ai/claude-agent-sdk";
|
|
3916
4563
|
import "zod";
|
|
4564
|
+
var warnedDescriptionFunctionToolNames = /* @__PURE__ */ new Set();
|
|
4565
|
+
function warnDiscardedDescriptionFunction(toolName) {
|
|
4566
|
+
if (warnedDescriptionFunctionToolNames.has(toolName)) {
|
|
4567
|
+
return;
|
|
4568
|
+
}
|
|
4569
|
+
warnedDescriptionFunctionToolNames.add(toolName);
|
|
4570
|
+
console.warn(
|
|
4571
|
+
`[claude-code] AI SDK tool "${toolName}" has a function-valued description; createAiSdkMcpServer cannot evaluate it during MCP bridging, so the bridged tool description was omitted.`
|
|
4572
|
+
);
|
|
4573
|
+
}
|
|
3917
4574
|
function buildIsErrorResult(text) {
|
|
3918
4575
|
return {
|
|
3919
4576
|
isError: true,
|
|
@@ -3956,7 +4613,11 @@ function createCustomMcpServer(config) {
|
|
|
3956
4613
|
}
|
|
3957
4614
|
var AI_SDK_SCHEMA_SYMBOL = Symbol.for("vercel.ai.schema");
|
|
3958
4615
|
function isAiSdkJsonSchema(schema) {
|
|
3959
|
-
|
|
4616
|
+
if (typeof schema !== "object" || schema === null) {
|
|
4617
|
+
return false;
|
|
4618
|
+
}
|
|
4619
|
+
const candidate = schema;
|
|
4620
|
+
return candidate[AI_SDK_SCHEMA_SYMBOL] === true && "jsonSchema" in candidate && "validate" in candidate;
|
|
3960
4621
|
}
|
|
3961
4622
|
function isZodObjectSchema(schema) {
|
|
3962
4623
|
if (typeof schema !== "object" || schema === null) {
|
|
@@ -3991,9 +4652,13 @@ function createAiSdkMcpServer(name, tools) {
|
|
|
3991
4652
|
);
|
|
3992
4653
|
}
|
|
3993
4654
|
const zodSchema = def.inputSchema;
|
|
4655
|
+
const description = typeof def.description === "string" ? def.description : "";
|
|
4656
|
+
if (typeof def.description === "function") {
|
|
4657
|
+
warnDiscardedDescriptionFunction(toolName);
|
|
4658
|
+
}
|
|
3994
4659
|
return tool(
|
|
3995
4660
|
toolName,
|
|
3996
|
-
|
|
4661
|
+
description,
|
|
3997
4662
|
zodSchema.shape,
|
|
3998
4663
|
async (args, extra) => {
|
|
3999
4664
|
try {
|
|
@@ -4026,10 +4691,12 @@ export {
|
|
|
4026
4691
|
createAiSdkMcpServer,
|
|
4027
4692
|
createAuthenticationError,
|
|
4028
4693
|
createClaudeCode,
|
|
4694
|
+
createClaudeCodeQueryController,
|
|
4029
4695
|
createCustomMcpServer,
|
|
4030
4696
|
createSdkMcpServer2 as createSdkMcpServer,
|
|
4031
4697
|
createTimeoutError,
|
|
4032
4698
|
deleteSession,
|
|
4699
|
+
filterEscalatingDefaultMode,
|
|
4033
4700
|
foldSessionSummary,
|
|
4034
4701
|
forkSession,
|
|
4035
4702
|
getErrorMetadata,
|
|
@@ -4042,6 +4709,7 @@ export {
|
|
|
4042
4709
|
listSessions,
|
|
4043
4710
|
listSubagents,
|
|
4044
4711
|
renameSession,
|
|
4712
|
+
resolveSettings,
|
|
4045
4713
|
startup,
|
|
4046
4714
|
tagSession,
|
|
4047
4715
|
tool2 as tool
|