@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.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
  };