@assistant-ui/react 0.7.67 → 0.7.69

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.
@@ -11,4 +11,5 @@ export * as ThreadListItemPrimitive from "./threadListItem";
11
11
  export { useContentPartDisplay } from "./contentPart/useContentPartDisplay";
12
12
  export { useContentPartImage } from "./contentPart/useContentPartImage";
13
13
  export { useContentPartText } from "./contentPart/useContentPartText";
14
+ export { useThreadViewportAutoScroll } from "./thread/useThreadViewportAutoScroll";
14
15
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/primitives/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,kBAAkB,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,uBAAuB,MAAM,kBAAkB,CAAC;AAC5D,OAAO,KAAK,mBAAmB,MAAM,cAAc,CAAC;AACpD,OAAO,KAAK,qBAAqB,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,iBAAiB,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,oBAAoB,MAAM,eAAe,CAAC;AACtD,OAAO,KAAK,gBAAgB,MAAM,WAAW,CAAC;AAC9C,OAAO,KAAK,eAAe,MAAM,UAAU,CAAC;AAC5C,OAAO,KAAK,mBAAmB,MAAM,cAAc,CAAC;AACpD,OAAO,KAAK,uBAAuB,MAAM,kBAAkB,CAAC;AAE5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/primitives/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,kBAAkB,MAAM,aAAa,CAAC;AAClD,OAAO,KAAK,uBAAuB,MAAM,kBAAkB,CAAC;AAC5D,OAAO,KAAK,mBAAmB,MAAM,cAAc,CAAC;AACpD,OAAO,KAAK,qBAAqB,MAAM,gBAAgB,CAAC;AACxD,OAAO,KAAK,iBAAiB,MAAM,YAAY,CAAC;AAChD,OAAO,KAAK,oBAAoB,MAAM,eAAe,CAAC;AACtD,OAAO,KAAK,gBAAgB,MAAM,WAAW,CAAC;AAC9C,OAAO,KAAK,eAAe,MAAM,UAAU,CAAC;AAC5C,OAAO,KAAK,mBAAmB,MAAM,cAAc,CAAC;AACpD,OAAO,KAAK,uBAAuB,MAAM,kBAAkB,CAAC;AAE5D,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,2BAA2B,EAAE,MAAM,sCAAsC,CAAC"}
@@ -42,7 +42,8 @@ __export(primitives_exports, {
42
42
  ThreadPrimitive: () => ThreadPrimitive,
43
43
  useContentPartDisplay: () => import_useContentPartDisplay.useContentPartDisplay,
44
44
  useContentPartImage: () => import_useContentPartImage.useContentPartImage,
45
- useContentPartText: () => import_useContentPartText.useContentPartText
45
+ useContentPartText: () => import_useContentPartText.useContentPartText,
46
+ useThreadViewportAutoScroll: () => import_useThreadViewportAutoScroll.useThreadViewportAutoScroll
46
47
  });
47
48
  module.exports = __toCommonJS(primitives_exports);
48
49
  var ActionBarPrimitive = __toESM(require("./actionBar/index.js"));
@@ -58,6 +59,7 @@ var ThreadListItemPrimitive = __toESM(require("./threadListItem/index.js"));
58
59
  var import_useContentPartDisplay = require("./contentPart/useContentPartDisplay.js");
59
60
  var import_useContentPartImage = require("./contentPart/useContentPartImage.js");
60
61
  var import_useContentPartText = require("./contentPart/useContentPartText.js");
62
+ var import_useThreadViewportAutoScroll = require("./thread/useThreadViewportAutoScroll.js");
61
63
  // Annotate the CommonJS export names for ESM import in node:
62
64
  0 && (module.exports = {
63
65
  ActionBarPrimitive,
@@ -72,6 +74,7 @@ var import_useContentPartText = require("./contentPart/useContentPartText.js");
72
74
  ThreadPrimitive,
73
75
  useContentPartDisplay,
74
76
  useContentPartImage,
75
- useContentPartText
77
+ useContentPartText,
78
+ useThreadViewportAutoScroll
76
79
  });
77
80
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/primitives/index.ts"],"sourcesContent":["export * as ActionBarPrimitive from \"./actionBar\";\nexport * as AssistantModalPrimitive from \"./assistantModal\";\nexport * as AttachmentPrimitive from \"./attachment\";\nexport * as BranchPickerPrimitive from \"./branchPicker\";\nexport * as ComposerPrimitive from \"./composer\";\nexport * as ContentPartPrimitive from \"./contentPart\";\nexport * as MessagePrimitive from \"./message\";\nexport * as ThreadPrimitive from \"./thread\";\nexport * as ThreadListPrimitive from \"./threadList\";\nexport * as ThreadListItemPrimitive from \"./threadListItem\";\n\nexport { useContentPartDisplay } from \"./contentPart/useContentPartDisplay\";\nexport { useContentPartImage } from \"./contentPart/useContentPartImage\";\nexport { useContentPartText } from \"./contentPart/useContentPartText\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yBAAoC;AACpC,8BAAyC;AACzC,0BAAqC;AACrC,4BAAuC;AACvC,wBAAmC;AACnC,2BAAsC;AACtC,uBAAkC;AAClC,sBAAiC;AACjC,0BAAqC;AACrC,8BAAyC;AAEzC,mCAAsC;AACtC,iCAAoC;AACpC,gCAAmC;","names":[]}
1
+ {"version":3,"sources":["../../src/primitives/index.ts"],"sourcesContent":["export * as ActionBarPrimitive from \"./actionBar\";\nexport * as AssistantModalPrimitive from \"./assistantModal\";\nexport * as AttachmentPrimitive from \"./attachment\";\nexport * as BranchPickerPrimitive from \"./branchPicker\";\nexport * as ComposerPrimitive from \"./composer\";\nexport * as ContentPartPrimitive from \"./contentPart\";\nexport * as MessagePrimitive from \"./message\";\nexport * as ThreadPrimitive from \"./thread\";\nexport * as ThreadListPrimitive from \"./threadList\";\nexport * as ThreadListItemPrimitive from \"./threadListItem\";\n\nexport { useContentPartDisplay } from \"./contentPart/useContentPartDisplay\";\nexport { useContentPartImage } from \"./contentPart/useContentPartImage\";\nexport { useContentPartText } from \"./contentPart/useContentPartText\";\nexport { useThreadViewportAutoScroll } from \"./thread/useThreadViewportAutoScroll\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yBAAoC;AACpC,8BAAyC;AACzC,0BAAqC;AACrC,4BAAuC;AACvC,wBAAmC;AACnC,2BAAsC;AACtC,uBAAkC;AAClC,sBAAiC;AACjC,0BAAqC;AACrC,8BAAyC;AAEzC,mCAAsC;AACtC,iCAAoC;AACpC,gCAAmC;AACnC,yCAA4C;","names":[]}
@@ -12,6 +12,7 @@ import * as ThreadListItemPrimitive from "./threadListItem/index.mjs";
12
12
  import { useContentPartDisplay } from "./contentPart/useContentPartDisplay.mjs";
13
13
  import { useContentPartImage } from "./contentPart/useContentPartImage.mjs";
14
14
  import { useContentPartText } from "./contentPart/useContentPartText.mjs";
15
+ import { useThreadViewportAutoScroll } from "./thread/useThreadViewportAutoScroll.mjs";
15
16
  export {
16
17
  ActionBarPrimitive,
17
18
  AssistantModalPrimitive,
@@ -25,6 +26,7 @@ export {
25
26
  ThreadPrimitive,
26
27
  useContentPartDisplay,
27
28
  useContentPartImage,
28
- useContentPartText
29
+ useContentPartText,
30
+ useThreadViewportAutoScroll
29
31
  };
30
32
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/primitives/index.ts"],"sourcesContent":["export * as ActionBarPrimitive from \"./actionBar\";\nexport * as AssistantModalPrimitive from \"./assistantModal\";\nexport * as AttachmentPrimitive from \"./attachment\";\nexport * as BranchPickerPrimitive from \"./branchPicker\";\nexport * as ComposerPrimitive from \"./composer\";\nexport * as ContentPartPrimitive from \"./contentPart\";\nexport * as MessagePrimitive from \"./message\";\nexport * as ThreadPrimitive from \"./thread\";\nexport * as ThreadListPrimitive from \"./threadList\";\nexport * as ThreadListItemPrimitive from \"./threadListItem\";\n\nexport { useContentPartDisplay } from \"./contentPart/useContentPartDisplay\";\nexport { useContentPartImage } from \"./contentPart/useContentPartImage\";\nexport { useContentPartText } from \"./contentPart/useContentPartText\";\n"],"mappings":";AAAA,YAAY,wBAAwB;AACpC,YAAY,6BAA6B;AACzC,YAAY,yBAAyB;AACrC,YAAY,2BAA2B;AACvC,YAAY,uBAAuB;AACnC,YAAY,0BAA0B;AACtC,YAAY,sBAAsB;AAClC,YAAY,qBAAqB;AACjC,YAAY,yBAAyB;AACrC,YAAY,6BAA6B;AAEzC,SAAS,6BAA6B;AACtC,SAAS,2BAA2B;AACpC,SAAS,0BAA0B;","names":[]}
1
+ {"version":3,"sources":["../../src/primitives/index.ts"],"sourcesContent":["export * as ActionBarPrimitive from \"./actionBar\";\nexport * as AssistantModalPrimitive from \"./assistantModal\";\nexport * as AttachmentPrimitive from \"./attachment\";\nexport * as BranchPickerPrimitive from \"./branchPicker\";\nexport * as ComposerPrimitive from \"./composer\";\nexport * as ContentPartPrimitive from \"./contentPart\";\nexport * as MessagePrimitive from \"./message\";\nexport * as ThreadPrimitive from \"./thread\";\nexport * as ThreadListPrimitive from \"./threadList\";\nexport * as ThreadListItemPrimitive from \"./threadListItem\";\n\nexport { useContentPartDisplay } from \"./contentPart/useContentPartDisplay\";\nexport { useContentPartImage } from \"./contentPart/useContentPartImage\";\nexport { useContentPartText } from \"./contentPart/useContentPartText\";\nexport { useThreadViewportAutoScroll } from \"./thread/useThreadViewportAutoScroll\";\n"],"mappings":";AAAA,YAAY,wBAAwB;AACpC,YAAY,6BAA6B;AACzC,YAAY,yBAAyB;AACrC,YAAY,2BAA2B;AACvC,YAAY,uBAAuB;AACnC,YAAY,0BAA0B;AACtC,YAAY,sBAAsB;AAClC,YAAY,qBAAqB;AACjC,YAAY,yBAAyB;AACrC,YAAY,6BAA6B;AAEzC,SAAS,6BAA6B;AACtC,SAAS,2BAA2B;AACpC,SAAS,0BAA0B;AACnC,SAAS,mCAAmC;","names":[]}
@@ -1,7 +1,7 @@
1
1
  import { ActionButtonElement, ActionButtonProps } from "../../utils/createActionButton";
2
2
  declare const useThreadSuggestion: ({ prompt, autoSend, }: {
3
3
  prompt: string;
4
- method: "replace";
4
+ method?: "replace";
5
5
  autoSend?: boolean | undefined;
6
6
  }) => (() => void) | null;
7
7
  export declare namespace ThreadPrimitiveSuggestion {
@@ -12,7 +12,7 @@ export declare const ThreadPrimitiveSuggestion: import("react").ForwardRefExotic
12
12
  asChild?: boolean;
13
13
  }, "ref"> & {
14
14
  prompt: string;
15
- method: "replace";
15
+ method?: "replace";
16
16
  autoSend?: boolean | undefined;
17
17
  } & import("react").RefAttributes<HTMLButtonElement>>;
18
18
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"ThreadSuggestion.d.ts","sourceRoot":"","sources":["../../../src/primitives/thread/ThreadSuggestion.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EAElB,MAAM,gCAAgC,CAAC;AAKxC,QAAA,MAAM,mBAAmB,0BAGtB;IACD,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,SAAS,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAChC,wBAeA,CAAC;AAEF,yBAAiB,yBAAyB,CAAC;IACzC,KAAY,OAAO,GAAG,mBAAmB,CAAC;IAC1C,KAAY,KAAK,GAAG,iBAAiB,CAAC,OAAO,mBAAmB,CAAC,CAAC;CACnE;AAED,eAAO,MAAM,yBAAyB;;;YAzB5B,MAAM;YACN,SAAS;eACN,OAAO,GAAG,SAAS;qDA2B/B,CAAC"}
1
+ {"version":3,"file":"ThreadSuggestion.d.ts","sourceRoot":"","sources":["../../../src/primitives/thread/ThreadSuggestion.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EAElB,MAAM,gCAAgC,CAAC;AAKxC,QAAA,MAAM,mBAAmB,0BAGtB;IACD,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAChC,wBAcA,CAAC;AAEF,yBAAiB,yBAAyB,CAAC;IACzC,KAAY,OAAO,GAAG,mBAAmB,CAAC;IAC1C,KAAY,KAAK,GAAG,iBAAiB,CAAC,OAAO,mBAAmB,CAAC,CAAC;CACnE;AAED,eAAO,MAAM,yBAAyB;;;YAxB5B,MAAM;aACL,SAAS;eACP,OAAO,GAAG,SAAS;qDA0B/B,CAAC"}
@@ -37,7 +37,6 @@ var useThreadSuggestion = ({
37
37
  const callback = (0, import_react.useCallback)(() => {
38
38
  if (autoSend && !threadRuntime.getState().isRunning) {
39
39
  threadRuntime.append(prompt);
40
- threadRuntime.composer.setText("");
41
40
  } else {
42
41
  threadRuntime.composer.setText(prompt);
43
42
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/primitives/thread/ThreadSuggestion.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n ActionButtonElement,\n ActionButtonProps,\n createActionButton,\n} from \"../../utils/createActionButton\";\nimport { useCallback } from \"react\";\nimport { useThread } from \"../../context\";\nimport { useThreadRuntime } from \"../../context/react/ThreadContext\";\n\nconst useThreadSuggestion = ({\n prompt,\n autoSend,\n}: {\n prompt: string;\n method: \"replace\";\n autoSend?: boolean | undefined;\n}) => {\n const threadRuntime = useThreadRuntime();\n\n const disabled = useThread((t) => t.isDisabled);\n const callback = useCallback(() => {\n if (autoSend && !threadRuntime.getState().isRunning) {\n threadRuntime.append(prompt);\n threadRuntime.composer.setText(\"\");\n } else {\n threadRuntime.composer.setText(prompt);\n }\n }, [threadRuntime, autoSend, prompt]);\n\n if (disabled) return null;\n return callback;\n};\n\nexport namespace ThreadPrimitiveSuggestion {\n export type Element = ActionButtonElement;\n export type Props = ActionButtonProps<typeof useThreadSuggestion>;\n}\n\nexport const ThreadPrimitiveSuggestion = createActionButton(\n \"ThreadPrimitive.Suggestion\",\n useThreadSuggestion,\n [\"prompt\", \"autoSend\", \"method\"],\n);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,gCAIO;AACP,mBAA4B;AAC5B,qBAA0B;AAC1B,2BAAiC;AAEjC,IAAM,sBAAsB,CAAC;AAAA,EAC3B;AAAA,EACA;AACF,MAIM;AACJ,QAAM,oBAAgB,uCAAiB;AAEvC,QAAM,eAAW,0BAAU,CAAC,MAAM,EAAE,UAAU;AAC9C,QAAM,eAAW,0BAAY,MAAM;AACjC,QAAI,YAAY,CAAC,cAAc,SAAS,EAAE,WAAW;AACnD,oBAAc,OAAO,MAAM;AAC3B,oBAAc,SAAS,QAAQ,EAAE;AAAA,IACnC,OAAO;AACL,oBAAc,SAAS,QAAQ,MAAM;AAAA,IACvC;AAAA,EACF,GAAG,CAAC,eAAe,UAAU,MAAM,CAAC;AAEpC,MAAI,SAAU,QAAO;AACrB,SAAO;AACT;AAOO,IAAM,gCAA4B;AAAA,EACvC;AAAA,EACA;AAAA,EACA,CAAC,UAAU,YAAY,QAAQ;AACjC;","names":[]}
1
+ {"version":3,"sources":["../../../src/primitives/thread/ThreadSuggestion.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n ActionButtonElement,\n ActionButtonProps,\n createActionButton,\n} from \"../../utils/createActionButton\";\nimport { useCallback } from \"react\";\nimport { useThread } from \"../../context\";\nimport { useThreadRuntime } from \"../../context/react/ThreadContext\";\n\nconst useThreadSuggestion = ({\n prompt,\n autoSend,\n}: {\n prompt: string;\n method?: \"replace\";\n autoSend?: boolean | undefined;\n}) => {\n const threadRuntime = useThreadRuntime();\n\n const disabled = useThread((t) => t.isDisabled);\n const callback = useCallback(() => {\n if (autoSend && !threadRuntime.getState().isRunning) {\n threadRuntime.append(prompt);\n } else {\n threadRuntime.composer.setText(prompt);\n }\n }, [threadRuntime, autoSend, prompt]);\n\n if (disabled) return null;\n return callback;\n};\n\nexport namespace ThreadPrimitiveSuggestion {\n export type Element = ActionButtonElement;\n export type Props = ActionButtonProps<typeof useThreadSuggestion>;\n}\n\nexport const ThreadPrimitiveSuggestion = createActionButton(\n \"ThreadPrimitive.Suggestion\",\n useThreadSuggestion,\n [\"prompt\", \"autoSend\", \"method\"],\n);\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,gCAIO;AACP,mBAA4B;AAC5B,qBAA0B;AAC1B,2BAAiC;AAEjC,IAAM,sBAAsB,CAAC;AAAA,EAC3B;AAAA,EACA;AACF,MAIM;AACJ,QAAM,oBAAgB,uCAAiB;AAEvC,QAAM,eAAW,0BAAU,CAAC,MAAM,EAAE,UAAU;AAC9C,QAAM,eAAW,0BAAY,MAAM;AACjC,QAAI,YAAY,CAAC,cAAc,SAAS,EAAE,WAAW;AACnD,oBAAc,OAAO,MAAM;AAAA,IAC7B,OAAO;AACL,oBAAc,SAAS,QAAQ,MAAM;AAAA,IACvC;AAAA,EACF,GAAG,CAAC,eAAe,UAAU,MAAM,CAAC;AAEpC,MAAI,SAAU,QAAO;AACrB,SAAO;AACT;AAOO,IAAM,gCAA4B;AAAA,EACvC;AAAA,EACA;AAAA,EACA,CAAC,UAAU,YAAY,QAAQ;AACjC;","names":[]}
@@ -16,7 +16,6 @@ var useThreadSuggestion = ({
16
16
  const callback = useCallback(() => {
17
17
  if (autoSend && !threadRuntime.getState().isRunning) {
18
18
  threadRuntime.append(prompt);
19
- threadRuntime.composer.setText("");
20
19
  } else {
21
20
  threadRuntime.composer.setText(prompt);
22
21
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/primitives/thread/ThreadSuggestion.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n ActionButtonElement,\n ActionButtonProps,\n createActionButton,\n} from \"../../utils/createActionButton\";\nimport { useCallback } from \"react\";\nimport { useThread } from \"../../context\";\nimport { useThreadRuntime } from \"../../context/react/ThreadContext\";\n\nconst useThreadSuggestion = ({\n prompt,\n autoSend,\n}: {\n prompt: string;\n method: \"replace\";\n autoSend?: boolean | undefined;\n}) => {\n const threadRuntime = useThreadRuntime();\n\n const disabled = useThread((t) => t.isDisabled);\n const callback = useCallback(() => {\n if (autoSend && !threadRuntime.getState().isRunning) {\n threadRuntime.append(prompt);\n threadRuntime.composer.setText(\"\");\n } else {\n threadRuntime.composer.setText(prompt);\n }\n }, [threadRuntime, autoSend, prompt]);\n\n if (disabled) return null;\n return callback;\n};\n\nexport namespace ThreadPrimitiveSuggestion {\n export type Element = ActionButtonElement;\n export type Props = ActionButtonProps<typeof useThreadSuggestion>;\n}\n\nexport const ThreadPrimitiveSuggestion = createActionButton(\n \"ThreadPrimitive.Suggestion\",\n useThreadSuggestion,\n [\"prompt\", \"autoSend\", \"method\"],\n);\n"],"mappings":";;;AAEA;AAAA,EAGE;AAAA,OACK;AACP,SAAS,mBAAmB;AAC5B,SAAS,iBAAiB;AAC1B,SAAS,wBAAwB;AAEjC,IAAM,sBAAsB,CAAC;AAAA,EAC3B;AAAA,EACA;AACF,MAIM;AACJ,QAAM,gBAAgB,iBAAiB;AAEvC,QAAM,WAAW,UAAU,CAAC,MAAM,EAAE,UAAU;AAC9C,QAAM,WAAW,YAAY,MAAM;AACjC,QAAI,YAAY,CAAC,cAAc,SAAS,EAAE,WAAW;AACnD,oBAAc,OAAO,MAAM;AAC3B,oBAAc,SAAS,QAAQ,EAAE;AAAA,IACnC,OAAO;AACL,oBAAc,SAAS,QAAQ,MAAM;AAAA,IACvC;AAAA,EACF,GAAG,CAAC,eAAe,UAAU,MAAM,CAAC;AAEpC,MAAI,SAAU,QAAO;AACrB,SAAO;AACT;AAOO,IAAM,4BAA4B;AAAA,EACvC;AAAA,EACA;AAAA,EACA,CAAC,UAAU,YAAY,QAAQ;AACjC;","names":[]}
1
+ {"version":3,"sources":["../../../src/primitives/thread/ThreadSuggestion.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n ActionButtonElement,\n ActionButtonProps,\n createActionButton,\n} from \"../../utils/createActionButton\";\nimport { useCallback } from \"react\";\nimport { useThread } from \"../../context\";\nimport { useThreadRuntime } from \"../../context/react/ThreadContext\";\n\nconst useThreadSuggestion = ({\n prompt,\n autoSend,\n}: {\n prompt: string;\n method?: \"replace\";\n autoSend?: boolean | undefined;\n}) => {\n const threadRuntime = useThreadRuntime();\n\n const disabled = useThread((t) => t.isDisabled);\n const callback = useCallback(() => {\n if (autoSend && !threadRuntime.getState().isRunning) {\n threadRuntime.append(prompt);\n } else {\n threadRuntime.composer.setText(prompt);\n }\n }, [threadRuntime, autoSend, prompt]);\n\n if (disabled) return null;\n return callback;\n};\n\nexport namespace ThreadPrimitiveSuggestion {\n export type Element = ActionButtonElement;\n export type Props = ActionButtonProps<typeof useThreadSuggestion>;\n}\n\nexport const ThreadPrimitiveSuggestion = createActionButton(\n \"ThreadPrimitive.Suggestion\",\n useThreadSuggestion,\n [\"prompt\", \"autoSend\", \"method\"],\n);\n"],"mappings":";;;AAEA;AAAA,EAGE;AAAA,OACK;AACP,SAAS,mBAAmB;AAC5B,SAAS,iBAAiB;AAC1B,SAAS,wBAAwB;AAEjC,IAAM,sBAAsB,CAAC;AAAA,EAC3B;AAAA,EACA;AACF,MAIM;AACJ,QAAM,gBAAgB,iBAAiB;AAEvC,QAAM,WAAW,UAAU,CAAC,MAAM,EAAE,UAAU;AAC9C,QAAM,WAAW,YAAY,MAAM;AACjC,QAAI,YAAY,CAAC,cAAc,SAAS,EAAE,WAAW;AACnD,oBAAc,OAAO,MAAM;AAAA,IAC7B,OAAO;AACL,oBAAc,SAAS,QAAQ,MAAM;AAAA,IACvC;AAAA,EACF,GAAG,CAAC,eAAe,UAAU,MAAM,CAAC;AAEpC,MAAI,SAAU,QAAO;AACrB,SAAO;AACT;AAOO,IAAM,4BAA4B;AAAA,EACvC;AAAA,EACA;AAAA,EACA,CAAC,UAAU,YAAY,QAAQ;AACjC;","names":[]}
@@ -1,6 +1,10 @@
1
1
  import { ThreadMessageLike } from "./ThreadMessageLike";
2
2
  export declare namespace useExternalMessageConverter {
3
- type Message = ThreadMessageLike | {
3
+ type Message = (ThreadMessageLike & {
4
+ readonly convertConfig?: {
5
+ readonly joinStrategy?: "concat-content" | "none";
6
+ };
7
+ }) | {
4
8
  role: "tool";
5
9
  toolCallId: string;
6
10
  toolName?: string | undefined;
@@ -9,9 +13,10 @@ export declare namespace useExternalMessageConverter {
9
13
  type Callback<T> = (message: T) => Message | Message[];
10
14
  }
11
15
  export declare const convertExternalMessages: <T extends WeakKey>(messages: T[], callback: useExternalMessageConverter.Callback<T>, isRunning: boolean) => import("../..").ThreadMessage[];
12
- export declare const useExternalMessageConverter: <T extends WeakKey>({ callback, messages, isRunning, }: {
16
+ export declare const useExternalMessageConverter: <T extends WeakKey>({ callback, messages, isRunning, joinStrategy, }: {
13
17
  callback: useExternalMessageConverter.Callback<T>;
14
18
  messages: T[];
15
19
  isRunning: boolean;
20
+ joinStrategy?: "concat-content" | "none";
16
21
  }) => import("../..").ThreadMessage[];
17
22
  //# sourceMappingURL=external-message-converter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"external-message-converter.d.ts","sourceRoot":"","sources":["../../../src/runtimes/external-store/external-message-converter.tsx"],"names":[],"mappings":"AAQA,OAAO,EAAyB,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAI/E,yBAAiB,2BAA2B,CAAC;IAC3C,KAAY,OAAO,GACf,iBAAiB,GACjB;QACE,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAC9B,MAAM,EAAE,GAAG,CAAC;KACb,CAAC;IAEN,KAAY,QAAQ,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,OAAO,GAAG,OAAO,EAAE,CAAC;CAC/D;AAkKD,eAAO,MAAM,uBAAuB,GAAI,CAAC,SAAS,OAAO,YAC7C,CAAC,EAAE,YACH,2BAA2B,CAAC,QAAQ,CAAC,CAAC,CAAC,aACtC,OAAO,oCAuBnB,CAAC;AAEF,eAAO,MAAM,2BAA2B,GAAI,CAAC,SAAS,OAAO,sCAI1D;IACD,QAAQ,EAAE,2BAA2B,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAClD,QAAQ,EAAE,CAAC,EAAE,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;CACpB,oCAuEA,CAAC"}
1
+ {"version":3,"file":"external-message-converter.d.ts","sourceRoot":"","sources":["../../../src/runtimes/external-store/external-message-converter.tsx"],"names":[],"mappings":"AAQA,OAAO,EAAyB,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAI/E,yBAAiB,2BAA2B,CAAC;IAC3C,KAAY,OAAO,GACf,CAAC,iBAAiB,GAAG;QACnB,QAAQ,CAAC,aAAa,CAAC,EAAE;YACvB,QAAQ,CAAC,YAAY,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAAC;SACnD,CAAC;KACH,CAAC,GACF;QACE,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAC9B,MAAM,EAAE,GAAG,CAAC;KACb,CAAC;IAEN,KAAY,QAAQ,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,OAAO,GAAG,OAAO,EAAE,CAAC;CAC/D;AAqLD,eAAO,MAAM,uBAAuB,GAAI,CAAC,SAAS,OAAO,YAC7C,CAAC,EAAE,YACH,2BAA2B,CAAC,QAAQ,CAAC,CAAC,CAAC,aACtC,OAAO,oCAuBnB,CAAC;AAEF,eAAO,MAAM,2BAA2B,GAAI,CAAC,SAAS,OAAO,oDAK1D;IACD,QAAQ,EAAE,2BAA2B,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;IAClD,QAAQ,EAAE,CAAC,EAAE,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAAC;CAC1C,oCA0EA,CAAC"}
@@ -126,9 +126,10 @@ var joinExternalMessages = (messages) => {
126
126
  }
127
127
  return assistantMessage;
128
128
  };
129
- var chunkExternalMessages = (callbackResults) => {
129
+ var chunkExternalMessages = (callbackResults, joinStrategy) => {
130
130
  const results = [];
131
131
  let isAssistant = false;
132
+ let pendingNone = false;
132
133
  let inputs = [];
133
134
  let outputs = [];
134
135
  const flush = () => {
@@ -140,10 +141,12 @@ var chunkExternalMessages = (callbackResults) => {
140
141
  }
141
142
  inputs = [];
142
143
  outputs = [];
144
+ isAssistant = false;
145
+ pendingNone = false;
143
146
  };
144
147
  for (const callbackResult of callbackResults) {
145
148
  for (const output of callbackResult.outputs) {
146
- if (!isAssistant || output.role === "user" || output.role === "system") {
149
+ if (pendingNone && output.role !== "tool" || !isAssistant || output.role === "user" || output.role === "system") {
147
150
  flush();
148
151
  }
149
152
  isAssistant = output.role === "assistant" || output.role === "tool";
@@ -151,6 +154,9 @@ var chunkExternalMessages = (callbackResults) => {
151
154
  inputs.push(callbackResult.input);
152
155
  }
153
156
  outputs.push(output);
157
+ if (output.role === "assistant" && (output.convertConfig?.joinStrategy === "none" || joinStrategy === "none")) {
158
+ pendingNone = true;
159
+ }
154
160
  }
155
161
  }
156
162
  flush();
@@ -180,7 +186,8 @@ var convertExternalMessages = (messages, callback, isRunning) => {
180
186
  var useExternalMessageConverter = ({
181
187
  callback,
182
188
  messages,
183
- isRunning
189
+ isRunning,
190
+ joinStrategy
184
191
  }) => {
185
192
  const state = (0, import_react.useMemo)(
186
193
  () => ({
@@ -203,14 +210,17 @@ var useExternalMessageConverter = ({
203
210
  }
204
211
  callbackResults.push(result);
205
212
  }
206
- const chunks = chunkExternalMessages(callbackResults).map((m) => {
207
- const key = m.outputs[0];
208
- if (!key) return m;
209
- const cached = state.chunkCache.get(key);
210
- if (cached && shallowArrayEqual(cached.outputs, m.outputs)) return cached;
211
- state.chunkCache.set(key, m);
212
- return m;
213
- });
213
+ const chunks = chunkExternalMessages(callbackResults, joinStrategy).map(
214
+ (m) => {
215
+ const key = m.outputs[0];
216
+ if (!key) return m;
217
+ const cached = state.chunkCache.get(key);
218
+ if (cached && shallowArrayEqual(cached.outputs, m.outputs))
219
+ return cached;
220
+ state.chunkCache.set(key, m);
221
+ return m;
222
+ }
223
+ );
214
224
  const threadMessages = state.converterCache.convertMessages(
215
225
  chunks,
216
226
  (cache, message, idx) => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/runtimes/external-store/external-message-converter.tsx"],"sourcesContent":["\"use client\";\n\nimport { useMemo } from \"react\";\nimport { ThreadMessageConverter } from \"./ThreadMessageConverter\";\nimport {\n getExternalStoreMessages,\n symbolInnerMessage,\n} from \"./getExternalStoreMessage\";\nimport { fromThreadMessageLike, ThreadMessageLike } from \"./ThreadMessageLike\";\nimport { getAutoStatus, isAutoStatus } from \"./auto-status\";\nimport { ToolCallContentPart } from \"../../types\";\n\nexport namespace useExternalMessageConverter {\n export type Message =\n | ThreadMessageLike\n | {\n role: \"tool\";\n toolCallId: string;\n toolName?: string | undefined;\n result: any;\n };\n\n export type Callback<T> = (message: T) => Message | Message[];\n}\n\ntype CallbackResult<T> = {\n input: T;\n outputs: useExternalMessageConverter.Message[];\n};\n\ntype ChunkResult<T> = {\n inputs: T[];\n outputs: useExternalMessageConverter.Message[];\n};\n\ntype Mutable<T> = {\n -readonly [P in keyof T]: T[P];\n};\n\nconst joinExternalMessages = (\n messages: readonly useExternalMessageConverter.Message[],\n): ThreadMessageLike => {\n const assistantMessage: Mutable<Omit<ThreadMessageLike, \"metadata\">> & {\n content: Exclude<ThreadMessageLike[\"content\"][0], string>[];\n metadata?: Mutable<ThreadMessageLike[\"metadata\"]>;\n } = {\n role: \"assistant\",\n content: [],\n };\n for (const output of messages) {\n if (output.role === \"tool\") {\n const toolCallIdx = assistantMessage.content.findIndex(\n (c) => c.type === \"tool-call\" && c.toolCallId === output.toolCallId,\n );\n if (toolCallIdx !== -1) {\n const toolCall = assistantMessage.content[\n toolCallIdx\n ]! as ToolCallContentPart;\n if (output.toolName) {\n if (toolCall.toolName !== output.toolName)\n throw new Error(\n `Tool call name ${output.toolCallId} ${output.toolName} does not match existing tool call ${toolCall.toolName}`,\n );\n }\n assistantMessage.content[toolCallIdx] = {\n ...toolCall,\n ...{\n [symbolInnerMessage]: [\n ...((toolCall as any)[symbolInnerMessage] ?? []),\n output,\n ],\n },\n result: output.result,\n };\n } else {\n throw new Error(\n `Tool call ${output.toolCallId} ${output.toolName} not found in assistant message`,\n );\n }\n } else {\n const role = output.role;\n const content = (\n typeof output.content === \"string\"\n ? [{ type: \"text\" as const, text: output.content }]\n : output.content\n ).map((c) => ({\n ...c,\n ...{ [symbolInnerMessage]: [output] },\n }));\n switch (role) {\n case \"system\":\n case \"user\":\n return {\n ...output,\n content,\n };\n case \"assistant\":\n if (assistantMessage.content.length === 0) {\n assistantMessage.id = output.id;\n assistantMessage.createdAt ??= output.createdAt;\n assistantMessage.status ??= output.status;\n\n if (output.attachments) {\n assistantMessage.attachments = [\n ...(assistantMessage.attachments ?? []),\n ...output.attachments,\n ];\n }\n\n if (output.metadata) {\n assistantMessage.metadata ??= {};\n if (output.metadata.unstable_annotations) {\n assistantMessage.metadata.unstable_annotations = [\n ...(assistantMessage.metadata.unstable_annotations ?? []),\n ...output.metadata.unstable_annotations,\n ];\n }\n if (output.metadata.unstable_data) {\n assistantMessage.metadata.unstable_data = [\n ...(assistantMessage.metadata.unstable_data ?? []),\n ...output.metadata.unstable_data,\n ];\n }\n if (output.metadata.steps) {\n assistantMessage.metadata.steps = [\n ...(assistantMessage.metadata.steps ?? []),\n ...output.metadata.steps,\n ];\n }\n if (output.metadata.custom) {\n assistantMessage.metadata.custom = {\n ...(assistantMessage.metadata.custom ?? {}),\n ...output.metadata.custom,\n };\n }\n }\n // TODO keep this in sync\n }\n\n assistantMessage.content.push(...content);\n break;\n default: {\n const unsupportedRole: never = role;\n throw new Error(`Unknown message role: ${unsupportedRole}`);\n }\n }\n }\n }\n return assistantMessage;\n};\n\nconst chunkExternalMessages = <T,>(callbackResults: CallbackResult<T>[]) => {\n const results: ChunkResult<T>[] = [];\n let isAssistant = false;\n let inputs: T[] = [];\n let outputs: useExternalMessageConverter.Message[] = [];\n\n const flush = () => {\n if (outputs.length) {\n results.push({\n inputs,\n outputs,\n });\n }\n inputs = [];\n outputs = [];\n };\n\n for (const callbackResult of callbackResults) {\n for (const output of callbackResult.outputs) {\n if (!isAssistant || output.role === \"user\" || output.role === \"system\") {\n flush();\n }\n isAssistant = output.role === \"assistant\" || output.role === \"tool\";\n\n if (inputs.at(-1) !== callbackResult.input) {\n inputs.push(callbackResult.input);\n }\n outputs.push(output);\n }\n }\n flush();\n return results;\n};\n\nexport const convertExternalMessages = <T extends WeakKey>(\n messages: T[],\n callback: useExternalMessageConverter.Callback<T>,\n isRunning: boolean,\n) => {\n const callbackResults: CallbackResult<T>[] = [];\n for (const message of messages) {\n const output = callback(message);\n const outputs = Array.isArray(output) ? output : [output];\n const result = { input: message, outputs };\n callbackResults.push(result);\n }\n\n const chunks = chunkExternalMessages(callbackResults);\n\n return chunks.map((message, idx) => {\n const isLast = idx === chunks.length - 1;\n const autoStatus = getAutoStatus(isLast, isRunning);\n const newMessage = fromThreadMessageLike(\n joinExternalMessages(message.outputs),\n idx.toString(),\n autoStatus,\n );\n (newMessage as any)[symbolInnerMessage] = message.inputs;\n return newMessage;\n });\n};\n\nexport const useExternalMessageConverter = <T extends WeakKey>({\n callback,\n messages,\n isRunning,\n}: {\n callback: useExternalMessageConverter.Callback<T>;\n messages: T[];\n isRunning: boolean;\n}) => {\n const state = useMemo(\n () => ({\n callback,\n callbackCache: new WeakMap<T, CallbackResult<T>>(),\n chunkCache: new WeakMap<\n useExternalMessageConverter.Message,\n ChunkResult<T>\n >(),\n converterCache: new ThreadMessageConverter(),\n }),\n [callback],\n );\n\n return useMemo(() => {\n const callbackResults: CallbackResult<T>[] = [];\n for (const message of messages) {\n let result = state.callbackCache.get(message);\n if (!result) {\n const output = state.callback(message);\n const outputs = Array.isArray(output) ? output : [output];\n result = { input: message, outputs };\n state.callbackCache.set(message, result);\n }\n callbackResults.push(result);\n }\n\n const chunks = chunkExternalMessages(callbackResults).map((m) => {\n const key = m.outputs[0];\n if (!key) return m;\n\n const cached = state.chunkCache.get(key);\n if (cached && shallowArrayEqual(cached.outputs, m.outputs)) return cached;\n state.chunkCache.set(key, m);\n return m;\n });\n\n const threadMessages = state.converterCache.convertMessages(\n chunks,\n (cache, message, idx) => {\n const isLast = idx === chunks.length - 1;\n const autoStatus = getAutoStatus(isLast, isRunning);\n\n if (\n cache &&\n (cache.role !== \"assistant\" ||\n !isAutoStatus(cache.status) ||\n cache.status === autoStatus)\n ) {\n const inputs = getExternalStoreMessages<T>(cache);\n if (shallowArrayEqual(inputs, message.inputs)) {\n return cache;\n }\n }\n\n const newMessage = fromThreadMessageLike(\n joinExternalMessages(message.outputs),\n idx.toString(),\n autoStatus,\n );\n (newMessage as any)[symbolInnerMessage] = message.inputs;\n return newMessage;\n },\n );\n\n (threadMessages as unknown as { [symbolInnerMessage]: T[] })[\n symbolInnerMessage\n ] = messages;\n\n return threadMessages;\n }, [state, messages, isRunning]);\n};\n\nconst shallowArrayEqual = (a: unknown[], b: unknown[]) => {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/runtimes/external-store/external-message-converter.tsx"],"sourcesContent":["\"use client\";\n\nimport { useMemo } from \"react\";\nimport { ThreadMessageConverter } from \"./ThreadMessageConverter\";\nimport {\n getExternalStoreMessages,\n symbolInnerMessage,\n} from \"./getExternalStoreMessage\";\nimport { fromThreadMessageLike, ThreadMessageLike } from \"./ThreadMessageLike\";\nimport { getAutoStatus, isAutoStatus } from \"./auto-status\";\nimport { ToolCallContentPart } from \"../../types\";\n\nexport namespace useExternalMessageConverter {\n export type Message =\n | (ThreadMessageLike & {\n readonly convertConfig?: {\n readonly joinStrategy?: \"concat-content\" | \"none\";\n };\n })\n | {\n role: \"tool\";\n toolCallId: string;\n toolName?: string | undefined;\n result: any;\n };\n\n export type Callback<T> = (message: T) => Message | Message[];\n}\n\ntype CallbackResult<T> = {\n input: T;\n outputs: useExternalMessageConverter.Message[];\n};\n\ntype ChunkResult<T> = {\n inputs: T[];\n outputs: useExternalMessageConverter.Message[];\n};\n\ntype Mutable<T> = {\n -readonly [P in keyof T]: T[P];\n};\n\nconst joinExternalMessages = (\n messages: readonly useExternalMessageConverter.Message[],\n): ThreadMessageLike => {\n const assistantMessage: Mutable<Omit<ThreadMessageLike, \"metadata\">> & {\n content: Exclude<ThreadMessageLike[\"content\"][0], string>[];\n metadata?: Mutable<ThreadMessageLike[\"metadata\"]>;\n } = {\n role: \"assistant\",\n content: [],\n };\n for (const output of messages) {\n if (output.role === \"tool\") {\n const toolCallIdx = assistantMessage.content.findIndex(\n (c) => c.type === \"tool-call\" && c.toolCallId === output.toolCallId,\n );\n if (toolCallIdx !== -1) {\n const toolCall = assistantMessage.content[\n toolCallIdx\n ]! as ToolCallContentPart;\n if (output.toolName) {\n if (toolCall.toolName !== output.toolName)\n throw new Error(\n `Tool call name ${output.toolCallId} ${output.toolName} does not match existing tool call ${toolCall.toolName}`,\n );\n }\n assistantMessage.content[toolCallIdx] = {\n ...toolCall,\n ...{\n [symbolInnerMessage]: [\n ...((toolCall as any)[symbolInnerMessage] ?? []),\n output,\n ],\n },\n result: output.result,\n };\n } else {\n throw new Error(\n `Tool call ${output.toolCallId} ${output.toolName} not found in assistant message`,\n );\n }\n } else {\n const role = output.role;\n const content = (\n typeof output.content === \"string\"\n ? [{ type: \"text\" as const, text: output.content }]\n : output.content\n ).map((c) => ({\n ...c,\n ...{ [symbolInnerMessage]: [output] },\n }));\n switch (role) {\n case \"system\":\n case \"user\":\n return {\n ...output,\n content,\n };\n case \"assistant\":\n if (assistantMessage.content.length === 0) {\n assistantMessage.id = output.id;\n assistantMessage.createdAt ??= output.createdAt;\n assistantMessage.status ??= output.status;\n\n if (output.attachments) {\n assistantMessage.attachments = [\n ...(assistantMessage.attachments ?? []),\n ...output.attachments,\n ];\n }\n\n if (output.metadata) {\n assistantMessage.metadata ??= {};\n if (output.metadata.unstable_annotations) {\n assistantMessage.metadata.unstable_annotations = [\n ...(assistantMessage.metadata.unstable_annotations ?? []),\n ...output.metadata.unstable_annotations,\n ];\n }\n if (output.metadata.unstable_data) {\n assistantMessage.metadata.unstable_data = [\n ...(assistantMessage.metadata.unstable_data ?? []),\n ...output.metadata.unstable_data,\n ];\n }\n if (output.metadata.steps) {\n assistantMessage.metadata.steps = [\n ...(assistantMessage.metadata.steps ?? []),\n ...output.metadata.steps,\n ];\n }\n if (output.metadata.custom) {\n assistantMessage.metadata.custom = {\n ...(assistantMessage.metadata.custom ?? {}),\n ...output.metadata.custom,\n };\n }\n }\n // TODO keep this in sync\n }\n\n assistantMessage.content.push(...content);\n break;\n default: {\n const unsupportedRole: never = role;\n throw new Error(`Unknown message role: ${unsupportedRole}`);\n }\n }\n }\n }\n return assistantMessage;\n};\n\nconst chunkExternalMessages = <T,>(\n callbackResults: CallbackResult<T>[],\n joinStrategy?: \"concat-content\" | \"none\",\n) => {\n const results: ChunkResult<T>[] = [];\n let isAssistant = false;\n let pendingNone = false; // true if the previous assistant message had joinStrategy \"none\"\n let inputs: T[] = [];\n let outputs: useExternalMessageConverter.Message[] = [];\n\n const flush = () => {\n if (outputs.length) {\n results.push({\n inputs,\n outputs,\n });\n }\n inputs = [];\n outputs = [];\n isAssistant = false;\n pendingNone = false;\n };\n\n for (const callbackResult of callbackResults) {\n for (const output of callbackResult.outputs) {\n if (\n (pendingNone && output.role !== \"tool\") ||\n !isAssistant ||\n output.role === \"user\" ||\n output.role === \"system\"\n ) {\n flush();\n }\n isAssistant = output.role === \"assistant\" || output.role === \"tool\";\n\n if (inputs.at(-1) !== callbackResult.input) {\n inputs.push(callbackResult.input);\n }\n outputs.push(output);\n\n if (\n output.role === \"assistant\" &&\n (output.convertConfig?.joinStrategy === \"none\" ||\n joinStrategy === \"none\")\n ) {\n pendingNone = true;\n }\n }\n }\n flush();\n return results;\n};\n\nexport const convertExternalMessages = <T extends WeakKey>(\n messages: T[],\n callback: useExternalMessageConverter.Callback<T>,\n isRunning: boolean,\n) => {\n const callbackResults: CallbackResult<T>[] = [];\n for (const message of messages) {\n const output = callback(message);\n const outputs = Array.isArray(output) ? output : [output];\n const result = { input: message, outputs };\n callbackResults.push(result);\n }\n\n const chunks = chunkExternalMessages(callbackResults);\n\n return chunks.map((message, idx) => {\n const isLast = idx === chunks.length - 1;\n const autoStatus = getAutoStatus(isLast, isRunning);\n const newMessage = fromThreadMessageLike(\n joinExternalMessages(message.outputs),\n idx.toString(),\n autoStatus,\n );\n (newMessage as any)[symbolInnerMessage] = message.inputs;\n return newMessage;\n });\n};\n\nexport const useExternalMessageConverter = <T extends WeakKey>({\n callback,\n messages,\n isRunning,\n joinStrategy,\n}: {\n callback: useExternalMessageConverter.Callback<T>;\n messages: T[];\n isRunning: boolean;\n joinStrategy?: \"concat-content\" | \"none\";\n}) => {\n const state = useMemo(\n () => ({\n callback,\n callbackCache: new WeakMap<T, CallbackResult<T>>(),\n chunkCache: new WeakMap<\n useExternalMessageConverter.Message,\n ChunkResult<T>\n >(),\n converterCache: new ThreadMessageConverter(),\n }),\n [callback],\n );\n\n return useMemo(() => {\n const callbackResults: CallbackResult<T>[] = [];\n for (const message of messages) {\n let result = state.callbackCache.get(message);\n if (!result) {\n const output = state.callback(message);\n const outputs = Array.isArray(output) ? output : [output];\n result = { input: message, outputs };\n state.callbackCache.set(message, result);\n }\n callbackResults.push(result);\n }\n\n const chunks = chunkExternalMessages(callbackResults, joinStrategy).map(\n (m) => {\n const key = m.outputs[0];\n if (!key) return m;\n\n const cached = state.chunkCache.get(key);\n if (cached && shallowArrayEqual(cached.outputs, m.outputs))\n return cached;\n state.chunkCache.set(key, m);\n return m;\n },\n );\n\n const threadMessages = state.converterCache.convertMessages(\n chunks,\n (cache, message, idx) => {\n const isLast = idx === chunks.length - 1;\n const autoStatus = getAutoStatus(isLast, isRunning);\n\n if (\n cache &&\n (cache.role !== \"assistant\" ||\n !isAutoStatus(cache.status) ||\n cache.status === autoStatus)\n ) {\n const inputs = getExternalStoreMessages<T>(cache);\n if (shallowArrayEqual(inputs, message.inputs)) {\n return cache;\n }\n }\n\n const newMessage = fromThreadMessageLike(\n joinExternalMessages(message.outputs),\n idx.toString(),\n autoStatus,\n );\n (newMessage as any)[symbolInnerMessage] = message.inputs;\n return newMessage;\n },\n );\n\n (threadMessages as unknown as { [symbolInnerMessage]: T[] })[\n symbolInnerMessage\n ] = messages;\n\n return threadMessages;\n }, [state, messages, isRunning]);\n};\n\nconst shallowArrayEqual = (a: unknown[], b: unknown[]) => {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n};\n"],"mappings":"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","names":[]}
@@ -105,9 +105,10 @@ var joinExternalMessages = (messages) => {
105
105
  }
106
106
  return assistantMessage;
107
107
  };
108
- var chunkExternalMessages = (callbackResults) => {
108
+ var chunkExternalMessages = (callbackResults, joinStrategy) => {
109
109
  const results = [];
110
110
  let isAssistant = false;
111
+ let pendingNone = false;
111
112
  let inputs = [];
112
113
  let outputs = [];
113
114
  const flush = () => {
@@ -119,10 +120,12 @@ var chunkExternalMessages = (callbackResults) => {
119
120
  }
120
121
  inputs = [];
121
122
  outputs = [];
123
+ isAssistant = false;
124
+ pendingNone = false;
122
125
  };
123
126
  for (const callbackResult of callbackResults) {
124
127
  for (const output of callbackResult.outputs) {
125
- if (!isAssistant || output.role === "user" || output.role === "system") {
128
+ if (pendingNone && output.role !== "tool" || !isAssistant || output.role === "user" || output.role === "system") {
126
129
  flush();
127
130
  }
128
131
  isAssistant = output.role === "assistant" || output.role === "tool";
@@ -130,6 +133,9 @@ var chunkExternalMessages = (callbackResults) => {
130
133
  inputs.push(callbackResult.input);
131
134
  }
132
135
  outputs.push(output);
136
+ if (output.role === "assistant" && (output.convertConfig?.joinStrategy === "none" || joinStrategy === "none")) {
137
+ pendingNone = true;
138
+ }
133
139
  }
134
140
  }
135
141
  flush();
@@ -159,7 +165,8 @@ var convertExternalMessages = (messages, callback, isRunning) => {
159
165
  var useExternalMessageConverter = ({
160
166
  callback,
161
167
  messages,
162
- isRunning
168
+ isRunning,
169
+ joinStrategy
163
170
  }) => {
164
171
  const state = useMemo(
165
172
  () => ({
@@ -182,14 +189,17 @@ var useExternalMessageConverter = ({
182
189
  }
183
190
  callbackResults.push(result);
184
191
  }
185
- const chunks = chunkExternalMessages(callbackResults).map((m) => {
186
- const key = m.outputs[0];
187
- if (!key) return m;
188
- const cached = state.chunkCache.get(key);
189
- if (cached && shallowArrayEqual(cached.outputs, m.outputs)) return cached;
190
- state.chunkCache.set(key, m);
191
- return m;
192
- });
192
+ const chunks = chunkExternalMessages(callbackResults, joinStrategy).map(
193
+ (m) => {
194
+ const key = m.outputs[0];
195
+ if (!key) return m;
196
+ const cached = state.chunkCache.get(key);
197
+ if (cached && shallowArrayEqual(cached.outputs, m.outputs))
198
+ return cached;
199
+ state.chunkCache.set(key, m);
200
+ return m;
201
+ }
202
+ );
193
203
  const threadMessages = state.converterCache.convertMessages(
194
204
  chunks,
195
205
  (cache, message, idx) => {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/runtimes/external-store/external-message-converter.tsx"],"sourcesContent":["\"use client\";\n\nimport { useMemo } from \"react\";\nimport { ThreadMessageConverter } from \"./ThreadMessageConverter\";\nimport {\n getExternalStoreMessages,\n symbolInnerMessage,\n} from \"./getExternalStoreMessage\";\nimport { fromThreadMessageLike, ThreadMessageLike } from \"./ThreadMessageLike\";\nimport { getAutoStatus, isAutoStatus } from \"./auto-status\";\nimport { ToolCallContentPart } from \"../../types\";\n\nexport namespace useExternalMessageConverter {\n export type Message =\n | ThreadMessageLike\n | {\n role: \"tool\";\n toolCallId: string;\n toolName?: string | undefined;\n result: any;\n };\n\n export type Callback<T> = (message: T) => Message | Message[];\n}\n\ntype CallbackResult<T> = {\n input: T;\n outputs: useExternalMessageConverter.Message[];\n};\n\ntype ChunkResult<T> = {\n inputs: T[];\n outputs: useExternalMessageConverter.Message[];\n};\n\ntype Mutable<T> = {\n -readonly [P in keyof T]: T[P];\n};\n\nconst joinExternalMessages = (\n messages: readonly useExternalMessageConverter.Message[],\n): ThreadMessageLike => {\n const assistantMessage: Mutable<Omit<ThreadMessageLike, \"metadata\">> & {\n content: Exclude<ThreadMessageLike[\"content\"][0], string>[];\n metadata?: Mutable<ThreadMessageLike[\"metadata\"]>;\n } = {\n role: \"assistant\",\n content: [],\n };\n for (const output of messages) {\n if (output.role === \"tool\") {\n const toolCallIdx = assistantMessage.content.findIndex(\n (c) => c.type === \"tool-call\" && c.toolCallId === output.toolCallId,\n );\n if (toolCallIdx !== -1) {\n const toolCall = assistantMessage.content[\n toolCallIdx\n ]! as ToolCallContentPart;\n if (output.toolName) {\n if (toolCall.toolName !== output.toolName)\n throw new Error(\n `Tool call name ${output.toolCallId} ${output.toolName} does not match existing tool call ${toolCall.toolName}`,\n );\n }\n assistantMessage.content[toolCallIdx] = {\n ...toolCall,\n ...{\n [symbolInnerMessage]: [\n ...((toolCall as any)[symbolInnerMessage] ?? []),\n output,\n ],\n },\n result: output.result,\n };\n } else {\n throw new Error(\n `Tool call ${output.toolCallId} ${output.toolName} not found in assistant message`,\n );\n }\n } else {\n const role = output.role;\n const content = (\n typeof output.content === \"string\"\n ? [{ type: \"text\" as const, text: output.content }]\n : output.content\n ).map((c) => ({\n ...c,\n ...{ [symbolInnerMessage]: [output] },\n }));\n switch (role) {\n case \"system\":\n case \"user\":\n return {\n ...output,\n content,\n };\n case \"assistant\":\n if (assistantMessage.content.length === 0) {\n assistantMessage.id = output.id;\n assistantMessage.createdAt ??= output.createdAt;\n assistantMessage.status ??= output.status;\n\n if (output.attachments) {\n assistantMessage.attachments = [\n ...(assistantMessage.attachments ?? []),\n ...output.attachments,\n ];\n }\n\n if (output.metadata) {\n assistantMessage.metadata ??= {};\n if (output.metadata.unstable_annotations) {\n assistantMessage.metadata.unstable_annotations = [\n ...(assistantMessage.metadata.unstable_annotations ?? []),\n ...output.metadata.unstable_annotations,\n ];\n }\n if (output.metadata.unstable_data) {\n assistantMessage.metadata.unstable_data = [\n ...(assistantMessage.metadata.unstable_data ?? []),\n ...output.metadata.unstable_data,\n ];\n }\n if (output.metadata.steps) {\n assistantMessage.metadata.steps = [\n ...(assistantMessage.metadata.steps ?? []),\n ...output.metadata.steps,\n ];\n }\n if (output.metadata.custom) {\n assistantMessage.metadata.custom = {\n ...(assistantMessage.metadata.custom ?? {}),\n ...output.metadata.custom,\n };\n }\n }\n // TODO keep this in sync\n }\n\n assistantMessage.content.push(...content);\n break;\n default: {\n const unsupportedRole: never = role;\n throw new Error(`Unknown message role: ${unsupportedRole}`);\n }\n }\n }\n }\n return assistantMessage;\n};\n\nconst chunkExternalMessages = <T,>(callbackResults: CallbackResult<T>[]) => {\n const results: ChunkResult<T>[] = [];\n let isAssistant = false;\n let inputs: T[] = [];\n let outputs: useExternalMessageConverter.Message[] = [];\n\n const flush = () => {\n if (outputs.length) {\n results.push({\n inputs,\n outputs,\n });\n }\n inputs = [];\n outputs = [];\n };\n\n for (const callbackResult of callbackResults) {\n for (const output of callbackResult.outputs) {\n if (!isAssistant || output.role === \"user\" || output.role === \"system\") {\n flush();\n }\n isAssistant = output.role === \"assistant\" || output.role === \"tool\";\n\n if (inputs.at(-1) !== callbackResult.input) {\n inputs.push(callbackResult.input);\n }\n outputs.push(output);\n }\n }\n flush();\n return results;\n};\n\nexport const convertExternalMessages = <T extends WeakKey>(\n messages: T[],\n callback: useExternalMessageConverter.Callback<T>,\n isRunning: boolean,\n) => {\n const callbackResults: CallbackResult<T>[] = [];\n for (const message of messages) {\n const output = callback(message);\n const outputs = Array.isArray(output) ? output : [output];\n const result = { input: message, outputs };\n callbackResults.push(result);\n }\n\n const chunks = chunkExternalMessages(callbackResults);\n\n return chunks.map((message, idx) => {\n const isLast = idx === chunks.length - 1;\n const autoStatus = getAutoStatus(isLast, isRunning);\n const newMessage = fromThreadMessageLike(\n joinExternalMessages(message.outputs),\n idx.toString(),\n autoStatus,\n );\n (newMessage as any)[symbolInnerMessage] = message.inputs;\n return newMessage;\n });\n};\n\nexport const useExternalMessageConverter = <T extends WeakKey>({\n callback,\n messages,\n isRunning,\n}: {\n callback: useExternalMessageConverter.Callback<T>;\n messages: T[];\n isRunning: boolean;\n}) => {\n const state = useMemo(\n () => ({\n callback,\n callbackCache: new WeakMap<T, CallbackResult<T>>(),\n chunkCache: new WeakMap<\n useExternalMessageConverter.Message,\n ChunkResult<T>\n >(),\n converterCache: new ThreadMessageConverter(),\n }),\n [callback],\n );\n\n return useMemo(() => {\n const callbackResults: CallbackResult<T>[] = [];\n for (const message of messages) {\n let result = state.callbackCache.get(message);\n if (!result) {\n const output = state.callback(message);\n const outputs = Array.isArray(output) ? output : [output];\n result = { input: message, outputs };\n state.callbackCache.set(message, result);\n }\n callbackResults.push(result);\n }\n\n const chunks = chunkExternalMessages(callbackResults).map((m) => {\n const key = m.outputs[0];\n if (!key) return m;\n\n const cached = state.chunkCache.get(key);\n if (cached && shallowArrayEqual(cached.outputs, m.outputs)) return cached;\n state.chunkCache.set(key, m);\n return m;\n });\n\n const threadMessages = state.converterCache.convertMessages(\n chunks,\n (cache, message, idx) => {\n const isLast = idx === chunks.length - 1;\n const autoStatus = getAutoStatus(isLast, isRunning);\n\n if (\n cache &&\n (cache.role !== \"assistant\" ||\n !isAutoStatus(cache.status) ||\n cache.status === autoStatus)\n ) {\n const inputs = getExternalStoreMessages<T>(cache);\n if (shallowArrayEqual(inputs, message.inputs)) {\n return cache;\n }\n }\n\n const newMessage = fromThreadMessageLike(\n joinExternalMessages(message.outputs),\n idx.toString(),\n autoStatus,\n );\n (newMessage as any)[symbolInnerMessage] = message.inputs;\n return newMessage;\n },\n );\n\n (threadMessages as unknown as { [symbolInnerMessage]: T[] })[\n symbolInnerMessage\n ] = messages;\n\n return threadMessages;\n }, [state, messages, isRunning]);\n};\n\nconst shallowArrayEqual = (a: unknown[], b: unknown[]) => {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n};\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/runtimes/external-store/external-message-converter.tsx"],"sourcesContent":["\"use client\";\n\nimport { useMemo } from \"react\";\nimport { ThreadMessageConverter } from \"./ThreadMessageConverter\";\nimport {\n getExternalStoreMessages,\n symbolInnerMessage,\n} from \"./getExternalStoreMessage\";\nimport { fromThreadMessageLike, ThreadMessageLike } from \"./ThreadMessageLike\";\nimport { getAutoStatus, isAutoStatus } from \"./auto-status\";\nimport { ToolCallContentPart } from \"../../types\";\n\nexport namespace useExternalMessageConverter {\n export type Message =\n | (ThreadMessageLike & {\n readonly convertConfig?: {\n readonly joinStrategy?: \"concat-content\" | \"none\";\n };\n })\n | {\n role: \"tool\";\n toolCallId: string;\n toolName?: string | undefined;\n result: any;\n };\n\n export type Callback<T> = (message: T) => Message | Message[];\n}\n\ntype CallbackResult<T> = {\n input: T;\n outputs: useExternalMessageConverter.Message[];\n};\n\ntype ChunkResult<T> = {\n inputs: T[];\n outputs: useExternalMessageConverter.Message[];\n};\n\ntype Mutable<T> = {\n -readonly [P in keyof T]: T[P];\n};\n\nconst joinExternalMessages = (\n messages: readonly useExternalMessageConverter.Message[],\n): ThreadMessageLike => {\n const assistantMessage: Mutable<Omit<ThreadMessageLike, \"metadata\">> & {\n content: Exclude<ThreadMessageLike[\"content\"][0], string>[];\n metadata?: Mutable<ThreadMessageLike[\"metadata\"]>;\n } = {\n role: \"assistant\",\n content: [],\n };\n for (const output of messages) {\n if (output.role === \"tool\") {\n const toolCallIdx = assistantMessage.content.findIndex(\n (c) => c.type === \"tool-call\" && c.toolCallId === output.toolCallId,\n );\n if (toolCallIdx !== -1) {\n const toolCall = assistantMessage.content[\n toolCallIdx\n ]! as ToolCallContentPart;\n if (output.toolName) {\n if (toolCall.toolName !== output.toolName)\n throw new Error(\n `Tool call name ${output.toolCallId} ${output.toolName} does not match existing tool call ${toolCall.toolName}`,\n );\n }\n assistantMessage.content[toolCallIdx] = {\n ...toolCall,\n ...{\n [symbolInnerMessage]: [\n ...((toolCall as any)[symbolInnerMessage] ?? []),\n output,\n ],\n },\n result: output.result,\n };\n } else {\n throw new Error(\n `Tool call ${output.toolCallId} ${output.toolName} not found in assistant message`,\n );\n }\n } else {\n const role = output.role;\n const content = (\n typeof output.content === \"string\"\n ? [{ type: \"text\" as const, text: output.content }]\n : output.content\n ).map((c) => ({\n ...c,\n ...{ [symbolInnerMessage]: [output] },\n }));\n switch (role) {\n case \"system\":\n case \"user\":\n return {\n ...output,\n content,\n };\n case \"assistant\":\n if (assistantMessage.content.length === 0) {\n assistantMessage.id = output.id;\n assistantMessage.createdAt ??= output.createdAt;\n assistantMessage.status ??= output.status;\n\n if (output.attachments) {\n assistantMessage.attachments = [\n ...(assistantMessage.attachments ?? []),\n ...output.attachments,\n ];\n }\n\n if (output.metadata) {\n assistantMessage.metadata ??= {};\n if (output.metadata.unstable_annotations) {\n assistantMessage.metadata.unstable_annotations = [\n ...(assistantMessage.metadata.unstable_annotations ?? []),\n ...output.metadata.unstable_annotations,\n ];\n }\n if (output.metadata.unstable_data) {\n assistantMessage.metadata.unstable_data = [\n ...(assistantMessage.metadata.unstable_data ?? []),\n ...output.metadata.unstable_data,\n ];\n }\n if (output.metadata.steps) {\n assistantMessage.metadata.steps = [\n ...(assistantMessage.metadata.steps ?? []),\n ...output.metadata.steps,\n ];\n }\n if (output.metadata.custom) {\n assistantMessage.metadata.custom = {\n ...(assistantMessage.metadata.custom ?? {}),\n ...output.metadata.custom,\n };\n }\n }\n // TODO keep this in sync\n }\n\n assistantMessage.content.push(...content);\n break;\n default: {\n const unsupportedRole: never = role;\n throw new Error(`Unknown message role: ${unsupportedRole}`);\n }\n }\n }\n }\n return assistantMessage;\n};\n\nconst chunkExternalMessages = <T,>(\n callbackResults: CallbackResult<T>[],\n joinStrategy?: \"concat-content\" | \"none\",\n) => {\n const results: ChunkResult<T>[] = [];\n let isAssistant = false;\n let pendingNone = false; // true if the previous assistant message had joinStrategy \"none\"\n let inputs: T[] = [];\n let outputs: useExternalMessageConverter.Message[] = [];\n\n const flush = () => {\n if (outputs.length) {\n results.push({\n inputs,\n outputs,\n });\n }\n inputs = [];\n outputs = [];\n isAssistant = false;\n pendingNone = false;\n };\n\n for (const callbackResult of callbackResults) {\n for (const output of callbackResult.outputs) {\n if (\n (pendingNone && output.role !== \"tool\") ||\n !isAssistant ||\n output.role === \"user\" ||\n output.role === \"system\"\n ) {\n flush();\n }\n isAssistant = output.role === \"assistant\" || output.role === \"tool\";\n\n if (inputs.at(-1) !== callbackResult.input) {\n inputs.push(callbackResult.input);\n }\n outputs.push(output);\n\n if (\n output.role === \"assistant\" &&\n (output.convertConfig?.joinStrategy === \"none\" ||\n joinStrategy === \"none\")\n ) {\n pendingNone = true;\n }\n }\n }\n flush();\n return results;\n};\n\nexport const convertExternalMessages = <T extends WeakKey>(\n messages: T[],\n callback: useExternalMessageConverter.Callback<T>,\n isRunning: boolean,\n) => {\n const callbackResults: CallbackResult<T>[] = [];\n for (const message of messages) {\n const output = callback(message);\n const outputs = Array.isArray(output) ? output : [output];\n const result = { input: message, outputs };\n callbackResults.push(result);\n }\n\n const chunks = chunkExternalMessages(callbackResults);\n\n return chunks.map((message, idx) => {\n const isLast = idx === chunks.length - 1;\n const autoStatus = getAutoStatus(isLast, isRunning);\n const newMessage = fromThreadMessageLike(\n joinExternalMessages(message.outputs),\n idx.toString(),\n autoStatus,\n );\n (newMessage as any)[symbolInnerMessage] = message.inputs;\n return newMessage;\n });\n};\n\nexport const useExternalMessageConverter = <T extends WeakKey>({\n callback,\n messages,\n isRunning,\n joinStrategy,\n}: {\n callback: useExternalMessageConverter.Callback<T>;\n messages: T[];\n isRunning: boolean;\n joinStrategy?: \"concat-content\" | \"none\";\n}) => {\n const state = useMemo(\n () => ({\n callback,\n callbackCache: new WeakMap<T, CallbackResult<T>>(),\n chunkCache: new WeakMap<\n useExternalMessageConverter.Message,\n ChunkResult<T>\n >(),\n converterCache: new ThreadMessageConverter(),\n }),\n [callback],\n );\n\n return useMemo(() => {\n const callbackResults: CallbackResult<T>[] = [];\n for (const message of messages) {\n let result = state.callbackCache.get(message);\n if (!result) {\n const output = state.callback(message);\n const outputs = Array.isArray(output) ? output : [output];\n result = { input: message, outputs };\n state.callbackCache.set(message, result);\n }\n callbackResults.push(result);\n }\n\n const chunks = chunkExternalMessages(callbackResults, joinStrategy).map(\n (m) => {\n const key = m.outputs[0];\n if (!key) return m;\n\n const cached = state.chunkCache.get(key);\n if (cached && shallowArrayEqual(cached.outputs, m.outputs))\n return cached;\n state.chunkCache.set(key, m);\n return m;\n },\n );\n\n const threadMessages = state.converterCache.convertMessages(\n chunks,\n (cache, message, idx) => {\n const isLast = idx === chunks.length - 1;\n const autoStatus = getAutoStatus(isLast, isRunning);\n\n if (\n cache &&\n (cache.role !== \"assistant\" ||\n !isAutoStatus(cache.status) ||\n cache.status === autoStatus)\n ) {\n const inputs = getExternalStoreMessages<T>(cache);\n if (shallowArrayEqual(inputs, message.inputs)) {\n return cache;\n }\n }\n\n const newMessage = fromThreadMessageLike(\n joinExternalMessages(message.outputs),\n idx.toString(),\n autoStatus,\n );\n (newMessage as any)[symbolInnerMessage] = message.inputs;\n return newMessage;\n },\n );\n\n (threadMessages as unknown as { [symbolInnerMessage]: T[] })[\n symbolInnerMessage\n ] = messages;\n\n return threadMessages;\n }, [state, messages, isRunning]);\n};\n\nconst shallowArrayEqual = (a: unknown[], b: unknown[]) => {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n};\n"],"mappings":"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","names":[]}
@@ -9,7 +9,7 @@
9
9
  }
10
10
 
11
11
  .aui-thread-viewport-footer {
12
- @apply max-w-aui-thread sticky bottom-0 mt-3 flex w-full flex-col items-center justify-end rounded-t-lg bg-inherit pb-4;
12
+ @apply max-w-[var(--aui-thread-max-width)] sticky bottom-0 mt-3 flex w-full flex-col items-center justify-end rounded-t-lg bg-inherit pb-4;
13
13
  }
14
14
 
15
15
  .aui-thread-scroll-to-bottom {
@@ -27,7 +27,7 @@
27
27
  /* thread welcome */
28
28
 
29
29
  .aui-thread-welcome-root {
30
- @apply max-w-aui-thread flex w-full flex-grow flex-col;
30
+ @apply max-w-[var(--aui-thread-max-width)] flex w-full flex-grow flex-col;
31
31
  }
32
32
 
33
33
  .aui-thread-welcome-center {
@@ -108,7 +108,7 @@
108
108
 
109
109
  .aui-user-message-root {
110
110
  @apply grid auto-rows-auto grid-cols-[minmax(72px,1fr)_auto] gap-y-2 [&>*]:col-start-2;
111
- @apply max-w-aui-thread w-full py-4;
111
+ @apply max-w-[var(--aui-thread-max-width)] w-full py-4;
112
112
  }
113
113
 
114
114
  :where(.aui-user-message-root) > .aui-user-action-bar-root {
@@ -146,7 +146,7 @@
146
146
  /* edit composer */
147
147
 
148
148
  .aui-edit-composer-root {
149
- @apply bg-aui-muted max-w-aui-thread my-4 flex w-full flex-col gap-2 rounded-xl;
149
+ @apply bg-aui-muted max-w-[var(--aui-thread-max-width)] my-4 flex w-full flex-col gap-2 rounded-xl;
150
150
  }
151
151
 
152
152
  .aui-edit-composer-input {
@@ -161,7 +161,7 @@
161
161
 
162
162
  .aui-assistant-message-root {
163
163
  @apply grid grid-cols-[auto_auto_1fr] grid-rows-[auto_1fr];
164
- @apply max-w-aui-thread relative w-full py-4;
164
+ @apply max-w-[var(--aui-thread-max-width)] relative w-full py-4;
165
165
  }
166
166
 
167
167
  :where(.aui-assistant-message-root) > .aui-avatar-root {
@@ -7,7 +7,7 @@
7
7
  "@apply bg-aui-background flex h-full flex-col items-center overflow-y-scroll scroll-smooth px-4 pt-8": {}
8
8
  },
9
9
  ".aui-thread-viewport-footer": {
10
- "@apply max-w-aui-thread sticky bottom-0 mt-3 flex w-full flex-col items-center justify-end rounded-t-lg bg-inherit pb-4": {}
10
+ "@apply max-w-[var(--aui-thread-max-width)] sticky bottom-0 mt-3 flex w-full flex-col items-center justify-end rounded-t-lg bg-inherit pb-4": {}
11
11
  },
12
12
  ".aui-thread-scroll-to-bottom": {
13
13
  "@apply absolute -top-8 rounded-full disabled:invisible": {}
@@ -19,7 +19,7 @@
19
19
  "@apply bg-aui-background hover:bg-aui-muted/80 rounded-full border px-3 py-1 text-sm transition-colors ease-in": {}
20
20
  },
21
21
  ".aui-thread-welcome-root": {
22
- "@apply max-w-aui-thread flex w-full flex-grow flex-col": {}
22
+ "@apply max-w-[var(--aui-thread-max-width)] flex w-full flex-grow flex-col": {}
23
23
  },
24
24
  ".aui-thread-welcome-center": {
25
25
  "@apply flex w-full flex-grow flex-col items-center justify-center": {}
@@ -74,7 +74,7 @@
74
74
  },
75
75
  ".aui-user-message-root": {
76
76
  "@apply grid auto-rows-auto grid-cols-[minmax(72px,1fr)_auto] gap-y-2 [&>*]:col-start-2": {},
77
- "@apply max-w-aui-thread w-full py-4": {}
77
+ "@apply max-w-[var(--aui-thread-max-width)] w-full py-4": {}
78
78
  },
79
79
  ":where(.aui-user-message-root) > .aui-user-action-bar-root": {
80
80
  "@apply col-start-1 row-start-2 mr-3 mt-2.5": {}
@@ -100,7 +100,7 @@
100
100
  "@apply flex flex-col items-end": {}
101
101
  },
102
102
  ".aui-edit-composer-root": {
103
- "@apply bg-aui-muted max-w-aui-thread my-4 flex w-full flex-col gap-2 rounded-xl": {}
103
+ "@apply bg-aui-muted max-w-[var(--aui-thread-max-width)] my-4 flex w-full flex-col gap-2 rounded-xl": {}
104
104
  },
105
105
  ".aui-edit-composer-input": {
106
106
  "@apply text-aui-foreground flex h-8 w-full resize-none bg-transparent p-4 pb-0 outline-none": {}
@@ -110,7 +110,7 @@
110
110
  },
111
111
  ".aui-assistant-message-root": {
112
112
  "@apply grid grid-cols-[auto_auto_1fr] grid-rows-[auto_1fr]": {},
113
- "@apply max-w-aui-thread relative w-full py-4": {}
113
+ "@apply max-w-[var(--aui-thread-max-width)] relative w-full py-4": {}
114
114
  },
115
115
  ":where(.aui-assistant-message-root) > .aui-avatar-root": {
116
116
  "@apply col-start-1 row-span-full row-start-1 mr-4": {}
package/package.json CHANGED
@@ -29,7 +29,7 @@
29
29
  "conversational-ui",
30
30
  "conversational-ai"
31
31
  ],
32
- "version": "0.7.67",
32
+ "version": "0.7.69",
33
33
  "license": "MIT",
34
34
  "exports": {
35
35
  ".": {
@@ -118,8 +118,8 @@
118
118
  "tailwindcss-animate": "^1.0.7",
119
119
  "tsx": "^4.19.2",
120
120
  "@assistant-ui/tailwindcss-transformer": "0.1.0",
121
- "@assistant-ui/tsbuildutils": "^0.0.1",
122
- "@assistant-ui/tsconfig": "0.0.0"
121
+ "@assistant-ui/tsconfig": "0.0.0",
122
+ "@assistant-ui/tsbuildutils": "^0.0.1"
123
123
  },
124
124
  "publishConfig": {
125
125
  "access": "public",
@@ -12,3 +12,4 @@ export * as ThreadListItemPrimitive from "./threadListItem";
12
12
  export { useContentPartDisplay } from "./contentPart/useContentPartDisplay";
13
13
  export { useContentPartImage } from "./contentPart/useContentPartImage";
14
14
  export { useContentPartText } from "./contentPart/useContentPartText";
15
+ export { useThreadViewportAutoScroll } from "./thread/useThreadViewportAutoScroll";
@@ -14,7 +14,7 @@ const useThreadSuggestion = ({
14
14
  autoSend,
15
15
  }: {
16
16
  prompt: string;
17
- method: "replace";
17
+ method?: "replace";
18
18
  autoSend?: boolean | undefined;
19
19
  }) => {
20
20
  const threadRuntime = useThreadRuntime();
@@ -23,7 +23,6 @@ const useThreadSuggestion = ({
23
23
  const callback = useCallback(() => {
24
24
  if (autoSend && !threadRuntime.getState().isRunning) {
25
25
  threadRuntime.append(prompt);
26
- threadRuntime.composer.setText("");
27
26
  } else {
28
27
  threadRuntime.composer.setText(prompt);
29
28
  }
@@ -12,7 +12,11 @@ import { ToolCallContentPart } from "../../types";
12
12
 
13
13
  export namespace useExternalMessageConverter {
14
14
  export type Message =
15
- | ThreadMessageLike
15
+ | (ThreadMessageLike & {
16
+ readonly convertConfig?: {
17
+ readonly joinStrategy?: "concat-content" | "none";
18
+ };
19
+ })
16
20
  | {
17
21
  role: "tool";
18
22
  toolCallId: string;
@@ -149,9 +153,13 @@ const joinExternalMessages = (
149
153
  return assistantMessage;
150
154
  };
151
155
 
152
- const chunkExternalMessages = <T,>(callbackResults: CallbackResult<T>[]) => {
156
+ const chunkExternalMessages = <T,>(
157
+ callbackResults: CallbackResult<T>[],
158
+ joinStrategy?: "concat-content" | "none",
159
+ ) => {
153
160
  const results: ChunkResult<T>[] = [];
154
161
  let isAssistant = false;
162
+ let pendingNone = false; // true if the previous assistant message had joinStrategy "none"
155
163
  let inputs: T[] = [];
156
164
  let outputs: useExternalMessageConverter.Message[] = [];
157
165
 
@@ -164,11 +172,18 @@ const chunkExternalMessages = <T,>(callbackResults: CallbackResult<T>[]) => {
164
172
  }
165
173
  inputs = [];
166
174
  outputs = [];
175
+ isAssistant = false;
176
+ pendingNone = false;
167
177
  };
168
178
 
169
179
  for (const callbackResult of callbackResults) {
170
180
  for (const output of callbackResult.outputs) {
171
- if (!isAssistant || output.role === "user" || output.role === "system") {
181
+ if (
182
+ (pendingNone && output.role !== "tool") ||
183
+ !isAssistant ||
184
+ output.role === "user" ||
185
+ output.role === "system"
186
+ ) {
172
187
  flush();
173
188
  }
174
189
  isAssistant = output.role === "assistant" || output.role === "tool";
@@ -177,6 +192,14 @@ const chunkExternalMessages = <T,>(callbackResults: CallbackResult<T>[]) => {
177
192
  inputs.push(callbackResult.input);
178
193
  }
179
194
  outputs.push(output);
195
+
196
+ if (
197
+ output.role === "assistant" &&
198
+ (output.convertConfig?.joinStrategy === "none" ||
199
+ joinStrategy === "none")
200
+ ) {
201
+ pendingNone = true;
202
+ }
180
203
  }
181
204
  }
182
205
  flush();
@@ -215,10 +238,12 @@ export const useExternalMessageConverter = <T extends WeakKey>({
215
238
  callback,
216
239
  messages,
217
240
  isRunning,
241
+ joinStrategy,
218
242
  }: {
219
243
  callback: useExternalMessageConverter.Callback<T>;
220
244
  messages: T[];
221
245
  isRunning: boolean;
246
+ joinStrategy?: "concat-content" | "none";
222
247
  }) => {
223
248
  const state = useMemo(
224
249
  () => ({
@@ -246,15 +271,18 @@ export const useExternalMessageConverter = <T extends WeakKey>({
246
271
  callbackResults.push(result);
247
272
  }
248
273
 
249
- const chunks = chunkExternalMessages(callbackResults).map((m) => {
250
- const key = m.outputs[0];
251
- if (!key) return m;
274
+ const chunks = chunkExternalMessages(callbackResults, joinStrategy).map(
275
+ (m) => {
276
+ const key = m.outputs[0];
277
+ if (!key) return m;
252
278
 
253
- const cached = state.chunkCache.get(key);
254
- if (cached && shallowArrayEqual(cached.outputs, m.outputs)) return cached;
255
- state.chunkCache.set(key, m);
256
- return m;
257
- });
279
+ const cached = state.chunkCache.get(key);
280
+ if (cached && shallowArrayEqual(cached.outputs, m.outputs))
281
+ return cached;
282
+ state.chunkCache.set(key, m);
283
+ return m;
284
+ },
285
+ );
258
286
 
259
287
  const threadMessages = state.converterCache.convertMessages(
260
288
  chunks,
@@ -9,7 +9,7 @@
9
9
  }
10
10
 
11
11
  .aui-thread-viewport-footer {
12
- @apply max-w-aui-thread sticky bottom-0 mt-3 flex w-full flex-col items-center justify-end rounded-t-lg bg-inherit pb-4;
12
+ @apply max-w-[var(--aui-thread-max-width)] sticky bottom-0 mt-3 flex w-full flex-col items-center justify-end rounded-t-lg bg-inherit pb-4;
13
13
  }
14
14
 
15
15
  .aui-thread-scroll-to-bottom {
@@ -27,7 +27,7 @@
27
27
  /* thread welcome */
28
28
 
29
29
  .aui-thread-welcome-root {
30
- @apply max-w-aui-thread flex w-full flex-grow flex-col;
30
+ @apply max-w-[var(--aui-thread-max-width)] flex w-full flex-grow flex-col;
31
31
  }
32
32
 
33
33
  .aui-thread-welcome-center {
@@ -108,7 +108,7 @@
108
108
 
109
109
  .aui-user-message-root {
110
110
  @apply grid auto-rows-auto grid-cols-[minmax(72px,1fr)_auto] gap-y-2 [&>*]:col-start-2;
111
- @apply max-w-aui-thread w-full py-4;
111
+ @apply max-w-[var(--aui-thread-max-width)] w-full py-4;
112
112
  }
113
113
 
114
114
  :where(.aui-user-message-root) > .aui-user-action-bar-root {
@@ -146,7 +146,7 @@
146
146
  /* edit composer */
147
147
 
148
148
  .aui-edit-composer-root {
149
- @apply bg-aui-muted max-w-aui-thread my-4 flex w-full flex-col gap-2 rounded-xl;
149
+ @apply bg-aui-muted max-w-[var(--aui-thread-max-width)] my-4 flex w-full flex-col gap-2 rounded-xl;
150
150
  }
151
151
 
152
152
  .aui-edit-composer-input {
@@ -161,7 +161,7 @@
161
161
 
162
162
  .aui-assistant-message-root {
163
163
  @apply grid grid-cols-[auto_auto_1fr] grid-rows-[auto_1fr];
164
- @apply max-w-aui-thread relative w-full py-4;
164
+ @apply max-w-[var(--aui-thread-max-width)] relative w-full py-4;
165
165
  }
166
166
 
167
167
  :where(.aui-assistant-message-root) > .aui-avatar-root {