ai-sdk-provider-claude-code 3.5.2 → 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 -120
- package/dist/index.d.ts +236 -51
- package/dist/index.js +951 -223
- package/dist/index.js.map +1 -1
- package/docs/sessions.md +4 -4
- package/package.json +12 -14
- package/dist/index.cjs +0 -4025
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -1329
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/");
|
|
68
|
+
}
|
|
69
|
+
function isConcreteImageMimeType(mediaType) {
|
|
70
|
+
const normalized = normalizeMediaType(mediaType);
|
|
71
|
+
return normalized.startsWith("image/") && !normalized.endsWith("/*");
|
|
30
72
|
}
|
|
31
|
-
function
|
|
32
|
-
|
|
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");
|
|
@@ -532,6 +698,18 @@ var claudeCodeSettingsSchema = z.object({
|
|
|
532
698
|
forwardSubagentText: z.boolean().optional(),
|
|
533
699
|
agentProgressSummaries: z.boolean().optional(),
|
|
534
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(),
|
|
535
713
|
taskBudget: z.object({ total: z.number().positive() }).strict().optional(),
|
|
536
714
|
sessionStore: z.any().refine(
|
|
537
715
|
(val) => val === void 0 || typeof val === "object" && val !== null && typeof val.append === "function" && typeof val.load === "function",
|
|
@@ -548,6 +726,9 @@ var claudeCodeSettingsSchema = z.object({
|
|
|
548
726
|
onUserDialog: z.any().refine((v) => v === void 0 || typeof v === "function", {
|
|
549
727
|
message: "onUserDialog must be a function"
|
|
550
728
|
}).optional(),
|
|
729
|
+
onElicitation: z.any().refine((v) => v === void 0 || typeof v === "function", {
|
|
730
|
+
message: "onElicitation must be a function"
|
|
731
|
+
}).optional(),
|
|
551
732
|
supportedDialogKinds: z.array(z.string()).optional(),
|
|
552
733
|
hooks: z.record(
|
|
553
734
|
z.string(),
|
|
@@ -594,6 +775,7 @@ var claudeCodeSettingsSchema = z.object({
|
|
|
594
775
|
logger: z.union([z.literal(false), loggerFunctionSchema]).optional(),
|
|
595
776
|
env: z.record(z.string(), z.string().optional()).optional(),
|
|
596
777
|
additionalDirectories: z.array(z.string()).optional(),
|
|
778
|
+
agent: z.string().optional(),
|
|
597
779
|
agents: z.record(
|
|
598
780
|
z.string(),
|
|
599
781
|
z.object({
|
|
@@ -631,10 +813,13 @@ var claudeCodeSettingsSchema = z.object({
|
|
|
631
813
|
onQueryCreated: z.any().refine((val) => val === void 0 || typeof val === "function", {
|
|
632
814
|
message: "onQueryCreated must be a function"
|
|
633
815
|
}).optional(),
|
|
816
|
+
onQueryControllerCreated: z.any().refine((val) => val === void 0 || typeof val === "function", {
|
|
817
|
+
message: "onQueryControllerCreated must be a function"
|
|
818
|
+
}).optional(),
|
|
634
819
|
onStreamStart: z.any().refine((val) => val === void 0 || typeof val === "function", {
|
|
635
820
|
message: "onStreamStart must be a function"
|
|
636
821
|
}).optional(),
|
|
637
|
-
// Callback invoked with the predicted next user prompt (
|
|
822
|
+
// Callback invoked with the predicted next user prompt (requires promptSuggestions: true)
|
|
638
823
|
onPromptSuggestion: z.any().refine((val) => val === void 0 || typeof val === "function", {
|
|
639
824
|
message: "onPromptSuggestion must be a function"
|
|
640
825
|
}).optional()
|
|
@@ -719,6 +904,11 @@ function validateSettings(settings) {
|
|
|
719
904
|
`Very high maxThinkingTokens (${validSettings.maxThinkingTokens}) may increase response time`
|
|
720
905
|
);
|
|
721
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
|
+
}
|
|
722
912
|
if (validSettings.allowedTools && validSettings.disallowedTools) {
|
|
723
913
|
warnings.push(
|
|
724
914
|
"Both allowedTools and disallowedTools are specified. Only allowedTools will be used."
|
|
@@ -956,9 +1146,38 @@ function createVerboseLogger(logger, verbose = false) {
|
|
|
956
1146
|
};
|
|
957
1147
|
}
|
|
958
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
|
+
|
|
959
1178
|
// src/claude-code-language-model.ts
|
|
960
1179
|
import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
961
|
-
var PROVIDER_VERSION = "
|
|
1180
|
+
var PROVIDER_VERSION = "4.0.0";
|
|
962
1181
|
var DEFAULT_CLIENT_APP = `ai-sdk-provider-claude-code/${PROVIDER_VERSION}`;
|
|
963
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.";
|
|
964
1183
|
var MIN_TRUNCATION_LENGTH = 512;
|
|
@@ -992,6 +1211,13 @@ function isClaudeCodeTruncationError(error, bufferedText) {
|
|
|
992
1211
|
return true;
|
|
993
1212
|
}
|
|
994
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
|
+
}
|
|
995
1221
|
function extractJsonObjectText(text) {
|
|
996
1222
|
const trimmed = text.trim();
|
|
997
1223
|
if (!trimmed) {
|
|
@@ -1085,7 +1311,7 @@ function getBaseProcessEnv() {
|
|
|
1085
1311
|
}
|
|
1086
1312
|
return env;
|
|
1087
1313
|
}
|
|
1088
|
-
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.";
|
|
1089
1315
|
var SDK_OPTIONS_BLOCKLIST = /* @__PURE__ */ new Set(["model", "abortController", "prompt", "outputFormat"]);
|
|
1090
1316
|
var SUBAGENT_TOOL_NAMES = /* @__PURE__ */ new Set(["Task", "Agent"]);
|
|
1091
1317
|
function isSubagentToolName(name) {
|
|
@@ -1108,7 +1334,7 @@ function computeRetractedToolCallIds(retracted, descriptors) {
|
|
|
1108
1334
|
function applySupersede(message, evict, logger, guard = "array") {
|
|
1109
1335
|
const supersedes = message.supersedes;
|
|
1110
1336
|
const triggered = guard === "truthy" ? Boolean(supersedes && supersedes.length > 0) : Array.isArray(supersedes) && supersedes.length > 0;
|
|
1111
|
-
if (!triggered) {
|
|
1337
|
+
if (!triggered || supersedes === void 0) {
|
|
1112
1338
|
return false;
|
|
1113
1339
|
}
|
|
1114
1340
|
logger.debug(`[claude-code] Assistant message supersedes ${supersedes.length} prior message(s)`);
|
|
@@ -1121,12 +1347,126 @@ function buildRetractionEvictor(evict) {
|
|
|
1121
1347
|
var INFORMATIONAL_SYSTEM_SUBTYPES = /* @__PURE__ */ new Set([
|
|
1122
1348
|
"notification",
|
|
1123
1349
|
"status",
|
|
1124
|
-
"task_updated",
|
|
1125
1350
|
"session_state_changed",
|
|
1126
1351
|
"commands_changed",
|
|
1127
1352
|
"memory_recall",
|
|
1128
|
-
"plugin_install"
|
|
1353
|
+
"plugin_install",
|
|
1354
|
+
"informational"
|
|
1129
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
|
+
}
|
|
1130
1470
|
function isContentBlock(item) {
|
|
1131
1471
|
return typeof item === "object" && item !== null && "type" in item;
|
|
1132
1472
|
}
|
|
@@ -1287,6 +1627,7 @@ function toAsyncIterablePrompt(messagesPrompt, outputStreamEnded, sessionId, con
|
|
|
1287
1627
|
};
|
|
1288
1628
|
}
|
|
1289
1629
|
var modelMap = {
|
|
1630
|
+
fable: "fable",
|
|
1290
1631
|
opus: "opus",
|
|
1291
1632
|
sonnet: "sonnet",
|
|
1292
1633
|
haiku: "haiku"
|
|
@@ -1335,7 +1676,7 @@ function truncateToolResultForStream(result, maxSize = MAX_TOOL_RESULT_SIZE) {
|
|
|
1335
1676
|
return result;
|
|
1336
1677
|
}
|
|
1337
1678
|
var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
1338
|
-
specificationVersion = "
|
|
1679
|
+
specificationVersion = "v4";
|
|
1339
1680
|
defaultObjectGenerationMode = "json";
|
|
1340
1681
|
supportsImageUrls = false;
|
|
1341
1682
|
supportedUrls = {};
|
|
@@ -1406,6 +1747,81 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1406
1747
|
}
|
|
1407
1748
|
return void 0;
|
|
1408
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
|
+
}
|
|
1409
1825
|
/**
|
|
1410
1826
|
* Single source of truth for the CLI's `--session-id` exclusivity rule.
|
|
1411
1827
|
*
|
|
@@ -1570,7 +1986,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1570
1986
|
input,
|
|
1571
1987
|
providerExecuted: true,
|
|
1572
1988
|
dynamic: true,
|
|
1573
|
-
//
|
|
1989
|
+
// V4 field: indicates tool is provider-defined (not in user's tools map)
|
|
1574
1990
|
providerMetadata: {
|
|
1575
1991
|
"claude-code": {
|
|
1576
1992
|
// rawInput preserves the original serialized format before AI SDK normalization.
|
|
@@ -1610,12 +2026,11 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1610
2026
|
toolName,
|
|
1611
2027
|
// `?? ''`: absent `content` (undefined) and string results that
|
|
1612
2028
|
// normalize to JSON null (e.g. the string "null") must not violate the
|
|
1613
|
-
// NonNullable<JSONValue> contract of
|
|
2029
|
+
// NonNullable<JSONValue> contract of LanguageModelV4ToolResult.result.
|
|
1614
2030
|
result: truncatedResult ?? "",
|
|
1615
2031
|
isError,
|
|
1616
|
-
providerExecuted: true,
|
|
1617
2032
|
dynamic: true,
|
|
1618
|
-
//
|
|
2033
|
+
// V4 field: indicates tool is provider-defined
|
|
1619
2034
|
providerMetadata: {
|
|
1620
2035
|
"claude-code": {
|
|
1621
2036
|
// rawResult preserves the original CLI output string before JSON parsing.
|
|
@@ -1638,37 +2053,12 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1638
2053
|
})() : String(error);
|
|
1639
2054
|
}
|
|
1640
2055
|
/**
|
|
1641
|
-
* Builds a provider
|
|
1642
|
-
* `tool_error` block
|
|
1643
|
-
*
|
|
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.
|
|
1644
2060
|
*/
|
|
1645
|
-
|
|
1646
|
-
const rawError = this.serializeToolError(error);
|
|
1647
|
-
return {
|
|
1648
|
-
type: "tool-error",
|
|
1649
|
-
toolCallId,
|
|
1650
|
-
toolName,
|
|
1651
|
-
error: rawError,
|
|
1652
|
-
providerExecuted: true,
|
|
1653
|
-
dynamic: true,
|
|
1654
|
-
// V3 field: indicates tool is provider-defined
|
|
1655
|
-
providerMetadata: {
|
|
1656
|
-
"claude-code": {
|
|
1657
|
-
rawError,
|
|
1658
|
-
parentToolCallId: parentToolCallId ?? null
|
|
1659
|
-
}
|
|
1660
|
-
}
|
|
1661
|
-
};
|
|
1662
|
-
}
|
|
1663
|
-
/**
|
|
1664
|
-
* Builds a V3 `tool-result` CONTENT part with `isError: true` from a
|
|
1665
|
-
* user-message `tool_error` block (doGenerate only). The V3 content union
|
|
1666
|
-
* has no `tool-error` member and AI SDK core's asContent() silently drops
|
|
1667
|
-
* unknown content part types, so an extension tool-error part would never
|
|
1668
|
-
* reach `generateText` users — an isError tool-result, by contrast,
|
|
1669
|
-
* round-trips into a proper tool-error part in steps content.
|
|
1670
|
-
*/
|
|
1671
|
-
buildToolErrorResultPart(toolCallId, toolName, error, parentToolCallId) {
|
|
2061
|
+
buildErroredToolResultPart(toolCallId, toolName, error, parentToolCallId) {
|
|
1672
2062
|
const rawError = this.serializeToolError(error);
|
|
1673
2063
|
return {
|
|
1674
2064
|
type: "tool-result",
|
|
@@ -1676,9 +2066,8 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1676
2066
|
toolName,
|
|
1677
2067
|
result: rawError,
|
|
1678
2068
|
isError: true,
|
|
1679
|
-
providerExecuted: true,
|
|
1680
2069
|
dynamic: true,
|
|
1681
|
-
//
|
|
2070
|
+
// V4 field: indicates tool is provider-defined
|
|
1682
2071
|
providerMetadata: {
|
|
1683
2072
|
"claude-code": {
|
|
1684
2073
|
rawError,
|
|
@@ -1704,7 +2093,33 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1704
2093
|
);
|
|
1705
2094
|
return true;
|
|
1706
2095
|
}
|
|
1707
|
-
|
|
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) {
|
|
1708
2123
|
const warnings = [];
|
|
1709
2124
|
const unsupportedParams = [];
|
|
1710
2125
|
if (options.temperature !== void 0) unsupportedParams.push("temperature");
|
|
@@ -1771,9 +2186,18 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1771
2186
|
message: promptWarning
|
|
1772
2187
|
});
|
|
1773
2188
|
}
|
|
2189
|
+
this.resolvePortableReasoningOptions(
|
|
2190
|
+
options,
|
|
2191
|
+
sdkOptions,
|
|
2192
|
+
extractClaudeReasoningProviderOptions(options.providerOptions, warnings),
|
|
2193
|
+
warnings
|
|
2194
|
+
);
|
|
1774
2195
|
return warnings;
|
|
1775
2196
|
}
|
|
1776
|
-
createQueryOptions(abortController,
|
|
2197
|
+
createQueryOptions(abortController, options, stderrCollector, sdkOptions, effectiveResume) {
|
|
2198
|
+
const claudeReasoningProviderOptions = extractClaudeReasoningProviderOptions(
|
|
2199
|
+
options.providerOptions
|
|
2200
|
+
);
|
|
1777
2201
|
const opts = {
|
|
1778
2202
|
model: this.getModel(),
|
|
1779
2203
|
abortController,
|
|
@@ -1801,8 +2225,14 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1801
2225
|
sandbox: this.settings.sandbox,
|
|
1802
2226
|
tools: this.settings.tools,
|
|
1803
2227
|
mcpServers: this.settings.mcpServers,
|
|
1804
|
-
canUseTool: this.settings.canUseTool
|
|
2228
|
+
canUseTool: this.settings.canUseTool,
|
|
2229
|
+
onElicitation: this.settings.onElicitation,
|
|
2230
|
+
agent: this.settings.agent
|
|
1805
2231
|
};
|
|
2232
|
+
Object.assign(
|
|
2233
|
+
opts,
|
|
2234
|
+
this.resolvePortableReasoningOptions(options, sdkOptions, claudeReasoningProviderOptions)
|
|
2235
|
+
);
|
|
1806
2236
|
if (this.settings.onUserDialog !== void 0) {
|
|
1807
2237
|
opts.onUserDialog = this.settings.onUserDialog;
|
|
1808
2238
|
}
|
|
@@ -1931,6 +2361,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1931
2361
|
}
|
|
1932
2362
|
}
|
|
1933
2363
|
}
|
|
2364
|
+
this.applyClaudeReasoningProviderOptions(opts, claudeReasoningProviderOptions);
|
|
1934
2365
|
this.applySessionResolution(opts, effectiveResume);
|
|
1935
2366
|
if (typeof opts.fallbackModel === "string" && opts.fallbackModel === opts.model) {
|
|
1936
2367
|
throw new Error(
|
|
@@ -1953,9 +2384,9 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1953
2384
|
mergedEnv.CLAUDE_AGENT_SDK_CLIENT_APP = DEFAULT_CLIENT_APP;
|
|
1954
2385
|
}
|
|
1955
2386
|
opts.env = mergedEnv;
|
|
1956
|
-
if (responseFormat?.type === "json" && responseFormat.schema) {
|
|
2387
|
+
if (options.responseFormat?.type === "json" && options.responseFormat.schema) {
|
|
1957
2388
|
const { schema: sanitizedSchema, strippedFormatPaths } = sanitizeJsonSchemaForOutputFormat(
|
|
1958
|
-
responseFormat.schema
|
|
2389
|
+
options.responseFormat.schema
|
|
1959
2390
|
);
|
|
1960
2391
|
if (strippedFormatPaths.length > 0) {
|
|
1961
2392
|
this.logger.debug(
|
|
@@ -2029,7 +2460,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2029
2460
|
if (errorKind === "model_not_found" || errorMessage.includes("model_not_found") || errorMessage.includes("no such model")) {
|
|
2030
2461
|
const originalMessage = isErrorWithMessage(error) && error.message ? error.message : "Model not found";
|
|
2031
2462
|
return createAPICallError({
|
|
2032
|
-
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.`,
|
|
2033
2464
|
code: errorCode || void 0,
|
|
2034
2465
|
exitCode,
|
|
2035
2466
|
stderr,
|
|
@@ -2099,16 +2530,159 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2099
2530
|
break;
|
|
2100
2531
|
case "permission_denied": {
|
|
2101
2532
|
const reason = message.decision_reason ?? message.message;
|
|
2533
|
+
const raw = toJsonSafeValue(message);
|
|
2102
2534
|
tracking.permissionDenials.push({
|
|
2103
2535
|
toolName: message.tool_name,
|
|
2104
2536
|
toolUseId: message.tool_use_id,
|
|
2105
|
-
...
|
|
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 }
|
|
2106
2543
|
});
|
|
2107
2544
|
this.logger.warn(
|
|
2108
2545
|
`[claude-code] Permission denied - Tool: ${message.tool_name}${reason ? `, Reason: ${reason}` : ""}`
|
|
2109
2546
|
);
|
|
2110
2547
|
break;
|
|
2111
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;
|
|
2112
2686
|
case "mirror_error": {
|
|
2113
2687
|
const mirrorError = message.error ?? "unknown error";
|
|
2114
2688
|
const mirrorSessionId = message.key?.sessionId ?? message.session_id ?? "unknown";
|
|
@@ -2161,12 +2735,21 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2161
2735
|
const alreadyTracked = tracking.permissionDenials.some(
|
|
2162
2736
|
(d) => d.toolUseId !== void 0 && d.toolUseId === denial.tool_use_id
|
|
2163
2737
|
);
|
|
2164
|
-
if (
|
|
2165
|
-
|
|
2166
|
-
toolName: denial.tool_name,
|
|
2167
|
-
toolUseId: denial.tool_use_id
|
|
2168
|
-
});
|
|
2738
|
+
if (alreadyTracked) {
|
|
2739
|
+
continue;
|
|
2169
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
|
+
});
|
|
2170
2753
|
}
|
|
2171
2754
|
}
|
|
2172
2755
|
/**
|
|
@@ -2175,11 +2758,10 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2175
2758
|
* suggestion arrives AFTER the result message; the SDK emits at most one
|
|
2176
2759
|
* per turn, so stop once it is delivered, and a timeout closes the
|
|
2177
2760
|
* iterator (tearing down the subprocess) if the CLI lingers after the
|
|
2178
|
-
* result without emitting one.
|
|
2179
|
-
*
|
|
2761
|
+
* result without emitting one. Drained messages still pass through the
|
|
2762
|
+
* generic raw SDK callback before prompt-specific handling.
|
|
2180
2763
|
*/
|
|
2181
|
-
async drainPromptSuggestion(
|
|
2182
|
-
const iterator = response[Symbol.asyncIterator]();
|
|
2764
|
+
async drainPromptSuggestion(iterator, onPromptSuggestion) {
|
|
2183
2765
|
let drainTimer;
|
|
2184
2766
|
const drainTimeout = new Promise((resolve) => {
|
|
2185
2767
|
drainTimer = setTimeout(
|
|
@@ -2202,8 +2784,9 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2202
2784
|
}
|
|
2203
2785
|
const trailingMessage = winner.value;
|
|
2204
2786
|
this.logger.debug(`[claude-code] Post-result message type: ${trailingMessage.type}`);
|
|
2787
|
+
this.invokeSdkMessageCallback(trailingMessage);
|
|
2205
2788
|
if (trailingMessage.type === "prompt_suggestion") {
|
|
2206
|
-
onPromptSuggestion(trailingMessage.suggestion);
|
|
2789
|
+
onPromptSuggestion?.(trailingMessage.suggestion);
|
|
2207
2790
|
void iterator.return?.().catch(() => {
|
|
2208
2791
|
});
|
|
2209
2792
|
break;
|
|
@@ -2244,7 +2827,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2244
2827
|
const effectiveResume = this.getEffectiveResume(sdkOptions);
|
|
2245
2828
|
const queryOptions = this.createQueryOptions(
|
|
2246
2829
|
abortController,
|
|
2247
|
-
options
|
|
2830
|
+
options,
|
|
2248
2831
|
stderrCollector,
|
|
2249
2832
|
sdkOptions,
|
|
2250
2833
|
effectiveResume
|
|
@@ -2318,9 +2901,15 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2318
2901
|
apiRetries: 0,
|
|
2319
2902
|
permissionDenials: [],
|
|
2320
2903
|
mirrorErrors: [],
|
|
2321
|
-
estimatedThinkingTokens: 0
|
|
2904
|
+
estimatedThinkingTokens: 0,
|
|
2905
|
+
taskEvents: [],
|
|
2906
|
+
hookEvents: []
|
|
2322
2907
|
};
|
|
2323
|
-
const warnings = this.generateAllWarnings(
|
|
2908
|
+
const warnings = this.generateAllWarnings(
|
|
2909
|
+
options,
|
|
2910
|
+
messagesPrompt,
|
|
2911
|
+
sdkOptions
|
|
2912
|
+
);
|
|
2324
2913
|
if (messageWarnings) {
|
|
2325
2914
|
messageWarnings.forEach((warning) => {
|
|
2326
2915
|
warnings.push({
|
|
@@ -2332,7 +2921,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2332
2921
|
const modeSetting = this.settings.streamingInput ?? "auto";
|
|
2333
2922
|
const effectiveCanUseTool = sdkOptions?.canUseTool ?? this.settings.canUseTool;
|
|
2334
2923
|
const effectivePermissionPromptToolName = sdkOptions?.permissionPromptToolName ?? this.settings.permissionPromptToolName;
|
|
2335
|
-
const wantsStreamInput = modeSetting === "always" || modeSetting === "auto" && !!effectiveCanUseTool;
|
|
2924
|
+
const wantsStreamInput = modeSetting === "always" || modeSetting === "auto" && (!!effectiveCanUseTool || hasImageParts);
|
|
2336
2925
|
if (!wantsStreamInput && hasImageParts) {
|
|
2337
2926
|
warnings.push({
|
|
2338
2927
|
type: "other",
|
|
@@ -2364,7 +2953,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2364
2953
|
prompt: sdkPrompt,
|
|
2365
2954
|
options: queryOptions
|
|
2366
2955
|
});
|
|
2367
|
-
this.
|
|
2956
|
+
this.notifyQueryCreated(response);
|
|
2368
2957
|
let lastAssistantErrorKind;
|
|
2369
2958
|
const sdkIterator = response[Symbol.asyncIterator]();
|
|
2370
2959
|
const detachableResponse = {
|
|
@@ -2379,6 +2968,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2379
2968
|
};
|
|
2380
2969
|
for await (const message of detachableResponse) {
|
|
2381
2970
|
this.logger.debug(`[claude-code] Received message type: ${message.type}`);
|
|
2971
|
+
this.invokeSdkMessageCallback(message);
|
|
2382
2972
|
if (message.type === "assistant") {
|
|
2383
2973
|
if (typeof message.error === "string") {
|
|
2384
2974
|
lastAssistantErrorKind = message.error;
|
|
@@ -2407,6 +2997,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2407
2997
|
} else if (block.type === "tool_use") {
|
|
2408
2998
|
const [tool3] = this.extractToolUses([block]);
|
|
2409
2999
|
if (!tool3) continue;
|
|
3000
|
+
if (isInternalStructuredOutputTool(tool3.name, options)) continue;
|
|
2410
3001
|
const parentToolCallId = isSubagentToolName(tool3.name) ? null : resolveToolParentId(
|
|
2411
3002
|
sdkParentToolUseId,
|
|
2412
3003
|
tool3.parentToolUseId,
|
|
@@ -2517,7 +3108,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2517
3108
|
kind: "tool-error",
|
|
2518
3109
|
...resultMessageUuid !== void 0 && { uuid: resultMessageUuid },
|
|
2519
3110
|
toolCallId: error.id,
|
|
2520
|
-
part: this.
|
|
3111
|
+
part: this.buildErroredToolResultPart(
|
|
2521
3112
|
error.id,
|
|
2522
3113
|
toolName,
|
|
2523
3114
|
error.error,
|
|
@@ -2575,14 +3166,19 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2575
3166
|
}
|
|
2576
3167
|
const stopReason = "stop_reason" in message ? message.stop_reason : void 0;
|
|
2577
3168
|
finishReason = mapClaudeCodeFinishReason(message.subtype, stopReason);
|
|
3169
|
+
if (structuredOutput !== void 0 && finishReason.unified === "tool-calls") {
|
|
3170
|
+
finishReason = { unified: "stop", raw: finishReason.raw };
|
|
3171
|
+
}
|
|
2578
3172
|
this.logger.debug(`[claude-code] Finish reason: ${finishReason.unified}`);
|
|
2579
3173
|
const effectivePromptSuggestions = sdkOptions?.promptSuggestions ?? this.settings.promptSuggestions;
|
|
2580
|
-
|
|
2581
|
-
|
|
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);
|
|
2582
3177
|
}
|
|
2583
3178
|
break;
|
|
2584
3179
|
} else if (message.type === "system" && message.subtype === "init") {
|
|
2585
3180
|
this.logMcpConnectionIssues(message.mcp_servers);
|
|
3181
|
+
this.trackMcpStatusFromInit(message, metadataTracking);
|
|
2586
3182
|
this.setSessionId(message.session_id);
|
|
2587
3183
|
this.logger.info(`[claude-code] Session initialized: ${message.session_id}`);
|
|
2588
3184
|
} else if (message.type === "system") {
|
|
@@ -2685,6 +3281,15 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2685
3281
|
...metadataTracking.permissionDenials.length > 0 && {
|
|
2686
3282
|
permissionDenials: metadataTracking.permissionDenials
|
|
2687
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
|
+
},
|
|
2688
3293
|
...metadataTracking.mirrorErrors.length > 0 && {
|
|
2689
3294
|
mirrorErrors: metadataTracking.mirrorErrors
|
|
2690
3295
|
},
|
|
@@ -2722,7 +3327,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2722
3327
|
const effectiveResume = this.getEffectiveResume(sdkOptions);
|
|
2723
3328
|
const queryOptions = this.createQueryOptions(
|
|
2724
3329
|
abortController,
|
|
2725
|
-
options
|
|
3330
|
+
options,
|
|
2726
3331
|
stderrCollector,
|
|
2727
3332
|
sdkOptions,
|
|
2728
3333
|
effectiveResume
|
|
@@ -2734,7 +3339,11 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2734
3339
|
if (queryOptions.includePartialMessages === void 0) {
|
|
2735
3340
|
queryOptions.includePartialMessages = true;
|
|
2736
3341
|
}
|
|
2737
|
-
const warnings = this.generateAllWarnings(
|
|
3342
|
+
const warnings = this.generateAllWarnings(
|
|
3343
|
+
options,
|
|
3344
|
+
messagesPrompt,
|
|
3345
|
+
sdkOptions
|
|
3346
|
+
);
|
|
2738
3347
|
if (messageWarnings) {
|
|
2739
3348
|
messageWarnings.forEach((warning) => {
|
|
2740
3349
|
warnings.push({
|
|
@@ -2746,7 +3355,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2746
3355
|
const modeSetting = this.settings.streamingInput ?? "auto";
|
|
2747
3356
|
const effectiveCanUseTool = sdkOptions?.canUseTool ?? this.settings.canUseTool;
|
|
2748
3357
|
const effectivePermissionPromptToolName = sdkOptions?.permissionPromptToolName ?? this.settings.permissionPromptToolName;
|
|
2749
|
-
const wantsStreamInput = modeSetting === "always" || modeSetting === "auto" && !!effectiveCanUseTool;
|
|
3358
|
+
const wantsStreamInput = modeSetting === "always" || modeSetting === "auto" && (!!effectiveCanUseTool || hasImageParts);
|
|
2750
3359
|
if (!wantsStreamInput && hasImageParts) {
|
|
2751
3360
|
warnings.push({
|
|
2752
3361
|
type: "other",
|
|
@@ -2813,9 +3422,13 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2813
3422
|
apiRetries: 0,
|
|
2814
3423
|
permissionDenials: [],
|
|
2815
3424
|
mirrorErrors: [],
|
|
2816
|
-
estimatedThinkingTokens: 0
|
|
3425
|
+
estimatedThinkingTokens: 0,
|
|
3426
|
+
taskEvents: [],
|
|
3427
|
+
hookEvents: []
|
|
2817
3428
|
};
|
|
2818
3429
|
const toolBlocksByIndex = /* @__PURE__ */ new Map();
|
|
3430
|
+
const structuredOutputBlockIndexes = /* @__PURE__ */ new Set();
|
|
3431
|
+
const nonTextToolBlockIndexes = /* @__PURE__ */ new Set();
|
|
2819
3432
|
const toolInputAccumulators = /* @__PURE__ */ new Map();
|
|
2820
3433
|
const textBlocksByIndex = /* @__PURE__ */ new Map();
|
|
2821
3434
|
let textStreamedViaContentBlock = false;
|
|
@@ -2878,9 +3491,24 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2878
3491
|
prompt: sdkPrompt,
|
|
2879
3492
|
options: queryOptions
|
|
2880
3493
|
});
|
|
2881
|
-
this.
|
|
2882
|
-
|
|
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) {
|
|
2883
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
|
+
}
|
|
2884
3512
|
if (message.type === "stream_event") {
|
|
2885
3513
|
const streamEvent = message;
|
|
2886
3514
|
const event = streamEvent.event;
|
|
@@ -2912,7 +3540,8 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2912
3540
|
const jsonDelta = event.delta.partial_json;
|
|
2913
3541
|
hasReceivedStreamEvents = true;
|
|
2914
3542
|
const blockIndex = "index" in event ? event.index : -1;
|
|
2915
|
-
|
|
3543
|
+
const isStructuredOutputDelta = structuredOutputBlockIndexes.has(blockIndex) || !toolBlocksByIndex.has(blockIndex) && !nonTextToolBlockIndexes.has(blockIndex);
|
|
3544
|
+
if (options.responseFormat?.type === "json" && isStructuredOutputDelta) {
|
|
2916
3545
|
if (!textPartId) {
|
|
2917
3546
|
textPartId = generateId();
|
|
2918
3547
|
controller.enqueue({
|
|
@@ -2942,12 +3571,25 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2942
3571
|
continue;
|
|
2943
3572
|
}
|
|
2944
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
|
+
}
|
|
2945
3581
|
if (event.type === "content_block_start" && "content_block" in event && event.content_block?.type === "tool_use") {
|
|
2946
3582
|
const blockIndex = "index" in event ? event.index : -1;
|
|
2947
3583
|
const toolBlock = event.content_block;
|
|
2948
3584
|
const toolId = typeof toolBlock.id === "string" && toolBlock.id.length > 0 ? toolBlock.id : generateId();
|
|
2949
3585
|
const toolName = typeof toolBlock.name === "string" && toolBlock.name.length > 0 ? toolBlock.name : _ClaudeCodeLanguageModel.UNKNOWN_TOOL_NAME;
|
|
2950
3586
|
hasReceivedStreamEvents = true;
|
|
3587
|
+
nonTextToolBlockIndexes.delete(blockIndex);
|
|
3588
|
+
if (isInternalStructuredOutputTool(toolName, options)) {
|
|
3589
|
+
structuredOutputBlockIndexes.add(blockIndex);
|
|
3590
|
+
continue;
|
|
3591
|
+
}
|
|
3592
|
+
structuredOutputBlockIndexes.delete(blockIndex);
|
|
2951
3593
|
if (textPartId) {
|
|
2952
3594
|
const closedTextId = textPartId;
|
|
2953
3595
|
controller.enqueue({
|
|
@@ -3094,6 +3736,12 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
3094
3736
|
toolInputAccumulators.delete(toolId);
|
|
3095
3737
|
continue;
|
|
3096
3738
|
}
|
|
3739
|
+
if (structuredOutputBlockIndexes.delete(blockIndex)) {
|
|
3740
|
+
continue;
|
|
3741
|
+
}
|
|
3742
|
+
if (nonTextToolBlockIndexes.delete(blockIndex)) {
|
|
3743
|
+
continue;
|
|
3744
|
+
}
|
|
3097
3745
|
const textId = textBlocksByIndex.get(blockIndex);
|
|
3098
3746
|
if (textId) {
|
|
3099
3747
|
this.logger.debug(
|
|
@@ -3140,7 +3788,9 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
3140
3788
|
}
|
|
3141
3789
|
const sdkParentToolUseId = message.parent_tool_use_id;
|
|
3142
3790
|
const content = message.message.content;
|
|
3143
|
-
const tools = this.extractToolUses(content)
|
|
3791
|
+
const tools = this.extractToolUses(content).filter(
|
|
3792
|
+
(tool3) => !isInternalStructuredOutputTool(tool3.name, options)
|
|
3793
|
+
);
|
|
3144
3794
|
if (textPartId && tools.length > 0) {
|
|
3145
3795
|
const closedTextId = textPartId;
|
|
3146
3796
|
controller.enqueue({
|
|
@@ -3193,7 +3843,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
3193
3843
|
toolName: tool3.name,
|
|
3194
3844
|
providerExecuted: true,
|
|
3195
3845
|
dynamic: true,
|
|
3196
|
-
//
|
|
3846
|
+
// V4 field: indicates tool is provider-defined
|
|
3197
3847
|
providerMetadata: {
|
|
3198
3848
|
"claude-code": {
|
|
3199
3849
|
parentToolCallId: state.parentToolCallId ?? null
|
|
@@ -3398,7 +4048,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
3398
4048
|
toolName,
|
|
3399
4049
|
providerExecuted: true,
|
|
3400
4050
|
dynamic: true,
|
|
3401
|
-
//
|
|
4051
|
+
// V4 field: indicates tool is provider-defined
|
|
3402
4052
|
providerMetadata: {
|
|
3403
4053
|
"claude-code": {
|
|
3404
4054
|
parentToolCallId: state.parentToolCallId ?? null
|
|
@@ -3450,19 +4100,47 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
3450
4100
|
);
|
|
3451
4101
|
state = {
|
|
3452
4102
|
name: toolName,
|
|
3453
|
-
inputStarted:
|
|
3454
|
-
inputClosed:
|
|
4103
|
+
inputStarted: false,
|
|
4104
|
+
inputClosed: false,
|
|
3455
4105
|
callEmitted: false,
|
|
3456
4106
|
parentToolCallId: errorResolvedParentId
|
|
3457
4107
|
};
|
|
3458
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
|
+
}
|
|
3459
4132
|
}
|
|
3460
4133
|
emitToolCall(error.id, state);
|
|
3461
4134
|
if (isSubagentToolName(toolName)) {
|
|
3462
4135
|
activeTaskTools.delete(error.id);
|
|
3463
4136
|
}
|
|
3464
4137
|
controller.enqueue(
|
|
3465
|
-
this.
|
|
4138
|
+
this.buildErroredToolResultPart(
|
|
4139
|
+
error.id,
|
|
4140
|
+
toolName,
|
|
4141
|
+
error.error,
|
|
4142
|
+
state.parentToolCallId
|
|
4143
|
+
)
|
|
3466
4144
|
);
|
|
3467
4145
|
}
|
|
3468
4146
|
} else if (message.type === "result") {
|
|
@@ -3492,13 +4170,16 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
3492
4170
|
);
|
|
3493
4171
|
}
|
|
3494
4172
|
const stopReason = "stop_reason" in message ? message.stop_reason : void 0;
|
|
3495
|
-
|
|
4173
|
+
let finishReason = mapClaudeCodeFinishReason(
|
|
3496
4174
|
message.subtype,
|
|
3497
4175
|
stopReason
|
|
3498
4176
|
);
|
|
3499
|
-
this.logger.debug(`[claude-code] Stream finish reason: ${finishReason.unified}`);
|
|
3500
4177
|
this.setSessionId(message.session_id);
|
|
3501
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}`);
|
|
3502
4183
|
const alreadyStreamedJson = hasStreamedJson && options.responseFormat?.type === "json" && hasReceivedStreamEvents;
|
|
3503
4184
|
if (alreadyStreamedJson) {
|
|
3504
4185
|
if (textPartId) {
|
|
@@ -3612,6 +4293,15 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
3612
4293
|
...metadataTracking.permissionDenials.length > 0 && {
|
|
3613
4294
|
permissionDenials: metadataTracking.permissionDenials
|
|
3614
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
|
+
},
|
|
3615
4305
|
...metadataTracking.mirrorErrors.length > 0 && {
|
|
3616
4306
|
mirrorErrors: metadataTracking.mirrorErrors
|
|
3617
4307
|
},
|
|
@@ -3629,12 +4319,14 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
3629
4319
|
});
|
|
3630
4320
|
controller.close();
|
|
3631
4321
|
const effectivePromptSuggestions = sdkOptions?.promptSuggestions ?? this.settings.promptSuggestions;
|
|
3632
|
-
|
|
3633
|
-
|
|
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);
|
|
3634
4325
|
}
|
|
3635
4326
|
return;
|
|
3636
4327
|
} else if (message.type === "system" && message.subtype === "init") {
|
|
3637
4328
|
this.logMcpConnectionIssues(message.mcp_servers);
|
|
4329
|
+
this.trackMcpStatusFromInit(message, metadataTracking);
|
|
3638
4330
|
this.setSessionId(message.session_id);
|
|
3639
4331
|
this.logger.info(`[claude-code] Stream session initialized: ${message.session_id}`);
|
|
3640
4332
|
controller.enqueue({
|
|
@@ -3708,6 +4400,15 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
3708
4400
|
...metadataTracking.permissionDenials.length > 0 && {
|
|
3709
4401
|
permissionDenials: metadataTracking.permissionDenials
|
|
3710
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
|
+
},
|
|
3711
4412
|
...metadataTracking.mirrorErrors.length > 0 && {
|
|
3712
4413
|
mirrorErrors: metadataTracking.mirrorErrors
|
|
3713
4414
|
},
|
|
@@ -3755,19 +4456,23 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
3755
4456
|
};
|
|
3756
4457
|
}
|
|
3757
4458
|
serializeWarningsForMetadata(warnings) {
|
|
3758
|
-
const result = warnings.map((
|
|
3759
|
-
const base = { type:
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
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;
|
|
3771
4476
|
}
|
|
3772
4477
|
return base;
|
|
3773
4478
|
});
|
|
@@ -3810,7 +4515,7 @@ function createClaudeCode(options = {}) {
|
|
|
3810
4515
|
};
|
|
3811
4516
|
provider.languageModel = createModel;
|
|
3812
4517
|
provider.chat = createModel;
|
|
3813
|
-
provider.specificationVersion = "
|
|
4518
|
+
provider.specificationVersion = "v4";
|
|
3814
4519
|
provider.embeddingModel = (modelId) => {
|
|
3815
4520
|
throw new NoSuchModelError2({
|
|
3816
4521
|
modelId,
|
|
@@ -3834,7 +4539,9 @@ import {
|
|
|
3834
4539
|
SYSTEM_PROMPT_DYNAMIC_BOUNDARY,
|
|
3835
4540
|
InMemorySessionStore,
|
|
3836
4541
|
HOOK_EVENTS,
|
|
3837
|
-
AbortError
|
|
4542
|
+
AbortError,
|
|
4543
|
+
resolveSettings,
|
|
4544
|
+
filterEscalatingDefaultMode
|
|
3838
4545
|
} from "@anthropic-ai/claude-agent-sdk";
|
|
3839
4546
|
import {
|
|
3840
4547
|
listSessions,
|
|
@@ -3854,6 +4561,16 @@ import { startup } from "@anthropic-ai/claude-agent-sdk";
|
|
|
3854
4561
|
// src/mcp-helpers.ts
|
|
3855
4562
|
import { createSdkMcpServer, tool } from "@anthropic-ai/claude-agent-sdk";
|
|
3856
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
|
+
}
|
|
3857
4574
|
function buildIsErrorResult(text) {
|
|
3858
4575
|
return {
|
|
3859
4576
|
isError: true,
|
|
@@ -3896,7 +4613,11 @@ function createCustomMcpServer(config) {
|
|
|
3896
4613
|
}
|
|
3897
4614
|
var AI_SDK_SCHEMA_SYMBOL = Symbol.for("vercel.ai.schema");
|
|
3898
4615
|
function isAiSdkJsonSchema(schema) {
|
|
3899
|
-
|
|
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;
|
|
3900
4621
|
}
|
|
3901
4622
|
function isZodObjectSchema(schema) {
|
|
3902
4623
|
if (typeof schema !== "object" || schema === null) {
|
|
@@ -3931,9 +4652,13 @@ function createAiSdkMcpServer(name, tools) {
|
|
|
3931
4652
|
);
|
|
3932
4653
|
}
|
|
3933
4654
|
const zodSchema = def.inputSchema;
|
|
4655
|
+
const description = typeof def.description === "string" ? def.description : "";
|
|
4656
|
+
if (typeof def.description === "function") {
|
|
4657
|
+
warnDiscardedDescriptionFunction(toolName);
|
|
4658
|
+
}
|
|
3934
4659
|
return tool(
|
|
3935
4660
|
toolName,
|
|
3936
|
-
|
|
4661
|
+
description,
|
|
3937
4662
|
zodSchema.shape,
|
|
3938
4663
|
async (args, extra) => {
|
|
3939
4664
|
try {
|
|
@@ -3966,10 +4691,12 @@ export {
|
|
|
3966
4691
|
createAiSdkMcpServer,
|
|
3967
4692
|
createAuthenticationError,
|
|
3968
4693
|
createClaudeCode,
|
|
4694
|
+
createClaudeCodeQueryController,
|
|
3969
4695
|
createCustomMcpServer,
|
|
3970
4696
|
createSdkMcpServer2 as createSdkMcpServer,
|
|
3971
4697
|
createTimeoutError,
|
|
3972
4698
|
deleteSession,
|
|
4699
|
+
filterEscalatingDefaultMode,
|
|
3973
4700
|
foldSessionSummary,
|
|
3974
4701
|
forkSession,
|
|
3975
4702
|
getErrorMetadata,
|
|
@@ -3982,6 +4709,7 @@ export {
|
|
|
3982
4709
|
listSessions,
|
|
3983
4710
|
listSubagents,
|
|
3984
4711
|
renameSession,
|
|
4712
|
+
resolveSettings,
|
|
3985
4713
|
startup,
|
|
3986
4714
|
tagSession,
|
|
3987
4715
|
tool2 as tool
|