@assistant-ui/react 0.4.2 → 0.4.4

Sign up to get free protection for your applications and to get access to all the features.
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,