ai-sdk-provider-claude-code 3.5.3 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +228 -124
- 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 -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/");
|
|
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");
|
|
@@ -561,6 +727,18 @@ var claudeCodeSettingsSchema = z.object({
|
|
|
561
727
|
forwardSubagentText: z.boolean().optional(),
|
|
562
728
|
agentProgressSummaries: z.boolean().optional(),
|
|
563
729
|
includeHookEvents: z.boolean().optional(),
|
|
730
|
+
onSdkMessage: z.any().refine((v) => v === void 0 || typeof v === "function", {
|
|
731
|
+
message: "onSdkMessage must be a function"
|
|
732
|
+
}).optional(),
|
|
733
|
+
onTaskEvent: z.any().refine((v) => v === void 0 || typeof v === "function", {
|
|
734
|
+
message: "onTaskEvent must be a function"
|
|
735
|
+
}).optional(),
|
|
736
|
+
onHookEvent: z.any().refine((v) => v === void 0 || typeof v === "function", {
|
|
737
|
+
message: "onHookEvent must be a function"
|
|
738
|
+
}).optional(),
|
|
739
|
+
onMcpStatusChange: z.any().refine((v) => v === void 0 || typeof v === "function", {
|
|
740
|
+
message: "onMcpStatusChange must be a function"
|
|
741
|
+
}).optional(),
|
|
564
742
|
taskBudget: z.object({ total: z.number().positive() }).strict().optional(),
|
|
565
743
|
sessionStore: z.any().refine(
|
|
566
744
|
(val) => val === void 0 || typeof val === "object" && val !== null && typeof val.append === "function" && typeof val.load === "function",
|
|
@@ -577,6 +755,9 @@ var claudeCodeSettingsSchema = z.object({
|
|
|
577
755
|
onUserDialog: z.any().refine((v) => v === void 0 || typeof v === "function", {
|
|
578
756
|
message: "onUserDialog must be a function"
|
|
579
757
|
}).optional(),
|
|
758
|
+
onElicitation: z.any().refine((v) => v === void 0 || typeof v === "function", {
|
|
759
|
+
message: "onElicitation must be a function"
|
|
760
|
+
}).optional(),
|
|
580
761
|
supportedDialogKinds: z.array(z.string()).optional(),
|
|
581
762
|
hooks: z.record(
|
|
582
763
|
z.string(),
|
|
@@ -623,6 +804,7 @@ var claudeCodeSettingsSchema = z.object({
|
|
|
623
804
|
logger: z.union([z.literal(false), loggerFunctionSchema]).optional(),
|
|
624
805
|
env: z.record(z.string(), z.string().optional()).optional(),
|
|
625
806
|
additionalDirectories: z.array(z.string()).optional(),
|
|
807
|
+
agent: z.string().optional(),
|
|
626
808
|
agents: z.record(
|
|
627
809
|
z.string(),
|
|
628
810
|
z.object({
|
|
@@ -660,10 +842,13 @@ var claudeCodeSettingsSchema = z.object({
|
|
|
660
842
|
onQueryCreated: z.any().refine((val) => val === void 0 || typeof val === "function", {
|
|
661
843
|
message: "onQueryCreated must be a function"
|
|
662
844
|
}).optional(),
|
|
845
|
+
onQueryControllerCreated: z.any().refine((val) => val === void 0 || typeof val === "function", {
|
|
846
|
+
message: "onQueryControllerCreated must be a function"
|
|
847
|
+
}).optional(),
|
|
663
848
|
onStreamStart: z.any().refine((val) => val === void 0 || typeof val === "function", {
|
|
664
849
|
message: "onStreamStart must be a function"
|
|
665
850
|
}).optional(),
|
|
666
|
-
// Callback invoked with the predicted next user prompt (
|
|
851
|
+
// Callback invoked with the predicted next user prompt (requires promptSuggestions: true)
|
|
667
852
|
onPromptSuggestion: z.any().refine((val) => val === void 0 || typeof val === "function", {
|
|
668
853
|
message: "onPromptSuggestion must be a function"
|
|
669
854
|
}).optional()
|
|
@@ -748,6 +933,11 @@ function validateSettings(settings) {
|
|
|
748
933
|
`Very high maxThinkingTokens (${validSettings.maxThinkingTokens}) may increase response time`
|
|
749
934
|
);
|
|
750
935
|
}
|
|
936
|
+
if (validSettings.onPromptSuggestion !== void 0 && effective("promptSuggestions") !== true) {
|
|
937
|
+
warnings.push(
|
|
938
|
+
"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."
|
|
939
|
+
);
|
|
940
|
+
}
|
|
751
941
|
if (validSettings.allowedTools && validSettings.disallowedTools) {
|
|
752
942
|
warnings.push(
|
|
753
943
|
"Both allowedTools and disallowedTools are specified. Only allowedTools will be used."
|
|
@@ -985,9 +1175,38 @@ function createVerboseLogger(logger, verbose = false) {
|
|
|
985
1175
|
};
|
|
986
1176
|
}
|
|
987
1177
|
|
|
1178
|
+
// src/query-controller.ts
|
|
1179
|
+
function createClaudeCodeQueryController(query2) {
|
|
1180
|
+
const controller = {
|
|
1181
|
+
rawQuery: query2,
|
|
1182
|
+
// SDK 0.3.205 returns the control-protocol response; the public contract stays Promise<void>.
|
|
1183
|
+
interrupt: async () => {
|
|
1184
|
+
await query2.interrupt();
|
|
1185
|
+
},
|
|
1186
|
+
setPermissionMode: (mode) => query2.setPermissionMode(mode),
|
|
1187
|
+
setMcpPermissionModeOverride: (serverName, mode) => query2.setMcpPermissionModeOverride(serverName, mode),
|
|
1188
|
+
setModel: (model) => query2.setModel(model),
|
|
1189
|
+
setMaxThinkingTokens: (maxThinkingTokens, thinkingDisplay) => query2.setMaxThinkingTokens(maxThinkingTokens, thinkingDisplay),
|
|
1190
|
+
applyFlagSettings: (settings) => query2.applyFlagSettings(settings),
|
|
1191
|
+
mcpServerStatus: () => query2.mcpServerStatus(),
|
|
1192
|
+
reconnectMcpServer: (serverName) => query2.reconnectMcpServer(serverName),
|
|
1193
|
+
toggleMcpServer: (serverName, enabled) => query2.toggleMcpServer(serverName, enabled),
|
|
1194
|
+
setMcpServers: (servers) => query2.setMcpServers(servers),
|
|
1195
|
+
getContextUsage: () => query2.getContextUsage(),
|
|
1196
|
+
rewindFiles: (userMessageId, options) => query2.rewindFiles(userMessageId, options),
|
|
1197
|
+
stopTask: (taskId) => query2.stopTask(taskId),
|
|
1198
|
+
backgroundTasks: (toolUseId) => toolUseId === void 0 ? query2.backgroundTasks() : query2.backgroundTasks(toolUseId)
|
|
1199
|
+
};
|
|
1200
|
+
const streamInput = query2.streamInput;
|
|
1201
|
+
if (typeof streamInput === "function") {
|
|
1202
|
+
controller.streamInput = (stream) => streamInput.call(query2, stream);
|
|
1203
|
+
}
|
|
1204
|
+
return controller;
|
|
1205
|
+
}
|
|
1206
|
+
|
|
988
1207
|
// src/claude-code-language-model.ts
|
|
989
1208
|
import { query } from "@anthropic-ai/claude-agent-sdk";
|
|
990
|
-
var PROVIDER_VERSION = "
|
|
1209
|
+
var PROVIDER_VERSION = "4.0.1";
|
|
991
1210
|
var DEFAULT_CLIENT_APP = `ai-sdk-provider-claude-code/${PROVIDER_VERSION}`;
|
|
992
1211
|
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
1212
|
var MIN_TRUNCATION_LENGTH = 512;
|
|
@@ -1027,6 +1246,13 @@ function isClaudeCodeTruncationError(error, bufferedText) {
|
|
|
1027
1246
|
return true;
|
|
1028
1247
|
}
|
|
1029
1248
|
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.";
|
|
1249
|
+
var INTERNAL_STRUCTURED_OUTPUT_TOOL_NAME = "StructuredOutput";
|
|
1250
|
+
function isInternalStructuredOutputTool(toolName, options) {
|
|
1251
|
+
return options.responseFormat?.type === "json" && toolName === INTERNAL_STRUCTURED_OUTPUT_TOOL_NAME;
|
|
1252
|
+
}
|
|
1253
|
+
function isNonTextToolUseContentBlockType(type) {
|
|
1254
|
+
return type === "server_tool_use" || type === "mcp_tool_use";
|
|
1255
|
+
}
|
|
1030
1256
|
function extractJsonObjectText(text) {
|
|
1031
1257
|
const trimmed = text.trim();
|
|
1032
1258
|
if (!trimmed) {
|
|
@@ -1120,7 +1346,7 @@ function getBaseProcessEnv() {
|
|
|
1120
1346
|
}
|
|
1121
1347
|
return env;
|
|
1122
1348
|
}
|
|
1123
|
-
var STREAMING_FEATURE_WARNING = "Claude Agent SDK
|
|
1349
|
+
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
1350
|
var SDK_OPTIONS_BLOCKLIST = /* @__PURE__ */ new Set(["model", "abortController", "prompt", "outputFormat"]);
|
|
1125
1351
|
var SUBAGENT_TOOL_NAMES = /* @__PURE__ */ new Set(["Task", "Agent"]);
|
|
1126
1352
|
function isSubagentToolName(name) {
|
|
@@ -1143,7 +1369,7 @@ function computeRetractedToolCallIds(retracted, descriptors) {
|
|
|
1143
1369
|
function applySupersede(message, evict, logger, guard = "array") {
|
|
1144
1370
|
const supersedes = message.supersedes;
|
|
1145
1371
|
const triggered = guard === "truthy" ? Boolean(supersedes && supersedes.length > 0) : Array.isArray(supersedes) && supersedes.length > 0;
|
|
1146
|
-
if (!triggered) {
|
|
1372
|
+
if (!triggered || supersedes === void 0) {
|
|
1147
1373
|
return false;
|
|
1148
1374
|
}
|
|
1149
1375
|
logger.debug(`[claude-code] Assistant message supersedes ${supersedes.length} prior message(s)`);
|
|
@@ -1156,12 +1382,126 @@ function buildRetractionEvictor(evict) {
|
|
|
1156
1382
|
var INFORMATIONAL_SYSTEM_SUBTYPES = /* @__PURE__ */ new Set([
|
|
1157
1383
|
"notification",
|
|
1158
1384
|
"status",
|
|
1159
|
-
"task_updated",
|
|
1160
1385
|
"session_state_changed",
|
|
1161
1386
|
"commands_changed",
|
|
1162
1387
|
"memory_recall",
|
|
1163
|
-
"plugin_install"
|
|
1388
|
+
"plugin_install",
|
|
1389
|
+
"informational"
|
|
1164
1390
|
]);
|
|
1391
|
+
var CLAUDE_REASONING_EFFORT_MAP = {
|
|
1392
|
+
minimal: "low",
|
|
1393
|
+
low: "low",
|
|
1394
|
+
medium: "medium",
|
|
1395
|
+
high: "high",
|
|
1396
|
+
xhigh: "xhigh"
|
|
1397
|
+
};
|
|
1398
|
+
var CLAUDE_EFFORT_LEVELS = /* @__PURE__ */ new Set(["low", "medium", "high", "xhigh", "max"]);
|
|
1399
|
+
function isObjectRecord(value) {
|
|
1400
|
+
return typeof value === "object" && value !== null;
|
|
1401
|
+
}
|
|
1402
|
+
function toJsonSafeValue(value) {
|
|
1403
|
+
if (value === void 0) {
|
|
1404
|
+
return void 0;
|
|
1405
|
+
}
|
|
1406
|
+
try {
|
|
1407
|
+
const serialized = JSON.stringify(value);
|
|
1408
|
+
return serialized === void 0 ? void 0 : JSON.parse(serialized);
|
|
1409
|
+
} catch {
|
|
1410
|
+
return String(value);
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
function deepFreezeJsonValue(value) {
|
|
1414
|
+
if (Array.isArray(value)) {
|
|
1415
|
+
for (const nested of value) {
|
|
1416
|
+
deepFreezeJsonValue(nested);
|
|
1417
|
+
}
|
|
1418
|
+
return Object.freeze(value);
|
|
1419
|
+
}
|
|
1420
|
+
if (!isObjectRecord(value)) {
|
|
1421
|
+
return value;
|
|
1422
|
+
}
|
|
1423
|
+
const objectValue = value;
|
|
1424
|
+
for (const nested of Object.values(objectValue)) {
|
|
1425
|
+
if (nested !== void 0) {
|
|
1426
|
+
deepFreezeJsonValue(nested);
|
|
1427
|
+
}
|
|
1428
|
+
}
|
|
1429
|
+
return Object.freeze(objectValue);
|
|
1430
|
+
}
|
|
1431
|
+
function toJsonSafeClone(value) {
|
|
1432
|
+
const clone = toJsonSafeValue(value);
|
|
1433
|
+
if (clone === void 0) {
|
|
1434
|
+
return void 0;
|
|
1435
|
+
}
|
|
1436
|
+
return clone;
|
|
1437
|
+
}
|
|
1438
|
+
function toImmutableJsonSafeClone(value) {
|
|
1439
|
+
const clone = toJsonSafeValue(value);
|
|
1440
|
+
if (clone === void 0) {
|
|
1441
|
+
return void 0;
|
|
1442
|
+
}
|
|
1443
|
+
return deepFreezeJsonValue(clone);
|
|
1444
|
+
}
|
|
1445
|
+
function hasValidThinkingDisplay(value) {
|
|
1446
|
+
return value === void 0 || value === "summarized" || value === "omitted";
|
|
1447
|
+
}
|
|
1448
|
+
function isClaudeEffortLevel(value) {
|
|
1449
|
+
return typeof value === "string" && CLAUDE_EFFORT_LEVELS.has(value);
|
|
1450
|
+
}
|
|
1451
|
+
function isClaudeThinkingConfig(value) {
|
|
1452
|
+
if (!isObjectRecord(value)) {
|
|
1453
|
+
return false;
|
|
1454
|
+
}
|
|
1455
|
+
if (value.type === "disabled") {
|
|
1456
|
+
return true;
|
|
1457
|
+
}
|
|
1458
|
+
if (value.type === "adaptive") {
|
|
1459
|
+
return hasValidThinkingDisplay(value.display);
|
|
1460
|
+
}
|
|
1461
|
+
if (value.type === "enabled") {
|
|
1462
|
+
const budgetTokens = value.budgetTokens;
|
|
1463
|
+
return (budgetTokens === void 0 || typeof budgetTokens === "number") && hasValidThinkingDisplay(value.display);
|
|
1464
|
+
}
|
|
1465
|
+
return false;
|
|
1466
|
+
}
|
|
1467
|
+
function addInvalidClaudeReasoningProviderOptionWarning(warnings, key) {
|
|
1468
|
+
warnings?.push({
|
|
1469
|
+
type: "other",
|
|
1470
|
+
message: `Invalid providerOptions['claude-code'].${key} value was ignored.`
|
|
1471
|
+
});
|
|
1472
|
+
}
|
|
1473
|
+
function extractClaudeReasoningProviderOptions(providerOptions, warnings) {
|
|
1474
|
+
const options = providerOptions?.["claude-code"];
|
|
1475
|
+
if (options === void 0) {
|
|
1476
|
+
return { hasClaudeReasoningSettings: false };
|
|
1477
|
+
}
|
|
1478
|
+
const result = { hasClaudeReasoningSettings: false };
|
|
1479
|
+
if (options.thinking !== void 0) {
|
|
1480
|
+
if (isClaudeThinkingConfig(options.thinking)) {
|
|
1481
|
+
result.thinking = options.thinking;
|
|
1482
|
+
result.hasClaudeReasoningSettings = true;
|
|
1483
|
+
} else {
|
|
1484
|
+
addInvalidClaudeReasoningProviderOptionWarning(warnings, "thinking");
|
|
1485
|
+
}
|
|
1486
|
+
}
|
|
1487
|
+
if (options.effort !== void 0) {
|
|
1488
|
+
if (isClaudeEffortLevel(options.effort)) {
|
|
1489
|
+
result.effort = options.effort;
|
|
1490
|
+
result.hasClaudeReasoningSettings = true;
|
|
1491
|
+
} else {
|
|
1492
|
+
addInvalidClaudeReasoningProviderOptionWarning(warnings, "effort");
|
|
1493
|
+
}
|
|
1494
|
+
}
|
|
1495
|
+
if (options.maxThinkingTokens !== void 0) {
|
|
1496
|
+
if (typeof options.maxThinkingTokens === "number") {
|
|
1497
|
+
result.maxThinkingTokens = options.maxThinkingTokens;
|
|
1498
|
+
result.hasClaudeReasoningSettings = true;
|
|
1499
|
+
} else {
|
|
1500
|
+
addInvalidClaudeReasoningProviderOptionWarning(warnings, "maxThinkingTokens");
|
|
1501
|
+
}
|
|
1502
|
+
}
|
|
1503
|
+
return result;
|
|
1504
|
+
}
|
|
1165
1505
|
function isContentBlock(item) {
|
|
1166
1506
|
return typeof item === "object" && item !== null && "type" in item;
|
|
1167
1507
|
}
|
|
@@ -1322,6 +1662,7 @@ function toAsyncIterablePrompt(messagesPrompt, outputStreamEnded, sessionId, con
|
|
|
1322
1662
|
};
|
|
1323
1663
|
}
|
|
1324
1664
|
var modelMap = {
|
|
1665
|
+
fable: "fable",
|
|
1325
1666
|
opus: "opus",
|
|
1326
1667
|
sonnet: "sonnet",
|
|
1327
1668
|
haiku: "haiku"
|
|
@@ -1370,7 +1711,7 @@ function truncateToolResultForStream(result, maxSize = MAX_TOOL_RESULT_SIZE) {
|
|
|
1370
1711
|
return result;
|
|
1371
1712
|
}
|
|
1372
1713
|
var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
1373
|
-
specificationVersion = "
|
|
1714
|
+
specificationVersion = "v4";
|
|
1374
1715
|
defaultObjectGenerationMode = "json";
|
|
1375
1716
|
supportsImageUrls = false;
|
|
1376
1717
|
supportedUrls = {};
|
|
@@ -1441,6 +1782,81 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1441
1782
|
}
|
|
1442
1783
|
return void 0;
|
|
1443
1784
|
}
|
|
1785
|
+
invokeObservabilityCallback(callbackName, callback, value) {
|
|
1786
|
+
if (!callback) {
|
|
1787
|
+
return;
|
|
1788
|
+
}
|
|
1789
|
+
const logError = (error) => {
|
|
1790
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
1791
|
+
this.logger.warn(`[claude-code] ${callbackName} callback failed; ignoring error: ${message}`);
|
|
1792
|
+
if (error instanceof Error && error.stack) {
|
|
1793
|
+
this.logger.debug(`[claude-code] ${callbackName} callback stack: ${error.stack}`);
|
|
1794
|
+
}
|
|
1795
|
+
};
|
|
1796
|
+
try {
|
|
1797
|
+
const result = callback(value);
|
|
1798
|
+
if (result && typeof result.then === "function") {
|
|
1799
|
+
void Promise.resolve(result).catch(logError);
|
|
1800
|
+
}
|
|
1801
|
+
} catch (error) {
|
|
1802
|
+
logError(error);
|
|
1803
|
+
}
|
|
1804
|
+
}
|
|
1805
|
+
invokeSdkMessageCallback(message) {
|
|
1806
|
+
const onSdkMessage = this.settings.onSdkMessage;
|
|
1807
|
+
if (onSdkMessage === void 0) {
|
|
1808
|
+
return;
|
|
1809
|
+
}
|
|
1810
|
+
this.invokeObservabilityCallback(
|
|
1811
|
+
"onSdkMessage",
|
|
1812
|
+
onSdkMessage,
|
|
1813
|
+
toImmutableJsonSafeClone(message)
|
|
1814
|
+
);
|
|
1815
|
+
}
|
|
1816
|
+
notifyQueryCreated(response) {
|
|
1817
|
+
this.settings.onQueryCreated?.(response);
|
|
1818
|
+
const onQueryControllerCreated = this.settings.onQueryControllerCreated;
|
|
1819
|
+
if (onQueryControllerCreated !== void 0) {
|
|
1820
|
+
this.invokeObservabilityCallback(
|
|
1821
|
+
"onQueryControllerCreated",
|
|
1822
|
+
onQueryControllerCreated,
|
|
1823
|
+
createClaudeCodeQueryController(response)
|
|
1824
|
+
);
|
|
1825
|
+
}
|
|
1826
|
+
}
|
|
1827
|
+
trackTaskEvent(event, tracking) {
|
|
1828
|
+
tracking.taskEvents.push(toJsonSafeClone(event));
|
|
1829
|
+
const onTaskEvent = this.settings.onTaskEvent;
|
|
1830
|
+
if (onTaskEvent !== void 0) {
|
|
1831
|
+
this.invokeObservabilityCallback("onTaskEvent", onTaskEvent, toImmutableJsonSafeClone(event));
|
|
1832
|
+
}
|
|
1833
|
+
}
|
|
1834
|
+
trackHookEvent(event, tracking) {
|
|
1835
|
+
tracking.hookEvents.push(toJsonSafeClone(event));
|
|
1836
|
+
const onHookEvent = this.settings.onHookEvent;
|
|
1837
|
+
if (onHookEvent !== void 0) {
|
|
1838
|
+
this.invokeObservabilityCallback("onHookEvent", onHookEvent, toImmutableJsonSafeClone(event));
|
|
1839
|
+
}
|
|
1840
|
+
}
|
|
1841
|
+
trackMcpStatusFromInit(message, tracking) {
|
|
1842
|
+
const servers = message.mcp_servers;
|
|
1843
|
+
tracking.mcpServers = toJsonSafeClone(servers);
|
|
1844
|
+
const statusEvent = {
|
|
1845
|
+
subtype: "init",
|
|
1846
|
+
sessionId: message.session_id,
|
|
1847
|
+
uuid: message.uuid,
|
|
1848
|
+
servers,
|
|
1849
|
+
raw: message
|
|
1850
|
+
};
|
|
1851
|
+
const onMcpStatusChange = this.settings.onMcpStatusChange;
|
|
1852
|
+
if (onMcpStatusChange !== void 0) {
|
|
1853
|
+
this.invokeObservabilityCallback(
|
|
1854
|
+
"onMcpStatusChange",
|
|
1855
|
+
onMcpStatusChange,
|
|
1856
|
+
toImmutableJsonSafeClone(statusEvent)
|
|
1857
|
+
);
|
|
1858
|
+
}
|
|
1859
|
+
}
|
|
1444
1860
|
/**
|
|
1445
1861
|
* Single source of truth for the CLI's `--session-id` exclusivity rule.
|
|
1446
1862
|
*
|
|
@@ -1605,7 +2021,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1605
2021
|
input,
|
|
1606
2022
|
providerExecuted: true,
|
|
1607
2023
|
dynamic: true,
|
|
1608
|
-
//
|
|
2024
|
+
// V4 field: indicates tool is provider-defined (not in user's tools map)
|
|
1609
2025
|
providerMetadata: {
|
|
1610
2026
|
"claude-code": {
|
|
1611
2027
|
// rawInput preserves the original serialized format before AI SDK normalization.
|
|
@@ -1645,12 +2061,11 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1645
2061
|
toolName,
|
|
1646
2062
|
// `?? ''`: absent `content` (undefined) and string results that
|
|
1647
2063
|
// normalize to JSON null (e.g. the string "null") must not violate the
|
|
1648
|
-
// NonNullable<JSONValue> contract of
|
|
2064
|
+
// NonNullable<JSONValue> contract of LanguageModelV4ToolResult.result.
|
|
1649
2065
|
result: truncatedResult ?? "",
|
|
1650
2066
|
isError,
|
|
1651
|
-
providerExecuted: true,
|
|
1652
2067
|
dynamic: true,
|
|
1653
|
-
//
|
|
2068
|
+
// V4 field: indicates tool is provider-defined
|
|
1654
2069
|
providerMetadata: {
|
|
1655
2070
|
"claude-code": {
|
|
1656
2071
|
// rawResult preserves the original CLI output string before JSON parsing.
|
|
@@ -1673,37 +2088,12 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1673
2088
|
})() : String(error);
|
|
1674
2089
|
}
|
|
1675
2090
|
/**
|
|
1676
|
-
* Builds a provider
|
|
1677
|
-
* `tool_error` block
|
|
1678
|
-
*
|
|
2091
|
+
* Builds a V4 provider `tool-result` part with `isError: true` from a
|
|
2092
|
+
* user-message `tool_error` block. V4 has no provider-level `tool-error`
|
|
2093
|
+
* content or stream part; AI SDK core derives user-facing tool-error
|
|
2094
|
+
* semantics from this result while preserving providerMetadata.
|
|
1679
2095
|
*/
|
|
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) {
|
|
2096
|
+
buildErroredToolResultPart(toolCallId, toolName, error, parentToolCallId) {
|
|
1707
2097
|
const rawError = this.serializeToolError(error);
|
|
1708
2098
|
return {
|
|
1709
2099
|
type: "tool-result",
|
|
@@ -1711,9 +2101,8 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1711
2101
|
toolName,
|
|
1712
2102
|
result: rawError,
|
|
1713
2103
|
isError: true,
|
|
1714
|
-
providerExecuted: true,
|
|
1715
2104
|
dynamic: true,
|
|
1716
|
-
//
|
|
2105
|
+
// V4 field: indicates tool is provider-defined
|
|
1717
2106
|
providerMetadata: {
|
|
1718
2107
|
"claude-code": {
|
|
1719
2108
|
rawError,
|
|
@@ -1739,7 +2128,33 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1739
2128
|
);
|
|
1740
2129
|
return true;
|
|
1741
2130
|
}
|
|
1742
|
-
|
|
2131
|
+
resolvePortableReasoningOptions(options, sdkOptions, claudeProviderOptions, warnings) {
|
|
2132
|
+
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;
|
|
2133
|
+
if (hasClaudeSpecificReasoning || !isCustomReasoning(options.reasoning)) {
|
|
2134
|
+
return {};
|
|
2135
|
+
}
|
|
2136
|
+
if (options.reasoning === "none") {
|
|
2137
|
+
return { thinking: { type: "disabled" } };
|
|
2138
|
+
}
|
|
2139
|
+
const effort = mapReasoningToProviderEffort({
|
|
2140
|
+
reasoning: options.reasoning,
|
|
2141
|
+
effortMap: CLAUDE_REASONING_EFFORT_MAP,
|
|
2142
|
+
warnings: warnings ?? []
|
|
2143
|
+
});
|
|
2144
|
+
return effort === void 0 ? {} : { effort };
|
|
2145
|
+
}
|
|
2146
|
+
applyClaudeReasoningProviderOptions(opts, claudeProviderOptions) {
|
|
2147
|
+
if (claudeProviderOptions.thinking !== void 0) {
|
|
2148
|
+
opts.thinking = claudeProviderOptions.thinking;
|
|
2149
|
+
}
|
|
2150
|
+
if (claudeProviderOptions.effort !== void 0) {
|
|
2151
|
+
opts.effort = claudeProviderOptions.effort;
|
|
2152
|
+
}
|
|
2153
|
+
if (claudeProviderOptions.maxThinkingTokens !== void 0) {
|
|
2154
|
+
opts.maxThinkingTokens = claudeProviderOptions.maxThinkingTokens;
|
|
2155
|
+
}
|
|
2156
|
+
}
|
|
2157
|
+
generateAllWarnings(options, prompt, sdkOptions) {
|
|
1743
2158
|
const warnings = [];
|
|
1744
2159
|
const unsupportedParams = [];
|
|
1745
2160
|
if (options.temperature !== void 0) unsupportedParams.push("temperature");
|
|
@@ -1806,9 +2221,18 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1806
2221
|
message: promptWarning
|
|
1807
2222
|
});
|
|
1808
2223
|
}
|
|
2224
|
+
this.resolvePortableReasoningOptions(
|
|
2225
|
+
options,
|
|
2226
|
+
sdkOptions,
|
|
2227
|
+
extractClaudeReasoningProviderOptions(options.providerOptions, warnings),
|
|
2228
|
+
warnings
|
|
2229
|
+
);
|
|
1809
2230
|
return warnings;
|
|
1810
2231
|
}
|
|
1811
|
-
createQueryOptions(abortController,
|
|
2232
|
+
createQueryOptions(abortController, options, stderrCollector, sdkOptions, effectiveResume) {
|
|
2233
|
+
const claudeReasoningProviderOptions = extractClaudeReasoningProviderOptions(
|
|
2234
|
+
options.providerOptions
|
|
2235
|
+
);
|
|
1812
2236
|
const opts = {
|
|
1813
2237
|
model: this.getModel(),
|
|
1814
2238
|
abortController,
|
|
@@ -1836,8 +2260,14 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1836
2260
|
sandbox: this.settings.sandbox,
|
|
1837
2261
|
tools: this.settings.tools,
|
|
1838
2262
|
mcpServers: this.settings.mcpServers,
|
|
1839
|
-
canUseTool: this.settings.canUseTool
|
|
2263
|
+
canUseTool: this.settings.canUseTool,
|
|
2264
|
+
onElicitation: this.settings.onElicitation,
|
|
2265
|
+
agent: this.settings.agent
|
|
1840
2266
|
};
|
|
2267
|
+
Object.assign(
|
|
2268
|
+
opts,
|
|
2269
|
+
this.resolvePortableReasoningOptions(options, sdkOptions, claudeReasoningProviderOptions)
|
|
2270
|
+
);
|
|
1841
2271
|
if (this.settings.onUserDialog !== void 0) {
|
|
1842
2272
|
opts.onUserDialog = this.settings.onUserDialog;
|
|
1843
2273
|
}
|
|
@@ -1966,6 +2396,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1966
2396
|
}
|
|
1967
2397
|
}
|
|
1968
2398
|
}
|
|
2399
|
+
this.applyClaudeReasoningProviderOptions(opts, claudeReasoningProviderOptions);
|
|
1969
2400
|
this.applySessionResolution(opts, effectiveResume);
|
|
1970
2401
|
if (typeof opts.fallbackModel === "string" && opts.fallbackModel === opts.model) {
|
|
1971
2402
|
throw new Error(
|
|
@@ -1988,9 +2419,9 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1988
2419
|
mergedEnv.CLAUDE_AGENT_SDK_CLIENT_APP = DEFAULT_CLIENT_APP;
|
|
1989
2420
|
}
|
|
1990
2421
|
opts.env = mergedEnv;
|
|
1991
|
-
if (responseFormat?.type === "json" && responseFormat.schema) {
|
|
2422
|
+
if (options.responseFormat?.type === "json" && options.responseFormat.schema) {
|
|
1992
2423
|
const { schema: sanitizedSchema, strippedFormatPaths } = sanitizeJsonSchemaForOutputFormat(
|
|
1993
|
-
responseFormat.schema
|
|
2424
|
+
options.responseFormat.schema
|
|
1994
2425
|
);
|
|
1995
2426
|
if (strippedFormatPaths.length > 0) {
|
|
1996
2427
|
this.logger.debug(
|
|
@@ -2087,7 +2518,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2087
2518
|
if (errorKind === "model_not_found" || errorMessage.includes("model_not_found") || errorMessage.includes("no such model")) {
|
|
2088
2519
|
const originalMessage = isErrorWithMessage(error) && error.message ? error.message : "Model not found";
|
|
2089
2520
|
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.`,
|
|
2521
|
+
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
2522
|
code: errorCode || void 0,
|
|
2092
2523
|
exitCode,
|
|
2093
2524
|
stderr,
|
|
@@ -2157,16 +2588,159 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2157
2588
|
break;
|
|
2158
2589
|
case "permission_denied": {
|
|
2159
2590
|
const reason = message.decision_reason ?? message.message;
|
|
2591
|
+
const raw = toJsonSafeValue(message);
|
|
2160
2592
|
tracking.permissionDenials.push({
|
|
2161
2593
|
toolName: message.tool_name,
|
|
2162
2594
|
toolUseId: message.tool_use_id,
|
|
2163
|
-
...
|
|
2595
|
+
...message.agent_id !== void 0 && { agentId: message.agent_id },
|
|
2596
|
+
...message.decision_reason_type !== void 0 && {
|
|
2597
|
+
decisionReasonType: message.decision_reason_type
|
|
2598
|
+
},
|
|
2599
|
+
...reason !== void 0 && { reason },
|
|
2600
|
+
...raw !== void 0 && { raw }
|
|
2164
2601
|
});
|
|
2165
2602
|
this.logger.warn(
|
|
2166
2603
|
`[claude-code] Permission denied - Tool: ${message.tool_name}${reason ? `, Reason: ${reason}` : ""}`
|
|
2167
2604
|
);
|
|
2168
2605
|
break;
|
|
2169
2606
|
}
|
|
2607
|
+
case "task_started":
|
|
2608
|
+
this.trackTaskEvent(
|
|
2609
|
+
{
|
|
2610
|
+
subtype: "task_started",
|
|
2611
|
+
taskId: message.task_id,
|
|
2612
|
+
...message.tool_use_id !== void 0 && { toolUseId: message.tool_use_id },
|
|
2613
|
+
description: message.description,
|
|
2614
|
+
...message.subagent_type !== void 0 && { subagentType: message.subagent_type },
|
|
2615
|
+
...message.task_type !== void 0 && { taskType: message.task_type },
|
|
2616
|
+
...message.workflow_name !== void 0 && { workflowName: message.workflow_name },
|
|
2617
|
+
...message.prompt !== void 0 && { prompt: message.prompt },
|
|
2618
|
+
...message.skip_transcript !== void 0 && {
|
|
2619
|
+
skipTranscript: message.skip_transcript
|
|
2620
|
+
},
|
|
2621
|
+
uuid: message.uuid,
|
|
2622
|
+
sessionId: message.session_id,
|
|
2623
|
+
raw: message
|
|
2624
|
+
},
|
|
2625
|
+
tracking
|
|
2626
|
+
);
|
|
2627
|
+
this.logger.debug(`[claude-code] Task started - ID: ${message.task_id}`);
|
|
2628
|
+
break;
|
|
2629
|
+
case "task_progress":
|
|
2630
|
+
this.trackTaskEvent(
|
|
2631
|
+
{
|
|
2632
|
+
subtype: "task_progress",
|
|
2633
|
+
taskId: message.task_id,
|
|
2634
|
+
...message.tool_use_id !== void 0 && { toolUseId: message.tool_use_id },
|
|
2635
|
+
description: message.description,
|
|
2636
|
+
...message.subagent_type !== void 0 && { subagentType: message.subagent_type },
|
|
2637
|
+
usage: message.usage,
|
|
2638
|
+
...message.last_tool_name !== void 0 && { lastToolName: message.last_tool_name },
|
|
2639
|
+
...message.summary !== void 0 && { summary: message.summary },
|
|
2640
|
+
uuid: message.uuid,
|
|
2641
|
+
sessionId: message.session_id,
|
|
2642
|
+
raw: message
|
|
2643
|
+
},
|
|
2644
|
+
tracking
|
|
2645
|
+
);
|
|
2646
|
+
this.logger.debug(`[claude-code] Task progress - ID: ${message.task_id}`);
|
|
2647
|
+
break;
|
|
2648
|
+
case "task_updated":
|
|
2649
|
+
this.trackTaskEvent(
|
|
2650
|
+
{
|
|
2651
|
+
subtype: "task_updated",
|
|
2652
|
+
taskId: message.task_id,
|
|
2653
|
+
patch: message.patch,
|
|
2654
|
+
uuid: message.uuid,
|
|
2655
|
+
sessionId: message.session_id,
|
|
2656
|
+
raw: message
|
|
2657
|
+
},
|
|
2658
|
+
tracking
|
|
2659
|
+
);
|
|
2660
|
+
this.logger.debug(`[claude-code] Task updated - ID: ${message.task_id}`);
|
|
2661
|
+
break;
|
|
2662
|
+
case "task_notification":
|
|
2663
|
+
this.trackTaskEvent(
|
|
2664
|
+
{
|
|
2665
|
+
subtype: "task_notification",
|
|
2666
|
+
taskId: message.task_id,
|
|
2667
|
+
...message.tool_use_id !== void 0 && { toolUseId: message.tool_use_id },
|
|
2668
|
+
status: message.status,
|
|
2669
|
+
outputFile: message.output_file,
|
|
2670
|
+
summary: message.summary,
|
|
2671
|
+
...message.usage !== void 0 && { usage: message.usage },
|
|
2672
|
+
...message.skip_transcript !== void 0 && {
|
|
2673
|
+
skipTranscript: message.skip_transcript
|
|
2674
|
+
},
|
|
2675
|
+
uuid: message.uuid,
|
|
2676
|
+
sessionId: message.session_id,
|
|
2677
|
+
raw: message
|
|
2678
|
+
},
|
|
2679
|
+
tracking
|
|
2680
|
+
);
|
|
2681
|
+
this.logger.debug(
|
|
2682
|
+
`[claude-code] Task notification - ID: ${message.task_id}, Status: ${message.status}`
|
|
2683
|
+
);
|
|
2684
|
+
break;
|
|
2685
|
+
case "hook_started":
|
|
2686
|
+
this.trackHookEvent(
|
|
2687
|
+
{
|
|
2688
|
+
subtype: "hook_started",
|
|
2689
|
+
hookId: message.hook_id,
|
|
2690
|
+
hookName: message.hook_name,
|
|
2691
|
+
hookEvent: message.hook_event,
|
|
2692
|
+
uuid: message.uuid,
|
|
2693
|
+
sessionId: message.session_id,
|
|
2694
|
+
raw: message
|
|
2695
|
+
},
|
|
2696
|
+
tracking
|
|
2697
|
+
);
|
|
2698
|
+
this.logger.debug(
|
|
2699
|
+
`[claude-code] Hook started - ID: ${message.hook_id}, Event: ${message.hook_event}`
|
|
2700
|
+
);
|
|
2701
|
+
break;
|
|
2702
|
+
case "hook_progress":
|
|
2703
|
+
this.trackHookEvent(
|
|
2704
|
+
{
|
|
2705
|
+
subtype: "hook_progress",
|
|
2706
|
+
hookId: message.hook_id,
|
|
2707
|
+
hookName: message.hook_name,
|
|
2708
|
+
hookEvent: message.hook_event,
|
|
2709
|
+
stdout: message.stdout,
|
|
2710
|
+
stderr: message.stderr,
|
|
2711
|
+
output: message.output,
|
|
2712
|
+
uuid: message.uuid,
|
|
2713
|
+
sessionId: message.session_id,
|
|
2714
|
+
raw: message
|
|
2715
|
+
},
|
|
2716
|
+
tracking
|
|
2717
|
+
);
|
|
2718
|
+
this.logger.debug(
|
|
2719
|
+
`[claude-code] Hook progress - ID: ${message.hook_id}, Event: ${message.hook_event}`
|
|
2720
|
+
);
|
|
2721
|
+
break;
|
|
2722
|
+
case "hook_response":
|
|
2723
|
+
this.trackHookEvent(
|
|
2724
|
+
{
|
|
2725
|
+
subtype: "hook_response",
|
|
2726
|
+
hookId: message.hook_id,
|
|
2727
|
+
hookName: message.hook_name,
|
|
2728
|
+
hookEvent: message.hook_event,
|
|
2729
|
+
output: message.output,
|
|
2730
|
+
stdout: message.stdout,
|
|
2731
|
+
stderr: message.stderr,
|
|
2732
|
+
...message.exit_code !== void 0 && { exitCode: message.exit_code },
|
|
2733
|
+
outcome: message.outcome,
|
|
2734
|
+
uuid: message.uuid,
|
|
2735
|
+
sessionId: message.session_id,
|
|
2736
|
+
raw: message
|
|
2737
|
+
},
|
|
2738
|
+
tracking
|
|
2739
|
+
);
|
|
2740
|
+
this.logger.debug(
|
|
2741
|
+
`[claude-code] Hook response - ID: ${message.hook_id}, Outcome: ${message.outcome}`
|
|
2742
|
+
);
|
|
2743
|
+
break;
|
|
2170
2744
|
case "mirror_error": {
|
|
2171
2745
|
const mirrorError = message.error ?? "unknown error";
|
|
2172
2746
|
const mirrorSessionId = message.key?.sessionId ?? message.session_id ?? "unknown";
|
|
@@ -2219,12 +2793,21 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2219
2793
|
const alreadyTracked = tracking.permissionDenials.some(
|
|
2220
2794
|
(d) => d.toolUseId !== void 0 && d.toolUseId === denial.tool_use_id
|
|
2221
2795
|
);
|
|
2222
|
-
if (
|
|
2223
|
-
|
|
2224
|
-
toolName: denial.tool_name,
|
|
2225
|
-
toolUseId: denial.tool_use_id
|
|
2226
|
-
});
|
|
2796
|
+
if (alreadyTracked) {
|
|
2797
|
+
continue;
|
|
2227
2798
|
}
|
|
2799
|
+
const agentId = typeof denial.agent_id === "string" ? denial.agent_id : typeof denial.agentId === "string" ? denial.agentId : void 0;
|
|
2800
|
+
const decisionReasonType = typeof denial.decision_reason_type === "string" ? denial.decision_reason_type : typeof denial.decisionReasonType === "string" ? denial.decisionReasonType : void 0;
|
|
2801
|
+
const reason = typeof denial.decision_reason === "string" ? denial.decision_reason : typeof denial.reason === "string" ? denial.reason : typeof denial.message === "string" ? denial.message : void 0;
|
|
2802
|
+
const raw = toJsonSafeValue(denial);
|
|
2803
|
+
tracking.permissionDenials.push({
|
|
2804
|
+
toolName: denial.tool_name,
|
|
2805
|
+
toolUseId: denial.tool_use_id,
|
|
2806
|
+
...agentId !== void 0 && { agentId },
|
|
2807
|
+
...decisionReasonType !== void 0 && { decisionReasonType },
|
|
2808
|
+
...reason !== void 0 && { reason },
|
|
2809
|
+
...raw !== void 0 && { raw }
|
|
2810
|
+
});
|
|
2228
2811
|
}
|
|
2229
2812
|
}
|
|
2230
2813
|
/**
|
|
@@ -2233,11 +2816,10 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2233
2816
|
* suggestion arrives AFTER the result message; the SDK emits at most one
|
|
2234
2817
|
* per turn, so stop once it is delivered, and a timeout closes the
|
|
2235
2818
|
* iterator (tearing down the subprocess) if the CLI lingers after the
|
|
2236
|
-
* result without emitting one.
|
|
2237
|
-
*
|
|
2819
|
+
* result without emitting one. Drained messages still pass through the
|
|
2820
|
+
* generic raw SDK callback before prompt-specific handling.
|
|
2238
2821
|
*/
|
|
2239
|
-
async drainPromptSuggestion(
|
|
2240
|
-
const iterator = response[Symbol.asyncIterator]();
|
|
2822
|
+
async drainPromptSuggestion(iterator, onPromptSuggestion) {
|
|
2241
2823
|
let drainTimer;
|
|
2242
2824
|
const drainTimeout = new Promise((resolve) => {
|
|
2243
2825
|
drainTimer = setTimeout(
|
|
@@ -2260,8 +2842,9 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2260
2842
|
}
|
|
2261
2843
|
const trailingMessage = winner.value;
|
|
2262
2844
|
this.logger.debug(`[claude-code] Post-result message type: ${trailingMessage.type}`);
|
|
2845
|
+
this.invokeSdkMessageCallback(trailingMessage);
|
|
2263
2846
|
if (trailingMessage.type === "prompt_suggestion") {
|
|
2264
|
-
onPromptSuggestion(trailingMessage.suggestion);
|
|
2847
|
+
onPromptSuggestion?.(trailingMessage.suggestion);
|
|
2265
2848
|
void iterator.return?.().catch(() => {
|
|
2266
2849
|
});
|
|
2267
2850
|
break;
|
|
@@ -2303,7 +2886,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2303
2886
|
const effectiveResume = this.getEffectiveResume(sdkOptions);
|
|
2304
2887
|
const queryOptions = this.createQueryOptions(
|
|
2305
2888
|
abortController,
|
|
2306
|
-
options
|
|
2889
|
+
options,
|
|
2307
2890
|
stderrCollector,
|
|
2308
2891
|
sdkOptions,
|
|
2309
2892
|
effectiveResume
|
|
@@ -2377,9 +2960,15 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2377
2960
|
apiRetries: 0,
|
|
2378
2961
|
permissionDenials: [],
|
|
2379
2962
|
mirrorErrors: [],
|
|
2380
|
-
estimatedThinkingTokens: 0
|
|
2963
|
+
estimatedThinkingTokens: 0,
|
|
2964
|
+
taskEvents: [],
|
|
2965
|
+
hookEvents: []
|
|
2381
2966
|
};
|
|
2382
|
-
const warnings = this.generateAllWarnings(
|
|
2967
|
+
const warnings = this.generateAllWarnings(
|
|
2968
|
+
options,
|
|
2969
|
+
messagesPrompt,
|
|
2970
|
+
sdkOptions
|
|
2971
|
+
);
|
|
2383
2972
|
if (messageWarnings) {
|
|
2384
2973
|
messageWarnings.forEach((warning) => {
|
|
2385
2974
|
warnings.push({
|
|
@@ -2391,7 +2980,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2391
2980
|
const modeSetting = this.settings.streamingInput ?? "auto";
|
|
2392
2981
|
const effectiveCanUseTool = sdkOptions?.canUseTool ?? this.settings.canUseTool;
|
|
2393
2982
|
const effectivePermissionPromptToolName = sdkOptions?.permissionPromptToolName ?? this.settings.permissionPromptToolName;
|
|
2394
|
-
const wantsStreamInput = modeSetting === "always" || modeSetting === "auto" && !!effectiveCanUseTool;
|
|
2983
|
+
const wantsStreamInput = modeSetting === "always" || modeSetting === "auto" && (!!effectiveCanUseTool || hasImageParts);
|
|
2395
2984
|
if (!wantsStreamInput && hasImageParts) {
|
|
2396
2985
|
warnings.push({
|
|
2397
2986
|
type: "other",
|
|
@@ -2423,7 +3012,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2423
3012
|
prompt: sdkPrompt,
|
|
2424
3013
|
options: queryOptions
|
|
2425
3014
|
});
|
|
2426
|
-
this.
|
|
3015
|
+
this.notifyQueryCreated(response);
|
|
2427
3016
|
let lastAssistantErrorKind;
|
|
2428
3017
|
const sdkIterator = response[Symbol.asyncIterator]();
|
|
2429
3018
|
const detachableResponse = {
|
|
@@ -2438,6 +3027,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2438
3027
|
};
|
|
2439
3028
|
for await (const message of detachableResponse) {
|
|
2440
3029
|
this.logger.debug(`[claude-code] Received message type: ${message.type}`);
|
|
3030
|
+
this.invokeSdkMessageCallback(message);
|
|
2441
3031
|
if (message.type === "assistant") {
|
|
2442
3032
|
if (typeof message.error === "string") {
|
|
2443
3033
|
lastAssistantErrorKind = message.error;
|
|
@@ -2466,6 +3056,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2466
3056
|
} else if (block.type === "tool_use") {
|
|
2467
3057
|
const [tool3] = this.extractToolUses([block]);
|
|
2468
3058
|
if (!tool3) continue;
|
|
3059
|
+
if (isInternalStructuredOutputTool(tool3.name, options)) continue;
|
|
2469
3060
|
const parentToolCallId = isSubagentToolName(tool3.name) ? null : resolveToolParentId(
|
|
2470
3061
|
sdkParentToolUseId,
|
|
2471
3062
|
tool3.parentToolUseId,
|
|
@@ -2576,7 +3167,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2576
3167
|
kind: "tool-error",
|
|
2577
3168
|
...resultMessageUuid !== void 0 && { uuid: resultMessageUuid },
|
|
2578
3169
|
toolCallId: error.id,
|
|
2579
|
-
part: this.
|
|
3170
|
+
part: this.buildErroredToolResultPart(
|
|
2580
3171
|
error.id,
|
|
2581
3172
|
toolName,
|
|
2582
3173
|
error.error,
|
|
@@ -2634,14 +3225,19 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2634
3225
|
}
|
|
2635
3226
|
const stopReason = "stop_reason" in message ? message.stop_reason : void 0;
|
|
2636
3227
|
finishReason = mapClaudeCodeFinishReason(message.subtype, stopReason);
|
|
3228
|
+
if (structuredOutput !== void 0 && finishReason.unified === "tool-calls") {
|
|
3229
|
+
finishReason = { unified: "stop", raw: finishReason.raw };
|
|
3230
|
+
}
|
|
2637
3231
|
this.logger.debug(`[claude-code] Finish reason: ${finishReason.unified}`);
|
|
2638
3232
|
const effectivePromptSuggestions = sdkOptions?.promptSuggestions ?? this.settings.promptSuggestions;
|
|
2639
|
-
|
|
2640
|
-
|
|
3233
|
+
const shouldDrainPromptSuggestion = effectivePromptSuggestions !== false && (this.settings.onPromptSuggestion !== void 0 || this.settings.onSdkMessage !== void 0);
|
|
3234
|
+
if (shouldDrainPromptSuggestion) {
|
|
3235
|
+
await this.drainPromptSuggestion(sdkIterator, this.settings.onPromptSuggestion);
|
|
2641
3236
|
}
|
|
2642
3237
|
break;
|
|
2643
3238
|
} else if (message.type === "system" && message.subtype === "init") {
|
|
2644
3239
|
this.logMcpConnectionIssues(message.mcp_servers);
|
|
3240
|
+
this.trackMcpStatusFromInit(message, metadataTracking);
|
|
2645
3241
|
this.setSessionId(message.session_id);
|
|
2646
3242
|
this.logger.info(`[claude-code] Session initialized: ${message.session_id}`);
|
|
2647
3243
|
} else if (message.type === "system") {
|
|
@@ -2744,6 +3340,15 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2744
3340
|
...metadataTracking.permissionDenials.length > 0 && {
|
|
2745
3341
|
permissionDenials: metadataTracking.permissionDenials
|
|
2746
3342
|
},
|
|
3343
|
+
...metadataTracking.taskEvents.length > 0 && {
|
|
3344
|
+
taskEvents: metadataTracking.taskEvents
|
|
3345
|
+
},
|
|
3346
|
+
...metadataTracking.hookEvents.length > 0 && {
|
|
3347
|
+
hookEvents: metadataTracking.hookEvents
|
|
3348
|
+
},
|
|
3349
|
+
...metadataTracking.mcpServers !== void 0 && {
|
|
3350
|
+
mcpServers: metadataTracking.mcpServers
|
|
3351
|
+
},
|
|
2747
3352
|
...metadataTracking.mirrorErrors.length > 0 && {
|
|
2748
3353
|
mirrorErrors: metadataTracking.mirrorErrors
|
|
2749
3354
|
},
|
|
@@ -2782,7 +3387,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2782
3387
|
const effectiveResume = this.getEffectiveResume(sdkOptions);
|
|
2783
3388
|
const queryOptions = this.createQueryOptions(
|
|
2784
3389
|
abortController,
|
|
2785
|
-
options
|
|
3390
|
+
options,
|
|
2786
3391
|
stderrCollector,
|
|
2787
3392
|
sdkOptions,
|
|
2788
3393
|
effectiveResume
|
|
@@ -2794,7 +3399,11 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2794
3399
|
if (queryOptions.includePartialMessages === void 0) {
|
|
2795
3400
|
queryOptions.includePartialMessages = true;
|
|
2796
3401
|
}
|
|
2797
|
-
const warnings = this.generateAllWarnings(
|
|
3402
|
+
const warnings = this.generateAllWarnings(
|
|
3403
|
+
options,
|
|
3404
|
+
messagesPrompt,
|
|
3405
|
+
sdkOptions
|
|
3406
|
+
);
|
|
2798
3407
|
if (messageWarnings) {
|
|
2799
3408
|
messageWarnings.forEach((warning) => {
|
|
2800
3409
|
warnings.push({
|
|
@@ -2806,7 +3415,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2806
3415
|
const modeSetting = this.settings.streamingInput ?? "auto";
|
|
2807
3416
|
const effectiveCanUseTool = sdkOptions?.canUseTool ?? this.settings.canUseTool;
|
|
2808
3417
|
const effectivePermissionPromptToolName = sdkOptions?.permissionPromptToolName ?? this.settings.permissionPromptToolName;
|
|
2809
|
-
const wantsStreamInput = modeSetting === "always" || modeSetting === "auto" && !!effectiveCanUseTool;
|
|
3418
|
+
const wantsStreamInput = modeSetting === "always" || modeSetting === "auto" && (!!effectiveCanUseTool || hasImageParts);
|
|
2810
3419
|
if (!wantsStreamInput && hasImageParts) {
|
|
2811
3420
|
warnings.push({
|
|
2812
3421
|
type: "other",
|
|
@@ -2873,9 +3482,13 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2873
3482
|
apiRetries: 0,
|
|
2874
3483
|
permissionDenials: [],
|
|
2875
3484
|
mirrorErrors: [],
|
|
2876
|
-
estimatedThinkingTokens: 0
|
|
3485
|
+
estimatedThinkingTokens: 0,
|
|
3486
|
+
taskEvents: [],
|
|
3487
|
+
hookEvents: []
|
|
2877
3488
|
};
|
|
2878
3489
|
const toolBlocksByIndex = /* @__PURE__ */ new Map();
|
|
3490
|
+
const structuredOutputBlockIndexes = /* @__PURE__ */ new Set();
|
|
3491
|
+
const nonTextToolBlockIndexes = /* @__PURE__ */ new Set();
|
|
2879
3492
|
const toolInputAccumulators = /* @__PURE__ */ new Map();
|
|
2880
3493
|
const textBlocksByIndex = /* @__PURE__ */ new Map();
|
|
2881
3494
|
let textStreamedViaContentBlock = false;
|
|
@@ -2938,9 +3551,24 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2938
3551
|
prompt: sdkPrompt,
|
|
2939
3552
|
options: queryOptions
|
|
2940
3553
|
});
|
|
2941
|
-
this.
|
|
2942
|
-
|
|
3554
|
+
this.notifyQueryCreated(response);
|
|
3555
|
+
const sdkIterator = response[Symbol.asyncIterator]();
|
|
3556
|
+
const detachableResponse = {
|
|
3557
|
+
[Symbol.asyncIterator]: () => ({
|
|
3558
|
+
next: () => sdkIterator.next(),
|
|
3559
|
+
return: () => {
|
|
3560
|
+
void sdkIterator.return?.().catch(() => {
|
|
3561
|
+
});
|
|
3562
|
+
return Promise.resolve({ done: true, value: void 0 });
|
|
3563
|
+
}
|
|
3564
|
+
})
|
|
3565
|
+
};
|
|
3566
|
+
for await (const message of detachableResponse) {
|
|
2943
3567
|
this.logger.debug(`[claude-code] Stream received message type: ${message.type}`);
|
|
3568
|
+
this.invokeSdkMessageCallback(message);
|
|
3569
|
+
if (options.includeRawChunks) {
|
|
3570
|
+
controller.enqueue({ type: "raw", rawValue: message });
|
|
3571
|
+
}
|
|
2944
3572
|
if (message.type === "stream_event") {
|
|
2945
3573
|
const streamEvent = message;
|
|
2946
3574
|
const event = streamEvent.event;
|
|
@@ -2972,7 +3600,8 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
2972
3600
|
const jsonDelta = event.delta.partial_json;
|
|
2973
3601
|
hasReceivedStreamEvents = true;
|
|
2974
3602
|
const blockIndex = "index" in event ? event.index : -1;
|
|
2975
|
-
|
|
3603
|
+
const isStructuredOutputDelta = structuredOutputBlockIndexes.has(blockIndex) || !toolBlocksByIndex.has(blockIndex) && !nonTextToolBlockIndexes.has(blockIndex);
|
|
3604
|
+
if (options.responseFormat?.type === "json" && isStructuredOutputDelta) {
|
|
2976
3605
|
if (!textPartId) {
|
|
2977
3606
|
textPartId = generateId();
|
|
2978
3607
|
controller.enqueue({
|
|
@@ -3002,12 +3631,25 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
3002
3631
|
continue;
|
|
3003
3632
|
}
|
|
3004
3633
|
}
|
|
3634
|
+
if (event.type === "content_block_start" && "content_block" in event && isNonTextToolUseContentBlockType(event.content_block?.type)) {
|
|
3635
|
+
const blockIndex = "index" in event ? event.index : -1;
|
|
3636
|
+
hasReceivedStreamEvents = true;
|
|
3637
|
+
nonTextToolBlockIndexes.add(blockIndex);
|
|
3638
|
+
structuredOutputBlockIndexes.delete(blockIndex);
|
|
3639
|
+
continue;
|
|
3640
|
+
}
|
|
3005
3641
|
if (event.type === "content_block_start" && "content_block" in event && event.content_block?.type === "tool_use") {
|
|
3006
3642
|
const blockIndex = "index" in event ? event.index : -1;
|
|
3007
3643
|
const toolBlock = event.content_block;
|
|
3008
3644
|
const toolId = typeof toolBlock.id === "string" && toolBlock.id.length > 0 ? toolBlock.id : generateId();
|
|
3009
3645
|
const toolName = typeof toolBlock.name === "string" && toolBlock.name.length > 0 ? toolBlock.name : _ClaudeCodeLanguageModel.UNKNOWN_TOOL_NAME;
|
|
3010
3646
|
hasReceivedStreamEvents = true;
|
|
3647
|
+
nonTextToolBlockIndexes.delete(blockIndex);
|
|
3648
|
+
if (isInternalStructuredOutputTool(toolName, options)) {
|
|
3649
|
+
structuredOutputBlockIndexes.add(blockIndex);
|
|
3650
|
+
continue;
|
|
3651
|
+
}
|
|
3652
|
+
structuredOutputBlockIndexes.delete(blockIndex);
|
|
3011
3653
|
if (textPartId) {
|
|
3012
3654
|
const closedTextId = textPartId;
|
|
3013
3655
|
controller.enqueue({
|
|
@@ -3154,6 +3796,12 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
3154
3796
|
toolInputAccumulators.delete(toolId);
|
|
3155
3797
|
continue;
|
|
3156
3798
|
}
|
|
3799
|
+
if (structuredOutputBlockIndexes.delete(blockIndex)) {
|
|
3800
|
+
continue;
|
|
3801
|
+
}
|
|
3802
|
+
if (nonTextToolBlockIndexes.delete(blockIndex)) {
|
|
3803
|
+
continue;
|
|
3804
|
+
}
|
|
3157
3805
|
const textId = textBlocksByIndex.get(blockIndex);
|
|
3158
3806
|
if (textId) {
|
|
3159
3807
|
this.logger.debug(
|
|
@@ -3200,7 +3848,9 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
3200
3848
|
}
|
|
3201
3849
|
const sdkParentToolUseId = message.parent_tool_use_id;
|
|
3202
3850
|
const content = message.message.content;
|
|
3203
|
-
const tools = this.extractToolUses(content)
|
|
3851
|
+
const tools = this.extractToolUses(content).filter(
|
|
3852
|
+
(tool3) => !isInternalStructuredOutputTool(tool3.name, options)
|
|
3853
|
+
);
|
|
3204
3854
|
if (textPartId && tools.length > 0) {
|
|
3205
3855
|
const closedTextId = textPartId;
|
|
3206
3856
|
controller.enqueue({
|
|
@@ -3253,7 +3903,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
3253
3903
|
toolName: tool3.name,
|
|
3254
3904
|
providerExecuted: true,
|
|
3255
3905
|
dynamic: true,
|
|
3256
|
-
//
|
|
3906
|
+
// V4 field: indicates tool is provider-defined
|
|
3257
3907
|
providerMetadata: {
|
|
3258
3908
|
"claude-code": {
|
|
3259
3909
|
parentToolCallId: state.parentToolCallId ?? null
|
|
@@ -3458,7 +4108,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
3458
4108
|
toolName,
|
|
3459
4109
|
providerExecuted: true,
|
|
3460
4110
|
dynamic: true,
|
|
3461
|
-
//
|
|
4111
|
+
// V4 field: indicates tool is provider-defined
|
|
3462
4112
|
providerMetadata: {
|
|
3463
4113
|
"claude-code": {
|
|
3464
4114
|
parentToolCallId: state.parentToolCallId ?? null
|
|
@@ -3510,19 +4160,47 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
3510
4160
|
);
|
|
3511
4161
|
state = {
|
|
3512
4162
|
name: toolName,
|
|
3513
|
-
inputStarted:
|
|
3514
|
-
inputClosed:
|
|
4163
|
+
inputStarted: false,
|
|
4164
|
+
inputClosed: false,
|
|
3515
4165
|
callEmitted: false,
|
|
3516
4166
|
parentToolCallId: errorResolvedParentId
|
|
3517
4167
|
};
|
|
3518
4168
|
toolStates.set(error.id, state);
|
|
4169
|
+
if (!state.inputStarted) {
|
|
4170
|
+
controller.enqueue({
|
|
4171
|
+
type: "tool-input-start",
|
|
4172
|
+
id: error.id,
|
|
4173
|
+
toolName,
|
|
4174
|
+
providerExecuted: true,
|
|
4175
|
+
dynamic: true,
|
|
4176
|
+
// V4 field: indicates tool is provider-defined
|
|
4177
|
+
providerMetadata: {
|
|
4178
|
+
"claude-code": {
|
|
4179
|
+
parentToolCallId: state.parentToolCallId ?? null
|
|
4180
|
+
}
|
|
4181
|
+
}
|
|
4182
|
+
});
|
|
4183
|
+
state.inputStarted = true;
|
|
4184
|
+
}
|
|
4185
|
+
if (!state.inputClosed) {
|
|
4186
|
+
controller.enqueue({
|
|
4187
|
+
type: "tool-input-end",
|
|
4188
|
+
id: error.id
|
|
4189
|
+
});
|
|
4190
|
+
state.inputClosed = true;
|
|
4191
|
+
}
|
|
3519
4192
|
}
|
|
3520
4193
|
emitToolCall(error.id, state);
|
|
3521
4194
|
if (isSubagentToolName(toolName)) {
|
|
3522
4195
|
activeTaskTools.delete(error.id);
|
|
3523
4196
|
}
|
|
3524
4197
|
controller.enqueue(
|
|
3525
|
-
this.
|
|
4198
|
+
this.buildErroredToolResultPart(
|
|
4199
|
+
error.id,
|
|
4200
|
+
toolName,
|
|
4201
|
+
error.error,
|
|
4202
|
+
state.parentToolCallId
|
|
4203
|
+
)
|
|
3526
4204
|
);
|
|
3527
4205
|
}
|
|
3528
4206
|
} else if (message.type === "result") {
|
|
@@ -3552,13 +4230,16 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
3552
4230
|
);
|
|
3553
4231
|
}
|
|
3554
4232
|
const stopReason = "stop_reason" in message ? message.stop_reason : void 0;
|
|
3555
|
-
|
|
4233
|
+
let finishReason = mapClaudeCodeFinishReason(
|
|
3556
4234
|
message.subtype,
|
|
3557
4235
|
stopReason
|
|
3558
4236
|
);
|
|
3559
|
-
this.logger.debug(`[claude-code] Stream finish reason: ${finishReason.unified}`);
|
|
3560
4237
|
this.setSessionId(message.session_id);
|
|
3561
4238
|
const structuredOutput = "structured_output" in message ? message.structured_output : void 0;
|
|
4239
|
+
if (structuredOutput !== void 0 && finishReason.unified === "tool-calls") {
|
|
4240
|
+
finishReason = { unified: "stop", raw: finishReason.raw };
|
|
4241
|
+
}
|
|
4242
|
+
this.logger.debug(`[claude-code] Stream finish reason: ${finishReason.unified}`);
|
|
3562
4243
|
const alreadyStreamedJson = hasStreamedJson && options.responseFormat?.type === "json" && hasReceivedStreamEvents;
|
|
3563
4244
|
if (alreadyStreamedJson) {
|
|
3564
4245
|
if (textPartId) {
|
|
@@ -3672,6 +4353,15 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
3672
4353
|
...metadataTracking.permissionDenials.length > 0 && {
|
|
3673
4354
|
permissionDenials: metadataTracking.permissionDenials
|
|
3674
4355
|
},
|
|
4356
|
+
...metadataTracking.taskEvents.length > 0 && {
|
|
4357
|
+
taskEvents: metadataTracking.taskEvents
|
|
4358
|
+
},
|
|
4359
|
+
...metadataTracking.hookEvents.length > 0 && {
|
|
4360
|
+
hookEvents: metadataTracking.hookEvents
|
|
4361
|
+
},
|
|
4362
|
+
...metadataTracking.mcpServers !== void 0 && {
|
|
4363
|
+
mcpServers: metadataTracking.mcpServers
|
|
4364
|
+
},
|
|
3675
4365
|
...metadataTracking.mirrorErrors.length > 0 && {
|
|
3676
4366
|
mirrorErrors: metadataTracking.mirrorErrors
|
|
3677
4367
|
},
|
|
@@ -3689,12 +4379,14 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
3689
4379
|
});
|
|
3690
4380
|
controller.close();
|
|
3691
4381
|
const effectivePromptSuggestions = sdkOptions?.promptSuggestions ?? this.settings.promptSuggestions;
|
|
3692
|
-
|
|
3693
|
-
|
|
4382
|
+
const shouldDrainPromptSuggestion = effectivePromptSuggestions !== false && (this.settings.onPromptSuggestion !== void 0 || this.settings.onSdkMessage !== void 0);
|
|
4383
|
+
if (shouldDrainPromptSuggestion) {
|
|
4384
|
+
await this.drainPromptSuggestion(sdkIterator, this.settings.onPromptSuggestion);
|
|
3694
4385
|
}
|
|
3695
4386
|
return;
|
|
3696
4387
|
} else if (message.type === "system" && message.subtype === "init") {
|
|
3697
4388
|
this.logMcpConnectionIssues(message.mcp_servers);
|
|
4389
|
+
this.trackMcpStatusFromInit(message, metadataTracking);
|
|
3698
4390
|
this.setSessionId(message.session_id);
|
|
3699
4391
|
this.logger.info(`[claude-code] Stream session initialized: ${message.session_id}`);
|
|
3700
4392
|
controller.enqueue({
|
|
@@ -3768,6 +4460,15 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
3768
4460
|
...metadataTracking.permissionDenials.length > 0 && {
|
|
3769
4461
|
permissionDenials: metadataTracking.permissionDenials
|
|
3770
4462
|
},
|
|
4463
|
+
...metadataTracking.taskEvents.length > 0 && {
|
|
4464
|
+
taskEvents: metadataTracking.taskEvents
|
|
4465
|
+
},
|
|
4466
|
+
...metadataTracking.hookEvents.length > 0 && {
|
|
4467
|
+
hookEvents: metadataTracking.hookEvents
|
|
4468
|
+
},
|
|
4469
|
+
...metadataTracking.mcpServers !== void 0 && {
|
|
4470
|
+
mcpServers: metadataTracking.mcpServers
|
|
4471
|
+
},
|
|
3771
4472
|
...metadataTracking.mirrorErrors.length > 0 && {
|
|
3772
4473
|
mirrorErrors: metadataTracking.mirrorErrors
|
|
3773
4474
|
},
|
|
@@ -3815,19 +4516,23 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
3815
4516
|
};
|
|
3816
4517
|
}
|
|
3817
4518
|
serializeWarningsForMetadata(warnings) {
|
|
3818
|
-
const result = warnings.map((
|
|
3819
|
-
const base = { type:
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
|
|
3827
|
-
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
4519
|
+
const result = warnings.map((warning) => {
|
|
4520
|
+
const base = { type: warning.type };
|
|
4521
|
+
switch (warning.type) {
|
|
4522
|
+
case "unsupported":
|
|
4523
|
+
case "compatibility":
|
|
4524
|
+
base.feature = warning.feature;
|
|
4525
|
+
if (warning.details !== void 0) {
|
|
4526
|
+
base.details = warning.details;
|
|
4527
|
+
}
|
|
4528
|
+
break;
|
|
4529
|
+
case "deprecated":
|
|
4530
|
+
base.setting = warning.setting;
|
|
4531
|
+
base.message = warning.message;
|
|
4532
|
+
break;
|
|
4533
|
+
case "other":
|
|
4534
|
+
base.message = warning.message;
|
|
4535
|
+
break;
|
|
3831
4536
|
}
|
|
3832
4537
|
return base;
|
|
3833
4538
|
});
|
|
@@ -3870,7 +4575,7 @@ function createClaudeCode(options = {}) {
|
|
|
3870
4575
|
};
|
|
3871
4576
|
provider.languageModel = createModel;
|
|
3872
4577
|
provider.chat = createModel;
|
|
3873
|
-
provider.specificationVersion = "
|
|
4578
|
+
provider.specificationVersion = "v4";
|
|
3874
4579
|
provider.embeddingModel = (modelId) => {
|
|
3875
4580
|
throw new NoSuchModelError2({
|
|
3876
4581
|
modelId,
|
|
@@ -3894,7 +4599,9 @@ import {
|
|
|
3894
4599
|
SYSTEM_PROMPT_DYNAMIC_BOUNDARY,
|
|
3895
4600
|
InMemorySessionStore,
|
|
3896
4601
|
HOOK_EVENTS,
|
|
3897
|
-
AbortError
|
|
4602
|
+
AbortError,
|
|
4603
|
+
resolveSettings,
|
|
4604
|
+
filterEscalatingDefaultMode
|
|
3898
4605
|
} from "@anthropic-ai/claude-agent-sdk";
|
|
3899
4606
|
import {
|
|
3900
4607
|
listSessions,
|
|
@@ -3914,6 +4621,16 @@ import { startup } from "@anthropic-ai/claude-agent-sdk";
|
|
|
3914
4621
|
// src/mcp-helpers.ts
|
|
3915
4622
|
import { createSdkMcpServer, tool } from "@anthropic-ai/claude-agent-sdk";
|
|
3916
4623
|
import "zod";
|
|
4624
|
+
var warnedDescriptionFunctionToolNames = /* @__PURE__ */ new Set();
|
|
4625
|
+
function warnDiscardedDescriptionFunction(toolName) {
|
|
4626
|
+
if (warnedDescriptionFunctionToolNames.has(toolName)) {
|
|
4627
|
+
return;
|
|
4628
|
+
}
|
|
4629
|
+
warnedDescriptionFunctionToolNames.add(toolName);
|
|
4630
|
+
console.warn(
|
|
4631
|
+
`[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.`
|
|
4632
|
+
);
|
|
4633
|
+
}
|
|
3917
4634
|
function buildIsErrorResult(text) {
|
|
3918
4635
|
return {
|
|
3919
4636
|
isError: true,
|
|
@@ -3956,7 +4673,11 @@ function createCustomMcpServer(config) {
|
|
|
3956
4673
|
}
|
|
3957
4674
|
var AI_SDK_SCHEMA_SYMBOL = Symbol.for("vercel.ai.schema");
|
|
3958
4675
|
function isAiSdkJsonSchema(schema) {
|
|
3959
|
-
|
|
4676
|
+
if (typeof schema !== "object" || schema === null) {
|
|
4677
|
+
return false;
|
|
4678
|
+
}
|
|
4679
|
+
const candidate = schema;
|
|
4680
|
+
return candidate[AI_SDK_SCHEMA_SYMBOL] === true && "jsonSchema" in candidate && "validate" in candidate;
|
|
3960
4681
|
}
|
|
3961
4682
|
function isZodObjectSchema(schema) {
|
|
3962
4683
|
if (typeof schema !== "object" || schema === null) {
|
|
@@ -3991,9 +4712,13 @@ function createAiSdkMcpServer(name, tools) {
|
|
|
3991
4712
|
);
|
|
3992
4713
|
}
|
|
3993
4714
|
const zodSchema = def.inputSchema;
|
|
4715
|
+
const description = typeof def.description === "string" ? def.description : "";
|
|
4716
|
+
if (typeof def.description === "function") {
|
|
4717
|
+
warnDiscardedDescriptionFunction(toolName);
|
|
4718
|
+
}
|
|
3994
4719
|
return tool(
|
|
3995
4720
|
toolName,
|
|
3996
|
-
|
|
4721
|
+
description,
|
|
3997
4722
|
zodSchema.shape,
|
|
3998
4723
|
async (args, extra) => {
|
|
3999
4724
|
try {
|
|
@@ -4026,10 +4751,12 @@ export {
|
|
|
4026
4751
|
createAiSdkMcpServer,
|
|
4027
4752
|
createAuthenticationError,
|
|
4028
4753
|
createClaudeCode,
|
|
4754
|
+
createClaudeCodeQueryController,
|
|
4029
4755
|
createCustomMcpServer,
|
|
4030
4756
|
createSdkMcpServer2 as createSdkMcpServer,
|
|
4031
4757
|
createTimeoutError,
|
|
4032
4758
|
deleteSession,
|
|
4759
|
+
filterEscalatingDefaultMode,
|
|
4033
4760
|
foldSessionSummary,
|
|
4034
4761
|
forkSession,
|
|
4035
4762
|
getErrorMetadata,
|
|
@@ -4042,6 +4769,7 @@ export {
|
|
|
4042
4769
|
listSessions,
|
|
4043
4770
|
listSubagents,
|
|
4044
4771
|
renameSession,
|
|
4772
|
+
resolveSettings,
|
|
4045
4773
|
startup,
|
|
4046
4774
|
tagSession,
|
|
4047
4775
|
tool2 as tool
|