ai-sdk-provider-claude-code 3.1.0 → 3.2.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 CHANGED
@@ -46,17 +46,13 @@ npm install ai-sdk-provider-claude-code@ai-sdk-v4 ai@^4.3.16
46
46
 
47
47
  ## Zod Compatibility
48
48
 
49
- This package is **fully compatible with both Zod 3 and Zod 4**.
49
+ **Starting from v3.2.0, this package requires Zod 4.**
50
50
 
51
51
  ```bash
52
- # With Zod 3
53
- npm install ai-sdk-provider-claude-code ai zod@^3.0.0
54
-
55
- # With Zod 4
56
52
  npm install ai-sdk-provider-claude-code ai zod@^4.0.0
57
53
  ```
58
54
 
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"`).
55
+ > **Note:** Zod 3 support was dropped in v3.2.0 due to the underlying `@anthropic-ai/claude-agent-sdk@0.2.x` requiring Zod 4. If you need Zod 3 support, use `ai-sdk-provider-claude-code@3.1.x`.
60
56
 
61
57
  ## Installation
62
58
 
@@ -271,11 +267,31 @@ console.log(result.object); // Guaranteed to match schema
271
267
 
272
268
  ## Agent SDK Options (Advanced)
273
269
 
274
- This provider now exposes additional Agent SDK options directly (e.g. `betas`, `sandbox`,
275
- `plugins`, `resumeSessionAt`, `enableFileCheckpointing`, `maxBudgetUsd`, `tools`,
276
- `allowDangerouslySkipPermissions`).
270
+ This provider exposes Agent SDK options directly. Key options include:
271
+
272
+ | Option | Description |
273
+ | --------------------------------- | --------------------------------------------------------------------------------------------------------- |
274
+ | `betas` | Enable beta features (e.g., `['context-1m-2025-08-07']`) |
275
+ | `sandbox` | Configure sandbox behavior (`{ enabled: true }`) |
276
+ | `plugins` | Load custom plugins from local paths |
277
+ | `resumeSessionAt` | Resume session at a specific message UUID |
278
+ | `enableFileCheckpointing` | Enable file rewind support |
279
+ | `maxBudgetUsd` | Maximum budget in USD for the query |
280
+ | `tools` | Tool configuration (array of names or preset) |
281
+ | `allowDangerouslySkipPermissions` | Allow bypassing permissions |
282
+ | `persistSession` | When `false`, disables session persistence to disk (v3.2.0+) |
283
+ | `spawnClaudeCodeProcess` | Custom process spawner for VMs/containers (v3.2.0+) |
284
+ | `permissionMode` | Permission mode: `'default'`, `'acceptEdits'`, `'bypassPermissions'`, `'plan'`, `'delegate'`, `'dontAsk'` |
285
+
286
+ **Agent definitions** (`agents`) now support additional fields (v3.2.0+):
287
+
288
+ - `disallowedTools` - Tools to explicitly disallow for the agent
289
+ - `mcpServers` - MCP servers available to the agent
290
+ - `criticalSystemReminder_EXPERIMENTAL` - Experimental critical reminder
291
+
292
+ See [`ClaudeCodeSettings`](https://github.com/ben-vargas/ai-sdk-provider-claude-code/blob/main/src/types.ts) for the full list of supported options (e.g., `allowedTools`, `disallowedTools`, `hooks`, `canUseTool`, `env`, `settingSources`).
277
293
 
278
- For newer SDK options, use the `sdkOptions` escape hatch. It **overrides** explicit settings,
294
+ For options not explicitly exposed, use the `sdkOptions` escape hatch. It **overrides** explicit settings,
279
295
  but provider-managed fields are ignored (`model`, `abortController`, `prompt`, `outputFormat`).
280
296
  If you set `sdkOptions.resume`, it also drives the streaming prompt `session_id` so the SDK
281
297
  and prompt target the same session.
@@ -284,6 +300,7 @@ and prompt target the same session.
284
300
  const model = claudeCode('sonnet', {
285
301
  betas: ['context-1m-2025-08-07'],
286
302
  sandbox: { enabled: true },
303
+ persistSession: false, // Don't persist session to disk
287
304
  sdkOptions: {
288
305
  maxBudgetUsd: 1,
289
306
  resume: 'session-abc',
package/dist/index.cjs CHANGED
@@ -461,7 +461,7 @@ var claudeCodeSettingsSchema = import_zod.z.object({
461
461
  ).optional(),
462
462
  executable: import_zod.z.enum(["bun", "deno", "node"]).optional(),
463
463
  executableArgs: import_zod.z.array(import_zod.z.string()).optional(),
464
- permissionMode: import_zod.z.enum(["default", "acceptEdits", "bypassPermissions", "plan"]).optional(),
464
+ permissionMode: import_zod.z.enum(["default", "acceptEdits", "bypassPermissions", "plan", "delegate", "dontAsk"]).optional(),
465
465
  permissionPromptToolName: import_zod.z.string().optional(),
466
466
  continue: import_zod.z.boolean().optional(),
467
467
  resume: import_zod.z.string().optional(),
@@ -542,9 +542,18 @@ var claudeCodeSettingsSchema = import_zod.z.object({
542
542
  import_zod.z.object({
543
543
  description: import_zod.z.string(),
544
544
  tools: import_zod.z.array(import_zod.z.string()).optional(),
545
+ disallowedTools: import_zod.z.array(import_zod.z.string()).optional(),
545
546
  prompt: import_zod.z.string(),
546
- model: import_zod.z.enum(["sonnet", "opus", "haiku", "inherit"]).optional()
547
- })
547
+ model: import_zod.z.enum(["sonnet", "opus", "haiku", "inherit"]).optional(),
548
+ mcpServers: import_zod.z.array(
549
+ import_zod.z.union([
550
+ import_zod.z.string(),
551
+ import_zod.z.record(import_zod.z.string(), import_zod.z.any())
552
+ // McpServerConfigForProcessTransport
553
+ ])
554
+ ).optional(),
555
+ criticalSystemReminder_EXPERIMENTAL: import_zod.z.string().optional()
556
+ }).passthrough()
548
557
  ).optional(),
549
558
  includePartialMessages: import_zod.z.boolean().optional(),
550
559
  fallbackModel: import_zod.z.string().optional(),
@@ -554,6 +563,10 @@ var claudeCodeSettingsSchema = import_zod.z.object({
554
563
  }).optional(),
555
564
  strictMcpConfig: import_zod.z.boolean().optional(),
556
565
  extraArgs: import_zod.z.record(import_zod.z.string(), import_zod.z.union([import_zod.z.string(), import_zod.z.null()])).optional(),
566
+ persistSession: import_zod.z.boolean().optional(),
567
+ spawnClaudeCodeProcess: import_zod.z.any().refine((val) => val === void 0 || typeof val === "function", {
568
+ message: "spawnClaudeCodeProcess must be a function"
569
+ }).optional(),
557
570
  sdkOptions: import_zod.z.record(import_zod.z.string(), import_zod.z.any()).optional()
558
571
  }).strict();
559
572
  function validateModelId(modelId) {
@@ -1045,6 +1058,12 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
1045
1058
  if (this.settings.extraArgs !== void 0) {
1046
1059
  opts.extraArgs = this.settings.extraArgs;
1047
1060
  }
1061
+ if (this.settings.persistSession !== void 0) {
1062
+ opts.persistSession = this.settings.persistSession;
1063
+ }
1064
+ if (this.settings.spawnClaudeCodeProcess !== void 0) {
1065
+ opts.spawnClaudeCodeProcess = this.settings.spawnClaudeCodeProcess;
1066
+ }
1048
1067
  if (this.settings.hooks) {
1049
1068
  opts.hooks = this.settings.hooks;
1050
1069
  }
@@ -1412,6 +1431,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
1412
1431
  let textPartId;
1413
1432
  let streamedTextLength = 0;
1414
1433
  let hasReceivedStreamEvents = false;
1434
+ let hasStreamedJson = false;
1415
1435
  try {
1416
1436
  controller.enqueue({ type: "stream-start", warnings });
1417
1437
  if (effectiveCanUseTool && effectivePermissionPromptToolName) {
@@ -1478,6 +1498,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
1478
1498
  });
1479
1499
  accumulatedText += jsonDelta;
1480
1500
  streamedTextLength += jsonDelta.length;
1501
+ hasStreamedJson = true;
1481
1502
  }
1482
1503
  }
1483
1504
  continue;
@@ -1490,7 +1511,15 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
1490
1511
  continue;
1491
1512
  }
1492
1513
  const content = message.message.content;
1493
- for (const tool3 of this.extractToolUses(content)) {
1514
+ const tools = this.extractToolUses(content);
1515
+ if (textPartId && tools.length > 0) {
1516
+ controller.enqueue({
1517
+ type: "text-end",
1518
+ id: textPartId
1519
+ });
1520
+ textPartId = void 0;
1521
+ }
1522
+ for (const tool3 of tools) {
1494
1523
  const toolId = tool3.id;
1495
1524
  let state = toolStates.get(toolId);
1496
1525
  if (!state) {
@@ -1721,12 +1750,14 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
1721
1750
  this.logger.debug(`[claude-code] Stream finish reason: ${finishReason.unified}`);
1722
1751
  this.setSessionId(message.session_id);
1723
1752
  const structuredOutput = "structured_output" in message ? message.structured_output : void 0;
1724
- const alreadyStreamedJson = textPartId && options.responseFormat?.type === "json" && hasReceivedStreamEvents;
1725
- if (alreadyStreamedJson && textPartId) {
1726
- controller.enqueue({
1727
- type: "text-end",
1728
- id: textPartId
1729
- });
1753
+ const alreadyStreamedJson = hasStreamedJson && options.responseFormat?.type === "json" && hasReceivedStreamEvents;
1754
+ if (alreadyStreamedJson) {
1755
+ if (textPartId) {
1756
+ controller.enqueue({
1757
+ type: "text-end",
1758
+ id: textPartId
1759
+ });
1760
+ }
1730
1761
  } else if (structuredOutput !== void 0) {
1731
1762
  const jsonTextId = (0, import_provider_utils.generateId)();
1732
1763
  const jsonText = JSON.stringify(structuredOutput);