ai-sdk-provider-claude-code 3.0.0-beta.1 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -72
- package/dist/index.cjs +55 -37
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +55 -37
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
# AI SDK Provider for Claude Code SDK
|
|
11
11
|
|
|
12
|
-
> **Latest Release**: Version
|
|
12
|
+
> **Latest Release**: Version 3.x supports AI SDK v6 stable with the Claude Agent SDK. For AI SDK v5 support, use the `ai-sdk-v5` tag.
|
|
13
13
|
|
|
14
14
|
**ai-sdk-provider-claude-code** lets you use Claude via the [Vercel AI SDK](https://sdk.vercel.ai/docs) through the official `@anthropic-ai/claude-agent-sdk` and the Claude Code CLI.
|
|
15
15
|
|
|
@@ -17,23 +17,24 @@
|
|
|
17
17
|
|
|
18
18
|
| Provider Version | AI SDK Version | Underlying SDK | NPM Tag | Status | Branch |
|
|
19
19
|
| ---------------- | -------------- | ------------------------------------ | -------------------- | ------ | --------------------------------------------------------------------------------------- |
|
|
20
|
-
|
|
|
21
|
-
|
|
|
22
|
-
|
|
|
20
|
+
| 3.x.x | v6 | `@anthropic-ai/claude-agent-sdk` | `latest` | Stable | `main` |
|
|
21
|
+
| 2.x.x | v5 | `@anthropic-ai/claude-agent-sdk` | `ai-sdk-v5` | Stable | [`ai-sdk-v5`](https://github.com/ben-vargas/ai-sdk-provider-claude-code/tree/ai-sdk-v5) |
|
|
22
|
+
| 1.x.x | v5 | `@anthropic-ai/claude-code` (legacy) | `v1-claude-code-sdk` | Legacy | [`v1`](https://github.com/ben-vargas/ai-sdk-provider-claude-code/tree/v1) |
|
|
23
|
+
| 0.x.x | v4 | `@anthropic-ai/claude-code` (legacy) | `ai-sdk-v4` | Legacy | [`ai-sdk-v4`](https://github.com/ben-vargas/ai-sdk-provider-claude-code/tree/ai-sdk-v4) |
|
|
23
24
|
|
|
24
25
|
### Installing the Right Version
|
|
25
26
|
|
|
26
|
-
**For AI SDK
|
|
27
|
+
**For AI SDK v6 (recommended):**
|
|
27
28
|
|
|
28
29
|
```bash
|
|
29
|
-
npm install ai-sdk-provider-claude-code ai
|
|
30
|
+
npm install ai-sdk-provider-claude-code ai@^6.0.0
|
|
30
31
|
# or explicitly: npm install ai-sdk-provider-claude-code@latest
|
|
31
32
|
```
|
|
32
33
|
|
|
33
|
-
**For AI SDK v5
|
|
34
|
+
**For AI SDK v5:**
|
|
34
35
|
|
|
35
36
|
```bash
|
|
36
|
-
npm install ai-sdk-provider-claude-code@
|
|
37
|
+
npm install ai-sdk-provider-claude-code@ai-sdk-v5 ai@^5.0.0
|
|
37
38
|
```
|
|
38
39
|
|
|
39
40
|
**For AI SDK v4 (legacy):**
|
|
@@ -45,69 +46,17 @@ npm install ai-sdk-provider-claude-code@ai-sdk-v4 ai@^4.3.16
|
|
|
45
46
|
|
|
46
47
|
## Zod Compatibility
|
|
47
48
|
|
|
48
|
-
This package is **
|
|
49
|
-
|
|
50
|
-
### Current Status
|
|
51
|
-
|
|
52
|
-
- ✅ **Zod 3** (fully supported, no warnings)
|
|
53
|
-
- ⚠️ **Zod 4** (functional, but requires `--legacy-peer-deps`)
|
|
54
|
-
|
|
55
|
-
While this package declares support for both versions (`peerDependencies: "zod": "^3.0.0 || ^4.0.0"`), the underlying `@anthropic-ai/claude-agent-sdk` currently only declares support for Zod 3 (`peerDependencies: "zod": "^3.24.1"`).
|
|
56
|
-
|
|
57
|
-
**All 302 tests pass with both Zod 3 and Zod 4.** See `examples/zod4-compatibility-test.ts` for comprehensive compatibility verification.
|
|
58
|
-
|
|
59
|
-
### Installation Instructions
|
|
60
|
-
|
|
61
|
-
**With Zod 3 (recommended for now):**
|
|
49
|
+
This package is **fully compatible with both Zod 3 and Zod 4**.
|
|
62
50
|
|
|
63
51
|
```bash
|
|
52
|
+
# With Zod 3
|
|
64
53
|
npm install ai-sdk-provider-claude-code ai zod@^3.0.0
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
**With Zod 4 (requires package manager-specific flags):**
|
|
68
|
-
|
|
69
|
-
For **npm**:
|
|
70
|
-
|
|
71
|
-
```bash
|
|
72
|
-
npm install ai-sdk-provider-claude-code ai zod@^4.0.0 --legacy-peer-deps
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
For **pnpm**:
|
|
76
|
-
|
|
77
|
-
```bash
|
|
78
|
-
pnpm install ai-sdk-provider-claude-code ai zod@^4.0.0 --no-strict-peer-dependencies
|
|
79
|
-
# Or configure it project-wide:
|
|
80
|
-
pnpm config set strict-peer-dependencies false
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
For **Yarn** (Berry/v2+):
|
|
84
|
-
|
|
85
|
-
```bash
|
|
86
|
-
yarn add ai-sdk-provider-claude-code ai zod@^4.0.0
|
|
87
|
-
# Yarn's peer resolution typically doesn't error here
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
### For Package Developers
|
|
91
|
-
|
|
92
|
-
If you're developing with this package in your repository, add a configuration file to avoid needing the flag on every install:
|
|
93
|
-
|
|
94
|
-
**For npm** (`.npmrc`):
|
|
95
54
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
legacy-peer-deps=true
|
|
55
|
+
# With Zod 4
|
|
56
|
+
npm install ai-sdk-provider-claude-code ai zod@^4.0.0
|
|
99
57
|
```
|
|
100
58
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
```ini
|
|
104
|
-
# .npmrc
|
|
105
|
-
strict-peer-dependencies=false
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
> **Note**: The `.npmrc` file in this repository is committed for CI/development consistency but is **not included in the published package** (it's excluded via the `files` field in `package.json`). End users will still need to use the appropriate flags when installing with Zod 4.
|
|
109
|
-
|
|
110
|
-
> **Temporary Workaround**: This configuration is needed until `@anthropic-ai/claude-agent-sdk` adds official Zod 4 support to their peer dependencies. Track progress in the [claude-agent-sdk repository](https://github.com/anthropics/anthropic-sdk-typescript).
|
|
59
|
+
Both this package and the underlying `@anthropic-ai/claude-agent-sdk` declare support for both versions (`peerDependencies: "zod": "^3.24.1 || ^4.0.0"`).
|
|
111
60
|
|
|
112
61
|
## Installation
|
|
113
62
|
|
|
@@ -121,10 +70,13 @@ claude login
|
|
|
121
70
|
### 2. Add the provider
|
|
122
71
|
|
|
123
72
|
```bash
|
|
124
|
-
# For
|
|
125
|
-
npm install ai-sdk-provider-claude-code ai
|
|
73
|
+
# For AI SDK v6 (recommended)
|
|
74
|
+
npm install ai-sdk-provider-claude-code ai@^6.0.0
|
|
126
75
|
|
|
127
|
-
# For
|
|
76
|
+
# For AI SDK v5
|
|
77
|
+
npm install ai-sdk-provider-claude-code@ai-sdk-v5 ai@^5.0.0
|
|
78
|
+
|
|
79
|
+
# For AI SDK v4 (legacy)
|
|
128
80
|
npm install ai-sdk-provider-claude-code@ai-sdk-v4 ai@^4.3.16
|
|
129
81
|
```
|
|
130
82
|
|
|
@@ -140,7 +92,7 @@ Please ensure you have appropriate permissions and comply with all applicable te
|
|
|
140
92
|
|
|
141
93
|
## Quick Start
|
|
142
94
|
|
|
143
|
-
### AI SDK
|
|
95
|
+
### AI SDK v6
|
|
144
96
|
|
|
145
97
|
```typescript
|
|
146
98
|
import { streamText } from 'ai';
|
|
@@ -155,22 +107,31 @@ const text = await result.text;
|
|
|
155
107
|
console.log(text);
|
|
156
108
|
```
|
|
157
109
|
|
|
158
|
-
### AI SDK
|
|
110
|
+
### AI SDK v5
|
|
159
111
|
|
|
160
112
|
```typescript
|
|
161
|
-
|
|
113
|
+
// npm install ai-sdk-provider-claude-code@ai-sdk-v5 ai@^5.0.0
|
|
114
|
+
import { streamText } from 'ai';
|
|
162
115
|
import { claudeCode } from 'ai-sdk-provider-claude-code';
|
|
163
116
|
|
|
164
|
-
const
|
|
117
|
+
const result = streamText({
|
|
165
118
|
model: claudeCode('haiku'),
|
|
166
119
|
prompt: 'Hello, Claude!',
|
|
167
120
|
});
|
|
168
121
|
|
|
122
|
+
const text = await result.text;
|
|
169
123
|
console.log(text);
|
|
170
124
|
```
|
|
171
125
|
|
|
172
126
|
## Breaking Changes
|
|
173
127
|
|
|
128
|
+
### Version 3.0.0 (AI SDK v6 Stable)
|
|
129
|
+
|
|
130
|
+
This version upgrades to AI SDK v6 stable with updated provider types:
|
|
131
|
+
|
|
132
|
+
- **`usage.raw`** now contains raw provider usage (previously in `providerMetadata['claude-code'].rawUsage`)
|
|
133
|
+
- Internal type changes for `LanguageModelV3Usage` and `LanguageModelV3FinishReason` (transparent to most users)
|
|
134
|
+
|
|
174
135
|
### Version 2.0.0 (Claude Agent SDK Migration)
|
|
175
136
|
|
|
176
137
|
This version migrates to `@anthropic-ai/claude-agent-sdk` with **new defaults for better control**:
|
package/dist/index.cjs
CHANGED
|
@@ -407,13 +407,15 @@ function getErrorMetadata(error) {
|
|
|
407
407
|
function mapClaudeCodeFinishReason(subtype) {
|
|
408
408
|
switch (subtype) {
|
|
409
409
|
case "success":
|
|
410
|
-
return "stop";
|
|
410
|
+
return { unified: "stop", raw: subtype };
|
|
411
411
|
case "error_max_turns":
|
|
412
|
-
return "length";
|
|
412
|
+
return { unified: "length", raw: subtype };
|
|
413
413
|
case "error_during_execution":
|
|
414
|
-
return "error";
|
|
414
|
+
return { unified: "error", raw: subtype };
|
|
415
|
+
case void 0:
|
|
416
|
+
return { unified: "stop", raw: void 0 };
|
|
415
417
|
default:
|
|
416
|
-
return "
|
|
418
|
+
return { unified: "other", raw: subtype };
|
|
417
419
|
}
|
|
418
420
|
}
|
|
419
421
|
|
|
@@ -689,6 +691,42 @@ function isAbortError(err) {
|
|
|
689
691
|
return false;
|
|
690
692
|
}
|
|
691
693
|
var STREAMING_FEATURE_WARNING = "Claude Agent SDK features (hooks/MCP/images) require streaming input. Set `streamingInput: 'always'` or provide `canUseTool` (auto streams only when canUseTool is set).";
|
|
694
|
+
function createEmptyUsage() {
|
|
695
|
+
return {
|
|
696
|
+
inputTokens: {
|
|
697
|
+
total: 0,
|
|
698
|
+
noCache: 0,
|
|
699
|
+
cacheRead: 0,
|
|
700
|
+
cacheWrite: 0
|
|
701
|
+
},
|
|
702
|
+
outputTokens: {
|
|
703
|
+
total: 0,
|
|
704
|
+
text: void 0,
|
|
705
|
+
reasoning: void 0
|
|
706
|
+
},
|
|
707
|
+
raw: void 0
|
|
708
|
+
};
|
|
709
|
+
}
|
|
710
|
+
function convertClaudeCodeUsage(usage) {
|
|
711
|
+
const inputTokens = usage.input_tokens ?? 0;
|
|
712
|
+
const outputTokens = usage.output_tokens ?? 0;
|
|
713
|
+
const cacheWrite = usage.cache_creation_input_tokens ?? 0;
|
|
714
|
+
const cacheRead = usage.cache_read_input_tokens ?? 0;
|
|
715
|
+
return {
|
|
716
|
+
inputTokens: {
|
|
717
|
+
total: inputTokens + cacheWrite + cacheRead,
|
|
718
|
+
noCache: inputTokens,
|
|
719
|
+
cacheRead,
|
|
720
|
+
cacheWrite
|
|
721
|
+
},
|
|
722
|
+
outputTokens: {
|
|
723
|
+
total: outputTokens,
|
|
724
|
+
text: void 0,
|
|
725
|
+
reasoning: void 0
|
|
726
|
+
},
|
|
727
|
+
raw: usage
|
|
728
|
+
};
|
|
729
|
+
}
|
|
692
730
|
function toAsyncIterablePrompt(messagesPrompt, outputStreamEnded, sessionId, contentParts) {
|
|
693
731
|
const content = contentParts && contentParts.length > 0 ? contentParts : [{ type: "text", text: messagesPrompt }];
|
|
694
732
|
const msg = {
|
|
@@ -1042,16 +1080,12 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1042
1080
|
const queryOptions = this.createQueryOptions(abortController, options.responseFormat);
|
|
1043
1081
|
let text = "";
|
|
1044
1082
|
let structuredOutput;
|
|
1045
|
-
let usage =
|
|
1046
|
-
let finishReason = "stop";
|
|
1083
|
+
let usage = createEmptyUsage();
|
|
1084
|
+
let finishReason = { unified: "stop", raw: void 0 };
|
|
1047
1085
|
let wasTruncated = false;
|
|
1048
1086
|
let costUsd;
|
|
1049
1087
|
let durationMs;
|
|
1050
|
-
|
|
1051
|
-
const warnings = this.generateAllWarnings(
|
|
1052
|
-
options,
|
|
1053
|
-
messagesPrompt
|
|
1054
|
-
);
|
|
1088
|
+
const warnings = this.generateAllWarnings(options, messagesPrompt);
|
|
1055
1089
|
if (messageWarnings) {
|
|
1056
1090
|
messageWarnings.forEach((warning) => {
|
|
1057
1091
|
warnings.push({
|
|
@@ -1114,18 +1148,13 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1114
1148
|
`[claude-code] Request completed - Session: ${message.session_id}, Cost: $${costUsd?.toFixed(4) ?? "N/A"}, Duration: ${durationMs ?? "N/A"}ms`
|
|
1115
1149
|
);
|
|
1116
1150
|
if ("usage" in message) {
|
|
1117
|
-
|
|
1118
|
-
usage = {
|
|
1119
|
-
inputTokens: (message.usage.cache_creation_input_tokens ?? 0) + (message.usage.cache_read_input_tokens ?? 0) + (message.usage.input_tokens ?? 0),
|
|
1120
|
-
outputTokens: message.usage.output_tokens ?? 0,
|
|
1121
|
-
totalTokens: (message.usage.cache_creation_input_tokens ?? 0) + (message.usage.cache_read_input_tokens ?? 0) + (message.usage.input_tokens ?? 0) + (message.usage.output_tokens ?? 0)
|
|
1122
|
-
};
|
|
1151
|
+
usage = convertClaudeCodeUsage(message.usage);
|
|
1123
1152
|
this.logger.debug(
|
|
1124
|
-
`[claude-code] Token usage - Input: ${usage.inputTokens}, Output: ${usage.outputTokens
|
|
1153
|
+
`[claude-code] Token usage - Input: ${usage.inputTokens.total}, Output: ${usage.outputTokens.total}`
|
|
1125
1154
|
);
|
|
1126
1155
|
}
|
|
1127
1156
|
finishReason = mapClaudeCodeFinishReason(message.subtype);
|
|
1128
|
-
this.logger.debug(`[claude-code] Finish reason: ${finishReason}`);
|
|
1157
|
+
this.logger.debug(`[claude-code] Finish reason: ${finishReason.unified}`);
|
|
1129
1158
|
} else if (message.type === "system" && message.subtype === "init") {
|
|
1130
1159
|
this.setSessionId(message.session_id);
|
|
1131
1160
|
this.logger.info(`[claude-code] Session initialized: ${message.session_id}`);
|
|
@@ -1145,7 +1174,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1145
1174
|
`[claude-code] Detected truncated response, returning ${text.length} characters of buffered text`
|
|
1146
1175
|
);
|
|
1147
1176
|
wasTruncated = true;
|
|
1148
|
-
finishReason = "length";
|
|
1177
|
+
finishReason = { unified: "length", raw: "truncation" };
|
|
1149
1178
|
warnings.push({
|
|
1150
1179
|
type: "other",
|
|
1151
1180
|
message: CLAUDE_CODE_TRUNCATION_WARNING
|
|
@@ -1177,7 +1206,6 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1177
1206
|
...this.sessionId !== void 0 && { sessionId: this.sessionId },
|
|
1178
1207
|
...costUsd !== void 0 && { costUsd },
|
|
1179
1208
|
...durationMs !== void 0 && { durationMs },
|
|
1180
|
-
...rawUsage !== void 0 && { rawUsage },
|
|
1181
1209
|
...wasTruncated && { truncated: true }
|
|
1182
1210
|
}
|
|
1183
1211
|
}
|
|
@@ -1207,10 +1235,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1207
1235
|
if (queryOptions.includePartialMessages === void 0) {
|
|
1208
1236
|
queryOptions.includePartialMessages = true;
|
|
1209
1237
|
}
|
|
1210
|
-
const warnings = this.generateAllWarnings(
|
|
1211
|
-
options,
|
|
1212
|
-
messagesPrompt
|
|
1213
|
-
);
|
|
1238
|
+
const warnings = this.generateAllWarnings(options, messagesPrompt);
|
|
1214
1239
|
if (messageWarnings) {
|
|
1215
1240
|
messageWarnings.forEach((warning) => {
|
|
1216
1241
|
warnings.push({
|
|
@@ -1275,7 +1300,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1275
1300
|
}
|
|
1276
1301
|
toolStates.clear();
|
|
1277
1302
|
};
|
|
1278
|
-
let usage =
|
|
1303
|
+
let usage = createEmptyUsage();
|
|
1279
1304
|
let accumulatedText = "";
|
|
1280
1305
|
let textPartId;
|
|
1281
1306
|
let streamedTextLength = 0;
|
|
@@ -1573,22 +1598,16 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1573
1598
|
this.logger.info(
|
|
1574
1599
|
`[claude-code] Stream completed - Session: ${message.session_id}, Cost: $${message.total_cost_usd?.toFixed(4) ?? "N/A"}, Duration: ${message.duration_ms ?? "N/A"}ms`
|
|
1575
1600
|
);
|
|
1576
|
-
let rawUsage;
|
|
1577
1601
|
if ("usage" in message) {
|
|
1578
|
-
|
|
1579
|
-
usage = {
|
|
1580
|
-
inputTokens: (message.usage.cache_creation_input_tokens ?? 0) + (message.usage.cache_read_input_tokens ?? 0) + (message.usage.input_tokens ?? 0),
|
|
1581
|
-
outputTokens: message.usage.output_tokens ?? 0,
|
|
1582
|
-
totalTokens: (message.usage.cache_creation_input_tokens ?? 0) + (message.usage.cache_read_input_tokens ?? 0) + (message.usage.input_tokens ?? 0) + (message.usage.output_tokens ?? 0)
|
|
1583
|
-
};
|
|
1602
|
+
usage = convertClaudeCodeUsage(message.usage);
|
|
1584
1603
|
this.logger.debug(
|
|
1585
|
-
`[claude-code] Stream token usage - Input: ${usage.inputTokens}, Output: ${usage.outputTokens
|
|
1604
|
+
`[claude-code] Stream token usage - Input: ${usage.inputTokens.total}, Output: ${usage.outputTokens.total}`
|
|
1586
1605
|
);
|
|
1587
1606
|
}
|
|
1588
1607
|
const finishReason = mapClaudeCodeFinishReason(
|
|
1589
1608
|
message.subtype
|
|
1590
1609
|
);
|
|
1591
|
-
this.logger.debug(`[claude-code] Stream finish reason: ${finishReason}`);
|
|
1610
|
+
this.logger.debug(`[claude-code] Stream finish reason: ${finishReason.unified}`);
|
|
1592
1611
|
this.setSessionId(message.session_id);
|
|
1593
1612
|
const structuredOutput = "structured_output" in message ? message.structured_output : void 0;
|
|
1594
1613
|
const alreadyStreamedJson = textPartId && options.responseFormat?.type === "json" && hasReceivedStreamEvents;
|
|
@@ -1647,7 +1666,6 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1647
1666
|
costUsd: message.total_cost_usd
|
|
1648
1667
|
},
|
|
1649
1668
|
...message.duration_ms !== void 0 && { durationMs: message.duration_ms },
|
|
1650
|
-
...rawUsage !== void 0 && { rawUsage },
|
|
1651
1669
|
// JSON validation warnings are collected during streaming and included
|
|
1652
1670
|
// in providerMetadata since the AI SDK's finish event doesn't support
|
|
1653
1671
|
// a top-level warnings field (unlike stream-start which was already emitted)
|
|
@@ -1710,7 +1728,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
|
|
|
1710
1728
|
const warningsJson = this.serializeWarningsForMetadata(streamWarnings);
|
|
1711
1729
|
controller.enqueue({
|
|
1712
1730
|
type: "finish",
|
|
1713
|
-
finishReason: "length",
|
|
1731
|
+
finishReason: { unified: "length", raw: "truncation" },
|
|
1714
1732
|
usage,
|
|
1715
1733
|
providerMetadata: {
|
|
1716
1734
|
"claude-code": {
|