@assistant-ui/react 0.5.15 → 0.5.17

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.mjs CHANGED
@@ -209,6 +209,7 @@ var makeComposerStore = (useThreadMessages, useThreadActions) => {
209
209
  import { create as create4 } from "zustand";
210
210
  var makeThreadStore = (runtimeRef) => {
211
211
  return create4(() => ({
212
+ isDisabled: runtimeRef.getState().isDisabled,
212
213
  isRunning: runtimeRef.getState().isRunning
213
214
  }));
214
215
  };
@@ -307,10 +308,12 @@ var ThreadProvider = ({
307
308
  useCallback2(
308
309
  (thread) => {
309
310
  const onThreadUpdate = () => {
310
- if (thread.isRunning !== context.useThread.getState().isRunning) {
311
+ const threadState = context.useThread.getState();
312
+ if (thread.isRunning !== threadState.isRunning || thread.isDisabled !== threadState.isDisabled) {
311
313
  context.useThread.setState(
312
314
  Object.freeze({
313
- isRunning: thread.isRunning
315
+ isRunning: thread.isRunning,
316
+ isDisabled: thread.isDisabled
314
317
  }),
315
318
  true
316
319
  );
@@ -621,7 +624,7 @@ var useActionBarReload = () => {
621
624
  const { useMessage } = useMessageContext();
622
625
  const disabled = useCombinedStore(
623
626
  [useThread, useMessage],
624
- (t, m) => t.isRunning || m.message.role !== "assistant"
627
+ (t, m) => t.isRunning || t.isDisabled || m.message.role !== "assistant"
625
628
  );
626
629
  const callback = useCallback7(() => {
627
630
  const { parentId } = useMessage.getState();
@@ -707,9 +710,16 @@ var useComposerIf = (props) => {
707
710
  // src/primitive-hooks/composer/useComposerSend.tsx
708
711
  import { useCallback as useCallback11 } from "react";
709
712
  var useComposerSend = () => {
710
- const { useViewport, useComposer: useNewComposer } = useThreadContext();
713
+ const {
714
+ useThread,
715
+ useViewport,
716
+ useComposer: useNewComposer
717
+ } = useThreadContext();
711
718
  const { useComposer } = useComposerContext();
712
- const disabled = useComposer((c) => !c.isEditing || c.value.length === 0);
719
+ const disabled = useCombinedStore(
720
+ [useThread, useComposer],
721
+ (t, c) => t.isDisabled || t.isRunning || !c.isEditing || c.value.length === 0
722
+ );
713
723
  const callback = useCallback11(() => {
714
724
  const composerState = useComposer.getState();
715
725
  if (!composerState.isEditing) return;
@@ -788,6 +798,8 @@ var useThreadIf = (props) => {
788
798
  if (props.empty === false && messages.length === 0) return false;
789
799
  if (props.running === true && !thread.isRunning) return false;
790
800
  if (props.running === false && thread.isRunning) return false;
801
+ if (props.disabled === true && thread.isDisabled) return false;
802
+ if (props.disabled === false && thread.isDisabled) return false;
791
803
  return true;
792
804
  }
793
805
  );
@@ -819,7 +831,7 @@ var useThreadSuggestion = ({
819
831
  }) => {
820
832
  const { useThread, useComposer } = useThreadContext();
821
833
  const append = useAppendMessage();
822
- const disabled = useThread((t) => t.isRunning);
834
+ const disabled = useThread((t) => t.isDisabled);
823
835
  const callback = useCallback13(() => {
824
836
  const thread = useThread.getState();
825
837
  const composer = useComposer.getState();
@@ -1512,7 +1524,14 @@ import TextareaAutosize from "react-textarea-autosize";
1512
1524
  import { useEscapeKeydown } from "@radix-ui/react-use-escape-keydown";
1513
1525
  import { jsx as jsx19 } from "react/jsx-runtime";
1514
1526
  var ComposerPrimitiveInput = forwardRef11(
1515
- ({ autoFocus = false, asChild, disabled, onChange, onKeyDown, ...rest }, forwardedRef) => {
1527
+ ({
1528
+ autoFocus = false,
1529
+ asChild,
1530
+ disabled: disabledProp,
1531
+ onChange,
1532
+ onKeyDown,
1533
+ ...rest
1534
+ }, forwardedRef) => {
1516
1535
  const { useThread } = useThreadContext();
1517
1536
  const { useComposer, type } = useComposerContext();
1518
1537
  const value = useComposer((c) => {
@@ -1520,6 +1539,7 @@ var ComposerPrimitiveInput = forwardRef11(
1520
1539
  return c.value;
1521
1540
  });
1522
1541
  const Component = asChild ? Slot : TextareaAutosize;
1542
+ const isDisabled = useThread((t) => t.isDisabled) ?? disabledProp ?? false;
1523
1543
  const textareaRef = useRef4(null);
1524
1544
  const ref = useComposedRefs2(forwardedRef, textareaRef);
1525
1545
  useEscapeKeydown((e) => {
@@ -1530,7 +1550,7 @@ var ComposerPrimitiveInput = forwardRef11(
1530
1550
  }
1531
1551
  });
1532
1552
  const handleKeyPress = (e) => {
1533
- if (disabled) return;
1553
+ if (isDisabled) return;
1534
1554
  if (e.key === "Enter" && e.shiftKey === false) {
1535
1555
  const isRunning = useThread.getState().isRunning;
1536
1556
  if (!isRunning) {
@@ -1539,7 +1559,7 @@ var ComposerPrimitiveInput = forwardRef11(
1539
1559
  }
1540
1560
  }
1541
1561
  };
1542
- const autoFocusEnabled = autoFocus && !disabled;
1562
+ const autoFocusEnabled = autoFocus && !isDisabled;
1543
1563
  const focus = useCallback15(() => {
1544
1564
  const textarea = textareaRef.current;
1545
1565
  if (!textarea || !autoFocusEnabled) return;
@@ -1562,7 +1582,7 @@ var ComposerPrimitiveInput = forwardRef11(
1562
1582
  value,
1563
1583
  ...rest,
1564
1584
  ref,
1565
- disabled,
1585
+ disabled: isDisabled,
1566
1586
  onChange: composeEventHandlers5(onChange, (e) => {
1567
1587
  const composerState = useComposer.getState();
1568
1588
  if (!composerState.isEditing) return;
@@ -3325,7 +3345,7 @@ var EdgeChatAdapter = class {
3325
3345
  constructor(options) {
3326
3346
  this.options = options;
3327
3347
  }
3328
- async run({ messages, abortSignal, config, onUpdate }) {
3348
+ async *run({ messages, abortSignal, config }) {
3329
3349
  const result = await fetch(this.options.api, {
3330
3350
  method: "POST",
3331
3351
  headers: {
@@ -3346,11 +3366,10 @@ var EdgeChatAdapter = class {
3346
3366
  const stream = result.body.pipeThrough(new TextDecoderStream()).pipeThrough(chunkByLineStream()).pipeThrough(assistantDecoderStream()).pipeThrough(toolResultStream(config.tools)).pipeThrough(runResultStream());
3347
3367
  let update;
3348
3368
  for await (update of asAsyncIterable(stream)) {
3349
- onUpdate(update);
3369
+ yield update;
3350
3370
  }
3351
3371
  if (update === void 0)
3352
3372
  throw new Error("No data received from Edge Runtime");
3353
- return update;
3354
3373
  }
3355
3374
  };
3356
3375
 
@@ -3392,6 +3411,7 @@ var LocalThreadRuntime = class {
3392
3411
  abortController = null;
3393
3412
  repository = new MessageRepository();
3394
3413
  capabilities = CAPABILITIES;
3414
+ isDisabled = false;
3395
3415
  get messages() {
3396
3416
  return this.repository.getMessages();
3397
3417
  }
@@ -3468,21 +3488,27 @@ var LocalThreadRuntime = class {
3468
3488
  });
3469
3489
  }
3470
3490
  try {
3471
- const result = await this.adapter.run({
3491
+ const promiseOrGenerator = this.adapter.run({
3472
3492
  messages,
3473
3493
  abortSignal: this.abortController.signal,
3474
3494
  config: this.configProvider.getModelConfig(),
3475
3495
  onUpdate: updateMessage
3476
3496
  });
3477
- if (result.status?.type === "running")
3478
- throw new Error(
3479
- "Unexpected running status returned from ChatModelAdapter"
3480
- );
3497
+ if (Symbol.asyncIterator in promiseOrGenerator) {
3498
+ for await (const r of promiseOrGenerator) {
3499
+ updateMessage(r);
3500
+ }
3501
+ } else {
3502
+ updateMessage(await promiseOrGenerator);
3503
+ }
3481
3504
  this.abortController = null;
3482
- updateMessage({
3483
- status: { type: "complete", reason: "unknown" },
3484
- ...result
3485
- });
3505
+ if (message.status.type === "running") {
3506
+ updateMessage({
3507
+ status: { type: "complete", reason: "unknown" }
3508
+ });
3509
+ } else {
3510
+ this.notifySubscribers();
3511
+ }
3486
3512
  } catch (e) {
3487
3513
  this.abortController = null;
3488
3514
  if (e instanceof Error && e.name === "AbortError") {
@@ -3702,6 +3728,7 @@ var useExternalStoreSync = (adapter, updateData) => {
3702
3728
  }, [adapter.convertMessage]);
3703
3729
  useEffect11(() => {
3704
3730
  updateData(
3731
+ adapter.isDisabled ?? false,
3705
3732
  adapter.isRunning ?? false,
3706
3733
  converter.convertMessages(adapter.messages, convertCallback)
3707
3734
  );
@@ -3709,8 +3736,9 @@ var useExternalStoreSync = (adapter, updateData) => {
3709
3736
  updateData,
3710
3737
  converter,
3711
3738
  convertCallback,
3712
- adapter.messages,
3713
- adapter.isRunning
3739
+ adapter.isDisabled,
3740
+ adapter.isRunning,
3741
+ adapter.messages
3714
3742
  ]);
3715
3743
  };
3716
3744
 
@@ -3721,6 +3749,9 @@ var hasUpcomingMessage = (isRunning, messages) => {
3721
3749
  var ExternalStoreThreadRuntime = class {
3722
3750
  constructor(store) {
3723
3751
  this.store = store;
3752
+ this.isDisabled = store.isDisabled ?? false;
3753
+ this.isRunning = store.isRunning ?? false;
3754
+ this.messages = store.messages;
3724
3755
  this.useStore = create14(() => ({
3725
3756
  store
3726
3757
  }));
@@ -3738,8 +3769,9 @@ var ExternalStoreThreadRuntime = class {
3738
3769
  copy: this.store.onCopy !== null
3739
3770
  };
3740
3771
  }
3741
- messages = [];
3742
- isRunning = false;
3772
+ messages;
3773
+ isDisabled;
3774
+ isRunning;
3743
3775
  getBranches(messageId) {
3744
3776
  return this.repository.getBranches(messageId);
3745
3777
  }
@@ -3790,7 +3822,7 @@ var ExternalStoreThreadRuntime = class {
3790
3822
  this.useStore.setState({ store: this.store });
3791
3823
  }
3792
3824
  }
3793
- updateData = (isRunning, vm) => {
3825
+ updateData = (isDisabled, isRunning, vm) => {
3794
3826
  for (let i = 0; i < vm.length; i++) {
3795
3827
  const message = vm[i];
3796
3828
  const parent = vm[i - 1];
@@ -3813,6 +3845,7 @@ var ExternalStoreThreadRuntime = class {
3813
3845
  this.assistantOptimisticId ?? vm.at(-1)?.id ?? null
3814
3846
  );
3815
3847
  this.messages = this.repository.getMessages();
3848
+ this.isDisabled = isDisabled;
3816
3849
  this.isRunning = isRunning;
3817
3850
  for (const callback of this._subscriptions) callback();
3818
3851
  };