ai-sdk-provider-claude-code 1.1.0 → 1.1.2
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 +5 -3
- package/dist/index.cjs +109 -19
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +47 -2
- package/dist/index.d.ts +47 -2
- package/dist/index.js +106 -19
- package/dist/index.js.map +1 -1
- package/docs/ai-sdk-v5/DEVELOPMENT-STATUS.md +23 -15
- package/docs/ai-sdk-v5/GUIDE.md +73 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
|
|
18
18
|
| Provider Version | AI SDK Version | NPM Tag | Status | Branch |
|
|
19
19
|
|-----------------|----------------|---------|---------|--------|
|
|
20
|
-
| 1.x | v5 | `latest` | Stable | `main` |
|
|
21
|
-
| 0.x | v4 | `ai-sdk-v4` | Maintenance | [`ai-sdk-v4`](https://github.com/ben-vargas/ai-sdk-provider-claude-code/tree/ai-sdk-v4) |
|
|
20
|
+
| 1.x.x | v5 | `latest` | Stable | `main` |
|
|
21
|
+
| 0.x.x | v4 | `ai-sdk-v4` | Maintenance | [`ai-sdk-v4`](https://github.com/ben-vargas/ai-sdk-provider-claude-code/tree/ai-sdk-v4) |
|
|
22
22
|
|
|
23
23
|
### Installing the Right Version
|
|
24
24
|
|
|
@@ -119,12 +119,14 @@ Key changes:
|
|
|
119
119
|
- 🎯 Object generation with JSON schemas
|
|
120
120
|
- 🛑 AbortSignal support
|
|
121
121
|
- 🔧 Tool management (MCP servers, permissions)
|
|
122
|
+
- 🧩 Callbacks (hooks, canUseTool)
|
|
122
123
|
|
|
123
124
|
## Limitations
|
|
124
125
|
|
|
125
126
|
- Requires Node.js ≥ 18
|
|
126
127
|
- No image support
|
|
127
128
|
- Some AI SDK parameters unsupported (temperature, maxTokens, etc.)
|
|
129
|
+
- `canUseTool` requires streaming input at the SDK level (AsyncIterable prompt). This provider supports it via `streamingInput`: use `'auto'` (default when `canUseTool` is set) or `'always'`. See GUIDE for details.
|
|
128
130
|
|
|
129
131
|
## Contributing
|
|
130
132
|
|
|
@@ -140,4 +142,4 @@ For development status and technical details, see [Development Status](docs/ai-s
|
|
|
140
142
|
|
|
141
143
|
## License
|
|
142
144
|
|
|
143
|
-
MIT
|
|
145
|
+
MIT
|
package/dist/index.cjs
CHANGED
|
@@ -25,10 +25,13 @@ __export(index_exports, {
|
|
|
25
25
|
createAPICallError: () => createAPICallError,
|
|
26
26
|
createAuthenticationError: () => createAuthenticationError,
|
|
27
27
|
createClaudeCode: () => createClaudeCode,
|
|
28
|
+
createCustomMcpServer: () => createCustomMcpServer,
|
|
29
|
+
createSdkMcpServer: () => import_claude_code3.createSdkMcpServer,
|
|
28
30
|
createTimeoutError: () => createTimeoutError,
|
|
29
31
|
getErrorMetadata: () => getErrorMetadata,
|
|
30
32
|
isAuthenticationError: () => isAuthenticationError,
|
|
31
|
-
isTimeoutError: () => isTimeoutError
|
|
33
|
+
isTimeoutError: () => isTimeoutError,
|
|
34
|
+
tool: () => import_claude_code3.tool
|
|
32
35
|
});
|
|
33
36
|
module.exports = __toCommonJS(index_exports);
|
|
34
37
|
|
|
@@ -82,9 +85,9 @@ function convertToClaudeCodeMessages(prompt, mode = { type: "regular" }, jsonSch
|
|
|
82
85
|
break;
|
|
83
86
|
}
|
|
84
87
|
case "tool":
|
|
85
|
-
for (const
|
|
86
|
-
const resultText =
|
|
87
|
-
messages.push(`Tool Result (${
|
|
88
|
+
for (const tool3 of message.content) {
|
|
89
|
+
const resultText = tool3.output.type === "text" ? tool3.output.value : JSON.stringify(tool3.output.value);
|
|
90
|
+
messages.push(`Tool Result (${tool3.toolName}): ${resultText}`);
|
|
88
91
|
}
|
|
89
92
|
break;
|
|
90
93
|
}
|
|
@@ -331,6 +334,15 @@ var claudeCodeSettingsSchema = import_zod.z.object({
|
|
|
331
334
|
resume: import_zod.z.string().optional(),
|
|
332
335
|
allowedTools: import_zod.z.array(import_zod.z.string()).optional(),
|
|
333
336
|
disallowedTools: import_zod.z.array(import_zod.z.string()).optional(),
|
|
337
|
+
streamingInput: import_zod.z.enum(["auto", "always", "off"]).optional(),
|
|
338
|
+
// Hooks and tool-permission callback (permissive validation of shapes)
|
|
339
|
+
canUseTool: import_zod.z.any().refine((v) => v === void 0 || typeof v === "function", {
|
|
340
|
+
message: "canUseTool must be a function"
|
|
341
|
+
}).optional(),
|
|
342
|
+
hooks: import_zod.z.record(import_zod.z.string(), import_zod.z.array(import_zod.z.object({
|
|
343
|
+
matcher: import_zod.z.string().optional(),
|
|
344
|
+
hooks: import_zod.z.array(import_zod.z.any()).nonempty()
|
|
345
|
+
}))).optional(),
|
|
334
346
|
mcpServers: import_zod.z.record(import_zod.z.string(), import_zod.z.union([
|
|
335
347
|
// McpStdioServerConfig
|
|
336
348
|
import_zod.z.object({
|
|
@@ -344,6 +356,18 @@ var claudeCodeSettingsSchema = import_zod.z.object({
|
|
|
344
356
|
type: import_zod.z.literal("sse"),
|
|
345
357
|
url: import_zod.z.string(),
|
|
346
358
|
headers: import_zod.z.record(import_zod.z.string(), import_zod.z.string()).optional()
|
|
359
|
+
}),
|
|
360
|
+
// McpHttpServerConfig
|
|
361
|
+
import_zod.z.object({
|
|
362
|
+
type: import_zod.z.literal("http"),
|
|
363
|
+
url: import_zod.z.string(),
|
|
364
|
+
headers: import_zod.z.record(import_zod.z.string(), import_zod.z.string()).optional()
|
|
365
|
+
}),
|
|
366
|
+
// McpSdkServerConfig (in-process custom tools)
|
|
367
|
+
import_zod.z.object({
|
|
368
|
+
type: import_zod.z.literal("sdk"),
|
|
369
|
+
name: import_zod.z.string(),
|
|
370
|
+
instance: import_zod.z.any()
|
|
347
371
|
})
|
|
348
372
|
])).optional(),
|
|
349
373
|
verbose: import_zod.z.boolean().optional(),
|
|
@@ -387,9 +411,9 @@ function validateSettings(settings) {
|
|
|
387
411
|
warnings.push("Both allowedTools and disallowedTools are specified. Only allowedTools will be used.");
|
|
388
412
|
}
|
|
389
413
|
const validateToolNames = (tools, type) => {
|
|
390
|
-
tools.forEach((
|
|
391
|
-
if (!/^[a-zA-Z_][a-zA-Z0-9_]*(\([^)]*\))?$/.test(
|
|
392
|
-
warnings.push(`Unusual ${type} tool name format: '${
|
|
414
|
+
tools.forEach((tool3) => {
|
|
415
|
+
if (!/^[a-zA-Z_][a-zA-Z0-9_]*(\([^)]*\))?$/.test(tool3) && !tool3.startsWith("mcp__")) {
|
|
416
|
+
warnings.push(`Unusual ${type} tool name format: '${tool3}'`);
|
|
393
417
|
}
|
|
394
418
|
});
|
|
395
419
|
};
|
|
@@ -442,6 +466,30 @@ function getLogger(logger) {
|
|
|
442
466
|
|
|
443
467
|
// src/claude-code-language-model.ts
|
|
444
468
|
var import_claude_code = require("@anthropic-ai/claude-code");
|
|
469
|
+
function isAbortError(err) {
|
|
470
|
+
if (err && typeof err === "object") {
|
|
471
|
+
const e = err;
|
|
472
|
+
if (typeof e.name === "string" && e.name === "AbortError") return true;
|
|
473
|
+
if (typeof e.code === "string" && e.code.toUpperCase() === "ABORT_ERR") return true;
|
|
474
|
+
}
|
|
475
|
+
return false;
|
|
476
|
+
}
|
|
477
|
+
function toAsyncIterablePrompt(messagesPrompt, sessionId) {
|
|
478
|
+
const msg = {
|
|
479
|
+
type: "user",
|
|
480
|
+
message: {
|
|
481
|
+
role: "user",
|
|
482
|
+
content: [{ type: "text", text: messagesPrompt }]
|
|
483
|
+
},
|
|
484
|
+
parent_tool_use_id: null,
|
|
485
|
+
session_id: sessionId ?? ""
|
|
486
|
+
};
|
|
487
|
+
return {
|
|
488
|
+
async *[Symbol.asyncIterator]() {
|
|
489
|
+
yield msg;
|
|
490
|
+
}
|
|
491
|
+
};
|
|
492
|
+
}
|
|
445
493
|
var modelMap = {
|
|
446
494
|
"opus": "opus",
|
|
447
495
|
"sonnet": "sonnet"
|
|
@@ -522,7 +570,7 @@ var ClaudeCodeLanguageModel = class {
|
|
|
522
570
|
return warnings;
|
|
523
571
|
}
|
|
524
572
|
createQueryOptions(abortController) {
|
|
525
|
-
|
|
573
|
+
const opts = {
|
|
526
574
|
model: this.getModel(),
|
|
527
575
|
abortController,
|
|
528
576
|
resume: this.settings.resume ?? this.sessionId,
|
|
@@ -539,11 +587,16 @@ var ClaudeCodeLanguageModel = class {
|
|
|
539
587
|
continue: this.settings.continue,
|
|
540
588
|
allowedTools: this.settings.allowedTools,
|
|
541
589
|
disallowedTools: this.settings.disallowedTools,
|
|
542
|
-
mcpServers: this.settings.mcpServers
|
|
590
|
+
mcpServers: this.settings.mcpServers,
|
|
591
|
+
canUseTool: this.settings.canUseTool
|
|
543
592
|
};
|
|
593
|
+
if (this.settings.hooks) {
|
|
594
|
+
opts.hooks = this.settings.hooks;
|
|
595
|
+
}
|
|
596
|
+
return opts;
|
|
544
597
|
}
|
|
545
598
|
handleClaudeCodeError(error, messagesPrompt) {
|
|
546
|
-
if (error
|
|
599
|
+
if (isAbortError(error)) {
|
|
547
600
|
throw error;
|
|
548
601
|
}
|
|
549
602
|
const isErrorWithMessage = (err) => {
|
|
@@ -626,8 +679,10 @@ var ClaudeCodeLanguageModel = class {
|
|
|
626
679
|
);
|
|
627
680
|
const abortController = new AbortController();
|
|
628
681
|
let abortListener;
|
|
629
|
-
if (options.abortSignal) {
|
|
630
|
-
|
|
682
|
+
if (options.abortSignal?.aborted) {
|
|
683
|
+
abortController.abort(options.abortSignal.reason);
|
|
684
|
+
} else if (options.abortSignal) {
|
|
685
|
+
abortListener = () => abortController.abort(options.abortSignal?.reason);
|
|
631
686
|
options.abortSignal.addEventListener("abort", abortListener, { once: true });
|
|
632
687
|
}
|
|
633
688
|
const queryOptions = this.createQueryOptions(abortController);
|
|
@@ -647,8 +702,14 @@ var ClaudeCodeLanguageModel = class {
|
|
|
647
702
|
});
|
|
648
703
|
}
|
|
649
704
|
try {
|
|
705
|
+
const modeSetting = this.settings.streamingInput ?? "auto";
|
|
706
|
+
const wantsStream = modeSetting === "always" || modeSetting === "auto" && !!this.settings.canUseTool;
|
|
707
|
+
if (this.settings.canUseTool && this.settings.permissionPromptToolName) {
|
|
708
|
+
throw new Error("canUseTool requires streamingInput mode ('auto' or 'always') and cannot be used with permissionPromptToolName (SDK constraint). Set streamingInput: 'auto' (or 'always') and remove permissionPromptToolName, or remove canUseTool.");
|
|
709
|
+
}
|
|
710
|
+
const sdkPrompt = wantsStream ? toAsyncIterablePrompt(messagesPrompt, this.settings.resume ?? this.sessionId) : messagesPrompt;
|
|
650
711
|
const response = (0, import_claude_code.query)({
|
|
651
|
-
prompt:
|
|
712
|
+
prompt: sdkPrompt,
|
|
652
713
|
options: queryOptions
|
|
653
714
|
});
|
|
654
715
|
for await (const message of response) {
|
|
@@ -674,7 +735,7 @@ var ClaudeCodeLanguageModel = class {
|
|
|
674
735
|
}
|
|
675
736
|
}
|
|
676
737
|
} catch (error) {
|
|
677
|
-
if (error
|
|
738
|
+
if (isAbortError(error)) {
|
|
678
739
|
throw options.abortSignal?.aborted ? options.abortSignal.reason : error;
|
|
679
740
|
}
|
|
680
741
|
throw this.handleClaudeCodeError(error, messagesPrompt);
|
|
@@ -723,8 +784,10 @@ var ClaudeCodeLanguageModel = class {
|
|
|
723
784
|
);
|
|
724
785
|
const abortController = new AbortController();
|
|
725
786
|
let abortListener;
|
|
726
|
-
if (options.abortSignal) {
|
|
727
|
-
|
|
787
|
+
if (options.abortSignal?.aborted) {
|
|
788
|
+
abortController.abort(options.abortSignal.reason);
|
|
789
|
+
} else if (options.abortSignal) {
|
|
790
|
+
abortListener = () => abortController.abort(options.abortSignal?.reason);
|
|
728
791
|
options.abortSignal.addEventListener("abort", abortListener, { once: true });
|
|
729
792
|
}
|
|
730
793
|
const queryOptions = this.createQueryOptions(abortController);
|
|
@@ -741,8 +804,14 @@ var ClaudeCodeLanguageModel = class {
|
|
|
741
804
|
start: async (controller) => {
|
|
742
805
|
try {
|
|
743
806
|
controller.enqueue({ type: "stream-start", warnings });
|
|
807
|
+
const modeSetting = this.settings.streamingInput ?? "auto";
|
|
808
|
+
const wantsStream = modeSetting === "always" || modeSetting === "auto" && !!this.settings.canUseTool;
|
|
809
|
+
if (this.settings.canUseTool && this.settings.permissionPromptToolName) {
|
|
810
|
+
throw new Error("canUseTool requires streamingInput mode ('auto' or 'always') and cannot be used with permissionPromptToolName (SDK constraint). Set streamingInput: 'auto' (or 'always') and remove permissionPromptToolName, or remove canUseTool.");
|
|
811
|
+
}
|
|
812
|
+
const sdkPrompt = wantsStream ? toAsyncIterablePrompt(messagesPrompt, this.settings.resume ?? this.sessionId) : messagesPrompt;
|
|
744
813
|
const response = (0, import_claude_code.query)({
|
|
745
|
-
prompt:
|
|
814
|
+
prompt: sdkPrompt,
|
|
746
815
|
options: queryOptions
|
|
747
816
|
});
|
|
748
817
|
let usage = { inputTokens: 0, outputTokens: 0, totalTokens: 0 };
|
|
@@ -829,7 +898,7 @@ var ClaudeCodeLanguageModel = class {
|
|
|
829
898
|
controller.close();
|
|
830
899
|
} catch (error) {
|
|
831
900
|
let errorToEmit;
|
|
832
|
-
if (error
|
|
901
|
+
if (isAbortError(error)) {
|
|
833
902
|
errorToEmit = options.abortSignal?.aborted ? options.abortSignal.reason : error;
|
|
834
903
|
} else {
|
|
835
904
|
errorToEmit = this.handleClaudeCodeError(error, messagesPrompt);
|
|
@@ -912,6 +981,24 @@ function createClaudeCode(options = {}) {
|
|
|
912
981
|
return provider;
|
|
913
982
|
}
|
|
914
983
|
var claudeCode = createClaudeCode();
|
|
984
|
+
|
|
985
|
+
// src/index.ts
|
|
986
|
+
var import_claude_code3 = require("@anthropic-ai/claude-code");
|
|
987
|
+
|
|
988
|
+
// src/mcp-helpers.ts
|
|
989
|
+
var import_claude_code2 = require("@anthropic-ai/claude-code");
|
|
990
|
+
var import_zod2 = require("zod");
|
|
991
|
+
function createCustomMcpServer(config) {
|
|
992
|
+
const defs = Object.entries(config.tools).map(
|
|
993
|
+
([name, def]) => (0, import_claude_code2.tool)(
|
|
994
|
+
name,
|
|
995
|
+
def.description,
|
|
996
|
+
def.inputSchema.shape,
|
|
997
|
+
(args, extra) => def.handler(args, extra)
|
|
998
|
+
)
|
|
999
|
+
);
|
|
1000
|
+
return (0, import_claude_code2.createSdkMcpServer)({ name: config.name, version: config.version, tools: defs });
|
|
1001
|
+
}
|
|
915
1002
|
// Annotate the CommonJS export names for ESM import in node:
|
|
916
1003
|
0 && (module.exports = {
|
|
917
1004
|
ClaudeCodeLanguageModel,
|
|
@@ -919,9 +1006,12 @@ var claudeCode = createClaudeCode();
|
|
|
919
1006
|
createAPICallError,
|
|
920
1007
|
createAuthenticationError,
|
|
921
1008
|
createClaudeCode,
|
|
1009
|
+
createCustomMcpServer,
|
|
1010
|
+
createSdkMcpServer,
|
|
922
1011
|
createTimeoutError,
|
|
923
1012
|
getErrorMetadata,
|
|
924
1013
|
isAuthenticationError,
|
|
925
|
-
isTimeoutError
|
|
1014
|
+
isTimeoutError,
|
|
1015
|
+
tool
|
|
926
1016
|
});
|
|
927
1017
|
//# sourceMappingURL=index.cjs.map
|