@assistant-ui/react 0.5.65 → 0.5.67

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3; var _class4; var _class5; var _class6; var _class7; var _class8; var _class9; var _class10; var _class11; var _class12; var _class13;
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _class; var _class2; var _class3; var _class4; var _class5; var _class6; var _class7; var _class8; var _class9; var _class10; var _class11; var _class12; var _class13; var _class14; var _class15; var _class16; var _class17;
2
2
 
3
3
 
4
4
 
@@ -17,9 +17,6 @@ var _chunkPZ5AY32Cjs = require('./chunk-PZ5AY32C.js');
17
17
  // src/context/providers/AssistantRuntimeProvider.tsx
18
18
  var _react = require('react');
19
19
 
20
- // src/context/providers/AssistantProvider.tsx
21
-
22
-
23
20
  // src/context/react/AssistantContext.ts
24
21
 
25
22
 
@@ -121,7 +118,7 @@ var makeAssistantToolUIsStore = () => _zustand.create.call(void 0, (set) => {
121
118
  });
122
119
  });
123
120
 
124
- // src/context/providers/ThreadProvider.tsx
121
+ // src/context/providers/ThreadRuntimeProvider.tsx
125
122
 
126
123
 
127
124
  // src/context/react/ThreadContext.ts
@@ -147,7 +144,9 @@ var { useThread, useThreadStore } = createContextStoreHook(
147
144
  useThreadContext,
148
145
  "useThread"
149
146
  );
150
- var { useThreadMessages, useThreadMessagesStore } = createContextStoreHook(useThreadContext, "useThreadMessages");
147
+ var messages = createContextStoreHook(useThreadContext, "useThreadMessages");
148
+ var useThreadMessages = messages.useThreadMessages;
149
+ var useThreadMessagesStore = messages.useThreadMessagesStore;
151
150
  var {
152
151
  useComposer: useThreadComposer,
153
152
  useComposerStore: useThreadComposerStore
@@ -157,76 +156,6 @@ var {
157
156
  useViewportStore: useThreadViewportStore
158
157
  } = createContextStoreHook(useThreadContext, "useViewport");
159
158
 
160
- // src/context/stores/ThreadComposer.ts
161
-
162
- var makeThreadComposerStore = (useThreadRuntime2) => {
163
- const focusListeners = /* @__PURE__ */ new Set();
164
- return _zustand.create.call(void 0, )((_, get) => {
165
- const runtime = useThreadRuntime2.getState();
166
- return {
167
- type: "thread",
168
- get value() {
169
- return get().text;
170
- },
171
- setValue(value) {
172
- get().setText(value);
173
- },
174
- attachmentAccept: runtime.composer.attachmentAccept,
175
- attachments: runtime.composer.attachments,
176
- addAttachment: (file) => {
177
- useThreadRuntime2.getState().composer.addAttachment(file);
178
- },
179
- removeAttachment: (attachmentId) => {
180
- useThreadRuntime2.getState().composer.removeAttachment(attachmentId);
181
- },
182
- reset: () => {
183
- useThreadRuntime2.getState().composer.reset();
184
- },
185
- text: runtime.composer.text,
186
- setText: (text) => {
187
- useThreadRuntime2.getState().composer.setText(text);
188
- },
189
- canCancel: runtime.capabilities.cancel,
190
- isEditing: true,
191
- isEmpty: runtime.composer.isEmpty,
192
- send: () => {
193
- const runtime2 = useThreadRuntime2.getState();
194
- runtime2.composer.send();
195
- },
196
- cancel: () => {
197
- useThreadRuntime2.getState().cancelRun();
198
- },
199
- focus: () => {
200
- for (const listener of focusListeners) {
201
- listener();
202
- }
203
- },
204
- onFocus: (listener) => {
205
- focusListeners.add(listener);
206
- return () => {
207
- focusListeners.delete(listener);
208
- };
209
- }
210
- };
211
- });
212
- };
213
-
214
- // src/context/stores/Thread.ts
215
-
216
- var getThreadStateFromRuntime = (runtime) => {
217
- const lastMessage = runtime.messages.at(-1);
218
- return Object.freeze({
219
- threadId: runtime.threadId,
220
- capabilities: runtime.capabilities,
221
- isDisabled: runtime.isDisabled,
222
- isRunning: _optionalChain([lastMessage, 'optionalAccess', _5 => _5.role]) !== "assistant" ? false : lastMessage.status.type === "running"
223
- });
224
- };
225
- var makeThreadStore = (runtimeRef) => {
226
- const runtime = runtimeRef.getState();
227
- return _zustand.create.call(void 0, () => getThreadStateFromRuntime(runtime));
228
- };
229
-
230
159
  // src/context/stores/ThreadViewport.tsx
231
160
 
232
161
  var makeThreadViewportStore = () => {
@@ -247,85 +176,65 @@ var makeThreadViewportStore = () => {
247
176
  }));
248
177
  };
249
178
 
250
- // src/context/stores/ThreadMessages.ts
251
-
252
- var makeThreadMessagesStore = (runtimeRef) => {
253
- return _zustand.create.call(void 0, () => runtimeRef.getState().messages);
254
- };
255
-
256
179
  // src/context/ReadonlyStore.ts
257
180
  var writableStore = (store) => {
258
181
  return store;
259
182
  };
260
183
 
261
- // src/context/providers/ThreadProvider.tsx
184
+ // src/context/providers/ThreadRuntimeProvider.tsx
262
185
 
263
186
  var _jsxruntime = require('react/jsx-runtime');
264
- var ThreadProvider = ({
265
- children,
266
- provider: thread
267
- }) => {
268
- const [context] = _react.useState.call(void 0, () => {
269
- const useThreadRuntime2 = _zustand.create.call(void 0, () => thread);
270
- const useThread2 = makeThreadStore(useThreadRuntime2);
271
- const useThreadMessages2 = makeThreadMessagesStore(useThreadRuntime2);
187
+ var useThreadRuntimeStore2 = (runtime) => {
188
+ const [store] = _react.useState.call(void 0, () => _zustand.create.call(void 0, () => runtime));
189
+ _react.useEffect.call(void 0, () => {
190
+ writableStore(store).setState(runtime, true);
191
+ }, [runtime, store]);
192
+ return store;
193
+ };
194
+ var useThreadStore2 = (runtime) => {
195
+ const [store] = _react.useState.call(void 0, () => _zustand.create.call(void 0, () => runtime.getState()));
196
+ _react.useEffect.call(void 0, () => {
197
+ const updateState = () => writableStore(store).setState(runtime.getState(), true);
198
+ updateState();
199
+ return runtime.subscribe(updateState);
200
+ }, [runtime, store]);
201
+ return store;
202
+ };
203
+ var useThreadMessagesStore2 = (runtime) => {
204
+ const [store] = _react.useState.call(void 0, () => _zustand.create.call(void 0, () => runtime.messages));
205
+ _react.useEffect.call(void 0, () => {
206
+ const updateState = () => writableStore(store).setState(runtime.messages, true);
207
+ updateState();
208
+ return runtime.subscribe(updateState);
209
+ }, [runtime, store]);
210
+ return store;
211
+ };
212
+ var useThreadComposerStore2 = (runtime) => {
213
+ const [store] = _react.useState.call(void 0, () => _zustand.create.call(void 0, () => runtime.getState()));
214
+ _react.useEffect.call(void 0, () => {
215
+ const updateState = () => writableStore(store).setState(runtime.getState(), true);
216
+ updateState();
217
+ return runtime.subscribe(updateState);
218
+ }, [runtime, store]);
219
+ return store;
220
+ };
221
+ var ThreadRuntimeProvider = ({ children, runtime }) => {
222
+ const useThreadRuntime2 = useThreadRuntimeStore2(runtime);
223
+ const useThread2 = useThreadStore2(runtime);
224
+ const useThreadMessages2 = useThreadMessagesStore2(runtime);
225
+ const useThreadComposer2 = useThreadComposerStore2(runtime.composer);
226
+ const context = _react.useMemo.call(void 0, () => {
272
227
  const useViewport = makeThreadViewportStore();
273
- const useComposer2 = makeThreadComposerStore(useThreadRuntime2);
274
228
  return {
275
229
  useThread: useThread2,
276
230
  useThreadRuntime: useThreadRuntime2,
277
231
  useThreadMessages: useThreadMessages2,
278
232
  useThreadActions: useThreadRuntime2,
279
- useComposer: useComposer2,
233
+ useComposer: useThreadComposer2,
280
234
  useViewport
281
235
  };
282
- });
283
- _react.useEffect.call(void 0, () => {
284
- const onThreadUpdate = () => {
285
- const oldState = context.useThread.getState();
286
- const state = getThreadStateFromRuntime(thread);
287
- if (oldState.threadId !== state.threadId || oldState.isDisabled !== state.isDisabled || oldState.isRunning !== state.isRunning || oldState.capabilities !== state.capabilities) {
288
- writableStore(context.useThread).setState(state, true);
289
- }
290
- if (thread.messages !== context.useThreadMessages.getState()) {
291
- writableStore(context.useThreadMessages).setState(
292
- thread.messages,
293
- true
294
- );
295
- }
296
- const composerState = context.useComposer.getState();
297
- if (state.capabilities.cancel !== composerState.canCancel) {
298
- writableStore(context.useComposer).setState({
299
- canCancel: state.capabilities.cancel
300
- });
301
- }
302
- };
303
- onThreadUpdate();
304
- return thread.subscribe(onThreadUpdate);
305
- }, [thread, context]);
306
- _react.useEffect.call(void 0, () => {
307
- const onComposerUpdate = () => {
308
- const composer = thread.composer;
309
- const composerState = context.useComposer.getState();
310
- if (composer.isEmpty !== composerState.isEmpty || composer.text !== composerState.text || composer.attachmentAccept !== composerState.attachmentAccept || composer.attachments !== composerState.attachments) {
311
- writableStore(context.useComposer).setState({
312
- isEmpty: composer.isEmpty,
313
- text: composer.text,
314
- attachmentAccept: composer.attachmentAccept,
315
- attachments: composer.attachments
316
- });
317
- }
318
- };
319
- onComposerUpdate();
320
- return thread.composer.subscribe(onComposerUpdate);
321
- }, [thread, context]);
322
- _react.useEffect.call(void 0,
323
- () => thread.subscribe(() => {
324
- writableStore(context.useThreadRuntime).setState(thread, true);
325
- }),
326
- [thread, context]
327
- );
328
- const Synchronizer = context.useThreadRuntime(
236
+ }, [useThread2, useThreadRuntime2, useThreadMessages2, useThreadComposer2]);
237
+ const Synchronizer = context.useThread(
329
238
  (t) => t.unstable_synchronizer
330
239
  );
331
240
  return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, ThreadContext.Provider, { value: context, children: [
@@ -334,34 +243,30 @@ var ThreadProvider = ({
334
243
  ] });
335
244
  };
336
245
 
337
- // src/context/providers/AssistantProvider.tsx
246
+ // src/context/providers/AssistantRuntimeProvider.tsx
338
247
 
339
248
 
340
- var AssistantProvider = ({ children, runtime }) => {
341
- const runtimeRef = _react.useRef.call(void 0, runtime);
342
- _react.useInsertionEffect.call(void 0, () => {
343
- runtimeRef.current = runtime;
344
- });
345
- const [context] = _react.useState.call(void 0, () => {
346
- const useAssistantRuntime2 = _zustand.create.call(void 0, () => runtime);
347
- const useToolUIs2 = makeAssistantToolUIsStore();
249
+ var useAssistantRuntimeStore2 = (runtime) => {
250
+ const [store] = _react.useState.call(void 0, () => _zustand.create.call(void 0, () => runtime));
251
+ _react.useEffect.call(void 0, () => {
252
+ writableStore(store).setState(runtime, true);
253
+ }, [runtime, store]);
254
+ return store;
255
+ };
256
+ var useAssistantToolUIsStore = () => {
257
+ return _react.useMemo.call(void 0, () => makeAssistantToolUIsStore(), []);
258
+ };
259
+ var AssistantRuntimeProviderImpl = ({ children, runtime }) => {
260
+ const useAssistantRuntime2 = useAssistantRuntimeStore2(runtime);
261
+ const useToolUIs2 = useAssistantToolUIsStore();
262
+ const context = _react.useMemo.call(void 0, () => {
348
263
  return {
349
264
  useToolUIs: useToolUIs2,
350
265
  useAssistantRuntime: useAssistantRuntime2,
351
266
  useAssistantActions: useAssistantRuntime2
352
267
  };
353
- });
354
- _react.useEffect.call(void 0,
355
- () => writableStore(context.useAssistantRuntime).setState(runtime, true),
356
- [runtime, context]
357
- );
358
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AssistantContext.Provider, { value: context, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ThreadProvider, { provider: runtime.thread, children }) });
359
- };
360
-
361
- // src/context/providers/AssistantRuntimeProvider.tsx
362
-
363
- var AssistantRuntimeProviderImpl = ({ children, runtime }) => {
364
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AssistantProvider, { runtime, children });
268
+ }, [useAssistantRuntime2, useToolUIs2]);
269
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, AssistantContext.Provider, { value: context, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ThreadRuntimeProvider, { runtime: runtime.thread, children }) });
365
270
  };
366
271
  var AssistantRuntimeProvider = _react.memo.call(void 0, AssistantRuntimeProviderImpl);
367
272
 
@@ -378,11 +283,47 @@ var useContentPartContext = createContextHook(
378
283
  ContentPartContext,
379
284
  "a component passed to <MessagePrimitive.Content components={...}>"
380
285
  );
286
+ function useContentPartRuntime(options) {
287
+ const context = useContentPartContext(options);
288
+ if (!context) return null;
289
+ return context.useContentPartRuntime();
290
+ }
381
291
  var { useContentPart, useContentPartStore } = createContextStoreHook(
382
292
  useContentPartContext,
383
293
  "useContentPart"
384
294
  );
385
295
 
296
+ // src/api/ContentPartRuntime.ts
297
+ var ContentPartRuntime = class {
298
+ constructor(contentBinding, messageApi, threadApi) {
299
+ this.contentBinding = contentBinding;
300
+ this.messageApi = messageApi;
301
+ this.threadApi = threadApi;
302
+ }
303
+ getState() {
304
+ return this.contentBinding.getState();
305
+ }
306
+ addToolResult(result) {
307
+ const message = this.messageApi.getState();
308
+ if (!message) throw new Error("Message is not available");
309
+ const state = this.contentBinding.getState();
310
+ if (!state) throw new Error("Content part is not available");
311
+ if (state.type !== "tool-call")
312
+ throw new Error("Tried to add tool result to non-tool content part");
313
+ const toolName = state.toolName;
314
+ const toolCallId = state.toolCallId;
315
+ this.threadApi.getState().addToolResult({
316
+ messageId: message.id,
317
+ toolName,
318
+ toolCallId,
319
+ result
320
+ });
321
+ }
322
+ subscribe(callback) {
323
+ return this.contentBinding.subscribe(callback);
324
+ }
325
+ };
326
+
386
327
  // src/context/providers/TextContentPartProvider.tsx
387
328
 
388
329
  var COMPLETE_STATUS = {
@@ -393,18 +334,22 @@ var RUNNING_STATUS = {
393
334
  };
394
335
  var TextContentPartProvider = ({ children, text, isRunning }) => {
395
336
  const [context] = _react.useState.call(void 0, () => {
337
+ const useContentPartRuntime2 = _zustand.create.call(void 0,
338
+ // TODO
339
+ () => new ContentPartRuntime(null, null, null)
340
+ );
396
341
  const useContentPart2 = _zustand.create.call(void 0, () => ({
397
342
  status: isRunning ? RUNNING_STATUS : COMPLETE_STATUS,
398
- part: { type: "text", text }
343
+ part: { type: "text", text },
344
+ type: "text",
345
+ text
399
346
  }));
400
- return {
401
- useContentPart: useContentPart2
402
- };
347
+ return { useContentPartRuntime: useContentPartRuntime2, useContentPart: useContentPart2 };
403
348
  });
404
349
  _react.useEffect.call(void 0, () => {
405
350
  const state = context.useContentPart.getState();
406
- const textUpdated = state.part.text !== text;
407
- const targetTextPart = textUpdated ? { type: "text", text } : state.part;
351
+ const textUpdated = state.text !== text;
352
+ const targetTextPart = textUpdated ? { type: "text", text } : state;
408
353
  const targetStatus = isRunning ? RUNNING_STATUS : COMPLETE_STATUS;
409
354
  const statusUpdated = state.status !== targetStatus;
410
355
  if (!textUpdated && !statusUpdated) return;
@@ -426,6 +371,11 @@ var useMessageContext = createContextHook(
426
371
  MessageContext,
427
372
  "a component passed to <ThreadPrimitive.Messages components={...} />"
428
373
  );
374
+ function useMessageRuntime(options) {
375
+ const context = useMessageContext(options);
376
+ if (!context) return null;
377
+ return context.useMessageRuntime();
378
+ }
429
379
  var { useMessage, useMessageStore } = createContextStoreHook(
430
380
  useMessageContext,
431
381
  "useMessage"
@@ -442,57 +392,39 @@ var { useEditComposer, useEditComposerStore } = createContextStoreHook(
442
392
  // src/context/react/ComposerContext.ts
443
393
 
444
394
  var useComposerContext = () => {
445
- const { useComposer: useComposer2 } = useThreadContext();
395
+ const { useComposer: useThreadComposer2 } = useThreadContext();
446
396
  const { useEditComposer: useEditComposer2 } = _nullishCoalesce(useMessageContext({ optional: true }), () => ( {}));
447
397
  return _react.useMemo.call(void 0,
448
398
  () => ({
449
- useComposer: _nullishCoalesce(useEditComposer2, () => ( useComposer2)),
399
+ useComposer: _nullishCoalesce(useEditComposer2, () => ( useThreadComposer2)),
450
400
  type: useEditComposer2 ? "edit" : "new"
451
401
  }),
452
- [useEditComposer2, useComposer2]
402
+ [useEditComposer2, useThreadComposer2]
453
403
  );
454
404
  };
455
405
  var { useComposer, useComposerStore } = createContextStoreHook(
456
406
  useComposerContext,
457
407
  "useComposer"
458
408
  );
409
+ function useComposerRuntime(options) {
410
+ const messageRuntime = useMessageRuntime({ optional: true });
411
+ const threadRuntime = useThreadRuntime(options);
412
+ return messageRuntime ? messageRuntime.composer : _nullishCoalesce(_optionalChain([threadRuntime, 'optionalAccess', _5 => _5.composer]), () => ( null));
413
+ }
459
414
 
460
415
  // src/hooks/useAppendMessage.tsx
461
416
 
462
- var toAppendMessage = (useThreadMessages2, message) => {
463
- if (typeof message === "string") {
464
- return {
465
- parentId: _nullishCoalesce(_optionalChain([useThreadMessages2, 'access', _6 => _6.getState, 'call', _7 => _7(), 'access', _8 => _8.at, 'call', _9 => _9(-1), 'optionalAccess', _10 => _10.id]), () => ( null)),
466
- role: "user",
467
- content: [{ type: "text", text: message }],
468
- attachments: []
469
- };
470
- }
471
- return {
472
- parentId: _nullishCoalesce(_nullishCoalesce(message.parentId, () => ( _optionalChain([useThreadMessages2, 'access', _11 => _11.getState, 'call', _12 => _12(), 'access', _13 => _13.at, 'call', _14 => _14(-1), 'optionalAccess', _15 => _15.id]))), () => ( null)),
473
- role: _nullishCoalesce(message.role, () => ( "user")),
474
- content: message.content,
475
- attachments: _nullishCoalesce(message.attachments, () => ( []))
476
- };
477
- };
478
417
  var useAppendMessage = () => {
479
- const threadMessagesStore = useThreadMessagesStore();
480
418
  const threadRuntime = useThreadRuntime();
481
419
  const threadViewportStore = useThreadViewportStore();
482
420
  const threadComposerStore = useThreadComposerStore();
483
421
  const append = _react.useCallback.call(void 0,
484
422
  (message) => {
485
- const appendMessage = toAppendMessage(threadMessagesStore, message);
486
- threadRuntime.append(appendMessage);
423
+ threadRuntime.append(message);
487
424
  threadViewportStore.getState().scrollToBottom();
488
425
  threadComposerStore.getState().focus();
489
426
  },
490
- [
491
- threadMessagesStore,
492
- threadRuntime,
493
- threadViewportStore,
494
- threadComposerStore
495
- ]
427
+ [threadRuntime, threadViewportStore, threadComposerStore]
496
428
  );
497
429
  return append;
498
430
  };
@@ -527,7 +459,7 @@ var useAssistantTool = (tool) => {
527
459
  const unsub2 = render ? toolUIsStore.getState().setToolUI(toolName, render) : void 0;
528
460
  return () => {
529
461
  unsub1();
530
- _optionalChain([unsub2, 'optionalCall', _16 => _16()]);
462
+ _optionalChain([unsub2, 'optionalCall', _6 => _6()]);
531
463
  };
532
464
  }, [assistantRuntime, toolUIsStore, tool]);
533
465
  };
@@ -623,12 +555,12 @@ var useActionBarCopy = ({
623
555
  const editComposerStore = useEditComposerStore();
624
556
  const hasCopyableContent = useCombinedStore(
625
557
  [messageStore, editComposerStore],
626
- ({ message }, c) => {
558
+ (message, c) => {
627
559
  return !c.isEditing && (message.role !== "assistant" || message.status.type !== "running") && message.content.some((c2) => c2.type === "text" && c2.text.length > 0);
628
560
  }
629
561
  );
630
562
  const callback = _react.useCallback.call(void 0, () => {
631
- const { message } = messageStore.getState();
563
+ const message = messageStore.getState();
632
564
  const { setIsCopied } = messageUtilsStore.getState();
633
565
  const { isEditing, text: composerValue } = editComposerStore.getState();
634
566
  const valueToCopy = isEditing ? composerValue : getThreadMessageText(message);
@@ -644,12 +576,11 @@ var useActionBarCopy = ({
644
576
  // src/primitive-hooks/actionBar/useActionBarEdit.tsx
645
577
 
646
578
  var useActionBarEdit = () => {
647
- const editComposerStore = useEditComposerStore();
648
- const disabled = useEditComposer((c) => c.isEditing);
579
+ const composerRuntime = useComposerRuntime();
580
+ const disabled = useComposer((c) => c.isEditing);
649
581
  const callback = _react.useCallback.call(void 0, () => {
650
- const { edit } = editComposerStore.getState();
651
- edit();
652
- }, [editComposerStore]);
582
+ composerRuntime.beginEdit();
583
+ }, [composerRuntime]);
653
584
  if (disabled) return null;
654
585
  return callback;
655
586
  };
@@ -659,19 +590,18 @@ var useActionBarEdit = () => {
659
590
  var useActionBarReload = () => {
660
591
  const messageStore = useMessageStore();
661
592
  const threadStore = useThreadStore();
662
- const threadRuntime = useThreadRuntime();
593
+ const messageRuntime = useMessageRuntime();
663
594
  const threadComposerStore = useThreadComposerStore();
664
595
  const threadViewportStore = useThreadViewportStore();
665
596
  const disabled = useCombinedStore(
666
597
  [threadStore, messageStore],
667
- (t, m) => t.isRunning || t.isDisabled || m.message.role !== "assistant"
598
+ (t, m) => t.isRunning || t.isDisabled || m.role !== "assistant"
668
599
  );
669
600
  const callback = _react.useCallback.call(void 0, () => {
670
- const { parentId } = messageStore.getState();
671
- threadRuntime.startRun(parentId);
601
+ messageRuntime.reload();
672
602
  threadViewportStore.getState().scrollToBottom();
673
603
  threadComposerStore.getState().focus();
674
- }, [threadRuntime, threadComposerStore, threadViewportStore, messageStore]);
604
+ }, [messageRuntime, threadComposerStore, threadViewportStore]);
675
605
  if (disabled) return null;
676
606
  return callback;
677
607
  };
@@ -681,19 +611,18 @@ var useActionBarReload = () => {
681
611
  var useActionBarSpeak = () => {
682
612
  const messageStore = useMessageStore();
683
613
  const editComposerStore = useEditComposerStore();
684
- const threadRuntime = useThreadRuntime();
614
+ const messageRunime = useMessageRuntime();
685
615
  const messageUtilsStore = useMessageUtilsStore();
686
616
  const hasSpeakableContent = useCombinedStore(
687
617
  [messageStore, editComposerStore],
688
- ({ message }, c) => {
618
+ (message, c) => {
689
619
  return !c.isEditing && (message.role !== "assistant" || message.status.type !== "running") && message.content.some((c2) => c2.type === "text" && c2.text.length > 0);
690
620
  }
691
621
  );
692
622
  const callback = _react.useCallback.call(void 0, async () => {
693
- const { message } = messageStore.getState();
694
- const utt = threadRuntime.speak(message.id);
623
+ const utt = messageRunime.speak();
695
624
  messageUtilsStore.getState().addUtterance(utt);
696
- }, [threadRuntime, messageStore, messageUtilsStore]);
625
+ }, [messageRunime, messageUtilsStore]);
697
626
  if (!hasSpeakableContent) return null;
698
627
  return callback;
699
628
  };
@@ -713,79 +642,73 @@ var useActionBarStopSpeaking = () => {
713
642
  // src/primitive-hooks/actionBar/useActionBarFeedbackPositive.tsx
714
643
 
715
644
  var useActionBarFeedbackPositive = () => {
716
- const threadRuntime = useThreadRuntime();
717
- const messageStore = useMessageStore();
645
+ const messageRuntime = useMessageRuntime();
718
646
  const messageUtilsStore = useMessageUtilsStore();
719
647
  const callback = _react.useCallback.call(void 0, () => {
720
- threadRuntime.submitFeedback({
721
- messageId: messageStore.getState().message.id,
648
+ messageRuntime.submitFeedback({
722
649
  type: "positive"
723
650
  });
724
651
  messageUtilsStore.getState().setSubmittedFeedback("positive");
725
- }, [messageStore, messageUtilsStore, threadRuntime]);
652
+ }, [messageUtilsStore, messageRuntime]);
726
653
  return callback;
727
654
  };
728
655
 
729
656
  // src/primitive-hooks/actionBar/useActionBarFeedbackNegative.tsx
730
657
 
731
658
  var useActionBarFeedbackNegative = () => {
732
- const threadRuntime = useThreadRuntime();
733
- const messageStore = useMessageStore();
659
+ const messageRuntime = useMessageRuntime();
734
660
  const messageUtilsStore = useMessageUtilsStore();
735
661
  const callback = _react.useCallback.call(void 0, () => {
736
- threadRuntime.submitFeedback({
737
- messageId: messageStore.getState().message.id,
662
+ messageRuntime.submitFeedback({
738
663
  type: "negative"
739
664
  });
740
665
  messageUtilsStore.getState().setSubmittedFeedback("negative");
741
- }, [messageStore, messageUtilsStore, threadRuntime]);
666
+ }, [messageUtilsStore, messageRuntime]);
742
667
  return callback;
743
668
  };
744
669
 
745
670
  // src/primitive-hooks/branchPicker/useBranchPickerCount.tsx
746
671
  var useBranchPickerCount = () => {
747
- const branchCount = useMessage((s) => s.branches.length);
672
+ const branchCount = useMessage((s) => s.branchCount);
748
673
  return branchCount;
749
674
  };
750
675
 
751
676
  // src/primitive-hooks/branchPicker/useBranchPickerNext.tsx
752
677
 
753
678
  var useBranchPickerNext = () => {
679
+ const messageRuntime = useMessageRuntime();
754
680
  const messageStore = useMessageStore();
755
681
  const editComposerStore = useEditComposerStore();
756
- const threadRuntime = useThreadRuntime();
757
682
  const disabled = useCombinedStore(
758
683
  [messageStore, editComposerStore],
759
- (m, c) => c.isEditing || m.branches.indexOf(m.message.id) + 1 >= m.branches.length
684
+ (m, c) => c.isEditing || m.branchNumber >= m.branchCount
760
685
  );
761
686
  const callback = _react.useCallback.call(void 0, () => {
762
- const { message, branches } = messageStore.getState();
763
- threadRuntime.switchToBranch(branches[branches.indexOf(message.id) + 1]);
764
- }, [threadRuntime, messageStore]);
687
+ messageRuntime.switchToBranch({ position: "next" });
688
+ }, [messageRuntime]);
765
689
  if (disabled) return null;
766
690
  return callback;
767
691
  };
768
692
 
769
693
  // src/primitive-hooks/branchPicker/useBranchPickerNumber.tsx
770
694
  var useBranchPickerNumber = () => {
771
- const branchIdx = useMessage((s) => s.branches.indexOf(s.message.id));
772
- return branchIdx + 1;
695
+ const branchNumber = useMessage((s) => s.branchNumber);
696
+ return branchNumber;
773
697
  };
774
698
 
775
699
  // src/primitive-hooks/branchPicker/useBranchPickerPrevious.tsx
776
700
 
777
701
  var useBranchPickerPrevious = () => {
702
+ const messageRuntime = useMessageRuntime();
778
703
  const messageStore = useMessageStore();
779
704
  const editComposerStore = useEditComposerStore();
780
- const threadRuntime = useThreadRuntime();
781
705
  const disabled = useCombinedStore(
782
706
  [messageStore, editComposerStore],
783
- (m, c) => c.isEditing || m.branches.indexOf(m.message.id) <= 0
707
+ (m, c) => c.isEditing || m.branchNumber <= 1
784
708
  );
785
709
  const callback = _react.useCallback.call(void 0, () => {
786
- const { message, branches } = messageStore.getState();
787
- threadRuntime.switchToBranch(branches[branches.indexOf(message.id) - 1]);
788
- }, [threadRuntime, messageStore]);
710
+ messageRuntime.switchToBranch({ position: "previous" });
711
+ }, [messageRuntime]);
789
712
  if (disabled) return null;
790
713
  return callback;
791
714
  };
@@ -849,7 +772,7 @@ var useComposerAddAttachment = () => {
849
772
  input.accept = attachmentAccept;
850
773
  }
851
774
  input.onchange = (e) => {
852
- const file = _optionalChain([e, 'access', _17 => _17.target, 'access', _18 => _18.files, 'optionalAccess', _19 => _19[0]]);
775
+ const file = _optionalChain([e, 'access', _7 => _7.target, 'access', _8 => _8.files, 'optionalAccess', _9 => _9[0]]);
853
776
  if (!file) return;
854
777
  addAttachment(file);
855
778
  };
@@ -862,7 +785,7 @@ var useComposerAddAttachment = () => {
862
785
  // src/primitive-hooks/contentPart/useContentPartDisplay.tsx
863
786
  var useContentPartDisplay = () => {
864
787
  const display = useContentPart((c) => {
865
- if (c.part.type !== "ui")
788
+ if (c.type !== "ui")
866
789
  throw new Error(
867
790
  "This component can only be used inside ui content parts."
868
791
  );
@@ -874,7 +797,7 @@ var useContentPartDisplay = () => {
874
797
  // src/primitive-hooks/contentPart/useContentPartImage.tsx
875
798
  var useContentPartImage = () => {
876
799
  const image = useContentPart((c) => {
877
- if (c.part.type !== "image")
800
+ if (c.type !== "image")
878
801
  throw new Error(
879
802
  "ContentPartImage can only be used inside image content parts."
880
803
  );
@@ -886,7 +809,7 @@ var useContentPartImage = () => {
886
809
  // src/primitive-hooks/contentPart/useContentPartText.tsx
887
810
  var useContentPartText = () => {
888
811
  const text = useContentPart((c) => {
889
- if (c.part.type !== "text")
812
+ if (c.type !== "text")
890
813
  throw new Error(
891
814
  "ContentPartText can only be used inside text content parts."
892
815
  );
@@ -901,19 +824,19 @@ var useMessageIf = (props) => {
901
824
  const messageUtilsStore = useMessageUtilsStore();
902
825
  return useCombinedStore(
903
826
  [messageStore, messageUtilsStore],
904
- ({ message, branches, isLast }, { isCopied, isHovering, isSpeaking, submittedFeedback }) => {
905
- if (props.hasBranches === true && branches.length < 2) return false;
906
- if (props.user && message.role !== "user") return false;
907
- if (props.assistant && message.role !== "assistant") return false;
908
- if (props.system && message.role !== "system") return false;
827
+ ({ role, attachments, branchCount, isLast }, { isCopied, isHovering, isSpeaking, submittedFeedback }) => {
828
+ if (props.hasBranches === true && branchCount < 2) return false;
829
+ if (props.user && role !== "user") return false;
830
+ if (props.assistant && role !== "assistant") return false;
831
+ if (props.system && role !== "system") return false;
909
832
  if (props.lastOrHover === true && !isHovering && !isLast) return false;
910
833
  if (props.copied === true && !isCopied) return false;
911
834
  if (props.copied === false && isCopied) return false;
912
835
  if (props.speaking === true && !isSpeaking) return false;
913
836
  if (props.speaking === false && isSpeaking) return false;
914
- if (props.hasAttachments === true && (message.role !== "user" || !message.attachments.length))
837
+ if (props.hasAttachments === true && (role !== "user" || !attachments.length))
915
838
  return false;
916
- if (props.hasAttachments === false && message.role === "user" && !!message.attachments.length)
839
+ if (props.hasAttachments === false && role === "user" && !!attachments.length)
917
840
  return false;
918
841
  if (props.submittedFeedback !== void 0 && submittedFeedback !== props.submittedFeedback)
919
842
  return false;
@@ -924,20 +847,15 @@ var useMessageIf = (props) => {
924
847
 
925
848
  // src/primitive-hooks/thread/useThreadIf.tsx
926
849
  var useThreadIf = (props) => {
927
- const threadStore = useThreadStore();
928
- const threadMessagesStore = useThreadMessagesStore();
929
- return useCombinedStore(
930
- [threadStore, threadMessagesStore],
931
- (thread, messages) => {
932
- if (props.empty === true && messages.length !== 0) return false;
933
- if (props.empty === false && messages.length === 0) return false;
934
- if (props.running === true && !thread.isRunning) return false;
935
- if (props.running === false && thread.isRunning) return false;
936
- if (props.disabled === true && thread.isDisabled) return false;
937
- if (props.disabled === false && thread.isDisabled) return false;
938
- return true;
939
- }
940
- );
850
+ return useThread((thread) => {
851
+ if (props.empty === true && thread.messages.length !== 0) return false;
852
+ if (props.empty === false && thread.messages.length === 0) return false;
853
+ if (props.running === true && !thread.isRunning) return false;
854
+ if (props.running === false && thread.isRunning) return false;
855
+ if (props.disabled === true && thread.isDisabled) return false;
856
+ if (props.disabled === false && thread.isDisabled) return false;
857
+ return true;
858
+ });
941
859
  };
942
860
 
943
861
  // src/primitive-hooks/thread/useThreadEmpty.tsx
@@ -1060,7 +978,7 @@ var ActionBarPrimitiveCopy = _react.forwardRef.call(void 0, ({ copiedDuration, o
1060
978
  ref: forwardedRef,
1061
979
  disabled: disabled || !callback,
1062
980
  onClick: _primitive.composeEventHandlers.call(void 0, onClick, () => {
1063
- _optionalChain([callback, 'optionalCall', _20 => _20()]);
981
+ _optionalChain([callback, 'optionalCall', _10 => _10()]);
1064
982
  })
1065
983
  }
1066
984
  );
@@ -1092,7 +1010,7 @@ var createActionButton = (displayName, useActionButton, forwardProps = []) => {
1092
1010
  ref: forwardedRef,
1093
1011
  disabled: primitiveProps.disabled || !callback,
1094
1012
  onClick: _primitive.composeEventHandlers.call(void 0, primitiveProps.onClick, () => {
1095
- _optionalChain([callback, 'optionalCall', _21 => _21()]);
1013
+ _optionalChain([callback, 'optionalCall', _11 => _11()]);
1096
1014
  })
1097
1015
  }
1098
1016
  );
@@ -1141,7 +1059,7 @@ var ActionBarPrimitiveStopSpeaking = _react.forwardRef.call(void 0, (props, ref)
1141
1059
  ...props,
1142
1060
  ref,
1143
1061
  onClick: _primitive.composeEventHandlers.call(void 0, props.onClick, () => {
1144
- _optionalChain([callback, 'optionalCall', _22 => _22()]);
1062
+ _optionalChain([callback, 'optionalCall', _12 => _12()]);
1145
1063
  })
1146
1064
  }
1147
1065
  );
@@ -1167,7 +1085,7 @@ var ActionBarPrimitiveFeedbackPositive = _react.forwardRef.call(void 0, ({ onCli
1167
1085
  ref: forwardedRef,
1168
1086
  disabled: disabled || !callback,
1169
1087
  onClick: _primitive.composeEventHandlers.call(void 0, onClick, () => {
1170
- _optionalChain([callback, 'optionalCall', _23 => _23()]);
1088
+ _optionalChain([callback, 'optionalCall', _13 => _13()]);
1171
1089
  })
1172
1090
  }
1173
1091
  );
@@ -1193,7 +1111,7 @@ var ActionBarPrimitiveFeedbackNegative = _react.forwardRef.call(void 0, ({ onCli
1193
1111
  ref: forwardedRef,
1194
1112
  disabled: disabled || !callback,
1195
1113
  onClick: _primitive.composeEventHandlers.call(void 0, onClick, () => {
1196
- _optionalChain([callback, 'optionalCall', _24 => _24()]);
1114
+ _optionalChain([callback, 'optionalCall', _14 => _14()]);
1197
1115
  })
1198
1116
  }
1199
1117
  );
@@ -1448,74 +1366,35 @@ MessagePrimitiveIf.displayName = "MessagePrimitive.If";
1448
1366
  // src/primitives/message/MessageContent.tsx
1449
1367
 
1450
1368
 
1451
- // src/context/providers/ContentPartProvider.tsx
1369
+ // src/context/providers/ContentPartRuntimeProvider.tsx
1452
1370
 
1453
1371
 
1454
1372
 
1455
- var COMPLETE_STATUS2 = {
1456
- type: "complete"
1457
- };
1458
- var toContentPartStatus = (message, partIndex, part) => {
1459
- if (message.role !== "assistant") return COMPLETE_STATUS2;
1460
- const isLastPart = partIndex === Math.max(0, message.content.length - 1);
1461
- if (part.type !== "tool-call") {
1462
- if ("reason" in message.status && message.status.reason === "tool-calls" && isLastPart)
1463
- throw new Error(
1464
- "Encountered unexpected requires-action status. This is likely an internal bug in assistant-ui."
1465
- );
1466
- return isLastPart ? message.status : COMPLETE_STATUS2;
1467
- }
1468
- if (!!part.result) {
1469
- return COMPLETE_STATUS2;
1470
- }
1471
- return message.status;
1472
- };
1473
- var EMPTY_CONTENT = Object.freeze({ type: "text", text: "" });
1474
- var getContentPartState = ({ message }, useContentPart2, partIndex) => {
1475
- let part = message.content[partIndex];
1476
- if (!part) {
1477
- if (message.content.length === 0 && partIndex === 0) {
1478
- part = EMPTY_CONTENT;
1479
- } else {
1480
- return null;
1481
- }
1482
- } else if (message.content.length === 1 && part.type === "text" && part.text.length === 0) {
1483
- part = EMPTY_CONTENT;
1484
- }
1485
- const status = toContentPartStatus(message, partIndex, part);
1486
- const currentState = _optionalChain([useContentPart2, 'optionalAccess', _25 => _25.getState, 'call', _26 => _26()]);
1487
- if (currentState && currentState.part === part && currentState.status === status)
1488
- return null;
1489
- return Object.freeze({ part, status });
1373
+ var useContentPartRuntimeStore = (runtime) => {
1374
+ const [store] = _react.useState.call(void 0, () => _zustand.create.call(void 0, () => runtime));
1375
+ _react.useEffect.call(void 0, () => {
1376
+ writableStore(store).setState(runtime, true);
1377
+ }, [runtime, store]);
1378
+ return store;
1490
1379
  };
1491
- var useContentPartContext2 = (partIndex) => {
1492
- const messageStore = useMessageStore();
1493
- const [context] = _react.useState.call(void 0, () => {
1494
- const useContentPart2 = _zustand.create.call(void 0,
1495
- () => getContentPartState(messageStore.getState(), void 0, partIndex)
1496
- );
1497
- return { useContentPart: useContentPart2 };
1498
- });
1380
+ var useContentPartStore2 = (runtime) => {
1381
+ const [store] = _react.useState.call(void 0, () => _zustand.create.call(void 0, () => runtime.getState()));
1499
1382
  _react.useEffect.call(void 0, () => {
1500
- const syncContentPart = (message) => {
1501
- const newState = getContentPartState(
1502
- message,
1503
- context.useContentPart,
1504
- partIndex
1505
- );
1506
- if (!newState) return;
1507
- writableStore(context.useContentPart).setState(newState, true);
1508
- };
1509
- syncContentPart(messageStore.getState());
1510
- return messageStore.subscribe(syncContentPart);
1511
- }, [context, messageStore, partIndex]);
1512
- return context;
1383
+ const updateState = () => writableStore(store).setState(runtime.getState(), true);
1384
+ updateState();
1385
+ return runtime.subscribe(updateState);
1386
+ }, [runtime, store]);
1387
+ return store;
1513
1388
  };
1514
- var ContentPartProvider = ({
1515
- partIndex,
1389
+ var ContentPartRuntimeProvider = ({
1390
+ runtime,
1516
1391
  children
1517
1392
  }) => {
1518
- const context = useContentPartContext2(partIndex);
1393
+ const useContentPartRuntime2 = useContentPartRuntimeStore(runtime);
1394
+ const useContentPart2 = useContentPartStore2(runtime);
1395
+ const [context] = _react.useState.call(void 0, () => {
1396
+ return { useContentPartRuntime: useContentPartRuntime2, useContentPart: useContentPart2 };
1397
+ });
1519
1398
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ContentPartContext.Provider, { value: context, children });
1520
1399
  };
1521
1400
 
@@ -1560,7 +1439,7 @@ var withSmoothContextProvider = (Component) => {
1560
1439
  };
1561
1440
  function useSmoothContext(options) {
1562
1441
  const context = _react.useContext.call(void 0, SmoothContext);
1563
- if (!_optionalChain([options, 'optionalAccess', _27 => _27.optional]) && !context)
1442
+ if (!_optionalChain([options, 'optionalAccess', _15 => _15.optional]) && !context)
1564
1443
  throw new Error(
1565
1444
  "This component must be used within a SmoothContextProvider."
1566
1445
  );
@@ -1620,12 +1499,10 @@ var SMOOTH_STATUS = Object.freeze({
1620
1499
  type: "running"
1621
1500
  });
1622
1501
  var useSmooth = (state, smooth = false) => {
1623
- const {
1624
- part: { text }
1625
- } = state;
1502
+ const { text } = state;
1626
1503
  const id = useMessage({
1627
1504
  optional: true,
1628
- selector: (m) => m.message.id
1505
+ selector: (m) => m.id
1629
1506
  });
1630
1507
  const idRef = _react.useRef.call(void 0, id);
1631
1508
  const [displayedText, setDisplayedText] = _react.useState.call(void 0, text);
@@ -1634,17 +1511,17 @@ var useSmooth = (state, smooth = false) => {
1634
1511
  setDisplayedText(text2);
1635
1512
  if (smoothStatusStore) {
1636
1513
  writableStore(smoothStatusStore).setState(
1637
- text2 !== state.part.text ? SMOOTH_STATUS : state.status
1514
+ text2 !== state.text ? SMOOTH_STATUS : state.status
1638
1515
  );
1639
1516
  }
1640
1517
  });
1641
1518
  _react.useEffect.call(void 0, () => {
1642
1519
  if (smoothStatusStore) {
1643
1520
  writableStore(smoothStatusStore).setState(
1644
- text !== state.part.text ? SMOOTH_STATUS : state.status
1521
+ text !== state.text ? SMOOTH_STATUS : state.status
1645
1522
  );
1646
1523
  }
1647
- }, [smoothStatusStore, text, displayedText, state.status, state.part.text]);
1524
+ }, [smoothStatusStore, text, displayedText, state.status, state.text]);
1648
1525
  const [animatorRef] = _react.useState.call(void 0,
1649
1526
  new TextStreamAnimator(text, setText)
1650
1527
  );
@@ -1671,6 +1548,8 @@ var useSmooth = (state, smooth = false) => {
1671
1548
  }, [animatorRef]);
1672
1549
  return _react.useMemo.call(void 0,
1673
1550
  () => smooth ? {
1551
+ type: "text",
1552
+ text: displayedText,
1674
1553
  part: { type: "text", text: displayedText },
1675
1554
  status: text === displayedText ? state.status : SMOOTH_STATUS
1676
1555
  } : state,
@@ -1681,10 +1560,7 @@ var useSmooth = (state, smooth = false) => {
1681
1560
  // src/primitives/contentPart/ContentPartText.tsx
1682
1561
 
1683
1562
  var ContentPartPrimitiveText = _react.forwardRef.call(void 0, ({ smooth = true, component: Component = "span", ...rest }, forwardedRef) => {
1684
- const {
1685
- part: { text },
1686
- status
1687
- } = useSmooth(useContentPartText(), smooth);
1563
+ const { text, status } = useSmooth(useContentPartText(), smooth);
1688
1564
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Component, { "data-status": status.type, ...rest, ref: forwardedRef, children: text });
1689
1565
  });
1690
1566
  ContentPartPrimitiveText.displayName = "ContentPartPrimitive.Text";
@@ -1694,18 +1570,14 @@ ContentPartPrimitiveText.displayName = "ContentPartPrimitive.Text";
1694
1570
 
1695
1571
 
1696
1572
  var ContentPartPrimitiveImage = _react.forwardRef.call(void 0, (props, forwardedRef) => {
1697
- const {
1698
- part: { image }
1699
- } = useContentPartImage();
1573
+ const { image } = useContentPartImage();
1700
1574
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactprimitive.Primitive.img, { src: image, ...props, ref: forwardedRef });
1701
1575
  });
1702
1576
  ContentPartPrimitiveImage.displayName = "ContentPartPrimitive.Image";
1703
1577
 
1704
1578
  // src/primitives/contentPart/ContentPartDisplay.tsx
1705
1579
  var ContentPartPrimitiveDisplay = () => {
1706
- const {
1707
- part: { display }
1708
- } = useContentPartDisplay();
1580
+ const { display } = useContentPartDisplay();
1709
1581
  return _nullishCoalesce(display, () => ( null));
1710
1582
  };
1711
1583
  ContentPartPrimitiveDisplay.displayName = "ContentPartPrimitive.Display";
@@ -1717,187 +1589,555 @@ var ContentPartPrimitiveInProgress = ({ children }) => {
1717
1589
  };
1718
1590
  ContentPartPrimitiveInProgress.displayName = "ContentPartPrimitive.InProgress";
1719
1591
 
1720
- // src/primitives/message/MessageContent.tsx
1721
-
1722
- var ToolUIDisplay = ({
1723
- UI,
1724
- ...props
1725
- }) => {
1726
- const Render = _nullishCoalesce(useToolUIs((s) => s.getToolUI(props.part.toolName)), () => ( UI));
1727
- if (!Render) return null;
1728
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Render, { ...props });
1592
+ // src/api/ComposerRuntime.ts
1593
+ var METHOD_NOT_SUPPORTED = () => {
1594
+ throw new Error("Composer is not available");
1729
1595
  };
1730
- var defaultComponents = {
1731
- Text: () => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { style: { whiteSpace: "pre-line" }, children: [
1732
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ContentPartPrimitiveText, {}),
1733
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ContentPartPrimitiveInProgress, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: { fontFamily: "revert" }, children: " \u25CF" }) })
1734
- ] }),
1735
- Image: () => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ContentPartPrimitiveImage, {}),
1736
- UI: () => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ContentPartPrimitiveDisplay, {})
1596
+ var EMPTY_ARRAY = Object.freeze([]);
1597
+ var getThreadComposerState = (type, runtime, beginEdit, focus, onFocus) => {
1598
+ return Object.freeze({
1599
+ type,
1600
+ isEditing: _nullishCoalesce(_optionalChain([runtime, 'optionalAccess', _16 => _16.isEditing]), () => ( false)),
1601
+ canCancel: _nullishCoalesce(_optionalChain([runtime, 'optionalAccess', _17 => _17.canCancel]), () => ( false)),
1602
+ isEmpty: _nullishCoalesce(_optionalChain([runtime, 'optionalAccess', _18 => _18.isEmpty]), () => ( true)),
1603
+ text: _nullishCoalesce(_optionalChain([runtime, 'optionalAccess', _19 => _19.text]), () => ( "")),
1604
+ attachments: _nullishCoalesce(_optionalChain([runtime, 'optionalAccess', _20 => _20.attachments]), () => ( EMPTY_ARRAY)),
1605
+ attachmentAccept: _nullishCoalesce(_optionalChain([runtime, 'optionalAccess', _21 => _21.attachmentAccept]), () => ( "*")),
1606
+ value: _nullishCoalesce(_optionalChain([runtime, 'optionalAccess', _22 => _22.text]), () => ( "")),
1607
+ setValue: _nullishCoalesce(_optionalChain([runtime, 'optionalAccess', _23 => _23.setText, 'access', _24 => _24.bind, 'call', _25 => _25(runtime)]), () => ( METHOD_NOT_SUPPORTED)),
1608
+ setText: _nullishCoalesce(_optionalChain([runtime, 'optionalAccess', _26 => _26.setText, 'access', _27 => _27.bind, 'call', _28 => _28(runtime)]), () => ( METHOD_NOT_SUPPORTED)),
1609
+ edit: beginEdit,
1610
+ send: _nullishCoalesce(_optionalChain([runtime, 'optionalAccess', _29 => _29.send, 'access', _30 => _30.bind, 'call', _31 => _31(runtime)]), () => ( METHOD_NOT_SUPPORTED)),
1611
+ cancel: _nullishCoalesce(_optionalChain([runtime, 'optionalAccess', _32 => _32.cancel, 'access', _33 => _33.bind, 'call', _34 => _34(runtime)]), () => ( METHOD_NOT_SUPPORTED)),
1612
+ focus: _nullishCoalesce(focus, () => ( METHOD_NOT_SUPPORTED)),
1613
+ onFocus: _nullishCoalesce(onFocus, () => ( METHOD_NOT_SUPPORTED)),
1614
+ reset: _nullishCoalesce(_optionalChain([runtime, 'optionalAccess', _35 => _35.reset, 'access', _36 => _36.bind, 'call', _37 => _37(runtime)]), () => ( METHOD_NOT_SUPPORTED)),
1615
+ addAttachment: _nullishCoalesce(_optionalChain([runtime, 'optionalAccess', _38 => _38.addAttachment, 'access', _39 => _39.bind, 'call', _40 => _40(runtime)]), () => ( METHOD_NOT_SUPPORTED)),
1616
+ removeAttachment: _nullishCoalesce(_optionalChain([runtime, 'optionalAccess', _41 => _41.removeAttachment, 'access', _42 => _42.bind, 'call', _43 => _43(runtime)]), () => ( METHOD_NOT_SUPPORTED))
1617
+ });
1737
1618
  };
1738
- var MessageContentPartComponent = ({
1739
- components: {
1740
- Text: Text2 = defaultComponents.Text,
1741
- Empty,
1742
- Image: Image2 = defaultComponents.Image,
1743
- UI = defaultComponents.UI,
1744
- tools: { by_name = {}, Fallback: Fallback2 = void 0 } = {}
1745
- } = {}
1746
- }) => {
1747
- const messageStore = useMessageStore();
1748
- const threadRuntime = useThreadRuntime();
1749
- const { part, status } = useContentPart();
1750
- const type = part.type;
1751
- switch (type) {
1752
- case "text":
1753
- if (status.type === "requires-action")
1754
- throw new Error("Encountered unexpected requires-action status");
1755
- if (part === EMPTY_CONTENT && !!Empty) {
1756
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Empty, { status });
1757
- }
1758
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Text2, { part, status });
1759
- case "image":
1760
- if (status.type === "requires-action")
1761
- throw new Error("Encountered unexpected requires-action status");
1762
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Image2, { part, status });
1763
- case "ui":
1764
- if (status.type === "requires-action")
1765
- throw new Error("Encountered unexpected requires-action status");
1766
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, UI, { part, status });
1767
- case "tool-call": {
1768
- const Tool = by_name[part.toolName] || Fallback2;
1769
- const addResult = (result) => threadRuntime.addToolResult({
1770
- messageId: messageStore.getState().message.id,
1771
- toolName: part.toolName,
1772
- toolCallId: part.toolCallId,
1773
- result
1774
- });
1775
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
1776
- ToolUIDisplay,
1777
- {
1778
- UI: Tool,
1779
- part,
1780
- status,
1781
- addResult
1782
- }
1783
- );
1784
- }
1785
- default:
1786
- const unhandledType = type;
1787
- throw new Error(`Unknown content part type: ${unhandledType}`);
1619
+ var ComposerRuntime = (_class2 = class {
1620
+ constructor(_core, _beginEdit) {;_class2.prototype.__init5.call(this);
1621
+ this._core = _core;
1622
+ this._beginEdit = _beginEdit;
1788
1623
  }
1789
- };
1790
- var MessageContentPartImpl = ({
1791
- partIndex,
1792
- components
1793
- }) => {
1794
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ContentPartProvider, { partIndex, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, MessageContentPartComponent, { components }) });
1795
- };
1796
- var MessageContentPart = _react.memo.call(void 0,
1797
- MessageContentPartImpl,
1798
- (prev, next) => prev.partIndex === next.partIndex && _optionalChain([prev, 'access', _28 => _28.components, 'optionalAccess', _29 => _29.Text]) === _optionalChain([next, 'access', _30 => _30.components, 'optionalAccess', _31 => _31.Text]) && _optionalChain([prev, 'access', _32 => _32.components, 'optionalAccess', _33 => _33.Image]) === _optionalChain([next, 'access', _34 => _34.components, 'optionalAccess', _35 => _35.Image]) && _optionalChain([prev, 'access', _36 => _36.components, 'optionalAccess', _37 => _37.UI]) === _optionalChain([next, 'access', _38 => _38.components, 'optionalAccess', _39 => _39.UI]) && _optionalChain([prev, 'access', _40 => _40.components, 'optionalAccess', _41 => _41.tools]) === _optionalChain([next, 'access', _42 => _42.components, 'optionalAccess', _43 => _43.tools])
1799
- );
1800
- var MessagePrimitiveContent = ({
1801
- components
1802
- }) => {
1803
- const contentLength = useMessage((s) => s.message.content.length) || 1;
1804
- return Array.from({ length: contentLength }, (_, index) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, MessageContentPart, { partIndex: index, components }, index));
1805
- };
1806
- MessagePrimitiveContent.displayName = "MessagePrimitive.Content";
1807
-
1808
- // src/primitives/message/MessageInProgress.tsx
1809
- var MessagePrimitiveInProgress = () => {
1810
- return null;
1811
- };
1812
- MessagePrimitiveInProgress.displayName = "MessagePrimitive.InProgress";
1813
-
1814
- // src/primitives/message/MessageAttachments.tsx
1624
+ get type() {
1625
+ return this._beginEdit ? "edit" : "thread";
1626
+ }
1627
+ /**
1628
+ * @deprecated Use `getState().isEditing` instead. This will be removed in 0.6.0.
1629
+ */
1630
+ get isEditing() {
1631
+ return this.getState().isEditing;
1632
+ }
1633
+ /**
1634
+ * @deprecated Use `getState().isEmpty` instead. This will be removed in 0.6.0.
1635
+ */
1636
+ get isEmpty() {
1637
+ return this.getState().isEmpty;
1638
+ }
1639
+ /**
1640
+ * @deprecated Use `getState().canCancel` instead. This will be removed in 0.6.0.
1641
+ */
1642
+ get canCancel() {
1643
+ return this.getState().canCancel;
1644
+ }
1645
+ /**
1646
+ * @deprecated Use `getState().text` instead. This will be removed in 0.6.0.
1647
+ */
1648
+ get text() {
1649
+ return this.getState().text;
1650
+ }
1651
+ /**
1652
+ * @deprecated Use `getState().attachmentAccept` instead. This will be removed in 0.6.0.
1653
+ */
1654
+ get attachmentAccept() {
1655
+ return this.getState().attachmentAccept;
1656
+ }
1657
+ // TODO should this instead return getAttachmentByIndex([idx]) instead?
1658
+ /**
1659
+ * @deprecated Use `getState().attachments` instead. This will be removed in 0.6.0.
1660
+ */
1661
+ get attachments() {
1662
+ return this.getState().attachments;
1663
+ }
1664
+ /**
1665
+ * @deprecated Use `getState().text` instead. This will be removed in 0.6.0.
1666
+ */
1667
+ get value() {
1668
+ return this.text;
1669
+ }
1670
+ getState() {
1671
+ return getThreadComposerState(
1672
+ this.type,
1673
+ this._core.getState(),
1674
+ _nullishCoalesce(_optionalChain([this, 'access', _44 => _44._beginEdit, 'optionalAccess', _45 => _45.bind, 'call', _46 => _46(this)]), () => ( METHOD_NOT_SUPPORTED)),
1675
+ this.focus.bind(this),
1676
+ this.onFocus.bind(this)
1677
+ );
1678
+ }
1679
+ setText(text) {
1680
+ const core = this._core.getState();
1681
+ if (!core) throw new Error("Composer is not available");
1682
+ core.setText(text);
1683
+ }
1684
+ setValue(text) {
1685
+ this.setText(text);
1686
+ }
1687
+ addAttachment(file) {
1688
+ const core = this._core.getState();
1689
+ if (!core) throw new Error("Composer is not available");
1690
+ return core.addAttachment(file);
1691
+ }
1692
+ // /**
1693
+ // * @deprecated Use `getAttachmentById(id).removeAttachment` instead. This will be removed in 0.6.0.
1694
+ // */
1695
+ removeAttachment(attachmentId) {
1696
+ const core = this._core.getState();
1697
+ if (!core) throw new Error("Composer is not available");
1698
+ return core.removeAttachment(attachmentId);
1699
+ }
1700
+ /**
1701
+ * @deprecated This method will be removed in 0.6.0. Submit feedback if you need this functionality.
1702
+ */
1703
+ reset() {
1704
+ const core = this._core.getState();
1705
+ if (!core) throw new Error("Composer is not available");
1706
+ core.reset();
1707
+ }
1708
+ send() {
1709
+ const core = this._core.getState();
1710
+ if (!core) throw new Error("Composer is not available");
1711
+ core.send();
1712
+ }
1713
+ cancel() {
1714
+ const core = this._core.getState();
1715
+ if (!core) throw new Error("Composer is not available");
1716
+ core.cancel();
1717
+ }
1718
+ beginEdit() {
1719
+ _optionalChain([this, 'access', _47 => _47._beginEdit, 'optionalCall', _48 => _48()]);
1720
+ }
1721
+ /**
1722
+ * @deprecated Use `beginEdit()` instead. This will be removed in 0.6.0.
1723
+ */
1724
+ edit() {
1725
+ this.beginEdit();
1726
+ }
1727
+ subscribe(callback) {
1728
+ return this._core.subscribe(callback);
1729
+ }
1730
+ __init5() {this._focusListeners = /* @__PURE__ */ new Set()}
1731
+ focus() {
1732
+ this._focusListeners.forEach((callback) => callback());
1733
+ }
1734
+ onFocus(callback) {
1735
+ this._focusListeners.add(callback);
1736
+ return () => this._focusListeners.delete(callback);
1737
+ }
1738
+ }, _class2);
1815
1739
 
1740
+ // src/api/subscribable/BaseSubject.ts
1741
+ var BaseSubject = (_class3 = class {constructor() { _class3.prototype.__init6.call(this); }
1742
+ __init6() {this._subscriptions = /* @__PURE__ */ new Set()}
1743
+
1744
+ get isConnected() {
1745
+ return !!this._connection;
1746
+ }
1747
+ notifySubscribers() {
1748
+ for (const callback of this._subscriptions) callback();
1749
+ }
1750
+ _updateConnection() {
1751
+ if (this._subscriptions.size > 0) {
1752
+ if (this._connection) return;
1753
+ this._connection = this._connect();
1754
+ } else {
1755
+ _optionalChain([this, 'access', _49 => _49._connection, 'optionalCall', _50 => _50()]);
1756
+ this._connection = void 0;
1757
+ }
1758
+ }
1759
+ subscribe(callback) {
1760
+ this._subscriptions.add(callback);
1761
+ this._updateConnection();
1762
+ return () => {
1763
+ this._subscriptions.delete(callback);
1764
+ this._updateConnection();
1765
+ };
1766
+ }
1767
+ }, _class3);
1816
1768
 
1817
- // src/context/react/AttachmentContext.ts
1769
+ // src/api/subscribable/NestedSubscriptionSubject.ts
1770
+ var NestedSubscriptionSubject = class extends BaseSubject {
1771
+ constructor(binding) {
1772
+ super();
1773
+ this.binding = binding;
1774
+ }
1775
+ getState() {
1776
+ return this.binding.getState();
1777
+ }
1778
+ _connect() {
1779
+ const callback = () => {
1780
+ this.notifySubscribers();
1781
+ };
1782
+ let lastState = this.binding.getState();
1783
+ let innerUnsubscribe = _optionalChain([lastState, 'optionalAccess', _51 => _51.subscribe, 'call', _52 => _52(callback)]);
1784
+ const onRuntimeUpdate = () => {
1785
+ const newState = this.binding.getState();
1786
+ if (newState === lastState) return;
1787
+ lastState = newState;
1788
+ _optionalChain([innerUnsubscribe, 'optionalCall', _53 => _53()]);
1789
+ innerUnsubscribe = _optionalChain([this, 'access', _54 => _54.binding, 'access', _55 => _55.getState, 'call', _56 => _56(), 'optionalAccess', _57 => _57.subscribe, 'call', _58 => _58(callback)]);
1790
+ callback();
1791
+ };
1792
+ const outerUnsubscribe = this.binding.subscribe(onRuntimeUpdate);
1793
+ return () => {
1794
+ _optionalChain([outerUnsubscribe, 'optionalCall', _59 => _59()]);
1795
+ _optionalChain([innerUnsubscribe, 'optionalCall', _60 => _60()]);
1796
+ };
1797
+ }
1798
+ };
1818
1799
 
1819
- var AttachmentContext = _react.createContext.call(void 0,
1820
- null
1821
- );
1822
- function useAttachmentContext(options) {
1823
- const context = _react.useContext.call(void 0, AttachmentContext);
1824
- if (!_optionalChain([options, 'optionalAccess', _44 => _44.optional]) && !context)
1825
- throw new Error(
1826
- "This component must be used within a ComposerPrimitive.Attachments or MessagePrimitive.Attachments component."
1827
- );
1828
- return context;
1829
- }
1830
- function useComposerAttachmentContext(options) {
1831
- const context = useAttachmentContext(options);
1832
- if (!context) return null;
1833
- if (context.type !== "composer")
1834
- throw new Error(
1835
- "This component must be used within a ComposerPrimitive.Attachments component."
1836
- );
1837
- return context;
1838
- }
1839
- function useMessageAttachmentContext(options) {
1840
- const context = useAttachmentContext(options);
1841
- if (!context) return null;
1842
- if (context.type !== "message")
1843
- throw new Error(
1844
- "This component must be used within a MessagePrimitive.Attachments component."
1845
- );
1846
- return context;
1800
+ // src/api/subscribable/shallowEqual.ts
1801
+ function shallowEqual(objA, objB) {
1802
+ if (objA === void 0 && objB === void 0) return true;
1803
+ if (objA === void 0) return false;
1804
+ if (objB === void 0) return false;
1805
+ for (const key of Object.keys(objA)) {
1806
+ const valueA = objA[key];
1807
+ const valueB = objB[key];
1808
+ if (!Object.is(valueA, valueB)) return false;
1809
+ }
1810
+ return true;
1847
1811
  }
1848
- var { useAttachment, useAttachmentStore } = createContextStoreHook(
1849
- useAttachmentContext,
1850
- "useAttachment"
1851
- );
1852
- var {
1853
- useAttachment: useComposerAttachment,
1854
- useAttachmentStore: useComposerAttachmentStore
1855
- } = createContextStoreHook(useComposerAttachmentContext, "useAttachment");
1856
- var {
1857
- useAttachment: useMessageAttachment,
1858
- useAttachmentStore: useMessageAttachmentStore
1859
- } = createContextStoreHook(useMessageAttachmentContext, "useAttachment");
1860
-
1861
- // src/context/providers/MessageAttachmentProvider.tsx
1862
-
1863
1812
 
1813
+ // src/api/subscribable/ShallowMemoizeSubject.ts
1814
+ var ShallowMemoizeSubject = (_class4 = class extends BaseSubject {
1815
+ constructor(binding) {
1816
+ super();_class4.prototype.__init7.call(this);;
1817
+ this.binding = binding;
1818
+ const state = binding.getState();
1819
+ if (state === void 0)
1820
+ throw new Error("Entry not available in the store");
1821
+ this._previousState = state;
1822
+ }
1823
+
1824
+ __init7() {this.getState = () => {
1825
+ if (!this.isConnected) this._syncState();
1826
+ return this._previousState;
1827
+ }}
1828
+ _syncState() {
1829
+ const state = this.binding.getState();
1830
+ if (state === void 0) return false;
1831
+ if (shallowEqual(state, this._previousState)) return false;
1832
+ this._previousState = state;
1833
+ return true;
1834
+ }
1835
+ _connect() {
1836
+ const callback = () => {
1837
+ if (this._syncState()) {
1838
+ this.notifySubscribers();
1839
+ }
1840
+ };
1841
+ return this.binding.subscribe(callback);
1842
+ }
1843
+ }, _class4);
1864
1844
 
1865
- var getAttachment = ({ message }, useAttachment2, partIndex) => {
1866
- if (message.role !== "user") return null;
1867
- const attachments = message.attachments;
1868
- const attachment = attachments[partIndex];
1869
- if (!attachment) return null;
1870
- const currentState = _optionalChain([useAttachment2, 'optionalAccess', _45 => _45.getState, 'call', _46 => _46()]);
1871
- if (currentState && currentState.attachment === attachment) return null;
1872
- return Object.freeze({ attachment });
1845
+ // src/api/MessageRuntime.ts
1846
+ var COMPLETE_STATUS2 = {
1847
+ type: "complete"
1873
1848
  };
1874
- var useMessageAttachmentContext2 = (partIndex) => {
1875
- const messageStore = useMessageStore();
1876
- const [context] = _react.useState.call(void 0,
1877
- () => {
1878
- const useAttachment2 = _zustand.create.call(void 0,
1879
- () => getAttachment(messageStore.getState(), void 0, partIndex)
1880
- );
1881
- return { type: "message", useAttachment: useAttachment2 };
1882
- }
1883
- );
1884
- _react.useEffect.call(void 0, () => {
1885
- const syncAttachment = (messageState) => {
1886
- const newState = getAttachment(
1887
- messageState,
1888
- context.useAttachment,
1889
- partIndex
1849
+ var toContentPartStatus = (message, partIndex, part) => {
1850
+ if (message.role !== "assistant") return COMPLETE_STATUS2;
1851
+ const isLastPart = partIndex === Math.max(0, message.content.length - 1);
1852
+ if (part.type !== "tool-call") {
1853
+ if ("reason" in message.status && message.status.reason === "tool-calls" && isLastPart)
1854
+ throw new Error(
1855
+ "Encountered unexpected requires-action status. This is likely an internal bug in assistant-ui."
1890
1856
  );
1891
- if (!newState) return;
1892
- writableStore(context.useAttachment).setState(newState, true);
1893
- };
1894
- syncAttachment(messageStore.getState());
1895
- return messageStore.subscribe(syncAttachment);
1896
- }, [context, messageStore, partIndex]);
1897
- return context;
1857
+ return isLastPart ? message.status : COMPLETE_STATUS2;
1858
+ }
1859
+ if (!!part.result) {
1860
+ return COMPLETE_STATUS2;
1861
+ }
1862
+ return message.status;
1898
1863
  };
1899
- var MessageAttachmentProvider = ({
1900
- attachmentIndex: partIndex,
1864
+ var EMPTY_CONTENT = Object.freeze({ type: "text", text: "" });
1865
+ var getContentPartState = (message, partIndex) => {
1866
+ let part = message.content[partIndex];
1867
+ if (!part) {
1868
+ if (message.content.length === 0 && partIndex === 0) {
1869
+ part = EMPTY_CONTENT;
1870
+ } else {
1871
+ return void 0;
1872
+ }
1873
+ } else if (message.content.length === 1 && part.type === "text" && part.text.length === 0) {
1874
+ part = EMPTY_CONTENT;
1875
+ }
1876
+ const status = toContentPartStatus(message, partIndex, part);
1877
+ return Object.freeze({ ...part, part, status });
1878
+ };
1879
+ var MessageRuntime = (_class5 = class {
1880
+ constructor(_core, _threadBinding) {;_class5.prototype.__init8.call(this);
1881
+ this._core = _core;
1882
+ this._threadBinding = _threadBinding;
1883
+ }
1884
+ __init8() {this.composer = new ComposerRuntime(
1885
+ new NestedSubscriptionSubject({
1886
+ getState: () => this._threadBinding.getState().getEditComposer(this._core.getState().id),
1887
+ subscribe: (callback) => this._threadBinding.subscribe(callback)
1888
+ }),
1889
+ () => this._threadBinding.getState().beginEdit(this._core.getState().id)
1890
+ )}
1891
+ getState() {
1892
+ return this._core.getState();
1893
+ }
1894
+ // TODO improve type
1895
+ unstable_edit(message) {
1896
+ const state = this._core.getState();
1897
+ if (!state) throw new Error("Message is not available");
1898
+ this._threadBinding.getState().append({
1899
+ ...message,
1900
+ parentId: state.parentId
1901
+ });
1902
+ }
1903
+ reload() {
1904
+ const state = this._core.getState();
1905
+ if (!state) throw new Error("Message is not available");
1906
+ if (state.role !== "assistant")
1907
+ throw new Error("Can only reload assistant messages");
1908
+ this._threadBinding.getState().startRun(state.parentId);
1909
+ }
1910
+ speak() {
1911
+ const state = this._core.getState();
1912
+ if (!state) throw new Error("Message is not available");
1913
+ return this._threadBinding.getState().speak(state.id);
1914
+ }
1915
+ submitFeedback({ type }) {
1916
+ const state = this._core.getState();
1917
+ if (!state) throw new Error("Message is not available");
1918
+ this._threadBinding.getState().submitFeedback({
1919
+ messageId: state.id,
1920
+ type
1921
+ });
1922
+ }
1923
+ switchToBranch({
1924
+ position,
1925
+ branchId
1926
+ }) {
1927
+ const state = this._core.getState();
1928
+ if (!state) throw new Error("Message is not available");
1929
+ if (branchId && position) {
1930
+ throw new Error("May not specify both branchId and position");
1931
+ } else if (!branchId && !position) {
1932
+ throw new Error("Must specify either branchId or position");
1933
+ }
1934
+ const thread = this._threadBinding.getState();
1935
+ const branches = thread.getBranches(state.id);
1936
+ let targetBranch = branchId;
1937
+ if (position === "previous") {
1938
+ targetBranch = branches[state.branchNumber - 2];
1939
+ } else if (position === "next") {
1940
+ targetBranch = branches[state.branchNumber];
1941
+ }
1942
+ if (!targetBranch) throw new Error("Branch not found");
1943
+ this._threadBinding.getState().switchToBranch(targetBranch);
1944
+ }
1945
+ subscribe(callback) {
1946
+ return this._core.subscribe(callback);
1947
+ }
1948
+ unstable_getContentPartByIndex(idx) {
1949
+ if (idx < 0) throw new Error("Message index must be >= 0");
1950
+ return new ContentPartRuntime(
1951
+ new ShallowMemoizeSubject({
1952
+ getState: () => {
1953
+ return getContentPartState(this.getState(), idx);
1954
+ },
1955
+ subscribe: (callback) => this._core.subscribe(callback)
1956
+ }),
1957
+ this._core,
1958
+ this._threadBinding
1959
+ );
1960
+ }
1961
+ }, _class5);
1962
+
1963
+ // src/primitives/message/MessageContent.tsx
1964
+
1965
+ var ToolUIDisplay = ({
1966
+ UI,
1967
+ ...props
1968
+ }) => {
1969
+ const Render = _nullishCoalesce(useToolUIs((s) => s.getToolUI(props.toolName)), () => ( UI));
1970
+ if (!Render) return null;
1971
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Render, { ...props });
1972
+ };
1973
+ var defaultComponents = {
1974
+ Text: () => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { style: { whiteSpace: "pre-line" }, children: [
1975
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ContentPartPrimitiveText, {}),
1976
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ContentPartPrimitiveInProgress, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { style: { fontFamily: "revert" }, children: " \u25CF" }) })
1977
+ ] }),
1978
+ Image: () => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ContentPartPrimitiveImage, {}),
1979
+ UI: () => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ContentPartPrimitiveDisplay, {})
1980
+ };
1981
+ var MessageContentPartComponent = ({
1982
+ components: {
1983
+ Text: Text2 = defaultComponents.Text,
1984
+ Empty,
1985
+ Image: Image2 = defaultComponents.Image,
1986
+ UI = defaultComponents.UI,
1987
+ tools: { by_name = {}, Fallback: Fallback2 = void 0 } = {}
1988
+ } = {}
1989
+ }) => {
1990
+ const messageStore = useMessageStore();
1991
+ const threadRuntime = useThreadRuntime();
1992
+ const part = useContentPart();
1993
+ const type = part.type;
1994
+ switch (type) {
1995
+ case "text":
1996
+ if (part.status.type === "requires-action")
1997
+ throw new Error("Encountered unexpected requires-action status");
1998
+ if (part.part === EMPTY_CONTENT && !!Empty) {
1999
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Empty, { status: part.status });
2000
+ }
2001
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Text2, { ...part, part });
2002
+ case "image":
2003
+ if (part.status.type === "requires-action")
2004
+ throw new Error("Encountered unexpected requires-action status");
2005
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Image2, { ...part, part });
2006
+ case "ui":
2007
+ if (part.status.type === "requires-action")
2008
+ throw new Error("Encountered unexpected requires-action status");
2009
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, UI, { ...part, part });
2010
+ case "tool-call": {
2011
+ const Tool = by_name[part.toolName] || Fallback2;
2012
+ const addResult = (result) => threadRuntime.addToolResult({
2013
+ messageId: messageStore.getState().id,
2014
+ toolName: part.toolName,
2015
+ toolCallId: part.toolCallId,
2016
+ result
2017
+ });
2018
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ToolUIDisplay, { ...part, part, UI: Tool, addResult });
2019
+ }
2020
+ default:
2021
+ const unhandledType = type;
2022
+ throw new Error(`Unknown content part type: ${unhandledType}`);
2023
+ }
2024
+ };
2025
+ var MessageContentPartImpl = ({
2026
+ partIndex,
2027
+ components
2028
+ }) => {
2029
+ const messageRuntime = useMessageRuntime();
2030
+ const runtime = _react.useMemo.call(void 0,
2031
+ () => messageRuntime.unstable_getContentPartByIndex(partIndex),
2032
+ [messageRuntime, partIndex]
2033
+ );
2034
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ContentPartRuntimeProvider, { runtime, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, MessageContentPartComponent, { components }) });
2035
+ };
2036
+ var MessageContentPart = _react.memo.call(void 0,
2037
+ MessageContentPartImpl,
2038
+ (prev, next) => prev.partIndex === next.partIndex && _optionalChain([prev, 'access', _61 => _61.components, 'optionalAccess', _62 => _62.Text]) === _optionalChain([next, 'access', _63 => _63.components, 'optionalAccess', _64 => _64.Text]) && _optionalChain([prev, 'access', _65 => _65.components, 'optionalAccess', _66 => _66.Image]) === _optionalChain([next, 'access', _67 => _67.components, 'optionalAccess', _68 => _68.Image]) && _optionalChain([prev, 'access', _69 => _69.components, 'optionalAccess', _70 => _70.UI]) === _optionalChain([next, 'access', _71 => _71.components, 'optionalAccess', _72 => _72.UI]) && _optionalChain([prev, 'access', _73 => _73.components, 'optionalAccess', _74 => _74.tools]) === _optionalChain([next, 'access', _75 => _75.components, 'optionalAccess', _76 => _76.tools])
2039
+ );
2040
+ var MessagePrimitiveContent = ({
2041
+ components
2042
+ }) => {
2043
+ const contentLength = useMessage((s) => s.content.length) || 1;
2044
+ return Array.from({ length: contentLength }, (_, index) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, MessageContentPart, { partIndex: index, components }, index));
2045
+ };
2046
+ MessagePrimitiveContent.displayName = "MessagePrimitive.Content";
2047
+
2048
+ // src/primitives/message/MessageInProgress.tsx
2049
+ var MessagePrimitiveInProgress = () => {
2050
+ return null;
2051
+ };
2052
+ MessagePrimitiveInProgress.displayName = "MessagePrimitive.InProgress";
2053
+
2054
+ // src/primitives/message/MessageAttachments.tsx
2055
+
2056
+
2057
+ // src/context/react/AttachmentContext.ts
2058
+
2059
+ var AttachmentContext = _react.createContext.call(void 0,
2060
+ null
2061
+ );
2062
+ function useAttachmentContext(options) {
2063
+ const context = _react.useContext.call(void 0, AttachmentContext);
2064
+ if (!_optionalChain([options, 'optionalAccess', _77 => _77.optional]) && !context)
2065
+ throw new Error(
2066
+ "This component must be used within a ComposerPrimitive.Attachments or MessagePrimitive.Attachments component."
2067
+ );
2068
+ return context;
2069
+ }
2070
+ function useComposerAttachmentContext(options) {
2071
+ const context = useAttachmentContext(options);
2072
+ if (!context) return null;
2073
+ if (context.type !== "composer")
2074
+ throw new Error(
2075
+ "This component must be used within a ComposerPrimitive.Attachments component."
2076
+ );
2077
+ return context;
2078
+ }
2079
+ function useMessageAttachmentContext(options) {
2080
+ const context = useAttachmentContext(options);
2081
+ if (!context) return null;
2082
+ if (context.type !== "message")
2083
+ throw new Error(
2084
+ "This component must be used within a MessagePrimitive.Attachments component."
2085
+ );
2086
+ return context;
2087
+ }
2088
+ var { useAttachment, useAttachmentStore } = createContextStoreHook(
2089
+ useAttachmentContext,
2090
+ "useAttachment"
2091
+ );
2092
+ var {
2093
+ useAttachment: useComposerAttachment,
2094
+ useAttachmentStore: useComposerAttachmentStore
2095
+ } = createContextStoreHook(useComposerAttachmentContext, "useAttachment");
2096
+ var {
2097
+ useAttachment: useMessageAttachment,
2098
+ useAttachmentStore: useMessageAttachmentStore
2099
+ } = createContextStoreHook(useMessageAttachmentContext, "useAttachment");
2100
+
2101
+ // src/context/providers/MessageAttachmentProvider.tsx
2102
+
2103
+
2104
+
2105
+ var getAttachment = (message, useAttachment2, partIndex) => {
2106
+ if (message.role !== "user") return null;
2107
+ const attachments = message.attachments;
2108
+ const attachment = attachments[partIndex];
2109
+ if (!attachment) return null;
2110
+ const currentState = _optionalChain([useAttachment2, 'optionalAccess', _78 => _78.getState, 'call', _79 => _79()]);
2111
+ if (currentState && currentState.attachment === attachment) return null;
2112
+ return Object.freeze({ attachment });
2113
+ };
2114
+ var useMessageAttachmentContext2 = (partIndex) => {
2115
+ const messageStore = useMessageStore();
2116
+ const [context] = _react.useState.call(void 0,
2117
+ () => {
2118
+ const useAttachment2 = _zustand.create.call(void 0,
2119
+ () => getAttachment(messageStore.getState(), void 0, partIndex)
2120
+ );
2121
+ return { type: "message", useAttachment: useAttachment2 };
2122
+ }
2123
+ );
2124
+ _react.useEffect.call(void 0, () => {
2125
+ const syncAttachment = (messageState) => {
2126
+ const newState = getAttachment(
2127
+ messageState,
2128
+ context.useAttachment,
2129
+ partIndex
2130
+ );
2131
+ if (!newState) return;
2132
+ writableStore(context.useAttachment).setState(newState, true);
2133
+ };
2134
+ syncAttachment(messageStore.getState());
2135
+ return messageStore.subscribe(syncAttachment);
2136
+ }, [context, messageStore, partIndex]);
2137
+ return context;
2138
+ };
2139
+ var MessageAttachmentProvider = ({
2140
+ attachmentIndex: partIndex,
1901
2141
  children
1902
2142
  }) => {
1903
2143
  const context = useMessageAttachmentContext2(partIndex);
@@ -1910,11 +2150,11 @@ var getComponent = (components, attachment) => {
1910
2150
  const type = attachment.type;
1911
2151
  switch (type) {
1912
2152
  case "image":
1913
- return _nullishCoalesce(_optionalChain([components, 'optionalAccess', _47 => _47.Image]), () => ( _optionalChain([components, 'optionalAccess', _48 => _48.Attachment])));
2153
+ return _nullishCoalesce(_optionalChain([components, 'optionalAccess', _80 => _80.Image]), () => ( _optionalChain([components, 'optionalAccess', _81 => _81.Attachment])));
1914
2154
  case "document":
1915
- return _nullishCoalesce(_optionalChain([components, 'optionalAccess', _49 => _49.Document]), () => ( _optionalChain([components, 'optionalAccess', _50 => _50.Attachment])));
2155
+ return _nullishCoalesce(_optionalChain([components, 'optionalAccess', _82 => _82.Document]), () => ( _optionalChain([components, 'optionalAccess', _83 => _83.Attachment])));
1916
2156
  case "file":
1917
- return _nullishCoalesce(_optionalChain([components, 'optionalAccess', _51 => _51.File]), () => ( _optionalChain([components, 'optionalAccess', _52 => _52.Attachment])));
2157
+ return _nullishCoalesce(_optionalChain([components, 'optionalAccess', _84 => _84.File]), () => ( _optionalChain([components, 'optionalAccess', _85 => _85.Attachment])));
1918
2158
  default:
1919
2159
  const _exhaustiveCheck = type;
1920
2160
  throw new Error(`Unknown attachment type: ${_exhaustiveCheck}`);
@@ -1932,7 +2172,7 @@ var MessageAttachmentImpl = ({ components, attachmentIndex }) => {
1932
2172
  };
1933
2173
  var MessageAttachment = _react.memo.call(void 0,
1934
2174
  MessageAttachmentImpl,
1935
- (prev, next) => prev.attachmentIndex === next.attachmentIndex && _optionalChain([prev, 'access', _53 => _53.components, 'optionalAccess', _54 => _54.Image]) === _optionalChain([next, 'access', _55 => _55.components, 'optionalAccess', _56 => _56.Image]) && _optionalChain([prev, 'access', _57 => _57.components, 'optionalAccess', _58 => _58.Document]) === _optionalChain([next, 'access', _59 => _59.components, 'optionalAccess', _60 => _60.Document]) && _optionalChain([prev, 'access', _61 => _61.components, 'optionalAccess', _62 => _62.File]) === _optionalChain([next, 'access', _63 => _63.components, 'optionalAccess', _64 => _64.File]) && _optionalChain([prev, 'access', _65 => _65.components, 'optionalAccess', _66 => _66.Attachment]) === _optionalChain([next, 'access', _67 => _67.components, 'optionalAccess', _68 => _68.Attachment])
2175
+ (prev, next) => prev.attachmentIndex === next.attachmentIndex && _optionalChain([prev, 'access', _86 => _86.components, 'optionalAccess', _87 => _87.Image]) === _optionalChain([next, 'access', _88 => _88.components, 'optionalAccess', _89 => _89.Image]) && _optionalChain([prev, 'access', _90 => _90.components, 'optionalAccess', _91 => _91.Document]) === _optionalChain([next, 'access', _92 => _92.components, 'optionalAccess', _93 => _93.Document]) && _optionalChain([prev, 'access', _94 => _94.components, 'optionalAccess', _95 => _95.File]) === _optionalChain([next, 'access', _96 => _96.components, 'optionalAccess', _97 => _97.File]) && _optionalChain([prev, 'access', _98 => _98.components, 'optionalAccess', _99 => _99.Attachment]) === _optionalChain([next, 'access', _100 => _100.components, 'optionalAccess', _101 => _101.Attachment])
1936
2176
  );
1937
2177
  var MessagePrimitiveAttachments = ({ components }) => {
1938
2178
  const attachmentsCount = useMessage(({ message }) => {
@@ -2043,7 +2283,7 @@ var ComposerPrimitiveInput = _react.forwardRef.call(void 0,
2043
2283
  const { isRunning } = threadStore.getState();
2044
2284
  if (!isRunning) {
2045
2285
  e.preventDefault();
2046
- _optionalChain([textareaRef, 'access', _69 => _69.current, 'optionalAccess', _70 => _70.closest, 'call', _71 => _71("form"), 'optionalAccess', _72 => _72.requestSubmit, 'call', _73 => _73()]);
2286
+ _optionalChain([textareaRef, 'access', _102 => _102.current, 'optionalAccess', _103 => _103.closest, 'call', _104 => _104("form"), 'optionalAccess', _105 => _105.requestSubmit, 'call', _106 => _106()]);
2047
2287
  }
2048
2288
  }
2049
2289
  };
@@ -2111,7 +2351,7 @@ var ComposerPrimitiveAddAttachment = createActionButton(
2111
2351
  var getAttachment2 = ({ attachments }, useAttachment2, partIndex) => {
2112
2352
  const attachment = attachments[partIndex];
2113
2353
  if (!attachment) return null;
2114
- const currentState = _optionalChain([useAttachment2, 'optionalAccess', _74 => _74.getState, 'call', _75 => _75()]);
2354
+ const currentState = _optionalChain([useAttachment2, 'optionalAccess', _107 => _107.getState, 'call', _108 => _108()]);
2115
2355
  if (currentState && currentState.attachment === attachment) return null;
2116
2356
  return Object.freeze({ attachment });
2117
2357
  };
@@ -2151,11 +2391,11 @@ var getComponent2 = (components, attachment) => {
2151
2391
  const type = attachment.type;
2152
2392
  switch (type) {
2153
2393
  case "image":
2154
- return _nullishCoalesce(_optionalChain([components, 'optionalAccess', _76 => _76.Image]), () => ( _optionalChain([components, 'optionalAccess', _77 => _77.Attachment])));
2394
+ return _nullishCoalesce(_optionalChain([components, 'optionalAccess', _109 => _109.Image]), () => ( _optionalChain([components, 'optionalAccess', _110 => _110.Attachment])));
2155
2395
  case "document":
2156
- return _nullishCoalesce(_optionalChain([components, 'optionalAccess', _78 => _78.Document]), () => ( _optionalChain([components, 'optionalAccess', _79 => _79.Attachment])));
2396
+ return _nullishCoalesce(_optionalChain([components, 'optionalAccess', _111 => _111.Document]), () => ( _optionalChain([components, 'optionalAccess', _112 => _112.Attachment])));
2157
2397
  case "file":
2158
- return _nullishCoalesce(_optionalChain([components, 'optionalAccess', _80 => _80.File]), () => ( _optionalChain([components, 'optionalAccess', _81 => _81.Attachment])));
2398
+ return _nullishCoalesce(_optionalChain([components, 'optionalAccess', _113 => _113.File]), () => ( _optionalChain([components, 'optionalAccess', _114 => _114.Attachment])));
2159
2399
  default:
2160
2400
  const _exhaustiveCheck = type;
2161
2401
  throw new Error(`Unknown attachment type: ${_exhaustiveCheck}`);
@@ -2173,7 +2413,7 @@ var ComposerAttachmentImpl = ({ components, attachmentIndex }) => {
2173
2413
  };
2174
2414
  var ComposerAttachment = _react.memo.call(void 0,
2175
2415
  ComposerAttachmentImpl,
2176
- (prev, next) => prev.attachmentIndex === next.attachmentIndex && _optionalChain([prev, 'access', _82 => _82.components, 'optionalAccess', _83 => _83.Image]) === _optionalChain([next, 'access', _84 => _84.components, 'optionalAccess', _85 => _85.Image]) && _optionalChain([prev, 'access', _86 => _86.components, 'optionalAccess', _87 => _87.Document]) === _optionalChain([next, 'access', _88 => _88.components, 'optionalAccess', _89 => _89.Document]) && _optionalChain([prev, 'access', _90 => _90.components, 'optionalAccess', _91 => _91.File]) === _optionalChain([next, 'access', _92 => _92.components, 'optionalAccess', _93 => _93.File]) && _optionalChain([prev, 'access', _94 => _94.components, 'optionalAccess', _95 => _95.Attachment]) === _optionalChain([next, 'access', _96 => _96.components, 'optionalAccess', _97 => _97.Attachment])
2416
+ (prev, next) => prev.attachmentIndex === next.attachmentIndex && _optionalChain([prev, 'access', _115 => _115.components, 'optionalAccess', _116 => _116.Image]) === _optionalChain([next, 'access', _117 => _117.components, 'optionalAccess', _118 => _118.Image]) && _optionalChain([prev, 'access', _119 => _119.components, 'optionalAccess', _120 => _120.Document]) === _optionalChain([next, 'access', _121 => _121.components, 'optionalAccess', _122 => _122.Document]) && _optionalChain([prev, 'access', _123 => _123.components, 'optionalAccess', _124 => _124.File]) === _optionalChain([next, 'access', _125 => _125.components, 'optionalAccess', _126 => _126.File]) && _optionalChain([prev, 'access', _127 => _127.components, 'optionalAccess', _128 => _128.Attachment]) === _optionalChain([next, 'access', _129 => _129.components, 'optionalAccess', _130 => _130.Attachment])
2177
2417
  );
2178
2418
  var ComposerPrimitiveAttachments = ({ components }) => {
2179
2419
  const attachmentsCount = useThreadComposer((s) => s.attachments.length);
@@ -2327,1177 +2567,836 @@ var useThreadViewportAutoScroll = ({
2327
2567
  const div = divRef.current;
2328
2568
  if (!div) return;
2329
2569
  const isAtBottom = threadViewportStore.getState().isAtBottom;
2330
- const newIsAtBottom = div.scrollHeight - div.scrollTop <= div.clientHeight + 1;
2331
- if (!newIsAtBottom && lastScrollTop.current < div.scrollTop) {
2332
- } else {
2333
- if (newIsAtBottom) {
2334
- isScrollingToBottomRef.current = false;
2335
- }
2336
- if (newIsAtBottom !== isAtBottom) {
2337
- writableStore(threadViewportStore).setState({
2338
- isAtBottom: newIsAtBottom
2339
- });
2340
- }
2341
- }
2342
- lastScrollTop.current = div.scrollTop;
2343
- };
2344
- const resizeRef = useOnResizeContent(() => {
2345
- if (isScrollingToBottomRef.current || threadViewportStore.getState().isAtBottom) {
2346
- scrollToBottom("instant");
2347
- }
2348
- handleScroll();
2349
- });
2350
- const scrollRef = useManagedRef((el) => {
2351
- el.addEventListener("scroll", handleScroll);
2352
- return () => {
2353
- el.removeEventListener("scroll", handleScroll);
2354
- };
2355
- });
2356
- const autoScrollRef = _reactcomposerefs.useComposedRefs.call(void 0, resizeRef, scrollRef, divRef);
2357
- useOnScrollToBottom(() => {
2358
- scrollToBottom("auto");
2359
- });
2360
- return autoScrollRef;
2361
- };
2362
-
2363
- // src/primitives/thread/ThreadViewport.tsx
2364
-
2365
- var ThreadPrimitiveViewport = _react.forwardRef.call(void 0, ({ autoScroll, children, ...rest }, forwardedRef) => {
2366
- const autoScrollRef = useThreadViewportAutoScroll({
2367
- autoScroll
2368
- });
2369
- const ref = _reactcomposerefs.useComposedRefs.call(void 0, forwardedRef, autoScrollRef);
2370
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactprimitive.Primitive.div, { ...rest, ref, children });
2371
- });
2372
- ThreadPrimitiveViewport.displayName = "ThreadPrimitive.Viewport";
2373
-
2374
- // src/primitives/thread/ThreadMessages.tsx
2375
-
2376
-
2377
- // src/context/providers/MessageProvider.tsx
2378
-
2379
-
2380
-
2381
- // src/context/stores/EditComposer.ts
2382
-
2383
- var makeEditComposerStore = ({
2384
- onEdit,
2385
- onSend
2386
- }) => _zustand.create.call(void 0, )((set, get) => ({
2387
- type: "edit",
2388
- get value() {
2389
- return get().text;
2390
- },
2391
- setValue(value) {
2392
- get().setText(value);
2393
- },
2394
- text: "",
2395
- setText: (text) => {
2396
- set({ text, isEmpty: text.trim().length === 0 });
2397
- },
2398
- canCancel: false,
2399
- isEditing: false,
2400
- isEmpty: true,
2401
- edit: () => {
2402
- const text = onEdit();
2403
- set({
2404
- isEditing: true,
2405
- canCancel: true,
2406
- isEmpty: text.trim().length === 0,
2407
- text
2408
- });
2409
- },
2410
- send: () => {
2411
- const text = get().text;
2412
- set({ isEditing: false, canCancel: false });
2413
- onSend(text);
2414
- },
2415
- cancel: () => {
2416
- set({ isEditing: false, canCancel: false });
2417
- }
2418
- }));
2419
-
2420
- // src/context/stores/MessageUtils.ts
2421
-
2422
- var makeMessageUtilsStore = () => _zustand.create.call(void 0, (set) => {
2423
- let utterance = null;
2424
- return {
2425
- isCopied: false,
2426
- setIsCopied: (value) => {
2427
- set({ isCopied: value });
2428
- },
2429
- isHovering: false,
2430
- setIsHovering: (value) => {
2431
- set({ isHovering: value });
2432
- },
2433
- isSpeaking: false,
2434
- stopSpeaking: () => {
2435
- _optionalChain([utterance, 'optionalAccess', _98 => _98.cancel, 'call', _99 => _99()]);
2436
- },
2437
- addUtterance: (utt) => {
2438
- utterance = utt;
2439
- set({ isSpeaking: true });
2440
- utt.onEnd(() => {
2441
- set({ isSpeaking: false });
2442
- });
2443
- },
2444
- submittedFeedback: null,
2445
- setSubmittedFeedback: (feedback) => {
2446
- set({ submittedFeedback: feedback });
2447
- }
2448
- };
2449
- });
2450
-
2451
- // src/context/providers/MessageProvider.tsx
2452
-
2453
- var getIsLast = (messages, message) => {
2454
- return _optionalChain([messages, 'access', _100 => _100[messages.length - 1], 'optionalAccess', _101 => _101.id]) === message.id;
2455
- };
2456
- var getMessageState = (messages, getBranches, useMessage2, messageIndex) => {
2457
- const parentId = _nullishCoalesce(_optionalChain([messages, 'access', _102 => _102[messageIndex - 1], 'optionalAccess', _103 => _103.id]), () => ( null));
2458
- const message = messages[messageIndex];
2459
- if (!message) return null;
2460
- const isLast = getIsLast(messages, message);
2461
- const branches = getBranches(message.id);
2462
- const currentState = _optionalChain([useMessage2, 'optionalAccess', _104 => _104.getState, 'call', _105 => _105()]);
2463
- if (currentState && currentState.message === message && currentState.parentId === parentId && currentState.branches === branches && currentState.isLast === isLast)
2464
- return null;
2465
- return Object.freeze({
2466
- message,
2467
- parentId,
2468
- branches,
2469
- isLast
2470
- });
2471
- };
2472
- var useMessageContext2 = (messageIndex) => {
2473
- const threadMessagesStore = useThreadMessagesStore();
2474
- const threadRuntime = useThreadRuntime();
2475
- const [context] = _react.useState.call(void 0, () => {
2476
- const useMessage2 = _zustand.create.call(void 0,
2477
- () => getMessageState(
2478
- threadMessagesStore.getState(),
2479
- threadRuntime.getBranches.bind(threadRuntime),
2480
- void 0,
2481
- messageIndex
2482
- )
2483
- );
2484
- const useMessageUtils2 = makeMessageUtilsStore();
2485
- const useEditComposer2 = makeEditComposerStore({
2486
- onEdit: () => {
2487
- const message = useMessage2.getState().message;
2488
- const text = getThreadMessageText(message);
2489
- return text;
2490
- },
2491
- onSend: (text) => {
2492
- const { message, parentId } = useMessage2.getState();
2493
- const previousText = getThreadMessageText(message);
2494
- if (previousText === text) return;
2495
- const nonTextParts = message.content.filter(
2496
- (part) => part.type !== "text" && part.type !== "ui"
2497
- );
2498
- threadRuntime.append({
2499
- parentId,
2500
- role: message.role,
2501
- content: [{ type: "text", text }, ...nonTextParts],
2502
- attachments: message.attachments
2503
- });
2504
- }
2505
- });
2506
- return { useMessage: useMessage2, useMessageUtils: useMessageUtils2, useEditComposer: useEditComposer2 };
2507
- });
2508
- _react.useEffect.call(void 0, () => {
2509
- const syncMessage = (thread) => {
2510
- const newState = getMessageState(
2511
- thread,
2512
- threadRuntime.getBranches.bind(threadRuntime),
2513
- context.useMessage,
2514
- messageIndex
2515
- );
2516
- if (!newState) return;
2517
- writableStore(context.useMessage).setState(newState, true);
2518
- };
2519
- syncMessage(threadMessagesStore.getState());
2520
- return threadMessagesStore.subscribe(syncMessage);
2521
- }, [threadMessagesStore, threadRuntime, context, messageIndex]);
2522
- return context;
2523
- };
2524
- var MessageProvider = ({
2525
- messageIndex,
2526
- children
2527
- }) => {
2528
- const context = useMessageContext2(messageIndex);
2529
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, MessageContext.Provider, { value: context, children });
2530
- };
2531
-
2532
- // src/primitives/thread/ThreadMessages.tsx
2533
-
2534
- var isComponentsSame = (prev, next) => {
2535
- return prev.Message === next.Message && prev.EditComposer === next.EditComposer && prev.UserEditComposer === next.UserEditComposer && prev.AssistantEditComposer === next.AssistantEditComposer && prev.SystemEditComposer === next.SystemEditComposer && prev.UserMessage === next.UserMessage && prev.AssistantMessage === next.AssistantMessage && prev.SystemMessage === next.SystemMessage;
2536
- };
2537
- var DEFAULT_SYSTEM_MESSAGE = () => null;
2538
- var getComponent3 = (components, role, isEditing) => {
2539
- switch (role) {
2540
- case "user":
2541
- if (isEditing) {
2542
- return _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(components.UserEditComposer, () => ( components.EditComposer)), () => ( components.UserMessage)), () => ( components.Message));
2543
- } else {
2544
- return _nullishCoalesce(components.UserMessage, () => ( components.Message));
2545
- }
2546
- case "assistant":
2547
- if (isEditing) {
2548
- return _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(components.AssistantEditComposer, () => ( components.EditComposer)), () => ( components.AssistantMessage)), () => ( components.Message));
2549
- } else {
2550
- return _nullishCoalesce(components.AssistantMessage, () => ( components.Message));
2551
- }
2552
- case "system":
2553
- if (isEditing) {
2554
- return _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(components.SystemEditComposer, () => ( components.EditComposer)), () => ( components.SystemMessage)), () => ( components.Message));
2555
- } else {
2556
- return _nullishCoalesce(components.SystemMessage, () => ( DEFAULT_SYSTEM_MESSAGE));
2557
- }
2558
- default:
2559
- const _exhaustiveCheck = role;
2560
- throw new Error(`Unknown message role: ${_exhaustiveCheck}`);
2561
- }
2562
- };
2563
- var ThreadMessageComponent = ({
2564
- components
2565
- }) => {
2566
- const role = useMessage((m) => m.message.role);
2567
- const isEditing = useEditComposer((c) => c.isEditing);
2568
- const Component = getComponent3(components, role, isEditing);
2569
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Component, {});
2570
- };
2571
- var ThreadMessageImpl = ({
2572
- messageIndex,
2573
- components
2574
- }) => {
2575
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, MessageProvider, { messageIndex, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ThreadMessageComponent, { components }) });
2576
- };
2577
- var ThreadMessage = _react.memo.call(void 0,
2578
- ThreadMessageImpl,
2579
- (prev, next) => prev.messageIndex === next.messageIndex && isComponentsSame(prev.components, next.components)
2580
- );
2581
- var ThreadPrimitiveMessagesImpl = ({
2582
- components
2583
- }) => {
2584
- const messagesLength = useThreadMessages((t) => t.length);
2585
- if (messagesLength === 0) return null;
2586
- return Array.from({ length: messagesLength }, (_, index) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ThreadMessage, { messageIndex: index, components }, index));
2587
- };
2588
- ThreadPrimitiveMessagesImpl.displayName = "ThreadPrimitive.Messages";
2589
- var ThreadPrimitiveMessages = _react.memo.call(void 0,
2590
- ThreadPrimitiveMessagesImpl,
2591
- (prev, next) => isComponentsSame(prev.components, next.components)
2592
- );
2593
-
2594
- // src/primitives/thread/ThreadScrollToBottom.tsx
2595
- var ThreadPrimitiveScrollToBottom = createActionButton(
2596
- "ThreadPrimitive.ScrollToBottom",
2597
- useThreadScrollToBottom
2598
- );
2599
-
2600
- // src/primitives/thread/ThreadSuggestion.tsx
2601
- var ThreadPrimitiveSuggestion = createActionButton(
2602
- "ThreadPrimitive.Suggestion",
2603
- useThreadSuggestion,
2604
- ["prompt", "autoSend", "method"]
2605
- );
2606
-
2607
- // src/runtimes/core/subscribeToMainThread.ts
2608
- var subscribeToMainThread = (runtime, callback) => {
2609
- let first = true;
2610
- let cleanup;
2611
- const inner = () => {
2612
- _optionalChain([cleanup, 'optionalCall', _106 => _106()]);
2613
- cleanup = runtime.thread.subscribe(callback);
2614
- if (!first) {
2615
- callback();
2616
- }
2617
- first = false;
2618
- };
2619
- const unsubscribe = runtime.subscribe(inner);
2620
- inner();
2621
- return () => {
2622
- unsubscribe();
2623
- _optionalChain([cleanup, 'optionalCall', _107 => _107()]);
2624
- };
2625
- };
2626
-
2627
- // src/runtimes/local/useLocalRuntime.tsx
2628
-
2629
-
2630
- // src/runtimes/core/BaseAssistantRuntimeCore.tsx
2631
- var BaseAssistantRuntimeCore = (_class2 = class {
2632
- constructor(_thread) {;_class2.prototype.__init5.call(this);_class2.prototype.__init6.call(this);
2633
- this._thread = _thread;
2634
- this._thread = _thread;
2635
- }
2636
- get thread() {
2637
- return this._thread;
2638
- }
2639
- set thread(thread) {
2640
- this._thread = thread;
2641
- this.subscriptionHandler();
2642
- }
2643
- __init5() {this._subscriptions = /* @__PURE__ */ new Set()}
2644
- subscribe(callback) {
2645
- this._subscriptions.add(callback);
2646
- return () => this._subscriptions.delete(callback);
2647
- }
2648
- __init6() {this.subscriptionHandler = () => {
2649
- for (const callback of this._subscriptions) callback();
2650
- }}
2651
- }, _class2);
2652
-
2653
- // src/internal.ts
2654
- var internal_exports = {};
2655
- _chunkPZ5AY32Cjs.__export.call(void 0, internal_exports, {
2656
- AssistantRuntime: () => AssistantRuntime,
2657
- BaseAssistantRuntimeCore: () => BaseAssistantRuntimeCore,
2658
- BaseThreadRuntimeComposerCore: () => BaseThreadComposerRuntimeCore,
2659
- MessageRepository: () => MessageRepository,
2660
- ProxyConfigProvider: () => ProxyConfigProvider,
2661
- ThreadRuntime: () => ThreadRuntime,
2662
- TooltipIconButton: () => TooltipIconButton,
2663
- generateId: () => generateId,
2664
- useSmooth: () => useSmooth,
2665
- useSmoothStatus: () => useSmoothStatus,
2666
- withSmoothContextProvider: () => withSmoothContextProvider
2667
- });
2668
-
2669
- // src/runtimes/utils/BaseThreadComposerRuntimeCore.tsx
2670
- var BaseThreadComposerRuntimeCore = (_class3 = class {
2671
- constructor(runtime) {;_class3.prototype.__init7.call(this);_class3.prototype.__init8.call(this);_class3.prototype.__init9.call(this);_class3.prototype.__init10.call(this);
2672
- this.runtime = runtime;
2673
- }
2674
-
2675
- __init7() {this.attachmentAccept = "*"}
2676
- get isEmpty() {
2677
- return !this.text.trim() && !this.attachments.length;
2678
- }
2679
- setAttachmentAdapter(adapter) {
2680
- this._attachmentAdapter = adapter;
2681
- const accept = _nullishCoalesce(_optionalChain([adapter, 'optionalAccess', _108 => _108.accept]), () => ( "*"));
2682
- if (this.attachmentAccept !== accept) {
2683
- this.attachmentAccept = accept;
2684
- return true;
2685
- }
2686
- return false;
2687
- }
2688
- __init8() {this._attachments = []}
2689
- get attachments() {
2690
- return this._attachments;
2691
- }
2692
- async addAttachment(file) {
2693
- if (!this._attachmentAdapter)
2694
- throw new Error("Attachments are not supported");
2695
- const attachment = await this._attachmentAdapter.add({ file });
2696
- this._attachments = [...this._attachments, attachment];
2697
- this.notifySubscribers();
2698
- }
2699
- async removeAttachment(attachmentId) {
2700
- if (!this._attachmentAdapter)
2701
- throw new Error("Attachments are not supported");
2702
- const index = this._attachments.findIndex((a) => a.id === attachmentId);
2703
- if (index === -1) throw new Error("Attachment not found");
2704
- const attachment = this._attachments[index];
2705
- await this._attachmentAdapter.remove(attachment);
2706
- this._attachments = this._attachments.toSpliced(index, 1);
2707
- this.notifySubscribers();
2708
- }
2709
- __init9() {this._text = ""}
2710
- get text() {
2711
- return this._text;
2712
- }
2713
- setText(value) {
2714
- this._text = value;
2715
- this.notifySubscribers();
2716
- }
2717
- reset() {
2718
- this._text = "";
2719
- this._attachments = [];
2720
- this.notifySubscribers();
2721
- }
2722
- async send() {
2723
- const attachments = this._attachmentAdapter ? await Promise.all(
2724
- this.attachments.map(
2725
- async (a) => await this._attachmentAdapter.send(a)
2726
- )
2727
- ) : [];
2728
- this.runtime.append({
2729
- parentId: _nullishCoalesce(_optionalChain([this, 'access', _109 => _109.runtime, 'access', _110 => _110.messages, 'access', _111 => _111.at, 'call', _112 => _112(-1), 'optionalAccess', _113 => _113.id]), () => ( null)),
2730
- role: "user",
2731
- content: this.text ? [{ type: "text", text: this.text }] : [],
2732
- attachments
2733
- });
2734
- this.reset();
2735
- }
2736
- __init10() {this._subscriptions = /* @__PURE__ */ new Set()}
2737
- notifySubscribers() {
2738
- for (const callback of this._subscriptions) callback();
2739
- }
2740
- subscribe(callback) {
2741
- this._subscriptions.add(callback);
2742
- return () => this._subscriptions.delete(callback);
2743
- }
2744
- }, _class3);
2745
-
2746
- // src/utils/ProxyConfigProvider.ts
2747
- var ProxyConfigProvider = (_class4 = class {constructor() { _class4.prototype.__init11.call(this); }
2748
- __init11() {this._providers = /* @__PURE__ */ new Set()}
2749
- getModelConfig() {
2750
- return _chunk5KIEXJRKjs.mergeModelConfigs.call(void 0, this._providers);
2751
- }
2752
- registerModelConfigProvider(provider) {
2753
- this._providers.add(provider);
2754
- return () => {
2755
- this._providers.delete(provider);
2756
- };
2757
- }
2758
- }, _class4);
2759
-
2760
- // src/utils/idUtils.tsx
2761
- var _nonsecure = require('nanoid/non-secure');
2762
- var generateId = _nonsecure.customAlphabet.call(void 0,
2763
- "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
2764
- 7
2765
- );
2766
- var optimisticPrefix = "__optimistic__";
2767
- var generateOptimisticId = () => `${optimisticPrefix}${generateId()}`;
2768
-
2769
- // src/runtimes/edge/converters/fromCoreMessage.ts
2770
- var fromCoreMessages = (message) => {
2771
- return message.map((message2) => fromCoreMessage(message2));
2772
- };
2773
- var fromCoreMessage = (message, {
2774
- id = generateId(),
2775
- status = { type: "complete", reason: "unknown" },
2776
- attachments = []
2777
- } = {}) => {
2778
- const commonProps = {
2779
- id,
2780
- createdAt: /* @__PURE__ */ new Date()
2781
- };
2782
- const role = message.role;
2783
- switch (role) {
2784
- case "assistant":
2785
- return {
2786
- ...commonProps,
2787
- role,
2788
- content: message.content.map((part) => {
2789
- if (part.type === "tool-call") {
2790
- return {
2791
- ...part,
2792
- argsText: JSON.stringify(part.args)
2793
- };
2794
- }
2795
- return part;
2796
- }),
2797
- status
2798
- };
2799
- case "user":
2800
- return {
2801
- ...commonProps,
2802
- role,
2803
- content: message.content,
2804
- attachments
2805
- };
2806
- case "system":
2807
- return {
2808
- ...commonProps,
2809
- role,
2810
- content: message.content
2811
- };
2812
- default: {
2813
- const unsupportedRole = role;
2814
- throw new Error(`Unknown message role: ${unsupportedRole}`);
2815
- }
2816
- }
2817
- };
2818
-
2819
- // src/runtimes/utils/MessageRepository.tsx
2820
- var findHead = (message) => {
2821
- if (message.next) return findHead(message.next);
2822
- if ("current" in message) return message;
2823
- return null;
2824
- };
2825
- var MessageRepository = (_class5 = class {constructor() { _class5.prototype.__init12.call(this);_class5.prototype.__init13.call(this);_class5.prototype.__init14.call(this); }
2826
- __init12() {this.messages = /* @__PURE__ */ new Map()}
2827
- // message_id -> item
2828
- __init13() {this.head = null}
2829
- __init14() {this.root = {
2830
- children: [],
2831
- next: null
2832
- }}
2833
- performOp(newParent, child, operation) {
2834
- const parentOrRoot = _nullishCoalesce(child.prev, () => ( this.root));
2835
- const newParentOrRoot = _nullishCoalesce(newParent, () => ( this.root));
2836
- if (operation === "relink" && parentOrRoot === newParentOrRoot) return;
2837
- if (operation !== "link") {
2838
- parentOrRoot.children = parentOrRoot.children.filter(
2839
- (m) => m !== child.current.id
2840
- );
2841
- if (parentOrRoot.next === child) {
2842
- const fallbackId = parentOrRoot.children.at(-1);
2843
- const fallback = fallbackId ? this.messages.get(fallbackId) : null;
2844
- if (fallback === void 0) {
2845
- throw new Error(
2846
- "MessageRepository(performOp/cut): Fallback sibling message not found. This is likely an internal bug in assistant-ui."
2847
- );
2848
- }
2849
- parentOrRoot.next = fallback;
2850
- }
2851
- }
2852
- if (operation !== "cut") {
2853
- for (let current = newParent; current; current = current.prev) {
2854
- if (current.current.id === child.current.id) {
2855
- throw new Error(
2856
- "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."
2857
- );
2858
- }
2859
- }
2860
- newParentOrRoot.children = [
2861
- ...newParentOrRoot.children,
2862
- child.current.id
2863
- ];
2864
- if (findHead(child) === this.head || newParentOrRoot.next === null) {
2865
- newParentOrRoot.next = child;
2866
- }
2867
- child.prev = newParent;
2868
- }
2869
- }
2870
- getMessages() {
2871
- const messages = new Array(_nullishCoalesce(_optionalChain([this, 'access', _114 => _114.head, 'optionalAccess', _115 => _115.level]), () => ( 0)));
2872
- for (let current = this.head; current; current = current.prev) {
2873
- messages[current.level] = current.current;
2874
- }
2875
- return messages;
2876
- }
2877
- addOrUpdateMessage(parentId, message) {
2878
- const existingItem = this.messages.get(message.id);
2879
- const prev = parentId ? this.messages.get(parentId) : null;
2880
- if (prev === void 0)
2881
- throw new Error(
2882
- "MessageRepository(addOrUpdateMessage): Parent message not found. This is likely an internal bug in assistant-ui."
2883
- );
2884
- if (existingItem) {
2885
- existingItem.current = message;
2886
- this.performOp(prev, existingItem, "relink");
2887
- return;
2888
- }
2889
- const newItem = {
2890
- prev,
2891
- current: message,
2892
- next: null,
2893
- children: [],
2894
- level: prev ? prev.level + 1 : 0
2895
- };
2896
- this.messages.set(message.id, newItem);
2897
- this.performOp(prev, newItem, "link");
2898
- if (this.head === prev) {
2899
- this.head = newItem;
2900
- }
2901
- }
2902
- getMessage(messageId) {
2903
- const message = this.messages.get(messageId);
2904
- if (!message)
2905
- throw new Error(
2906
- "MessageRepository(updateMessage): Message not found. This is likely an internal bug in assistant-ui."
2907
- );
2908
- return {
2909
- parentId: _nullishCoalesce(_optionalChain([message, 'access', _116 => _116.prev, 'optionalAccess', _117 => _117.current, 'access', _118 => _118.id]), () => ( null)),
2910
- message: message.current
2911
- };
2912
- }
2913
- appendOptimisticMessage(parentId, message) {
2914
- let optimisticId;
2915
- do {
2916
- optimisticId = generateOptimisticId();
2917
- } while (this.messages.has(optimisticId));
2918
- this.addOrUpdateMessage(
2919
- parentId,
2920
- fromCoreMessage(message, {
2921
- id: optimisticId,
2922
- status: { type: "running" }
2923
- })
2924
- );
2925
- return optimisticId;
2926
- }
2927
- deleteMessage(messageId, replacementId) {
2928
- const message = this.messages.get(messageId);
2929
- if (!message)
2930
- throw new Error(
2931
- "MessageRepository(deleteMessage): Optimistic message not found. This is likely an internal bug in assistant-ui."
2932
- );
2933
- const replacement = replacementId === void 0 ? message.prev : replacementId === null ? null : this.messages.get(replacementId);
2934
- if (replacement === void 0)
2935
- throw new Error(
2936
- "MessageRepository(deleteMessage): Replacement not found. This is likely an internal bug in assistant-ui."
2937
- );
2938
- for (const child of message.children) {
2939
- const childMessage = this.messages.get(child);
2940
- if (!childMessage)
2941
- throw new Error(
2942
- "MessageRepository(deleteMessage): Child message not found. This is likely an internal bug in assistant-ui."
2943
- );
2944
- this.performOp(replacement, childMessage, "relink");
2945
- }
2946
- this.performOp(null, message, "cut");
2947
- this.messages.delete(messageId);
2948
- if (this.head === message) {
2949
- this.head = findHead(_nullishCoalesce(replacement, () => ( this.root)));
2950
- }
2951
- }
2952
- getBranches(messageId) {
2953
- const message = this.messages.get(messageId);
2954
- if (!message)
2955
- throw new Error(
2956
- "MessageRepository(getBranches): Message not found. This is likely an internal bug in assistant-ui."
2957
- );
2958
- const { children } = _nullishCoalesce(message.prev, () => ( this.root));
2959
- return children;
2960
- }
2961
- switchToBranch(messageId) {
2962
- const message = this.messages.get(messageId);
2963
- if (!message)
2964
- throw new Error(
2965
- "MessageRepository(switchToBranch): Branch not found. This is likely an internal bug in assistant-ui."
2966
- );
2967
- const prevOrRoot = _nullishCoalesce(message.prev, () => ( this.root));
2968
- prevOrRoot.next = message;
2969
- this.head = findHead(message);
2970
- }
2971
- resetHead(messageId) {
2972
- if (messageId === null) {
2973
- this.head = null;
2974
- return;
2975
- }
2976
- const message = this.messages.get(messageId);
2977
- if (!message)
2978
- throw new Error(
2979
- "MessageRepository(resetHead): Branch not found. This is likely an internal bug in assistant-ui."
2980
- );
2981
- this.head = message;
2982
- for (let current = message; current; current = current.prev) {
2983
- if (current.prev) {
2984
- current.prev.next = current;
2570
+ const newIsAtBottom = div.scrollHeight - div.scrollTop <= div.clientHeight + 1;
2571
+ if (!newIsAtBottom && lastScrollTop.current < div.scrollTop) {
2572
+ } else {
2573
+ if (newIsAtBottom) {
2574
+ isScrollingToBottomRef.current = false;
2575
+ }
2576
+ if (newIsAtBottom !== isAtBottom) {
2577
+ writableStore(threadViewportStore).setState({
2578
+ isAtBottom: newIsAtBottom
2579
+ });
2985
2580
  }
2986
2581
  }
2987
- }
2988
- export() {
2989
- const exportItems = [];
2990
- for (const [, message] of this.messages) {
2991
- exportItems.push({
2992
- message: message.current,
2993
- parentId: _nullishCoalesce(_optionalChain([message, 'access', _119 => _119.prev, 'optionalAccess', _120 => _120.current, 'access', _121 => _121.id]), () => ( null))
2994
- });
2582
+ lastScrollTop.current = div.scrollTop;
2583
+ };
2584
+ const resizeRef = useOnResizeContent(() => {
2585
+ if (isScrollingToBottomRef.current || threadViewportStore.getState().isAtBottom) {
2586
+ scrollToBottom("instant");
2995
2587
  }
2996
- return {
2997
- headId: _nullishCoalesce(_optionalChain([this, 'access', _122 => _122.head, 'optionalAccess', _123 => _123.current, 'access', _124 => _124.id]), () => ( null)),
2998
- messages: exportItems
2588
+ handleScroll();
2589
+ });
2590
+ const scrollRef = useManagedRef((el) => {
2591
+ el.addEventListener("scroll", handleScroll);
2592
+ return () => {
2593
+ el.removeEventListener("scroll", handleScroll);
2999
2594
  };
3000
- }
3001
- import({ headId, messages }) {
3002
- for (const { message, parentId } of messages) {
3003
- this.addOrUpdateMessage(parentId, message);
3004
- }
3005
- this.resetHead(_nullishCoalesce(_nullishCoalesce(headId, () => ( _optionalChain([messages, 'access', _125 => _125.at, 'call', _126 => _126(-1), 'optionalAccess', _127 => _127.message, 'access', _128 => _128.id]))), () => ( null)));
3006
- }
3007
- }, _class5);
2595
+ });
2596
+ const autoScrollRef = _reactcomposerefs.useComposedRefs.call(void 0, resizeRef, scrollRef, divRef);
2597
+ useOnScrollToBottom(() => {
2598
+ scrollToBottom("auto");
2599
+ });
2600
+ return autoScrollRef;
2601
+ };
3008
2602
 
3009
- // src/ui/base/tooltip-icon-button.tsx
2603
+ // src/primitives/thread/ThreadViewport.tsx
2604
+
2605
+ var ThreadPrimitiveViewport = _react.forwardRef.call(void 0, ({ autoScroll, children, ...rest }, forwardedRef) => {
2606
+ const autoScrollRef = useThreadViewportAutoScroll({
2607
+ autoScroll
2608
+ });
2609
+ const ref = _reactcomposerefs.useComposedRefs.call(void 0, forwardedRef, autoScrollRef);
2610
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, _reactprimitive.Primitive.div, { ...rest, ref, children });
2611
+ });
2612
+ ThreadPrimitiveViewport.displayName = "ThreadPrimitive.Viewport";
3010
2613
 
2614
+ // src/primitives/thread/ThreadMessages.tsx
3011
2615
 
3012
- // src/ui/base/tooltip.tsx
3013
- var _reacttooltip = require('@radix-ui/react-tooltip'); var TooltipPrimitive = _interopRequireWildcard(_reacttooltip);
3014
2616
 
3015
- // src/ui/utils/withDefaults.tsx
2617
+ // src/context/providers/MessageRuntimeProvider.tsx
3016
2618
 
3017
2619
 
3018
2620
 
3019
- var _classnames = require('classnames'); var _classnames2 = _interopRequireDefault(_classnames);
2621
+ // src/context/stores/MessageUtils.ts
3020
2622
 
3021
- var withDefaultProps = ({
3022
- className,
3023
- ...defaultProps
3024
- }) => ({ className: classNameProp, ...props }) => {
2623
+ var makeMessageUtilsStore = () => _zustand.create.call(void 0, (set) => {
2624
+ let utterance = null;
3025
2625
  return {
3026
- className: _classnames2.default.call(void 0, className, classNameProp),
3027
- ...defaultProps,
3028
- ...props
3029
- };
3030
- };
3031
- var withDefaults = (Component, defaultProps) => {
3032
- const getProps = withDefaultProps(defaultProps);
3033
- const WithDefaults = _react.forwardRef.call(void 0,
3034
- (props, ref) => {
3035
- const ComponentAsAny = Component;
3036
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ComponentAsAny, { ...getProps(props), ref });
2626
+ isCopied: false,
2627
+ setIsCopied: (value) => {
2628
+ set({ isCopied: value });
2629
+ },
2630
+ isHovering: false,
2631
+ setIsHovering: (value) => {
2632
+ set({ isHovering: value });
2633
+ },
2634
+ isSpeaking: false,
2635
+ stopSpeaking: () => {
2636
+ _optionalChain([utterance, 'optionalAccess', _131 => _131.cancel, 'call', _132 => _132()]);
2637
+ },
2638
+ addUtterance: (utt) => {
2639
+ utterance = utt;
2640
+ set({ isSpeaking: true });
2641
+ utt.onEnd(() => {
2642
+ set({ isSpeaking: false });
2643
+ });
2644
+ },
2645
+ submittedFeedback: null,
2646
+ setSubmittedFeedback: (feedback) => {
2647
+ set({ submittedFeedback: feedback });
3037
2648
  }
3038
- );
3039
- WithDefaults.displayName = "withDefaults(" + (typeof Component === "string" ? Component : Component.displayName) + ")";
3040
- return WithDefaults;
3041
- };
3042
-
3043
- // src/ui/base/tooltip.tsx
3044
-
3045
- var Tooltip = (props) => {
3046
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TooltipPrimitive.Provider, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TooltipPrimitive.Root, { ...props }) });
3047
- };
3048
- Tooltip.displayName = "Tooltip";
3049
- var TooltipTrigger = TooltipPrimitive.Trigger;
3050
- var TooltipContent = withDefaults(TooltipPrimitive.Content, {
3051
- sideOffset: 4,
3052
- className: "aui-tooltip-content"
2649
+ };
3053
2650
  });
3054
- TooltipContent.displayName = "TooltipContent";
3055
2651
 
3056
- // src/ui/base/button.tsx
3057
- var _classvarianceauthority = require('class-variance-authority');
2652
+ // src/context/providers/MessageRuntimeProvider.tsx
3058
2653
 
2654
+ var useMessageRuntimeStore = (runtime) => {
2655
+ const [store] = _react.useState.call(void 0, () => _zustand.create.call(void 0, () => runtime));
2656
+ _react.useEffect.call(void 0, () => {
2657
+ writableStore(store).setState(runtime, true);
2658
+ }, [runtime, store]);
2659
+ return store;
2660
+ };
2661
+ var useMessageStore2 = (runtime) => {
2662
+ const [store] = _react.useState.call(void 0, () => _zustand.create.call(void 0, () => runtime.getState()));
2663
+ _react.useEffect.call(void 0, () => {
2664
+ const updateState = () => writableStore(store).setState(runtime.getState(), true);
2665
+ updateState();
2666
+ return runtime.subscribe(updateState);
2667
+ }, [runtime, store]);
2668
+ return store;
2669
+ };
2670
+ var useMessageUtilsStore2 = () => {
2671
+ const [store] = _react.useState.call(void 0, () => makeMessageUtilsStore());
2672
+ return store;
2673
+ };
2674
+ var useEditComposerStore2 = (useMessageRuntime2) => {
2675
+ const runtime = useMessageRuntime2.getState().composer;
2676
+ const [store] = _react.useState.call(void 0, () => _zustand.create.call(void 0, () => runtime.getState()));
2677
+ _react.useEffect.call(void 0, () => {
2678
+ const updateState = () => writableStore(store).setState(runtime.getState());
2679
+ updateState();
2680
+ return runtime.subscribe(updateState);
2681
+ }, [runtime, store]);
2682
+ return store;
2683
+ };
2684
+ var MessageRuntimeProvider = ({
2685
+ runtime,
2686
+ children
2687
+ }) => {
2688
+ const useMessageRuntime2 = useMessageRuntimeStore(runtime);
2689
+ const useMessage2 = useMessageStore2(runtime);
2690
+ const useMessageUtils2 = useMessageUtilsStore2();
2691
+ const useEditComposer2 = useEditComposerStore2(useMessageRuntime2);
2692
+ const [context] = _react.useState.call(void 0, () => {
2693
+ return { useMessageRuntime: useMessageRuntime2, useMessage: useMessage2, useMessageUtils: useMessageUtils2, useEditComposer: useEditComposer2 };
2694
+ });
2695
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, MessageContext.Provider, { value: context, children });
2696
+ };
3059
2697
 
2698
+ // src/primitives/thread/ThreadMessages.tsx
3060
2699
 
3061
- var buttonVariants = _classvarianceauthority.cva.call(void 0, "aui-button", {
3062
- variants: {
3063
- variant: {
3064
- default: "aui-button-primary",
3065
- outline: "aui-button-outline",
3066
- ghost: "aui-button-ghost"
3067
- },
3068
- size: {
3069
- default: "aui-button-medium",
3070
- icon: "aui-button-icon"
3071
- }
3072
- },
3073
- defaultVariants: {
3074
- variant: "default",
3075
- size: "default"
3076
- }
3077
- });
3078
- var Button = _react.forwardRef.call(void 0,
3079
- ({ className, variant, size, ...props }, ref) => {
3080
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3081
- _reactprimitive.Primitive.button,
3082
- {
3083
- className: buttonVariants({ variant, size, className }),
3084
- ...props,
3085
- ref
2700
+ var isComponentsSame = (prev, next) => {
2701
+ return prev.Message === next.Message && prev.EditComposer === next.EditComposer && prev.UserEditComposer === next.UserEditComposer && prev.AssistantEditComposer === next.AssistantEditComposer && prev.SystemEditComposer === next.SystemEditComposer && prev.UserMessage === next.UserMessage && prev.AssistantMessage === next.AssistantMessage && prev.SystemMessage === next.SystemMessage;
2702
+ };
2703
+ var DEFAULT_SYSTEM_MESSAGE = () => null;
2704
+ var getComponent3 = (components, role, isEditing) => {
2705
+ switch (role) {
2706
+ case "user":
2707
+ if (isEditing) {
2708
+ return _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(components.UserEditComposer, () => ( components.EditComposer)), () => ( components.UserMessage)), () => ( components.Message));
2709
+ } else {
2710
+ return _nullishCoalesce(components.UserMessage, () => ( components.Message));
3086
2711
  }
3087
- );
2712
+ case "assistant":
2713
+ if (isEditing) {
2714
+ return _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(components.AssistantEditComposer, () => ( components.EditComposer)), () => ( components.AssistantMessage)), () => ( components.Message));
2715
+ } else {
2716
+ return _nullishCoalesce(components.AssistantMessage, () => ( components.Message));
2717
+ }
2718
+ case "system":
2719
+ if (isEditing) {
2720
+ return _nullishCoalesce(_nullishCoalesce(_nullishCoalesce(components.SystemEditComposer, () => ( components.EditComposer)), () => ( components.SystemMessage)), () => ( components.Message));
2721
+ } else {
2722
+ return _nullishCoalesce(components.SystemMessage, () => ( DEFAULT_SYSTEM_MESSAGE));
2723
+ }
2724
+ default:
2725
+ const _exhaustiveCheck = role;
2726
+ throw new Error(`Unknown message role: ${_exhaustiveCheck}`);
3088
2727
  }
2728
+ };
2729
+ var ThreadMessageComponent = ({
2730
+ components
2731
+ }) => {
2732
+ const role = useMessage((m) => m.role);
2733
+ const isEditing = useEditComposer((c) => c.isEditing);
2734
+ const Component = getComponent3(components, role, isEditing);
2735
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Component, {});
2736
+ };
2737
+ var ThreadMessageImpl = ({
2738
+ messageIndex,
2739
+ components
2740
+ }) => {
2741
+ const threadRuntime = useThreadRuntime();
2742
+ const runtime = _react.useMemo.call(void 0,
2743
+ () => threadRuntime.unstable_getMesssageByIndex(messageIndex),
2744
+ [threadRuntime, messageIndex]
2745
+ );
2746
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, MessageRuntimeProvider, { runtime, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ThreadMessageComponent, { components }) });
2747
+ };
2748
+ var ThreadMessage = _react.memo.call(void 0,
2749
+ ThreadMessageImpl,
2750
+ (prev, next) => prev.messageIndex === next.messageIndex && isComponentsSame(prev.components, next.components)
2751
+ );
2752
+ var ThreadPrimitiveMessagesImpl = ({
2753
+ components
2754
+ }) => {
2755
+ const messagesLength = useThread((t) => t.messages.length);
2756
+ if (messagesLength === 0) return null;
2757
+ return Array.from({ length: messagesLength }, (_, index) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ThreadMessage, { messageIndex: index, components }, index));
2758
+ };
2759
+ ThreadPrimitiveMessagesImpl.displayName = "ThreadPrimitive.Messages";
2760
+ var ThreadPrimitiveMessages = _react.memo.call(void 0,
2761
+ ThreadPrimitiveMessagesImpl,
2762
+ (prev, next) => isComponentsSame(prev.components, next.components)
3089
2763
  );
3090
- Button.displayName = "Button";
3091
2764
 
3092
- // src/ui/base/tooltip-icon-button.tsx
2765
+ // src/primitives/thread/ThreadScrollToBottom.tsx
2766
+ var ThreadPrimitiveScrollToBottom = createActionButton(
2767
+ "ThreadPrimitive.ScrollToBottom",
2768
+ useThreadScrollToBottom
2769
+ );
3093
2770
 
3094
- var TooltipIconButton = _react.forwardRef.call(void 0, ({ children, tooltip, side = "bottom", ...rest }, ref) => {
3095
- return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Tooltip, { children: [
3096
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TooltipTrigger, { asChild: true, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Button, { variant: "ghost", size: "icon", ...rest, ref, children: [
3097
- children,
3098
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "aui-sr-only", children: tooltip })
3099
- ] }) }),
3100
- /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TooltipContent, { side, children: tooltip })
3101
- ] });
3102
- });
3103
- TooltipIconButton.displayName = "TooltipIconButton";
2771
+ // src/primitives/thread/ThreadSuggestion.tsx
2772
+ var ThreadPrimitiveSuggestion = createActionButton(
2773
+ "ThreadPrimitive.Suggestion",
2774
+ useThreadSuggestion,
2775
+ ["prompt", "autoSend", "method"]
2776
+ );
2777
+
2778
+ // src/runtimes/core/subscribeToMainThread.ts
2779
+ var subscribeToMainThread = (runtime, callback) => {
2780
+ let first = true;
2781
+ let cleanup;
2782
+ const inner = () => {
2783
+ _optionalChain([cleanup, 'optionalCall', _133 => _133()]);
2784
+ cleanup = runtime.thread.subscribe(callback);
2785
+ if (!first) {
2786
+ callback();
2787
+ }
2788
+ first = false;
2789
+ };
2790
+ const unsubscribe = runtime.subscribe(inner);
2791
+ inner();
2792
+ return () => {
2793
+ unsubscribe();
2794
+ _optionalChain([cleanup, 'optionalCall', _134 => _134()]);
2795
+ };
2796
+ };
3104
2797
 
3105
- // src/api/subscribable/BaseSubject.ts
3106
- var BaseSubject = (_class6 = class {constructor() { _class6.prototype.__init15.call(this); }
3107
- __init15() {this._subscriptions = /* @__PURE__ */ new Set()}
3108
-
3109
- get isConnected() {
3110
- return !!this._connection;
2798
+ // src/runtimes/local/useLocalRuntime.tsx
2799
+
2800
+
2801
+ // src/runtimes/core/BaseAssistantRuntimeCore.tsx
2802
+ var BaseAssistantRuntimeCore = (_class6 = class {
2803
+ constructor(_thread) {;_class6.prototype.__init9.call(this);_class6.prototype.__init10.call(this);
2804
+ this._thread = _thread;
2805
+ this._thread = _thread;
3111
2806
  }
3112
- notifySubscribers() {
3113
- for (const callback of this._subscriptions) callback();
2807
+ get thread() {
2808
+ return this._thread;
3114
2809
  }
3115
- _updateConnection() {
3116
- if (this._subscriptions.size > 0) {
3117
- if (this._connection) return;
3118
- this._connection = this._connect();
3119
- } else {
3120
- _optionalChain([this, 'access', _129 => _129._connection, 'optionalCall', _130 => _130()]);
3121
- this._connection = void 0;
3122
- }
2810
+ set thread(thread) {
2811
+ this._thread = thread;
2812
+ this.subscriptionHandler();
3123
2813
  }
2814
+ __init9() {this._subscriptions = /* @__PURE__ */ new Set()}
3124
2815
  subscribe(callback) {
3125
2816
  this._subscriptions.add(callback);
3126
- this._updateConnection();
3127
- return () => {
3128
- this._subscriptions.delete(callback);
3129
- this._updateConnection();
3130
- };
2817
+ return () => this._subscriptions.delete(callback);
3131
2818
  }
2819
+ __init10() {this.subscriptionHandler = () => {
2820
+ for (const callback of this._subscriptions) callback();
2821
+ }}
3132
2822
  }, _class6);
3133
2823
 
3134
- // src/api/subscribable/NestedSubscriptionSubject.ts
3135
- var NestedSubscriptionSubject = class extends BaseSubject {
3136
- constructor(binding) {
3137
- super();
3138
- this.binding = binding;
2824
+ // src/internal.ts
2825
+ var internal_exports = {};
2826
+ _chunkPZ5AY32Cjs.__export.call(void 0, internal_exports, {
2827
+ AssistantRuntime: () => AssistantRuntime,
2828
+ BaseAssistantRuntimeCore: () => BaseAssistantRuntimeCore,
2829
+ DefaultThreadComposerRuntimeCore: () => DefaultThreadComposerRuntimeCore,
2830
+ MessageRepository: () => MessageRepository,
2831
+ ProxyConfigProvider: () => ProxyConfigProvider,
2832
+ ThreadRuntime: () => ThreadRuntime,
2833
+ TooltipIconButton: () => TooltipIconButton,
2834
+ generateId: () => generateId,
2835
+ useSmooth: () => useSmooth,
2836
+ useSmoothStatus: () => useSmoothStatus,
2837
+ withSmoothContextProvider: () => withSmoothContextProvider
2838
+ });
2839
+
2840
+ // src/runtimes/composer/BaseComposerRuntimeCore.tsx
2841
+ var BaseComposerRuntimeCore = (_class7 = class {constructor() { _class7.prototype.__init11.call(this);_class7.prototype.__init12.call(this);_class7.prototype.__init13.call(this);_class7.prototype.__init14.call(this);_class7.prototype.__init15.call(this); }
2842
+ __init11() {this.isEditing = true}
2843
+ __init12() {this.attachmentAccept = "*"}
2844
+ __init13() {this._attachments = []}
2845
+ set attachments(value) {
2846
+ this._attachments = value;
2847
+ this.notifySubscribers();
3139
2848
  }
3140
- getState() {
3141
- return this.binding.getState();
2849
+ get attachments() {
2850
+ return this._attachments;
3142
2851
  }
3143
- _connect() {
3144
- const callback = () => {
3145
- this.notifySubscribers();
3146
- };
3147
- let lastState = this.binding.getState();
3148
- let innerUnsubscribe = lastState.subscribe(callback);
3149
- const onRuntimeUpdate = () => {
3150
- const newState = this.binding.getState();
3151
- if (newState === lastState) return;
3152
- lastState = newState;
3153
- _optionalChain([innerUnsubscribe, 'optionalCall', _131 => _131()]);
3154
- innerUnsubscribe = this.binding.getState().subscribe(callback);
3155
- callback();
3156
- };
3157
- const outerUnsubscribe = this.binding.subscribe(onRuntimeUpdate);
3158
- return () => {
3159
- _optionalChain([outerUnsubscribe, 'optionalCall', _132 => _132()]);
3160
- innerUnsubscribe();
3161
- };
2852
+ get isEmpty() {
2853
+ return !this.text.trim() && !this.attachments.length;
3162
2854
  }
3163
- };
3164
-
3165
- // src/api/AssistantRuntime.ts
3166
- var AssistantRuntime = class {
3167
- constructor(_core, CustomThreadRuntime) {
3168
- this._core = _core;
3169
- this.thread = new CustomThreadRuntime(
3170
- new NestedSubscriptionSubject({
3171
- getState: () => this._core.thread,
3172
- subscribe: (callback) => this._core.subscribe(callback)
3173
- })
3174
- );
2855
+ __init14() {this._text = ""}
2856
+ get text() {
2857
+ return this._text;
2858
+ }
2859
+ setText(value) {
2860
+ this._text = value;
2861
+ this.notifySubscribers();
2862
+ }
2863
+ reset() {
2864
+ this._text = "";
2865
+ this._attachments = [];
2866
+ this.notifySubscribers();
2867
+ }
2868
+ async send() {
2869
+ const attachments = this._attachmentAdapter ? await Promise.all(
2870
+ this.attachments.map(
2871
+ async (a) => await this._attachmentAdapter.send(a)
2872
+ )
2873
+ ) : [];
2874
+ const message = {
2875
+ role: "user",
2876
+ content: this.text ? [{ type: "text", text: this.text }] : [],
2877
+ attachments
2878
+ };
2879
+ this.reset();
2880
+ this.handleSend(message);
3175
2881
  }
3176
2882
 
3177
- switchToNewThread() {
3178
- return this._core.switchToNewThread();
2883
+ setAttachmentAdapter(adapter) {
2884
+ this._attachmentAdapter = adapter;
2885
+ const accept = _nullishCoalesce(_optionalChain([adapter, 'optionalAccess', _135 => _135.accept]), () => ( "*"));
2886
+ if (this.attachmentAccept !== accept) {
2887
+ this.attachmentAccept = accept;
2888
+ this.notifySubscribers();
2889
+ }
3179
2890
  }
3180
- switchToThread(threadId) {
3181
- return this._core.switchToThread(threadId);
2891
+ async addAttachment(file) {
2892
+ if (!this._attachmentAdapter)
2893
+ throw new Error("Attachments are not supported");
2894
+ const attachment = await this._attachmentAdapter.add({ file });
2895
+ this._attachments = [...this._attachments, attachment];
2896
+ this.notifySubscribers();
3182
2897
  }
3183
- registerModelConfigProvider(provider) {
3184
- return this._core.registerModelConfigProvider(provider);
2898
+ async removeAttachment(attachmentId) {
2899
+ if (!this._attachmentAdapter)
2900
+ throw new Error("Attachments are not supported");
2901
+ const index = this._attachments.findIndex((a) => a.id === attachmentId);
2902
+ if (index === -1) throw new Error("Attachment not found");
2903
+ const attachment = this._attachments[index];
2904
+ await this._attachmentAdapter.remove(attachment);
2905
+ this._attachments = this._attachments.toSpliced(index, 1);
2906
+ this.notifySubscribers();
2907
+ }
2908
+ __init15() {this._subscriptions = /* @__PURE__ */ new Set()}
2909
+ notifySubscribers() {
2910
+ for (const callback of this._subscriptions) callback();
3185
2911
  }
3186
- // TODO events for thread switching
3187
- /**
3188
- * @deprecated Thread is now static and never gets updated. This will be removed in 0.6.0.
3189
- */
3190
2912
  subscribe(callback) {
3191
- return this._core.subscribe(callback);
2913
+ this._subscriptions.add(callback);
2914
+ return () => this._subscriptions.delete(callback);
3192
2915
  }
3193
- };
2916
+ }, _class7);
3194
2917
 
3195
- // src/api/ContentPartRuntime.ts
3196
- var ContentPartRuntime = class {
3197
- constructor(contentBinding, messageApi, threadApi) {
3198
- this.contentBinding = contentBinding;
3199
- this.messageApi = messageApi;
3200
- this.threadApi = threadApi;
2918
+ // src/runtimes/composer/DefaultThreadComposerRuntimeCore.tsx
2919
+ var DefaultThreadComposerRuntimeCore = (_class8 = class extends BaseComposerRuntimeCore {
2920
+ constructor(runtime) {
2921
+ super();_class8.prototype.__init16.call(this);;
2922
+ this.runtime = runtime;
2923
+ this.connect();
3201
2924
  }
3202
- getState() {
3203
- return this.contentBinding.getState();
2925
+ __init16() {this._canCancel = false}
2926
+ get canCancel() {
2927
+ return this._canCancel;
3204
2928
  }
3205
- addToolResult(result) {
3206
- const message = this.messageApi.getState();
3207
- if (!message) throw new Error("Message is not available");
3208
- const state = this.contentBinding.getState();
3209
- if (!state) throw new Error("Content part is not available");
3210
- if (state.part.type !== "tool-call")
3211
- throw new Error("Tried to add tool result to non-tool content part");
3212
- const toolName = state.part.toolName;
3213
- const toolCallId = state.part.toolCallId;
3214
- this.threadApi.getState().addToolResult({
3215
- messageId: message.message.id,
3216
- toolName,
3217
- toolCallId,
3218
- result
2929
+ connect() {
2930
+ return this.runtime.subscribe(() => {
2931
+ if (this.canCancel !== this.runtime.capabilities.cancel) {
2932
+ this._canCancel = this.runtime.capabilities.cancel;
2933
+ this.notifySubscribers();
2934
+ }
3219
2935
  });
3220
2936
  }
3221
- };
2937
+ async handleSend(message) {
2938
+ this.runtime.append({
2939
+ ...message,
2940
+ parentId: _nullishCoalesce(_optionalChain([this, 'access', _136 => _136.runtime, 'access', _137 => _137.messages, 'access', _138 => _138.at, 'call', _139 => _139(-1), 'optionalAccess', _140 => _140.id]), () => ( null))
2941
+ });
2942
+ }
2943
+ async cancel() {
2944
+ this.runtime.cancelRun();
2945
+ }
2946
+ }, _class8);
3222
2947
 
3223
- // src/api/subscribable/shallowEqual.ts
3224
- function shallowEqual(objA, objB) {
3225
- if (objA === void 0 && objB === void 0) return true;
3226
- if (objA === void 0) return false;
3227
- if (objB === void 0) return false;
3228
- for (const key of Object.keys(objA)) {
3229
- const valueA = objA[key];
3230
- const valueB = objB[key];
3231
- if (!Object.is(valueA, valueB)) return false;
2948
+ // src/utils/ProxyConfigProvider.ts
2949
+ var ProxyConfigProvider = (_class9 = class {constructor() { _class9.prototype.__init17.call(this); }
2950
+ __init17() {this._providers = /* @__PURE__ */ new Set()}
2951
+ getModelConfig() {
2952
+ return _chunk5KIEXJRKjs.mergeModelConfigs.call(void 0, this._providers);
3232
2953
  }
3233
- return true;
3234
- }
2954
+ registerModelConfigProvider(provider) {
2955
+ this._providers.add(provider);
2956
+ return () => {
2957
+ this._providers.delete(provider);
2958
+ };
2959
+ }
2960
+ }, _class9);
3235
2961
 
3236
- // src/api/subscribable/ShallowMemoizeSubject.ts
3237
- var ShallowMemoizeSubject = (_class7 = class extends BaseSubject {
3238
- constructor(binding) {
3239
- super();_class7.prototype.__init16.call(this);;
3240
- this.binding = binding;
3241
- const state = binding.getState();
3242
- if (state === void 0)
3243
- throw new Error("Entry not available in the store");
3244
- this._previousState = state;
2962
+ // src/utils/idUtils.tsx
2963
+ var _nonsecure = require('nanoid/non-secure');
2964
+ var generateId = _nonsecure.customAlphabet.call(void 0,
2965
+ "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
2966
+ 7
2967
+ );
2968
+ var optimisticPrefix = "__optimistic__";
2969
+ var generateOptimisticId = () => `${optimisticPrefix}${generateId()}`;
2970
+
2971
+ // src/runtimes/edge/converters/fromCoreMessage.ts
2972
+ var fromCoreMessages = (message) => {
2973
+ return message.map((message2) => fromCoreMessage(message2));
2974
+ };
2975
+ var fromCoreMessage = (message, {
2976
+ id = generateId(),
2977
+ status = { type: "complete", reason: "unknown" },
2978
+ attachments = []
2979
+ } = {}) => {
2980
+ const commonProps = {
2981
+ id,
2982
+ createdAt: /* @__PURE__ */ new Date()
2983
+ };
2984
+ const role = message.role;
2985
+ switch (role) {
2986
+ case "assistant":
2987
+ return {
2988
+ ...commonProps,
2989
+ role,
2990
+ content: message.content.map((part) => {
2991
+ if (part.type === "tool-call") {
2992
+ return {
2993
+ ...part,
2994
+ argsText: JSON.stringify(part.args)
2995
+ };
2996
+ }
2997
+ return part;
2998
+ }),
2999
+ status
3000
+ };
3001
+ case "user":
3002
+ return {
3003
+ ...commonProps,
3004
+ role,
3005
+ content: message.content,
3006
+ attachments
3007
+ };
3008
+ case "system":
3009
+ return {
3010
+ ...commonProps,
3011
+ role,
3012
+ content: message.content
3013
+ };
3014
+ default: {
3015
+ const unsupportedRole = role;
3016
+ throw new Error(`Unknown message role: ${unsupportedRole}`);
3017
+ }
3245
3018
  }
3246
-
3247
- __init16() {this.getState = () => {
3248
- if (!this.isConnected) this._syncState();
3249
- return this._previousState;
3019
+ };
3020
+
3021
+ // src/runtimes/utils/MessageRepository.tsx
3022
+ var findHead = (message) => {
3023
+ if (message.next) return findHead(message.next);
3024
+ if ("current" in message) return message;
3025
+ return null;
3026
+ };
3027
+ var MessageRepository = (_class10 = class {constructor() { _class10.prototype.__init18.call(this);_class10.prototype.__init19.call(this);_class10.prototype.__init20.call(this); }
3028
+ __init18() {this.messages = /* @__PURE__ */ new Map()}
3029
+ // message_id -> item
3030
+ __init19() {this.head = null}
3031
+ __init20() {this.root = {
3032
+ children: [],
3033
+ next: null
3250
3034
  }}
3251
- _syncState() {
3252
- const state = this.binding.getState();
3253
- if (state === void 0) return false;
3254
- if (shallowEqual(state, this._previousState)) return false;
3255
- this._previousState = state;
3256
- return true;
3257
- }
3258
- _connect() {
3259
- const callback = () => {
3260
- if (this._syncState()) {
3261
- this.notifySubscribers();
3035
+ performOp(newParent, child, operation) {
3036
+ const parentOrRoot = _nullishCoalesce(child.prev, () => ( this.root));
3037
+ const newParentOrRoot = _nullishCoalesce(newParent, () => ( this.root));
3038
+ if (operation === "relink" && parentOrRoot === newParentOrRoot) return;
3039
+ if (operation !== "link") {
3040
+ parentOrRoot.children = parentOrRoot.children.filter(
3041
+ (m) => m !== child.current.id
3042
+ );
3043
+ if (parentOrRoot.next === child) {
3044
+ const fallbackId = parentOrRoot.children.at(-1);
3045
+ const fallback = fallbackId ? this.messages.get(fallbackId) : null;
3046
+ if (fallback === void 0) {
3047
+ throw new Error(
3048
+ "MessageRepository(performOp/cut): Fallback sibling message not found. This is likely an internal bug in assistant-ui."
3049
+ );
3050
+ }
3051
+ parentOrRoot.next = fallback;
3262
3052
  }
3263
- };
3264
- return this.binding.subscribe(callback);
3265
- }
3266
- }, _class7);
3267
-
3268
- // src/api/MessageRuntime.ts
3269
- var MessageState = class {
3270
- constructor(snapshot) {
3271
- this.snapshot = snapshot;
3272
- }
3273
- /**
3274
- * @deprecated Replace `.message.content` with `.content` etc. This will be removed in 0.6.0.
3275
- */
3276
- get message() {
3277
- return this.snapshot.message;
3278
- }
3279
- get id() {
3280
- return this.snapshot.message.id;
3281
- }
3282
- get createdAt() {
3283
- return this.snapshot.message.createdAt;
3284
- }
3285
- get role() {
3286
- return this.snapshot.message.role;
3287
- }
3288
- get content() {
3289
- return this.snapshot.message.content;
3290
- }
3291
- get attachments() {
3292
- return this.snapshot.message.attachments;
3293
- }
3294
- get metadata() {
3295
- return this.snapshot.message.metadata;
3296
- }
3297
- get status() {
3298
- return this.snapshot.message.status;
3299
- }
3300
- get parentId() {
3301
- return this.snapshot.parentId;
3053
+ }
3054
+ if (operation !== "cut") {
3055
+ for (let current = newParent; current; current = current.prev) {
3056
+ if (current.current.id === child.current.id) {
3057
+ throw new Error(
3058
+ "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."
3059
+ );
3060
+ }
3061
+ }
3062
+ newParentOrRoot.children = [
3063
+ ...newParentOrRoot.children,
3064
+ child.current.id
3065
+ ];
3066
+ if (findHead(child) === this.head || newParentOrRoot.next === null) {
3067
+ newParentOrRoot.next = child;
3068
+ }
3069
+ child.prev = newParent;
3070
+ }
3302
3071
  }
3303
- get isLast() {
3304
- return this.snapshot.isLast;
3072
+ getMessages() {
3073
+ const messages2 = new Array(_nullishCoalesce(_optionalChain([this, 'access', _141 => _141.head, 'optionalAccess', _142 => _142.level]), () => ( 0)));
3074
+ for (let current = this.head; current; current = current.prev) {
3075
+ messages2[current.level] = current.current;
3076
+ }
3077
+ return messages2;
3305
3078
  }
3306
- get branches() {
3307
- return this.snapshot.branches;
3079
+ addOrUpdateMessage(parentId, message) {
3080
+ const existingItem = this.messages.get(message.id);
3081
+ const prev = parentId ? this.messages.get(parentId) : null;
3082
+ if (prev === void 0)
3083
+ throw new Error(
3084
+ "MessageRepository(addOrUpdateMessage): Parent message not found. This is likely an internal bug in assistant-ui."
3085
+ );
3086
+ if (existingItem) {
3087
+ existingItem.current = message;
3088
+ this.performOp(prev, existingItem, "relink");
3089
+ return;
3090
+ }
3091
+ const newItem = {
3092
+ prev,
3093
+ current: message,
3094
+ next: null,
3095
+ children: [],
3096
+ level: prev ? prev.level + 1 : 0
3097
+ };
3098
+ this.messages.set(message.id, newItem);
3099
+ this.performOp(prev, newItem, "link");
3100
+ if (this.head === prev) {
3101
+ this.head = newItem;
3102
+ }
3308
3103
  }
3309
- get branchNumber() {
3310
- return this.snapshot.branchNumber;
3104
+ getMessage(messageId) {
3105
+ const message = this.messages.get(messageId);
3106
+ if (!message)
3107
+ throw new Error(
3108
+ "MessageRepository(updateMessage): Message not found. This is likely an internal bug in assistant-ui."
3109
+ );
3110
+ return {
3111
+ parentId: _nullishCoalesce(_optionalChain([message, 'access', _143 => _143.prev, 'optionalAccess', _144 => _144.current, 'access', _145 => _145.id]), () => ( null)),
3112
+ message: message.current
3113
+ };
3311
3114
  }
3312
- get branchCount() {
3313
- return this.snapshot.branchCount;
3115
+ appendOptimisticMessage(parentId, message) {
3116
+ let optimisticId;
3117
+ do {
3118
+ optimisticId = generateOptimisticId();
3119
+ } while (this.messages.has(optimisticId));
3120
+ this.addOrUpdateMessage(
3121
+ parentId,
3122
+ fromCoreMessage(message, {
3123
+ id: optimisticId,
3124
+ status: { type: "running" }
3125
+ })
3126
+ );
3127
+ return optimisticId;
3314
3128
  }
3315
- };
3316
- var MessageRuntime = class {
3317
- constructor(_core, _threadBinding) {
3318
- this._core = _core;
3319
- this._threadBinding = _threadBinding;
3129
+ deleteMessage(messageId, replacementId) {
3130
+ const message = this.messages.get(messageId);
3131
+ if (!message)
3132
+ throw new Error(
3133
+ "MessageRepository(deleteMessage): Optimistic message not found. This is likely an internal bug in assistant-ui."
3134
+ );
3135
+ const replacement = replacementId === void 0 ? message.prev : replacementId === null ? null : this.messages.get(replacementId);
3136
+ if (replacement === void 0)
3137
+ throw new Error(
3138
+ "MessageRepository(deleteMessage): Replacement not found. This is likely an internal bug in assistant-ui."
3139
+ );
3140
+ for (const child of message.children) {
3141
+ const childMessage = this.messages.get(child);
3142
+ if (!childMessage)
3143
+ throw new Error(
3144
+ "MessageRepository(deleteMessage): Child message not found. This is likely an internal bug in assistant-ui."
3145
+ );
3146
+ this.performOp(replacement, childMessage, "relink");
3147
+ }
3148
+ this.performOp(null, message, "cut");
3149
+ this.messages.delete(messageId);
3150
+ if (this.head === message) {
3151
+ this.head = findHead(_nullishCoalesce(replacement, () => ( this.root)));
3152
+ }
3320
3153
  }
3321
- getState() {
3322
- return new MessageState(this._core.getState());
3154
+ getBranches(messageId) {
3155
+ const message = this.messages.get(messageId);
3156
+ if (!message)
3157
+ throw new Error(
3158
+ "MessageRepository(getBranches): Message not found. This is likely an internal bug in assistant-ui."
3159
+ );
3160
+ const { children } = _nullishCoalesce(message.prev, () => ( this.root));
3161
+ return children;
3323
3162
  }
3324
- // TODO improve type
3325
- edit(message) {
3326
- const state = this._core.getState();
3327
- if (!state) throw new Error("Message is not available");
3328
- this._threadBinding.getState().append({
3329
- ...message,
3330
- parentId: state.parentId
3331
- });
3163
+ switchToBranch(messageId) {
3164
+ const message = this.messages.get(messageId);
3165
+ if (!message)
3166
+ throw new Error(
3167
+ "MessageRepository(switchToBranch): Branch not found. This is likely an internal bug in assistant-ui."
3168
+ );
3169
+ const prevOrRoot = _nullishCoalesce(message.prev, () => ( this.root));
3170
+ prevOrRoot.next = message;
3171
+ this.head = findHead(message);
3332
3172
  }
3333
- reload() {
3334
- const state = this._core.getState();
3335
- if (!state) throw new Error("Message is not available");
3336
- this._threadBinding.getState().startRun(state.parentId);
3173
+ resetHead(messageId) {
3174
+ if (messageId === null) {
3175
+ this.head = null;
3176
+ return;
3177
+ }
3178
+ const message = this.messages.get(messageId);
3179
+ if (!message)
3180
+ throw new Error(
3181
+ "MessageRepository(resetHead): Branch not found. This is likely an internal bug in assistant-ui."
3182
+ );
3183
+ this.head = message;
3184
+ for (let current = message; current; current = current.prev) {
3185
+ if (current.prev) {
3186
+ current.prev.next = current;
3187
+ }
3188
+ }
3337
3189
  }
3338
- speak() {
3339
- const state = this._core.getState();
3340
- if (!state) throw new Error("Message is not available");
3341
- this._threadBinding.getState().speak(state.message.id);
3190
+ export() {
3191
+ const exportItems = [];
3192
+ for (const [, message] of this.messages) {
3193
+ exportItems.push({
3194
+ message: message.current,
3195
+ parentId: _nullishCoalesce(_optionalChain([message, 'access', _146 => _146.prev, 'optionalAccess', _147 => _147.current, 'access', _148 => _148.id]), () => ( null))
3196
+ });
3197
+ }
3198
+ return {
3199
+ headId: _nullishCoalesce(_optionalChain([this, 'access', _149 => _149.head, 'optionalAccess', _150 => _150.current, 'access', _151 => _151.id]), () => ( null)),
3200
+ messages: exportItems
3201
+ };
3342
3202
  }
3343
- submitFeedback({ type }) {
3344
- const state = this._core.getState();
3345
- if (!state) throw new Error("Message is not available");
3346
- this._threadBinding.getState().submitFeedback({
3347
- messageId: state.message.id,
3348
- type
3349
- });
3203
+ import({ headId, messages: messages2 }) {
3204
+ for (const { message, parentId } of messages2) {
3205
+ this.addOrUpdateMessage(parentId, message);
3206
+ }
3207
+ this.resetHead(_nullishCoalesce(_nullishCoalesce(headId, () => ( _optionalChain([messages2, 'access', _152 => _152.at, 'call', _153 => _153(-1), 'optionalAccess', _154 => _154.message, 'access', _155 => _155.id]))), () => ( null)));
3350
3208
  }
3351
- switchToBranch({
3352
- position,
3353
- branchId
3354
- }) {
3355
- const state = this._core.getState();
3356
- if (!state) throw new Error("Message is not available");
3357
- if (branchId && position) {
3358
- throw new Error("May not specify both branchId and position");
3359
- } else if (!branchId && !position) {
3360
- throw new Error("Must specify either branchId or position");
3209
+ }, _class10);
3210
+
3211
+ // src/ui/base/tooltip-icon-button.tsx
3212
+
3213
+
3214
+ // src/ui/base/tooltip.tsx
3215
+ var _reacttooltip = require('@radix-ui/react-tooltip'); var TooltipPrimitive = _interopRequireWildcard(_reacttooltip);
3216
+
3217
+ // src/ui/utils/withDefaults.tsx
3218
+
3219
+
3220
+
3221
+ var _classnames = require('classnames'); var _classnames2 = _interopRequireDefault(_classnames);
3222
+
3223
+ var withDefaultProps = ({
3224
+ className,
3225
+ ...defaultProps
3226
+ }) => ({ className: classNameProp, ...props }) => {
3227
+ return {
3228
+ className: _classnames2.default.call(void 0, className, classNameProp),
3229
+ ...defaultProps,
3230
+ ...props
3231
+ };
3232
+ };
3233
+ var withDefaults = (Component, defaultProps) => {
3234
+ const getProps = withDefaultProps(defaultProps);
3235
+ const WithDefaults = _react.forwardRef.call(void 0,
3236
+ (props, ref) => {
3237
+ const ComponentAsAny = Component;
3238
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ComponentAsAny, { ...getProps(props), ref });
3361
3239
  }
3362
- const thread = this._threadBinding.getState();
3363
- const branches = thread.getBranches(state.message.id);
3364
- let targetBranch = branchId;
3365
- if (position === "previous") {
3366
- targetBranch = branches[state.branchNumber - 2];
3367
- } else if (position === "next") {
3368
- targetBranch = branches[state.branchNumber];
3240
+ );
3241
+ WithDefaults.displayName = "withDefaults(" + (typeof Component === "string" ? Component : Component.displayName) + ")";
3242
+ return WithDefaults;
3243
+ };
3244
+
3245
+ // src/ui/base/tooltip.tsx
3246
+
3247
+ var Tooltip = (props) => {
3248
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TooltipPrimitive.Provider, { children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TooltipPrimitive.Root, { ...props }) });
3249
+ };
3250
+ Tooltip.displayName = "Tooltip";
3251
+ var TooltipTrigger = TooltipPrimitive.Trigger;
3252
+ var TooltipContent = withDefaults(TooltipPrimitive.Content, {
3253
+ sideOffset: 4,
3254
+ className: "aui-tooltip-content"
3255
+ });
3256
+ TooltipContent.displayName = "TooltipContent";
3257
+
3258
+ // src/ui/base/button.tsx
3259
+ var _classvarianceauthority = require('class-variance-authority');
3260
+
3261
+
3262
+
3263
+ var buttonVariants = _classvarianceauthority.cva.call(void 0, "aui-button", {
3264
+ variants: {
3265
+ variant: {
3266
+ default: "aui-button-primary",
3267
+ outline: "aui-button-outline",
3268
+ ghost: "aui-button-ghost"
3269
+ },
3270
+ size: {
3271
+ default: "aui-button-medium",
3272
+ icon: "aui-button-icon"
3369
3273
  }
3370
- if (!targetBranch) throw new Error("Branch not found");
3371
- this._threadBinding.getState().switchToBranch(targetBranch);
3372
- }
3373
- subscribe(callback) {
3374
- return this._core.subscribe(callback);
3274
+ },
3275
+ defaultVariants: {
3276
+ variant: "default",
3277
+ size: "default"
3375
3278
  }
3376
- getContentPartByIdx(idx) {
3377
- if (idx < 0) throw new Error("Message index must be >= 0");
3378
- return new ContentPartRuntime(
3379
- new ShallowMemoizeSubject({
3380
- getState: () => {
3381
- const state = this.getState();
3382
- if (!state) return void 0;
3383
- const message = state.message;
3384
- const part = message.content[idx];
3385
- if (!part) return void 0;
3386
- return {
3387
- part,
3388
- status: toContentPartStatus(message, idx, part)
3389
- };
3390
- },
3391
- subscribe: (callback) => this._core.subscribe(callback)
3392
- }),
3393
- this._core,
3394
- this._threadBinding
3279
+ });
3280
+ var Button = _react.forwardRef.call(void 0,
3281
+ ({ className, variant, size, ...props }, ref) => {
3282
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
3283
+ _reactprimitive.Primitive.button,
3284
+ {
3285
+ className: buttonVariants({ variant, size, className }),
3286
+ ...props,
3287
+ ref
3288
+ }
3395
3289
  );
3396
3290
  }
3397
- };
3291
+ );
3292
+ Button.displayName = "Button";
3398
3293
 
3399
- // src/api/ThreadComposerRuntime.ts
3400
- var ComposerState = class {
3401
- constructor(_composerBinding) {
3402
- this._composerBinding = _composerBinding;
3403
- }
3404
- get isEmpty() {
3405
- return this._composerBinding.getState().isEmpty;
3406
- }
3407
- get text() {
3408
- return this._composerBinding.getState().text;
3409
- }
3410
- get attachmentAccept() {
3411
- return this._composerBinding.getState().attachmentAccept;
3412
- }
3413
- get attachments() {
3414
- return this._composerBinding.getState().attachments;
3415
- }
3416
- };
3417
- var ThreadComposerRuntime = class {
3418
- constructor(_core) {
3294
+ // src/ui/base/tooltip-icon-button.tsx
3295
+
3296
+ var TooltipIconButton = _react.forwardRef.call(void 0, ({ children, tooltip, side = "bottom", ...rest }, ref) => {
3297
+ return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Tooltip, { children: [
3298
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TooltipTrigger, { asChild: true, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, Button, { variant: "ghost", size: "icon", ...rest, ref, children: [
3299
+ children,
3300
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { className: "aui-sr-only", children: tooltip })
3301
+ ] }) }),
3302
+ /* @__PURE__ */ _jsxruntime.jsx.call(void 0, TooltipContent, { side, children: tooltip })
3303
+ ] });
3304
+ });
3305
+ TooltipIconButton.displayName = "TooltipIconButton";
3306
+
3307
+ // src/api/AssistantRuntime.ts
3308
+ var AssistantRuntime = class {
3309
+ constructor(_core, CustomThreadRuntime) {
3419
3310
  this._core = _core;
3420
- this._state = new ComposerState(_core);
3421
- }
3422
- /**
3423
- * @deprecated Use `getState().isEmpty` instead. This will be removed in 0.6.0.
3424
- */
3425
- get isEmpty() {
3426
- return this._core.getState().isEmpty;
3427
- }
3428
- /**
3429
- * @deprecated Use `getState().text` instead. This will be removed in 0.6.0.
3430
- */
3431
- get text() {
3432
- return this._core.getState().text;
3433
- }
3434
- /**
3435
- * @deprecated Use `getState().attachmentAccept` instead. This will be removed in 0.6.0.
3436
- */
3437
- get attachmentAccept() {
3438
- return this._core.getState().attachmentAccept;
3439
- }
3440
- // TODO should this instead return getAttachmentByIndex([idx]) instead?
3441
- /**
3442
- * @deprecated Use `getState().attachments` instead. This will be removed in 0.6.0.
3443
- */
3444
- get attachments() {
3445
- return this._core.getState().attachments;
3311
+ this.thread = new CustomThreadRuntime(
3312
+ new NestedSubscriptionSubject({
3313
+ getState: () => this._core.thread,
3314
+ subscribe: (callback) => this._core.subscribe(callback)
3315
+ })
3316
+ );
3446
3317
  }
3447
3318
 
3448
- getState() {
3449
- return this._state;
3450
- }
3451
- setText(text) {
3452
- this._core.getState().setText(text);
3319
+ switchToNewThread() {
3320
+ return this._core.switchToNewThread();
3453
3321
  }
3454
- addAttachment(file) {
3455
- return this._core.getState().addAttachment(file);
3322
+ switchToThread(threadId) {
3323
+ return this._core.switchToThread(threadId);
3456
3324
  }
3457
- // /**
3458
- // * @deprecated Use `getAttachmentById(id).removeAttachment` instead. This will be removed in 0.6.0.
3459
- // */
3460
- removeAttachment(attachmentId) {
3461
- return this._core.getState().removeAttachment(attachmentId);
3325
+ registerModelConfigProvider(provider) {
3326
+ return this._core.registerModelConfigProvider(provider);
3462
3327
  }
3328
+ // TODO events for thread switching
3463
3329
  /**
3464
- * @deprecated This method will be removed in 0.6.0. Submit feedback if you need this functionality.
3330
+ * @deprecated Thread is now static and never gets updated. This will be removed in 0.6.0.
3465
3331
  */
3466
- reset() {
3467
- this._core.getState().reset();
3468
- }
3469
- send() {
3470
- this._core.getState().send();
3471
- }
3472
3332
  subscribe(callback) {
3473
3333
  return this._core.subscribe(callback);
3474
3334
  }
3475
3335
  };
3476
3336
 
3477
- // src/api/ThreadRuntime.ts
3478
- var ThreadState = class {
3479
- constructor(_core) {
3480
- this._core = _core;
3481
- }
3482
- get threadId() {
3483
- return this._core.threadId;
3337
+ // src/api/subscribable/LazyMemoizeSubject.ts
3338
+ var LazyMemoizeSubject = (_class11 = class extends BaseSubject {
3339
+ constructor(binding) {
3340
+ super();_class11.prototype.__init21.call(this);_class11.prototype.__init22.call(this);;
3341
+ this.binding = binding;
3342
+ const state = binding.getState();
3343
+ if (state === void 0)
3344
+ throw new Error("Entry not available in the store");
3345
+ this._previousState = state;
3484
3346
  }
3485
- get isDisabled() {
3486
- return this._core.isDisabled;
3347
+ __init21() {this._previousStateDirty = true}
3348
+
3349
+ __init22() {this.getState = () => {
3350
+ if (!this.isConnected || this._previousStateDirty) {
3351
+ const newState = this.binding.getState();
3352
+ if (newState !== void 0) {
3353
+ this._previousState = newState;
3354
+ }
3355
+ this._previousStateDirty = false;
3356
+ }
3357
+ return this._previousState;
3358
+ }}
3359
+ _connect() {
3360
+ const callback = () => {
3361
+ this._previousStateDirty = true;
3362
+ this.notifySubscribers();
3363
+ };
3364
+ return this.binding.subscribe(callback);
3487
3365
  }
3488
- get isRunning() {
3489
- const messages = this._core.messages;
3490
- const lastMessage = messages[messages.length - 1];
3491
- return _optionalChain([lastMessage, 'optionalAccess', _133 => _133.role]) !== "assistant" ? false : lastMessage.status.type === "running";
3366
+ }, _class11);
3367
+
3368
+ // src/api/ThreadRuntime.ts
3369
+ var toAppendMessage = (messages2, message) => {
3370
+ if (typeof message === "string") {
3371
+ return {
3372
+ parentId: _nullishCoalesce(_optionalChain([messages2, 'access', _156 => _156.at, 'call', _157 => _157(-1), 'optionalAccess', _158 => _158.id]), () => ( null)),
3373
+ role: "user",
3374
+ content: [{ type: "text", text: message }],
3375
+ attachments: []
3376
+ };
3492
3377
  }
3493
- get capabilities() {
3494
- return this._core.capabilities;
3378
+ if (message.role && message.parentId && message.attachments) {
3379
+ return message;
3495
3380
  }
3381
+ return {
3382
+ parentId: _nullishCoalesce(_nullishCoalesce(message.parentId, () => ( _optionalChain([messages2, 'access', _159 => _159.at, 'call', _160 => _160(-1), 'optionalAccess', _161 => _161.id]))), () => ( null)),
3383
+ role: _nullishCoalesce(message.role, () => ( "user")),
3384
+ content: message.content,
3385
+ attachments: _nullishCoalesce(message.attachments, () => ( []))
3386
+ };
3496
3387
  };
3497
- var ThreadRuntime = (_class8 = class {
3498
- constructor(_threadBinding) {;_class8.prototype.__init17.call(this);
3499
- this._threadBinding = _threadBinding;
3500
- }
3388
+ var getThreadState = (runtime) => {
3389
+ const lastMessage = runtime.messages.at(-1);
3390
+ return Object.freeze({
3391
+ threadId: runtime.threadId,
3392
+ capabilities: runtime.capabilities,
3393
+ isDisabled: runtime.isDisabled,
3394
+ isRunning: _optionalChain([lastMessage, 'optionalAccess', _162 => _162.role]) !== "assistant" ? false : lastMessage.status.type === "running",
3395
+ messages: runtime.messages,
3396
+ unstable_synchronizer: runtime.unstable_synchronizer
3397
+ });
3398
+ };
3399
+ var ThreadRuntime = (_class12 = class {
3501
3400
  // public path = "assistant.threads[main]"; // TODO
3502
3401
  /**
3503
3402
  * @deprecated Use `getState().threadId` instead. This will be removed in 0.6.0.
@@ -3523,24 +3422,40 @@ var ThreadRuntime = (_class8 = class {
3523
3422
  get capabilities() {
3524
3423
  return this.getState().capabilities;
3525
3424
  }
3526
- // TODO this should instead return getMessageByIndex([idx])
3425
+ /**
3426
+ * @deprecated Use `getState().messages` instead. This will be removed in 0.6.0.
3427
+ */
3527
3428
  get messages() {
3528
3429
  return this._threadBinding.getState().messages;
3529
3430
  }
3530
3431
  unstable_getCore() {
3531
3432
  return this._threadBinding.getState();
3532
3433
  }
3533
- __init17() {this.composer = new ThreadComposerRuntime(
3434
+
3435
+ constructor(threadBinding) {;_class12.prototype.__init23.call(this);
3436
+ const stateBinding = new LazyMemoizeSubject({
3437
+ getState: () => getThreadState(threadBinding.getState()),
3438
+ subscribe: (callback) => threadBinding.subscribe(callback)
3439
+ });
3440
+ this._threadBinding = {
3441
+ getState: () => threadBinding.getState(),
3442
+ getStateState: () => stateBinding.getState(),
3443
+ subscribe: (callback) => threadBinding.subscribe(callback)
3444
+ };
3445
+ }
3446
+ __init23() {this.composer = new ComposerRuntime(
3534
3447
  new NestedSubscriptionSubject({
3535
3448
  getState: () => this._threadBinding.getState().composer,
3536
3449
  subscribe: (callback) => this._threadBinding.subscribe(callback)
3537
3450
  })
3538
3451
  )}
3539
3452
  getState() {
3540
- return new ThreadState(this._threadBinding.getState());
3453
+ return this._threadBinding.getStateState();
3541
3454
  }
3542
3455
  append(message) {
3543
- this._threadBinding.getState().append(message);
3456
+ this._threadBinding.getState().append(
3457
+ toAppendMessage(this._threadBinding.getState().messages, message)
3458
+ );
3544
3459
  }
3545
3460
  subscribe(callback) {
3546
3461
  return this._threadBinding.subscribe(callback);
@@ -3584,6 +3499,18 @@ var ThreadRuntime = (_class8 = class {
3584
3499
  submitFeedback(options) {
3585
3500
  return this._threadBinding.getState().submitFeedback(options);
3586
3501
  }
3502
+ /**
3503
+ * @deprecated This is a temporary API. This will be removed in 0.6.0.
3504
+ */
3505
+ getEditComposer(messageId) {
3506
+ return this._threadBinding.getState().getEditComposer(messageId);
3507
+ }
3508
+ /**
3509
+ * @deprecated This is a temporary API. This will be removed in 0.6.0.
3510
+ */
3511
+ beginEdit(messageId) {
3512
+ return this._threadBinding.getState().beginEdit(messageId);
3513
+ }
3587
3514
  export() {
3588
3515
  return this._threadBinding.getState().export();
3589
3516
  }
@@ -3595,14 +3522,15 @@ var ThreadRuntime = (_class8 = class {
3595
3522
  return new MessageRuntime(
3596
3523
  new ShallowMemoizeSubject({
3597
3524
  getState: () => {
3598
- const messages = this.messages;
3599
- const message = messages[idx];
3525
+ const messages2 = this.messages;
3526
+ const message = messages2[idx];
3600
3527
  if (!message) return void 0;
3601
3528
  const branches = this._threadBinding.getState().getBranches(message.id);
3602
3529
  return {
3530
+ ...message,
3603
3531
  message,
3604
- isLast: idx === messages.length - 1,
3605
- parentId: _nullishCoalesce(_optionalChain([messages, 'access', _134 => _134[idx - 1], 'optionalAccess', _135 => _135.id]), () => ( null)),
3532
+ isLast: idx === messages2.length - 1,
3533
+ parentId: _nullishCoalesce(_optionalChain([messages2, 'access', _163 => _163[idx - 1], 'optionalAccess', _164 => _164.id]), () => ( null)),
3606
3534
  branches,
3607
3535
  branchNumber: branches.indexOf(message.id) + 1,
3608
3536
  branchCount: branches.length
@@ -3613,16 +3541,16 @@ var ThreadRuntime = (_class8 = class {
3613
3541
  this._threadBinding
3614
3542
  );
3615
3543
  }
3616
- }, _class8);
3544
+ }, _class12);
3617
3545
 
3618
3546
  // src/runtimes/edge/converters/fromLanguageModelMessages.ts
3619
3547
  var fromLanguageModelMessages = (lm, { mergeRoundtrips }) => {
3620
- const messages = [];
3548
+ const messages2 = [];
3621
3549
  for (const lmMessage of lm) {
3622
3550
  const role = lmMessage.role;
3623
3551
  switch (role) {
3624
3552
  case "system": {
3625
- messages.push({
3553
+ messages2.push({
3626
3554
  role: "system",
3627
3555
  content: [
3628
3556
  {
@@ -3634,7 +3562,7 @@ var fromLanguageModelMessages = (lm, { mergeRoundtrips }) => {
3634
3562
  break;
3635
3563
  }
3636
3564
  case "user": {
3637
- messages.push({
3565
+ messages2.push({
3638
3566
  role: "user",
3639
3567
  content: lmMessage.content.map((part) => {
3640
3568
  const type = part.type;
@@ -3677,21 +3605,21 @@ var fromLanguageModelMessages = (lm, { mergeRoundtrips }) => {
3677
3605
  return part;
3678
3606
  });
3679
3607
  if (mergeRoundtrips) {
3680
- const previousMessage = messages[messages.length - 1];
3681
- if (_optionalChain([previousMessage, 'optionalAccess', _136 => _136.role]) === "assistant") {
3608
+ const previousMessage = messages2[messages2.length - 1];
3609
+ if (_optionalChain([previousMessage, 'optionalAccess', _165 => _165.role]) === "assistant") {
3682
3610
  previousMessage.content.push(...newContent);
3683
3611
  break;
3684
3612
  }
3685
3613
  }
3686
- messages.push({
3614
+ messages2.push({
3687
3615
  role: "assistant",
3688
3616
  content: newContent
3689
3617
  });
3690
3618
  break;
3691
3619
  }
3692
3620
  case "tool": {
3693
- const previousMessage = messages[messages.length - 1];
3694
- if (_optionalChain([previousMessage, 'optionalAccess', _137 => _137.role]) !== "assistant")
3621
+ const previousMessage = messages2[messages2.length - 1];
3622
+ if (_optionalChain([previousMessage, 'optionalAccess', _166 => _166.role]) !== "assistant")
3695
3623
  throw new Error(
3696
3624
  "A tool message must be preceded by an assistant message."
3697
3625
  );
@@ -3716,7 +3644,7 @@ var fromLanguageModelMessages = (lm, { mergeRoundtrips }) => {
3716
3644
  }
3717
3645
  }
3718
3646
  }
3719
- return messages;
3647
+ return messages2;
3720
3648
  };
3721
3649
 
3722
3650
  // src/runtimes/edge/converters/fromLanguageModelTools.ts
@@ -3874,7 +3802,7 @@ var EdgeChatAdapter = class {
3874
3802
  constructor(options) {
3875
3803
  this.options = options;
3876
3804
  }
3877
- async *run({ messages, abortSignal, config }) {
3805
+ async *run({ messages: messages2, abortSignal, config }) {
3878
3806
  const headers = new Headers(this.options.headers);
3879
3807
  headers.set("Content-Type", "application/json");
3880
3808
  const result = await fetch(this.options.api, {
@@ -3883,7 +3811,7 @@ var EdgeChatAdapter = class {
3883
3811
  credentials: _nullishCoalesce(this.options.credentials, () => ( "same-origin")),
3884
3812
  body: JSON.stringify({
3885
3813
  system: config.system,
3886
- messages: _chunk5KIEXJRKjs.toCoreMessages.call(void 0, messages),
3814
+ messages: _chunk5KIEXJRKjs.toCoreMessages.call(void 0, messages2),
3887
3815
  tools: config.tools ? _chunk5KIEXJRKjs.toLanguageModelTools.call(void 0, config.tools) : [],
3888
3816
  ...config.callSettings,
3889
3817
  ...config.config,
@@ -3920,28 +3848,65 @@ var useEdgeRuntime = ({
3920
3848
  };
3921
3849
 
3922
3850
  // src/runtimes/local/shouldContinue.tsx
3923
- var shouldContinue = (result) => _optionalChain([result, 'access', _138 => _138.status, 'optionalAccess', _139 => _139.type]) === "requires-action" && result.status.reason === "tool-calls" && result.content.every((c) => c.type !== "tool-call" || !!c.result);
3851
+ var shouldContinue = (result) => _optionalChain([result, 'access', _167 => _167.status, 'optionalAccess', _168 => _168.type]) === "requires-action" && result.status.reason === "tool-calls" && result.content.every((c) => c.type !== "tool-call" || !!c.result);
3852
+
3853
+ // src/runtimes/composer/DefaultEditComposerRuntimeCore.tsx
3854
+ var DefaultEditComposerRuntimeCore = class extends BaseComposerRuntimeCore {
3855
+ constructor(runtime, endEditCallback, { parentId, message }) {
3856
+ super();
3857
+ this.runtime = runtime;
3858
+ this.endEditCallback = endEditCallback;
3859
+ this._parentId = parentId;
3860
+ this._previousText = getThreadMessageText(message);
3861
+ this.setText(this._previousText);
3862
+ this._nonTextParts = message.content.filter(
3863
+ (part) => part.type !== "text" && part.type !== "ui"
3864
+ );
3865
+ }
3866
+ get canCancel() {
3867
+ return true;
3868
+ }
3869
+
3870
+
3871
+
3872
+ async handleSend(message) {
3873
+ const text = getThreadMessageText(message);
3874
+ if (text !== this._previousText) {
3875
+ this.runtime.append({
3876
+ ...message,
3877
+ content: [...message.content, ...this._nonTextParts],
3878
+ parentId: this._parentId
3879
+ });
3880
+ }
3881
+ this.endEditCallback();
3882
+ this.notifySubscribers();
3883
+ }
3884
+ async cancel() {
3885
+ this.endEditCallback();
3886
+ this.notifySubscribers();
3887
+ }
3888
+ };
3924
3889
 
3925
3890
  // src/runtimes/local/LocalThreadRuntimeCore.tsx
3926
- var LocalThreadRuntimeCore = (_class9 = class {
3927
- constructor(configProvider, adapter, { initialMessages, ...options }) {;_class9.prototype.__init18.call(this);_class9.prototype.__init19.call(this);_class9.prototype.__init20.call(this);_class9.prototype.__init21.call(this);_class9.prototype.__init22.call(this);_class9.prototype.__init23.call(this);
3891
+ var LocalThreadRuntimeCore = (_class13 = class {
3892
+ constructor(configProvider, adapter, { initialMessages, ...options }) {;_class13.prototype.__init24.call(this);_class13.prototype.__init25.call(this);_class13.prototype.__init26.call(this);_class13.prototype.__init27.call(this);_class13.prototype.__init28.call(this);_class13.prototype.__init29.call(this);_class13.prototype.__init30.call(this);
3928
3893
  this.configProvider = configProvider;
3929
3894
  this.adapter = adapter;
3930
3895
  this.threadId = generateId();
3931
3896
  this.options = options;
3932
3897
  if (initialMessages) {
3933
3898
  let parentId = null;
3934
- const messages = fromCoreMessages(initialMessages);
3935
- for (const message of messages) {
3899
+ const messages2 = fromCoreMessages(initialMessages);
3900
+ for (const message of messages2) {
3936
3901
  this.repository.addOrUpdateMessage(parentId, message);
3937
3902
  parentId = message.id;
3938
3903
  }
3939
3904
  }
3940
3905
  }
3941
- __init18() {this._subscriptions = /* @__PURE__ */ new Set()}
3942
- __init19() {this.abortController = null}
3943
- __init20() {this.repository = new MessageRepository()}
3944
- __init21() {this.capabilities = {
3906
+ __init24() {this._subscriptions = /* @__PURE__ */ new Set()}
3907
+ __init25() {this.abortController = null}
3908
+ __init26() {this.repository = new MessageRepository()}
3909
+ __init27() {this.capabilities = {
3945
3910
  switchToBranch: true,
3946
3911
  edit: true,
3947
3912
  reload: true,
@@ -3952,11 +3917,11 @@ var LocalThreadRuntimeCore = (_class9 = class {
3952
3917
  feedback: false
3953
3918
  }}
3954
3919
 
3955
- __init22() {this.isDisabled = false}
3920
+ __init28() {this.isDisabled = false}
3956
3921
  get messages() {
3957
3922
  return this.repository.getMessages();
3958
3923
  }
3959
- __init23() {this.composer = new BaseThreadComposerRuntimeCore(this)}
3924
+ __init29() {this.composer = new DefaultThreadComposerRuntimeCore(this)}
3960
3925
  getModelConfig() {
3961
3926
  return this.configProvider.getModelConfig();
3962
3927
  }
@@ -3967,24 +3932,41 @@ var LocalThreadRuntimeCore = (_class9 = class {
3967
3932
  set options({ initialMessages, ...options }) {
3968
3933
  this._options = options;
3969
3934
  let hasUpdates = false;
3970
- const canSpeak = _optionalChain([options, 'access', _140 => _140.adapters, 'optionalAccess', _141 => _141.speech]) !== void 0;
3935
+ const canSpeak = _optionalChain([options, 'access', _169 => _169.adapters, 'optionalAccess', _170 => _170.speech]) !== void 0;
3971
3936
  if (this.capabilities.speak !== canSpeak) {
3972
3937
  this.capabilities.speak = canSpeak;
3973
3938
  hasUpdates = true;
3974
3939
  }
3975
- this.composer.setAttachmentAdapter(_optionalChain([options, 'access', _142 => _142.adapters, 'optionalAccess', _143 => _143.attachments]));
3976
- const canAttach = _optionalChain([options, 'access', _144 => _144.adapters, 'optionalAccess', _145 => _145.attachments]) !== void 0;
3940
+ this.composer.setAttachmentAdapter(_optionalChain([options, 'access', _171 => _171.adapters, 'optionalAccess', _172 => _172.attachments]));
3941
+ const canAttach = _optionalChain([options, 'access', _173 => _173.adapters, 'optionalAccess', _174 => _174.attachments]) !== void 0;
3977
3942
  if (this.capabilities.attachments !== canAttach) {
3978
3943
  this.capabilities.attachments = canAttach;
3979
3944
  hasUpdates = true;
3980
3945
  }
3981
- const canFeedback = _optionalChain([options, 'access', _146 => _146.adapters, 'optionalAccess', _147 => _147.feedback]) !== void 0;
3946
+ const canFeedback = _optionalChain([options, 'access', _175 => _175.adapters, 'optionalAccess', _176 => _176.feedback]) !== void 0;
3982
3947
  if (this.capabilities.feedback !== canFeedback) {
3983
3948
  this.capabilities.feedback = canFeedback;
3984
3949
  hasUpdates = true;
3985
3950
  }
3986
3951
  if (hasUpdates) this.notifySubscribers();
3987
3952
  }
3953
+ __init30() {this._editComposers = /* @__PURE__ */ new Map()}
3954
+ getEditComposer(messageId) {
3955
+ return this._editComposers.get(messageId);
3956
+ }
3957
+ beginEdit(messageId) {
3958
+ if (this._editComposers.has(messageId))
3959
+ throw new Error("Edit already in progress");
3960
+ this._editComposers.set(
3961
+ messageId,
3962
+ new DefaultEditComposerRuntimeCore(
3963
+ this,
3964
+ () => this._editComposers.delete(messageId),
3965
+ this.repository.getMessage(messageId)
3966
+ )
3967
+ );
3968
+ this.notifySubscribers();
3969
+ }
3988
3970
  getBranches(messageId) {
3989
3971
  return this.repository.getBranches(messageId);
3990
3972
  }
@@ -4019,19 +4001,19 @@ var LocalThreadRuntimeCore = (_class9 = class {
4019
4001
  } while (shouldContinue(message));
4020
4002
  }
4021
4003
  async performRoundtrip(parentId, message) {
4022
- const messages = this.repository.getMessages();
4023
- _optionalChain([this, 'access', _148 => _148.abortController, 'optionalAccess', _149 => _149.abort, 'call', _150 => _150()]);
4004
+ const messages2 = this.repository.getMessages();
4005
+ _optionalChain([this, 'access', _177 => _177.abortController, 'optionalAccess', _178 => _178.abort, 'call', _179 => _179()]);
4024
4006
  this.abortController = new AbortController();
4025
4007
  const initialContent = message.content;
4026
- const initialRoundtrips = _optionalChain([message, 'access', _151 => _151.metadata, 'optionalAccess', _152 => _152.roundtrips]);
4027
- const initalCustom = _optionalChain([message, 'access', _153 => _153.metadata, 'optionalAccess', _154 => _154.custom]);
4008
+ const initialRoundtrips = _optionalChain([message, 'access', _180 => _180.metadata, 'optionalAccess', _181 => _181.roundtrips]);
4009
+ const initalCustom = _optionalChain([message, 'access', _182 => _182.metadata, 'optionalAccess', _183 => _183.custom]);
4028
4010
  const updateMessage = (m) => {
4029
4011
  message = {
4030
4012
  ...message,
4031
4013
  ...m.content ? { content: [...initialContent, ..._nullishCoalesce(m.content, () => ( []))] } : void 0,
4032
4014
  status: _nullishCoalesce(m.status, () => ( message.status)),
4033
4015
  // TODO deprecated, remove in v0.6
4034
- ..._optionalChain([m, 'access', _155 => _155.metadata, 'optionalAccess', _156 => _156.roundtrips]) ? {
4016
+ ..._optionalChain([m, 'access', _184 => _184.metadata, 'optionalAccess', _185 => _185.roundtrips]) ? {
4035
4017
  roundtrips: [
4036
4018
  ..._nullishCoalesce(initialRoundtrips, () => ( [])),
4037
4019
  ...m.metadata.roundtrips
@@ -4046,7 +4028,7 @@ var LocalThreadRuntimeCore = (_class9 = class {
4046
4028
  ...m.metadata.roundtrips
4047
4029
  ]
4048
4030
  } : void 0,
4049
- ..._optionalChain([m, 'access', _157 => _157.metadata, 'optionalAccess', _158 => _158.custom]) ? {
4031
+ ..._optionalChain([m, 'access', _186 => _186.metadata, 'optionalAccess', _187 => _187.custom]) ? {
4050
4032
  custom: { ..._nullishCoalesce(initalCustom, () => ( {})), ...m.metadata.custom }
4051
4033
  } : void 0
4052
4034
  }
@@ -4056,7 +4038,7 @@ var LocalThreadRuntimeCore = (_class9 = class {
4056
4038
  this.notifySubscribers();
4057
4039
  };
4058
4040
  const maxToolRoundtrips = _nullishCoalesce(this.options.maxToolRoundtrips, () => ( 1));
4059
- const toolRoundtrips = _nullishCoalesce(_optionalChain([message, 'access', _159 => _159.metadata, 'optionalAccess', _160 => _160.roundtrips, 'optionalAccess', _161 => _161.length]), () => ( 0));
4041
+ const toolRoundtrips = _nullishCoalesce(_optionalChain([message, 'access', _188 => _188.metadata, 'optionalAccess', _189 => _189.roundtrips, 'optionalAccess', _190 => _190.length]), () => ( 0));
4060
4042
  if (toolRoundtrips > maxToolRoundtrips) {
4061
4043
  updateMessage({
4062
4044
  status: {
@@ -4074,7 +4056,7 @@ var LocalThreadRuntimeCore = (_class9 = class {
4074
4056
  }
4075
4057
  try {
4076
4058
  const promiseOrGenerator = this.adapter.run({
4077
- messages,
4059
+ messages: messages2,
4078
4060
  abortSignal: this.abortController.signal,
4079
4061
  config: this.configProvider.getModelConfig(),
4080
4062
  onUpdate: updateMessage
@@ -4155,7 +4137,7 @@ var LocalThreadRuntimeCore = (_class9 = class {
4155
4137
  // TODO lift utterance state to thread runtime
4156
4138
 
4157
4139
  speak(messageId) {
4158
- const adapter = _optionalChain([this, 'access', _162 => _162.options, 'access', _163 => _163.adapters, 'optionalAccess', _164 => _164.speech]);
4140
+ const adapter = _optionalChain([this, 'access', _191 => _191.options, 'access', _192 => _192.adapters, 'optionalAccess', _193 => _193.speech]);
4159
4141
  if (!adapter) throw new Error("Speech adapter not configured");
4160
4142
  const { message } = this.repository.getMessage(messageId);
4161
4143
  if (this._utterance) {
@@ -4172,7 +4154,7 @@ var LocalThreadRuntimeCore = (_class9 = class {
4172
4154
  return this._utterance;
4173
4155
  }
4174
4156
  submitFeedback({ messageId, type }) {
4175
- const adapter = _optionalChain([this, 'access', _165 => _165.options, 'access', _166 => _166.adapters, 'optionalAccess', _167 => _167.feedback]);
4157
+ const adapter = _optionalChain([this, 'access', _194 => _194.options, 'access', _195 => _195.adapters, 'optionalAccess', _196 => _196.feedback]);
4176
4158
  if (!adapter) throw new Error("Feedback adapter not configured");
4177
4159
  const { message } = this.repository.getMessage(messageId);
4178
4160
  adapter.submit({ message, type });
@@ -4184,7 +4166,7 @@ var LocalThreadRuntimeCore = (_class9 = class {
4184
4166
  this.repository.import(data);
4185
4167
  this.notifySubscribers();
4186
4168
  }
4187
- }, _class9);
4169
+ }, _class13);
4188
4170
 
4189
4171
  // src/runtimes/local/LocalRuntimeCore.tsx
4190
4172
  var LocalRuntimeCore = class extends BaseAssistantRuntimeCore {
@@ -4216,10 +4198,10 @@ var LocalRuntimeCore = class extends BaseAssistantRuntimeCore {
4216
4198
  } = {}) {
4217
4199
  this.switchToThread(null);
4218
4200
  if (!initialMessages) return;
4219
- const messages = fromCoreMessages(initialMessages);
4201
+ const messages2 = fromCoreMessages(initialMessages);
4220
4202
  this.thread.import({
4221
- messages: messages.map((m, idx) => ({
4222
- parentId: _nullishCoalesce(_optionalChain([messages, 'access', _168 => _168[idx - 1], 'optionalAccess', _169 => _169.id]), () => ( null)),
4203
+ messages: messages2.map((m, idx) => ({
4204
+ parentId: _nullishCoalesce(_optionalChain([messages2, 'access', _197 => _197[idx - 1], 'optionalAccess', _198 => _198.id]), () => ( null)),
4223
4205
  message: m
4224
4206
  }))
4225
4207
  });
@@ -4255,17 +4237,17 @@ var getExternalStoreMessage = (message) => {
4255
4237
  };
4256
4238
 
4257
4239
  // src/runtimes/external-store/ThreadMessageConverter.ts
4258
- var ThreadMessageConverter = (_class10 = class {constructor() { _class10.prototype.__init24.call(this); }
4259
- __init24() {this.cache = /* @__PURE__ */ new WeakMap()}
4260
- convertMessages(messages, converter) {
4261
- return messages.map((m, idx) => {
4240
+ var ThreadMessageConverter = (_class14 = class {constructor() { _class14.prototype.__init31.call(this); }
4241
+ __init31() {this.cache = /* @__PURE__ */ new WeakMap()}
4242
+ convertMessages(messages2, converter) {
4243
+ return messages2.map((m, idx) => {
4262
4244
  const cached = this.cache.get(m);
4263
4245
  const newMessage = converter(cached, m, idx);
4264
4246
  this.cache.set(m, newMessage);
4265
4247
  return newMessage;
4266
4248
  });
4267
4249
  }
4268
- }, _class10);
4250
+ }, _class14);
4269
4251
 
4270
4252
  // src/runtimes/external-store/auto-status.tsx
4271
4253
  var AUTO_STATUS_RUNNING = Object.freeze({ type: "running" });
@@ -4351,18 +4333,18 @@ var fromThreadMessageLike = (like, fallbackId, fallbackStatus) => {
4351
4333
  };
4352
4334
 
4353
4335
  // src/runtimes/external-store/ExternalStoreThreadRuntimeCore.tsx
4354
- var hasUpcomingMessage = (isRunning, messages) => {
4355
- return isRunning && _optionalChain([messages, 'access', _170 => _170[messages.length - 1], 'optionalAccess', _171 => _171.role]) !== "assistant";
4336
+ var hasUpcomingMessage = (isRunning, messages2) => {
4337
+ return isRunning && _optionalChain([messages2, 'access', _199 => _199[messages2.length - 1], 'optionalAccess', _200 => _200.role]) !== "assistant";
4356
4338
  };
4357
- var ExternalStoreThreadRuntimeCore = (_class11 = class {
4358
- constructor(configProvider, store) {;_class11.prototype.__init25.call(this);_class11.prototype.__init26.call(this);_class11.prototype.__init27.call(this);_class11.prototype.__init28.call(this);_class11.prototype.__init29.call(this);_class11.prototype.__init30.call(this);_class11.prototype.__init31.call(this);
4339
+ var ExternalStoreThreadRuntimeCore = (_class15 = class {
4340
+ constructor(configProvider, store) {;_class15.prototype.__init32.call(this);_class15.prototype.__init33.call(this);_class15.prototype.__init34.call(this);_class15.prototype.__init35.call(this);_class15.prototype.__init36.call(this);_class15.prototype.__init37.call(this);_class15.prototype.__init38.call(this);_class15.prototype.__init39.call(this);
4359
4341
  this.configProvider = configProvider;
4360
4342
  this.store = store;
4361
4343
  }
4362
- __init25() {this._subscriptions = /* @__PURE__ */ new Set()}
4363
- __init26() {this.repository = new MessageRepository()}
4364
- __init27() {this.assistantOptimisticId = null}
4365
- __init28() {this._capabilities = {
4344
+ __init32() {this._subscriptions = /* @__PURE__ */ new Set()}
4345
+ __init33() {this.repository = new MessageRepository()}
4346
+ __init34() {this.assistantOptimisticId = null}
4347
+ __init35() {this._capabilities = {
4366
4348
  switchToBranch: false,
4367
4349
  edit: false,
4368
4350
  reload: false,
@@ -4378,9 +4360,26 @@ var ExternalStoreThreadRuntimeCore = (_class11 = class {
4378
4360
 
4379
4361
 
4380
4362
 
4381
- __init29() {this.converter = new ThreadMessageConverter()}
4363
+ __init36() {this.converter = new ThreadMessageConverter()}
4382
4364
 
4383
- __init30() {this.composer = new BaseThreadComposerRuntimeCore(this)}
4365
+ __init37() {this.composer = new DefaultThreadComposerRuntimeCore(this)}
4366
+ __init38() {this._editComposers = /* @__PURE__ */ new Map()}
4367
+ getEditComposer(messageId) {
4368
+ return this._editComposers.get(messageId);
4369
+ }
4370
+ beginEdit(messageId) {
4371
+ if (this._editComposers.has(messageId))
4372
+ throw new Error("Edit already in progress");
4373
+ this._editComposers.set(
4374
+ messageId,
4375
+ new DefaultEditComposerRuntimeCore(
4376
+ this,
4377
+ () => this._editComposers.delete(messageId),
4378
+ this.repository.getMessage(messageId)
4379
+ )
4380
+ );
4381
+ this.notifySubscribers();
4382
+ }
4384
4383
  get store() {
4385
4384
  return this._store;
4386
4385
  }
@@ -4397,12 +4396,12 @@ var ExternalStoreThreadRuntimeCore = (_class11 = class {
4397
4396
  reload: this._store.onReload !== void 0,
4398
4397
  cancel: this._store.onCancel !== void 0,
4399
4398
  speak: this._store.onSpeak !== void 0,
4400
- unstable_copy: _optionalChain([this, 'access', _175 => _175._store, 'access', _176 => _176.unstable_capabilities, 'optionalAccess', _177 => _177.copy]) !== false,
4399
+ unstable_copy: _optionalChain([this, 'access', _204 => _204._store, 'access', _205 => _205.unstable_capabilities, 'optionalAccess', _206 => _206.copy]) !== false,
4401
4400
  // default true
4402
- attachments: !!_optionalChain([this, 'access', _178 => _178.store, 'access', _179 => _179.adapters, 'optionalAccess', _180 => _180.attachments]),
4403
- feedback: !!_optionalChain([this, 'access', _181 => _181.store, 'access', _182 => _182.adapters, 'optionalAccess', _183 => _183.feedback])
4401
+ attachments: !!_optionalChain([this, 'access', _207 => _207.store, 'access', _208 => _208.adapters, 'optionalAccess', _209 => _209.attachments]),
4402
+ feedback: !!_optionalChain([this, 'access', _210 => _210.store, 'access', _211 => _211.adapters, 'optionalAccess', _212 => _212.feedback])
4404
4403
  };
4405
- this.composer.setAttachmentAdapter(_optionalChain([this, 'access', _184 => _184._store, 'access', _185 => _185.adapters, 'optionalAccess', _186 => _186.attachments]));
4404
+ this.composer.setAttachmentAdapter(_optionalChain([this, 'access', _213 => _213._store, 'access', _214 => _214.adapters, 'optionalAccess', _215 => _215.attachments]));
4406
4405
  if (oldStore) {
4407
4406
  if (oldStore.convertMessage !== store.convertMessage) {
4408
4407
  this.converter = new ThreadMessageConverter();
@@ -4411,7 +4410,7 @@ var ExternalStoreThreadRuntimeCore = (_class11 = class {
4411
4410
  return;
4412
4411
  }
4413
4412
  }
4414
- const messages = !store.convertMessage ? store.messages : this.converter.convertMessages(store.messages, (cache, m, idx) => {
4413
+ const messages2 = !store.convertMessage ? store.messages : this.converter.convertMessages(store.messages, (cache, m, idx) => {
4415
4414
  if (!store.convertMessage) return m;
4416
4415
  const isLast = idx === store.messages.length - 1;
4417
4416
  const autoStatus = getAutoStatus(isLast, isRunning);
@@ -4425,18 +4424,18 @@ var ExternalStoreThreadRuntimeCore = (_class11 = class {
4425
4424
  newMessage[symbolInnerMessage] = m;
4426
4425
  return newMessage;
4427
4426
  });
4428
- for (let i = 0; i < messages.length; i++) {
4429
- const message = messages[i];
4430
- const parent = messages[i - 1];
4431
- this.repository.addOrUpdateMessage(_nullishCoalesce(_optionalChain([parent, 'optionalAccess', _187 => _187.id]), () => ( null)), message);
4427
+ for (let i = 0; i < messages2.length; i++) {
4428
+ const message = messages2[i];
4429
+ const parent = messages2[i - 1];
4430
+ this.repository.addOrUpdateMessage(_nullishCoalesce(_optionalChain([parent, 'optionalAccess', _216 => _216.id]), () => ( null)), message);
4432
4431
  }
4433
4432
  if (this.assistantOptimisticId) {
4434
4433
  this.repository.deleteMessage(this.assistantOptimisticId);
4435
4434
  this.assistantOptimisticId = null;
4436
4435
  }
4437
- if (hasUpcomingMessage(isRunning, messages)) {
4436
+ if (hasUpcomingMessage(isRunning, messages2)) {
4438
4437
  this.assistantOptimisticId = this.repository.appendOptimisticMessage(
4439
- _nullishCoalesce(_optionalChain([messages, 'access', _188 => _188.at, 'call', _189 => _189(-1), 'optionalAccess', _190 => _190.id]), () => ( null)),
4438
+ _nullishCoalesce(_optionalChain([messages2, 'access', _217 => _217.at, 'call', _218 => _218(-1), 'optionalAccess', _219 => _219.id]), () => ( null)),
4440
4439
  {
4441
4440
  role: "assistant",
4442
4441
  content: []
@@ -4444,7 +4443,7 @@ var ExternalStoreThreadRuntimeCore = (_class11 = class {
4444
4443
  );
4445
4444
  }
4446
4445
  this.repository.resetHead(
4447
- _nullishCoalesce(_nullishCoalesce(this.assistantOptimisticId, () => ( _optionalChain([messages, 'access', _191 => _191.at, 'call', _192 => _192(-1), 'optionalAccess', _193 => _193.id]))), () => ( null))
4446
+ _nullishCoalesce(_nullishCoalesce(this.assistantOptimisticId, () => ( _optionalChain([messages2, 'access', _220 => _220.at, 'call', _221 => _221(-1), 'optionalAccess', _222 => _222.id]))), () => ( null))
4448
4447
  );
4449
4448
  this.messages = this.repository.getMessages();
4450
4449
  this.notifySubscribers();
@@ -4465,7 +4464,7 @@ var ExternalStoreThreadRuntimeCore = (_class11 = class {
4465
4464
  this.updateMessages(this.repository.getMessages());
4466
4465
  }
4467
4466
  async append(message) {
4468
- if (message.parentId !== (_nullishCoalesce(_optionalChain([this, 'access', _194 => _194.messages, 'access', _195 => _195.at, 'call', _196 => _196(-1), 'optionalAccess', _197 => _197.id]), () => ( null)))) {
4467
+ if (message.parentId !== (_nullishCoalesce(_optionalChain([this, 'access', _223 => _223.messages, 'access', _224 => _224.at, 'call', _225 => _225(-1), 'optionalAccess', _226 => _226.id]), () => ( null)))) {
4469
4468
  if (!this._store.onEdit)
4470
4469
  throw new Error("Runtime does not support editing messages.");
4471
4470
  await this._store.onEdit(message);
@@ -4486,19 +4485,19 @@ var ExternalStoreThreadRuntimeCore = (_class11 = class {
4486
4485
  this.repository.deleteMessage(this.assistantOptimisticId);
4487
4486
  this.assistantOptimisticId = null;
4488
4487
  }
4489
- let messages = this.repository.getMessages();
4490
- const previousMessage = messages[messages.length - 1];
4491
- if (_optionalChain([previousMessage, 'optionalAccess', _198 => _198.role]) === "user" && previousMessage.id === _optionalChain([messages, 'access', _199 => _199.at, 'call', _200 => _200(-1), 'optionalAccess', _201 => _201.id])) {
4488
+ let messages2 = this.repository.getMessages();
4489
+ const previousMessage = messages2[messages2.length - 1];
4490
+ if (_optionalChain([previousMessage, 'optionalAccess', _227 => _227.role]) === "user" && previousMessage.id === _optionalChain([messages2, 'access', _228 => _228.at, 'call', _229 => _229(-1), 'optionalAccess', _230 => _230.id])) {
4492
4491
  this.repository.deleteMessage(previousMessage.id);
4493
4492
  if (!this.composer.text.trim()) {
4494
4493
  this.composer.setText(getThreadMessageText(previousMessage));
4495
4494
  }
4496
- messages = this.repository.getMessages();
4495
+ messages2 = this.repository.getMessages();
4497
4496
  } else {
4498
4497
  this.notifySubscribers();
4499
4498
  }
4500
4499
  setTimeout(() => {
4501
- this.updateMessages(messages);
4500
+ this.updateMessages(messages2);
4502
4501
  }, 0);
4503
4502
  }
4504
4503
  addToolResult(options) {
@@ -4513,7 +4512,7 @@ var ExternalStoreThreadRuntimeCore = (_class11 = class {
4513
4512
  return this._store.onSpeak(message);
4514
4513
  }
4515
4514
  submitFeedback({ messageId, type }) {
4516
- const adapter = _optionalChain([this, 'access', _202 => _202._store, 'access', _203 => _203.adapters, 'optionalAccess', _204 => _204.feedback]);
4515
+ const adapter = _optionalChain([this, 'access', _231 => _231._store, 'access', _232 => _232.adapters, 'optionalAccess', _233 => _233.feedback]);
4517
4516
  if (!adapter) throw new Error("Feedback adapter not configured");
4518
4517
  const { message } = this.repository.getMessage(messageId);
4519
4518
  adapter.submit({ message, type });
@@ -4522,9 +4521,9 @@ var ExternalStoreThreadRuntimeCore = (_class11 = class {
4522
4521
  this._subscriptions.add(callback);
4523
4522
  return () => this._subscriptions.delete(callback);
4524
4523
  }
4525
- __init31() {this.updateMessages = (messages) => {
4526
- _optionalChain([this, 'access', _205 => _205._store, 'access', _206 => _206.setMessages, 'optionalCall', _207 => _207(
4527
- messages.flatMap(getExternalStoreMessage).filter((m) => m != null)
4524
+ __init39() {this.updateMessages = (messages2) => {
4525
+ _optionalChain([this, 'access', _234 => _234._store, 'access', _235 => _235.setMessages, 'optionalCall', _236 => _236(
4526
+ messages2.flatMap(getExternalStoreMessage).filter((m) => m != null)
4528
4527
  )]);
4529
4528
  }}
4530
4529
  import(repository) {
@@ -4533,7 +4532,7 @@ var ExternalStoreThreadRuntimeCore = (_class11 = class {
4533
4532
  export() {
4534
4533
  return this.repository.export();
4535
4534
  }
4536
- }, _class11);
4535
+ }, _class15);
4537
4536
 
4538
4537
  // src/runtimes/external-store/ExternalStoreRuntimeCore.tsx
4539
4538
  var ExternalStoreRuntimeCore = class extends BaseAssistantRuntimeCore {
@@ -4591,12 +4590,12 @@ var useExternalStoreRuntime = (store) => {
4591
4590
 
4592
4591
  // src/runtimes/external-store/external-message-converter.tsx
4593
4592
 
4594
- var joinExternalMessages = (messages) => {
4593
+ var joinExternalMessages = (messages2) => {
4595
4594
  const assistantMessage = {
4596
4595
  role: "assistant",
4597
4596
  content: []
4598
4597
  };
4599
- for (const output of messages) {
4598
+ for (const output of messages2) {
4600
4599
  if (output.role === "tool") {
4601
4600
  const toolCallIdx = assistantMessage.content.findIndex(
4602
4601
  (c) => c.type === "tool-call" && c.toolCallId === output.toolCallId
@@ -4619,19 +4618,18 @@ var joinExternalMessages = (messages) => {
4619
4618
  );
4620
4619
  }
4621
4620
  } else {
4622
- const content = output.content;
4623
4621
  const role = output.role;
4624
4622
  switch (role) {
4625
4623
  case "system":
4626
4624
  case "user":
4627
- return { role, content };
4625
+ return output;
4628
4626
  case "assistant":
4629
4627
  if (assistantMessage.content.length === 0) {
4630
4628
  assistantMessage.id = output.id;
4631
4629
  assistantMessage.createdAt ??= output.createdAt;
4632
4630
  assistantMessage.status ??= output.status;
4633
4631
  }
4634
- assistantMessage.content.push(...content);
4632
+ assistantMessage.content.push(...output.content);
4635
4633
  break;
4636
4634
  default: {
4637
4635
  const unsupportedRole = role;
@@ -4674,7 +4672,7 @@ var chunkExternalMessages = (callbackResults) => {
4674
4672
  };
4675
4673
  var useExternalMessageConverter = ({
4676
4674
  callback,
4677
- messages,
4675
+ messages: messages2,
4678
4676
  isRunning
4679
4677
  }) => {
4680
4678
  const state = _react.useMemo.call(void 0,
@@ -4688,7 +4686,7 @@ var useExternalMessageConverter = ({
4688
4686
  );
4689
4687
  return _react.useMemo.call(void 0, () => {
4690
4688
  const callbackResults = [];
4691
- for (const message of messages) {
4689
+ for (const message of messages2) {
4692
4690
  let result = state.callbackCache.get(message);
4693
4691
  if (!result) {
4694
4692
  const output = state.callback(message);
@@ -4726,7 +4724,7 @@ var useExternalMessageConverter = ({
4726
4724
  return newMessage;
4727
4725
  }
4728
4726
  );
4729
- }, [state, messages, isRunning]);
4727
+ }, [state, messages2, isRunning]);
4730
4728
  };
4731
4729
  var shallowArrayEqual = (a, b) => {
4732
4730
  if (a.length !== b.length) return false;
@@ -4744,13 +4742,13 @@ var DangerousInBrowserAdapter = class {
4744
4742
  constructor(options) {
4745
4743
  this.options = options;
4746
4744
  }
4747
- async *run({ messages, abortSignal, config }) {
4745
+ async *run({ messages: messages2, abortSignal, config }) {
4748
4746
  const res = await _chunk5KIEXJRKjs.getEdgeRuntimeStream.call(void 0, {
4749
4747
  options: this.options,
4750
4748
  abortSignal,
4751
4749
  requestData: {
4752
4750
  system: config.system,
4753
- messages: _chunk5KIEXJRKjs.toCoreMessages.call(void 0, messages),
4751
+ messages: _chunk5KIEXJRKjs.toCoreMessages.call(void 0, messages2),
4754
4752
  tools: config.tools ? _chunk5KIEXJRKjs.toLanguageModelTools.call(void 0, config.tools) : [],
4755
4753
  ...config.callSettings,
4756
4754
  ...config.config
@@ -4814,8 +4812,8 @@ var WebSpeechSynthesisAdapter = class {
4814
4812
  };
4815
4813
 
4816
4814
  // src/runtimes/attachment/SimpleImageAttachmentAdapter.ts
4817
- var SimpleImageAttachmentAdapter = (_class12 = class {constructor() { _class12.prototype.__init32.call(this); }
4818
- __init32() {this.accept = "image/*"}
4815
+ var SimpleImageAttachmentAdapter = (_class16 = class {constructor() { _class16.prototype.__init40.call(this); }
4816
+ __init40() {this.accept = "image/*"}
4819
4817
  async add(state) {
4820
4818
  return {
4821
4819
  id: state.file.name,
@@ -4837,7 +4835,7 @@ var SimpleImageAttachmentAdapter = (_class12 = class {constructor() { _class12.p
4837
4835
  }
4838
4836
  async remove() {
4839
4837
  }
4840
- }, _class12);
4838
+ }, _class16);
4841
4839
  var getFileDataURL = (file) => new Promise((resolve, reject) => {
4842
4840
  const reader = new FileReader();
4843
4841
  reader.onload = () => resolve(reader.result);
@@ -4846,8 +4844,8 @@ var getFileDataURL = (file) => new Promise((resolve, reject) => {
4846
4844
  });
4847
4845
 
4848
4846
  // src/runtimes/attachment/SimpleTextAttachmentAdapter.ts
4849
- var SimpleTextAttachmentAdapter = (_class13 = class {constructor() { _class13.prototype.__init33.call(this); }
4850
- __init33() {this.accept = "text/plain,text/html,text/markdown,text/csv,text/xml,text/json,text/css"}
4847
+ var SimpleTextAttachmentAdapter = (_class17 = class {constructor() { _class17.prototype.__init41.call(this); }
4848
+ __init41() {this.accept = "text/plain,text/html,text/markdown,text/csv,text/xml,text/json,text/css"}
4851
4849
  async add(state) {
4852
4850
  return {
4853
4851
  id: state.file.name,
@@ -4871,7 +4869,7 @@ ${await getFileText(attachment.file)}
4871
4869
  }
4872
4870
  async remove() {
4873
4871
  }
4874
- }, _class13);
4872
+ }, _class17);
4875
4873
  var getFileText = (file) => new Promise((resolve, reject) => {
4876
4874
  const reader = new FileReader();
4877
4875
  reader.onload = () => resolve(reader.result);
@@ -4965,7 +4963,7 @@ var ThreadConfigProvider = ({
4965
4963
  }) => {
4966
4964
  const hasAssistant = !!useAssistantRuntime({ optional: true });
4967
4965
  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 });
4968
- if (!_optionalChain([config, 'optionalAccess', _208 => _208.runtime])) return configProvider;
4966
+ if (!_optionalChain([config, 'optionalAccess', _237 => _237.runtime])) return configProvider;
4969
4967
  if (hasAssistant) {
4970
4968
  throw new Error(
4971
4969
  "You provided a runtime to <Thread> while simulataneously using <AssistantRuntimeProvider>. This is not allowed."
@@ -5293,7 +5291,7 @@ var AssistantMessageContent = _react.forwardRef.call(void 0, ({ components: comp
5293
5291
  {
5294
5292
  components: {
5295
5293
  ...componentsProp,
5296
- Text: _nullishCoalesce(_nullishCoalesce(_optionalChain([componentsProp, 'optionalAccess', _209 => _209.Text]), () => ( components.Text)), () => ( content_part_default.Text)),
5294
+ Text: _nullishCoalesce(_nullishCoalesce(_optionalChain([componentsProp, 'optionalAccess', _238 => _238.Text]), () => ( components.Text)), () => ( content_part_default.Text)),
5297
5295
  tools: toolsComponents
5298
5296
  }
5299
5297
  }
@@ -5436,7 +5434,7 @@ var ComposerAttachments = ({ components }) => {
5436
5434
  {
5437
5435
  components: {
5438
5436
  ...components,
5439
- Attachment: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _210 => _210.Attachment]), () => ( composer_attachment_default))
5437
+ Attachment: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _239 => _239.Attachment]), () => ( composer_attachment_default))
5440
5438
  }
5441
5439
  }
5442
5440
  ) });
@@ -5568,7 +5566,7 @@ var ThreadWelcomeSuggestion = ({
5568
5566
  };
5569
5567
  var ThreadWelcomeSuggestions = () => {
5570
5568
  const { welcome: { suggestions } = {} } = useThreadConfig();
5571
- return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ThreadWelcomeSuggestionContainer, { children: _optionalChain([suggestions, 'optionalAccess', _211 => _211.map, 'call', _212 => _212((suggestion, idx) => {
5569
+ return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ThreadWelcomeSuggestionContainer, { children: _optionalChain([suggestions, 'optionalAccess', _240 => _240.map, 'call', _241 => _241((suggestion, idx) => {
5572
5570
  const key = `${suggestion.prompt}-${idx}`;
5573
5571
  return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ThreadWelcomeSuggestion, { suggestion }, key);
5574
5572
  })]) });
@@ -5667,7 +5665,7 @@ var UserMessageContent = _react.forwardRef.call(void 0,
5667
5665
  {
5668
5666
  components: {
5669
5667
  ...components,
5670
- Text: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _213 => _213.Text]), () => ( content_part_default.Text))
5668
+ Text: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _242 => _242.Text]), () => ( content_part_default.Text))
5671
5669
  }
5672
5670
  }
5673
5671
  ) });
@@ -5685,7 +5683,7 @@ var UserMessageAttachments = ({
5685
5683
  {
5686
5684
  components: {
5687
5685
  ...components,
5688
- Attachment: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _214 => _214.Attachment]), () => ( user_message_attachment_default))
5686
+ Attachment: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _243 => _243.Attachment]), () => ( user_message_attachment_default))
5689
5687
  }
5690
5688
  }
5691
5689
  ) }) });
@@ -5786,10 +5784,10 @@ var ThreadMessages = ({ components, ...rest }) => {
5786
5784
  thread_exports.Messages,
5787
5785
  {
5788
5786
  components: {
5789
- UserMessage: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _215 => _215.UserMessage]), () => ( user_message_default)),
5790
- EditComposer: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _216 => _216.EditComposer]), () => ( edit_composer_default)),
5791
- AssistantMessage: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _217 => _217.AssistantMessage]), () => ( assistant_message_default)),
5792
- SystemMessage: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _218 => _218.SystemMessage]), () => ( SystemMessage))
5787
+ UserMessage: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _244 => _244.UserMessage]), () => ( user_message_default)),
5788
+ EditComposer: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _245 => _245.EditComposer]), () => ( edit_composer_default)),
5789
+ AssistantMessage: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _246 => _246.AssistantMessage]), () => ( assistant_message_default)),
5790
+ SystemMessage: _nullishCoalesce(_optionalChain([components, 'optionalAccess', _247 => _247.SystemMessage]), () => ( SystemMessage))
5793
5791
  },
5794
5792
  ...rest
5795
5793
  }
@@ -6008,5 +6006,8 @@ var assistant_modal_default = Object.assign(AssistantModal, exports13);
6008
6006
 
6009
6007
 
6010
6008
 
6011
- exports.ActionBarPrimitive = actionBar_exports; exports.AssistantActionBar = assistant_action_bar_default; exports.AssistantMessage = assistant_message_default; exports.AssistantModal = assistant_modal_default; exports.AssistantModalPrimitive = assistantModal_exports; exports.AssistantRuntimeProvider = AssistantRuntimeProvider; exports.BranchPicker = branch_picker_default; exports.BranchPickerPrimitive = branchPicker_exports; exports.Composer = composer_default; exports.ComposerAttachment = composer_attachment_default; exports.ComposerPrimitive = composer_exports; exports.CompositeAttachmentAdapter = CompositeAttachmentAdapter; exports.ContentPart = content_part_default; exports.ContentPartPrimitive = contentPart_exports; exports.EdgeChatAdapter = EdgeChatAdapter; exports.EditComposer = edit_composer_default; exports.INTERNAL = internal_exports; exports.MessagePrimitive = message_exports; exports.SimpleImageAttachmentAdapter = SimpleImageAttachmentAdapter; exports.SimpleTextAttachmentAdapter = SimpleTextAttachmentAdapter; exports.TextContentPartProvider = TextContentPartProvider; exports.Thread = thread_default; exports.ThreadConfigProvider = ThreadConfigProvider; exports.ThreadPrimitive = thread_exports; exports.ThreadWelcome = thread_welcome_default; exports.UserActionBar = user_action_bar_default; exports.UserMessage = user_message_default; exports.UserMessageAttachment = user_message_attachment_default; exports.WebSpeechSynthesisAdapter = WebSpeechSynthesisAdapter; exports.fromCoreMessage = fromCoreMessage; exports.fromCoreMessages = fromCoreMessages; exports.fromLanguageModelMessages = fromLanguageModelMessages; exports.fromLanguageModelTools = fromLanguageModelTools; exports.getExternalStoreMessage = getExternalStoreMessage; exports.makeAssistantTool = makeAssistantTool; exports.makeAssistantToolUI = makeAssistantToolUI; exports.streamUtils = streamUtils; exports.subscribeToMainThread = subscribeToMainThread; exports.toCoreMessage = _chunk5KIEXJRKjs.toCoreMessage; exports.toCoreMessages = _chunk5KIEXJRKjs.toCoreMessages; exports.toLanguageModelMessages = _chunk5KIEXJRKjs.toLanguageModelMessages; exports.toLanguageModelTools = _chunk5KIEXJRKjs.toLanguageModelTools; exports.useActionBarCopy = useActionBarCopy; exports.useActionBarEdit = useActionBarEdit; exports.useActionBarFeedbackNegative = useActionBarFeedbackNegative; exports.useActionBarFeedbackPositive = useActionBarFeedbackPositive; exports.useActionBarReload = useActionBarReload; exports.useActionBarSpeak = useActionBarSpeak; exports.useActionBarStopSpeaking = useActionBarStopSpeaking; exports.useAppendMessage = useAppendMessage; exports.useAssistantActions = useAssistantActions; exports.useAssistantActionsStore = useAssistantActionsStore; exports.useAssistantContext = useAssistantContext; exports.useAssistantInstructions = useAssistantInstructions; exports.useAssistantRuntime = useAssistantRuntime; exports.useAssistantRuntimeStore = useAssistantRuntimeStore; exports.useAssistantTool = useAssistantTool; exports.useAssistantToolUI = useAssistantToolUI; exports.useBranchPickerCount = useBranchPickerCount; exports.useBranchPickerNext = useBranchPickerNext; exports.useBranchPickerNumber = useBranchPickerNumber; exports.useBranchPickerPrevious = useBranchPickerPrevious; exports.useComposer = useComposer; exports.useComposerAddAttachment = useComposerAddAttachment; exports.useComposerCancel = useComposerCancel; exports.useComposerContext = useComposerContext; exports.useComposerIf = useComposerIf; exports.useComposerSend = useComposerSend; exports.useComposerStore = useComposerStore; exports.useContentPart = useContentPart; exports.useContentPartContext = useContentPartContext; exports.useContentPartDisplay = useContentPartDisplay; exports.useContentPartImage = useContentPartImage; exports.useContentPartStore = useContentPartStore; exports.useContentPartText = useContentPartText; exports.useDangerousInBrowserRuntime = useDangerousInBrowserRuntime; exports.useEdgeRuntime = useEdgeRuntime; exports.useEditComposer = useEditComposer; exports.useEditComposerStore = useEditComposerStore; exports.useExternalMessageConverter = useExternalMessageConverter; exports.useExternalStoreRuntime = useExternalStoreRuntime; exports.useLocalRuntime = useLocalRuntime; exports.useMessage = useMessage; exports.useMessageContext = useMessageContext; exports.useMessageIf = useMessageIf; exports.useMessageStore = useMessageStore; exports.useMessageUtils = useMessageUtils; exports.useMessageUtilsStore = useMessageUtilsStore; exports.useSwitchToNewThread = useSwitchToNewThread; exports.useThread = useThread; exports.useThreadActions = useThreadActions; exports.useThreadActionsStore = useThreadActionsStore; exports.useThreadComposer = useThreadComposer; exports.useThreadComposerStore = useThreadComposerStore; exports.useThreadConfig = useThreadConfig; exports.useThreadContext = useThreadContext; exports.useThreadEmpty = useThreadEmpty; exports.useThreadIf = useThreadIf; exports.useThreadMessages = useThreadMessages; exports.useThreadMessagesStore = useThreadMessagesStore; exports.useThreadRuntime = useThreadRuntime; exports.useThreadRuntimeStore = useThreadRuntimeStore; exports.useThreadScrollToBottom = useThreadScrollToBottom; exports.useThreadStore = useThreadStore; exports.useThreadSuggestion = useThreadSuggestion; exports.useThreadViewport = useThreadViewport; exports.useThreadViewportStore = useThreadViewportStore; exports.useToolUIs = useToolUIs; exports.useToolUIsStore = useToolUIsStore;
6009
+
6010
+
6011
+
6012
+ exports.ActionBarPrimitive = actionBar_exports; exports.AssistantActionBar = assistant_action_bar_default; exports.AssistantMessage = assistant_message_default; exports.AssistantModal = assistant_modal_default; exports.AssistantModalPrimitive = assistantModal_exports; exports.AssistantRuntimeProvider = AssistantRuntimeProvider; exports.BranchPicker = branch_picker_default; exports.BranchPickerPrimitive = branchPicker_exports; exports.Composer = composer_default; exports.ComposerAttachment = composer_attachment_default; exports.ComposerPrimitive = composer_exports; exports.CompositeAttachmentAdapter = CompositeAttachmentAdapter; exports.ContentPart = content_part_default; exports.ContentPartPrimitive = contentPart_exports; exports.EdgeChatAdapter = EdgeChatAdapter; exports.EditComposer = edit_composer_default; exports.INTERNAL = internal_exports; exports.MessagePrimitive = message_exports; exports.SimpleImageAttachmentAdapter = SimpleImageAttachmentAdapter; exports.SimpleTextAttachmentAdapter = SimpleTextAttachmentAdapter; exports.TextContentPartProvider = TextContentPartProvider; exports.Thread = thread_default; exports.ThreadConfigProvider = ThreadConfigProvider; exports.ThreadPrimitive = thread_exports; exports.ThreadWelcome = thread_welcome_default; exports.UserActionBar = user_action_bar_default; exports.UserMessage = user_message_default; exports.UserMessageAttachment = user_message_attachment_default; exports.WebSpeechSynthesisAdapter = WebSpeechSynthesisAdapter; exports.fromCoreMessage = fromCoreMessage; exports.fromCoreMessages = fromCoreMessages; exports.fromLanguageModelMessages = fromLanguageModelMessages; exports.fromLanguageModelTools = fromLanguageModelTools; exports.getExternalStoreMessage = getExternalStoreMessage; exports.makeAssistantTool = makeAssistantTool; exports.makeAssistantToolUI = makeAssistantToolUI; exports.streamUtils = streamUtils; exports.subscribeToMainThread = subscribeToMainThread; exports.toCoreMessage = _chunk5KIEXJRKjs.toCoreMessage; exports.toCoreMessages = _chunk5KIEXJRKjs.toCoreMessages; exports.toLanguageModelMessages = _chunk5KIEXJRKjs.toLanguageModelMessages; exports.toLanguageModelTools = _chunk5KIEXJRKjs.toLanguageModelTools; exports.useActionBarCopy = useActionBarCopy; exports.useActionBarEdit = useActionBarEdit; exports.useActionBarFeedbackNegative = useActionBarFeedbackNegative; exports.useActionBarFeedbackPositive = useActionBarFeedbackPositive; exports.useActionBarReload = useActionBarReload; exports.useActionBarSpeak = useActionBarSpeak; exports.useActionBarStopSpeaking = useActionBarStopSpeaking; exports.useAppendMessage = useAppendMessage; exports.useAssistantActions = useAssistantActions; exports.useAssistantActionsStore = useAssistantActionsStore; exports.useAssistantContext = useAssistantContext; exports.useAssistantInstructions = useAssistantInstructions; exports.useAssistantRuntime = useAssistantRuntime; exports.useAssistantRuntimeStore = useAssistantRuntimeStore; exports.useAssistantTool = useAssistantTool; exports.useAssistantToolUI = useAssistantToolUI; exports.useBranchPickerCount = useBranchPickerCount; exports.useBranchPickerNext = useBranchPickerNext; exports.useBranchPickerNumber = useBranchPickerNumber; exports.useBranchPickerPrevious = useBranchPickerPrevious; exports.useComposer = useComposer; exports.useComposerAddAttachment = useComposerAddAttachment; exports.useComposerCancel = useComposerCancel; exports.useComposerContext = useComposerContext; exports.useComposerIf = useComposerIf; exports.useComposerRuntime = useComposerRuntime; exports.useComposerSend = useComposerSend; exports.useComposerStore = useComposerStore; exports.useContentPart = useContentPart; exports.useContentPartContext = useContentPartContext; exports.useContentPartDisplay = useContentPartDisplay; exports.useContentPartImage = useContentPartImage; exports.useContentPartRuntime = useContentPartRuntime; exports.useContentPartStore = useContentPartStore; exports.useContentPartText = useContentPartText; exports.useDangerousInBrowserRuntime = useDangerousInBrowserRuntime; exports.useEdgeRuntime = useEdgeRuntime; exports.useEditComposer = useEditComposer; exports.useEditComposerStore = useEditComposerStore; exports.useExternalMessageConverter = useExternalMessageConverter; exports.useExternalStoreRuntime = useExternalStoreRuntime; exports.useLocalRuntime = useLocalRuntime; exports.useMessage = useMessage; exports.useMessageContext = useMessageContext; exports.useMessageIf = useMessageIf; exports.useMessageRuntime = useMessageRuntime; exports.useMessageStore = useMessageStore; exports.useMessageUtils = useMessageUtils; exports.useMessageUtilsStore = useMessageUtilsStore; exports.useSwitchToNewThread = useSwitchToNewThread; exports.useThread = useThread; exports.useThreadActions = useThreadActions; exports.useThreadActionsStore = useThreadActionsStore; exports.useThreadComposer = useThreadComposer; exports.useThreadComposerStore = useThreadComposerStore; exports.useThreadConfig = useThreadConfig; exports.useThreadContext = useThreadContext; exports.useThreadEmpty = useThreadEmpty; exports.useThreadIf = useThreadIf; exports.useThreadMessages = useThreadMessages; exports.useThreadMessagesStore = useThreadMessagesStore; exports.useThreadRuntime = useThreadRuntime; exports.useThreadRuntimeStore = useThreadRuntimeStore; exports.useThreadScrollToBottom = useThreadScrollToBottom; exports.useThreadStore = useThreadStore; exports.useThreadSuggestion = useThreadSuggestion; exports.useThreadViewport = useThreadViewport; exports.useThreadViewportStore = useThreadViewportStore; exports.useToolUIs = useToolUIs; exports.useToolUIsStore = useToolUIsStore;
6012
6013
  //# sourceMappingURL=index.js.map