@assistant-ui/react 0.5.15 → 0.5.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -186,10 +186,13 @@ type ChatModelRunOptions = {
186
186
  messages: ThreadMessage[];
187
187
  abortSignal: AbortSignal;
188
188
  config: ModelConfig;
189
+ /**
190
+ * @deprecated Declare the run function as an AsyncGenerator instead. This method will be removed in v0.6
191
+ */
189
192
  onUpdate: (result: ChatModelRunUpdate) => void;
190
193
  };
191
194
  type ChatModelAdapter = {
192
- run: (options: ChatModelRunOptions) => Promise<ChatModelRunResult>;
195
+ run: (options: ChatModelRunOptions) => Promise<ChatModelRunResult> | AsyncGenerator<ChatModelRunResult, void>;
193
196
  };
194
197
 
195
198
  declare abstract class BaseAssistantRuntime<TThreadRuntime extends ReactThreadRuntime> implements AssistantRuntime {
@@ -245,6 +248,7 @@ declare class LocalThreadRuntime implements ThreadRuntime {
245
248
  cancel: true;
246
249
  copy: true;
247
250
  }>;
251
+ readonly isDisabled = false;
248
252
  get messages(): ThreadMessage[];
249
253
  get isRunning(): boolean;
250
254
  constructor(configProvider: ModelConfigProvider, adapter: ChatModelAdapter, options?: LocalRuntimeOptions | undefined);
@@ -295,7 +299,7 @@ type EdgeChatAdapterOptions = {
295
299
  declare class EdgeChatAdapter implements ChatModelAdapter {
296
300
  private options;
297
301
  constructor(options: EdgeChatAdapterOptions);
298
- run({ messages, abortSignal, config, onUpdate }: ChatModelRunOptions): Promise<ChatModelRunResult>;
302
+ run({ messages, abortSignal, config }: ChatModelRunOptions): AsyncGenerator<ChatModelRunResult, void, unknown>;
299
303
  }
300
304
 
301
305
  type EdgeRuntimeOptions = EdgeChatAdapterOptions & LocalRuntimeOptions;
@@ -565,6 +569,7 @@ type ExternalStoreMessageConverterAdapter<T> = {
565
569
  };
566
570
  type ExternalStoreAdapterBase<T> = {
567
571
  threadId?: string | undefined;
572
+ isDisabled?: boolean | undefined;
568
573
  isRunning?: boolean | undefined;
569
574
  messages: T[];
570
575
  setMessages?: ((messages: T[]) => void) | undefined;
@@ -656,7 +661,8 @@ declare class ExternalStoreThreadRuntime implements ReactThreadRuntime {
656
661
  cancel: boolean;
657
662
  copy: boolean;
658
663
  };
659
- messages: ThreadMessage[];
664
+ messages: any[];
665
+ isDisabled: boolean;
660
666
  isRunning: boolean;
661
667
  constructor(store: ExternalStoreAdapter<any>);
662
668
  getBranches(messageId: string): string[];
@@ -760,6 +766,7 @@ declare function useAssistantContext(options: {
760
766
 
761
767
  type ThreadState = Readonly<{
762
768
  isRunning: boolean;
769
+ isDisabled: boolean;
763
770
  }>;
764
771
 
765
772
  type ThreadViewportState = Readonly<{
@@ -932,6 +939,7 @@ declare const useThreadEmpty: () => boolean;
932
939
  type ThreadIfFilters = {
933
940
  empty: boolean | undefined;
934
941
  running: boolean | undefined;
942
+ disabled: boolean | undefined;
935
943
  };
936
944
  type UseThreadIfProps = RequireAtLeastOne<ThreadIfFilters>;
937
945
  declare const useThreadIf: (props: UseThreadIfProps) => boolean;
package/dist/index.d.ts CHANGED
@@ -186,10 +186,13 @@ type ChatModelRunOptions = {
186
186
  messages: ThreadMessage[];
187
187
  abortSignal: AbortSignal;
188
188
  config: ModelConfig;
189
+ /**
190
+ * @deprecated Declare the run function as an AsyncGenerator instead. This method will be removed in v0.6
191
+ */
189
192
  onUpdate: (result: ChatModelRunUpdate) => void;
190
193
  };
191
194
  type ChatModelAdapter = {
192
- run: (options: ChatModelRunOptions) => Promise<ChatModelRunResult>;
195
+ run: (options: ChatModelRunOptions) => Promise<ChatModelRunResult> | AsyncGenerator<ChatModelRunResult, void>;
193
196
  };
194
197
 
195
198
  declare abstract class BaseAssistantRuntime<TThreadRuntime extends ReactThreadRuntime> implements AssistantRuntime {
@@ -245,6 +248,7 @@ declare class LocalThreadRuntime implements ThreadRuntime {
245
248
  cancel: true;
246
249
  copy: true;
247
250
  }>;
251
+ readonly isDisabled = false;
248
252
  get messages(): ThreadMessage[];
249
253
  get isRunning(): boolean;
250
254
  constructor(configProvider: ModelConfigProvider, adapter: ChatModelAdapter, options?: LocalRuntimeOptions | undefined);
@@ -295,7 +299,7 @@ type EdgeChatAdapterOptions = {
295
299
  declare class EdgeChatAdapter implements ChatModelAdapter {
296
300
  private options;
297
301
  constructor(options: EdgeChatAdapterOptions);
298
- run({ messages, abortSignal, config, onUpdate }: ChatModelRunOptions): Promise<ChatModelRunResult>;
302
+ run({ messages, abortSignal, config }: ChatModelRunOptions): AsyncGenerator<ChatModelRunResult, void, unknown>;
299
303
  }
300
304
 
301
305
  type EdgeRuntimeOptions = EdgeChatAdapterOptions & LocalRuntimeOptions;
@@ -565,6 +569,7 @@ type ExternalStoreMessageConverterAdapter<T> = {
565
569
  };
566
570
  type ExternalStoreAdapterBase<T> = {
567
571
  threadId?: string | undefined;
572
+ isDisabled?: boolean | undefined;
568
573
  isRunning?: boolean | undefined;
569
574
  messages: T[];
570
575
  setMessages?: ((messages: T[]) => void) | undefined;
@@ -656,7 +661,8 @@ declare class ExternalStoreThreadRuntime implements ReactThreadRuntime {
656
661
  cancel: boolean;
657
662
  copy: boolean;
658
663
  };
659
- messages: ThreadMessage[];
664
+ messages: any[];
665
+ isDisabled: boolean;
660
666
  isRunning: boolean;
661
667
  constructor(store: ExternalStoreAdapter<any>);
662
668
  getBranches(messageId: string): string[];
@@ -760,6 +766,7 @@ declare function useAssistantContext(options: {
760
766
 
761
767
  type ThreadState = Readonly<{
762
768
  isRunning: boolean;
769
+ isDisabled: boolean;
763
770
  }>;
764
771
 
765
772
  type ThreadViewportState = Readonly<{
@@ -932,6 +939,7 @@ declare const useThreadEmpty: () => boolean;
932
939
  type ThreadIfFilters = {
933
940
  empty: boolean | undefined;
934
941
  running: boolean | undefined;
942
+ disabled: boolean | undefined;
935
943
  };
936
944
  type UseThreadIfProps = RequireAtLeastOne<ThreadIfFilters>;
937
945
  declare const useThreadIf: (props: UseThreadIfProps) => boolean;
package/dist/index.js CHANGED
@@ -304,6 +304,7 @@ var makeComposerStore = (useThreadMessages, useThreadActions) => {
304
304
  var import_zustand4 = require("zustand");
305
305
  var makeThreadStore = (runtimeRef) => {
306
306
  return (0, import_zustand4.create)(() => ({
307
+ isDisabled: runtimeRef.getState().isDisabled,
307
308
  isRunning: runtimeRef.getState().isRunning
308
309
  }));
309
310
  };
@@ -402,10 +403,12 @@ var ThreadProvider = ({
402
403
  (0, import_react4.useCallback)(
403
404
  (thread) => {
404
405
  const onThreadUpdate = () => {
405
- if (thread.isRunning !== context.useThread.getState().isRunning) {
406
+ const threadState = context.useThread.getState();
407
+ if (thread.isRunning !== threadState.isRunning || thread.isDisabled !== threadState.isDisabled) {
406
408
  context.useThread.setState(
407
409
  Object.freeze({
408
- isRunning: thread.isRunning
410
+ isRunning: thread.isRunning,
411
+ isDisabled: thread.isDisabled
409
412
  }),
410
413
  true
411
414
  );
@@ -716,7 +719,7 @@ var useActionBarReload = () => {
716
719
  const { useMessage } = useMessageContext();
717
720
  const disabled = useCombinedStore(
718
721
  [useThread, useMessage],
719
- (t, m) => t.isRunning || m.message.role !== "assistant"
722
+ (t, m) => t.isRunning || t.isDisabled || m.message.role !== "assistant"
720
723
  );
721
724
  const callback = (0, import_react19.useCallback)(() => {
722
725
  const { parentId } = useMessage.getState();
@@ -802,9 +805,16 @@ var useComposerIf = (props) => {
802
805
  // src/primitive-hooks/composer/useComposerSend.tsx
803
806
  var import_react23 = require("react");
804
807
  var useComposerSend = () => {
805
- const { useViewport, useComposer: useNewComposer } = useThreadContext();
808
+ const {
809
+ useThread,
810
+ useViewport,
811
+ useComposer: useNewComposer
812
+ } = useThreadContext();
806
813
  const { useComposer } = useComposerContext();
807
- const disabled = useComposer((c) => !c.isEditing || c.value.length === 0);
814
+ const disabled = useCombinedStore(
815
+ [useThread, useComposer],
816
+ (t, c) => t.isDisabled || t.isRunning || !c.isEditing || c.value.length === 0
817
+ );
808
818
  const callback = (0, import_react23.useCallback)(() => {
809
819
  const composerState = useComposer.getState();
810
820
  if (!composerState.isEditing) return;
@@ -883,6 +893,8 @@ var useThreadIf = (props) => {
883
893
  if (props.empty === false && messages.length === 0) return false;
884
894
  if (props.running === true && !thread.isRunning) return false;
885
895
  if (props.running === false && thread.isRunning) return false;
896
+ if (props.disabled === true && thread.isDisabled) return false;
897
+ if (props.disabled === false && thread.isDisabled) return false;
886
898
  return true;
887
899
  }
888
900
  );
@@ -914,7 +926,7 @@ var useThreadSuggestion = ({
914
926
  }) => {
915
927
  const { useThread, useComposer } = useThreadContext();
916
928
  const append = useAppendMessage();
917
- const disabled = useThread((t) => t.isRunning);
929
+ const disabled = useThread((t) => t.isDisabled);
918
930
  const callback = (0, import_react25.useCallback)(() => {
919
931
  const thread = useThread.getState();
920
932
  const composer = useComposer.getState();
@@ -1597,7 +1609,14 @@ var import_react_textarea_autosize = __toESM(require("react-textarea-autosize"))
1597
1609
  var import_react_use_escape_keydown = require("@radix-ui/react-use-escape-keydown");
1598
1610
  var import_jsx_runtime19 = require("react/jsx-runtime");
1599
1611
  var ComposerPrimitiveInput = (0, import_react41.forwardRef)(
1600
- ({ autoFocus = false, asChild, disabled, onChange, onKeyDown, ...rest }, forwardedRef) => {
1612
+ ({
1613
+ autoFocus = false,
1614
+ asChild,
1615
+ disabled: disabledProp,
1616
+ onChange,
1617
+ onKeyDown,
1618
+ ...rest
1619
+ }, forwardedRef) => {
1601
1620
  const { useThread } = useThreadContext();
1602
1621
  const { useComposer, type } = useComposerContext();
1603
1622
  const value = useComposer((c) => {
@@ -1605,6 +1624,7 @@ var ComposerPrimitiveInput = (0, import_react41.forwardRef)(
1605
1624
  return c.value;
1606
1625
  });
1607
1626
  const Component = asChild ? import_react_slot.Slot : import_react_textarea_autosize.default;
1627
+ const isDisabled = useThread((t) => t.isDisabled) ?? disabledProp ?? false;
1608
1628
  const textareaRef = (0, import_react41.useRef)(null);
1609
1629
  const ref = (0, import_react_compose_refs2.useComposedRefs)(forwardedRef, textareaRef);
1610
1630
  (0, import_react_use_escape_keydown.useEscapeKeydown)((e) => {
@@ -1615,7 +1635,7 @@ var ComposerPrimitiveInput = (0, import_react41.forwardRef)(
1615
1635
  }
1616
1636
  });
1617
1637
  const handleKeyPress = (e) => {
1618
- if (disabled) return;
1638
+ if (isDisabled) return;
1619
1639
  if (e.key === "Enter" && e.shiftKey === false) {
1620
1640
  const isRunning = useThread.getState().isRunning;
1621
1641
  if (!isRunning) {
@@ -1624,7 +1644,7 @@ var ComposerPrimitiveInput = (0, import_react41.forwardRef)(
1624
1644
  }
1625
1645
  }
1626
1646
  };
1627
- const autoFocusEnabled = autoFocus && !disabled;
1647
+ const autoFocusEnabled = autoFocus && !isDisabled;
1628
1648
  const focus = (0, import_react41.useCallback)(() => {
1629
1649
  const textarea = textareaRef.current;
1630
1650
  if (!textarea || !autoFocusEnabled) return;
@@ -1647,7 +1667,7 @@ var ComposerPrimitiveInput = (0, import_react41.forwardRef)(
1647
1667
  value,
1648
1668
  ...rest,
1649
1669
  ref,
1650
- disabled,
1670
+ disabled: isDisabled,
1651
1671
  onChange: (0, import_primitive5.composeEventHandlers)(onChange, (e) => {
1652
1672
  const composerState = useComposer.getState();
1653
1673
  if (!composerState.isEditing) return;
@@ -3408,7 +3428,7 @@ var EdgeChatAdapter = class {
3408
3428
  constructor(options) {
3409
3429
  this.options = options;
3410
3430
  }
3411
- async run({ messages, abortSignal, config, onUpdate }) {
3431
+ async *run({ messages, abortSignal, config }) {
3412
3432
  const result = await fetch(this.options.api, {
3413
3433
  method: "POST",
3414
3434
  headers: {
@@ -3429,11 +3449,10 @@ var EdgeChatAdapter = class {
3429
3449
  const stream = result.body.pipeThrough(new TextDecoderStream()).pipeThrough(chunkByLineStream()).pipeThrough(assistantDecoderStream()).pipeThrough(toolResultStream(config.tools)).pipeThrough(runResultStream());
3430
3450
  let update;
3431
3451
  for await (update of asAsyncIterable(stream)) {
3432
- onUpdate(update);
3452
+ yield update;
3433
3453
  }
3434
3454
  if (update === void 0)
3435
3455
  throw new Error("No data received from Edge Runtime");
3436
- return update;
3437
3456
  }
3438
3457
  };
3439
3458
 
@@ -3475,6 +3494,7 @@ var LocalThreadRuntime = class {
3475
3494
  abortController = null;
3476
3495
  repository = new MessageRepository();
3477
3496
  capabilities = CAPABILITIES;
3497
+ isDisabled = false;
3478
3498
  get messages() {
3479
3499
  return this.repository.getMessages();
3480
3500
  }
@@ -3551,21 +3571,27 @@ var LocalThreadRuntime = class {
3551
3571
  });
3552
3572
  }
3553
3573
  try {
3554
- const result = await this.adapter.run({
3574
+ const promiseOrGenerator = this.adapter.run({
3555
3575
  messages,
3556
3576
  abortSignal: this.abortController.signal,
3557
3577
  config: this.configProvider.getModelConfig(),
3558
3578
  onUpdate: updateMessage
3559
3579
  });
3560
- if (result.status?.type === "running")
3561
- throw new Error(
3562
- "Unexpected running status returned from ChatModelAdapter"
3563
- );
3580
+ if (Symbol.asyncIterator in promiseOrGenerator) {
3581
+ for await (const r of promiseOrGenerator) {
3582
+ updateMessage(r);
3583
+ }
3584
+ } else {
3585
+ updateMessage(await promiseOrGenerator);
3586
+ }
3564
3587
  this.abortController = null;
3565
- updateMessage({
3566
- status: { type: "complete", reason: "unknown" },
3567
- ...result
3568
- });
3588
+ if (message.status.type === "running") {
3589
+ updateMessage({
3590
+ status: { type: "complete", reason: "unknown" }
3591
+ });
3592
+ } else {
3593
+ this.notifySubscribers();
3594
+ }
3569
3595
  } catch (e) {
3570
3596
  this.abortController = null;
3571
3597
  if (e instanceof Error && e.name === "AbortError") {
@@ -3785,6 +3811,7 @@ var useExternalStoreSync = (adapter, updateData) => {
3785
3811
  }, [adapter.convertMessage]);
3786
3812
  (0, import_react55.useEffect)(() => {
3787
3813
  updateData(
3814
+ adapter.isDisabled ?? false,
3788
3815
  adapter.isRunning ?? false,
3789
3816
  converter.convertMessages(adapter.messages, convertCallback)
3790
3817
  );
@@ -3792,8 +3819,9 @@ var useExternalStoreSync = (adapter, updateData) => {
3792
3819
  updateData,
3793
3820
  converter,
3794
3821
  convertCallback,
3795
- adapter.messages,
3796
- adapter.isRunning
3822
+ adapter.isDisabled,
3823
+ adapter.isRunning,
3824
+ adapter.messages
3797
3825
  ]);
3798
3826
  };
3799
3827
 
@@ -3804,6 +3832,9 @@ var hasUpcomingMessage = (isRunning, messages) => {
3804
3832
  var ExternalStoreThreadRuntime = class {
3805
3833
  constructor(store) {
3806
3834
  this.store = store;
3835
+ this.isDisabled = store.isDisabled ?? false;
3836
+ this.isRunning = store.isRunning ?? false;
3837
+ this.messages = store.messages;
3807
3838
  this.useStore = (0, import_zustand14.create)(() => ({
3808
3839
  store
3809
3840
  }));
@@ -3821,8 +3852,9 @@ var ExternalStoreThreadRuntime = class {
3821
3852
  copy: this.store.onCopy !== null
3822
3853
  };
3823
3854
  }
3824
- messages = [];
3825
- isRunning = false;
3855
+ messages;
3856
+ isDisabled;
3857
+ isRunning;
3826
3858
  getBranches(messageId) {
3827
3859
  return this.repository.getBranches(messageId);
3828
3860
  }
@@ -3873,7 +3905,7 @@ var ExternalStoreThreadRuntime = class {
3873
3905
  this.useStore.setState({ store: this.store });
3874
3906
  }
3875
3907
  }
3876
- updateData = (isRunning, vm) => {
3908
+ updateData = (isDisabled, isRunning, vm) => {
3877
3909
  for (let i = 0; i < vm.length; i++) {
3878
3910
  const message = vm[i];
3879
3911
  const parent = vm[i - 1];
@@ -3896,6 +3928,7 @@ var ExternalStoreThreadRuntime = class {
3896
3928
  this.assistantOptimisticId ?? vm.at(-1)?.id ?? null
3897
3929
  );
3898
3930
  this.messages = this.repository.getMessages();
3931
+ this.isDisabled = isDisabled;
3899
3932
  this.isRunning = isRunning;
3900
3933
  for (const callback of this._subscriptions) callback();
3901
3934
  };