ai-sdk-provider-claude-code 3.2.1 → 3.3.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 CHANGED
@@ -361,6 +361,31 @@ See [examples/skills-management.ts](examples/skills-management.ts) for more exam
361
361
  - For parity with other tool events, `tool-error` includes `providerExecuted: true` and `providerMetadata['claude-code']` (e.g., `rawError`). These fields are documented extensions; downstream consumers may safely ignore them if unused.
362
362
  - See Tool Streaming Support for full event list, ordering guarantees, and performance considerations.
363
363
 
364
+ ## Content Block Streaming
365
+
366
+ This provider handles Anthropic `content_block_*` stream events directly for more responsive UIs:
367
+
368
+ - **Tool input streaming** — `tool-input-delta` streams arguments incrementally; `tool-call` emits when the tool input block completes (before results), enabling “running” state in UIs.
369
+ - **Text streaming** — `text-start/delta/end` emitted from content blocks with proper lifecycle management.
370
+ - **Extended thinking** — `reasoning-start/delta/end` emitted from `thinking` content blocks (availability depends on model and request).
371
+
372
+ For subagent parent/child tracking, see **Subagent Hierarchy Tracking** in this README.
373
+
374
+ ## Subagent Hierarchy Tracking
375
+
376
+ When Claude Code spawns subagents via the `Task` tool, this provider exposes parent-child relationships through `providerMetadata`:
377
+
378
+ ```ts
379
+ // Available on tool-input-start, tool-call, tool-result, and tool-error events
380
+ providerMetadata['claude-code'].parentToolCallId: string | null;
381
+ ```
382
+
383
+ - Task tools: Always null (top-level)
384
+ - Child tools: Reference their parent Task's ID
385
+ - Parallel Tasks: Child returns null if parent is ambiguous
386
+
387
+ This enables UIs to build hierarchical views of nested agent execution.
388
+
364
389
  ## Contributing
365
390
 
366
391
  We welcome contributions, especially:
package/dist/index.cjs CHANGED
@@ -567,7 +567,8 @@ var claudeCodeSettingsSchema = import_zod.z.object({
567
567
  spawnClaudeCodeProcess: import_zod.z.any().refine((val) => val === void 0 || typeof val === "function", {
568
568
  message: "spawnClaudeCodeProcess must be a function"
569
569
  }).optional(),
570
- sdkOptions: import_zod.z.record(import_zod.z.string(), import_zod.z.any()).optional()
570
+ sdkOptions: import_zod.z.record(import_zod.z.string(), import_zod.z.any()).optional(),
571
+ maxToolResultSize: import_zod.z.number().int().min(100).max(1e6).optional()
571
572
  }).strict();
572
573
  function validateModelId(modelId) {
573
574
  const knownModels = ["opus", "sonnet", "haiku"];
@@ -732,6 +733,37 @@ function isAbortError(err) {
732
733
  }
733
734
  return false;
734
735
  }
736
+ var DEFAULT_INHERITED_ENV_VARS = process.platform === "win32" ? [
737
+ "APPDATA",
738
+ "HOMEDRIVE",
739
+ "HOMEPATH",
740
+ "LOCALAPPDATA",
741
+ "PATH",
742
+ "PATHEXT",
743
+ "SYSTEMDRIVE",
744
+ "SYSTEMROOT",
745
+ "TEMP",
746
+ "TMP",
747
+ "USERNAME",
748
+ "USERPROFILE",
749
+ "WINDIR"
750
+ ] : ["HOME", "LOGNAME", "PATH", "SHELL", "TERM", "USER", "LANG", "LC_ALL", "TMPDIR"];
751
+ var CLAUDE_ENV_VARS = ["CLAUDE_CONFIG_DIR"];
752
+ function getBaseProcessEnv() {
753
+ const env = {};
754
+ const allowedKeys = /* @__PURE__ */ new Set([...DEFAULT_INHERITED_ENV_VARS, ...CLAUDE_ENV_VARS]);
755
+ for (const key of allowedKeys) {
756
+ const value = process.env[key];
757
+ if (typeof value !== "string") {
758
+ continue;
759
+ }
760
+ if (value.startsWith("()")) {
761
+ continue;
762
+ }
763
+ env[key] = value;
764
+ }
765
+ return env;
766
+ }
735
767
  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).";
736
768
  var SDK_OPTIONS_BLOCKLIST = /* @__PURE__ */ new Set(["model", "abortController", "prompt", "outputFormat"]);
737
769
  function createEmptyUsage() {
@@ -793,6 +825,49 @@ var modelMap = {
793
825
  sonnet: "sonnet",
794
826
  haiku: "haiku"
795
827
  };
828
+ var MAX_TOOL_RESULT_SIZE = 1e4;
829
+ function truncateToolResultForStream(result, maxSize = MAX_TOOL_RESULT_SIZE) {
830
+ if (typeof result === "string") {
831
+ if (result.length <= maxSize) return result;
832
+ return result.slice(0, maxSize) + `
833
+ ...[truncated ${result.length - maxSize} chars]`;
834
+ }
835
+ if (typeof result !== "object" || result === null) return result;
836
+ if (Array.isArray(result)) {
837
+ let largestIndex = -1;
838
+ let largestSize2 = 0;
839
+ for (let i = 0; i < result.length; i++) {
840
+ const value = result[i];
841
+ if (typeof value === "string" && value.length > largestSize2) {
842
+ largestIndex = i;
843
+ largestSize2 = value.length;
844
+ }
845
+ }
846
+ if (largestIndex >= 0 && largestSize2 > maxSize) {
847
+ const truncatedValue = result[largestIndex].slice(0, maxSize) + `
848
+ ...[truncated ${largestSize2 - maxSize} chars]`;
849
+ const cloned = [...result];
850
+ cloned[largestIndex] = truncatedValue;
851
+ return cloned;
852
+ }
853
+ return result;
854
+ }
855
+ const obj = result;
856
+ let largestKey = null;
857
+ let largestSize = 0;
858
+ for (const [key, value] of Object.entries(obj)) {
859
+ if (typeof value === "string" && value.length > largestSize) {
860
+ largestKey = key;
861
+ largestSize = value.length;
862
+ }
863
+ }
864
+ if (largestKey && largestSize > maxSize) {
865
+ const truncatedValue = obj[largestKey].slice(0, maxSize) + `
866
+ ...[truncated ${largestSize - maxSize} chars]`;
867
+ return { ...obj, [largestKey]: truncatedValue };
868
+ }
869
+ return result;
870
+ }
796
871
  var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
797
872
  specificationVersion = "v3";
798
873
  defaultObjectGenerationMode = "json";
@@ -864,11 +939,12 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
864
939
  return content.filter(
865
940
  (item) => typeof item === "object" && item !== null && "type" in item && item.type === "tool_use"
866
941
  ).map((item) => {
867
- const { id, name, input } = item;
942
+ const { id, name, input, parent_tool_use_id } = item;
868
943
  return {
869
944
  id: typeof id === "string" && id.length > 0 ? id : (0, import_provider_utils.generateId)(),
870
945
  name: typeof name === "string" && name.length > 0 ? name : _ClaudeCodeLanguageModel.UNKNOWN_TOOL_NAME,
871
- input
946
+ input,
947
+ parentToolUseId: typeof parent_tool_use_id === "string" ? parent_tool_use_id : null
872
948
  };
873
949
  });
874
950
  }
@@ -940,6 +1016,27 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
940
1016
  return result;
941
1017
  }
942
1018
  }
1019
+ if (Array.isArray(result) && result.length > 0) {
1020
+ const textBlocks = result.filter(
1021
+ (block) => block?.type === "text" && typeof block.text === "string"
1022
+ ).map((block) => block.text);
1023
+ if (textBlocks.length !== result.length) {
1024
+ return result;
1025
+ }
1026
+ if (textBlocks.length === 1) {
1027
+ try {
1028
+ return JSON.parse(textBlocks[0]);
1029
+ } catch {
1030
+ return textBlocks[0];
1031
+ }
1032
+ }
1033
+ const combined = textBlocks.join("\n");
1034
+ try {
1035
+ return JSON.parse(combined);
1036
+ } catch {
1037
+ return combined;
1038
+ }
1039
+ }
943
1040
  return result;
944
1041
  }
945
1042
  generateAllWarnings(options, prompt) {
@@ -1084,7 +1181,8 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
1084
1181
  };
1085
1182
  }
1086
1183
  if (this.settings.env !== void 0 || sdkEnv !== void 0) {
1087
- opts.env = { ...process.env, ...this.settings.env, ...sdkEnv };
1184
+ const baseEnv = getBaseProcessEnv();
1185
+ opts.env = { ...baseEnv, ...this.settings.env, ...sdkEnv };
1088
1186
  }
1089
1187
  if (responseFormat?.type === "json" && responseFormat.schema) {
1090
1188
  opts.outputFormat = {
@@ -1386,6 +1484,13 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
1386
1484
  done = () => resolve(void 0);
1387
1485
  });
1388
1486
  const toolStates = /* @__PURE__ */ new Map();
1487
+ const activeTaskTools = /* @__PURE__ */ new Map();
1488
+ const getFallbackParentId = () => {
1489
+ if (activeTaskTools.size === 1) {
1490
+ return activeTaskTools.keys().next().value ?? null;
1491
+ }
1492
+ return null;
1493
+ };
1389
1494
  const streamWarnings = [];
1390
1495
  const closeToolInput = (toolId, state) => {
1391
1496
  if (!state.inputClosed && state.inputStarted) {
@@ -1414,7 +1519,8 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
1414
1519
  // rawInput preserves the original serialized format before AI SDK normalization.
1415
1520
  // Use this if you need the exact string sent to the Claude CLI, which may differ
1416
1521
  // from the `input` field after AI SDK processing.
1417
- rawInput: state.lastSerializedInput ?? ""
1522
+ rawInput: state.lastSerializedInput ?? "",
1523
+ parentToolCallId: state.parentToolCallId ?? null
1418
1524
  }
1419
1525
  }
1420
1526
  });
@@ -1432,6 +1538,12 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
1432
1538
  let streamedTextLength = 0;
1433
1539
  let hasReceivedStreamEvents = false;
1434
1540
  let hasStreamedJson = false;
1541
+ const toolBlocksByIndex = /* @__PURE__ */ new Map();
1542
+ const toolInputAccumulators = /* @__PURE__ */ new Map();
1543
+ const textBlocksByIndex = /* @__PURE__ */ new Map();
1544
+ let textStreamedViaContentBlock = false;
1545
+ const reasoningBlocksByIndex = /* @__PURE__ */ new Map();
1546
+ let currentReasoningPartId;
1435
1547
  try {
1436
1548
  controller.enqueue({ type: "stream-start", warnings });
1437
1549
  if (effectiveCanUseTool && effectivePermissionPromptToolName) {
@@ -1483,6 +1595,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
1483
1595
  if (event.type === "content_block_delta" && event.delta.type === "input_json_delta" && "partial_json" in event.delta && event.delta.partial_json) {
1484
1596
  const jsonDelta = event.delta.partial_json;
1485
1597
  hasReceivedStreamEvents = true;
1598
+ const blockIndex = "index" in event ? event.index : -1;
1486
1599
  if (options.responseFormat?.type === "json") {
1487
1600
  if (!textPartId) {
1488
1601
  textPartId = (0, import_provider_utils.generateId)();
@@ -1499,6 +1612,189 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
1499
1612
  accumulatedText += jsonDelta;
1500
1613
  streamedTextLength += jsonDelta.length;
1501
1614
  hasStreamedJson = true;
1615
+ continue;
1616
+ }
1617
+ const toolId = toolBlocksByIndex.get(blockIndex);
1618
+ if (toolId) {
1619
+ const accumulated = (toolInputAccumulators.get(toolId) ?? "") + jsonDelta;
1620
+ toolInputAccumulators.set(toolId, accumulated);
1621
+ controller.enqueue({
1622
+ type: "tool-input-delta",
1623
+ id: toolId,
1624
+ delta: jsonDelta
1625
+ });
1626
+ continue;
1627
+ }
1628
+ }
1629
+ if (event.type === "content_block_start" && "content_block" in event && event.content_block?.type === "tool_use") {
1630
+ const blockIndex = "index" in event ? event.index : -1;
1631
+ const toolBlock = event.content_block;
1632
+ const toolId = typeof toolBlock.id === "string" && toolBlock.id.length > 0 ? toolBlock.id : (0, import_provider_utils.generateId)();
1633
+ const toolName = typeof toolBlock.name === "string" && toolBlock.name.length > 0 ? toolBlock.name : _ClaudeCodeLanguageModel.UNKNOWN_TOOL_NAME;
1634
+ hasReceivedStreamEvents = true;
1635
+ if (textPartId) {
1636
+ controller.enqueue({
1637
+ type: "text-end",
1638
+ id: textPartId
1639
+ });
1640
+ textPartId = void 0;
1641
+ }
1642
+ toolBlocksByIndex.set(blockIndex, toolId);
1643
+ toolInputAccumulators.set(toolId, "");
1644
+ let state = toolStates.get(toolId);
1645
+ if (!state) {
1646
+ const currentParentId = toolName === "Task" ? null : getFallbackParentId();
1647
+ state = {
1648
+ name: toolName,
1649
+ inputStarted: false,
1650
+ inputClosed: false,
1651
+ callEmitted: false,
1652
+ parentToolCallId: currentParentId
1653
+ };
1654
+ toolStates.set(toolId, state);
1655
+ }
1656
+ if (!state.inputStarted) {
1657
+ this.logger.debug(
1658
+ `[claude-code] Tool input started (content_block) - Tool: ${toolName}, ID: ${toolId}, parent: ${state.parentToolCallId}`
1659
+ );
1660
+ controller.enqueue({
1661
+ type: "tool-input-start",
1662
+ id: toolId,
1663
+ toolName,
1664
+ providerExecuted: true,
1665
+ dynamic: true,
1666
+ providerMetadata: {
1667
+ "claude-code": {
1668
+ parentToolCallId: state.parentToolCallId ?? null
1669
+ }
1670
+ }
1671
+ });
1672
+ if (toolName === "Task") {
1673
+ activeTaskTools.set(toolId, { startTime: Date.now() });
1674
+ }
1675
+ state.inputStarted = true;
1676
+ }
1677
+ continue;
1678
+ }
1679
+ if (event.type === "content_block_start" && "content_block" in event && event.content_block?.type === "text") {
1680
+ const blockIndex = "index" in event ? event.index : -1;
1681
+ hasReceivedStreamEvents = true;
1682
+ const partId = (0, import_provider_utils.generateId)();
1683
+ textBlocksByIndex.set(blockIndex, partId);
1684
+ textPartId = partId;
1685
+ this.logger.debug(
1686
+ `[claude-code] Text content block started - Index: ${blockIndex}, ID: ${partId}`
1687
+ );
1688
+ controller.enqueue({
1689
+ type: "text-start",
1690
+ id: partId
1691
+ });
1692
+ textStreamedViaContentBlock = true;
1693
+ continue;
1694
+ }
1695
+ if (event.type === "content_block_start" && "content_block" in event && event.content_block?.type === "thinking") {
1696
+ const blockIndex = "index" in event ? event.index : -1;
1697
+ hasReceivedStreamEvents = true;
1698
+ if (textPartId) {
1699
+ controller.enqueue({
1700
+ type: "text-end",
1701
+ id: textPartId
1702
+ });
1703
+ textPartId = void 0;
1704
+ }
1705
+ const reasoningPartId = (0, import_provider_utils.generateId)();
1706
+ reasoningBlocksByIndex.set(blockIndex, reasoningPartId);
1707
+ currentReasoningPartId = reasoningPartId;
1708
+ this.logger.debug(
1709
+ `[claude-code] Reasoning started (content_block) - ID: ${reasoningPartId}`
1710
+ );
1711
+ controller.enqueue({
1712
+ type: "reasoning-start",
1713
+ id: reasoningPartId
1714
+ });
1715
+ continue;
1716
+ }
1717
+ if (event.type === "content_block_delta" && event.delta.type === "thinking_delta" && "thinking" in event.delta && event.delta.thinking) {
1718
+ const blockIndex = "index" in event ? event.index : -1;
1719
+ const reasoningPartId = reasoningBlocksByIndex.get(blockIndex) ?? currentReasoningPartId;
1720
+ hasReceivedStreamEvents = true;
1721
+ if (reasoningPartId) {
1722
+ controller.enqueue({
1723
+ type: "reasoning-delta",
1724
+ id: reasoningPartId,
1725
+ delta: event.delta.thinking
1726
+ });
1727
+ }
1728
+ continue;
1729
+ }
1730
+ if (event.type === "content_block_stop") {
1731
+ const blockIndex = "index" in event ? event.index : -1;
1732
+ hasReceivedStreamEvents = true;
1733
+ const toolId = toolBlocksByIndex.get(blockIndex);
1734
+ if (toolId) {
1735
+ const state = toolStates.get(toolId);
1736
+ if (state && !state.inputClosed) {
1737
+ const accumulatedInput = toolInputAccumulators.get(toolId) ?? "";
1738
+ this.logger.debug(
1739
+ `[claude-code] Tool content block stopped - Index: ${blockIndex}, Tool: ${state.name}, ID: ${toolId}`
1740
+ );
1741
+ controller.enqueue({
1742
+ type: "tool-input-end",
1743
+ id: toolId
1744
+ });
1745
+ state.inputClosed = true;
1746
+ state.lastSerializedInput = accumulatedInput;
1747
+ if (!state.callEmitted) {
1748
+ controller.enqueue({
1749
+ type: "tool-call",
1750
+ toolCallId: toolId,
1751
+ toolName: state.name,
1752
+ input: accumulatedInput,
1753
+ providerExecuted: true,
1754
+ dynamic: true,
1755
+ providerMetadata: {
1756
+ "claude-code": {
1757
+ rawInput: accumulatedInput,
1758
+ parentToolCallId: state.parentToolCallId ?? null
1759
+ }
1760
+ }
1761
+ });
1762
+ state.callEmitted = true;
1763
+ }
1764
+ }
1765
+ toolBlocksByIndex.delete(blockIndex);
1766
+ toolInputAccumulators.delete(toolId);
1767
+ continue;
1768
+ }
1769
+ const textId = textBlocksByIndex.get(blockIndex);
1770
+ if (textId) {
1771
+ this.logger.debug(
1772
+ `[claude-code] Text content block stopped - Index: ${blockIndex}, ID: ${textId}`
1773
+ );
1774
+ controller.enqueue({
1775
+ type: "text-end",
1776
+ id: textId
1777
+ });
1778
+ textBlocksByIndex.delete(blockIndex);
1779
+ if (textPartId === textId) {
1780
+ textPartId = void 0;
1781
+ }
1782
+ continue;
1783
+ }
1784
+ const reasoningPartId = reasoningBlocksByIndex.get(blockIndex);
1785
+ if (reasoningPartId) {
1786
+ this.logger.debug(
1787
+ `[claude-code] Reasoning ended (content_block) - ID: ${reasoningPartId}`
1788
+ );
1789
+ controller.enqueue({
1790
+ type: "reasoning-end",
1791
+ id: reasoningPartId
1792
+ });
1793
+ reasoningBlocksByIndex.delete(blockIndex);
1794
+ if (currentReasoningPartId === reasoningPartId) {
1795
+ currentReasoningPartId = void 0;
1796
+ }
1797
+ continue;
1502
1798
  }
1503
1799
  }
1504
1800
  continue;
@@ -1510,6 +1806,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
1510
1806
  );
1511
1807
  continue;
1512
1808
  }
1809
+ const sdkParentToolUseId = message.parent_tool_use_id;
1513
1810
  const content = message.message.content;
1514
1811
  const tools = this.extractToolUses(content);
1515
1812
  if (textPartId && tools.length > 0) {
@@ -1523,15 +1820,22 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
1523
1820
  const toolId = tool3.id;
1524
1821
  let state = toolStates.get(toolId);
1525
1822
  if (!state) {
1823
+ const currentParentId = tool3.name === "Task" ? null : sdkParentToolUseId ?? tool3.parentToolUseId ?? getFallbackParentId();
1526
1824
  state = {
1527
1825
  name: tool3.name,
1528
1826
  inputStarted: false,
1529
1827
  inputClosed: false,
1530
- callEmitted: false
1828
+ callEmitted: false,
1829
+ parentToolCallId: currentParentId
1531
1830
  };
1532
1831
  toolStates.set(toolId, state);
1533
1832
  this.logger.debug(
1534
- `[claude-code] New tool use detected - Tool: ${tool3.name}, ID: ${toolId}`
1833
+ `[claude-code] New tool use detected - Tool: ${tool3.name}, ID: ${toolId}, SDK parent: ${sdkParentToolUseId}, resolved parent: ${currentParentId}`
1834
+ );
1835
+ } else if (!state.parentToolCallId && sdkParentToolUseId && tool3.name !== "Task") {
1836
+ state.parentToolCallId = sdkParentToolUseId;
1837
+ this.logger.debug(
1838
+ `[claude-code] Retroactive parent context - Tool: ${tool3.name}, ID: ${toolId}, parent: ${sdkParentToolUseId}`
1535
1839
  );
1536
1840
  }
1537
1841
  state.name = tool3.name;
@@ -1544,9 +1848,17 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
1544
1848
  id: toolId,
1545
1849
  toolName: tool3.name,
1546
1850
  providerExecuted: true,
1547
- dynamic: true
1851
+ dynamic: true,
1548
1852
  // V3 field: indicates tool is provider-defined
1853
+ providerMetadata: {
1854
+ "claude-code": {
1855
+ parentToolCallId: state.parentToolCallId ?? null
1856
+ }
1857
+ }
1549
1858
  });
1859
+ if (tool3.name === "Task") {
1860
+ activeTaskTools.set(toolId, { startTime: Date.now() });
1861
+ }
1550
1862
  state.inputStarted = true;
1551
1863
  }
1552
1864
  const serializedInput = this.serializeToolInput(tool3.input);
@@ -1617,6 +1929,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
1617
1929
  );
1618
1930
  continue;
1619
1931
  }
1932
+ const sdkParentToolUseIdForResults = message.parent_tool_use_id;
1620
1933
  const content = message.message.content;
1621
1934
  for (const result of this.extractToolResults(content)) {
1622
1935
  let state = toolStates.get(result.id);
@@ -1628,11 +1941,13 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
1628
1941
  this.logger.warn(
1629
1942
  `[claude-code] Received tool result for unknown tool ID: ${result.id}`
1630
1943
  );
1944
+ const resolvedParentId = toolName === "Task" ? null : sdkParentToolUseIdForResults ?? getFallbackParentId();
1631
1945
  state = {
1632
1946
  name: toolName,
1633
1947
  inputStarted: false,
1634
1948
  inputClosed: false,
1635
- callEmitted: false
1949
+ callEmitted: false,
1950
+ parentToolCallId: resolvedParentId
1636
1951
  };
1637
1952
  toolStates.set(result.id, state);
1638
1953
  if (!state.inputStarted) {
@@ -1641,8 +1956,13 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
1641
1956
  id: result.id,
1642
1957
  toolName,
1643
1958
  providerExecuted: true,
1644
- dynamic: true
1959
+ dynamic: true,
1645
1960
  // V3 field: indicates tool is provider-defined
1961
+ providerMetadata: {
1962
+ "claude-code": {
1963
+ parentToolCallId: state.parentToolCallId ?? null
1964
+ }
1965
+ }
1646
1966
  });
1647
1967
  state.inputStarted = true;
1648
1968
  }
@@ -1663,12 +1983,25 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
1663
1983
  return String(result.result);
1664
1984
  }
1665
1985
  })();
1986
+ const maxToolResultSize = this.settings.maxToolResultSize;
1987
+ const truncatedResult = truncateToolResultForStream(
1988
+ normalizedResult,
1989
+ maxToolResultSize
1990
+ );
1991
+ const truncatedRawResult = truncateToolResultForStream(
1992
+ rawResult,
1993
+ maxToolResultSize
1994
+ );
1995
+ const rawResultTruncated = truncatedRawResult !== rawResult;
1666
1996
  emitToolCall(result.id, state);
1997
+ if (toolName === "Task") {
1998
+ activeTaskTools.delete(result.id);
1999
+ }
1667
2000
  controller.enqueue({
1668
2001
  type: "tool-result",
1669
2002
  toolCallId: result.id,
1670
2003
  toolName,
1671
- result: normalizedResult,
2004
+ result: truncatedResult,
1672
2005
  isError: result.isError,
1673
2006
  providerExecuted: true,
1674
2007
  dynamic: true,
@@ -1678,7 +2011,9 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
1678
2011
  // rawResult preserves the original CLI output string before JSON parsing.
1679
2012
  // Use this when you need the exact string returned by the tool, especially
1680
2013
  // if the `result` field has been parsed/normalized and you need the original format.
1681
- rawResult
2014
+ rawResult: truncatedRawResult,
2015
+ rawResultTruncated,
2016
+ parentToolCallId: state.parentToolCallId ?? null
1682
2017
  }
1683
2018
  }
1684
2019
  });
@@ -1693,15 +2028,20 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
1693
2028
  this.logger.warn(
1694
2029
  `[claude-code] Received tool error for unknown tool ID: ${error.id}`
1695
2030
  );
2031
+ const errorResolvedParentId = toolName === "Task" ? null : sdkParentToolUseIdForResults ?? getFallbackParentId();
1696
2032
  state = {
1697
2033
  name: toolName,
1698
2034
  inputStarted: true,
1699
2035
  inputClosed: true,
1700
- callEmitted: false
2036
+ callEmitted: false,
2037
+ parentToolCallId: errorResolvedParentId
1701
2038
  };
1702
2039
  toolStates.set(error.id, state);
1703
2040
  }
1704
2041
  emitToolCall(error.id, state);
2042
+ if (toolName === "Task") {
2043
+ activeTaskTools.delete(error.id);
2044
+ }
1705
2045
  const rawError = typeof error.error === "string" ? error.error : typeof error.error === "object" && error.error !== null ? (() => {
1706
2046
  try {
1707
2047
  return JSON.stringify(error.error);
@@ -1719,7 +2059,8 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
1719
2059
  // V3 field: indicates tool is provider-defined
1720
2060
  providerMetadata: {
1721
2061
  "claude-code": {
1722
- rawError
2062
+ rawError,
2063
+ parentToolCallId: state.parentToolCallId ?? null
1723
2064
  }
1724
2065
  }
1725
2066
  });
@@ -1779,7 +2120,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
1779
2120
  type: "text-end",
1780
2121
  id: textPartId
1781
2122
  });
1782
- } else if (accumulatedText) {
2123
+ } else if (accumulatedText && !textStreamedViaContentBlock) {
1783
2124
  const fallbackTextId = (0, import_provider_utils.generateId)();
1784
2125
  controller.enqueue({
1785
2126
  type: "text-start",
@@ -1817,6 +2158,8 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
1817
2158
  }
1818
2159
  }
1819
2160
  });
2161
+ controller.close();
2162
+ return;
1820
2163
  } else if (message.type === "system" && message.subtype === "init") {
1821
2164
  this.setSessionId(message.session_id);
1822
2165
  this.logger.info(`[claude-code] Stream session initialized: ${message.session_id}`);
@@ -1850,7 +2193,7 @@ var ClaudeCodeLanguageModel = class _ClaudeCodeLanguageModel {
1850
2193
  type: "text-end",
1851
2194
  id: textPartId
1852
2195
  });
1853
- } else if (accumulatedText) {
2196
+ } else if (accumulatedText && !textStreamedViaContentBlock) {
1854
2197
  const fallbackTextId = (0, import_provider_utils.generateId)();
1855
2198
  controller.enqueue({
1856
2199
  type: "text-start",