@ai-sdk/harness-claude-code 1.0.171 → 1.0.173

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/CHANGELOG.md CHANGED
@@ -1,5 +1,32 @@
1
1
  # @ai-sdk/harness-claude-code
2
2
 
3
+ ## 1.0.173
4
+
5
+ ### Patch Changes
6
+
7
+ - edd4d4f: fix(harness-claude-code): correctly map dotted AI Gateway model IDs to the ID shapes Claude Code expects
8
+ - Updated dependencies [7716e18]
9
+ - Updated dependencies [5c247e9]
10
+ - Updated dependencies [dcd2f8d]
11
+ - @ai-sdk/provider-utils@5.0.72
12
+ - @ai-sdk/provider@4.0.35
13
+ - @ai-sdk/harness@1.0.169
14
+
15
+ ## 1.0.172
16
+
17
+ ### Patch Changes
18
+
19
+ - 4ab93bb: feat(harness-claude-code): add `toolHints` to mark host tools read-only or always-loaded
20
+ - ede06e3: carry out an approval answered after a resume instead of asking again
21
+ - 0808bf4: fix(harness-claude-code): preserve host tool numeric bounds, string lengths, array item counts, and defaults in Zod schemas
22
+ - Updated dependencies [033f8d9]
23
+ - Updated dependencies [e7a8988]
24
+ - Updated dependencies [2c12e25]
25
+ - Updated dependencies [61a315e]
26
+ - Updated dependencies [6eab0f7]
27
+ - @ai-sdk/harness@1.0.168
28
+ - @ai-sdk/provider-utils@5.0.71
29
+
3
30
  ## 1.0.171
4
31
 
5
32
  ### Patch Changes
@@ -1224,7 +1224,8 @@ function defaultUsage() {
1224
1224
  //#endregion
1225
1225
  //#region src/bridge/json-schema-to-zod.ts
1226
1226
  function jsonSchemaToZodObject(input) {
1227
- return toZodObject(isJsonSchemaObject(input) ? input : {});
1227
+ const schema = isJsonSchemaObject(input) ? input : {};
1228
+ return withJsonSchemaMetadata(toZodObject(schema), schema);
1228
1229
  }
1229
1230
  function toZodObject(schema) {
1230
1231
  const object = z.object(toZodShape(schema));
@@ -1248,7 +1249,22 @@ function toZodType(schema) {
1248
1249
  let zType = zodForConst(schema) ?? zodForEnum(schema) ?? zodForUnion(schema) ?? zodForType(schema);
1249
1250
  if (isNullable(schema)) zType = zType.nullable();
1250
1251
  if (schema.description) zType = zType.describe(schema.description);
1251
- return zType;
1252
+ return withJsonSchemaMetadata(zType, schema);
1253
+ }
1254
+ function withJsonSchemaMetadata(zType, schema) {
1255
+ const metadata = {};
1256
+ for (const key of [
1257
+ "minimum",
1258
+ "maximum",
1259
+ "exclusiveMinimum",
1260
+ "exclusiveMaximum",
1261
+ "minLength",
1262
+ "maxLength",
1263
+ "minItems",
1264
+ "maxItems",
1265
+ "default"
1266
+ ]) if (schema[key] !== void 0) metadata[key] = schema[key];
1267
+ return zType.meta(metadata);
1252
1268
  }
1253
1269
  function zodForType(schema) {
1254
1270
  const types = getNonNullTypes(schema);
@@ -1487,18 +1503,23 @@ function createPermissionOptions(input) {
1487
1503
  return {
1488
1504
  ...baseOptions,
1489
1505
  canUseTool: async (toolName, toolInput, options) => {
1490
- if (toolName.startsWith("mcp__harness-tools__")) return {
1491
- behavior: "allow",
1492
- updatedInput: toolInput
1493
- };
1494
- if (!inactiveNativeTools.has(toolName) && !nativeToolRequiresApproval({
1495
- nativeName: toolName,
1496
- permissionMode
1506
+ if (!needsHostApproval({
1507
+ toolName,
1508
+ permissionMode,
1509
+ inactiveNativeTools
1497
1510
  })) return {
1498
1511
  behavior: "allow",
1499
1512
  updatedInput: toolInput
1500
1513
  };
1501
1514
  const approvalId = options.toolUseID;
1515
+ if (input.approvalDecisions.get(approvalId)?.approved === true) {
1516
+ input.approvalDecisions.delete(approvalId);
1517
+ return {
1518
+ behavior: "allow",
1519
+ updatedInput: toolInput,
1520
+ toolUseID: approvalId
1521
+ };
1522
+ }
1502
1523
  input.approvalRequestedToolUseIds.add(approvalId);
1503
1524
  input.nativeToolCallNames.set(approvalId, toolName);
1504
1525
  if (!input.emittedToolCallIds.has(approvalId)) {
@@ -1582,6 +1603,53 @@ function createPermissionSettings(input) {
1582
1603
  sandbox: { autoAllowBashIfSandboxed: false }
1583
1604
  };
1584
1605
  }
1606
+ /**
1607
+ * Claude Code picks a model's output limit, system prompt and default effort
1608
+ * from its own reading of the model id, and misreads AI Gateway ids with a
1609
+ * dotted version such as `anthropic/claude-opus-5.5`. `modelOverrides` maps
1610
+ * the id Claude Code expects (`claude-opus-5-5`) to the gateway id, which
1611
+ * stays the id sent to the gateway.
1612
+ */
1613
+ function createGatewayModelOverrides(model) {
1614
+ if (!model?.startsWith("anthropic/")) return void 0;
1615
+ const id = model.slice(10).replace(/\[[^\]]*\]$/, "");
1616
+ return id.includes(".") ? { [id.replace(/\./g, "-")]: model } : void 0;
1617
+ }
1618
+ function needsHostApproval(input) {
1619
+ if (input.toolName.startsWith("mcp__harness-tools__")) return false;
1620
+ return input.inactiveNativeTools.has(input.toolName) || nativeToolRequiresApproval({
1621
+ nativeName: input.toolName,
1622
+ permissionMode: input.permissionMode
1623
+ });
1624
+ }
1625
+ function createApprovalPreToolUseHook(input) {
1626
+ return async (hookInput, toolUseID) => {
1627
+ const toolName = hookInput.tool_name;
1628
+ if (toolUseID == null || typeof toolName !== "string" || toolName === "AskUserQuestion") return {};
1629
+ const decision = input.decisions.get(toolUseID);
1630
+ if (decision != null) {
1631
+ input.nativeToolCallNames.set(toolUseID, toolName);
1632
+ if (!decision.approved) input.decisions.delete(toolUseID);
1633
+ return { hookSpecificOutput: {
1634
+ hookEventName: "PreToolUse",
1635
+ ...decision.approved ? { permissionDecision: "allow" } : {
1636
+ permissionDecision: "deny",
1637
+ permissionDecisionReason: decision.reason ?? "Denied"
1638
+ }
1639
+ } };
1640
+ }
1641
+ if (!needsHostApproval({
1642
+ toolName,
1643
+ permissionMode: input.permissionMode,
1644
+ inactiveNativeTools: input.inactiveNativeTools
1645
+ })) return {};
1646
+ input.deferredToolUseIds.add(toolUseID);
1647
+ return { hookSpecificOutput: {
1648
+ hookEventName: "PreToolUse",
1649
+ permissionDecision: "defer"
1650
+ } };
1651
+ };
1652
+ }
1585
1653
  function nativeToolRequiresApproval(input) {
1586
1654
  if (input.permissionMode === "allow-all") return false;
1587
1655
  const kind = NATIVE_TOOL_KINDS[input.nativeName] ?? "edit";
@@ -1606,70 +1674,75 @@ async function runTurn(start, turn) {
1606
1674
  name: "harness-tools",
1607
1675
  version: "1.0.0"
1608
1676
  });
1609
- for (const tool of start.tools) server.registerTool(tool.name, {
1610
- description: tool.description ?? "",
1611
- inputSchema: jsonSchemaToZodObject(tool.inputSchema)
1612
- }, async (...handlerArgs) => {
1613
- const [input, extra] = handlerArgs;
1614
- const metadataToolCallId = extra._meta?.["claudecode/toolUseId"];
1615
- const toolCallId = resolveMcpHandlerToolUseId({
1616
- state: streamEventState,
1617
- metadataToolUseId: typeof metadataToolCallId === "string" ? metadataToolCallId : void 0,
1618
- toolName: tool.name,
1619
- input
1620
- }) ?? randomUUID();
1621
- streamEventState.mcpHandlerCalls.set(toolCallId, {
1622
- toolName: tool.name,
1623
- input
1624
- });
1625
- if (!streamEventState.emittedToolCallIds.has(toolCallId)) {
1626
- streamEventState.emittedToolCallIds.add(toolCallId);
1627
- emit({
1628
- type: "tool-call",
1629
- toolCallId,
1677
+ for (const tool of start.tools) {
1678
+ const hints = start.toolHints?.[tool.name];
1679
+ server.registerTool(tool.name, {
1680
+ description: tool.description ?? "",
1681
+ inputSchema: jsonSchemaToZodObject(tool.inputSchema),
1682
+ ...hints?.readOnly == null ? {} : { annotations: { readOnlyHint: hints.readOnly } },
1683
+ ...hints?.alwaysLoad == null ? {} : { _meta: { "anthropic/alwaysLoad": hints.alwaysLoad } }
1684
+ }, async (...handlerArgs) => {
1685
+ const [input, extra] = handlerArgs;
1686
+ const metadataToolCallId = extra._meta?.["claudecode/toolUseId"];
1687
+ const toolCallId = resolveMcpHandlerToolUseId({
1688
+ state: streamEventState,
1689
+ metadataToolUseId: typeof metadataToolCallId === "string" ? metadataToolCallId : void 0,
1690
+ toolName: tool.name,
1691
+ input
1692
+ }) ?? randomUUID();
1693
+ streamEventState.mcpHandlerCalls.set(toolCallId, {
1630
1694
  toolName: tool.name,
1631
- input: JSON.stringify(input),
1632
- providerExecuted: false
1695
+ input
1633
1696
  });
1634
- markWaitingOnHostInput({
1635
- state: streamEventState,
1636
- emit,
1637
- toolUseId: toolCallId
1697
+ if (!streamEventState.emittedToolCallIds.has(toolCallId)) {
1698
+ streamEventState.emittedToolCallIds.add(toolCallId);
1699
+ emit({
1700
+ type: "tool-call",
1701
+ toolCallId,
1702
+ toolName: tool.name,
1703
+ input: JSON.stringify(input),
1704
+ providerExecuted: false
1705
+ });
1706
+ markWaitingOnHostInput({
1707
+ state: streamEventState,
1708
+ emit,
1709
+ toolUseId: toolCallId
1710
+ });
1711
+ }
1712
+ const { output, isError, toolResult } = await turn.requestToolResult(toolCallId).finally(() => {
1713
+ clearWaitingOnHostInput({
1714
+ state: streamEventState,
1715
+ toolUseId: toolCallId
1716
+ });
1717
+ if (!streamEventState.mcpToolCalls.has(toolCallId)) streamEventState.pendingStepToolUseIds.delete(toolCallId);
1638
1718
  });
1639
- }
1640
- const { output, isError, toolResult } = await turn.requestToolResult(toolCallId).finally(() => {
1641
- clearWaitingOnHostInput({
1642
- state: streamEventState,
1643
- toolUseId: toolCallId
1719
+ emit({
1720
+ type: "tool-result",
1721
+ toolCallId,
1722
+ toolName: tool.name,
1723
+ result: output ?? null,
1724
+ isError: !!isError
1644
1725
  });
1645
- if (!streamEventState.mcpToolCalls.has(toolCallId)) streamEventState.pendingStepToolUseIds.delete(toolCallId);
1646
- });
1647
- emit({
1648
- type: "tool-result",
1649
- toolCallId,
1650
- toolName: tool.name,
1651
- result: output ?? null,
1652
- isError: !!isError
1653
- });
1654
- if (toolResult != null) {
1655
- const converted = convertHarnessToolModelOutput({ output: toolResult.output });
1726
+ if (toolResult != null) {
1727
+ const converted = convertHarnessToolModelOutput({ output: toolResult.output });
1728
+ return {
1729
+ content: converted.content.map((part) => part.type === "text" ? part : {
1730
+ type: "image",
1731
+ data: part.data,
1732
+ mimeType: part.mediaType
1733
+ }),
1734
+ isError: isError === true || converted.isError
1735
+ };
1736
+ }
1656
1737
  return {
1657
- content: converted.content.map((part) => part.type === "text" ? part : {
1658
- type: "image",
1659
- data: part.data,
1660
- mimeType: part.mediaType
1661
- }),
1662
- isError: isError === true || converted.isError
1738
+ content: [{
1739
+ type: "text",
1740
+ text: JSON.stringify(output ?? null)
1741
+ }],
1742
+ isError
1663
1743
  };
1664
- }
1665
- return {
1666
- content: [{
1667
- type: "text",
1668
- text: JSON.stringify(output ?? null)
1669
- }],
1670
- isError
1671
- };
1672
- });
1744
+ });
1745
+ }
1673
1746
  mcpServers["harness-tools"] = {
1674
1747
  type: "sdk",
1675
1748
  name: "harness-tools",
@@ -1693,7 +1766,10 @@ async function runTurn(start, turn) {
1693
1766
  const skillsOption = toClaudeSkillsOption(start.skills);
1694
1767
  const nativeTools = resolveNativeTools(start.builtinToolFiltering);
1695
1768
  const inactiveNativeTools = resolveInactiveNativeTools(start.builtinToolFiltering);
1769
+ const permissionMode = start.permissionMode ?? "allow-all";
1770
+ const approvalDecisions = /* @__PURE__ */ new Map();
1696
1771
  const permissionOptions = createPermissionOptions({
1772
+ approvalDecisions,
1697
1773
  start,
1698
1774
  inactiveNativeTools,
1699
1775
  turn,
@@ -1711,6 +1787,15 @@ async function runTurn(start, turn) {
1711
1787
  approvalRequestedToolUseIds: streamEventState.approvalRequestedToolUseIds,
1712
1788
  emittedToolCallIds: streamEventState.emittedToolCallIds
1713
1789
  });
1790
+ const modelOverrides = createGatewayModelOverrides(start.model);
1791
+ const deferredToolUseIds = /* @__PURE__ */ new Set();
1792
+ const approvalPreToolUseHook = createApprovalPreToolUseHook({
1793
+ permissionMode,
1794
+ inactiveNativeTools: new Set(inactiveNativeTools),
1795
+ decisions: approvalDecisions,
1796
+ deferredToolUseIds,
1797
+ nativeToolCallNames: streamEventState.nativeToolCallNames
1798
+ });
1714
1799
  const questionPreToolUseHook = createQuestionPreToolUseHook({
1715
1800
  turn,
1716
1801
  emit,
@@ -1725,7 +1810,7 @@ async function runTurn(start, turn) {
1725
1810
  toolUseId
1726
1811
  })
1727
1812
  });
1728
- const q = claudeSdk.query({
1813
+ const queryArgs = {
1729
1814
  prompt: queryInput.input,
1730
1815
  options: {
1731
1816
  ...start.model ? { model: start.model } : {},
@@ -1750,7 +1835,7 @@ async function runTurn(start, turn) {
1750
1835
  } } : {},
1751
1836
  includePartialMessages: true,
1752
1837
  hooks: {
1753
- PreToolUse: [{
1838
+ PreToolUse: [...permissionMode === "allow-all" ? [] : [{ hooks: [approvalPreToolUseHook] }], {
1754
1839
  matcher: "AskUserQuestion",
1755
1840
  hooks: [questionPreToolUseHook],
1756
1841
  ...start.questionTimeoutMs !== void 0 ? { timeout: Math.ceil(start.questionTimeoutMs / 1e3) } : {}
@@ -1762,18 +1847,70 @@ async function runTurn(start, turn) {
1762
1847
  },
1763
1848
  ...start.resumeSessionId ?? lastClaudeSessionId ? { resume: start.resumeSessionId ?? lastClaudeSessionId } : start.continue === true || !turn.firstTurn ? { continue: true } : {},
1764
1849
  ...permissionOptions,
1850
+ ...modelOverrides ? { settings: {
1851
+ ...permissionOptions.settings,
1852
+ modelOverrides
1853
+ } } : {},
1765
1854
  mcpServers,
1766
1855
  cwd: workdir,
1767
1856
  abortSignal: abortCtl.signal
1768
1857
  }
1858
+ };
1859
+ let deferredToolUseId = start.deferredToolUseId;
1860
+ let resumingDeferredCall = false;
1861
+ let q = deferredToolUseId == null ? claudeSdk.query(queryArgs) : void 0;
1862
+ const hostAborted = new Promise((resolve) => {
1863
+ if (abortCtl.signal.aborted) resolve(void 0);
1864
+ abortCtl.signal.addEventListener("abort", () => resolve(void 0), { once: true });
1769
1865
  });
1770
1866
  gracefulAbort = () => {
1771
1867
  hardAbortTimer = setTimeout(() => abortCtl.abort(), 5e3);
1772
1868
  hardAbortTimer.unref?.();
1773
- Promise.resolve().then(() => q.interrupt()).catch(() => abortCtl.abort());
1869
+ Promise.resolve().then(() => q?.interrupt()).catch(() => abortCtl.abort());
1774
1870
  };
1775
1871
  let turnUsage;
1776
1872
  let totalCostUsd;
1873
+ let deferredDecision;
1874
+ const requestDeferredApproval = (call) => {
1875
+ for (const droppedToolUseId of deferredToolUseIds) {
1876
+ if (droppedToolUseId === call.toolUseId) continue;
1877
+ const nativeName = streamEventState.nativeToolCallNames.get(droppedToolUseId) ?? "unknown";
1878
+ emit({
1879
+ type: "tool-result",
1880
+ toolCallId: droppedToolUseId,
1881
+ toolName: toCommonName(nativeName),
1882
+ result: "Claude Code can wait for only one approval at a time, so this call did not run.",
1883
+ isError: true
1884
+ });
1885
+ streamEventState.pendingStepToolUseIds.delete(droppedToolUseId);
1886
+ }
1887
+ deferredToolUseIds.clear();
1888
+ streamEventState.approvalRequestedToolUseIds.add(call.toolUseId);
1889
+ streamEventState.nativeToolCallNames.set(call.toolUseId, call.toolName);
1890
+ if (!streamEventState.emittedToolCallIds.has(call.toolUseId)) {
1891
+ streamEventState.emittedToolCallIds.add(call.toolUseId);
1892
+ emit({
1893
+ type: "tool-call",
1894
+ toolCallId: call.toolUseId,
1895
+ toolName: toCommonName(call.toolName),
1896
+ nativeName: call.toolName,
1897
+ input: JSON.stringify(call.toolInput ?? {}),
1898
+ providerExecuted: true,
1899
+ ...isExternalMcpTool(call.toolName) ? { dynamic: true } : {}
1900
+ });
1901
+ }
1902
+ deferredDecision = turn.requestToolApproval(call.toolUseId);
1903
+ emit({
1904
+ type: "tool-approval-request",
1905
+ approvalId: call.toolUseId,
1906
+ toolCallId: call.toolUseId
1907
+ });
1908
+ markWaitingOnHostInput({
1909
+ state: streamEventState,
1910
+ emit,
1911
+ toolUseId: call.toolUseId
1912
+ });
1913
+ };
1777
1914
  let emittedTerminalError = false;
1778
1915
  let emittedTerminalFinish = false;
1779
1916
  const emitTerminalError = (message) => {
@@ -1796,14 +1933,59 @@ async function runTurn(start, turn) {
1796
1933
  onCompactionBoundary: (boundary) => compaction.onBoundary(boundary),
1797
1934
  toCommonName
1798
1935
  });
1936
+ async function* messages() {
1937
+ for (;;) {
1938
+ if (deferredToolUseId != null) {
1939
+ const toolUseId = deferredToolUseId;
1940
+ const decision = await Promise.race([deferredDecision ?? turn.requestToolApproval(toolUseId), hostAborted]).finally(() => clearWaitingOnHostInput({
1941
+ state: streamEventState,
1942
+ toolUseId
1943
+ }));
1944
+ deferredDecision = void 0;
1945
+ if (decision == null || abortCtl.signal.aborted) return;
1946
+ approvalDecisions.set(toolUseId, decision);
1947
+ deferredToolUseId = void 0;
1948
+ resumingDeferredCall = true;
1949
+ q = claudeSdk.query({
1950
+ prompt: withoutInitialMessage(queryInput.input),
1951
+ options: {
1952
+ ...queryArgs.options,
1953
+ ...lastClaudeSessionId != null ? {
1954
+ continue: void 0,
1955
+ resume: lastClaudeSessionId
1956
+ } : {}
1957
+ }
1958
+ });
1959
+ }
1960
+ for await (const msg of q) {
1961
+ yield msg;
1962
+ if (deferredToolUseId != null) break;
1963
+ }
1964
+ if (deferredToolUseId == null || abortCtl.signal.aborted) return;
1965
+ queryInput.retire();
1966
+ await disposeQuery(q);
1967
+ }
1968
+ }
1799
1969
  try {
1800
- for await (const msg of q) {
1970
+ for await (const msg of messages()) {
1801
1971
  if (abortCtl.signal.aborted) break;
1802
1972
  const type = msg.type;
1803
1973
  if (type === "command_lifecycle") queryInput.handleLifecycle(msg);
1804
1974
  const sessionId = msg.session_id;
1805
1975
  if (typeof sessionId === "string" && sessionId.length > 0) lastClaudeSessionId = sessionId;
1806
1976
  emitStreamEvent(msg);
1977
+ if (type === "result" && msg.terminal_reason === "tool_deferred" && msg.deferred_tool_use?.id != null) {
1978
+ const harnessUsage = mapUsage(msg.usage ?? msg.message?.usage);
1979
+ if (harnessUsage) turnUsage = addUsage(turnUsage, harnessUsage);
1980
+ if (typeof msg.total_cost_usd === "number") totalCostUsd = msg.total_cost_usd;
1981
+ deferredToolUseId = msg.deferred_tool_use.id;
1982
+ requestDeferredApproval({
1983
+ toolUseId: msg.deferred_tool_use.id,
1984
+ toolName: msg.deferred_tool_use.name,
1985
+ toolInput: msg.deferred_tool_use.input
1986
+ });
1987
+ continue;
1988
+ }
1807
1989
  if (type === "result") {
1808
1990
  if (msg.subtype === "success") {
1809
1991
  if (msg.is_error) {
@@ -1839,7 +2021,7 @@ async function runTurn(start, turn) {
1839
2021
  emit,
1840
2022
  usage: streamEventState.pendingStepUsage ?? harnessUsage
1841
2023
  });
1842
- if (!queryInput.answersSentMessage(msg)) continue;
2024
+ if (!resumingDeferredCall && !queryInput.answersSentMessage(msg)) continue;
1843
2025
  queryInput.observeResult();
1844
2026
  if (!queryInput.hasActiveUserMessages()) {
1845
2027
  queryInput.close();
@@ -1864,9 +2046,7 @@ async function runTurn(start, turn) {
1864
2046
  if (hardAbortTimer != null) clearTimeout(hardAbortTimer);
1865
2047
  turn.abortSignal.removeEventListener("abort", onHostAbort);
1866
2048
  queryInput.close();
1867
- try {
1868
- await q.return?.(void 0);
1869
- } catch {}
2049
+ await disposeQuery(q);
1870
2050
  }
1871
2051
  if (emittedTerminalError) return;
1872
2052
  emittedTerminalFinish = true;
@@ -1923,6 +2103,24 @@ function createQueryInput({ initialUserMessage, userMessages, abortSignal }) {
1923
2103
  ...options.priority == null ? {} : { priority: options.priority }
1924
2104
  });
1925
2105
  const messageIterator = userMessages[Symbol.asyncIterator]();
2106
+ let liveInputId = 0;
2107
+ let bufferedMessage;
2108
+ let pulling;
2109
+ const takeMessage = async (inputId) => {
2110
+ for (;;) {
2111
+ if (inputId !== liveInputId) return void 0;
2112
+ if (bufferedMessage != null) {
2113
+ const message = bufferedMessage;
2114
+ bufferedMessage = void 0;
2115
+ return message;
2116
+ }
2117
+ pulling ??= messageIterator.next().then((result) => {
2118
+ bufferedMessage = result;
2119
+ pulling = void 0;
2120
+ });
2121
+ await pulling;
2122
+ }
2123
+ };
1926
2124
  return {
1927
2125
  close,
1928
2126
  handleLifecycle: (message) => {
@@ -1947,10 +2145,14 @@ function createQueryInput({ initialUserMessage, userMessages, abortSignal }) {
1947
2145
  observeResult: () => {
1948
2146
  observedResult = true;
1949
2147
  },
2148
+ retire: () => {
2149
+ liveInputId++;
2150
+ },
1950
2151
  get hasObservedResult() {
1951
2152
  return observedResult;
1952
2153
  },
1953
2154
  input: { [Symbol.asyncIterator]() {
2155
+ const inputId = ++liveInputId;
1954
2156
  let sentInitial = false;
1955
2157
  return { async next() {
1956
2158
  if (closed || abortSignal.aborted) return {
@@ -1967,8 +2169,8 @@ function createQueryInput({ initialUserMessage, userMessages, abortSignal }) {
1967
2169
  done: false
1968
2170
  };
1969
2171
  }
1970
- const nextMessage = await messageIterator.next();
1971
- if (nextMessage.done) return {
2172
+ const nextMessage = await takeMessage(inputId);
2173
+ if (nextMessage == null || nextMessage.done) return {
1972
2174
  value: void 0,
1973
2175
  done: true
1974
2176
  };
@@ -1986,6 +2188,24 @@ function createQueryInput({ initialUserMessage, userMessages, abortSignal }) {
1986
2188
  } }
1987
2189
  };
1988
2190
  }
2191
+ function withoutInitialMessage(input) {
2192
+ return { [Symbol.asyncIterator]() {
2193
+ const iterator = input[Symbol.asyncIterator]();
2194
+ let skipped = false;
2195
+ return { async next() {
2196
+ if (!skipped) {
2197
+ skipped = true;
2198
+ await iterator.next();
2199
+ }
2200
+ return iterator.next();
2201
+ } };
2202
+ } };
2203
+ }
2204
+ async function disposeQuery(query) {
2205
+ try {
2206
+ await query?.return?.(void 0);
2207
+ } catch {}
2208
+ }
1989
2209
  function addUsage(total, usage) {
1990
2210
  if (total == null) return usage;
1991
2211
  const result = { ...total };