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/dist/index.js CHANGED
@@ -370,13 +370,15 @@ function getErrorMetadata(error) {
370
370
  function mapClaudeCodeFinishReason(subtype) {
371
371
  switch (subtype) {
372
372
  case "success":
373
- return "stop";
373
+ return { unified: "stop", raw: subtype };
374
374
  case "error_max_turns":
375
- return "length";
375
+ return { unified: "length", raw: subtype };
376
376
  case "error_during_execution":
377
- return "error";
377
+ return { unified: "error", raw: subtype };
378
+ case void 0:
379
+ return { unified: "stop", raw: void 0 };
378
380
  default:
379
- return "stop";
381
+ return { unified: "other", raw: subtype };
380
382
  }
381
383
  }
382
384
 
@@ -652,6 +654,42 @@ function isAbortError(err) {
652
654
  return false;
653
655
  }
654
656
  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).";
657
+ function createEmptyUsage() {
658
+ return {
659
+ inputTokens: {
660
+ total: 0,
661
+ noCache: 0,
662
+ cacheRead: 0,
663
+ cacheWrite: 0
664
+ },
665
+ outputTokens: {
666
+ total: 0,
667
+ text: void 0,
668
+ reasoning: void 0
669
+ },
670
+ raw: void 0
671
+ };
672
+ }
673
+ function convertClaudeCodeUsage(usage) {
674
+ const inputTokens = usage.input_tokens ?? 0;
675
+ const outputTokens = usage.output_tokens ?? 0;
676
+ const cacheWrite = usage.cache_creation_input_tokens ?? 0;
677
+ const cacheRead = usage.cache_read_input_tokens ?? 0;
678
+ return {
679
+ inputTokens: {
680
+ total: inputTokens + cacheWrite + cacheRead,
681
+ noCache: inputTokens,
682
+ cacheRead,
683
+ cacheWrite
684
+ },
685
+ outputTokens: {
686
+ total: outputTokens,
687
+ text: void 0,
688
+ reasoning: void 0
689
+ },
690
+ raw: usage
691
+ };
692
+ }
655
693
  function toAsyncIterablePrompt(messagesPrompt, outputStreamEnded, sessionId, contentParts) {
656
694
  const content = contentParts && contentParts.length > 0 ? contentParts : [{ type: "text", text: messagesPrompt }];
657
695
  const msg = {
@@ -1005,16 +1043,12 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
1005
1043
  const queryOptions = this.createQueryOptions(abortController, options.responseFormat);
1006
1044
  let text = "";
1007
1045
  let structuredOutput;
1008
- let usage = { inputTokens: 0, outputTokens: 0, totalTokens: 0 };
1009
- let finishReason = "stop";
1046
+ let usage = createEmptyUsage();
1047
+ let finishReason = { unified: "stop", raw: void 0 };
1010
1048
  let wasTruncated = false;
1011
1049
  let costUsd;
1012
1050
  let durationMs;
1013
- let rawUsage;
1014
- const warnings = this.generateAllWarnings(
1015
- options,
1016
- messagesPrompt
1017
- );
1051
+ const warnings = this.generateAllWarnings(options, messagesPrompt);
1018
1052
  if (messageWarnings) {
1019
1053
  messageWarnings.forEach((warning) => {
1020
1054
  warnings.push({
@@ -1077,18 +1111,13 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
1077
1111
  `[claude-code] Request completed - Session: ${message.session_id}, Cost: $${costUsd?.toFixed(4) ?? "N/A"}, Duration: ${durationMs ?? "N/A"}ms`
1078
1112
  );
1079
1113
  if ("usage" in message) {
1080
- rawUsage = message.usage;
1081
- usage = {
1082
- inputTokens: (message.usage.cache_creation_input_tokens ?? 0) + (message.usage.cache_read_input_tokens ?? 0) + (message.usage.input_tokens ?? 0),
1083
- outputTokens: message.usage.output_tokens ?? 0,
1084
- 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)
1085
- };
1114
+ usage = convertClaudeCodeUsage(message.usage);
1086
1115
  this.logger.debug(
1087
- `[claude-code] Token usage - Input: ${usage.inputTokens}, Output: ${usage.outputTokens}, Total: ${usage.totalTokens}`
1116
+ `[claude-code] Token usage - Input: ${usage.inputTokens.total}, Output: ${usage.outputTokens.total}`
1088
1117
  );
1089
1118
  }
1090
1119
  finishReason = mapClaudeCodeFinishReason(message.subtype);
1091
- this.logger.debug(`[claude-code] Finish reason: ${finishReason}`);
1120
+ this.logger.debug(`[claude-code] Finish reason: ${finishReason.unified}`);
1092
1121
  } else if (message.type === "system" && message.subtype === "init") {
1093
1122
  this.setSessionId(message.session_id);
1094
1123
  this.logger.info(`[claude-code] Session initialized: ${message.session_id}`);
@@ -1108,7 +1137,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
1108
1137
  `[claude-code] Detected truncated response, returning ${text.length} characters of buffered text`
1109
1138
  );
1110
1139
  wasTruncated = true;
1111
- finishReason = "length";
1140
+ finishReason = { unified: "length", raw: "truncation" };
1112
1141
  warnings.push({
1113
1142
  type: "other",
1114
1143
  message: CLAUDE_CODE_TRUNCATION_WARNING
@@ -1140,7 +1169,6 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
1140
1169
  ...this.sessionId !== void 0 && { sessionId: this.sessionId },
1141
1170
  ...costUsd !== void 0 && { costUsd },
1142
1171
  ...durationMs !== void 0 && { durationMs },
1143
- ...rawUsage !== void 0 && { rawUsage },
1144
1172
  ...wasTruncated && { truncated: true }
1145
1173
  }
1146
1174
  }
@@ -1170,10 +1198,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
1170
1198
  if (queryOptions.includePartialMessages === void 0) {
1171
1199
  queryOptions.includePartialMessages = true;
1172
1200
  }
1173
- const warnings = this.generateAllWarnings(
1174
- options,
1175
- messagesPrompt
1176
- );
1201
+ const warnings = this.generateAllWarnings(options, messagesPrompt);
1177
1202
  if (messageWarnings) {
1178
1203
  messageWarnings.forEach((warning) => {
1179
1204
  warnings.push({
@@ -1238,7 +1263,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
1238
1263
  }
1239
1264
  toolStates.clear();
1240
1265
  };
1241
- let usage = { inputTokens: 0, outputTokens: 0, totalTokens: 0 };
1266
+ let usage = createEmptyUsage();
1242
1267
  let accumulatedText = "";
1243
1268
  let textPartId;
1244
1269
  let streamedTextLength = 0;
@@ -1536,22 +1561,16 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
1536
1561
  this.logger.info(
1537
1562
  `[claude-code] Stream completed - Session: ${message.session_id}, Cost: $${message.total_cost_usd?.toFixed(4) ?? "N/A"}, Duration: ${message.duration_ms ?? "N/A"}ms`
1538
1563
  );
1539
- let rawUsage;
1540
1564
  if ("usage" in message) {
1541
- rawUsage = message.usage;
1542
- usage = {
1543
- inputTokens: (message.usage.cache_creation_input_tokens ?? 0) + (message.usage.cache_read_input_tokens ?? 0) + (message.usage.input_tokens ?? 0),
1544
- outputTokens: message.usage.output_tokens ?? 0,
1545
- 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)
1546
- };
1565
+ usage = convertClaudeCodeUsage(message.usage);
1547
1566
  this.logger.debug(
1548
- `[claude-code] Stream token usage - Input: ${usage.inputTokens}, Output: ${usage.outputTokens}, Total: ${usage.totalTokens}`
1567
+ `[claude-code] Stream token usage - Input: ${usage.inputTokens.total}, Output: ${usage.outputTokens.total}`
1549
1568
  );
1550
1569
  }
1551
1570
  const finishReason = mapClaudeCodeFinishReason(
1552
1571
  message.subtype
1553
1572
  );
1554
- this.logger.debug(`[claude-code] Stream finish reason: ${finishReason}`);
1573
+ this.logger.debug(`[claude-code] Stream finish reason: ${finishReason.unified}`);
1555
1574
  this.setSessionId(message.session_id);
1556
1575
  const structuredOutput = "structured_output" in message ? message.structured_output : void 0;
1557
1576
  const alreadyStreamedJson = textPartId && options.responseFormat?.type === "json" && hasReceivedStreamEvents;
@@ -1610,7 +1629,6 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
1610
1629
  costUsd: message.total_cost_usd
1611
1630
  },
1612
1631
  ...message.duration_ms !== void 0 && { durationMs: message.duration_ms },
1613
- ...rawUsage !== void 0 && { rawUsage },
1614
1632
  // JSON validation warnings are collected during streaming and included
1615
1633
  // in providerMetadata since the AI SDK's finish event doesn't support
1616
1634
  // a top-level warnings field (unlike stream-start which was already emitted)
@@ -1673,7 +1691,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
1673
1691
  const warningsJson = this.serializeWarningsForMetadata(streamWarnings);
1674
1692
  controller.enqueue({
1675
1693
  type: "finish",
1676
- finishReason: "length",
1694
+ finishReason: { unified: "length", raw: "truncation" },
1677
1695
  usage,
1678
1696
  providerMetadata: {
1679
1697
  "claude-code": {