@deepagents/context 0.39.0 → 1.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.
Files changed (110) hide show
  1. package/README.md +44 -11
  2. package/dist/browser.js +171 -15
  3. package/dist/browser.js.map +3 -3
  4. package/dist/index.d.ts +6 -0
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +2309 -1233
  7. package/dist/index.js.map +4 -4
  8. package/dist/lib/agent.d.ts +6 -0
  9. package/dist/lib/agent.d.ts.map +1 -1
  10. package/dist/lib/chain-summary.d.ts +18 -0
  11. package/dist/lib/chain-summary.d.ts.map +1 -0
  12. package/dist/lib/engine.d.ts +25 -6
  13. package/dist/lib/engine.d.ts.map +1 -1
  14. package/dist/lib/fragments/message/user.d.ts +21 -2
  15. package/dist/lib/fragments/message/user.d.ts.map +1 -1
  16. package/dist/lib/fragments.d.ts +8 -3
  17. package/dist/lib/fragments.d.ts.map +1 -1
  18. package/dist/lib/resolvers/async-resolver.d.ts +8 -0
  19. package/dist/lib/resolvers/async-resolver.d.ts.map +1 -0
  20. package/dist/lib/resolvers/function-resolver.d.ts +8 -0
  21. package/dist/lib/resolvers/function-resolver.d.ts.map +1 -0
  22. package/dist/lib/resolvers/generator-resolver.d.ts +13 -0
  23. package/dist/lib/resolvers/generator-resolver.d.ts.map +1 -0
  24. package/dist/lib/resolvers/index.d.ts +10 -0
  25. package/dist/lib/resolvers/index.d.ts.map +1 -0
  26. package/dist/lib/resolvers/iterable-resolver.d.ts +12 -0
  27. package/dist/lib/resolvers/iterable-resolver.d.ts.map +1 -0
  28. package/dist/lib/resolvers/loader-resolver.d.ts +13 -0
  29. package/dist/lib/resolvers/loader-resolver.d.ts.map +1 -0
  30. package/dist/lib/resolvers/promise-resolver.d.ts +7 -0
  31. package/dist/lib/resolvers/promise-resolver.d.ts.map +1 -0
  32. package/dist/lib/resolvers/types.d.ts +45 -0
  33. package/dist/lib/resolvers/types.d.ts.map +1 -0
  34. package/dist/lib/sandbox/ast-utils.d.ts +5 -2
  35. package/dist/lib/sandbox/ast-utils.d.ts.map +1 -1
  36. package/dist/lib/sandbox/bash-tool.d.ts.map +1 -1
  37. package/dist/lib/sandbox/container-tool.d.ts +32 -8
  38. package/dist/lib/sandbox/container-tool.d.ts.map +1 -1
  39. package/dist/lib/sandbox/docker-sandbox-errors.d.ts +58 -0
  40. package/dist/lib/sandbox/docker-sandbox-errors.d.ts.map +1 -0
  41. package/dist/lib/sandbox/docker-sandbox.d.ts +69 -357
  42. package/dist/lib/sandbox/docker-sandbox.d.ts.map +1 -1
  43. package/dist/lib/sandbox/index.d.ts +2 -7
  44. package/dist/lib/sandbox/index.d.ts.map +1 -1
  45. package/dist/lib/sandbox/installers/github-release.d.ts +46 -0
  46. package/dist/lib/sandbox/installers/github-release.d.ts.map +1 -0
  47. package/dist/lib/sandbox/installers/index.d.ts +7 -0
  48. package/dist/lib/sandbox/installers/index.d.ts.map +1 -0
  49. package/dist/lib/sandbox/installers/installer.d.ts +44 -0
  50. package/dist/lib/sandbox/installers/installer.d.ts.map +1 -0
  51. package/dist/lib/sandbox/installers/npm.d.ts +32 -0
  52. package/dist/lib/sandbox/installers/npm.d.ts.map +1 -0
  53. package/dist/lib/sandbox/installers/package-manager.d.ts +19 -0
  54. package/dist/lib/sandbox/installers/package-manager.d.ts.map +1 -0
  55. package/dist/lib/sandbox/installers/pip.d.ts +37 -0
  56. package/dist/lib/sandbox/installers/pip.d.ts.map +1 -0
  57. package/dist/lib/sandbox/installers/url-binary.d.ts +41 -0
  58. package/dist/lib/sandbox/installers/url-binary.d.ts.map +1 -0
  59. package/dist/lib/sandbox/subcommand.d.ts +11 -11
  60. package/dist/lib/sandbox/subcommand.d.ts.map +1 -1
  61. package/dist/lib/sandbox/upload-skills.d.ts +6 -0
  62. package/dist/lib/sandbox/upload-skills.d.ts.map +1 -1
  63. package/dist/lib/sandbox/virtual-sandbox.d.ts +10 -0
  64. package/dist/lib/sandbox/virtual-sandbox.d.ts.map +1 -0
  65. package/dist/lib/save/reminder-target-handler.d.ts +36 -0
  66. package/dist/lib/save/reminder-target-handler.d.ts.map +1 -0
  67. package/dist/lib/save/save-pipeline.d.ts +28 -0
  68. package/dist/lib/save/save-pipeline.d.ts.map +1 -0
  69. package/dist/lib/save/tool-output-target-handler.d.ts +7 -0
  70. package/dist/lib/save/tool-output-target-handler.d.ts.map +1 -0
  71. package/dist/lib/save/user-target-handler.d.ts +7 -0
  72. package/dist/lib/save/user-target-handler.d.ts.map +1 -0
  73. package/dist/lib/stream/change-source.d.ts +11 -0
  74. package/dist/lib/stream/change-source.d.ts.map +1 -0
  75. package/dist/lib/stream/ddl.stream.postgres-notify.d.ts +3 -0
  76. package/dist/lib/stream/ddl.stream.postgres-notify.d.ts.map +1 -0
  77. package/dist/lib/stream/ddl.stream.postgres.d.ts +2 -0
  78. package/dist/lib/stream/ddl.stream.postgres.d.ts.map +1 -0
  79. package/dist/lib/stream/polling-change-source.d.ts +27 -0
  80. package/dist/lib/stream/polling-change-source.d.ts.map +1 -0
  81. package/dist/lib/stream/polling-policy.d.ts +0 -1
  82. package/dist/lib/stream/polling-policy.d.ts.map +1 -1
  83. package/dist/lib/stream/postgres-notify-change-source.d.ts +15 -0
  84. package/dist/lib/stream/postgres-notify-change-source.d.ts.map +1 -0
  85. package/dist/lib/stream/postgres.stream-store.d.ts +29 -0
  86. package/dist/lib/stream/postgres.stream-store.d.ts.map +1 -0
  87. package/dist/lib/stream/stream-manager.d.ts +8 -27
  88. package/dist/lib/stream/stream-manager.d.ts.map +1 -1
  89. package/dist/lib/ui-message-guards.d.ts +10 -0
  90. package/dist/lib/ui-message-guards.d.ts.map +1 -0
  91. package/package.json +2 -7
  92. package/dist/lib/sandbox/extension.d.ts +0 -39
  93. package/dist/lib/sandbox/extension.d.ts.map +0 -1
  94. package/dist/lib/sandbox/openapi/demo.d.ts +0 -2
  95. package/dist/lib/sandbox/openapi/demo.d.ts.map +0 -1
  96. package/dist/lib/sandbox/openapi/extension.d.ts +0 -19
  97. package/dist/lib/sandbox/openapi/extension.d.ts.map +0 -1
  98. package/dist/lib/sandbox/openapi/format.d.ts +0 -11
  99. package/dist/lib/sandbox/openapi/format.d.ts.map +0 -1
  100. package/dist/lib/sandbox/openapi/schema.d.ts +0 -9
  101. package/dist/lib/sandbox/openapi/schema.d.ts.map +0 -1
  102. package/dist/lib/sandbox/openapi/skill/index.d.ts +0 -6
  103. package/dist/lib/sandbox/openapi/skill/index.d.ts.map +0 -1
  104. package/dist/lib/sandbox/openapi/skill/index.js +0 -14
  105. package/dist/lib/sandbox/openapi/skill/index.js.map +0 -7
  106. package/dist/lib/sandbox/openapi/skill/openapi-cli/SKILL.md +0 -109
  107. package/dist/lib/sandbox/openapi/validate.d.ts +0 -7
  108. package/dist/lib/sandbox/openapi/validate.d.ts.map +0 -1
  109. package/dist/lib/sandbox/routing-sandbox.d.ts +0 -28
  110. package/dist/lib/sandbox/routing-sandbox.d.ts.map +0 -1
package/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # @deepagents/context
2
2
 
3
- A domain-agnostic context system for LLM applications, including fragment rendering, persistence, chat orchestration, and portable sandbox tooling.
3
+ A domain-agnostic context system for LLM applications, including fragment rendering, persistence, chat orchestration, and sandbox tooling.
4
4
 
5
5
  ## Overview
6
6
 
7
- This package provides a flexible way to compose and render context in multiple formats (XML, Markdown, TOML, TOON), persist conversations, orchestrate chat flows, and expose portable host-side command surfaces. Context fragments are structured units that can be transformed into different prompt representations for different LLM styles.
7
+ This package provides a flexible way to compose and render context in multiple formats (XML, Markdown, TOML, TOON), persist conversations, orchestrate chat flows, and run real sandbox commands. Context fragments are structured units that can be transformed into different prompt representations for different LLM styles.
8
8
 
9
9
  ## Installation
10
10
 
@@ -26,19 +26,16 @@ like store implementations, sandbox tooling, and filesystem-based skill loading.
26
26
  ## Sandbox Tooling
27
27
 
28
28
  The server-side package also ships the sandbox primitives used by
29
- `@deepagents/text2sql` and other tool-driven agents. Use
30
- `createRoutingSandbox({ backend, hostExtensions })` to run the same host
31
- commands across virtual, Docker, or Agent OS backends.
32
-
33
- If an upstream service already has an OpenAPI description,
34
- `createOpenAPIExtension({ name, openapi, ... })` turns it into a portable
35
- `SandboxExtension` with validated subcommands and a built-in `schema`
36
- introspection command.
29
+ `@deepagents/text2sql` and other tool-driven agents. Use `createBashTool()`
30
+ with `createVirtualSandbox()`, `createContainerTool()`, `createDockerSandbox()`,
31
+ or `createAgentOsSandbox()` depending on whether commands should run in memory,
32
+ Docker, or Agent OS.
37
33
 
38
34
  See the docs for the full API surface:
39
35
 
40
- - [Routing Sandbox](https://januarylabs.github.io/deepagents/docs/context/routing-sandbox)
41
36
  - [Sandbox](https://januarylabs.github.io/deepagents/docs/context/sandbox)
37
+ - [Container Tool](https://januarylabs.github.io/deepagents/docs/context/container-tool)
38
+ - [Subcommand Builders](https://januarylabs.github.io/deepagents/docs/context/subcommand)
42
39
 
43
40
  ## Basic Usage
44
41
 
@@ -218,6 +215,42 @@ const messageWithoutReminders = stripReminders(message);
218
215
  ```
219
216
 
220
217
  - `getReminderRanges(metadata)` returns `metadata.reminders` as offset ranges (or `[]` when missing).
218
+
219
+ Conditional reminders are registered on the engine, not inside `user(...)`.
220
+ They can react to turn cadence, classifier matches, tool activity, assistant
221
+ history, token usage, and idle time:
222
+
223
+ ```ts
224
+ import {
225
+ anyToolCalled,
226
+ everyOfLastN,
227
+ not,
228
+ reminder,
229
+ toolCalled,
230
+ usageExceeds,
231
+ user,
232
+ } from '@deepagents/context';
233
+
234
+ engine.set(
235
+ reminder('Ask for confirmation before repeating destructive tool calls', {
236
+ when: toolCalled('bash'),
237
+ }),
238
+ reminder('Pause and summarize if the thread is getting expensive', {
239
+ when: usageExceeds(20_000),
240
+ }),
241
+ reminder('If no tools were needed for three turns, keep the answer brief', {
242
+ when: everyOfLastN(3, not(anyToolCalled())),
243
+ }),
244
+ user('continue'),
245
+ );
246
+ ```
247
+
248
+ Other exported helpers include `toolCallCount(...)`,
249
+ `lastAssistantLength(...)`, `withinLastN(...)`, `everyOfLastN(...)`, and
250
+ `elapsedExceeds(...)`. See the
251
+ [Predicates](https://januarylabs.github.io/deepagents/docs/context/predicates)
252
+ page for the full catalog.
253
+
221
254
  - `stripTextByRanges(text, ranges)` removes offset spans from text and returns the remaining visible content.
222
255
  - `stripReminders(message)` strips inline/part reminders from a `UIMessage` and removes `metadata.reminders`.
223
256
  - Reminder ranges are local to a message part, so filter by `partIndex` before stripping a specific part's text.
package/dist/browser.js CHANGED
@@ -4,7 +4,12 @@ function isFragment(data) {
4
4
  return typeof data === "object" && data !== null && "name" in data && ("data" in data || "codec" in data) && typeof data.name === "string";
5
5
  }
6
6
  function isFragmentObject(data) {
7
- return typeof data === "object" && data !== null && !Array.isArray(data) && !isFragment(data);
7
+ if (typeof data !== "object" || data === null) return false;
8
+ if (Array.isArray(data)) return false;
9
+ if (data instanceof Promise) return false;
10
+ if (Symbol.asyncIterator in data || Symbol.iterator in data) return false;
11
+ if (isFragment(data)) return false;
12
+ return true;
8
13
  }
9
14
  function isMessageFragment(fragment2) {
10
15
  return fragment2.type === "message";
@@ -890,7 +895,10 @@ async function estimate(modelId, renderer, ...fragments) {
890
895
  }
891
896
 
892
897
  // packages/context/src/lib/fragments/message/user.ts
893
- import { generateId as generateId2 } from "ai";
898
+ import {
899
+ generateId as generateId2,
900
+ isStaticToolUIPart
901
+ } from "ai";
894
902
 
895
903
  // packages/context/src/lib/renderers/abstract.renderer.ts
896
904
  import pluralize from "pluralize";
@@ -1784,7 +1792,56 @@ function isConditionalReminder(fragment2) {
1784
1792
  var SYSTEM_REMINDER_OPEN_TAG = "<system-reminder>";
1785
1793
  var SYSTEM_REMINDER_CLOSE_TAG = "</system-reminder>";
1786
1794
  function getReminderRanges(metadata) {
1787
- return metadata?.reminders ?? [];
1795
+ return getReminderMetadataRecords(metadata).map((record) => ({
1796
+ partIndex: record.partIndex,
1797
+ start: record.start,
1798
+ end: record.end
1799
+ }));
1800
+ }
1801
+ function getReminderMetadataRecords(metadata) {
1802
+ const reminders = metadata?.reminders;
1803
+ if (!Array.isArray(reminders)) return [];
1804
+ return reminders.filter(
1805
+ (item) => isRecord(item) && typeof item.partIndex === "number" && typeof item.start === "number" && typeof item.end === "number"
1806
+ );
1807
+ }
1808
+ function reminderTargetOf(record) {
1809
+ return record.target === "tool-output" ? "tool-output" : "user";
1810
+ }
1811
+ function normalizeReminderTarget(target) {
1812
+ if (target === void 0 || target === "user") return "user";
1813
+ if (target === "tool-output") return "tool-output";
1814
+ throw new Error(`Unsupported reminder target: ${String(target)}`);
1815
+ }
1816
+ function isConditionalReminderOptions(options) {
1817
+ return options !== void 0 && "when" in options;
1818
+ }
1819
+ function isPromiseLike(value) {
1820
+ return (typeof value === "object" || typeof value === "function") && value !== null && "then" in value && typeof value.then === "function";
1821
+ }
1822
+ function normalizeImmediateReminderText(textOrFragment) {
1823
+ if (isFragment(textOrFragment)) {
1824
+ return new XmlRenderer().render([textOrFragment]);
1825
+ }
1826
+ if (typeof textOrFragment === "string") {
1827
+ return textOrFragment;
1828
+ }
1829
+ return (ctx) => {
1830
+ const resolved = textOrFragment(ctx);
1831
+ if (isPromiseLike(resolved)) {
1832
+ throw new Error("Async reminder text requires a when predicate");
1833
+ }
1834
+ return resolved;
1835
+ };
1836
+ }
1837
+ function normalizeConditionalReminderText(textOrFragment) {
1838
+ return isFragment(textOrFragment) ? new XmlRenderer().render([textOrFragment]) : textOrFragment;
1839
+ }
1840
+ function isOutputAvailableToolPart(part) {
1841
+ return isStaticToolUIPart(part) && part.state === "output-available";
1842
+ }
1843
+ function isToolOutputReminderEnvelope(value) {
1844
+ return isRecord(value) && typeof value.systemReminder === "string";
1788
1845
  }
1789
1846
  function stripTextByRanges(text, ranges) {
1790
1847
  if (ranges.length === 0) {
@@ -1813,17 +1870,44 @@ function stripTextByRanges(text, ranges) {
1813
1870
  return output.trimEnd();
1814
1871
  }
1815
1872
  function stripReminders(message2) {
1816
- const reminderRanges = getReminderRanges(
1873
+ const reminderRecords = getReminderMetadataRecords(
1817
1874
  isRecord(message2.metadata) ? message2.metadata : void 0
1818
1875
  );
1819
1876
  const rangesByPartIndex = /* @__PURE__ */ new Map();
1820
- for (const range of reminderRanges) {
1877
+ const toolRemindersByPartIndex = /* @__PURE__ */ new Map();
1878
+ for (const range of reminderRecords) {
1879
+ if (reminderTargetOf(range) === "tool-output") {
1880
+ const records = toolRemindersByPartIndex.get(range.partIndex) ?? [];
1881
+ records.push(range);
1882
+ toolRemindersByPartIndex.set(range.partIndex, records);
1883
+ continue;
1884
+ }
1821
1885
  const partRanges = rangesByPartIndex.get(range.partIndex) ?? [];
1822
1886
  partRanges.push({ start: range.start, end: range.end });
1823
1887
  rangesByPartIndex.set(range.partIndex, partRanges);
1824
1888
  }
1825
1889
  const strippedParts = message2.parts.flatMap((part, partIndex) => {
1826
1890
  const clonedPart = { ...part };
1891
+ const toolReminderRecords = toolRemindersByPartIndex.get(partIndex);
1892
+ if (toolReminderRecords !== void 0 && isOutputAvailableToolPart(clonedPart)) {
1893
+ if (typeof clonedPart.output === "string") {
1894
+ return [
1895
+ {
1896
+ ...clonedPart,
1897
+ output: stripTextByRanges(
1898
+ clonedPart.output,
1899
+ toolReminderRecords.map((record) => ({
1900
+ start: record.start,
1901
+ end: record.end
1902
+ }))
1903
+ )
1904
+ }
1905
+ ];
1906
+ }
1907
+ if (isToolOutputReminderEnvelope(clonedPart.output)) {
1908
+ return [{ ...clonedPart, output: clonedPart.output.result }];
1909
+ }
1910
+ }
1827
1911
  const ranges = rangesByPartIndex.get(partIndex);
1828
1912
  if (clonedPart.type !== "text" || ranges === void 0) {
1829
1913
  return [clonedPart];
@@ -1893,6 +1977,7 @@ function applyInlineReminder(message2, value) {
1893
1977
  return {
1894
1978
  id: generateId2(),
1895
1979
  text: value,
1980
+ target: "user",
1896
1981
  partIndex,
1897
1982
  start,
1898
1983
  end: start + reminderText.length,
@@ -1906,6 +1991,7 @@ function applyPartReminder(message2, value) {
1906
1991
  return {
1907
1992
  id: generateId2(),
1908
1993
  text: value,
1994
+ target: "user",
1909
1995
  partIndex,
1910
1996
  start: 0,
1911
1997
  end: value.length,
@@ -1960,6 +2046,65 @@ function applyReminderToMessage(message2, item, ctx) {
1960
2046
  }
1961
2047
  return item.asPart ? applyPartReminder(message2, resolved.text) : applyInlineReminder(message2, resolved.text);
1962
2048
  }
2049
+ function findSingleOutputAvailableToolPart(message2) {
2050
+ let match = null;
2051
+ for (let partIndex = 0; partIndex < message2.parts.length; partIndex++) {
2052
+ const part = message2.parts[partIndex];
2053
+ if (!isOutputAvailableToolPart(part)) continue;
2054
+ if (match) return null;
2055
+ match = { partIndex, part };
2056
+ }
2057
+ return match;
2058
+ }
2059
+ function applyToolOutputRemindersToMessage(message2, reminders) {
2060
+ if (reminders.length === 0) return [];
2061
+ const target = findSingleOutputAvailableToolPart(message2);
2062
+ if (!target) return [];
2063
+ for (const reminder2 of reminders) {
2064
+ if (reminder2.metadata) {
2065
+ mergeMessageMetadata(message2, reminder2.metadata);
2066
+ }
2067
+ }
2068
+ const added = [];
2069
+ if (typeof target.part.output === "string") {
2070
+ let output = target.part.output;
2071
+ for (const reminder2 of reminders) {
2072
+ const reminderText = formatTaggedReminder(reminder2.text);
2073
+ const start = output.length;
2074
+ output = `${output}${reminderText}`;
2075
+ added.push({
2076
+ id: generateId2(),
2077
+ text: reminder2.text,
2078
+ target: "tool-output",
2079
+ partIndex: target.partIndex,
2080
+ start,
2081
+ end: start + reminderText.length,
2082
+ mode: "tool-output"
2083
+ });
2084
+ }
2085
+ message2.parts[target.partIndex] = {
2086
+ ...target.part,
2087
+ output
2088
+ };
2089
+ return added;
2090
+ }
2091
+ message2.parts[target.partIndex] = {
2092
+ ...target.part,
2093
+ output: {
2094
+ result: target.part.output,
2095
+ systemReminder: reminders.map((reminder2) => reminder2.text).join("\n")
2096
+ }
2097
+ };
2098
+ return reminders.map((reminder2) => ({
2099
+ id: generateId2(),
2100
+ text: reminder2.text,
2101
+ target: "tool-output",
2102
+ partIndex: target.partIndex,
2103
+ start: 0,
2104
+ end: 0,
2105
+ mode: "tool-output"
2106
+ }));
2107
+ }
1963
2108
  function mergeReminderMetadata(message2, addedReminders) {
1964
2109
  if (addedReminders.length === 0) return;
1965
2110
  const metadata = isRecord(message2.metadata) ? { ...message2.metadata } : {};
@@ -1968,28 +2113,37 @@ function mergeReminderMetadata(message2, addedReminders) {
1968
2113
  message2.metadata = metadata;
1969
2114
  }
1970
2115
  function reminder(textOrFragment, options) {
1971
- const fromFragment2 = isFragment(textOrFragment);
1972
- const text = fromFragment2 ? new XmlRenderer().render([textOrFragment]) : textOrFragment;
1973
- if (typeof text === "string") {
1974
- assertReminderText(text);
1975
- }
1976
- const asPart = options?.asPart ?? false;
1977
- if (options && "when" in options && options.when) {
2116
+ const target = normalizeReminderTarget(options?.target);
2117
+ const asPart = target === "user" ? options?.asPart ?? false : false;
2118
+ if (isConditionalReminderOptions(options)) {
2119
+ const text2 = normalizeConditionalReminderText(textOrFragment);
2120
+ if (typeof text2 === "string") {
2121
+ assertReminderText(text2);
2122
+ }
1978
2123
  return {
1979
2124
  name: "reminder",
1980
2125
  data: null,
1981
2126
  metadata: {
1982
2127
  reminder: {
1983
- text,
2128
+ text: text2,
1984
2129
  when: options.when,
1985
- asPart
2130
+ asPart,
2131
+ target
1986
2132
  }
1987
2133
  }
1988
2134
  };
1989
2135
  }
2136
+ if (target !== "user") {
2137
+ throw new Error('Reminder target "tool-output" requires a when predicate');
2138
+ }
2139
+ const text = normalizeImmediateReminderText(textOrFragment);
2140
+ if (typeof text === "string") {
2141
+ assertReminderText(text);
2142
+ }
1990
2143
  return {
1991
2144
  text,
1992
- asPart
2145
+ asPart,
2146
+ target
1993
2147
  };
1994
2148
  }
1995
2149
  function user(content, ...reminders) {
@@ -2215,6 +2369,7 @@ export {
2215
2369
  applyInlineReminder,
2216
2370
  applyPartReminder,
2217
2371
  applyReminderToMessage,
2372
+ applyToolOutputRemindersToMessage,
2218
2373
  assistant,
2219
2374
  assistantText,
2220
2375
  clarification,
@@ -2224,6 +2379,7 @@ export {
2224
2379
  example,
2225
2380
  explain,
2226
2381
  fail,
2382
+ findSingleOutputAvailableToolPart,
2227
2383
  fragment,
2228
2384
  fromFragment,
2229
2385
  getFragmentData,