@assistant-ui/react 0.4.2 → 0.4.4

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.mjs CHANGED
@@ -30,7 +30,7 @@ import { create } from "zustand";
30
30
 
31
31
  // src/types/ModelConfigTypes.ts
32
32
  var mergeModelConfigs = (configSet) => {
33
- const configs = Array.from(configSet).map((c) => c()).sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
33
+ const configs = Array.from(configSet).map((c) => c.getModelConfig()).sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
34
34
  return configs.reduce((acc, config) => {
35
35
  if (config.system) {
36
36
  if (acc.system) {
@@ -226,7 +226,8 @@ var makeThreadActionStore = (runtimeRef) => {
226
226
  startRun: (parentId) => runtimeRef.current.startRun(parentId),
227
227
  append: (message) => runtimeRef.current.append(message),
228
228
  cancelRun: () => runtimeRef.current.cancelRun(),
229
- addToolResult: (options) => runtimeRef.current.addToolResult(options)
229
+ addToolResult: (options) => runtimeRef.current.addToolResult(options),
230
+ getRuntime: () => runtimeRef.current
230
231
  })
231
232
  );
232
233
  };
@@ -243,10 +244,7 @@ var ThreadProvider = ({
243
244
  children,
244
245
  runtime
245
246
  }) => {
246
- const runtimeRef = useRef(runtime);
247
- useInsertionEffect(() => {
248
- runtimeRef.current = runtime;
249
- });
247
+ const runtimeRef = useRef(runtime.thread);
250
248
  const [context] = useState(() => {
251
249
  const useThread = makeThreadStore(runtimeRef);
252
250
  const useThreadMessages = makeThreadMessagesStore(runtimeRef);
@@ -261,8 +259,16 @@ var ThreadProvider = ({
261
259
  useViewport
262
260
  };
263
261
  });
262
+ const thread = useSyncExternalStore(
263
+ useCallback((c) => runtime.subscribe(c), [runtime]),
264
+ () => runtime.thread,
265
+ () => runtime.thread
266
+ );
267
+ useInsertionEffect(() => {
268
+ runtimeRef.current = thread;
269
+ });
264
270
  useEffect(() => {
265
- const onRuntimeUpdate = () => {
271
+ const onThreadUpdate = () => {
266
272
  context.useThread.setState(
267
273
  Object.freeze({
268
274
  isRunning: runtimeRef.current.isRunning
@@ -271,20 +277,11 @@ var ThreadProvider = ({
271
277
  );
272
278
  context.useThreadMessages.setState(Object.freeze(runtimeRef.current.messages), true);
273
279
  };
274
- onRuntimeUpdate();
275
- return runtime.subscribe(onRuntimeUpdate);
276
- }, [context, runtime]);
277
- const subscribe = useCallback(
278
- (c) => runtime.subscribe(c),
279
- [runtime]
280
- );
281
- const RuntimeSynchronizer = useSyncExternalStore(
282
- subscribe,
283
- () => runtime.unstable_synchronizer,
284
- () => void 0
285
- );
280
+ onThreadUpdate();
281
+ return thread.subscribe(onThreadUpdate);
282
+ }, [context, thread]);
286
283
  return /* @__PURE__ */ jsxs(ThreadContext.Provider, { value: context, children: [
287
- RuntimeSynchronizer && /* @__PURE__ */ jsx(RuntimeSynchronizer, {}),
284
+ thread.unstable_synchronizer && /* @__PURE__ */ jsx(thread.unstable_synchronizer, {}),
288
285
  children
289
286
  ] });
290
287
  };
@@ -293,7 +290,8 @@ var ThreadProvider = ({
293
290
  import { create as create8 } from "zustand";
294
291
  var makeAssistantActionsStore = (runtimeRef) => create8(
295
292
  () => Object.freeze({
296
- switchToThread: () => runtimeRef.current.switchToThread(null)
293
+ switchToThread: () => runtimeRef.current.switchToThread(null),
294
+ getRuntime: () => runtimeRef.current
297
295
  })
298
296
  );
299
297
 
@@ -310,10 +308,10 @@ var AssistantProvider = ({ children, runtime }) => {
310
308
  const useAssistantActions = makeAssistantActionsStore(runtimeRef);
311
309
  return { useModelConfig, useToolUIs, useAssistantActions };
312
310
  });
313
- const getModelCOnfig = context.useModelConfig((c) => c.getModelConfig);
311
+ const getModelConfig = context.useModelConfig();
314
312
  useEffect2(() => {
315
- return runtime.registerModelConfigProvider(getModelCOnfig);
316
- }, [runtime, getModelCOnfig]);
313
+ return runtime.registerModelConfigProvider(getModelConfig);
314
+ }, [runtime, getModelConfig]);
317
315
  return /* @__PURE__ */ jsx2(AssistantContext.Provider, { value: context, children: /* @__PURE__ */ jsx2(ThreadProvider, { runtime, children }) });
318
316
  };
319
317
 
@@ -423,7 +421,9 @@ var useAssistantTool = (tool) => {
423
421
  [tool.toolName]: rest
424
422
  }
425
423
  };
426
- const unsub1 = registerModelConfigProvider(() => config);
424
+ const unsub1 = registerModelConfigProvider({
425
+ getModelConfig: () => config
426
+ });
427
427
  const unsub2 = render ? setToolUI(toolName, render) : void 0;
428
428
  return () => {
429
429
  unsub1();
@@ -473,7 +473,7 @@ var useAssistantInstructions = (instruction) => {
473
473
  const config = {
474
474
  system: instruction
475
475
  };
476
- return registerModelConfigProvider(() => config);
476
+ return registerModelConfigProvider({ getModelConfig: () => config });
477
477
  }, [registerModelConfigProvider, instruction]);
478
478
  };
479
479
 
@@ -1179,7 +1179,7 @@ import { Primitive as Primitive4 } from "@radix-ui/react-primitive";
1179
1179
  import { forwardRef as forwardRef7 } from "react";
1180
1180
 
1181
1181
  // src/utils/hooks/useSmooth.tsx
1182
- import { useEffect as useEffect8, useState as useState5 } from "react";
1182
+ import { useEffect as useEffect8, useRef as useRef4, useState as useState5 } from "react";
1183
1183
  var TextStreamAnimator = class {
1184
1184
  constructor(currentText, setText) {
1185
1185
  this.currentText = currentText;
@@ -1225,6 +1225,9 @@ var TextStreamAnimator = class {
1225
1225
  };
1226
1226
  };
1227
1227
  var useSmooth = (text, smooth = false) => {
1228
+ const { useMessage } = useMessageContext();
1229
+ const id = useMessage((m) => m.message.id);
1230
+ const idRef = useRef4(id);
1228
1231
  const [displayedText, setDisplayedText] = useState5(text);
1229
1232
  const [animatorRef] = useState5(
1230
1233
  new TextStreamAnimator(text, setDisplayedText)
@@ -1234,7 +1237,8 @@ var useSmooth = (text, smooth = false) => {
1234
1237
  animatorRef.stop();
1235
1238
  return;
1236
1239
  }
1237
- if (!text.startsWith(animatorRef.targetText)) {
1240
+ if (idRef.current !== id || !text.startsWith(animatorRef.targetText)) {
1241
+ idRef.current = id;
1238
1242
  setDisplayedText(text);
1239
1243
  animatorRef.currentText = text;
1240
1244
  animatorRef.targetText = text;
@@ -1243,7 +1247,7 @@ var useSmooth = (text, smooth = false) => {
1243
1247
  }
1244
1248
  animatorRef.targetText = text;
1245
1249
  animatorRef.start();
1246
- }, [animatorRef, smooth, text]);
1250
+ }, [animatorRef, id, smooth, text]);
1247
1251
  useEffect8(() => {
1248
1252
  return () => {
1249
1253
  animatorRef.stop();
@@ -1431,7 +1435,7 @@ import {
1431
1435
  forwardRef as forwardRef11,
1432
1436
  useCallback as useCallback15,
1433
1437
  useEffect as useEffect9,
1434
- useRef as useRef4
1438
+ useRef as useRef5
1435
1439
  } from "react";
1436
1440
  import TextareaAutosize from "react-textarea-autosize";
1437
1441
  import { useEscapeKeydown } from "@radix-ui/react-use-escape-keydown";
@@ -1445,7 +1449,7 @@ var ComposerPrimitiveInput = forwardRef11(
1445
1449
  return c.value;
1446
1450
  });
1447
1451
  const Component = asChild ? Slot : TextareaAutosize;
1448
- const textareaRef = useRef4(null);
1452
+ const textareaRef = useRef5(null);
1449
1453
  const ref = useComposedRefs2(forwardedRef, textareaRef);
1450
1454
  useEscapeKeydown((e) => {
1451
1455
  const composer = useComposer.getState();
@@ -1591,7 +1595,7 @@ import { forwardRef as forwardRef14 } from "react";
1591
1595
 
1592
1596
  // src/primitive-hooks/thread/useThreadViewportAutoScroll.tsx
1593
1597
  import { useComposedRefs as useComposedRefs3 } from "@radix-ui/react-compose-refs";
1594
- import { useRef as useRef5 } from "react";
1598
+ import { useRef as useRef6 } from "react";
1595
1599
 
1596
1600
  // src/utils/hooks/useOnResizeContent.tsx
1597
1601
  import { useCallbackRef as useCallbackRef2 } from "@radix-ui/react-use-callback-ref";
@@ -1650,16 +1654,13 @@ var useOnScrollToBottom = (callback) => {
1650
1654
  var useThreadViewportAutoScroll = ({
1651
1655
  autoScroll = true
1652
1656
  }) => {
1653
- const divRef = useRef5(null);
1657
+ const divRef = useRef6(null);
1654
1658
  const { useViewport } = useThreadContext();
1655
- const firstRenderRef = useRef5(true);
1656
- const lastScrollTop = useRef5(0);
1657
- const isScrollingToBottomRef = useRef5(false);
1658
- const scrollToBottom = () => {
1659
+ const lastScrollTop = useRef6(0);
1660
+ const isScrollingToBottomRef = useRef6(false);
1661
+ const scrollToBottom = (behavior) => {
1659
1662
  const div = divRef.current;
1660
1663
  if (!div || !autoScroll) return;
1661
- const behavior = firstRenderRef.current ? "instant" : "auto";
1662
- firstRenderRef.current = false;
1663
1664
  isScrollingToBottomRef.current = true;
1664
1665
  div.scrollTo({ top: div.scrollHeight, behavior });
1665
1666
  };
@@ -1670,7 +1671,9 @@ var useThreadViewportAutoScroll = ({
1670
1671
  const newIsAtBottom = div.scrollHeight - div.scrollTop <= div.clientHeight;
1671
1672
  if (!newIsAtBottom && lastScrollTop.current < div.scrollTop) {
1672
1673
  } else {
1673
- isScrollingToBottomRef.current = newIsAtBottom;
1674
+ if (newIsAtBottom) {
1675
+ isScrollingToBottomRef.current = false;
1676
+ }
1674
1677
  if (newIsAtBottom !== isAtBottom) {
1675
1678
  useViewport.setState({
1676
1679
  isAtBottom: newIsAtBottom
@@ -1680,11 +1683,10 @@ var useThreadViewportAutoScroll = ({
1680
1683
  lastScrollTop.current = div.scrollTop;
1681
1684
  };
1682
1685
  const resizeRef = useOnResizeContent(() => {
1683
- if (!isScrollingToBottomRef.current && !useViewport.getState().isAtBottom && !firstRenderRef.current) {
1684
- handleScroll();
1685
- } else {
1686
- scrollToBottom();
1686
+ if (isScrollingToBottomRef.current || useViewport.getState().isAtBottom) {
1687
+ scrollToBottom("instant");
1687
1688
  }
1689
+ handleScroll();
1688
1690
  });
1689
1691
  const scrollRef = useManagedRef((el) => {
1690
1692
  el.addEventListener("scroll", handleScroll);
@@ -1694,7 +1696,7 @@ var useThreadViewportAutoScroll = ({
1694
1696
  });
1695
1697
  const autoScrollRef = useComposedRefs3(resizeRef, scrollRef, divRef);
1696
1698
  useOnScrollToBottom(() => {
1697
- scrollToBottom();
1699
+ scrollToBottom("auto");
1698
1700
  });
1699
1701
  return autoScrollRef;
1700
1702
  };
@@ -2078,45 +2080,14 @@ var BaseAssistantRuntime = class {
2078
2080
  constructor(_thread) {
2079
2081
  this._thread = _thread;
2080
2082
  this._thread = _thread;
2081
- this._unsubscribe = this._thread.subscribe(this.subscriptionHandler);
2082
- }
2083
- get capabilities() {
2084
- return this._thread.capabilities;
2085
2083
  }
2086
- _unsubscribe;
2087
2084
  get thread() {
2088
2085
  return this._thread;
2089
2086
  }
2090
2087
  set thread(thread) {
2091
- this._unsubscribe();
2092
2088
  this._thread = thread;
2093
- this._unsubscribe = this._thread.subscribe(this.subscriptionHandler);
2094
2089
  this.subscriptionHandler();
2095
2090
  }
2096
- get messages() {
2097
- return this.thread.messages;
2098
- }
2099
- get isRunning() {
2100
- return this.thread.isRunning;
2101
- }
2102
- getBranches(messageId) {
2103
- return this.thread.getBranches(messageId);
2104
- }
2105
- switchToBranch(branchId) {
2106
- return this.thread.switchToBranch(branchId);
2107
- }
2108
- append(message) {
2109
- return this.thread.append(message);
2110
- }
2111
- startRun(parentId) {
2112
- return this.thread.startRun(parentId);
2113
- }
2114
- cancelRun() {
2115
- return this.thread.cancelRun();
2116
- }
2117
- addToolResult(options) {
2118
- return this.thread.addToolResult(options);
2119
- }
2120
2091
  _subscriptions = /* @__PURE__ */ new Set();
2121
2092
  subscribe(callback) {
2122
2093
  this._subscriptions.add(callback);
@@ -2125,32 +2096,135 @@ var BaseAssistantRuntime = class {
2125
2096
  subscriptionHandler = () => {
2126
2097
  for (const callback of this._subscriptions) callback();
2127
2098
  };
2128
- get unstable_synchronizer() {
2129
- return this.thread.unstable_synchronizer;
2130
- }
2131
2099
  };
2132
2100
 
2101
+ // src/internal.ts
2102
+ var internal_exports = {};
2103
+ __export(internal_exports, {
2104
+ BaseAssistantRuntime: () => BaseAssistantRuntime,
2105
+ MessageRepository: () => MessageRepository,
2106
+ ProxyConfigProvider: () => ProxyConfigProvider,
2107
+ TooltipIconButton: () => TooltipIconButton,
2108
+ generateId: () => generateId,
2109
+ useSmooth: () => useSmooth
2110
+ });
2111
+
2112
+ // src/ui/base/tooltip-icon-button.tsx
2113
+ import { forwardRef as forwardRef17 } from "react";
2114
+
2115
+ // src/ui/base/tooltip.tsx
2116
+ import * as TooltipPrimitive from "@radix-ui/react-tooltip";
2117
+
2118
+ // src/ui/utils/withDefaults.tsx
2119
+ import {
2120
+ forwardRef as forwardRef15
2121
+ } from "react";
2122
+ import classNames from "classnames";
2123
+ import { jsx as jsx25 } from "react/jsx-runtime";
2124
+ var withDefaultProps = ({
2125
+ className,
2126
+ ...defaultProps
2127
+ }) => ({ className: classNameProp, ...props }) => {
2128
+ return {
2129
+ className: classNames(className, classNameProp),
2130
+ ...defaultProps,
2131
+ ...props
2132
+ };
2133
+ };
2134
+ var withDefaults = (Component, defaultProps) => {
2135
+ const getProps = withDefaultProps(defaultProps);
2136
+ const WithDefaults = forwardRef15(
2137
+ (props, ref) => {
2138
+ const ComponentAsAny = Component;
2139
+ return /* @__PURE__ */ jsx25(ComponentAsAny, { ...getProps(props), ref });
2140
+ }
2141
+ );
2142
+ WithDefaults.displayName = "withDefaults(" + (typeof Component === "string" ? Component : Component.displayName) + ")";
2143
+ return WithDefaults;
2144
+ };
2145
+
2146
+ // src/ui/base/tooltip.tsx
2147
+ import { jsx as jsx26 } from "react/jsx-runtime";
2148
+ var Tooltip = (props) => {
2149
+ return /* @__PURE__ */ jsx26(TooltipPrimitive.Provider, { children: /* @__PURE__ */ jsx26(TooltipPrimitive.Root, { ...props }) });
2150
+ };
2151
+ Tooltip.displayName = "Tooltip";
2152
+ var TooltipTrigger = TooltipPrimitive.Trigger;
2153
+ var TooltipContent = withDefaults(TooltipPrimitive.Content, {
2154
+ sideOffset: 4,
2155
+ className: "aui-tooltip-content"
2156
+ });
2157
+ TooltipContent.displayName = "TooltipContent";
2158
+
2159
+ // src/ui/base/button.tsx
2160
+ import { cva } from "class-variance-authority";
2161
+ import { Primitive as Primitive11 } from "@radix-ui/react-primitive";
2162
+ import { forwardRef as forwardRef16 } from "react";
2163
+ import { jsx as jsx27 } from "react/jsx-runtime";
2164
+ var buttonVariants = cva("aui-button", {
2165
+ variants: {
2166
+ variant: {
2167
+ default: "aui-button-primary",
2168
+ outline: "aui-button-outline",
2169
+ ghost: "aui-button-ghost"
2170
+ },
2171
+ size: {
2172
+ default: "aui-button-medium",
2173
+ icon: "aui-button-icon"
2174
+ }
2175
+ },
2176
+ defaultVariants: {
2177
+ variant: "default",
2178
+ size: "default"
2179
+ }
2180
+ });
2181
+ var Button = forwardRef16(
2182
+ ({ className, variant, size, ...props }, ref) => {
2183
+ return /* @__PURE__ */ jsx27(
2184
+ Primitive11.button,
2185
+ {
2186
+ className: buttonVariants({ variant, size, className }),
2187
+ ...props,
2188
+ ref
2189
+ }
2190
+ );
2191
+ }
2192
+ );
2193
+ Button.displayName = "Button";
2194
+
2195
+ // src/ui/base/tooltip-icon-button.tsx
2196
+ import { jsx as jsx28, jsxs as jsxs4 } from "react/jsx-runtime";
2197
+ var TooltipIconButton = forwardRef17(({ children, tooltip, side = "bottom", ...rest }, ref) => {
2198
+ return /* @__PURE__ */ jsxs4(Tooltip, { children: [
2199
+ /* @__PURE__ */ jsx28(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs4(Button, { variant: "ghost", size: "icon", ...rest, ref, children: [
2200
+ children,
2201
+ /* @__PURE__ */ jsx28("span", { className: "aui-sr-only", children: tooltip })
2202
+ ] }) }),
2203
+ /* @__PURE__ */ jsx28(TooltipContent, { side, children: tooltip })
2204
+ ] });
2205
+ });
2206
+ TooltipIconButton.displayName = "TooltipIconButton";
2207
+
2133
2208
  // src/runtimes/local/LocalRuntime.tsx
2134
2209
  var LocalRuntime = class extends BaseAssistantRuntime {
2135
- _configProviders;
2210
+ _proxyConfigProvider;
2136
2211
  constructor(adapter) {
2137
- const configProviders = /* @__PURE__ */ new Set();
2138
- super(new LocalThreadRuntime(configProviders, adapter));
2139
- this._configProviders = configProviders;
2212
+ const proxyConfigProvider = new ProxyConfigProvider();
2213
+ super(new LocalThreadRuntime(proxyConfigProvider, adapter));
2214
+ this._proxyConfigProvider = proxyConfigProvider;
2140
2215
  }
2141
2216
  set adapter(adapter) {
2142
2217
  this.thread.adapter = adapter;
2143
2218
  }
2144
2219
  registerModelConfigProvider(provider) {
2145
- this._configProviders.add(provider);
2146
- return () => this._configProviders.delete(provider);
2220
+ return this._proxyConfigProvider.registerModelConfigProvider(provider);
2147
2221
  }
2148
2222
  switchToThread(threadId) {
2149
2223
  if (threadId) {
2150
2224
  throw new Error("LocalRuntime does not yet support switching threads");
2151
2225
  }
2152
2226
  return this.thread = new LocalThreadRuntime(
2153
- this._configProviders,
2227
+ this._proxyConfigProvider,
2154
2228
  this.thread.adapter
2155
2229
  );
2156
2230
  }
@@ -2162,8 +2236,8 @@ var CAPABILITIES = Object.freeze({
2162
2236
  copy: true
2163
2237
  });
2164
2238
  var LocalThreadRuntime = class {
2165
- constructor(_configProviders, adapter) {
2166
- this._configProviders = _configProviders;
2239
+ constructor(configProvider, adapter) {
2240
+ this.configProvider = configProvider;
2167
2241
  this.adapter = adapter;
2168
2242
  }
2169
2243
  _subscriptions = /* @__PURE__ */ new Set();
@@ -2184,6 +2258,10 @@ var LocalThreadRuntime = class {
2184
2258
  this.notifySubscribers();
2185
2259
  }
2186
2260
  async append(message) {
2261
+ if (message.role !== "user")
2262
+ throw new Error(
2263
+ "Only appending user messages are supported in LocalRuntime. This is likely an internal bug in assistant-ui."
2264
+ );
2187
2265
  const userMessageId = generateId();
2188
2266
  const userMessage = {
2189
2267
  id: userMessageId,
@@ -2195,11 +2273,10 @@ var LocalThreadRuntime = class {
2195
2273
  await this.startRun(userMessageId);
2196
2274
  }
2197
2275
  async startRun(parentId) {
2198
- const id = generateId();
2199
2276
  this.repository.resetHead(parentId);
2200
2277
  const messages = this.repository.getMessages();
2201
2278
  const message = {
2202
- id,
2279
+ id: generateId(),
2203
2280
  role: "assistant",
2204
2281
  status: { type: "in_progress" },
2205
2282
  content: [{ type: "text", text: "" }],
@@ -2218,7 +2295,7 @@ var LocalThreadRuntime = class {
2218
2295
  const result = await this.adapter.run({
2219
2296
  messages,
2220
2297
  abortSignal: this.abortController.signal,
2221
- config: mergeModelConfigs(this._configProviders),
2298
+ config: this.configProvider.getModelConfig(),
2222
2299
  onUpdate: updateHandler
2223
2300
  });
2224
2301
  if (result !== void 0) {
@@ -2233,7 +2310,7 @@ var LocalThreadRuntime = class {
2233
2310
  } catch (e) {
2234
2311
  message.status = { type: "error", error: e };
2235
2312
  this.repository.addOrUpdateMessage(parentId, { ...message });
2236
- console.error(e);
2313
+ throw e;
2237
2314
  } finally {
2238
2315
  this.abortController = null;
2239
2316
  this.notifySubscribers();
@@ -2243,7 +2320,6 @@ var LocalThreadRuntime = class {
2243
2320
  if (!this.abortController) return;
2244
2321
  this.abortController.abort();
2245
2322
  this.abortController = null;
2246
- this.notifySubscribers();
2247
2323
  }
2248
2324
  notifySubscribers() {
2249
2325
  for (const callback of this._subscriptions) callback();
@@ -2255,7 +2331,7 @@ var LocalThreadRuntime = class {
2255
2331
  addToolResult({ messageId, toolCallId, result }) {
2256
2332
  const { parentId, message } = this.repository.getMessage(messageId);
2257
2333
  if (message.role !== "assistant")
2258
- throw new Error("Tried to add tool re^sult to non-assistant message");
2334
+ throw new Error("Tried to add tool result to non-assistant message");
2259
2335
  let found = false;
2260
2336
  const newContent = message.content.map((c) => {
2261
2337
  if (c.type !== "tool-call") return c;
@@ -2284,20 +2360,48 @@ var useLocalRuntime = (adapter) => {
2284
2360
  return runtime;
2285
2361
  };
2286
2362
 
2363
+ // src/runtimes/edge/useEdgeRuntime.ts
2364
+ import { useState as useState8 } from "react";
2365
+
2366
+ // src/runtimes/edge/converters/toCoreMessages.ts
2367
+ var toCoreMessages = (message) => {
2368
+ return message.map((message2) => {
2369
+ return {
2370
+ role: message2.role,
2371
+ content: message2.content.map((part) => {
2372
+ if (part.type === "ui") throw new Error("UI parts are not supported");
2373
+ return part;
2374
+ })
2375
+ };
2376
+ });
2377
+ };
2378
+
2379
+ // src/runtimes/edge/converters/toLanguageModelTools.ts
2380
+ import { z } from "zod";
2381
+ import zodToJsonSchema from "zod-to-json-schema";
2382
+ var toLanguageModelTools = (tools) => {
2383
+ if (!tools) return [];
2384
+ return Object.entries(tools).map(([name, tool]) => ({
2385
+ type: "function",
2386
+ name,
2387
+ ...tool.description ? { description: tool.description } : void 0,
2388
+ parameters: tool.parameters instanceof z.ZodType ? zodToJsonSchema(tool.parameters) : tool.parameters
2389
+ }));
2390
+ };
2391
+
2287
2392
  // src/runtimes/edge/streams/assistantDecoderStream.ts
2288
2393
  function assistantDecoderStream() {
2289
2394
  let currentToolCall;
2290
2395
  return new TransformStream({
2291
2396
  transform(chunk, controller) {
2292
- const [code, valueJson] = chunk.split(":");
2293
- const value = JSON.parse(valueJson);
2397
+ const [code, value] = parseStreamPart(chunk);
2294
2398
  if (currentToolCall && code !== "2" /* ToolCallArgsTextDelta */ && code !== "E" /* Error */) {
2295
2399
  controller.enqueue({
2296
2400
  type: "tool-call",
2297
2401
  toolCallType: "function",
2298
2402
  toolCallId: currentToolCall.id,
2299
2403
  toolName: currentToolCall.name,
2300
- args: JSON.parse(currentToolCall.argsText)
2404
+ args: currentToolCall.argsText
2301
2405
  });
2302
2406
  currentToolCall = void 0;
2303
2407
  }
@@ -2310,12 +2414,12 @@ function assistantDecoderStream() {
2310
2414
  break;
2311
2415
  }
2312
2416
  case "1" /* ToolCallBegin */: {
2313
- const { id, name } = JSON.parse(value);
2417
+ const { id, name } = value;
2314
2418
  currentToolCall = { id, name, argsText: "" };
2315
2419
  break;
2316
2420
  }
2317
2421
  case "2" /* ToolCallArgsTextDelta */: {
2318
- const delta = JSON.parse(value);
2422
+ const delta = value;
2319
2423
  currentToolCall.argsText += delta;
2320
2424
  controller.enqueue({
2321
2425
  type: "tool-call-delta",
@@ -2329,14 +2433,14 @@ function assistantDecoderStream() {
2329
2433
  case "F" /* Finish */: {
2330
2434
  controller.enqueue({
2331
2435
  type: "finish",
2332
- ...JSON.parse(value)
2436
+ ...value
2333
2437
  });
2334
2438
  break;
2335
2439
  }
2336
2440
  case "E" /* Error */: {
2337
2441
  controller.enqueue({
2338
2442
  type: "error",
2339
- error: JSON.parse(value)
2443
+ error: value
2340
2444
  });
2341
2445
  break;
2342
2446
  }
@@ -2348,6 +2452,14 @@ function assistantDecoderStream() {
2348
2452
  }
2349
2453
  });
2350
2454
  }
2455
+ var parseStreamPart = (part) => {
2456
+ const index = part.indexOf(":");
2457
+ if (index === -1) throw new Error("Invalid stream part");
2458
+ return [
2459
+ part.slice(0, index),
2460
+ JSON.parse(part.slice(index + 1))
2461
+ ];
2462
+ };
2351
2463
 
2352
2464
  // src/runtimes/edge/streams/chunkByLineStream.ts
2353
2465
  function chunkByLineStream() {
@@ -2730,7 +2842,7 @@ function runResultStream() {
2730
2842
  message,
2731
2843
  toolCallId,
2732
2844
  toolName,
2733
- parsePartialJson(currentToolCall.argsText)
2845
+ currentToolCall.argsText
2734
2846
  );
2735
2847
  controller.enqueue(message);
2736
2848
  break;
@@ -2778,7 +2890,7 @@ var appendOrUpdateText = (message, textDelta) => {
2778
2890
  content: contentParts.concat([contentPart])
2779
2891
  };
2780
2892
  };
2781
- var appendOrUpdateToolCall = (message, toolCallId, toolName, args) => {
2893
+ var appendOrUpdateToolCall = (message, toolCallId, toolName, argsText) => {
2782
2894
  let contentParts = message.content;
2783
2895
  let contentPart = message.content.at(-1);
2784
2896
  if (contentPart?.type !== "tool-call" || contentPart.toolCallId !== toolCallId) {
@@ -2786,13 +2898,15 @@ var appendOrUpdateToolCall = (message, toolCallId, toolName, args) => {
2786
2898
  type: "tool-call",
2787
2899
  toolCallId,
2788
2900
  toolName,
2789
- args
2901
+ argsText,
2902
+ args: parsePartialJson(argsText)
2790
2903
  };
2791
2904
  } else {
2792
2905
  contentParts = contentParts.slice(0, -1);
2793
2906
  contentPart = {
2794
2907
  ...contentPart,
2795
- args
2908
+ argsText,
2909
+ args: parsePartialJson(argsText)
2796
2910
  };
2797
2911
  }
2798
2912
  return {
@@ -2835,11 +2949,8 @@ var appendOrUpdateFinish = (message, chunk) => {
2835
2949
  };
2836
2950
  };
2837
2951
 
2838
- // src/runtimes/edge/useEdgeRuntime.ts
2839
- import { useMemo as useMemo3 } from "react";
2840
-
2841
2952
  // src/runtimes/edge/streams/toolResultStream.ts
2842
- import { z } from "zod";
2953
+ import { z as z2 } from "zod";
2843
2954
  import sjson2 from "secure-json-parse";
2844
2955
  function toolResultStream(tools) {
2845
2956
  const toolCallExecutions = /* @__PURE__ */ new Map();
@@ -2851,9 +2962,9 @@ function toolResultStream(tools) {
2851
2962
  case "tool-call": {
2852
2963
  const { toolCallId, toolCallType, toolName, args: argsText } = chunk;
2853
2964
  const tool = tools?.[toolName];
2854
- if (!tool) return;
2965
+ if (!tool || !tool.execute) return;
2855
2966
  const args = sjson2.parse(argsText);
2856
- if (tool.parameters instanceof z.ZodType) {
2967
+ if (tool.parameters instanceof z2.ZodType) {
2857
2968
  const result = tool.parameters.safeParse(args);
2858
2969
  if (!result.success) {
2859
2970
  controller.enqueue({
@@ -2905,9 +3016,7 @@ function toolResultStream(tools) {
2905
3016
  });
2906
3017
  }
2907
3018
 
2908
- // src/runtimes/edge/useEdgeRuntime.ts
2909
- import { z as z2 } from "zod";
2910
- import { zodToJsonSchema } from "zod-to-json-schema";
3019
+ // src/runtimes/edge/EdgeChatAdapter.ts
2911
3020
  function asAsyncIterable(source) {
2912
3021
  return {
2913
3022
  [Symbol.asyncIterator]: () => {
@@ -2921,28 +3030,20 @@ function asAsyncIterable(source) {
2921
3030
  }
2922
3031
  };
2923
3032
  }
2924
- var toSerializableTools = (tools) => {
2925
- if (!tools) return [];
2926
- return Object.entries(tools).map(([name, tool]) => ({
2927
- type: "function",
2928
- name,
2929
- ...tool.description ? { description: tool.description } : void 0,
2930
- parameters: tool.parameters instanceof z2.ZodType ? zodToJsonSchema(tool.parameters) : tool.parameters
2931
- }));
2932
- };
2933
- var createEdgeChatAdapter = ({
2934
- api
2935
- }) => ({
2936
- run: async ({ messages, abortSignal, config, onUpdate }) => {
2937
- const result = await fetch(api, {
3033
+ var EdgeChatAdapter = class {
3034
+ constructor(options) {
3035
+ this.options = options;
3036
+ }
3037
+ async run({ messages, abortSignal, config, onUpdate }) {
3038
+ const result = await fetch(this.options.api, {
2938
3039
  method: "POST",
2939
3040
  headers: {
2940
3041
  "Content-Type": "application/json"
2941
3042
  },
2942
3043
  body: JSON.stringify({
2943
3044
  system: config.system,
2944
- messages,
2945
- tools: toSerializableTools(
3045
+ messages: toCoreMessages(messages),
3046
+ tools: toLanguageModelTools(
2946
3047
  config.tools
2947
3048
  )
2948
3049
  }),
@@ -2957,15 +3058,251 @@ var createEdgeChatAdapter = ({
2957
3058
  throw new Error("No data received from Edge Runtime");
2958
3059
  return update;
2959
3060
  }
2960
- });
3061
+ };
3062
+
3063
+ // src/runtimes/edge/useEdgeRuntime.ts
2961
3064
  var useEdgeRuntime = (options) => {
2962
- const adapter = useMemo3(() => createEdgeChatAdapter(options), [options]);
3065
+ const [adapter] = useState8(() => new EdgeChatAdapter(options));
2963
3066
  return useLocalRuntime(adapter);
2964
3067
  };
2965
3068
 
3069
+ // src/runtimes/edge/converters/toLanguageModelMessages.ts
3070
+ var assistantMessageSplitter = () => {
3071
+ const stash = [];
3072
+ let assistantMessage = {
3073
+ role: "assistant",
3074
+ content: []
3075
+ };
3076
+ let toolMessage = {
3077
+ role: "tool",
3078
+ content: []
3079
+ };
3080
+ return {
3081
+ addTextContentPart: (part) => {
3082
+ if (toolMessage.content.length > 0) {
3083
+ stash.push(assistantMessage);
3084
+ stash.push(toolMessage);
3085
+ assistantMessage = {
3086
+ role: "assistant",
3087
+ content: []
3088
+ };
3089
+ toolMessage = {
3090
+ role: "tool",
3091
+ content: []
3092
+ };
3093
+ }
3094
+ assistantMessage.content.push(part);
3095
+ },
3096
+ addToolCallPart: (part) => {
3097
+ assistantMessage.content.push({
3098
+ type: "tool-call",
3099
+ toolCallId: part.toolCallId,
3100
+ toolName: part.toolName,
3101
+ args: part.args
3102
+ });
3103
+ if (part.result) {
3104
+ toolMessage.content.push({
3105
+ type: "tool-result",
3106
+ toolCallId: part.toolCallId,
3107
+ toolName: part.toolName,
3108
+ result: part.result
3109
+ // isError
3110
+ });
3111
+ }
3112
+ },
3113
+ getMessages: () => {
3114
+ if (toolMessage.content.length > 0) {
3115
+ return [...stash, assistantMessage, toolMessage];
3116
+ }
3117
+ return [...stash, assistantMessage];
3118
+ }
3119
+ };
3120
+ };
3121
+ function toLanguageModelMessages(message) {
3122
+ return message.flatMap((message2) => {
3123
+ const role = message2.role;
3124
+ switch (role) {
3125
+ case "system": {
3126
+ return [{ role: "system", content: message2.content[0].text }];
3127
+ }
3128
+ case "user": {
3129
+ const msg = {
3130
+ role: "user",
3131
+ content: message2.content.map(
3132
+ (part) => {
3133
+ const type = part.type;
3134
+ switch (type) {
3135
+ case "text": {
3136
+ return part;
3137
+ }
3138
+ case "image": {
3139
+ return {
3140
+ type: "image",
3141
+ image: new URL(part.image)
3142
+ };
3143
+ }
3144
+ default: {
3145
+ const unhandledType = type;
3146
+ throw new Error(
3147
+ `Unspported content part type: ${unhandledType}`
3148
+ );
3149
+ }
3150
+ }
3151
+ }
3152
+ )
3153
+ };
3154
+ return [msg];
3155
+ }
3156
+ case "assistant": {
3157
+ const splitter = assistantMessageSplitter();
3158
+ for (const part of message2.content) {
3159
+ const type = part.type;
3160
+ switch (type) {
3161
+ case "text": {
3162
+ splitter.addTextContentPart(part);
3163
+ break;
3164
+ }
3165
+ case "tool-call": {
3166
+ splitter.addToolCallPart(part);
3167
+ break;
3168
+ }
3169
+ default: {
3170
+ const unhandledType = type;
3171
+ throw new Error(`Unhandled content part type: ${unhandledType}`);
3172
+ }
3173
+ }
3174
+ }
3175
+ return splitter.getMessages();
3176
+ }
3177
+ default: {
3178
+ const unhandledRole = role;
3179
+ throw new Error(`Unknown message role: ${unhandledRole}`);
3180
+ }
3181
+ }
3182
+ });
3183
+ }
3184
+
3185
+ // src/runtimes/edge/converters/fromLanguageModelMessages.ts
3186
+ var fromLanguageModelMessages = (lm, mergeRoundtrips) => {
3187
+ const messages = [];
3188
+ for (const lmMessage of lm) {
3189
+ const role = lmMessage.role;
3190
+ switch (role) {
3191
+ case "system": {
3192
+ messages.push({
3193
+ role: "system",
3194
+ content: [
3195
+ {
3196
+ type: "text",
3197
+ text: lmMessage.content
3198
+ }
3199
+ ]
3200
+ });
3201
+ break;
3202
+ }
3203
+ case "user": {
3204
+ messages.push({
3205
+ role: "user",
3206
+ content: lmMessage.content.map((part) => {
3207
+ const type = part.type;
3208
+ switch (type) {
3209
+ case "text": {
3210
+ return {
3211
+ type: "text",
3212
+ text: part.text
3213
+ };
3214
+ }
3215
+ case "image": {
3216
+ if (part.image instanceof URL) {
3217
+ return {
3218
+ type: "image",
3219
+ image: part.image.href
3220
+ };
3221
+ }
3222
+ throw new Error("Only images with URL data are supported");
3223
+ }
3224
+ default: {
3225
+ const unhandledType = type;
3226
+ throw new Error(`Unknown content part type: ${unhandledType}`);
3227
+ }
3228
+ }
3229
+ })
3230
+ });
3231
+ break;
3232
+ }
3233
+ case "assistant": {
3234
+ const newContent = lmMessage.content.map((part) => {
3235
+ if (part.type === "tool-call") {
3236
+ return {
3237
+ type: "tool-call",
3238
+ toolCallId: part.toolCallId,
3239
+ toolName: part.toolName,
3240
+ argsText: JSON.stringify(part.args),
3241
+ args: typeof part.args === "string" ? part.args : part.args
3242
+ };
3243
+ }
3244
+ return part;
3245
+ });
3246
+ if (mergeRoundtrips) {
3247
+ const previousMessage = messages[messages.length - 1];
3248
+ if (previousMessage?.role === "assistant") {
3249
+ previousMessage.content.push(...newContent);
3250
+ break;
3251
+ }
3252
+ }
3253
+ messages.push({
3254
+ role: "assistant",
3255
+ content: newContent
3256
+ });
3257
+ break;
3258
+ }
3259
+ case "tool": {
3260
+ const previousMessage = messages[messages.length - 1];
3261
+ if (previousMessage?.role !== "assistant")
3262
+ throw new Error(
3263
+ "A tool message must be preceded by an assistant message."
3264
+ );
3265
+ for (const tool of lmMessage.content) {
3266
+ const toolCall = previousMessage.content.find(
3267
+ (c) => c.type === "tool-call" && c.toolCallId === tool.toolCallId
3268
+ );
3269
+ if (!toolCall)
3270
+ throw new Error("Received tool result for an unknown tool call.");
3271
+ if (toolCall.toolName !== tool.toolName)
3272
+ throw new Error("Tool call name mismatch.");
3273
+ toolCall.result = tool.result;
3274
+ if (tool.isError) {
3275
+ toolCall.isError = true;
3276
+ }
3277
+ }
3278
+ break;
3279
+ }
3280
+ default: {
3281
+ const unhandledRole = role;
3282
+ throw new Error(`Unknown message role: ${unhandledRole}`);
3283
+ }
3284
+ }
3285
+ }
3286
+ return messages;
3287
+ };
3288
+
3289
+ // src/runtimes/edge/converters/fromCoreMessage.ts
3290
+ var fromCoreMessages = (message) => {
3291
+ return message.map((message2) => {
3292
+ return {
3293
+ ...message2,
3294
+ id: generateId(),
3295
+ createdAt: /* @__PURE__ */ new Date(),
3296
+ ...message2.role === "assistant" ? {
3297
+ status: { type: "done" }
3298
+ } : void 0
3299
+ };
3300
+ });
3301
+ };
3302
+
2966
3303
  // src/ui/thread-config.tsx
2967
3304
  import { createContext as createContext5, useContext as useContext5 } from "react";
2968
- import { Fragment as Fragment3, jsx as jsx25 } from "react/jsx-runtime";
3305
+ import { Fragment as Fragment3, jsx as jsx29 } from "react/jsx-runtime";
2969
3306
  var ThreadConfigContext = createContext5({});
2970
3307
  var useThreadConfig = () => {
2971
3308
  return useContext5(ThreadConfigContext);
@@ -2975,119 +3312,21 @@ var ThreadConfigProvider = ({
2975
3312
  config
2976
3313
  }) => {
2977
3314
  const assistant = useAssistantContext({ optional: true });
2978
- const configProvider = config && Object.keys(config ?? {}).length > 0 ? /* @__PURE__ */ jsx25(ThreadConfigContext.Provider, { value: config, children }) : /* @__PURE__ */ jsx25(Fragment3, { children });
3315
+ const configProvider = config && Object.keys(config ?? {}).length > 0 ? /* @__PURE__ */ jsx29(ThreadConfigContext.Provider, { value: config, children }) : /* @__PURE__ */ jsx29(Fragment3, { children });
2979
3316
  if (!config?.runtime) return configProvider;
2980
3317
  if (assistant) {
2981
3318
  throw new Error(
2982
3319
  "You provided a runtime to <Thread> while simulataneously using <AssistantRuntimeProvider>. This is not allowed."
2983
3320
  );
2984
3321
  }
2985
- return /* @__PURE__ */ jsx25(AssistantRuntimeProvider, { runtime: config.runtime, children: configProvider });
3322
+ return /* @__PURE__ */ jsx29(AssistantRuntimeProvider, { runtime: config.runtime, children: configProvider });
2986
3323
  };
2987
3324
  ThreadConfigProvider.displayName = "ThreadConfigProvider";
2988
3325
 
2989
3326
  // src/ui/assistant-action-bar.tsx
2990
3327
  import { forwardRef as forwardRef18 } from "react";
2991
3328
  import { CheckIcon, CopyIcon, RefreshCwIcon } from "lucide-react";
2992
-
2993
- // src/ui/base/tooltip-icon-button.tsx
2994
- import { forwardRef as forwardRef17 } from "react";
2995
-
2996
- // src/ui/base/tooltip.tsx
2997
- import * as TooltipPrimitive from "@radix-ui/react-tooltip";
2998
-
2999
- // src/ui/utils/withDefaults.tsx
3000
- import {
3001
- forwardRef as forwardRef15
3002
- } from "react";
3003
- import classNames from "classnames";
3004
- import { jsx as jsx26 } from "react/jsx-runtime";
3005
- var withDefaultProps = ({
3006
- className,
3007
- ...defaultProps
3008
- }) => ({ className: classNameProp, ...props }) => {
3009
- return {
3010
- className: classNames(className, classNameProp),
3011
- ...defaultProps,
3012
- ...props
3013
- };
3014
- };
3015
- var withDefaults = (Component, defaultProps) => {
3016
- const getProps = withDefaultProps(defaultProps);
3017
- const WithDefaults = forwardRef15(
3018
- (props, ref) => {
3019
- const ComponentAsAny = Component;
3020
- return /* @__PURE__ */ jsx26(ComponentAsAny, { ...getProps(props), ref });
3021
- }
3022
- );
3023
- WithDefaults.displayName = "withDefaults(" + (typeof Component === "string" ? Component : Component.displayName) + ")";
3024
- return WithDefaults;
3025
- };
3026
-
3027
- // src/ui/base/tooltip.tsx
3028
- import { jsx as jsx27 } from "react/jsx-runtime";
3029
- var Tooltip = (props) => {
3030
- return /* @__PURE__ */ jsx27(TooltipPrimitive.Provider, { children: /* @__PURE__ */ jsx27(TooltipPrimitive.Root, { ...props }) });
3031
- };
3032
- Tooltip.displayName = "Tooltip";
3033
- var TooltipTrigger = TooltipPrimitive.Trigger;
3034
- var TooltipContent = withDefaults(TooltipPrimitive.Content, {
3035
- sideOffset: 4,
3036
- className: "aui-tooltip-content"
3037
- });
3038
- TooltipContent.displayName = "TooltipContent";
3039
-
3040
- // src/ui/base/button.tsx
3041
- import { cva } from "class-variance-authority";
3042
- import { Primitive as Primitive11 } from "@radix-ui/react-primitive";
3043
- import { forwardRef as forwardRef16 } from "react";
3044
- import { jsx as jsx28 } from "react/jsx-runtime";
3045
- var buttonVariants = cva("aui-button", {
3046
- variants: {
3047
- variant: {
3048
- default: "aui-button-primary",
3049
- outline: "aui-button-outline",
3050
- ghost: "aui-button-ghost"
3051
- },
3052
- size: {
3053
- default: "aui-button-medium",
3054
- icon: "aui-button-icon"
3055
- }
3056
- },
3057
- defaultVariants: {
3058
- variant: "default",
3059
- size: "default"
3060
- }
3061
- });
3062
- var Button = forwardRef16(
3063
- ({ className, variant, size, ...props }, ref) => {
3064
- return /* @__PURE__ */ jsx28(
3065
- Primitive11.button,
3066
- {
3067
- className: buttonVariants({ variant, size, className }),
3068
- ...props,
3069
- ref
3070
- }
3071
- );
3072
- }
3073
- );
3074
- Button.displayName = "Button";
3075
-
3076
- // src/ui/base/tooltip-icon-button.tsx
3077
- import { jsx as jsx29, jsxs as jsxs4 } from "react/jsx-runtime";
3078
- var TooltipIconButton = forwardRef17(({ children, tooltip, side = "bottom", ...rest }, ref) => {
3079
- return /* @__PURE__ */ jsxs4(Tooltip, { children: [
3080
- /* @__PURE__ */ jsx29(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs4(Button, { variant: "ghost", size: "icon", ...rest, ref, children: [
3081
- children,
3082
- /* @__PURE__ */ jsx29("span", { className: "aui-sr-only", children: tooltip })
3083
- ] }) }),
3084
- /* @__PURE__ */ jsx29(TooltipContent, { side, children: tooltip })
3085
- ] });
3086
- });
3087
- TooltipIconButton.displayName = "TooltipIconButton";
3088
-
3089
- // src/ui/assistant-action-bar.tsx
3090
- import { jsx as jsx30, jsxs as jsxs5 } from "react/jsx-runtime";
3329
+ import { Fragment as Fragment4, jsx as jsx30, jsxs as jsxs5 } from "react/jsx-runtime";
3091
3330
  var useAllowCopy = () => {
3092
3331
  const { assistantMessage: { allowCopy = true } = {} } = useThreadConfig();
3093
3332
  const { useThreadActions } = useThreadContext();
@@ -3130,10 +3369,10 @@ var AssistantActionBarCopy = forwardRef18((props, ref) => {
3130
3369
  } = useThreadConfig();
3131
3370
  const allowCopy = useAllowCopy();
3132
3371
  if (!allowCopy) return null;
3133
- return /* @__PURE__ */ jsx30(actionBar_exports.Copy, { asChild: true, children: /* @__PURE__ */ jsxs5(TooltipIconButton, { tooltip, ...props, ref, children: [
3372
+ return /* @__PURE__ */ jsx30(actionBar_exports.Copy, { asChild: true, children: /* @__PURE__ */ jsx30(TooltipIconButton, { tooltip, ...props, ref, children: props.children ?? /* @__PURE__ */ jsxs5(Fragment4, { children: [
3134
3373
  /* @__PURE__ */ jsx30(message_exports.If, { copied: true, children: /* @__PURE__ */ jsx30(CheckIcon, {}) }),
3135
3374
  /* @__PURE__ */ jsx30(message_exports.If, { copied: false, children: /* @__PURE__ */ jsx30(CopyIcon, {}) })
3136
- ] }) });
3375
+ ] }) }) });
3137
3376
  });
3138
3377
  AssistantActionBarCopy.displayName = "AssistantActionBarCopy";
3139
3378
  var AssistantActionBarReload = forwardRef18((props, ref) => {
@@ -3182,7 +3421,7 @@ var BranchPickerPrevious2 = forwardRef19((props, ref) => {
3182
3421
  branchPicker: { previous: { tooltip = "Previous" } = {} } = {}
3183
3422
  } = {}
3184
3423
  } = useThreadConfig();
3185
- return /* @__PURE__ */ jsx31(branchPicker_exports.Previous, { asChild: true, children: /* @__PURE__ */ jsx31(TooltipIconButton, { tooltip, ...props, ref, children: /* @__PURE__ */ jsx31(ChevronLeftIcon, {}) }) });
3424
+ return /* @__PURE__ */ jsx31(branchPicker_exports.Previous, { asChild: true, children: /* @__PURE__ */ jsx31(TooltipIconButton, { tooltip, ...props, ref, children: props.children ?? /* @__PURE__ */ jsx31(ChevronLeftIcon, {}) }) });
3186
3425
  });
3187
3426
  BranchPickerPrevious2.displayName = "BranchPickerPrevious";
3188
3427
  var BranchPickerStateWrapper = withDefaults("span", {
@@ -3200,7 +3439,7 @@ var BranchPickerNext = forwardRef19((props, ref) => {
3200
3439
  const {
3201
3440
  strings: { branchPicker: { next: { tooltip = "Next" } = {} } = {} } = {}
3202
3441
  } = useThreadConfig();
3203
- return /* @__PURE__ */ jsx31(branchPicker_exports.Next, { asChild: true, children: /* @__PURE__ */ jsx31(TooltipIconButton, { tooltip, ...props, ref, children: /* @__PURE__ */ jsx31(ChevronRightIcon, {}) }) });
3442
+ return /* @__PURE__ */ jsx31(branchPicker_exports.Next, { asChild: true, children: /* @__PURE__ */ jsx31(TooltipIconButton, { tooltip, ...props, ref, children: props.children ?? /* @__PURE__ */ jsx31(ChevronRightIcon, {}) }) });
3204
3443
  });
3205
3444
  BranchPickerNext.displayName = "BranchPickerNext";
3206
3445
  var exports2 = {
@@ -3307,7 +3546,7 @@ import { ArrowDownIcon } from "lucide-react";
3307
3546
 
3308
3547
  // src/ui/composer.tsx
3309
3548
  import { forwardRef as forwardRef21 } from "react";
3310
- import { SendHorizonalIcon } from "lucide-react";
3549
+ import { SendHorizontalIcon } from "lucide-react";
3311
3550
 
3312
3551
  // src/ui/base/CircleStopIcon.tsx
3313
3552
  import { jsx as jsx35 } from "react/jsx-runtime";
@@ -3325,7 +3564,7 @@ var CircleStopIcon = () => {
3325
3564
  CircleStopIcon.displayName = "CircleStopIcon";
3326
3565
 
3327
3566
  // src/ui/composer.tsx
3328
- import { Fragment as Fragment4, jsx as jsx36, jsxs as jsxs9 } from "react/jsx-runtime";
3567
+ import { Fragment as Fragment5, jsx as jsx36, jsxs as jsxs9 } from "react/jsx-runtime";
3329
3568
  var Composer = () => {
3330
3569
  return /* @__PURE__ */ jsxs9(ComposerRoot, { children: [
3331
3570
  /* @__PURE__ */ jsx36(ComposerInput, { autoFocus: true }),
@@ -3361,7 +3600,7 @@ var useAllowCancel = () => {
3361
3600
  var ComposerAction = () => {
3362
3601
  const allowCancel = useAllowCancel();
3363
3602
  if (!allowCancel) return /* @__PURE__ */ jsx36(ComposerSend, {});
3364
- return /* @__PURE__ */ jsxs9(Fragment4, { children: [
3603
+ return /* @__PURE__ */ jsxs9(Fragment5, { children: [
3365
3604
  /* @__PURE__ */ jsx36(thread_exports.If, { running: false, children: /* @__PURE__ */ jsx36(ComposerSend, {}) }),
3366
3605
  /* @__PURE__ */ jsx36(thread_exports.If, { running: true, children: /* @__PURE__ */ jsx36(ComposerCancel, {}) })
3367
3606
  ] });
@@ -3375,7 +3614,7 @@ var ComposerSend = forwardRef21((props, ref) => {
3375
3614
  const {
3376
3615
  strings: { composer: { send: { tooltip = "Send" } = {} } = {} } = {}
3377
3616
  } = useThreadConfig();
3378
- return /* @__PURE__ */ jsx36(composer_exports.Send, { asChild: true, children: /* @__PURE__ */ jsx36(ComposerSendButton, { tooltip, ...props, ref, children: /* @__PURE__ */ jsx36(SendHorizonalIcon, {}) }) });
3617
+ return /* @__PURE__ */ jsx36(composer_exports.Send, { asChild: true, children: /* @__PURE__ */ jsx36(ComposerSendButton, { tooltip, ...props, ref, children: props.children ?? /* @__PURE__ */ jsx36(SendHorizontalIcon, {}) }) });
3379
3618
  });
3380
3619
  ComposerSend.displayName = "ComposerSend";
3381
3620
  var ComposerCancelButton = withDefaults(TooltipIconButton, {
@@ -3386,7 +3625,7 @@ var ComposerCancel = forwardRef21((props, ref) => {
3386
3625
  const {
3387
3626
  strings: { composer: { cancel: { tooltip = "Cancel" } = {} } = {} } = {}
3388
3627
  } = useThreadConfig();
3389
- return /* @__PURE__ */ jsx36(composer_exports.Cancel, { asChild: true, children: /* @__PURE__ */ jsx36(ComposerCancelButton, { tooltip, ...props, ref, children: /* @__PURE__ */ jsx36(CircleStopIcon, {}) }) });
3628
+ return /* @__PURE__ */ jsx36(composer_exports.Cancel, { asChild: true, children: /* @__PURE__ */ jsx36(ComposerCancelButton, { tooltip, ...props, ref, children: props.children ?? /* @__PURE__ */ jsx36(CircleStopIcon, {}) }) });
3390
3629
  });
3391
3630
  ComposerCancel.displayName = "ComposerCancel";
3392
3631
  var exports5 = {
@@ -3501,7 +3740,7 @@ var UserActionBarEdit = forwardRef23((props, ref) => {
3501
3740
  } = useThreadConfig();
3502
3741
  const allowEdit = useAllowEdit();
3503
3742
  if (!allowEdit) return null;
3504
- return /* @__PURE__ */ jsx38(actionBar_exports.Edit, { asChild: true, children: /* @__PURE__ */ jsx38(TooltipIconButton, { tooltip, ...props, ref, children: /* @__PURE__ */ jsx38(PencilIcon, {}) }) });
3743
+ return /* @__PURE__ */ jsx38(actionBar_exports.Edit, { asChild: true, children: /* @__PURE__ */ jsx38(TooltipIconButton, { tooltip, ...props, ref, children: props.children ?? /* @__PURE__ */ jsx38(PencilIcon, {}) }) });
3505
3744
  });
3506
3745
  UserActionBarEdit.displayName = "UserActionBarEdit";
3507
3746
  var exports7 = {
@@ -3579,7 +3818,7 @@ var EditComposerCancel = forwardRef25(
3579
3818
  editComposer: { cancel: { label = "Cancel" } = {} } = {}
3580
3819
  } = {}
3581
3820
  } = useThreadConfig();
3582
- return /* @__PURE__ */ jsx40(composer_exports.Cancel, { asChild: true, children: /* @__PURE__ */ jsx40(Button, { variant: "ghost", ...props, ref, children: label }) });
3821
+ return /* @__PURE__ */ jsx40(composer_exports.Cancel, { asChild: true, children: /* @__PURE__ */ jsx40(Button, { variant: "ghost", ...props, ref, children: props.children ?? label }) });
3583
3822
  }
3584
3823
  );
3585
3824
  EditComposerCancel.displayName = "EditComposerCancel";
@@ -3588,7 +3827,7 @@ var EditComposerSend = forwardRef25(
3588
3827
  const {
3589
3828
  strings: { editComposer: { send: { label = "Send" } = {} } = {} } = {}
3590
3829
  } = useThreadConfig();
3591
- return /* @__PURE__ */ jsx40(composer_exports.Send, { asChild: true, children: /* @__PURE__ */ jsx40(Button, { ...props, ref, children: label }) });
3830
+ return /* @__PURE__ */ jsx40(composer_exports.Send, { asChild: true, children: /* @__PURE__ */ jsx40(Button, { ...props, ref, children: props.children ?? label }) });
3592
3831
  }
3593
3832
  );
3594
3833
  EditComposerSend.displayName = "EditComposerSend";
@@ -3656,7 +3895,10 @@ var ThreadScrollToBottom = forwardRef26((props, ref) => {
3656
3895
  thread: { scrollToBottom: { tooltip = "Scroll to bottom" } = {} } = {}
3657
3896
  } = {}
3658
3897
  } = useThreadConfig();
3659
- return /* @__PURE__ */ jsx41(thread_exports.ScrollToBottom, { asChild: true, children: /* @__PURE__ */ jsx41(ThreadScrollToBottomIconButton, { tooltip, ...props, ref, children: /* @__PURE__ */ jsx41(ArrowDownIcon, {}) }) });
3898
+ return /* @__PURE__ */ jsx41(thread_exports.ScrollToBottom, { asChild: true, children: /* @__PURE__ */ jsxs13(ThreadScrollToBottomIconButton, { tooltip, ...props, ref, children: [
3899
+ "|",
3900
+ props.children ?? /* @__PURE__ */ jsx41(ArrowDownIcon, {})
3901
+ ] }) });
3660
3902
  });
3661
3903
  ThreadScrollToBottom.displayName = "ThreadScrollToBottom";
3662
3904
  var exports10 = {
@@ -3669,7 +3911,7 @@ var exports10 = {
3669
3911
  var thread_default = Object.assign(Thread, exports10);
3670
3912
 
3671
3913
  // src/ui/assistant-modal.tsx
3672
- import { jsx as jsx42, jsxs as jsxs14 } from "react/jsx-runtime";
3914
+ import { Fragment as Fragment6, jsx as jsx42, jsxs as jsxs14 } from "react/jsx-runtime";
3673
3915
  var AssistantModal = (config) => {
3674
3916
  return /* @__PURE__ */ jsxs14(AssistantModalRoot, { config, children: [
3675
3917
  /* @__PURE__ */ jsx42(AssistantModalTrigger, {}),
@@ -3707,7 +3949,7 @@ var AssistantModalButton = forwardRef27(({ "data-state": state, ...rest }, ref)
3707
3949
  } = {}
3708
3950
  } = useThreadConfig();
3709
3951
  const tooltip = state === "open" ? openTooltip : closedTooltip;
3710
- return /* @__PURE__ */ jsxs14(
3952
+ return /* @__PURE__ */ jsx42(
3711
3953
  ModalButtonStyled,
3712
3954
  {
3713
3955
  side: "left",
@@ -3715,17 +3957,22 @@ var AssistantModalButton = forwardRef27(({ "data-state": state, ...rest }, ref)
3715
3957
  "data-state": state,
3716
3958
  ...rest,
3717
3959
  ref,
3718
- children: [
3719
- /* @__PURE__ */ jsx42(BotIcon, { "data-state": state, className: "aui-modal-button-closed-icon" }),
3960
+ children: rest.children ?? /* @__PURE__ */ jsxs14(Fragment6, { children: [
3961
+ /* @__PURE__ */ jsx42(
3962
+ BotIcon,
3963
+ {
3964
+ "data-state": state,
3965
+ className: "aui-modal-button-closed-icon"
3966
+ }
3967
+ ),
3720
3968
  /* @__PURE__ */ jsx42(
3721
3969
  ChevronDownIcon,
3722
3970
  {
3723
3971
  "data-state": state,
3724
3972
  className: "aui-modal-button-open-icon"
3725
3973
  }
3726
- ),
3727
- /* @__PURE__ */ jsx42("span", { className: "aui-sr-only", children: tooltip })
3728
- ]
3974
+ )
3975
+ ] })
3729
3976
  }
3730
3977
  );
3731
3978
  });
@@ -3741,16 +3988,6 @@ var exports11 = {
3741
3988
  Content: AssistantModalContent
3742
3989
  };
3743
3990
  var assistant_modal_default = Object.assign(AssistantModal, exports11);
3744
-
3745
- // src/internal.ts
3746
- var internal_exports = {};
3747
- __export(internal_exports, {
3748
- BaseAssistantRuntime: () => BaseAssistantRuntime,
3749
- MessageRepository: () => MessageRepository,
3750
- ProxyConfigProvider: () => ProxyConfigProvider,
3751
- TooltipIconButton: () => TooltipIconButton,
3752
- useSmooth: () => useSmooth
3753
- });
3754
3991
  export {
3755
3992
  actionBar_exports as ActionBarPrimitive,
3756
3993
  assistant_action_bar_default as AssistantActionBar,
@@ -3764,6 +4001,7 @@ export {
3764
4001
  composer_exports as ComposerPrimitive,
3765
4002
  content_part_default as ContentPart,
3766
4003
  contentPart_exports as ContentPartPrimitive,
4004
+ EdgeChatAdapter,
3767
4005
  edit_composer_default as EditComposer,
3768
4006
  internal_exports as INTERNAL,
3769
4007
  message_exports as MessagePrimitive,
@@ -3773,8 +4011,11 @@ export {
3773
4011
  thread_welcome_default as ThreadWelcome,
3774
4012
  user_action_bar_default as UserActionBar,
3775
4013
  user_message_default as UserMessage,
4014
+ fromCoreMessages,
4015
+ fromLanguageModelMessages,
3776
4016
  makeAssistantTool,
3777
4017
  makeAssistantToolUI,
4018
+ toLanguageModelMessages,
3778
4019
  useActionBarCopy,
3779
4020
  useActionBarEdit,
3780
4021
  useActionBarReload,