@assistant-ui/react 0.5.23 → 0.5.25

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.js CHANGED
@@ -159,11 +159,23 @@ var makeComposerStore = (useThreadMessages, useThreadActions) => {
159
159
 
160
160
  // src/context/stores/Thread.ts
161
161
 
162
+ var getThreadStateFromRuntime = (runtime) => {
163
+ const lastMessage = runtime.messages.at(-1);
164
+ if (_optionalChain([lastMessage, 'optionalAccess', _11 => _11.role]) !== "assistant")
165
+ return Object.freeze({
166
+ isDisabled: runtime.isDisabled,
167
+ isRunning: false,
168
+ unstable_canAppendNew: runtime.isDisabled
169
+ });
170
+ return Object.freeze({
171
+ isDisabled: runtime.isDisabled,
172
+ isRunning: lastMessage.status.type === "running",
173
+ unstable_canAppendNew: !runtime.isDisabled && lastMessage.status.type !== "running" && lastMessage.status.type !== "requires-action"
174
+ });
175
+ };
162
176
  var makeThreadStore = (runtimeRef) => {
163
- return _zustand.create.call(void 0, () => ({
164
- isDisabled: runtimeRef.getState().isDisabled,
165
- isRunning: runtimeRef.getState().isRunning
166
- }));
177
+ const runtime = runtimeRef.getState();
178
+ return _zustand.create.call(void 0, () => getThreadStateFromRuntime(runtime));
167
179
  };
168
180
 
169
181
  // src/context/stores/ThreadViewport.tsx
@@ -260,13 +272,11 @@ var ThreadProvider = ({
260
272
  _react.useCallback.call(void 0,
261
273
  (thread) => {
262
274
  const onThreadUpdate = () => {
263
- const threadState = context.useThread.getState();
264
- if (thread.isRunning !== threadState.isRunning || thread.isDisabled !== threadState.isDisabled) {
275
+ const oldState = context.useThread.getState();
276
+ const state = getThreadStateFromRuntime(thread);
277
+ if (oldState.isDisabled !== state.isDisabled || oldState.isRunning !== state.isRunning || oldState.unstable_canAppendNew !== state.unstable_canAppendNew) {
265
278
  context.useThread.setState(
266
- Object.freeze({
267
- isRunning: thread.isRunning,
268
- isDisabled: thread.isDisabled
269
- }),
279
+ getThreadStateFromRuntime(thread),
270
280
  true
271
281
  );
272
282
  }
@@ -344,7 +354,7 @@ var AssistantRuntimeProvider = _react.memo.call(void 0, AssistantRuntimeProvider
344
354
  var MessageContext = _react.createContext.call(void 0, null);
345
355
  function useMessageContext(options) {
346
356
  const context = _react.useContext.call(void 0, MessageContext);
347
- if (!_optionalChain([options, 'optionalAccess', _11 => _11.optional]) && !context)
357
+ if (!_optionalChain([options, 'optionalAccess', _12 => _12.optional]) && !context)
348
358
  throw new Error(
349
359
  "This component can only be used inside a component passed to <ThreadPrimitive.Messages components={...} />."
350
360
  );
@@ -371,7 +381,7 @@ var ContentPartContext = _react.createContext.call(void 0,
371
381
  );
372
382
  function useContentPartContext(options) {
373
383
  const context = _react.useContext.call(void 0, ContentPartContext);
374
- if (!_optionalChain([options, 'optionalAccess', _12 => _12.optional]) && !context)
384
+ if (!_optionalChain([options, 'optionalAccess', _13 => _13.optional]) && !context)
375
385
  throw new Error(
376
386
  "This component can only be used inside a component passed to <MessagePrimitive.Content components={...} >."
377
387
  );
@@ -383,13 +393,13 @@ function useContentPartContext(options) {
383
393
  var toAppendMessage = (useThreadMessages, message) => {
384
394
  if (typeof message === "string") {
385
395
  return {
386
- parentId: _nullishCoalesce(_optionalChain([useThreadMessages, 'access', _13 => _13.getState, 'call', _14 => _14(), 'access', _15 => _15.at, 'call', _16 => _16(-1), 'optionalAccess', _17 => _17.id]), () => ( null)),
396
+ parentId: _nullishCoalesce(_optionalChain([useThreadMessages, 'access', _14 => _14.getState, 'call', _15 => _15(), 'access', _16 => _16.at, 'call', _17 => _17(-1), 'optionalAccess', _18 => _18.id]), () => ( null)),
387
397
  role: "user",
388
398
  content: [{ type: "text", text: message }]
389
399
  };
390
400
  }
391
401
  return {
392
- parentId: _nullishCoalesce(_nullishCoalesce(message.parentId, () => ( _optionalChain([useThreadMessages, 'access', _18 => _18.getState, 'call', _19 => _19(), 'access', _20 => _20.at, 'call', _21 => _21(-1), 'optionalAccess', _22 => _22.id]))), () => ( null)),
402
+ parentId: _nullishCoalesce(_nullishCoalesce(message.parentId, () => ( _optionalChain([useThreadMessages, 'access', _19 => _19.getState, 'call', _20 => _20(), 'access', _21 => _21.at, 'call', _22 => _22(-1), 'optionalAccess', _23 => _23.id]))), () => ( null)),
393
403
  role: _nullishCoalesce(message.role, () => ( "user")),
394
404
  content: message.content
395
405
  };
@@ -441,7 +451,7 @@ var useAssistantTool = (tool) => {
441
451
  const unsub2 = render ? setToolUI(toolName, render) : void 0;
442
452
  return () => {
443
453
  unsub1();
444
- _optionalChain([unsub2, 'optionalCall', _23 => _23()]);
454
+ _optionalChain([unsub2, 'optionalCall', _24 => _24()]);
445
455
  };
446
456
  }, [registerModelConfigProvider, setToolUI, tool]);
447
457
  };
@@ -520,8 +530,8 @@ var useCombinedStore = (stores, selector) => {
520
530
  return useCombined(selector);
521
531
  };
522
532
 
523
- // src/utils/getMessageText.tsx
524
- var getMessageText = (message) => {
533
+ // src/utils/getThreadMessageText.tsx
534
+ var getThreadMessageText = (message) => {
525
535
  const textParts = message.content.filter(
526
536
  (part) => part.type === "text"
527
537
  );
@@ -543,7 +553,7 @@ var useActionBarCopy = ({
543
553
  const { message } = useMessage.getState();
544
554
  const { setIsCopied } = useMessageUtils.getState();
545
555
  const { isEditing, value: composerValue } = useEditComposer.getState();
546
- const valueToCopy = isEditing ? composerValue : getMessageText(message);
556
+ const valueToCopy = isEditing ? composerValue : getThreadMessageText(message);
547
557
  navigator.clipboard.writeText(valueToCopy).then(() => {
548
558
  setIsCopied(true);
549
559
  setTimeout(() => setIsCopied(false), copiedDuration);
@@ -670,7 +680,7 @@ var useComposerSend = () => {
670
680
  const { useComposer } = useComposerContext();
671
681
  const disabled = useCombinedStore(
672
682
  [useThread, useComposer],
673
- (t, c) => t.isDisabled || t.isRunning || !c.isEditing || c.value.length === 0
683
+ (t, c) => !t.unstable_canAppendNew || !c.isEditing || c.value.length === 0
674
684
  );
675
685
  const callback = _react.useCallback.call(void 0, () => {
676
686
  const composerState = useComposer.getState();
@@ -878,7 +888,7 @@ var createActionButton = (displayName, useActionButton, forwardProps = []) => {
878
888
  ...primitiveProps,
879
889
  ref: forwardedRef,
880
890
  onClick: _primitive.composeEventHandlers.call(void 0, primitiveProps.onClick, () => {
881
- _optionalChain([callback, 'optionalCall', _24 => _24()]);
891
+ _optionalChain([callback, 'optionalCall', _25 => _25()]);
882
892
  })
883
893
  }
884
894
  );
@@ -1166,7 +1176,7 @@ var getContentPartState = ({ message }, useContentPart, partIndex) => {
1166
1176
  }
1167
1177
  }
1168
1178
  const status = toContentPartStatus(message, partIndex, part);
1169
- const currentState = _optionalChain([useContentPart, 'optionalAccess', _25 => _25.getState, 'call', _26 => _26()]);
1179
+ const currentState = _optionalChain([useContentPart, 'optionalAccess', _26 => _26.getState, 'call', _27 => _27()]);
1170
1180
  if (currentState && currentState.part === part && currentState.status === status)
1171
1181
  return null;
1172
1182
  return Object.freeze({ part, status });
@@ -1242,7 +1252,7 @@ var withSmoothContextProvider = (Component) => {
1242
1252
  };
1243
1253
  function useSmoothContext(options) {
1244
1254
  const context = _react.useContext.call(void 0, SmoothContext);
1245
- if (!_optionalChain([options, 'optionalAccess', _27 => _27.optional]) && !context)
1255
+ if (!_optionalChain([options, 'optionalAccess', _28 => _28.optional]) && !context)
1246
1256
  throw new Error(
1247
1257
  "This component must be used within a SmoothContextProvider."
1248
1258
  );
@@ -1313,7 +1323,7 @@ var useSmooth = (state, smooth = false) => {
1313
1323
  const [displayedText, setDisplayedText] = _react.useState.call(void 0, text);
1314
1324
  const setText = _reactusecallbackref.useCallbackRef.call(void 0, (text2) => {
1315
1325
  setDisplayedText(text2);
1316
- _optionalChain([useSmoothStatus2, 'optionalAccess', _28 => _28.setState, 'call', _29 => _29(text2 !== state.part.text ? SMOOTH_STATUS : state.status)]);
1326
+ _optionalChain([useSmoothStatus2, 'optionalAccess', _29 => _29.setState, 'call', _30 => _30(text2 !== state.part.text ? SMOOTH_STATUS : state.status)]);
1317
1327
  });
1318
1328
  const [animatorRef] = _react.useState.call(void 0,
1319
1329
  new TextStreamAnimator(text, setText)
@@ -1457,7 +1467,7 @@ var MessageContentPartImpl = ({
1457
1467
  };
1458
1468
  var MessageContentPart = _react.memo.call(void 0,
1459
1469
  MessageContentPartImpl,
1460
- (prev, next) => prev.partIndex === next.partIndex && _optionalChain([prev, 'access', _30 => _30.components, 'optionalAccess', _31 => _31.Text]) === _optionalChain([next, 'access', _32 => _32.components, 'optionalAccess', _33 => _33.Text]) && _optionalChain([prev, 'access', _34 => _34.components, 'optionalAccess', _35 => _35.Image]) === _optionalChain([next, 'access', _36 => _36.components, 'optionalAccess', _37 => _37.Image]) && _optionalChain([prev, 'access', _38 => _38.components, 'optionalAccess', _39 => _39.UI]) === _optionalChain([next, 'access', _40 => _40.components, 'optionalAccess', _41 => _41.UI]) && _optionalChain([prev, 'access', _42 => _42.components, 'optionalAccess', _43 => _43.tools]) === _optionalChain([next, 'access', _44 => _44.components, 'optionalAccess', _45 => _45.tools])
1470
+ (prev, next) => prev.partIndex === next.partIndex && _optionalChain([prev, 'access', _31 => _31.components, 'optionalAccess', _32 => _32.Text]) === _optionalChain([next, 'access', _33 => _33.components, 'optionalAccess', _34 => _34.Text]) && _optionalChain([prev, 'access', _35 => _35.components, 'optionalAccess', _36 => _36.Image]) === _optionalChain([next, 'access', _37 => _37.components, 'optionalAccess', _38 => _38.Image]) && _optionalChain([prev, 'access', _39 => _39.components, 'optionalAccess', _40 => _40.UI]) === _optionalChain([next, 'access', _41 => _41.components, 'optionalAccess', _42 => _42.UI]) && _optionalChain([prev, 'access', _43 => _43.components, 'optionalAccess', _44 => _44.tools]) === _optionalChain([next, 'access', _45 => _45.components, 'optionalAccess', _46 => _46.tools])
1461
1471
  );
1462
1472
  var MessagePrimitiveContent = ({
1463
1473
  components
@@ -1568,10 +1578,10 @@ var ComposerPrimitiveInput = _react.forwardRef.call(void 0,
1568
1578
  const handleKeyPress = (e) => {
1569
1579
  if (isDisabled) return;
1570
1580
  if (e.key === "Enter" && e.shiftKey === false) {
1571
- const isRunning = useThread.getState().isRunning;
1572
- if (!isRunning) {
1581
+ const { unstable_canAppendNew } = useThread.getState();
1582
+ if (unstable_canAppendNew) {
1573
1583
  e.preventDefault();
1574
- _optionalChain([textareaRef, 'access', _46 => _46.current, 'optionalAccess', _47 => _47.closest, 'call', _48 => _48("form"), 'optionalAccess', _49 => _49.requestSubmit, 'call', _50 => _50()]);
1584
+ _optionalChain([textareaRef, 'access', _47 => _47.current, 'optionalAccess', _48 => _48.closest, 'call', _49 => _49("form"), 'optionalAccess', _50 => _50.requestSubmit, 'call', _51 => _51()]);
1575
1585
  }
1576
1586
  }
1577
1587
  };
@@ -1865,15 +1875,15 @@ var makeMessageUtilsStore = () => _zustand.create.call(void 0, (set) => ({
1865
1875
  // src/context/providers/MessageProvider.tsx
1866
1876
 
1867
1877
  var getIsLast = (messages, message) => {
1868
- return _optionalChain([messages, 'access', _51 => _51[messages.length - 1], 'optionalAccess', _52 => _52.id]) === message.id;
1878
+ return _optionalChain([messages, 'access', _52 => _52[messages.length - 1], 'optionalAccess', _53 => _53.id]) === message.id;
1869
1879
  };
1870
1880
  var getMessageState = (messages, getBranches, useMessage, messageIndex) => {
1871
- const parentId = _nullishCoalesce(_optionalChain([messages, 'access', _53 => _53[messageIndex - 1], 'optionalAccess', _54 => _54.id]), () => ( null));
1881
+ const parentId = _nullishCoalesce(_optionalChain([messages, 'access', _54 => _54[messageIndex - 1], 'optionalAccess', _55 => _55.id]), () => ( null));
1872
1882
  const message = messages[messageIndex];
1873
1883
  if (!message) return null;
1874
1884
  const isLast = getIsLast(messages, message);
1875
1885
  const branches = getBranches(message.id);
1876
- const currentState = _optionalChain([useMessage, 'optionalAccess', _55 => _55.getState, 'call', _56 => _56()]);
1886
+ const currentState = _optionalChain([useMessage, 'optionalAccess', _56 => _56.getState, 'call', _57 => _57()]);
1877
1887
  if (currentState && currentState.message === message && currentState.parentId === parentId && currentState.branches === branches && currentState.isLast === isLast)
1878
1888
  return null;
1879
1889
  return Object.freeze({
@@ -1902,7 +1912,7 @@ var useMessageContext2 = (messageIndex) => {
1902
1912
  throw new Error(
1903
1913
  "Tried to edit a non-user message. Editing is only supported for user messages. This is likely an internal bug in assistant-ui."
1904
1914
  );
1905
- const text = getMessageText(message);
1915
+ const text = getThreadMessageText(message);
1906
1916
  return text;
1907
1917
  },
1908
1918
  onSend: (text) => {
@@ -2000,7 +2010,7 @@ var ThreadPrimitiveMessagesImpl = ({
2000
2010
  ThreadPrimitiveMessagesImpl.displayName = "ThreadPrimitive.Messages";
2001
2011
  var ThreadPrimitiveMessages = _react.memo.call(void 0,
2002
2012
  ThreadPrimitiveMessagesImpl,
2003
- (prev, next) => _optionalChain([prev, 'access', _57 => _57.components, 'optionalAccess', _58 => _58.Message]) === _optionalChain([next, 'access', _59 => _59.components, 'optionalAccess', _60 => _60.Message]) && _optionalChain([prev, 'access', _61 => _61.components, 'optionalAccess', _62 => _62.UserMessage]) === _optionalChain([next, 'access', _63 => _63.components, 'optionalAccess', _64 => _64.UserMessage]) && _optionalChain([prev, 'access', _65 => _65.components, 'optionalAccess', _66 => _66.EditComposer]) === _optionalChain([next, 'access', _67 => _67.components, 'optionalAccess', _68 => _68.EditComposer]) && _optionalChain([prev, 'access', _69 => _69.components, 'optionalAccess', _70 => _70.AssistantMessage]) === _optionalChain([next, 'access', _71 => _71.components, 'optionalAccess', _72 => _72.AssistantMessage]) && _optionalChain([prev, 'access', _73 => _73.components, 'optionalAccess', _74 => _74.SystemMessage]) === _optionalChain([next, 'access', _75 => _75.components, 'optionalAccess', _76 => _76.SystemMessage])
2013
+ (prev, next) => _optionalChain([prev, 'access', _58 => _58.components, 'optionalAccess', _59 => _59.Message]) === _optionalChain([next, 'access', _60 => _60.components, 'optionalAccess', _61 => _61.Message]) && _optionalChain([prev, 'access', _62 => _62.components, 'optionalAccess', _63 => _63.UserMessage]) === _optionalChain([next, 'access', _64 => _64.components, 'optionalAccess', _65 => _65.UserMessage]) && _optionalChain([prev, 'access', _66 => _66.components, 'optionalAccess', _67 => _67.EditComposer]) === _optionalChain([next, 'access', _68 => _68.components, 'optionalAccess', _69 => _69.EditComposer]) && _optionalChain([prev, 'access', _70 => _70.components, 'optionalAccess', _71 => _71.AssistantMessage]) === _optionalChain([next, 'access', _72 => _72.components, 'optionalAccess', _73 => _73.AssistantMessage]) && _optionalChain([prev, 'access', _74 => _74.components, 'optionalAccess', _75 => _75.SystemMessage]) === _optionalChain([next, 'access', _76 => _76.components, 'optionalAccess', _77 => _77.SystemMessage])
2004
2014
  );
2005
2015
 
2006
2016
  // src/primitives/thread/ThreadScrollToBottom.tsx
@@ -2132,7 +2142,7 @@ var MessageRepository = (_class4 = class {constructor() { _class4.prototype.__in
2132
2142
  parentOrRoot.children = parentOrRoot.children.filter(
2133
2143
  (m) => m !== child.current.id
2134
2144
  );
2135
- if (_optionalChain([child, 'access', _77 => _77.prev, 'optionalAccess', _78 => _78.next]) === child) {
2145
+ if (_optionalChain([child, 'access', _78 => _78.prev, 'optionalAccess', _79 => _79.next]) === child) {
2136
2146
  const fallbackId = child.prev.children.at(-1);
2137
2147
  const fallback = fallbackId ? this.messages.get(fallbackId) : null;
2138
2148
  if (fallback === void 0) {
@@ -2144,6 +2154,13 @@ var MessageRepository = (_class4 = class {constructor() { _class4.prototype.__in
2144
2154
  }
2145
2155
  }
2146
2156
  if (operation !== "cut") {
2157
+ for (let current = newParent; current; current = current.prev) {
2158
+ if (current.current.id === child.current.id) {
2159
+ throw new Error(
2160
+ "MessageRepository(performOp/link): A message with the same id already exists in the parent tree. This error occurs if the same message id is found multiple times. This is likely an internal bug in assistant-ui."
2161
+ );
2162
+ }
2163
+ }
2147
2164
  newParentOrRoot.children = [
2148
2165
  ...newParentOrRoot.children,
2149
2166
  child.current.id
@@ -2155,7 +2172,7 @@ var MessageRepository = (_class4 = class {constructor() { _class4.prototype.__in
2155
2172
  }
2156
2173
  }
2157
2174
  getMessages() {
2158
- const messages = new Array(_nullishCoalesce(_optionalChain([this, 'access', _79 => _79.head, 'optionalAccess', _80 => _80.level]), () => ( 0)));
2175
+ const messages = new Array(_nullishCoalesce(_optionalChain([this, 'access', _80 => _80.head, 'optionalAccess', _81 => _81.level]), () => ( 0)));
2159
2176
  for (let current = this.head; current; current = current.prev) {
2160
2177
  messages[current.level] = current.current;
2161
2178
  }
@@ -2193,7 +2210,7 @@ var MessageRepository = (_class4 = class {constructor() { _class4.prototype.__in
2193
2210
  "MessageRepository(updateMessage): Message not found. This is likely an internal bug in assistant-ui."
2194
2211
  );
2195
2212
  return {
2196
- parentId: _nullishCoalesce(_optionalChain([message, 'access', _81 => _81.prev, 'optionalAccess', _82 => _82.current, 'access', _83 => _83.id]), () => ( null)),
2213
+ parentId: _nullishCoalesce(_optionalChain([message, 'access', _82 => _82.prev, 'optionalAccess', _83 => _83.current, 'access', _84 => _84.id]), () => ( null)),
2197
2214
  message: message.current
2198
2215
  };
2199
2216
  }
@@ -2278,11 +2295,11 @@ var MessageRepository = (_class4 = class {constructor() { _class4.prototype.__in
2278
2295
  for (const [, message] of this.messages) {
2279
2296
  exportItems.push({
2280
2297
  message: message.current,
2281
- parentId: _nullishCoalesce(_optionalChain([message, 'access', _84 => _84.prev, 'optionalAccess', _85 => _85.current, 'access', _86 => _86.id]), () => ( null))
2298
+ parentId: _nullishCoalesce(_optionalChain([message, 'access', _85 => _85.prev, 'optionalAccess', _86 => _86.current, 'access', _87 => _87.id]), () => ( null))
2282
2299
  });
2283
2300
  }
2284
2301
  return {
2285
- headId: _nullishCoalesce(_optionalChain([this, 'access', _87 => _87.head, 'optionalAccess', _88 => _88.current, 'access', _89 => _89.id]), () => ( null)),
2302
+ headId: _nullishCoalesce(_optionalChain([this, 'access', _88 => _88.head, 'optionalAccess', _89 => _89.current, 'access', _90 => _90.id]), () => ( null)),
2286
2303
  messages: exportItems
2287
2304
  };
2288
2305
  }
@@ -2290,7 +2307,7 @@ var MessageRepository = (_class4 = class {constructor() { _class4.prototype.__in
2290
2307
  for (const { message, parentId } of messages) {
2291
2308
  this.addOrUpdateMessage(parentId, message);
2292
2309
  }
2293
- this.resetHead(_nullishCoalesce(_nullishCoalesce(headId, () => ( _optionalChain([messages, 'access', _90 => _90.at, 'call', _91 => _91(-1), 'optionalAccess', _92 => _92.message, 'access', _93 => _93.id]))), () => ( null)));
2310
+ this.resetHead(_nullishCoalesce(_nullishCoalesce(headId, () => ( _optionalChain([messages, 'access', _91 => _91.at, 'call', _92 => _92(-1), 'optionalAccess', _93 => _93.message, 'access', _94 => _94.id]))), () => ( null)));
2294
2311
  }
2295
2312
  }, _class4);
2296
2313
 
@@ -2453,7 +2470,7 @@ var fromLanguageModelMessages = (lm, { mergeRoundtrips }) => {
2453
2470
  });
2454
2471
  if (mergeRoundtrips) {
2455
2472
  const previousMessage = messages[messages.length - 1];
2456
- if (_optionalChain([previousMessage, 'optionalAccess', _94 => _94.role]) === "assistant") {
2473
+ if (_optionalChain([previousMessage, 'optionalAccess', _95 => _95.role]) === "assistant") {
2457
2474
  previousMessage.content.push(...newContent);
2458
2475
  break;
2459
2476
  }
@@ -2466,7 +2483,7 @@ var fromLanguageModelMessages = (lm, { mergeRoundtrips }) => {
2466
2483
  }
2467
2484
  case "tool": {
2468
2485
  const previousMessage = messages[messages.length - 1];
2469
- if (_optionalChain([previousMessage, 'optionalAccess', _95 => _95.role]) !== "assistant")
2486
+ if (_optionalChain([previousMessage, 'optionalAccess', _96 => _96.role]) !== "assistant")
2470
2487
  throw new Error(
2471
2488
  "A tool message must be preceded by an assistant message."
2472
2489
  );
@@ -2670,7 +2687,7 @@ var useEdgeRuntime = ({
2670
2687
  };
2671
2688
 
2672
2689
  // src/runtimes/local/shouldContinue.tsx
2673
- var shouldContinue = (result) => _optionalChain([result, 'access', _96 => _96.status, 'optionalAccess', _97 => _97.type]) === "requires-action" && result.status.reason === "tool-calls" && result.content.every((c) => c.type !== "tool-call" || !!c.result);
2690
+ var shouldContinue = (result) => _optionalChain([result, 'access', _97 => _97.status, 'optionalAccess', _98 => _98.type]) === "requires-action" && result.status.reason === "tool-calls" && result.content.every((c) => c.type !== "tool-call" || !!c.result);
2674
2691
 
2675
2692
  // src/runtimes/local/LocalThreadRuntime.tsx
2676
2693
  var CAPABILITIES = Object.freeze({
@@ -2685,7 +2702,7 @@ var LocalThreadRuntime = (_class5 = class {
2685
2702
  this.configProvider = configProvider;
2686
2703
  this.adapter = adapter;
2687
2704
  this.options = options;
2688
- if (_optionalChain([options, 'optionalAccess', _98 => _98.initialMessages])) {
2705
+ if (_optionalChain([options, 'optionalAccess', _99 => _99.initialMessages])) {
2689
2706
  let parentId = null;
2690
2707
  const messages = fromCoreMessages(options.initialMessages);
2691
2708
  for (const message of messages) {
@@ -2702,9 +2719,6 @@ var LocalThreadRuntime = (_class5 = class {
2702
2719
  get messages() {
2703
2720
  return this.repository.getMessages();
2704
2721
  }
2705
- get isRunning() {
2706
- return this.abortController != null;
2707
- }
2708
2722
  getBranches(messageId) {
2709
2723
  return this.repository.getBranches(messageId);
2710
2724
  }
@@ -2743,7 +2757,7 @@ var LocalThreadRuntime = (_class5 = class {
2743
2757
  }
2744
2758
  async performRoundtrip(parentId, message) {
2745
2759
  const messages = this.repository.getMessages();
2746
- _optionalChain([this, 'access', _99 => _99.abortController, 'optionalAccess', _100 => _100.abort, 'call', _101 => _101()]);
2760
+ _optionalChain([this, 'access', _100 => _100.abortController, 'optionalAccess', _101 => _101.abort, 'call', _102 => _102()]);
2747
2761
  this.abortController = new AbortController();
2748
2762
  const initialContent = message.content;
2749
2763
  const initialRoundtrips = message.roundtrips;
@@ -2752,13 +2766,13 @@ var LocalThreadRuntime = (_class5 = class {
2752
2766
  ...message,
2753
2767
  ...m.content ? { content: [...initialContent, ..._nullishCoalesce(m.content, () => ( []))] } : void 0,
2754
2768
  status: _nullishCoalesce(m.status, () => ( message.status)),
2755
- ..._optionalChain([m, 'access', _102 => _102.roundtrips, 'optionalAccess', _103 => _103.length]) ? { roundtrips: [..._nullishCoalesce(initialRoundtrips, () => ( [])), ...m.roundtrips] } : void 0
2769
+ ..._optionalChain([m, 'access', _103 => _103.roundtrips, 'optionalAccess', _104 => _104.length]) ? { roundtrips: [..._nullishCoalesce(initialRoundtrips, () => ( [])), ...m.roundtrips] } : void 0
2756
2770
  };
2757
2771
  this.repository.addOrUpdateMessage(parentId, message);
2758
2772
  this.notifySubscribers();
2759
2773
  };
2760
- const maxToolRoundtrips = _nullishCoalesce(_optionalChain([this, 'access', _104 => _104.options, 'optionalAccess', _105 => _105.maxToolRoundtrips]), () => ( 1));
2761
- const toolRoundtrips = _nullishCoalesce(_optionalChain([message, 'access', _106 => _106.roundtrips, 'optionalAccess', _107 => _107.length]), () => ( 0));
2774
+ const maxToolRoundtrips = _nullishCoalesce(_optionalChain([this, 'access', _105 => _105.options, 'optionalAccess', _106 => _106.maxToolRoundtrips]), () => ( 1));
2775
+ const toolRoundtrips = _nullishCoalesce(_optionalChain([message, 'access', _107 => _107.roundtrips, 'optionalAccess', _108 => _108.length]), () => ( 0));
2762
2776
  if (toolRoundtrips > maxToolRoundtrips) {
2763
2777
  updateMessage({
2764
2778
  status: {
@@ -2793,8 +2807,6 @@ var LocalThreadRuntime = (_class5 = class {
2793
2807
  updateMessage({
2794
2808
  status: { type: "complete", reason: "unknown" }
2795
2809
  });
2796
- } else {
2797
- this.notifySubscribers();
2798
2810
  }
2799
2811
  } catch (e) {
2800
2812
  this.abortController = null;
@@ -2893,18 +2905,12 @@ var useLocalRuntime = (adapter, options) => {
2893
2905
  return runtime;
2894
2906
  };
2895
2907
 
2896
- // src/runtimes/external-store/ExternalStoreThreadRuntime.tsx
2897
-
2898
-
2899
2908
  // src/runtimes/external-store/getExternalStoreMessage.tsx
2900
2909
  var symbolInnerMessage = Symbol("innerMessage");
2901
2910
  var getExternalStoreMessage = (message) => {
2902
2911
  return message[symbolInnerMessage];
2903
2912
  };
2904
2913
 
2905
- // src/runtimes/external-store/useExternalStoreSync.tsx
2906
-
2907
-
2908
2914
  // src/runtimes/external-store/ThreadMessageConverter.ts
2909
2915
  var ThreadMessageConverter = (_class6 = class {constructor() { _class6.prototype.__init16.call(this); }
2910
2916
  __init16() {this.cache = /* @__PURE__ */ new WeakMap()}
@@ -2925,6 +2931,7 @@ var AUTO_STATUS_COMPLETE = Object.freeze({
2925
2931
  type: "complete",
2926
2932
  reason: "unknown"
2927
2933
  });
2934
+ var isAutoStatus = (status) => status === AUTO_STATUS_RUNNING || status === AUTO_STATUS_COMPLETE;
2928
2935
  var getAutoStatus = (isLast, isRunning) => isLast && isRunning ? AUTO_STATUS_RUNNING : AUTO_STATUS_COMPLETE;
2929
2936
 
2930
2937
  // src/runtimes/external-store/ThreadMessageLike.tsx
@@ -2995,106 +3002,112 @@ var fromThreadMessageLike = (like, fallbackId, fallbackStatus) => {
2995
3002
  }
2996
3003
  };
2997
3004
 
2998
- // src/runtimes/external-store/useExternalStoreSync.tsx
2999
- var useExternalStoreSync = (adapter, updateData) => {
3000
- const adapterRef = _react.useRef.call(void 0, adapter);
3001
- _react.useInsertionEffect.call(void 0, () => {
3002
- adapterRef.current = adapter;
3003
- });
3004
- const [converter, convertCallback] = _react.useMemo.call(void 0, () => {
3005
- const converter2 = _nullishCoalesce(adapter.convertMessage, () => ( ((m) => m)));
3006
- const convertCallback2 = (cache, m, idx) => {
3007
- const autoStatus = getAutoStatus(
3008
- adapterRef.current.messages.at(-1) === m,
3009
- _nullishCoalesce(adapterRef.current.isRunning, () => ( false))
3010
- );
3011
- if (cache && (cache.role !== "assistant" || cache.status === autoStatus))
3012
- return cache;
3013
- const newMessage = fromThreadMessageLike(
3014
- converter2(m, idx),
3015
- idx.toString(),
3016
- autoStatus
3017
- );
3018
- newMessage[symbolInnerMessage] = m;
3019
- return newMessage;
3020
- };
3021
- return [new ThreadMessageConverter(), convertCallback2];
3022
- }, [adapter.convertMessage]);
3023
- _react.useEffect.call(void 0, () => {
3024
- updateData(
3025
- _nullishCoalesce(adapter.isDisabled, () => ( false)),
3026
- _nullishCoalesce(adapter.isRunning, () => ( false)),
3027
- converter.convertMessages(adapter.messages, convertCallback)
3028
- );
3029
- }, [
3030
- updateData,
3031
- converter,
3032
- convertCallback,
3033
- adapter.isDisabled,
3034
- adapter.isRunning,
3035
- adapter.messages
3036
- ]);
3037
- };
3038
-
3039
3005
  // src/runtimes/external-store/ExternalStoreThreadRuntime.tsx
3040
3006
  var hasUpcomingMessage = (isRunning, messages) => {
3041
- return isRunning && _optionalChain([messages, 'access', _108 => _108[messages.length - 1], 'optionalAccess', _109 => _109.role]) !== "assistant";
3007
+ return isRunning && _optionalChain([messages, 'access', _109 => _109[messages.length - 1], 'optionalAccess', _110 => _110.role]) !== "assistant";
3042
3008
  };
3043
3009
  var ExternalStoreThreadRuntime = (_class7 = class {
3044
- constructor(store) {;_class7.prototype.__init17.call(this);_class7.prototype.__init18.call(this);_class7.prototype.__init19.call(this);_class7.prototype.__init20.call(this);_class7.prototype.__init21.call(this);_class7.prototype.__init22.call(this);_class7.prototype.__init23.call(this);_class7.prototype.__init24.call(this);_class7.prototype.__init25.call(this);
3045
- this.store = store;
3046
- this.updateData(
3047
- _nullishCoalesce(store.isDisabled, () => ( false)),
3048
- _nullishCoalesce(store.isRunning, () => ( false)),
3049
- store.messages
3050
- );
3051
- this.useStore = _zustand.create.call(void 0, () => ({
3052
- store
3053
- }));
3054
- }
3055
3010
  __init17() {this._subscriptions = /* @__PURE__ */ new Set()}
3056
3011
  __init18() {this.repository = new MessageRepository()}
3057
3012
  __init19() {this.assistantOptimisticId = null}
3058
-
3059
3013
  get capabilities() {
3060
3014
  return {
3061
- switchToBranch: this.store.setMessages !== void 0,
3062
- edit: this.store.onEdit !== void 0,
3063
- reload: this.store.onReload !== void 0,
3064
- cancel: this.store.onCancel !== void 0,
3065
- copy: this.store.onCopy !== null
3015
+ switchToBranch: this._store.setMessages !== void 0,
3016
+ edit: this._store.onEdit !== void 0,
3017
+ reload: this._store.onReload !== void 0,
3018
+ cancel: this._store.onCancel !== void 0,
3019
+ copy: this._store.onCopy !== null
3066
3020
  };
3067
3021
  }
3068
3022
  __init20() {this.messages = []}
3069
3023
  __init21() {this.isDisabled = false}
3070
- __init22() {this.isRunning = false}
3024
+ __init22() {this.converter = new ThreadMessageConverter()}
3025
+
3026
+ constructor(store) {;_class7.prototype.__init17.call(this);_class7.prototype.__init18.call(this);_class7.prototype.__init19.call(this);_class7.prototype.__init20.call(this);_class7.prototype.__init21.call(this);_class7.prototype.__init22.call(this);_class7.prototype.__init23.call(this);
3027
+ this.store = store;
3028
+ }
3029
+ set store(store) {
3030
+ const oldStore = this._store;
3031
+ if (oldStore) {
3032
+ if (oldStore.convertMessage !== store.convertMessage) {
3033
+ this.converter = new ThreadMessageConverter();
3034
+ } else if (oldStore.isDisabled === store.isDisabled && oldStore.isRunning === store.isRunning && oldStore.messages === store.messages) {
3035
+ return;
3036
+ }
3037
+ }
3038
+ this._store = store;
3039
+ const isRunning = _nullishCoalesce(store.isRunning, () => ( false));
3040
+ const isDisabled = _nullishCoalesce(store.isDisabled, () => ( false));
3041
+ const convertCallback = (cache, m, idx) => {
3042
+ if (!store.convertMessage) return m;
3043
+ const isLast = idx === store.messages.length - 1;
3044
+ const autoStatus = getAutoStatus(isLast, isRunning);
3045
+ if (cache && (cache.role !== "assistant" || !isAutoStatus(cache.status) || cache.status === autoStatus))
3046
+ return cache;
3047
+ const newMessage = fromThreadMessageLike(
3048
+ store.convertMessage(m, idx),
3049
+ idx.toString(),
3050
+ autoStatus
3051
+ );
3052
+ newMessage[symbolInnerMessage] = m;
3053
+ return newMessage;
3054
+ };
3055
+ const messages = this.converter.convertMessages(
3056
+ store.messages,
3057
+ convertCallback
3058
+ );
3059
+ for (let i = 0; i < messages.length; i++) {
3060
+ const message = messages[i];
3061
+ const parent = messages[i - 1];
3062
+ this.repository.addOrUpdateMessage(_nullishCoalesce(_optionalChain([parent, 'optionalAccess', _114 => _114.id]), () => ( null)), message);
3063
+ }
3064
+ if (this.assistantOptimisticId) {
3065
+ this.repository.deleteMessage(this.assistantOptimisticId);
3066
+ this.assistantOptimisticId = null;
3067
+ }
3068
+ if (hasUpcomingMessage(isRunning, messages)) {
3069
+ this.assistantOptimisticId = this.repository.appendOptimisticMessage(
3070
+ _nullishCoalesce(_optionalChain([messages, 'access', _115 => _115.at, 'call', _116 => _116(-1), 'optionalAccess', _117 => _117.id]), () => ( null)),
3071
+ {
3072
+ role: "assistant",
3073
+ content: []
3074
+ }
3075
+ );
3076
+ }
3077
+ this.repository.resetHead(
3078
+ _nullishCoalesce(_nullishCoalesce(this.assistantOptimisticId, () => ( _optionalChain([messages, 'access', _118 => _118.at, 'call', _119 => _119(-1), 'optionalAccess', _120 => _120.id]))), () => ( null))
3079
+ );
3080
+ this.messages = this.repository.getMessages();
3081
+ this.isDisabled = isDisabled;
3082
+ for (const callback of this._subscriptions) callback();
3083
+ }
3071
3084
  getBranches(messageId) {
3072
3085
  return this.repository.getBranches(messageId);
3073
3086
  }
3074
3087
  switchToBranch(branchId) {
3075
- if (!this.store.setMessages)
3088
+ if (!this._store.setMessages)
3076
3089
  throw new Error("Runtime does not support switching branches.");
3077
3090
  this.repository.switchToBranch(branchId);
3078
3091
  this.updateMessages(this.repository.getMessages());
3079
3092
  }
3080
3093
  async append(message) {
3081
- if (message.parentId !== (_nullishCoalesce(_optionalChain([this, 'access', _120 => _120.messages, 'access', _121 => _121.at, 'call', _122 => _122(-1), 'optionalAccess', _123 => _123.id]), () => ( null)))) {
3082
- if (!this.store.onEdit)
3094
+ if (message.parentId !== (_nullishCoalesce(_optionalChain([this, 'access', _121 => _121.messages, 'access', _122 => _122.at, 'call', _123 => _123(-1), 'optionalAccess', _124 => _124.id]), () => ( null)))) {
3095
+ if (!this._store.onEdit)
3083
3096
  throw new Error("Runtime does not support editing messages.");
3084
- await this.store.onEdit(message);
3097
+ await this._store.onEdit(message);
3085
3098
  } else {
3086
- await this.store.onNew(message);
3099
+ await this._store.onNew(message);
3087
3100
  }
3088
3101
  }
3089
3102
  async startRun(parentId) {
3090
- if (!this.store.onReload)
3103
+ if (!this._store.onReload)
3091
3104
  throw new Error("Runtime does not support reloading messages.");
3092
- await this.store.onReload(parentId);
3105
+ await this._store.onReload(parentId);
3093
3106
  }
3094
3107
  cancelRun() {
3095
- if (!this.store.onCancel)
3108
+ if (!this._store.onCancel)
3096
3109
  throw new Error("Runtime does not support cancelling runs.");
3097
- this.store.onCancel();
3110
+ this._store.onCancel();
3098
3111
  if (this.assistantOptimisticId) {
3099
3112
  this.repository.deleteMessage(this.assistantOptimisticId);
3100
3113
  this.assistantOptimisticId = null;
@@ -3109,66 +3122,26 @@ var ExternalStoreThreadRuntime = (_class7 = class {
3109
3122
  return () => this._subscriptions.delete(callback);
3110
3123
  }
3111
3124
  __init23() {this.updateMessages = (messages) => {
3112
- _optionalChain([this, 'access', _124 => _124.store, 'access', _125 => _125.setMessages, 'optionalCall', _126 => _126(
3125
+ _optionalChain([this, 'access', _125 => _125._store, 'access', _126 => _126.setMessages, 'optionalCall', _127 => _127(
3113
3126
  messages.flatMap(getExternalStoreMessage).filter((m) => m != null)
3114
3127
  )]);
3115
3128
  }}
3116
- onStoreUpdated() {
3117
- if (this.useStore.getState().store !== this.store) {
3118
- this.useStore.setState({ store: this.store });
3119
- }
3120
- }
3121
- __init24() {this.updateData = (isDisabled, isRunning, vm) => {
3122
- for (let i = 0; i < vm.length; i++) {
3123
- const message = vm[i];
3124
- const parent = vm[i - 1];
3125
- this.repository.addOrUpdateMessage(_nullishCoalesce(_optionalChain([parent, 'optionalAccess', _127 => _127.id]), () => ( null)), message);
3126
- }
3127
- if (this.assistantOptimisticId) {
3128
- this.repository.deleteMessage(this.assistantOptimisticId);
3129
- this.assistantOptimisticId = null;
3130
- }
3131
- if (hasUpcomingMessage(isRunning, vm)) {
3132
- this.assistantOptimisticId = this.repository.appendOptimisticMessage(
3133
- _nullishCoalesce(_optionalChain([vm, 'access', _128 => _128.at, 'call', _129 => _129(-1), 'optionalAccess', _130 => _130.id]), () => ( null)),
3134
- {
3135
- role: "assistant",
3136
- content: []
3137
- }
3138
- );
3139
- }
3140
- this.repository.resetHead(
3141
- _nullishCoalesce(_nullishCoalesce(this.assistantOptimisticId, () => ( _optionalChain([vm, 'access', _131 => _131.at, 'call', _132 => _132(-1), 'optionalAccess', _133 => _133.id]))), () => ( null))
3142
- );
3143
- this.messages = this.repository.getMessages();
3144
- this.isDisabled = isDisabled;
3145
- this.isRunning = isRunning;
3146
- for (const callback of this._subscriptions) callback();
3147
- }}
3148
- __init25() {this.unstable_synchronizer = () => {
3149
- const { store } = this.useStore();
3150
- useExternalStoreSync(store, this.updateData);
3151
- return null;
3152
- }}
3153
3129
  addToolResult(options) {
3154
- if (!this.store.onAddToolResult)
3130
+ if (!this._store.onAddToolResult)
3155
3131
  throw new Error("Runtime does not support tool results.");
3156
- this.store.onAddToolResult(options);
3132
+ this._store.onAddToolResult(options);
3157
3133
  }
3158
3134
  }, _class7);
3159
3135
 
3160
3136
  // src/runtimes/external-store/ExternalStoreRuntime.tsx
3161
3137
  var ExternalStoreRuntime = (_class8 = class extends BaseAssistantRuntime {
3162
- __init26() {this._proxyConfigProvider = new ProxyConfigProvider()}
3138
+ __init24() {this._proxyConfigProvider = new ProxyConfigProvider()}
3163
3139
  constructor(store) {
3164
- super(new ExternalStoreThreadRuntime(store));_class8.prototype.__init26.call(this);;
3140
+ super(new ExternalStoreThreadRuntime(store));_class8.prototype.__init24.call(this);;
3165
3141
  }
3166
3142
  set store(store) {
3167
3143
  this.thread.store = store;
3168
3144
  }
3169
- onStoreUpdated() {
3170
- return this.thread.onStoreUpdated();
3171
- }
3172
3145
  getModelConfig() {
3173
3146
  return this._proxyConfigProvider.getModelConfig();
3174
3147
  }
@@ -3195,9 +3168,6 @@ var useExternalStoreRuntime = (store) => {
3195
3168
  _react.useInsertionEffect.call(void 0, () => {
3196
3169
  runtime.store = store;
3197
3170
  });
3198
- _react.useEffect.call(void 0, () => {
3199
- runtime.onStoreUpdated();
3200
- });
3201
3171
  return runtime;
3202
3172
  };
3203
3173
 
@@ -3217,7 +3187,7 @@ var ThreadConfigProvider = ({
3217
3187
  }) => {
3218
3188
  const assistant = useAssistantContext({ optional: true });
3219
3189
  const configProvider = config && Object.keys(_nullishCoalesce(config, () => ( {}))).length > 0 ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ThreadConfigContext.Provider, { value: config, children }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _jsxruntime.Fragment, { children });
3220
- if (!_optionalChain([config, 'optionalAccess', _134 => _134.runtime])) return configProvider;
3190
+ if (!_optionalChain([config, 'optionalAccess', _128 => _128.runtime])) return configProvider;
3221
3191
  if (assistant) {
3222
3192
  throw new Error(
3223
3193
  "You provided a runtime to <Thread> while simulataneously using <AssistantRuntimeProvider>. This is not allowed."
@@ -3433,7 +3403,7 @@ var AssistantMessageContent = _react.forwardRef.call(void 0, ({ components: comp
3433
3403
  {
3434
3404
  components: {
3435
3405
  ...componentsProp,
3436
- Text: _nullishCoalesce(_nullishCoalesce(_optionalChain([componentsProp, 'optionalAccess', _135 => _135.Text]), () => ( components.Text)), () => ( content_part_default.Text))
3406
+ Text: _nullishCoalesce(_nullishCoalesce(_optionalChain([componentsProp, 'optionalAccess', _129 => _129.Text]), () => ( components.Text)), () => ( content_part_default.Text))
3437
3407
  }
3438
3408
  }
3439
3409
  ) });
@@ -3608,7 +3578,7 @@ var ThreadWelcomeSuggestion = ({
3608
3578
  };
3609
3579
  var ThreadWelcomeSuggestions = () => {
3610
3580
  const { welcome: { suggestions } = {} } = useThreadConfig();
3611
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ThreadWelcomeSuggestionContainer, { children: _optionalChain([suggestions, 'optionalAccess', _136 => _136.map, 'call', _137 => _137((suggestion, idx) => {
3581
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ThreadWelcomeSuggestionContainer, { children: _optionalChain([suggestions, 'optionalAccess', _130 => _130.map, 'call', _131 => _131((suggestion, idx) => {
3612
3582
  const key = `${suggestion.prompt}-${idx}`;
3613
3583
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ThreadWelcomeSuggestion, { suggestion }, key);
3614
3584
  })]) });
@@ -3686,7 +3656,7 @@ var UserMessageContent = _react.forwardRef.call(void 0,
3686
3656
  {
3687
3657
  components: {
3688
3658
  ...components,
3689
- Text: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _138 => _138.Text]), () => ( content_part_default.Text))
3659
+ Text: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _132 => _132.Text]), () => ( content_part_default.Text))
3690
3660
  }
3691
3661
  }
3692
3662
  ) });
@@ -3788,10 +3758,10 @@ var ThreadMessages = ({ components, ...rest }) => {
3788
3758
  thread_exports.Messages,
3789
3759
  {
3790
3760
  components: {
3791
- UserMessage: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _139 => _139.UserMessage]), () => ( user_message_default)),
3792
- EditComposer: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _140 => _140.EditComposer]), () => ( edit_composer_default)),
3793
- AssistantMessage: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _141 => _141.AssistantMessage]), () => ( assistant_message_default)),
3794
- SystemMessage: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _142 => _142.SystemMessage]), () => ( SystemMessage))
3761
+ UserMessage: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _133 => _133.UserMessage]), () => ( user_message_default)),
3762
+ EditComposer: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _134 => _134.EditComposer]), () => ( edit_composer_default)),
3763
+ AssistantMessage: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _135 => _135.AssistantMessage]), () => ( assistant_message_default)),
3764
+ SystemMessage: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _136 => _136.SystemMessage]), () => ( SystemMessage))
3795
3765
  },
3796
3766
  ...rest
3797
3767
  }