@assistant-ui/react 0.4.1 → 0.4.3

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.mjs CHANGED
@@ -831,21 +831,30 @@ var ActionBarPrimitiveRoot = forwardRef(({ hideWhenRunning, autohide, autohideFl
831
831
  ActionBarPrimitiveRoot.displayName = "ActionBarPrimitive.Root";
832
832
 
833
833
  // src/utils/createActionButton.tsx
834
- import { composeEventHandlers } from "@radix-ui/primitive";
835
- import { Primitive as Primitive2 } from "@radix-ui/react-primitive";
836
834
  import { forwardRef as forwardRef2 } from "react";
835
+ import { Primitive as Primitive2 } from "@radix-ui/react-primitive";
836
+ import { composeEventHandlers } from "@radix-ui/primitive";
837
837
  import { jsx as jsx5 } from "react/jsx-runtime";
838
- var createActionButton = (displayName, useActionButton) => {
838
+ var createActionButton = (displayName, useActionButton, forwardProps = []) => {
839
839
  const ActionButton = forwardRef2((props, forwardedRef) => {
840
- const callback = useActionButton(props);
840
+ const forwardedProps = {};
841
+ const primitiveProps = {};
842
+ Object.keys(props).forEach((key) => {
843
+ if (forwardProps.includes(key)) {
844
+ forwardedProps[key] = props[key];
845
+ } else {
846
+ primitiveProps[key] = props[key];
847
+ }
848
+ });
849
+ const callback = useActionButton(forwardedProps);
841
850
  return /* @__PURE__ */ jsx5(
842
851
  Primitive2.button,
843
852
  {
844
853
  type: "button",
845
854
  disabled: !callback,
846
- ...props,
855
+ ...primitiveProps,
847
856
  ref: forwardedRef,
848
- onClick: composeEventHandlers(props.onClick, () => {
857
+ onClick: composeEventHandlers(primitiveProps.onClick, () => {
849
858
  callback?.();
850
859
  })
851
860
  }
@@ -858,7 +867,8 @@ var createActionButton = (displayName, useActionButton) => {
858
867
  // src/primitives/actionBar/ActionBarCopy.tsx
859
868
  var ActionBarPrimitiveCopy = createActionButton(
860
869
  "ActionBarPrimitive.Copy",
861
- useActionBarCopy
870
+ useActionBarCopy,
871
+ ["copiedDuration"]
862
872
  );
863
873
 
864
874
  // src/primitives/actionBar/ActionBarReload.tsx
@@ -1169,7 +1179,7 @@ import { Primitive as Primitive4 } from "@radix-ui/react-primitive";
1169
1179
  import { forwardRef as forwardRef7 } from "react";
1170
1180
 
1171
1181
  // src/utils/hooks/useSmooth.tsx
1172
- import { useEffect as useEffect8, useState as useState5 } from "react";
1182
+ import { useEffect as useEffect8, useRef as useRef4, useState as useState5 } from "react";
1173
1183
  var TextStreamAnimator = class {
1174
1184
  constructor(currentText, setText) {
1175
1185
  this.currentText = currentText;
@@ -1215,6 +1225,9 @@ var TextStreamAnimator = class {
1215
1225
  };
1216
1226
  };
1217
1227
  var useSmooth = (text, smooth = false) => {
1228
+ const { useMessage } = useMessageContext();
1229
+ const id = useMessage((m) => m.message.id);
1230
+ const idRef = useRef4(id);
1218
1231
  const [displayedText, setDisplayedText] = useState5(text);
1219
1232
  const [animatorRef] = useState5(
1220
1233
  new TextStreamAnimator(text, setDisplayedText)
@@ -1224,7 +1237,8 @@ var useSmooth = (text, smooth = false) => {
1224
1237
  animatorRef.stop();
1225
1238
  return;
1226
1239
  }
1227
- if (!text.startsWith(animatorRef.targetText)) {
1240
+ if (idRef.current !== id || !text.startsWith(animatorRef.targetText)) {
1241
+ idRef.current = id;
1228
1242
  setDisplayedText(text);
1229
1243
  animatorRef.currentText = text;
1230
1244
  animatorRef.targetText = text;
@@ -1233,7 +1247,7 @@ var useSmooth = (text, smooth = false) => {
1233
1247
  }
1234
1248
  animatorRef.targetText = text;
1235
1249
  animatorRef.start();
1236
- }, [animatorRef, smooth, text]);
1250
+ }, [animatorRef, id, smooth, text]);
1237
1251
  useEffect8(() => {
1238
1252
  return () => {
1239
1253
  animatorRef.stop();
@@ -1421,7 +1435,7 @@ import {
1421
1435
  forwardRef as forwardRef11,
1422
1436
  useCallback as useCallback15,
1423
1437
  useEffect as useEffect9,
1424
- useRef as useRef4
1438
+ useRef as useRef5
1425
1439
  } from "react";
1426
1440
  import TextareaAutosize from "react-textarea-autosize";
1427
1441
  import { useEscapeKeydown } from "@radix-ui/react-use-escape-keydown";
@@ -1435,7 +1449,7 @@ var ComposerPrimitiveInput = forwardRef11(
1435
1449
  return c.value;
1436
1450
  });
1437
1451
  const Component = asChild ? Slot : TextareaAutosize;
1438
- const textareaRef = useRef4(null);
1452
+ const textareaRef = useRef5(null);
1439
1453
  const ref = useComposedRefs2(forwardedRef, textareaRef);
1440
1454
  useEscapeKeydown((e) => {
1441
1455
  const composer = useComposer.getState();
@@ -1581,7 +1595,7 @@ import { forwardRef as forwardRef14 } from "react";
1581
1595
 
1582
1596
  // src/primitive-hooks/thread/useThreadViewportAutoScroll.tsx
1583
1597
  import { useComposedRefs as useComposedRefs3 } from "@radix-ui/react-compose-refs";
1584
- import { useRef as useRef5 } from "react";
1598
+ import { useRef as useRef6 } from "react";
1585
1599
 
1586
1600
  // src/utils/hooks/useOnResizeContent.tsx
1587
1601
  import { useCallbackRef as useCallbackRef2 } from "@radix-ui/react-use-callback-ref";
@@ -1640,16 +1654,13 @@ var useOnScrollToBottom = (callback) => {
1640
1654
  var useThreadViewportAutoScroll = ({
1641
1655
  autoScroll = true
1642
1656
  }) => {
1643
- const divRef = useRef5(null);
1657
+ const divRef = useRef6(null);
1644
1658
  const { useViewport } = useThreadContext();
1645
- const firstRenderRef = useRef5(true);
1646
- const lastScrollTop = useRef5(0);
1647
- const isScrollingToBottomRef = useRef5(false);
1648
- const scrollToBottom = () => {
1659
+ const lastScrollTop = useRef6(0);
1660
+ const isScrollingToBottomRef = useRef6(false);
1661
+ const scrollToBottom = (behavior) => {
1649
1662
  const div = divRef.current;
1650
1663
  if (!div || !autoScroll) return;
1651
- const behavior = firstRenderRef.current ? "instant" : "auto";
1652
- firstRenderRef.current = false;
1653
1664
  isScrollingToBottomRef.current = true;
1654
1665
  div.scrollTo({ top: div.scrollHeight, behavior });
1655
1666
  };
@@ -1660,7 +1671,9 @@ var useThreadViewportAutoScroll = ({
1660
1671
  const newIsAtBottom = div.scrollHeight - div.scrollTop <= div.clientHeight;
1661
1672
  if (!newIsAtBottom && lastScrollTop.current < div.scrollTop) {
1662
1673
  } else {
1663
- isScrollingToBottomRef.current = newIsAtBottom;
1674
+ if (newIsAtBottom) {
1675
+ isScrollingToBottomRef.current = false;
1676
+ }
1664
1677
  if (newIsAtBottom !== isAtBottom) {
1665
1678
  useViewport.setState({
1666
1679
  isAtBottom: newIsAtBottom
@@ -1670,11 +1683,10 @@ var useThreadViewportAutoScroll = ({
1670
1683
  lastScrollTop.current = div.scrollTop;
1671
1684
  };
1672
1685
  const resizeRef = useOnResizeContent(() => {
1673
- if (!isScrollingToBottomRef.current && !useViewport.getState().isAtBottom && !firstRenderRef.current) {
1674
- handleScroll();
1675
- } else {
1676
- scrollToBottom();
1686
+ if (isScrollingToBottomRef.current || useViewport.getState().isAtBottom) {
1687
+ scrollToBottom("instant");
1677
1688
  }
1689
+ handleScroll();
1678
1690
  });
1679
1691
  const scrollRef = useManagedRef((el) => {
1680
1692
  el.addEventListener("scroll", handleScroll);
@@ -1684,7 +1696,7 @@ var useThreadViewportAutoScroll = ({
1684
1696
  });
1685
1697
  const autoScrollRef = useComposedRefs3(resizeRef, scrollRef, divRef);
1686
1698
  useOnScrollToBottom(() => {
1687
- scrollToBottom();
1699
+ scrollToBottom("auto");
1688
1700
  });
1689
1701
  return autoScrollRef;
1690
1702
  };
@@ -1885,7 +1897,8 @@ var ThreadPrimitiveScrollToBottom = createActionButton(
1885
1897
  // src/primitives/thread/ThreadSuggestion.tsx
1886
1898
  var ThreadPrimitiveSuggestion = createActionButton(
1887
1899
  "ThreadPrimitive.Suggestion",
1888
- useThreadSuggestion
1900
+ useThreadSuggestion,
1901
+ ["prompt", "autoSend", "method"]
1889
1902
  );
1890
1903
 
1891
1904
  // src/runtimes/local/useLocalRuntime.tsx
@@ -2278,7 +2291,7 @@ function assistantDecoderStream() {
2278
2291
  let currentToolCall;
2279
2292
  return new TransformStream({
2280
2293
  transform(chunk, controller) {
2281
- const [code, valueJson] = chunk.split(":");
2294
+ const [code, valueJson] = parseStreamPart(chunk);
2282
2295
  const value = JSON.parse(valueJson);
2283
2296
  if (currentToolCall && code !== "2" /* ToolCallArgsTextDelta */ && code !== "E" /* Error */) {
2284
2297
  controller.enqueue({
@@ -2337,6 +2350,14 @@ function assistantDecoderStream() {
2337
2350
  }
2338
2351
  });
2339
2352
  }
2353
+ var parseStreamPart = (part) => {
2354
+ const index = part.indexOf(":");
2355
+ if (index === -1) throw new Error("Invalid stream part");
2356
+ return [
2357
+ part.slice(0, index),
2358
+ part.slice(index + 1)
2359
+ ];
2360
+ };
2340
2361
 
2341
2362
  // src/runtimes/edge/streams/chunkByLineStream.ts
2342
2363
  function chunkByLineStream() {