@assistant-ui/react 0.4.5 → 0.4.7

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.mjs CHANGED
@@ -9,7 +9,7 @@ var __export = (target, all) => {
9
9
  import { memo } from "react";
10
10
 
11
11
  // src/context/providers/AssistantProvider.tsx
12
- import { useEffect as useEffect2, useInsertionEffect as useInsertionEffect2, useRef as useRef2, useState as useState2 } from "react";
12
+ import { useEffect, useInsertionEffect as useInsertionEffect2, useRef as useRef2, useState as useState2 } from "react";
13
13
 
14
14
  // src/context/react/AssistantContext.ts
15
15
  import { createContext, useContext } from "react";
@@ -29,6 +29,21 @@ function useAssistantContext(options) {
29
29
  import { create } from "zustand";
30
30
 
31
31
  // src/types/ModelConfigTypes.ts
32
+ import { z } from "zod";
33
+ var LanguageModelV1CallSettingsSchema = z.object({
34
+ maxTokens: z.number().int().positive().optional(),
35
+ temperature: z.number().optional(),
36
+ topP: z.number().optional(),
37
+ presencePenalty: z.number().optional(),
38
+ frequencyPenalty: z.number().optional(),
39
+ seed: z.number().int().optional(),
40
+ headers: z.record(z.string().optional()).optional()
41
+ });
42
+ var LanguageModelConfigSchema = z.object({
43
+ apiKey: z.string().optional(),
44
+ baseUrl: z.string().optional(),
45
+ modelName: z.string().optional()
46
+ });
32
47
  var mergeModelConfigs = (configSet) => {
33
48
  const configs = Array.from(configSet).map((c) => c.getModelConfig()).sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
34
49
  return configs.reduce((acc, config) => {
@@ -52,6 +67,18 @@ ${config.system}`;
52
67
  acc.tools[name] = tool;
53
68
  }
54
69
  }
70
+ if (config.config) {
71
+ acc.config = {
72
+ ...acc.config,
73
+ ...config.config
74
+ };
75
+ }
76
+ if (config.callSettings) {
77
+ acc.callSettings = {
78
+ ...acc.callSettings,
79
+ ...config.callSettings
80
+ };
81
+ }
55
82
  return acc;
56
83
  }, {});
57
84
  };
@@ -116,14 +143,7 @@ var makeAssistantToolUIsStore = () => create2((set) => {
116
143
  });
117
144
 
118
145
  // src/context/providers/ThreadProvider.tsx
119
- import {
120
- useCallback,
121
- useEffect,
122
- useInsertionEffect,
123
- useRef,
124
- useState,
125
- useSyncExternalStore
126
- } from "react";
146
+ import { useCallback as useCallback2, useInsertionEffect, useState } from "react";
127
147
 
128
148
  // src/context/react/ThreadContext.ts
129
149
  import { createContext as createContext2, useContext as useContext2 } from "react";
@@ -189,7 +209,7 @@ var makeComposerStore = (useThreadMessages, useThreadActions) => {
189
209
  import { create as create4 } from "zustand";
190
210
  var makeThreadStore = (runtimeRef) => {
191
211
  return create4(() => ({
192
- isRunning: runtimeRef.current.isRunning
212
+ isRunning: runtimeRef.getState().isRunning
193
213
  }));
194
214
  };
195
215
 
@@ -215,19 +235,18 @@ var makeThreadViewportStore = () => {
215
235
 
216
236
  // src/context/stores/ThreadActions.ts
217
237
  import { create as create6 } from "zustand";
218
- var makeThreadActionStore = (runtimeRef) => {
238
+ var makeThreadActionStore = (runtimeStore) => {
219
239
  return create6(
220
240
  () => Object.freeze({
221
241
  get capabilities() {
222
- return runtimeRef.current.capabilities;
242
+ return runtimeStore.getState().capabilities;
223
243
  },
224
- getBranches: (messageId) => runtimeRef.current.getBranches(messageId),
225
- switchToBranch: (branchId) => runtimeRef.current.switchToBranch(branchId),
226
- startRun: (parentId) => runtimeRef.current.startRun(parentId),
227
- append: (message) => runtimeRef.current.append(message),
228
- cancelRun: () => runtimeRef.current.cancelRun(),
229
- addToolResult: (options) => runtimeRef.current.addToolResult(options),
230
- getRuntime: () => runtimeRef.current
244
+ getBranches: (messageId) => runtimeStore.getState().getBranches(messageId),
245
+ switchToBranch: (branchId) => runtimeStore.getState().switchToBranch(branchId),
246
+ startRun: (parentId) => runtimeStore.getState().startRun(parentId),
247
+ append: (message) => runtimeStore.getState().append(message),
248
+ cancelRun: () => runtimeStore.getState().cancelRun(),
249
+ addToolResult: (options) => runtimeStore.getState().addToolResult(options)
231
250
  })
232
251
  );
233
252
  };
@@ -235,60 +254,96 @@ var makeThreadActionStore = (runtimeRef) => {
235
254
  // src/context/stores/ThreadMessages.ts
236
255
  import { create as create7 } from "zustand";
237
256
  var makeThreadMessagesStore = (runtimeRef) => {
238
- return create7(() => runtimeRef.current.messages);
257
+ return create7(() => runtimeRef.getState().messages);
258
+ };
259
+
260
+ // src/context/stores/ThreadRuntime.tsx
261
+ import { create as create8 } from "zustand";
262
+ var makeThreadRuntimeStore = (runtime) => {
263
+ return create8(() => runtime);
264
+ };
265
+
266
+ // src/utils/hooks/useManagedRef.ts
267
+ import { useCallback, useRef } from "react";
268
+ var useManagedRef = (callback) => {
269
+ const cleanupRef = useRef();
270
+ const ref = useCallback(
271
+ (el) => {
272
+ if (cleanupRef.current) {
273
+ cleanupRef.current();
274
+ }
275
+ if (el) {
276
+ cleanupRef.current = callback(el);
277
+ }
278
+ },
279
+ [callback]
280
+ );
281
+ return ref;
239
282
  };
240
283
 
241
284
  // src/context/providers/ThreadProvider.tsx
242
285
  import { jsx, jsxs } from "react/jsx-runtime";
243
286
  var ThreadProvider = ({
244
287
  children,
245
- runtime
288
+ provider
246
289
  }) => {
247
- const runtimeRef = useRef(runtime.thread);
248
290
  const [context] = useState(() => {
249
- const useThread = makeThreadStore(runtimeRef);
250
- const useThreadMessages = makeThreadMessagesStore(runtimeRef);
251
- const useThreadActions = makeThreadActionStore(runtimeRef);
291
+ const useThreadRuntime = makeThreadRuntimeStore(provider.thread);
292
+ const useThread = makeThreadStore(useThreadRuntime);
293
+ const useThreadMessages = makeThreadMessagesStore(useThreadRuntime);
294
+ const useThreadActions = makeThreadActionStore(useThreadRuntime);
252
295
  const useViewport = makeThreadViewportStore();
253
296
  const useComposer = makeComposerStore(useThreadMessages, useThreadActions);
254
297
  return {
255
298
  useThread,
299
+ useThreadRuntime,
256
300
  useThreadMessages,
257
301
  useThreadActions,
258
302
  useComposer,
259
303
  useViewport
260
304
  };
261
305
  });
262
- const thread = useSyncExternalStore(
263
- useCallback((c) => runtime.subscribe(c), [runtime]),
264
- () => runtime.thread,
265
- () => runtime.thread
306
+ const threadRef = useManagedRef(
307
+ useCallback2(
308
+ (thread) => {
309
+ const onThreadUpdate = () => {
310
+ context.useThread.setState(
311
+ Object.freeze({
312
+ isRunning: context.useThreadRuntime.getState().isRunning
313
+ }),
314
+ true
315
+ );
316
+ context.useThreadMessages.setState(thread.messages, true);
317
+ };
318
+ onThreadUpdate();
319
+ return thread.subscribe(onThreadUpdate);
320
+ },
321
+ [context]
322
+ )
266
323
  );
267
324
  useInsertionEffect(() => {
268
- runtimeRef.current = thread;
269
- });
270
- useEffect(() => {
271
- const onThreadUpdate = () => {
272
- context.useThread.setState(
273
- Object.freeze({
274
- isRunning: runtimeRef.current.isRunning
275
- }),
276
- true
277
- );
278
- context.useThreadMessages.setState(Object.freeze(runtimeRef.current.messages), true);
325
+ const unsubscribe = provider.subscribe(() => {
326
+ context.useThreadRuntime.setState(provider.thread, true);
327
+ threadRef(provider.thread);
328
+ });
329
+ threadRef(provider.thread);
330
+ return () => {
331
+ unsubscribe();
332
+ threadRef(null);
279
333
  };
280
- onThreadUpdate();
281
- return thread.subscribe(onThreadUpdate);
282
- }, [context, thread]);
334
+ }, [provider, context]);
335
+ const Synchronizer = context.useThreadRuntime(
336
+ (t) => t.unstable_synchronizer
337
+ );
283
338
  return /* @__PURE__ */ jsxs(ThreadContext.Provider, { value: context, children: [
284
- thread.unstable_synchronizer && /* @__PURE__ */ jsx(thread.unstable_synchronizer, {}),
339
+ Synchronizer && /* @__PURE__ */ jsx(Synchronizer, {}),
285
340
  children
286
341
  ] });
287
342
  };
288
343
 
289
344
  // src/context/stores/AssistantActions.tsx
290
- import { create as create8 } from "zustand";
291
- var makeAssistantActionsStore = (runtimeRef) => create8(
345
+ import { create as create9 } from "zustand";
346
+ var makeAssistantActionsStore = (runtimeRef) => create9(
292
347
  () => Object.freeze({
293
348
  switchToThread: () => runtimeRef.current.switchToThread(null),
294
349
  getRuntime: () => runtimeRef.current
@@ -309,10 +364,10 @@ var AssistantProvider = ({ children, runtime }) => {
309
364
  return { useModelConfig, useToolUIs, useAssistantActions };
310
365
  });
311
366
  const getModelConfig = context.useModelConfig();
312
- useEffect2(() => {
367
+ useEffect(() => {
313
368
  return runtime.registerModelConfigProvider(getModelConfig);
314
369
  }, [runtime, getModelConfig]);
315
- return /* @__PURE__ */ jsx2(AssistantContext.Provider, { value: context, children: /* @__PURE__ */ jsx2(ThreadProvider, { runtime, children }) });
370
+ return /* @__PURE__ */ jsx2(AssistantContext.Provider, { value: context, children: /* @__PURE__ */ jsx2(ThreadProvider, { provider: runtime, children }) });
316
371
  };
317
372
 
318
373
  // src/context/providers/AssistantRuntimeProvider.tsx
@@ -365,7 +420,7 @@ function useContentPartContext(options) {
365
420
  }
366
421
 
367
422
  // src/hooks/useAppendMessage.tsx
368
- import { useCallback as useCallback2 } from "react";
423
+ import { useCallback as useCallback3 } from "react";
369
424
  var toAppendMessage = (useThreadMessages, message) => {
370
425
  if (typeof message === "string") {
371
426
  return {
@@ -382,7 +437,7 @@ var toAppendMessage = (useThreadMessages, message) => {
382
437
  };
383
438
  var useAppendMessage = () => {
384
439
  const { useThreadMessages, useThreadActions, useViewport, useComposer } = useThreadContext();
385
- const append = useCallback2(
440
+ const append = useCallback3(
386
441
  (message) => {
387
442
  const appendMessage = toAppendMessage(useThreadMessages, message);
388
443
  useThreadActions.getState().append(appendMessage);
@@ -395,11 +450,11 @@ var useAppendMessage = () => {
395
450
  };
396
451
 
397
452
  // src/hooks/useSwitchToNewThread.tsx
398
- import { useCallback as useCallback3 } from "react";
453
+ import { useCallback as useCallback4 } from "react";
399
454
  var useSwitchToNewThread = () => {
400
455
  const { useAssistantActions } = useAssistantContext();
401
456
  const { useComposer } = useThreadContext();
402
- const switchToNewThread = useCallback3(() => {
457
+ const switchToNewThread = useCallback4(() => {
403
458
  useAssistantActions.getState().switchToThread(null);
404
459
  useComposer.getState().focus();
405
460
  }, [useAssistantActions, useComposer]);
@@ -407,14 +462,14 @@ var useSwitchToNewThread = () => {
407
462
  };
408
463
 
409
464
  // src/model-config/useAssistantTool.tsx
410
- import { useEffect as useEffect3 } from "react";
465
+ import { useEffect as useEffect2 } from "react";
411
466
  var useAssistantTool = (tool) => {
412
467
  const { useModelConfig, useToolUIs } = useAssistantContext();
413
468
  const registerModelConfigProvider = useModelConfig(
414
469
  (s) => s.registerModelConfigProvider
415
470
  );
416
471
  const setToolUI = useToolUIs((s) => s.setToolUI);
417
- useEffect3(() => {
472
+ useEffect2(() => {
418
473
  const { toolName, render, ...rest } = tool;
419
474
  const config = {
420
475
  tools: {
@@ -442,11 +497,11 @@ var makeAssistantTool = (tool) => {
442
497
  };
443
498
 
444
499
  // src/model-config/useAssistantToolUI.tsx
445
- import { useEffect as useEffect4 } from "react";
500
+ import { useEffect as useEffect3 } from "react";
446
501
  var useAssistantToolUI = (tool) => {
447
502
  const { useToolUIs } = useAssistantContext();
448
503
  const setToolUI = useToolUIs((s) => s.setToolUI);
449
- useEffect4(() => {
504
+ useEffect3(() => {
450
505
  if (!tool) return;
451
506
  const { toolName, render } = tool;
452
507
  return setToolUI(toolName, render);
@@ -463,13 +518,13 @@ var makeAssistantToolUI = (tool) => {
463
518
  };
464
519
 
465
520
  // src/model-config/useAssistantInstructions.tsx
466
- import { useEffect as useEffect5 } from "react";
521
+ import { useEffect as useEffect4 } from "react";
467
522
  var useAssistantInstructions = (instruction) => {
468
523
  const { useModelConfig } = useAssistantContext();
469
524
  const registerModelConfigProvider = useModelConfig(
470
525
  (s) => s.registerModelConfigProvider
471
526
  );
472
- useEffect5(() => {
527
+ useEffect4(() => {
473
528
  const config = {
474
529
  system: instruction
475
530
  };
@@ -478,13 +533,13 @@ var useAssistantInstructions = (instruction) => {
478
533
  };
479
534
 
480
535
  // src/primitive-hooks/actionBar/useActionBarCopy.tsx
481
- import { useCallback as useCallback4 } from "react";
536
+ import { useCallback as useCallback5 } from "react";
482
537
 
483
538
  // src/utils/combined/useCombinedStore.ts
484
539
  import { useMemo as useMemo2 } from "react";
485
540
 
486
541
  // src/utils/combined/createCombinedStore.ts
487
- import { useSyncExternalStore as useSyncExternalStore2 } from "react";
542
+ import { useSyncExternalStore } from "react";
488
543
  var createCombinedStore = (stores) => {
489
544
  const subscribe = (callback) => {
490
545
  const unsubscribes = stores.map((store) => store.subscribe(callback));
@@ -496,7 +551,7 @@ var createCombinedStore = (stores) => {
496
551
  };
497
552
  return (selector) => {
498
553
  const getSnapshot = () => selector(...stores.map((store) => store.getState()));
499
- return useSyncExternalStore2(subscribe, getSnapshot, getSnapshot);
554
+ return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
500
555
  };
501
556
  };
502
557
 
@@ -525,7 +580,7 @@ var useActionBarCopy = ({
525
580
  return !c.isEditing && m.message.content.some((c2) => c2.type === "text" && c2.text.length > 0);
526
581
  }
527
582
  );
528
- const callback = useCallback4(() => {
583
+ const callback = useCallback5(() => {
529
584
  const { message } = useMessage.getState();
530
585
  const { setIsCopied } = useMessageUtils.getState();
531
586
  const { isEditing, value: composerValue } = useEditComposer.getState();
@@ -540,14 +595,14 @@ var useActionBarCopy = ({
540
595
  };
541
596
 
542
597
  // src/primitive-hooks/actionBar/useActionBarEdit.tsx
543
- import { useCallback as useCallback5 } from "react";
598
+ import { useCallback as useCallback6 } from "react";
544
599
  var useActionBarEdit = () => {
545
600
  const { useMessage, useEditComposer } = useMessageContext();
546
601
  const disabled = useCombinedStore(
547
602
  [useMessage, useEditComposer],
548
603
  (m, c) => m.message.role !== "user" || c.isEditing
549
604
  );
550
- const callback = useCallback5(() => {
605
+ const callback = useCallback6(() => {
551
606
  const { edit } = useEditComposer.getState();
552
607
  edit();
553
608
  }, [useEditComposer]);
@@ -556,7 +611,7 @@ var useActionBarEdit = () => {
556
611
  };
557
612
 
558
613
  // src/primitive-hooks/actionBar/useActionBarReload.tsx
559
- import { useCallback as useCallback6 } from "react";
614
+ import { useCallback as useCallback7 } from "react";
560
615
  var useActionBarReload = () => {
561
616
  const { useThread, useThreadActions, useComposer, useViewport } = useThreadContext();
562
617
  const { useMessage } = useMessageContext();
@@ -564,7 +619,7 @@ var useActionBarReload = () => {
564
619
  [useThread, useMessage],
565
620
  (t, m) => t.isRunning || m.message.role !== "assistant"
566
621
  );
567
- const callback = useCallback6(() => {
622
+ const callback = useCallback7(() => {
568
623
  const { parentId } = useMessage.getState();
569
624
  useThreadActions.getState().startRun(parentId);
570
625
  useViewport.getState().scrollToBottom();
@@ -582,7 +637,7 @@ var useBranchPickerCount = () => {
582
637
  };
583
638
 
584
639
  // src/primitive-hooks/branchPicker/useBranchPickerNext.tsx
585
- import { useCallback as useCallback7 } from "react";
640
+ import { useCallback as useCallback8 } from "react";
586
641
  var useBranchPickerNext = () => {
587
642
  const { useThreadActions } = useThreadContext();
588
643
  const { useMessage, useEditComposer } = useMessageContext();
@@ -590,7 +645,7 @@ var useBranchPickerNext = () => {
590
645
  [useMessage, useEditComposer],
591
646
  (m, c) => c.isEditing || m.branches.indexOf(m.message.id) + 1 >= m.branches.length
592
647
  );
593
- const callback = useCallback7(() => {
648
+ const callback = useCallback8(() => {
594
649
  const { message, branches } = useMessage.getState();
595
650
  useThreadActions.getState().switchToBranch(branches[branches.indexOf(message.id) + 1]);
596
651
  }, [useThreadActions, useMessage]);
@@ -606,7 +661,7 @@ var useBranchPickerNumber = () => {
606
661
  };
607
662
 
608
663
  // src/primitive-hooks/branchPicker/useBranchPickerPrevious.tsx
609
- import { useCallback as useCallback8 } from "react";
664
+ import { useCallback as useCallback9 } from "react";
610
665
  var useBranchPickerPrevious = () => {
611
666
  const { useThreadActions } = useThreadContext();
612
667
  const { useMessage, useEditComposer } = useMessageContext();
@@ -614,7 +669,7 @@ var useBranchPickerPrevious = () => {
614
669
  [useMessage, useEditComposer],
615
670
  (m, c) => c.isEditing || m.branches.indexOf(m.message.id) <= 0
616
671
  );
617
- const callback = useCallback8(() => {
672
+ const callback = useCallback9(() => {
618
673
  const { message, branches } = useMessage.getState();
619
674
  useThreadActions.getState().switchToBranch(branches[branches.indexOf(message.id) - 1]);
620
675
  }, [useThreadActions, useMessage]);
@@ -623,11 +678,11 @@ var useBranchPickerPrevious = () => {
623
678
  };
624
679
 
625
680
  // src/primitive-hooks/composer/useComposerCancel.tsx
626
- import { useCallback as useCallback9 } from "react";
681
+ import { useCallback as useCallback10 } from "react";
627
682
  var useComposerCancel = () => {
628
683
  const { useComposer } = useComposerContext();
629
684
  const disabled = useComposer((c) => !c.canCancel);
630
- const callback = useCallback9(() => {
685
+ const callback = useCallback10(() => {
631
686
  const { cancel } = useComposer.getState();
632
687
  cancel();
633
688
  }, [useComposer]);
@@ -646,12 +701,12 @@ var useComposerIf = (props) => {
646
701
  };
647
702
 
648
703
  // src/primitive-hooks/composer/useComposerSend.tsx
649
- import { useCallback as useCallback10 } from "react";
704
+ import { useCallback as useCallback11 } from "react";
650
705
  var useComposerSend = () => {
651
706
  const { useViewport, useComposer: useNewComposer } = useThreadContext();
652
707
  const { useComposer } = useComposerContext();
653
708
  const disabled = useComposer((c) => !c.isEditing || c.value.length === 0);
654
- const callback = useCallback10(() => {
709
+ const callback = useCallback11(() => {
655
710
  const composerState = useComposer.getState();
656
711
  if (!composerState.isEditing) return;
657
712
  composerState.send();
@@ -740,11 +795,11 @@ var useThreadEmpty = () => {
740
795
  };
741
796
 
742
797
  // src/primitive-hooks/thread/useThreadScrollToBottom.tsx
743
- import { useCallback as useCallback11 } from "react";
798
+ import { useCallback as useCallback12 } from "react";
744
799
  var useThreadScrollToBottom = () => {
745
800
  const { useComposer, useViewport } = useThreadContext();
746
801
  const isAtBottom = useViewport((s) => s.isAtBottom);
747
- const handleScrollToBottom = useCallback11(() => {
802
+ const handleScrollToBottom = useCallback12(() => {
748
803
  useViewport.getState().scrollToBottom();
749
804
  useComposer.getState().focus();
750
805
  }, [useViewport, useComposer]);
@@ -753,7 +808,7 @@ var useThreadScrollToBottom = () => {
753
808
  };
754
809
 
755
810
  // src/primitive-hooks/thread/useThreadSuggestion.tsx
756
- import { useCallback as useCallback12 } from "react";
811
+ import { useCallback as useCallback13 } from "react";
757
812
  var useThreadSuggestion = ({
758
813
  prompt,
759
814
  autoSend
@@ -761,7 +816,7 @@ var useThreadSuggestion = ({
761
816
  const { useThread, useComposer } = useThreadContext();
762
817
  const append = useAppendMessage();
763
818
  const disabled = useThread((t) => t.isRunning);
764
- const callback = useCallback12(() => {
819
+ const callback = useCallback13(() => {
765
820
  const thread = useThread.getState();
766
821
  const composer = useComposer.getState();
767
822
  if (autoSend && !thread.isRunning) {
@@ -899,11 +954,11 @@ import { composeEventHandlers as composeEventHandlers2 } from "@radix-ui/primiti
899
954
 
900
955
  // src/utils/hooks/useOnComposerFocus.tsx
901
956
  import { useCallbackRef } from "@radix-ui/react-use-callback-ref";
902
- import { useEffect as useEffect6 } from "react";
957
+ import { useEffect as useEffect5 } from "react";
903
958
  var useOnComposerFocus = (callback) => {
904
959
  const callbackRef = useCallbackRef(callback);
905
960
  const { useComposer } = useThreadContext();
906
- useEffect6(() => {
961
+ useEffect5(() => {
907
962
  return useComposer.getState().onFocus(() => {
908
963
  callbackRef();
909
964
  });
@@ -1065,26 +1120,6 @@ import {
1065
1120
  forwardRef as forwardRef6,
1066
1121
  useCallback as useCallback14
1067
1122
  } from "react";
1068
-
1069
- // src/utils/hooks/useManagedRef.ts
1070
- import { useCallback as useCallback13, useRef as useRef3 } from "react";
1071
- var useManagedRef = (callback) => {
1072
- const cleanupRef = useRef3();
1073
- const ref = useCallback13(
1074
- (el) => {
1075
- if (cleanupRef.current) {
1076
- cleanupRef.current();
1077
- }
1078
- if (el) {
1079
- cleanupRef.current = callback(el);
1080
- }
1081
- },
1082
- [callback]
1083
- );
1084
- return ref;
1085
- };
1086
-
1087
- // src/primitives/message/MessageRoot.tsx
1088
1123
  import { useComposedRefs } from "@radix-ui/react-compose-refs";
1089
1124
  import { jsx as jsx12 } from "react/jsx-runtime";
1090
1125
  var useIsHoveringRef = () => {
@@ -1131,8 +1166,8 @@ MessagePrimitiveIf.displayName = "MessagePrimitive.If";
1131
1166
  import { memo as memo2 } from "react";
1132
1167
 
1133
1168
  // src/context/providers/ContentPartProvider.tsx
1134
- import { useEffect as useEffect7, useState as useState4 } from "react";
1135
- import { create as create9 } from "zustand";
1169
+ import { useEffect as useEffect6, useState as useState4 } from "react";
1170
+ import { create as create10 } from "zustand";
1136
1171
  import { jsx as jsx13 } from "react/jsx-runtime";
1137
1172
  var DONE_STATUS = { type: "done" };
1138
1173
  var syncContentPart = ({ message }, useContentPart, partIndex) => {
@@ -1152,13 +1187,13 @@ var syncContentPart = ({ message }, useContentPart, partIndex) => {
1152
1187
  var useContentPartContext2 = (partIndex) => {
1153
1188
  const { useMessage } = useMessageContext();
1154
1189
  const [context] = useState4(() => {
1155
- const useContentPart = create9(
1190
+ const useContentPart = create10(
1156
1191
  () => ({})
1157
1192
  );
1158
1193
  syncContentPart(useMessage.getState(), useContentPart, partIndex);
1159
1194
  return { useContentPart };
1160
1195
  });
1161
- useEffect7(() => {
1196
+ useEffect6(() => {
1162
1197
  syncContentPart(useMessage.getState(), context.useContentPart, partIndex);
1163
1198
  return useMessage.subscribe((message) => {
1164
1199
  syncContentPart(message, context.useContentPart, partIndex);
@@ -1179,7 +1214,7 @@ import { Primitive as Primitive4 } from "@radix-ui/react-primitive";
1179
1214
  import { forwardRef as forwardRef7 } from "react";
1180
1215
 
1181
1216
  // src/utils/hooks/useSmooth.tsx
1182
- import { useEffect as useEffect8, useRef as useRef4, useState as useState5 } from "react";
1217
+ import { useEffect as useEffect7, useRef as useRef3, useState as useState5 } from "react";
1183
1218
  var TextStreamAnimator = class {
1184
1219
  constructor(currentText, setText) {
1185
1220
  this.currentText = currentText;
@@ -1227,12 +1262,12 @@ var TextStreamAnimator = class {
1227
1262
  var useSmooth = (text, smooth = false) => {
1228
1263
  const { useMessage } = useMessageContext();
1229
1264
  const id = useMessage((m) => m.message.id);
1230
- const idRef = useRef4(id);
1265
+ const idRef = useRef3(id);
1231
1266
  const [displayedText, setDisplayedText] = useState5(text);
1232
1267
  const [animatorRef] = useState5(
1233
1268
  new TextStreamAnimator(text, setDisplayedText)
1234
1269
  );
1235
- useEffect8(() => {
1270
+ useEffect7(() => {
1236
1271
  if (!smooth) {
1237
1272
  animatorRef.stop();
1238
1273
  return;
@@ -1248,7 +1283,7 @@ var useSmooth = (text, smooth = false) => {
1248
1283
  animatorRef.targetText = text;
1249
1284
  animatorRef.start();
1250
1285
  }, [animatorRef, id, smooth, text]);
1251
- useEffect8(() => {
1286
+ useEffect7(() => {
1252
1287
  return () => {
1253
1288
  animatorRef.stop();
1254
1289
  };
@@ -1434,8 +1469,8 @@ import { Slot } from "@radix-ui/react-slot";
1434
1469
  import {
1435
1470
  forwardRef as forwardRef11,
1436
1471
  useCallback as useCallback15,
1437
- useEffect as useEffect9,
1438
- useRef as useRef5
1472
+ useEffect as useEffect8,
1473
+ useRef as useRef4
1439
1474
  } from "react";
1440
1475
  import TextareaAutosize from "react-textarea-autosize";
1441
1476
  import { useEscapeKeydown } from "@radix-ui/react-use-escape-keydown";
@@ -1449,7 +1484,7 @@ var ComposerPrimitiveInput = forwardRef11(
1449
1484
  return c.value;
1450
1485
  });
1451
1486
  const Component = asChild ? Slot : TextareaAutosize;
1452
- const textareaRef = useRef5(null);
1487
+ const textareaRef = useRef4(null);
1453
1488
  const ref = useComposedRefs2(forwardedRef, textareaRef);
1454
1489
  useEscapeKeydown((e) => {
1455
1490
  const composer = useComposer.getState();
@@ -1478,7 +1513,7 @@ var ComposerPrimitiveInput = forwardRef11(
1478
1513
  textareaRef.current.value.length
1479
1514
  );
1480
1515
  }, [autoFocusEnabled]);
1481
- useEffect9(() => focus(), [focus]);
1516
+ useEffect8(() => focus(), [focus]);
1482
1517
  useOnComposerFocus(() => {
1483
1518
  if (type === "new") {
1484
1519
  focus();
@@ -1595,7 +1630,7 @@ import { forwardRef as forwardRef14 } from "react";
1595
1630
 
1596
1631
  // src/primitive-hooks/thread/useThreadViewportAutoScroll.tsx
1597
1632
  import { useComposedRefs as useComposedRefs3 } from "@radix-ui/react-compose-refs";
1598
- import { useRef as useRef6 } from "react";
1633
+ import { useRef as useRef5 } from "react";
1599
1634
 
1600
1635
  // src/utils/hooks/useOnResizeContent.tsx
1601
1636
  import { useCallbackRef as useCallbackRef2 } from "@radix-ui/react-use-callback-ref";
@@ -1639,11 +1674,11 @@ var useOnResizeContent = (callback) => {
1639
1674
 
1640
1675
  // src/utils/hooks/useOnScrollToBottom.tsx
1641
1676
  import { useCallbackRef as useCallbackRef3 } from "@radix-ui/react-use-callback-ref";
1642
- import { useEffect as useEffect10 } from "react";
1677
+ import { useEffect as useEffect9 } from "react";
1643
1678
  var useOnScrollToBottom = (callback) => {
1644
1679
  const callbackRef = useCallbackRef3(callback);
1645
1680
  const { useViewport } = useThreadContext();
1646
- useEffect10(() => {
1681
+ useEffect9(() => {
1647
1682
  return useViewport.getState().onScrollToBottom(() => {
1648
1683
  callbackRef();
1649
1684
  });
@@ -1654,10 +1689,10 @@ var useOnScrollToBottom = (callback) => {
1654
1689
  var useThreadViewportAutoScroll = ({
1655
1690
  autoScroll = true
1656
1691
  }) => {
1657
- const divRef = useRef6(null);
1692
+ const divRef = useRef5(null);
1658
1693
  const { useViewport } = useThreadContext();
1659
- const lastScrollTop = useRef6(0);
1660
- const isScrollingToBottomRef = useRef6(false);
1694
+ const lastScrollTop = useRef5(0);
1695
+ const isScrollingToBottomRef = useRef5(false);
1661
1696
  const scrollToBottom = (behavior) => {
1662
1697
  const div = divRef.current;
1663
1698
  if (!div || !autoScroll) return;
@@ -1716,15 +1751,15 @@ ThreadPrimitiveViewport.displayName = "ThreadPrimitive.Viewport";
1716
1751
  import { memo as memo3 } from "react";
1717
1752
 
1718
1753
  // src/context/providers/MessageProvider.tsx
1719
- import { useEffect as useEffect11, useState as useState6 } from "react";
1720
- import { create as create12 } from "zustand";
1754
+ import { useEffect as useEffect10, useState as useState6 } from "react";
1755
+ import { create as create13 } from "zustand";
1721
1756
 
1722
1757
  // src/context/stores/EditComposer.ts
1723
- import { create as create10 } from "zustand";
1758
+ import { create as create11 } from "zustand";
1724
1759
  var makeEditComposerStore = ({
1725
1760
  onEdit,
1726
1761
  onSend
1727
- }) => create10()((set, get, store) => ({
1762
+ }) => create11()((set, get, store) => ({
1728
1763
  ...makeBaseComposer(set, get, store),
1729
1764
  canCancel: false,
1730
1765
  isEditing: false,
@@ -1743,8 +1778,8 @@ var makeEditComposerStore = ({
1743
1778
  }));
1744
1779
 
1745
1780
  // src/context/stores/MessageUtils.ts
1746
- import { create as create11 } from "zustand";
1747
- var makeMessageUtilsStore = () => create11((set) => ({
1781
+ import { create as create12 } from "zustand";
1782
+ var makeMessageUtilsStore = () => create12((set) => ({
1748
1783
  isCopied: false,
1749
1784
  setIsCopied: (value) => {
1750
1785
  set({ isCopied: value });
@@ -1779,7 +1814,7 @@ var syncMessage = (messages, getBranches, useMessage, messageIndex) => {
1779
1814
  var useMessageContext2 = (messageIndex) => {
1780
1815
  const { useThreadMessages, useThreadActions } = useThreadContext();
1781
1816
  const [context] = useState6(() => {
1782
- const useMessage = create12(() => ({}));
1817
+ const useMessage = create13(() => ({}));
1783
1818
  const useMessageUtils = makeMessageUtilsStore();
1784
1819
  const useEditComposer = makeEditComposerStore({
1785
1820
  onEdit: () => {
@@ -1815,7 +1850,7 @@ var useMessageContext2 = (messageIndex) => {
1815
1850
  );
1816
1851
  return { useMessage, useMessageUtils, useEditComposer };
1817
1852
  });
1818
- useEffect11(() => {
1853
+ useEffect10(() => {
1819
1854
  return useThreadMessages.subscribe((thread) => {
1820
1855
  syncMessage(
1821
1856
  thread,
@@ -2205,108 +2240,358 @@ var TooltipIconButton = forwardRef17(({ children, tooltip, side = "bottom", ...r
2205
2240
  });
2206
2241
  TooltipIconButton.displayName = "TooltipIconButton";
2207
2242
 
2208
- // src/runtimes/edge/useEdgeRuntime.ts
2209
- import { useState as useState7 } from "react";
2210
-
2211
- // src/runtimes/edge/converters/toCoreMessages.ts
2212
- var toCoreMessages = (message) => {
2213
- return message.map((message2) => {
2214
- return {
2215
- role: message2.role,
2216
- content: message2.content.map((part) => {
2217
- if (part.type === "ui") throw new Error("UI parts are not supported");
2218
- return part;
2219
- })
2220
- };
2221
- });
2222
- };
2223
-
2224
- // src/runtimes/edge/converters/toLanguageModelTools.ts
2225
- import { z } from "zod";
2226
- import zodToJsonSchema from "zod-to-json-schema";
2227
- var toLanguageModelTools = (tools) => {
2228
- if (!tools) return [];
2229
- return Object.entries(tools).map(([name, tool]) => ({
2230
- type: "function",
2231
- name,
2232
- ...tool.description ? { description: tool.description } : void 0,
2233
- parameters: tool.parameters instanceof z.ZodType ? zodToJsonSchema(tool.parameters) : tool.parameters
2234
- }));
2235
- };
2236
-
2237
- // src/runtimes/edge/streams/assistantDecoderStream.ts
2238
- function assistantDecoderStream() {
2239
- const toolCallNames = /* @__PURE__ */ new Map();
2240
- let currentToolCall;
2241
- return new TransformStream({
2242
- transform(chunk, controller) {
2243
- const [code, value] = parseStreamPart(chunk);
2244
- if (currentToolCall && code !== "2" /* ToolCallArgsTextDelta */ && code !== "E" /* Error */) {
2245
- controller.enqueue({
2246
- type: "tool-call",
2247
- toolCallType: "function",
2248
- toolCallId: currentToolCall.id,
2249
- toolName: currentToolCall.name,
2250
- args: currentToolCall.argsText
2251
- });
2252
- currentToolCall = void 0;
2243
+ // src/runtimes/edge/converters/toLanguageModelMessages.ts
2244
+ var assistantMessageSplitter = () => {
2245
+ const stash = [];
2246
+ let assistantMessage = {
2247
+ role: "assistant",
2248
+ content: []
2249
+ };
2250
+ let toolMessage = {
2251
+ role: "tool",
2252
+ content: []
2253
+ };
2254
+ return {
2255
+ addTextContentPart: (part) => {
2256
+ if (toolMessage.content.length > 0) {
2257
+ stash.push(assistantMessage);
2258
+ stash.push(toolMessage);
2259
+ assistantMessage = {
2260
+ role: "assistant",
2261
+ content: []
2262
+ };
2263
+ toolMessage = {
2264
+ role: "tool",
2265
+ content: []
2266
+ };
2253
2267
  }
2254
- switch (code) {
2255
- case "0" /* TextDelta */: {
2256
- controller.enqueue({
2257
- type: "text-delta",
2258
- textDelta: value
2259
- });
2260
- break;
2261
- }
2262
- case "1" /* ToolCallBegin */: {
2263
- const { id, name } = value;
2264
- toolCallNames.set(id, name);
2265
- currentToolCall = { id, name, argsText: "" };
2266
- break;
2267
- }
2268
- case "2" /* ToolCallArgsTextDelta */: {
2269
- const delta = value;
2270
- currentToolCall.argsText += delta;
2271
- controller.enqueue({
2272
- type: "tool-call-delta",
2273
- toolCallType: "function",
2274
- toolCallId: currentToolCall.id,
2275
- toolName: currentToolCall.name,
2276
- argsTextDelta: delta
2277
- });
2278
- break;
2279
- }
2280
- case "3" /* ToolCallResult */: {
2281
- controller.enqueue({
2282
- type: "tool-result",
2283
- toolCallType: "function",
2284
- toolCallId: value.id,
2285
- toolName: toolCallNames.get(value.id),
2286
- result: value.result
2287
- });
2288
- break;
2289
- }
2290
- case "F" /* Finish */: {
2291
- controller.enqueue({
2292
- type: "finish",
2293
- ...value
2294
- });
2295
- break;
2296
- }
2297
- case "E" /* Error */: {
2298
- controller.enqueue({
2299
- type: "error",
2300
- error: value
2301
- });
2302
- break;
2303
- }
2304
- default: {
2305
- const unhandledType = code;
2306
- throw new Error(`Unhandled chunk type: ${unhandledType}`);
2307
- }
2268
+ assistantMessage.content.push(part);
2269
+ },
2270
+ addToolCallPart: (part) => {
2271
+ assistantMessage.content.push({
2272
+ type: "tool-call",
2273
+ toolCallId: part.toolCallId,
2274
+ toolName: part.toolName,
2275
+ args: part.args
2276
+ });
2277
+ if (part.result) {
2278
+ toolMessage.content.push({
2279
+ type: "tool-result",
2280
+ toolCallId: part.toolCallId,
2281
+ toolName: part.toolName,
2282
+ result: part.result
2283
+ // isError
2284
+ });
2308
2285
  }
2309
- }
2286
+ },
2287
+ getMessages: () => {
2288
+ if (toolMessage.content.length > 0) {
2289
+ return [...stash, assistantMessage, toolMessage];
2290
+ }
2291
+ return [...stash, assistantMessage];
2292
+ }
2293
+ };
2294
+ };
2295
+ function toLanguageModelMessages(message) {
2296
+ return message.flatMap((message2) => {
2297
+ const role = message2.role;
2298
+ switch (role) {
2299
+ case "system": {
2300
+ return [{ role: "system", content: message2.content[0].text }];
2301
+ }
2302
+ case "user": {
2303
+ const msg = {
2304
+ role: "user",
2305
+ content: message2.content.map(
2306
+ (part) => {
2307
+ const type = part.type;
2308
+ switch (type) {
2309
+ case "text": {
2310
+ return part;
2311
+ }
2312
+ case "image": {
2313
+ return {
2314
+ type: "image",
2315
+ image: new URL(part.image)
2316
+ };
2317
+ }
2318
+ default: {
2319
+ const unhandledType = type;
2320
+ throw new Error(
2321
+ `Unspported content part type: ${unhandledType}`
2322
+ );
2323
+ }
2324
+ }
2325
+ }
2326
+ )
2327
+ };
2328
+ return [msg];
2329
+ }
2330
+ case "assistant": {
2331
+ const splitter = assistantMessageSplitter();
2332
+ for (const part of message2.content) {
2333
+ const type = part.type;
2334
+ switch (type) {
2335
+ case "text": {
2336
+ splitter.addTextContentPart(part);
2337
+ break;
2338
+ }
2339
+ case "tool-call": {
2340
+ splitter.addToolCallPart(part);
2341
+ break;
2342
+ }
2343
+ default: {
2344
+ const unhandledType = type;
2345
+ throw new Error(`Unhandled content part type: ${unhandledType}`);
2346
+ }
2347
+ }
2348
+ }
2349
+ return splitter.getMessages();
2350
+ }
2351
+ default: {
2352
+ const unhandledRole = role;
2353
+ throw new Error(`Unknown message role: ${unhandledRole}`);
2354
+ }
2355
+ }
2356
+ });
2357
+ }
2358
+
2359
+ // src/runtimes/edge/converters/fromLanguageModelMessages.ts
2360
+ var fromLanguageModelMessages = (lm, { mergeRoundtrips }) => {
2361
+ const messages = [];
2362
+ for (const lmMessage of lm) {
2363
+ const role = lmMessage.role;
2364
+ switch (role) {
2365
+ case "system": {
2366
+ messages.push({
2367
+ role: "system",
2368
+ content: [
2369
+ {
2370
+ type: "text",
2371
+ text: lmMessage.content
2372
+ }
2373
+ ]
2374
+ });
2375
+ break;
2376
+ }
2377
+ case "user": {
2378
+ messages.push({
2379
+ role: "user",
2380
+ content: lmMessage.content.map((part) => {
2381
+ const type = part.type;
2382
+ switch (type) {
2383
+ case "text": {
2384
+ return {
2385
+ type: "text",
2386
+ text: part.text
2387
+ };
2388
+ }
2389
+ case "image": {
2390
+ if (part.image instanceof URL) {
2391
+ return {
2392
+ type: "image",
2393
+ image: part.image.href
2394
+ };
2395
+ }
2396
+ throw new Error("Only images with URL data are supported");
2397
+ }
2398
+ default: {
2399
+ const unhandledType = type;
2400
+ throw new Error(`Unknown content part type: ${unhandledType}`);
2401
+ }
2402
+ }
2403
+ })
2404
+ });
2405
+ break;
2406
+ }
2407
+ case "assistant": {
2408
+ const newContent = lmMessage.content.map((part) => {
2409
+ if (part.type === "tool-call") {
2410
+ return {
2411
+ type: "tool-call",
2412
+ toolCallId: part.toolCallId,
2413
+ toolName: part.toolName,
2414
+ argsText: JSON.stringify(part.args),
2415
+ args: part.args
2416
+ };
2417
+ }
2418
+ return part;
2419
+ });
2420
+ if (mergeRoundtrips) {
2421
+ const previousMessage = messages[messages.length - 1];
2422
+ if (previousMessage?.role === "assistant") {
2423
+ previousMessage.content.push(...newContent);
2424
+ break;
2425
+ }
2426
+ }
2427
+ messages.push({
2428
+ role: "assistant",
2429
+ content: newContent
2430
+ });
2431
+ break;
2432
+ }
2433
+ case "tool": {
2434
+ const previousMessage = messages[messages.length - 1];
2435
+ if (previousMessage?.role !== "assistant")
2436
+ throw new Error(
2437
+ "A tool message must be preceded by an assistant message."
2438
+ );
2439
+ for (const tool of lmMessage.content) {
2440
+ const toolCall = previousMessage.content.find(
2441
+ (c) => c.type === "tool-call" && c.toolCallId === tool.toolCallId
2442
+ );
2443
+ if (!toolCall)
2444
+ throw new Error("Received tool result for an unknown tool call.");
2445
+ if (toolCall.toolName !== tool.toolName)
2446
+ throw new Error("Tool call name mismatch.");
2447
+ toolCall.result = tool.result;
2448
+ if (tool.isError) {
2449
+ toolCall.isError = true;
2450
+ }
2451
+ }
2452
+ break;
2453
+ }
2454
+ default: {
2455
+ const unhandledRole = role;
2456
+ throw new Error(`Unknown message role: ${unhandledRole}`);
2457
+ }
2458
+ }
2459
+ }
2460
+ return messages;
2461
+ };
2462
+
2463
+ // src/runtimes/edge/converters/fromCoreMessage.ts
2464
+ var fromCoreMessages = (message) => {
2465
+ return message.map((message2) => {
2466
+ return {
2467
+ id: generateId(),
2468
+ createdAt: /* @__PURE__ */ new Date(),
2469
+ ...message2.role === "assistant" ? {
2470
+ status: { type: "done" }
2471
+ } : void 0,
2472
+ ...message2
2473
+ };
2474
+ });
2475
+ };
2476
+
2477
+ // src/runtimes/edge/converters/toCoreMessages.ts
2478
+ var toCoreMessages = (message) => {
2479
+ return message.map((message2) => {
2480
+ return {
2481
+ role: message2.role,
2482
+ content: message2.content.map((part) => {
2483
+ if (part.type === "ui") throw new Error("UI parts are not supported");
2484
+ if (part.type === "tool-call") {
2485
+ const { argsText, ...rest } = part;
2486
+ return rest;
2487
+ }
2488
+ return part;
2489
+ })
2490
+ };
2491
+ });
2492
+ };
2493
+
2494
+ // src/runtimes/edge/converters/fromLanguageModelTools.ts
2495
+ var fromLanguageModelTools = (tools) => {
2496
+ return Object.fromEntries(
2497
+ tools.map((tool) => [
2498
+ tool.name,
2499
+ {
2500
+ description: tool.description,
2501
+ parameters: tool.parameters
2502
+ }
2503
+ ])
2504
+ );
2505
+ };
2506
+
2507
+ // src/runtimes/edge/converters/toLanguageModelTools.ts
2508
+ import { z as z2 } from "zod";
2509
+ import zodToJsonSchema from "zod-to-json-schema";
2510
+ var toLanguageModelTools = (tools) => {
2511
+ return Object.entries(tools).map(([name, tool]) => ({
2512
+ type: "function",
2513
+ name,
2514
+ ...tool.description ? { description: tool.description } : void 0,
2515
+ parameters: tool.parameters instanceof z2.ZodType ? zodToJsonSchema(tool.parameters) : tool.parameters
2516
+ }));
2517
+ };
2518
+
2519
+ // src/runtimes/edge/useEdgeRuntime.ts
2520
+ import { useState as useState7 } from "react";
2521
+
2522
+ // src/runtimes/edge/streams/assistantDecoderStream.ts
2523
+ function assistantDecoderStream() {
2524
+ const toolCallNames = /* @__PURE__ */ new Map();
2525
+ let currentToolCall;
2526
+ return new TransformStream({
2527
+ transform(chunk, controller) {
2528
+ const [code, value] = parseStreamPart(chunk);
2529
+ if (currentToolCall && code !== "2" /* ToolCallArgsTextDelta */ && code !== "E" /* Error */) {
2530
+ controller.enqueue({
2531
+ type: "tool-call",
2532
+ toolCallType: "function",
2533
+ toolCallId: currentToolCall.id,
2534
+ toolName: currentToolCall.name,
2535
+ args: currentToolCall.argsText
2536
+ });
2537
+ currentToolCall = void 0;
2538
+ }
2539
+ switch (code) {
2540
+ case "0" /* TextDelta */: {
2541
+ controller.enqueue({
2542
+ type: "text-delta",
2543
+ textDelta: value
2544
+ });
2545
+ break;
2546
+ }
2547
+ case "1" /* ToolCallBegin */: {
2548
+ const { id, name } = value;
2549
+ toolCallNames.set(id, name);
2550
+ currentToolCall = { id, name, argsText: "" };
2551
+ break;
2552
+ }
2553
+ case "2" /* ToolCallArgsTextDelta */: {
2554
+ const delta = value;
2555
+ currentToolCall.argsText += delta;
2556
+ controller.enqueue({
2557
+ type: "tool-call-delta",
2558
+ toolCallType: "function",
2559
+ toolCallId: currentToolCall.id,
2560
+ toolName: currentToolCall.name,
2561
+ argsTextDelta: delta
2562
+ });
2563
+ break;
2564
+ }
2565
+ case "3" /* ToolCallResult */: {
2566
+ controller.enqueue({
2567
+ type: "tool-result",
2568
+ toolCallType: "function",
2569
+ toolCallId: value.id,
2570
+ toolName: toolCallNames.get(value.id),
2571
+ result: value.result
2572
+ });
2573
+ break;
2574
+ }
2575
+ case "F" /* Finish */: {
2576
+ controller.enqueue({
2577
+ type: "finish",
2578
+ ...value
2579
+ });
2580
+ break;
2581
+ }
2582
+ case "E" /* Error */: {
2583
+ controller.enqueue({
2584
+ type: "error",
2585
+ error: value
2586
+ });
2587
+ break;
2588
+ }
2589
+ default: {
2590
+ const unhandledType = code;
2591
+ throw new Error(`Unhandled chunk type: ${unhandledType}`);
2592
+ }
2593
+ }
2594
+ }
2310
2595
  });
2311
2596
  }
2312
2597
  var parseStreamPart = (part) => {
@@ -2807,7 +3092,7 @@ var appendOrUpdateFinish = (message, chunk) => {
2807
3092
  };
2808
3093
 
2809
3094
  // src/runtimes/edge/streams/toolResultStream.ts
2810
- import { z as z2 } from "zod";
3095
+ import { z as z3 } from "zod";
2811
3096
  import sjson2 from "secure-json-parse";
2812
3097
  function toolResultStream(tools) {
2813
3098
  const toolCallExecutions = /* @__PURE__ */ new Map();
@@ -2821,12 +3106,16 @@ function toolResultStream(tools) {
2821
3106
  const tool = tools?.[toolName];
2822
3107
  if (!tool || !tool.execute) return;
2823
3108
  const args = sjson2.parse(argsText);
2824
- if (tool.parameters instanceof z2.ZodType) {
3109
+ if (tool.parameters instanceof z3.ZodType) {
2825
3110
  const result = tool.parameters.safeParse(args);
2826
3111
  if (!result.success) {
2827
3112
  controller.enqueue({
2828
- type: "error",
2829
- error: new Error("Invalid tool call arguments")
3113
+ type: "tool-result",
3114
+ toolCallType,
3115
+ toolCallId,
3116
+ toolName,
3117
+ result: "Function parameter validation failed. " + JSON.stringify(result.error.issues),
3118
+ isError: true
2830
3119
  });
2831
3120
  return;
2832
3121
  } else {
@@ -2843,9 +3132,14 @@ function toolResultStream(tools) {
2843
3132
  result: result2
2844
3133
  });
2845
3134
  } catch (error) {
3135
+ console.error("Error: ", error);
2846
3136
  controller.enqueue({
2847
- type: "error",
2848
- error
3137
+ type: "tool-result",
3138
+ toolCallType,
3139
+ toolCallId,
3140
+ toolName,
3141
+ result: "Error: " + error,
3142
+ isError: true
2849
3143
  });
2850
3144
  } finally {
2851
3145
  toolCallExecutions.delete(toolCallId);
@@ -2901,12 +3195,17 @@ var EdgeChatAdapter = class {
2901
3195
  body: JSON.stringify({
2902
3196
  system: config.system,
2903
3197
  messages: toCoreMessages(messages),
2904
- tools: toLanguageModelTools(
2905
- config.tools
2906
- )
3198
+ tools: config.tools ? toLanguageModelTools(config.tools) : [],
3199
+ ...config.callSettings,
3200
+ ...config.config
2907
3201
  }),
2908
3202
  signal: abortSignal
2909
3203
  });
3204
+ if (result.status !== 200) {
3205
+ throw new Error(
3206
+ `Edge runtime returned status ${result.status}: ${await result.text()}`
3207
+ );
3208
+ }
2910
3209
  const stream = result.body.pipeThrough(new TextDecoderStream()).pipeThrough(chunkByLineStream()).pipeThrough(assistantDecoderStream()).pipeThrough(toolResultStream(config.tools)).pipeThrough(runResultStream(initialContent));
2911
3210
  let message;
2912
3211
  let update;
@@ -2959,240 +3258,6 @@ var useEdgeRuntime = ({
2959
3258
  return useLocalRuntime(adapter, { initialMessages });
2960
3259
  };
2961
3260
 
2962
- // src/runtimes/edge/converters/toLanguageModelMessages.ts
2963
- var assistantMessageSplitter = () => {
2964
- const stash = [];
2965
- let assistantMessage = {
2966
- role: "assistant",
2967
- content: []
2968
- };
2969
- let toolMessage = {
2970
- role: "tool",
2971
- content: []
2972
- };
2973
- return {
2974
- addTextContentPart: (part) => {
2975
- if (toolMessage.content.length > 0) {
2976
- stash.push(assistantMessage);
2977
- stash.push(toolMessage);
2978
- assistantMessage = {
2979
- role: "assistant",
2980
- content: []
2981
- };
2982
- toolMessage = {
2983
- role: "tool",
2984
- content: []
2985
- };
2986
- }
2987
- assistantMessage.content.push(part);
2988
- },
2989
- addToolCallPart: (part) => {
2990
- assistantMessage.content.push({
2991
- type: "tool-call",
2992
- toolCallId: part.toolCallId,
2993
- toolName: part.toolName,
2994
- args: part.args
2995
- });
2996
- if (part.result) {
2997
- toolMessage.content.push({
2998
- type: "tool-result",
2999
- toolCallId: part.toolCallId,
3000
- toolName: part.toolName,
3001
- result: part.result
3002
- // isError
3003
- });
3004
- }
3005
- },
3006
- getMessages: () => {
3007
- if (toolMessage.content.length > 0) {
3008
- return [...stash, assistantMessage, toolMessage];
3009
- }
3010
- return [...stash, assistantMessage];
3011
- }
3012
- };
3013
- };
3014
- function toLanguageModelMessages(message) {
3015
- return message.flatMap((message2) => {
3016
- const role = message2.role;
3017
- switch (role) {
3018
- case "system": {
3019
- return [{ role: "system", content: message2.content[0].text }];
3020
- }
3021
- case "user": {
3022
- const msg = {
3023
- role: "user",
3024
- content: message2.content.map(
3025
- (part) => {
3026
- const type = part.type;
3027
- switch (type) {
3028
- case "text": {
3029
- return part;
3030
- }
3031
- case "image": {
3032
- return {
3033
- type: "image",
3034
- image: new URL(part.image)
3035
- };
3036
- }
3037
- default: {
3038
- const unhandledType = type;
3039
- throw new Error(
3040
- `Unspported content part type: ${unhandledType}`
3041
- );
3042
- }
3043
- }
3044
- }
3045
- )
3046
- };
3047
- return [msg];
3048
- }
3049
- case "assistant": {
3050
- const splitter = assistantMessageSplitter();
3051
- for (const part of message2.content) {
3052
- const type = part.type;
3053
- switch (type) {
3054
- case "text": {
3055
- splitter.addTextContentPart(part);
3056
- break;
3057
- }
3058
- case "tool-call": {
3059
- splitter.addToolCallPart(part);
3060
- break;
3061
- }
3062
- default: {
3063
- const unhandledType = type;
3064
- throw new Error(`Unhandled content part type: ${unhandledType}`);
3065
- }
3066
- }
3067
- }
3068
- return splitter.getMessages();
3069
- }
3070
- default: {
3071
- const unhandledRole = role;
3072
- throw new Error(`Unknown message role: ${unhandledRole}`);
3073
- }
3074
- }
3075
- });
3076
- }
3077
-
3078
- // src/runtimes/edge/converters/fromLanguageModelMessages.ts
3079
- var fromLanguageModelMessages = (lm, mergeRoundtrips) => {
3080
- const messages = [];
3081
- for (const lmMessage of lm) {
3082
- const role = lmMessage.role;
3083
- switch (role) {
3084
- case "system": {
3085
- messages.push({
3086
- role: "system",
3087
- content: [
3088
- {
3089
- type: "text",
3090
- text: lmMessage.content
3091
- }
3092
- ]
3093
- });
3094
- break;
3095
- }
3096
- case "user": {
3097
- messages.push({
3098
- role: "user",
3099
- content: lmMessage.content.map((part) => {
3100
- const type = part.type;
3101
- switch (type) {
3102
- case "text": {
3103
- return {
3104
- type: "text",
3105
- text: part.text
3106
- };
3107
- }
3108
- case "image": {
3109
- if (part.image instanceof URL) {
3110
- return {
3111
- type: "image",
3112
- image: part.image.href
3113
- };
3114
- }
3115
- throw new Error("Only images with URL data are supported");
3116
- }
3117
- default: {
3118
- const unhandledType = type;
3119
- throw new Error(`Unknown content part type: ${unhandledType}`);
3120
- }
3121
- }
3122
- })
3123
- });
3124
- break;
3125
- }
3126
- case "assistant": {
3127
- const newContent = lmMessage.content.map((part) => {
3128
- if (part.type === "tool-call") {
3129
- return {
3130
- type: "tool-call",
3131
- toolCallId: part.toolCallId,
3132
- toolName: part.toolName,
3133
- argsText: JSON.stringify(part.args),
3134
- args: typeof part.args === "string" ? part.args : part.args
3135
- };
3136
- }
3137
- return part;
3138
- });
3139
- if (mergeRoundtrips) {
3140
- const previousMessage = messages[messages.length - 1];
3141
- if (previousMessage?.role === "assistant") {
3142
- previousMessage.content.push(...newContent);
3143
- break;
3144
- }
3145
- }
3146
- messages.push({
3147
- role: "assistant",
3148
- content: newContent
3149
- });
3150
- break;
3151
- }
3152
- case "tool": {
3153
- const previousMessage = messages[messages.length - 1];
3154
- if (previousMessage?.role !== "assistant")
3155
- throw new Error(
3156
- "A tool message must be preceded by an assistant message."
3157
- );
3158
- for (const tool of lmMessage.content) {
3159
- const toolCall = previousMessage.content.find(
3160
- (c) => c.type === "tool-call" && c.toolCallId === tool.toolCallId
3161
- );
3162
- if (!toolCall)
3163
- throw new Error("Received tool result for an unknown tool call.");
3164
- if (toolCall.toolName !== tool.toolName)
3165
- throw new Error("Tool call name mismatch.");
3166
- toolCall.result = tool.result;
3167
- if (tool.isError) {
3168
- toolCall.isError = true;
3169
- }
3170
- }
3171
- break;
3172
- }
3173
- default: {
3174
- const unhandledRole = role;
3175
- throw new Error(`Unknown message role: ${unhandledRole}`);
3176
- }
3177
- }
3178
- }
3179
- return messages;
3180
- };
3181
-
3182
- // src/runtimes/edge/converters/fromCoreMessage.ts
3183
- var fromCoreMessages = (message) => {
3184
- return message.map((message2) => {
3185
- return {
3186
- id: generateId(),
3187
- createdAt: /* @__PURE__ */ new Date(),
3188
- ...message2.role === "assistant" ? {
3189
- status: { type: "done" }
3190
- } : void 0,
3191
- ...message2
3192
- };
3193
- });
3194
- };
3195
-
3196
3261
  // src/runtimes/local/LocalRuntime.tsx
3197
3262
  var LocalRuntime = class extends BaseAssistantRuntime {
3198
3263
  _proxyConfigProvider;
@@ -3271,47 +3336,47 @@ var LocalThreadRuntime = class {
3271
3336
  async startRun(parentId) {
3272
3337
  this.repository.resetHead(parentId);
3273
3338
  const messages = this.repository.getMessages();
3274
- const message = {
3339
+ let message = {
3275
3340
  id: generateId(),
3276
3341
  role: "assistant",
3277
3342
  status: { type: "in_progress" },
3278
3343
  content: [{ type: "text", text: "" }],
3279
3344
  createdAt: /* @__PURE__ */ new Date()
3280
3345
  };
3281
- this.repository.addOrUpdateMessage(parentId, { ...message });
3282
3346
  this.abortController?.abort();
3283
3347
  this.abortController = new AbortController();
3348
+ this.repository.addOrUpdateMessage(parentId, { ...message });
3284
3349
  this.notifySubscribers();
3285
- try {
3286
- const updateHandler = ({ content }) => {
3287
- message.content = content;
3288
- const newMessage = { ...message };
3289
- this.repository.addOrUpdateMessage(parentId, newMessage);
3290
- this.notifySubscribers();
3291
- return newMessage;
3350
+ const updateMessage = (m) => {
3351
+ message = {
3352
+ ...message,
3353
+ ...m
3292
3354
  };
3355
+ this.repository.addOrUpdateMessage(parentId, message);
3356
+ this.notifySubscribers();
3357
+ return message;
3358
+ };
3359
+ try {
3293
3360
  const result = await this.adapter.run({
3294
3361
  messages,
3295
3362
  abortSignal: this.abortController.signal,
3296
3363
  config: this.configProvider.getModelConfig(),
3297
- onUpdate: updateHandler
3364
+ onUpdate: updateMessage
3298
3365
  });
3299
- if (result !== void 0) {
3300
- updateHandler(result);
3301
- }
3302
3366
  if (result.status?.type === "in_progress")
3303
3367
  throw new Error(
3304
3368
  "Unexpected in_progress status returned from ChatModelAdapter"
3305
3369
  );
3306
- message.status = result.status ?? { type: "done" };
3370
+ this.abortController = null;
3371
+ updateMessage({ status: { type: "done" }, ...result });
3307
3372
  this.repository.addOrUpdateMessage(parentId, { ...message });
3308
3373
  } catch (e) {
3309
- message.status = { type: "error", error: e };
3310
- this.repository.addOrUpdateMessage(parentId, { ...message });
3311
- throw e;
3312
- } finally {
3374
+ const isAbortError = e instanceof Error && e.name === "AbortError";
3313
3375
  this.abortController = null;
3314
- this.notifySubscribers();
3376
+ updateMessage({
3377
+ status: isAbortError ? { type: "cancelled" } : { type: "error", error: e }
3378
+ });
3379
+ if (!isAbortError) throw e;
3315
3380
  }
3316
3381
  }
3317
3382
  cancelRun() {
@@ -4068,9 +4133,12 @@ export {
4068
4133
  user_message_default as UserMessage,
4069
4134
  fromCoreMessages,
4070
4135
  fromLanguageModelMessages,
4136
+ fromLanguageModelTools,
4071
4137
  makeAssistantTool,
4072
4138
  makeAssistantToolUI,
4139
+ toCoreMessages,
4073
4140
  toLanguageModelMessages,
4141
+ toLanguageModelTools,
4074
4142
  useActionBarCopy,
4075
4143
  useActionBarEdit,
4076
4144
  useActionBarReload,