@assistant-ui/react 0.11.47 → 0.11.49

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.
Files changed (86) hide show
  1. package/dist/client/types/Thread.d.ts +4 -0
  2. package/dist/client/types/Thread.d.ts.map +1 -1
  3. package/dist/context/react/index.d.ts +1 -1
  4. package/dist/context/react/index.d.ts.map +1 -1
  5. package/dist/context/react/index.js.map +1 -1
  6. package/dist/context/stores/ThreadViewport.js +1 -1
  7. package/dist/context/stores/ThreadViewport.js.map +1 -1
  8. package/dist/legacy-runtime/client/ThreadRuntimeClient.d.ts.map +1 -1
  9. package/dist/legacy-runtime/client/ThreadRuntimeClient.js +1 -0
  10. package/dist/legacy-runtime/client/ThreadRuntimeClient.js.map +1 -1
  11. package/dist/legacy-runtime/runtime/subscribable/SKIP_UPDATE.js +1 -1
  12. package/dist/legacy-runtime/runtime/subscribable/SKIP_UPDATE.js.map +1 -1
  13. package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.js +2 -2
  14. package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.js.map +1 -1
  15. package/dist/legacy-runtime/runtime-cores/assistant-transport/useToolInvocations.d.ts +1 -4
  16. package/dist/legacy-runtime/runtime-cores/assistant-transport/useToolInvocations.d.ts.map +1 -1
  17. package/dist/legacy-runtime/runtime-cores/assistant-transport/useToolInvocations.js +34 -12
  18. package/dist/legacy-runtime/runtime-cores/assistant-transport/useToolInvocations.js.map +1 -1
  19. package/dist/legacy-runtime/runtime-cores/external-store/auto-status.js +1 -1
  20. package/dist/legacy-runtime/runtime-cores/external-store/auto-status.js.map +1 -1
  21. package/dist/legacy-runtime/runtime-cores/external-store/getExternalStoreMessage.js +2 -2
  22. package/dist/legacy-runtime/runtime-cores/external-store/getExternalStoreMessage.js.map +1 -1
  23. package/dist/model-context/registry/ModelContextRegistry.js +3 -3
  24. package/dist/model-context/registry/ModelContextRegistry.js.map +1 -1
  25. package/dist/primitives/actionBar/ActionBarExportMarkdown.d.ts +17 -0
  26. package/dist/primitives/actionBar/ActionBarExportMarkdown.d.ts.map +1 -0
  27. package/dist/primitives/actionBar/ActionBarExportMarkdown.js +54 -0
  28. package/dist/primitives/actionBar/ActionBarExportMarkdown.js.map +1 -0
  29. package/dist/primitives/actionBar/index.d.ts +1 -0
  30. package/dist/primitives/actionBar/index.d.ts.map +1 -1
  31. package/dist/primitives/actionBar/index.js +2 -0
  32. package/dist/primitives/actionBar/index.js.map +1 -1
  33. package/dist/primitives/assistant/AssistantIf.d.ts +12 -0
  34. package/dist/primitives/assistant/AssistantIf.d.ts.map +1 -0
  35. package/dist/primitives/assistant/AssistantIf.js +16 -0
  36. package/dist/primitives/assistant/AssistantIf.js.map +1 -0
  37. package/dist/primitives/composer/ComposerIf.d.ts +3 -0
  38. package/dist/primitives/composer/ComposerIf.d.ts.map +1 -1
  39. package/dist/primitives/composer/ComposerIf.js.map +1 -1
  40. package/dist/primitives/composer/ComposerInput.d.ts.map +1 -1
  41. package/dist/primitives/composer/ComposerInput.js +1 -0
  42. package/dist/primitives/composer/ComposerInput.js.map +1 -1
  43. package/dist/primitives/index.d.ts +1 -0
  44. package/dist/primitives/index.d.ts.map +1 -1
  45. package/dist/primitives/index.js +2 -0
  46. package/dist/primitives/index.js.map +1 -1
  47. package/dist/primitives/message/MessageIf.d.ts +3 -0
  48. package/dist/primitives/message/MessageIf.d.ts.map +1 -1
  49. package/dist/primitives/message/MessageIf.js.map +1 -1
  50. package/dist/primitives/message/MessageParts.js +2 -2
  51. package/dist/primitives/message/MessageParts.js.map +1 -1
  52. package/dist/primitives/thread/ThreadIf.d.ts +3 -0
  53. package/dist/primitives/thread/ThreadIf.d.ts.map +1 -1
  54. package/dist/primitives/thread/ThreadIf.js +2 -3
  55. package/dist/primitives/thread/ThreadIf.js.map +1 -1
  56. package/dist/primitives/thread/ThreadViewport.d.ts +36 -0
  57. package/dist/primitives/thread/ThreadViewport.d.ts.map +1 -1
  58. package/dist/primitives/thread/ThreadViewport.js +21 -12
  59. package/dist/primitives/thread/ThreadViewport.js.map +1 -1
  60. package/dist/primitives/thread/ThreadViewportSlack.d.ts.map +1 -1
  61. package/dist/primitives/thread/ThreadViewportSlack.js +4 -1
  62. package/dist/primitives/thread/ThreadViewportSlack.js.map +1 -1
  63. package/dist/primitives/thread/useThreadViewportAutoScroll.d.ts +20 -2
  64. package/dist/primitives/thread/useThreadViewportAutoScroll.d.ts.map +1 -1
  65. package/dist/primitives/thread/useThreadViewportAutoScroll.js +21 -2
  66. package/dist/primitives/thread/useThreadViewportAutoScroll.js.map +1 -1
  67. package/dist/tests/setup.js +44 -42
  68. package/dist/tests/setup.js.map +1 -1
  69. package/package.json +7 -7
  70. package/src/client/types/Thread.ts +5 -0
  71. package/src/context/react/index.ts +1 -0
  72. package/src/legacy-runtime/client/ThreadRuntimeClient.ts +1 -0
  73. package/src/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.tsx +1 -1
  74. package/src/legacy-runtime/runtime-cores/assistant-transport/useToolInvocations.ts +40 -17
  75. package/src/primitives/actionBar/ActionBarExportMarkdown.tsx +70 -0
  76. package/src/primitives/actionBar/index.ts +1 -0
  77. package/src/primitives/assistant/AssistantIf.tsx +25 -0
  78. package/src/primitives/composer/ComposerIf.tsx +3 -0
  79. package/src/primitives/composer/ComposerInput.tsx +3 -0
  80. package/src/primitives/index.ts +2 -0
  81. package/src/primitives/message/MessageIf.tsx +3 -0
  82. package/src/primitives/message/MessageParts.tsx +2 -2
  83. package/src/primitives/thread/ThreadIf.tsx +5 -3
  84. package/src/primitives/thread/ThreadViewport.tsx +49 -18
  85. package/src/primitives/thread/ThreadViewportSlack.tsx +4 -1
  86. package/src/primitives/thread/useThreadViewportAutoScroll.tsx +48 -2
@@ -0,0 +1,54 @@
1
+ "use client";
2
+
3
+ // src/primitives/actionBar/ActionBarExportMarkdown.tsx
4
+ import { forwardRef, useCallback } from "react";
5
+ import { composeEventHandlers } from "@radix-ui/primitive";
6
+ import { Primitive } from "@radix-ui/react-primitive";
7
+ import { useAssistantState, useAssistantApi } from "../../context/index.js";
8
+ import { jsx } from "react/jsx-runtime";
9
+ var useActionBarExportMarkdown = ({
10
+ filename,
11
+ onExport
12
+ } = {}) => {
13
+ const api = useAssistantApi();
14
+ const hasExportableContent = useAssistantState(({ message }) => {
15
+ return (message.role !== "assistant" || message.status?.type !== "running") && message.parts.some((c) => c.type === "text" && c.text.length > 0);
16
+ });
17
+ const callback = useCallback(async () => {
18
+ const content = api.message().getCopyText();
19
+ if (!content) return;
20
+ if (onExport) {
21
+ await onExport(content);
22
+ return;
23
+ }
24
+ const blob = new Blob([content], { type: "text/markdown" });
25
+ const url = URL.createObjectURL(blob);
26
+ const a = document.createElement("a");
27
+ a.href = url;
28
+ a.download = filename ?? `message-${Date.now()}.md`;
29
+ a.click();
30
+ URL.revokeObjectURL(url);
31
+ }, [api, filename, onExport]);
32
+ if (!hasExportableContent) return null;
33
+ return callback;
34
+ };
35
+ var ActionBarPrimitiveExportMarkdown = forwardRef(({ filename, onExport, onClick, disabled, ...props }, forwardedRef) => {
36
+ const callback = useActionBarExportMarkdown({ filename, onExport });
37
+ return /* @__PURE__ */ jsx(
38
+ Primitive.button,
39
+ {
40
+ type: "button",
41
+ ...props,
42
+ ref: forwardedRef,
43
+ disabled: disabled || !callback,
44
+ onClick: composeEventHandlers(onClick, () => {
45
+ callback?.();
46
+ })
47
+ }
48
+ );
49
+ });
50
+ ActionBarPrimitiveExportMarkdown.displayName = "ActionBarPrimitive.ExportMarkdown";
51
+ export {
52
+ ActionBarPrimitiveExportMarkdown
53
+ };
54
+ //# sourceMappingURL=ActionBarExportMarkdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/primitives/actionBar/ActionBarExportMarkdown.tsx"],"sourcesContent":["\"use client\";\n\nimport { forwardRef, useCallback } from \"react\";\nimport { ActionButtonProps } from \"../../utils/createActionButton\";\nimport { composeEventHandlers } from \"@radix-ui/primitive\";\nimport { Primitive } from \"@radix-ui/react-primitive\";\nimport { useAssistantState, useAssistantApi } from \"../../context\";\n\nconst useActionBarExportMarkdown = ({\n filename,\n onExport,\n}: {\n filename?: string | undefined;\n onExport?: ((content: string) => void | Promise<void>) | undefined;\n} = {}) => {\n const api = useAssistantApi();\n const hasExportableContent = useAssistantState(({ message }) => {\n return (\n (message.role !== \"assistant\" || message.status?.type !== \"running\") &&\n message.parts.some((c) => c.type === \"text\" && c.text.length > 0)\n );\n });\n\n const callback = useCallback(async () => {\n const content = api.message().getCopyText();\n if (!content) return;\n\n if (onExport) {\n await onExport(content);\n return;\n }\n\n const blob = new Blob([content], { type: \"text/markdown\" });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.href = url;\n a.download = filename ?? `message-${Date.now()}.md`;\n a.click();\n URL.revokeObjectURL(url);\n }, [api, filename, onExport]);\n\n if (!hasExportableContent) return null;\n return callback;\n};\n\nexport namespace ActionBarPrimitiveExportMarkdown {\n export type Element = HTMLButtonElement;\n export type Props = ActionButtonProps<typeof useActionBarExportMarkdown>;\n}\n\nexport const ActionBarPrimitiveExportMarkdown = forwardRef<\n ActionBarPrimitiveExportMarkdown.Element,\n ActionBarPrimitiveExportMarkdown.Props\n>(({ filename, onExport, onClick, disabled, ...props }, forwardedRef) => {\n const callback = useActionBarExportMarkdown({ filename, onExport });\n return (\n <Primitive.button\n type=\"button\"\n {...props}\n ref={forwardedRef}\n disabled={disabled || !callback}\n onClick={composeEventHandlers(onClick, () => {\n callback?.();\n })}\n />\n );\n});\n\nActionBarPrimitiveExportMarkdown.displayName =\n \"ActionBarPrimitive.ExportMarkdown\";\n"],"mappings":";;;AAEA,SAAS,YAAY,mBAAmB;AAExC,SAAS,4BAA4B;AACrC,SAAS,iBAAiB;AAC1B,SAAS,mBAAmB,uBAAuB;AAkD/C;AAhDJ,IAAM,6BAA6B,CAAC;AAAA,EAClC;AAAA,EACA;AACF,IAGI,CAAC,MAAM;AACT,QAAM,MAAM,gBAAgB;AAC5B,QAAM,uBAAuB,kBAAkB,CAAC,EAAE,QAAQ,MAAM;AAC9D,YACG,QAAQ,SAAS,eAAe,QAAQ,QAAQ,SAAS,cAC1D,QAAQ,MAAM,KAAK,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,KAAK,SAAS,CAAC;AAAA,EAEpE,CAAC;AAED,QAAM,WAAW,YAAY,YAAY;AACvC,UAAM,UAAU,IAAI,QAAQ,EAAE,YAAY;AAC1C,QAAI,CAAC,QAAS;AAEd,QAAI,UAAU;AACZ,YAAM,SAAS,OAAO;AACtB;AAAA,IACF;AAEA,UAAM,OAAO,IAAI,KAAK,CAAC,OAAO,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAC1D,UAAM,MAAM,IAAI,gBAAgB,IAAI;AACpC,UAAM,IAAI,SAAS,cAAc,GAAG;AACpC,MAAE,OAAO;AACT,MAAE,WAAW,YAAY,WAAW,KAAK,IAAI,CAAC;AAC9C,MAAE,MAAM;AACR,QAAI,gBAAgB,GAAG;AAAA,EACzB,GAAG,CAAC,KAAK,UAAU,QAAQ,CAAC;AAE5B,MAAI,CAAC,qBAAsB,QAAO;AAClC,SAAO;AACT;AAOO,IAAM,mCAAmC,WAG9C,CAAC,EAAE,UAAU,UAAU,SAAS,UAAU,GAAG,MAAM,GAAG,iBAAiB;AACvE,QAAM,WAAW,2BAA2B,EAAE,UAAU,SAAS,CAAC;AAClE,SACE;AAAA,IAAC,UAAU;AAAA,IAAV;AAAA,MACC,MAAK;AAAA,MACJ,GAAG;AAAA,MACJ,KAAK;AAAA,MACL,UAAU,YAAY,CAAC;AAAA,MACvB,SAAS,qBAAqB,SAAS,MAAM;AAC3C,mBAAW;AAAA,MACb,CAAC;AAAA;AAAA,EACH;AAEJ,CAAC;AAED,iCAAiC,cAC/B;","names":[]}
@@ -6,4 +6,5 @@ export { ActionBarPrimitiveSpeak as Speak } from "./ActionBarSpeak";
6
6
  export { ActionBarPrimitiveStopSpeaking as StopSpeaking } from "./ActionBarStopSpeaking";
7
7
  export { ActionBarPrimitiveFeedbackPositive as FeedbackPositive } from "./ActionBarFeedbackPositive";
8
8
  export { ActionBarPrimitiveFeedbackNegative as FeedbackNegative } from "./ActionBarFeedbackNegative";
9
+ export { ActionBarPrimitiveExportMarkdown as ExportMarkdown } from "./ActionBarExportMarkdown";
9
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/primitives/actionBar/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,IAAI,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,sBAAsB,IAAI,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,wBAAwB,IAAI,MAAM,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,sBAAsB,IAAI,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,uBAAuB,IAAI,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,8BAA8B,IAAI,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACzF,OAAO,EAAE,kCAAkC,IAAI,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AACrG,OAAO,EAAE,kCAAkC,IAAI,gBAAgB,EAAE,MAAM,6BAA6B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/primitives/actionBar/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,IAAI,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,sBAAsB,IAAI,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,wBAAwB,IAAI,MAAM,EAAE,MAAM,mBAAmB,CAAC;AACvE,OAAO,EAAE,sBAAsB,IAAI,IAAI,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,EAAE,uBAAuB,IAAI,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EAAE,8BAA8B,IAAI,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACzF,OAAO,EAAE,kCAAkC,IAAI,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AACrG,OAAO,EAAE,kCAAkC,IAAI,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AACrG,OAAO,EAAE,gCAAgC,IAAI,cAAc,EAAE,MAAM,2BAA2B,CAAC"}
@@ -7,9 +7,11 @@ import { ActionBarPrimitiveSpeak } from "./ActionBarSpeak.js";
7
7
  import { ActionBarPrimitiveStopSpeaking } from "./ActionBarStopSpeaking.js";
8
8
  import { ActionBarPrimitiveFeedbackPositive } from "./ActionBarFeedbackPositive.js";
9
9
  import { ActionBarPrimitiveFeedbackNegative } from "./ActionBarFeedbackNegative.js";
10
+ import { ActionBarPrimitiveExportMarkdown } from "./ActionBarExportMarkdown.js";
10
11
  export {
11
12
  ActionBarPrimitiveCopy as Copy,
12
13
  ActionBarPrimitiveEdit as Edit,
14
+ ActionBarPrimitiveExportMarkdown as ExportMarkdown,
13
15
  ActionBarPrimitiveFeedbackNegative as FeedbackNegative,
14
16
  ActionBarPrimitiveFeedbackPositive as FeedbackPositive,
15
17
  ActionBarPrimitiveReload as Reload,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/primitives/actionBar/index.ts"],"sourcesContent":["export { ActionBarPrimitiveRoot as Root } from \"./ActionBarRoot\";\nexport { ActionBarPrimitiveCopy as Copy } from \"./ActionBarCopy\";\nexport { ActionBarPrimitiveReload as Reload } from \"./ActionBarReload\";\nexport { ActionBarPrimitiveEdit as Edit } from \"./ActionBarEdit\";\nexport { ActionBarPrimitiveSpeak as Speak } from \"./ActionBarSpeak\";\nexport { ActionBarPrimitiveStopSpeaking as StopSpeaking } from \"./ActionBarStopSpeaking\";\nexport { ActionBarPrimitiveFeedbackPositive as FeedbackPositive } from \"./ActionBarFeedbackPositive\";\nexport { ActionBarPrimitiveFeedbackNegative as FeedbackNegative } from \"./ActionBarFeedbackNegative\";\n"],"mappings":";AAAA,SAAmC,8BAAY;AAC/C,SAAmC,8BAAY;AAC/C,SAAqC,gCAAc;AACnD,SAAmC,8BAAY;AAC/C,SAAoC,+BAAa;AACjD,SAA2C,sCAAoB;AAC/D,SAA+C,0CAAwB;AACvE,SAA+C,0CAAwB;","names":[]}
1
+ {"version":3,"sources":["../../../src/primitives/actionBar/index.ts"],"sourcesContent":["export { ActionBarPrimitiveRoot as Root } from \"./ActionBarRoot\";\nexport { ActionBarPrimitiveCopy as Copy } from \"./ActionBarCopy\";\nexport { ActionBarPrimitiveReload as Reload } from \"./ActionBarReload\";\nexport { ActionBarPrimitiveEdit as Edit } from \"./ActionBarEdit\";\nexport { ActionBarPrimitiveSpeak as Speak } from \"./ActionBarSpeak\";\nexport { ActionBarPrimitiveStopSpeaking as StopSpeaking } from \"./ActionBarStopSpeaking\";\nexport { ActionBarPrimitiveFeedbackPositive as FeedbackPositive } from \"./ActionBarFeedbackPositive\";\nexport { ActionBarPrimitiveFeedbackNegative as FeedbackNegative } from \"./ActionBarFeedbackNegative\";\nexport { ActionBarPrimitiveExportMarkdown as ExportMarkdown } from \"./ActionBarExportMarkdown\";\n"],"mappings":";AAAA,SAAmC,8BAAY;AAC/C,SAAmC,8BAAY;AAC/C,SAAqC,gCAAc;AACnD,SAAmC,8BAAY;AAC/C,SAAoC,+BAAa;AACjD,SAA2C,sCAAoB;AAC/D,SAA+C,0CAAwB;AACvE,SAA+C,0CAAwB;AACvE,SAA6C,wCAAsB;","names":[]}
@@ -0,0 +1,12 @@
1
+ import type { FC, PropsWithChildren } from "react";
2
+ import type { AssistantState } from "../../context/react/AssistantApiContext";
3
+ type UseAssistantIfProps = {
4
+ condition: AssistantIf.Condition;
5
+ };
6
+ export declare namespace AssistantIf {
7
+ type Props = PropsWithChildren<UseAssistantIfProps>;
8
+ type Condition = (state: AssistantState) => boolean;
9
+ }
10
+ export declare const AssistantIf: FC<AssistantIf.Props>;
11
+ export {};
12
+ //# sourceMappingURL=AssistantIf.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AssistantIf.d.ts","sourceRoot":"","sources":["../../../src/primitives/assistant/AssistantIf.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAE,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAEnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,yCAAyC,CAAC;AAE9E,KAAK,mBAAmB,GAAG;IACzB,SAAS,EAAE,WAAW,CAAC,SAAS,CAAC;CAClC,CAAC;AAMF,yBAAiB,WAAW,CAAC;IAC3B,KAAY,KAAK,GAAG,iBAAiB,CAAC,mBAAmB,CAAC,CAAC;IAC3D,KAAY,SAAS,GAAG,CAAC,KAAK,EAAE,cAAc,KAAK,OAAO,CAAC;CAC5D;AAED,eAAO,MAAM,WAAW,EAAE,EAAE,CAAC,WAAW,CAAC,KAAK,CAG7C,CAAC"}
@@ -0,0 +1,16 @@
1
+ "use client";
2
+
3
+ // src/primitives/assistant/AssistantIf.tsx
4
+ import { useAssistantState } from "../../context/index.js";
5
+ var useAssistantIf = (props) => {
6
+ return useAssistantState(props.condition);
7
+ };
8
+ var AssistantIf = ({ children, condition }) => {
9
+ const result = useAssistantIf({ condition });
10
+ return result ? children : null;
11
+ };
12
+ AssistantIf.displayName = "AssistantIf";
13
+ export {
14
+ AssistantIf
15
+ };
16
+ //# sourceMappingURL=AssistantIf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/primitives/assistant/AssistantIf.tsx"],"sourcesContent":["\"use client\";\n\nimport type { FC, PropsWithChildren } from \"react\";\nimport { useAssistantState } from \"../../context\";\nimport type { AssistantState } from \"../../context/react/AssistantApiContext\";\n\ntype UseAssistantIfProps = {\n condition: AssistantIf.Condition;\n};\n\nconst useAssistantIf = (props: UseAssistantIfProps) => {\n return useAssistantState(props.condition);\n};\n\nexport namespace AssistantIf {\n export type Props = PropsWithChildren<UseAssistantIfProps>;\n export type Condition = (state: AssistantState) => boolean;\n}\n\nexport const AssistantIf: FC<AssistantIf.Props> = ({ children, condition }) => {\n const result = useAssistantIf({ condition });\n return result ? children : null;\n};\n\nAssistantIf.displayName = \"AssistantIf\";\n"],"mappings":";;;AAGA,SAAS,yBAAyB;AAOlC,IAAM,iBAAiB,CAAC,UAA+B;AACrD,SAAO,kBAAkB,MAAM,SAAS;AAC1C;AAOO,IAAM,cAAqC,CAAC,EAAE,UAAU,UAAU,MAAM;AAC7E,QAAM,SAAS,eAAe,EAAE,UAAU,CAAC;AAC3C,SAAO,SAAS,WAAW;AAC7B;AAEA,YAAY,cAAc;","names":[]}
@@ -7,6 +7,9 @@ export type UseComposerIfProps = RequireAtLeastOne<ComposerIfFilters>;
7
7
  export declare namespace ComposerPrimitiveIf {
8
8
  type Props = PropsWithChildren<UseComposerIfProps>;
9
9
  }
10
+ /**
11
+ * @deprecated Use `<AssistantIf condition={({ composer }) => ...} />` instead.
12
+ */
10
13
  export declare const ComposerPrimitiveIf: FC<ComposerPrimitiveIf.Props>;
11
14
  export {};
12
15
  //# sourceMappingURL=ComposerIf.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ComposerIf.d.ts","sourceRoot":"","sources":["../../../src/primitives/composer/ComposerIf.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAE,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAEnD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAEvE,KAAK,iBAAiB,GAAG;IACvB,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;AAWtE,yBAAiB,mBAAmB,CAAC;IACnC,KAAY,KAAK,GAAG,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;CAC3D;AAED,eAAO,MAAM,mBAAmB,EAAE,EAAE,CAAC,mBAAmB,CAAC,KAAK,CAM7D,CAAC"}
1
+ {"version":3,"file":"ComposerIf.d.ts","sourceRoot":"","sources":["../../../src/primitives/composer/ComposerIf.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAE,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAEnD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAEvE,KAAK,iBAAiB,GAAG;IACvB,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC;CAC9B,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;AAWtE,yBAAiB,mBAAmB,CAAC;IACnC,KAAY,KAAK,GAAG,iBAAiB,CAAC,kBAAkB,CAAC,CAAC;CAC3D;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB,EAAE,EAAE,CAAC,mBAAmB,CAAC,KAAK,CAM7D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/primitives/composer/ComposerIf.tsx"],"sourcesContent":["\"use client\";\n\nimport type { FC, PropsWithChildren } from \"react\";\nimport { useAssistantState } from \"../../context\";\nimport type { RequireAtLeastOne } from \"../../utils/RequireAtLeastOne\";\n\ntype ComposerIfFilters = {\n editing: boolean | undefined;\n};\n\nexport type UseComposerIfProps = RequireAtLeastOne<ComposerIfFilters>;\n\nconst useComposerIf = (props: UseComposerIfProps) => {\n return useAssistantState(({ composer }) => {\n if (props.editing === true && !composer.isEditing) return false;\n if (props.editing === false && composer.isEditing) return false;\n\n return true;\n });\n};\n\nexport namespace ComposerPrimitiveIf {\n export type Props = PropsWithChildren<UseComposerIfProps>;\n}\n\nexport const ComposerPrimitiveIf: FC<ComposerPrimitiveIf.Props> = ({\n children,\n ...query\n}) => {\n const result = useComposerIf(query);\n return result ? children : null;\n};\n\nComposerPrimitiveIf.displayName = \"ComposerPrimitive.If\";\n"],"mappings":";;;AAGA,SAAS,yBAAyB;AASlC,IAAM,gBAAgB,CAAC,UAA8B;AACnD,SAAO,kBAAkB,CAAC,EAAE,SAAS,MAAM;AACzC,QAAI,MAAM,YAAY,QAAQ,CAAC,SAAS,UAAW,QAAO;AAC1D,QAAI,MAAM,YAAY,SAAS,SAAS,UAAW,QAAO;AAE1D,WAAO;AAAA,EACT,CAAC;AACH;AAMO,IAAM,sBAAqD,CAAC;AAAA,EACjE;AAAA,EACA,GAAG;AACL,MAAM;AACJ,QAAM,SAAS,cAAc,KAAK;AAClC,SAAO,SAAS,WAAW;AAC7B;AAEA,oBAAoB,cAAc;","names":[]}
1
+ {"version":3,"sources":["../../../src/primitives/composer/ComposerIf.tsx"],"sourcesContent":["\"use client\";\n\nimport type { FC, PropsWithChildren } from \"react\";\nimport { useAssistantState } from \"../../context\";\nimport type { RequireAtLeastOne } from \"../../utils/RequireAtLeastOne\";\n\ntype ComposerIfFilters = {\n editing: boolean | undefined;\n};\n\nexport type UseComposerIfProps = RequireAtLeastOne<ComposerIfFilters>;\n\nconst useComposerIf = (props: UseComposerIfProps) => {\n return useAssistantState(({ composer }) => {\n if (props.editing === true && !composer.isEditing) return false;\n if (props.editing === false && composer.isEditing) return false;\n\n return true;\n });\n};\n\nexport namespace ComposerPrimitiveIf {\n export type Props = PropsWithChildren<UseComposerIfProps>;\n}\n\n/**\n * @deprecated Use `<AssistantIf condition={({ composer }) => ...} />` instead.\n */\nexport const ComposerPrimitiveIf: FC<ComposerPrimitiveIf.Props> = ({\n children,\n ...query\n}) => {\n const result = useComposerIf(query);\n return result ? children : null;\n};\n\nComposerPrimitiveIf.displayName = \"ComposerPrimitive.If\";\n"],"mappings":";;;AAGA,SAAS,yBAAyB;AASlC,IAAM,gBAAgB,CAAC,UAA8B;AACnD,SAAO,kBAAkB,CAAC,EAAE,SAAS,MAAM;AACzC,QAAI,MAAM,YAAY,QAAQ,CAAC,SAAS,UAAW,QAAO;AAC1D,QAAI,MAAM,YAAY,SAAS,SAAS,UAAW,QAAO;AAE1D,WAAO;AAAA,EACT,CAAC;AACH;AASO,IAAM,sBAAqD,CAAC;AAAA,EACjE;AAAA,EACA,GAAG;AACL,MAAM;AACJ,QAAM,SAAS,cAAc,KAAK;AAClC,SAAO,SAAS,WAAW;AAC7B;AAEA,oBAAoB,cAAc;","names":[]}
@@ -1 +1 @@
1
- {"version":3,"file":"ComposerInput.d.ts","sourceRoot":"","sources":["../../../src/primitives/composer/ComposerInput.tsx"],"names":[],"mappings":"AAaA,OAAyB,EACvB,KAAK,qBAAqB,EAC3B,MAAM,yBAAyB,CAAC;AAKjC,yBAAiB,sBAAsB,CAAC;IACtC,KAAY,OAAO,GAAG,mBAAmB,CAAC;IAC1C,KAAY,KAAK,GAAG,qBAAqB,GAAG;QAC1C;;;WAGG;QACH,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAC9B;;;WAGG;QACH,aAAa,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QACpC;;;WAGG;QACH,cAAc,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QACrC;;;WAGG;QACH,wBAAwB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAC/C;;;WAGG;QACH,8BAA8B,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QACrD;;;WAGG;QACH,8BAA8B,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QACrD;;;WAGG;QACH,oBAAoB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;KAC5C,CAAC;CACH;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,sBAAsB;IAtD/B;;;OAGG;cACO,OAAO,GAAG,SAAS;IAC7B;;;OAGG;oBACa,OAAO,GAAG,SAAS;IACnC;;;OAGG;qBACc,OAAO,GAAG,SAAS;IACpC;;;OAGG;+BACwB,OAAO,GAAG,SAAS;IAC9C;;;OAGG;qCAC8B,OAAO,GAAG,SAAS;IACpD;;;OAGG;qCAC8B,OAAO,GAAG,SAAS;IACpD;;;OAGG;2BACoB,OAAO,GAAG,SAAS;uDA6J7C,CAAC"}
1
+ {"version":3,"file":"ComposerInput.d.ts","sourceRoot":"","sources":["../../../src/primitives/composer/ComposerInput.tsx"],"names":[],"mappings":"AAaA,OAAyB,EACvB,KAAK,qBAAqB,EAC3B,MAAM,yBAAyB,CAAC;AAKjC,yBAAiB,sBAAsB,CAAC;IACtC,KAAY,OAAO,GAAG,mBAAmB,CAAC;IAC1C,KAAY,KAAK,GAAG,qBAAqB,GAAG;QAC1C;;;WAGG;QACH,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAC9B;;;WAGG;QACH,aAAa,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QACpC;;;WAGG;QACH,cAAc,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QACrC;;;WAGG;QACH,wBAAwB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAC/C;;;WAGG;QACH,8BAA8B,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QACrD;;;WAGG;QACH,8BAA8B,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QACrD;;;WAGG;QACH,oBAAoB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;KAC5C,CAAC;CACH;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,sBAAsB;IAtD/B;;;OAGG;cACO,OAAO,GAAG,SAAS;IAC7B;;;OAGG;oBACa,OAAO,GAAG,SAAS;IACnC;;;OAGG;qBACc,OAAO,GAAG,SAAS;IACpC;;;OAGG;+BACwB,OAAO,GAAG,SAAS;IAC9C;;;OAGG;qCAC8B,OAAO,GAAG,SAAS;IACpD;;;OAGG;qCAC8B,OAAO,GAAG,SAAS;IACpD;;;OAGG;2BACoB,OAAO,GAAG,SAAS;uDAgK7C,CAAC"}
@@ -42,6 +42,7 @@ var ComposerPrimitiveInput = forwardRef(
42
42
  const ref = useComposedRefs(forwardedRef, textareaRef);
43
43
  useEscapeKeydown((e) => {
44
44
  if (!cancelOnEscape) return;
45
+ if (!textareaRef.current?.contains(e.target)) return;
45
46
  const composer = api.composer();
46
47
  if (composer.getState().canCancel) {
47
48
  composer.cancel();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/primitives/composer/ComposerInput.tsx"],"sourcesContent":["\"use client\";\n\nimport { composeEventHandlers } from \"@radix-ui/primitive\";\nimport { useComposedRefs } from \"@radix-ui/react-compose-refs\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport {\n ClipboardEvent,\n type KeyboardEvent,\n forwardRef,\n useCallback,\n useEffect,\n useRef,\n} from \"react\";\nimport TextareaAutosize, {\n type TextareaAutosizeProps,\n} from \"react-textarea-autosize\";\nimport { useEscapeKeydown } from \"@radix-ui/react-use-escape-keydown\";\nimport { useOnScrollToBottom } from \"../../utils/hooks/useOnScrollToBottom\";\nimport { useAssistantState, useAssistantApi } from \"../../context\";\n\nexport namespace ComposerPrimitiveInput {\n export type Element = HTMLTextAreaElement;\n export type Props = TextareaAutosizeProps & {\n /**\n * Whether to render as a child component using Slot.\n * When true, the component will merge its props with its child.\n */\n asChild?: boolean | undefined;\n /**\n * Whether to submit the message when Enter is pressed (without Shift).\n * @default true\n */\n submitOnEnter?: boolean | undefined;\n /**\n * Whether to cancel message composition when Escape is pressed.\n * @default true\n */\n cancelOnEscape?: boolean | undefined;\n /**\n * Whether to automatically focus the input when a new run starts.\n * @default true\n */\n unstable_focusOnRunStart?: boolean | undefined;\n /**\n * Whether to automatically focus the input when scrolling to bottom.\n * @default true\n */\n unstable_focusOnScrollToBottom?: boolean | undefined;\n /**\n * Whether to automatically focus the input when switching threads.\n * @default true\n */\n unstable_focusOnThreadSwitched?: boolean | undefined;\n /**\n * Whether to automatically add pasted files as attachments.\n * @default true\n */\n addAttachmentOnPaste?: boolean | undefined;\n };\n}\n\n/**\n * A text input component for composing messages.\n *\n * This component provides a rich text input experience with automatic resizing,\n * keyboard shortcuts, file paste support, and intelligent focus management.\n * It integrates with the composer context to manage message state and submission.\n *\n * @example\n * ```tsx\n * <ComposerPrimitive.Input\n * placeholder=\"Type your message...\"\n * submitOnEnter={true}\n * addAttachmentOnPaste={true}\n * />\n * ```\n */\nexport const ComposerPrimitiveInput = forwardRef<\n ComposerPrimitiveInput.Element,\n ComposerPrimitiveInput.Props\n>(\n (\n {\n autoFocus = false,\n asChild,\n disabled: disabledProp,\n onChange,\n onKeyDown,\n onPaste,\n submitOnEnter = true,\n cancelOnEscape = true,\n unstable_focusOnRunStart = true,\n unstable_focusOnScrollToBottom = true,\n unstable_focusOnThreadSwitched = true,\n addAttachmentOnPaste = true,\n ...rest\n },\n forwardedRef,\n ) => {\n const api = useAssistantApi();\n\n const value = useAssistantState(({ composer }) => {\n if (!composer.isEditing) return \"\";\n return composer.text;\n });\n\n const Component = asChild ? Slot : TextareaAutosize;\n\n const isDisabled =\n useAssistantState(({ thread }) => thread.isDisabled) || disabledProp;\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const ref = useComposedRefs(forwardedRef, textareaRef);\n\n useEscapeKeydown((e) => {\n if (!cancelOnEscape) return;\n\n const composer = api.composer();\n if (composer.getState().canCancel) {\n composer.cancel();\n e.preventDefault();\n }\n });\n\n const handleKeyPress = (e: KeyboardEvent) => {\n if (isDisabled || !submitOnEnter) return;\n\n // ignore IME composition events\n if (e.nativeEvent.isComposing) return;\n\n if (e.key === \"Enter\" && e.shiftKey === false) {\n const isRunning = api.thread().getState().isRunning;\n\n if (!isRunning) {\n e.preventDefault();\n\n textareaRef.current?.closest(\"form\")?.requestSubmit();\n }\n }\n };\n\n const handlePaste = async (e: ClipboardEvent<HTMLTextAreaElement>) => {\n if (!addAttachmentOnPaste) return;\n const threadCapabilities = api.thread().getState().capabilities;\n const files = Array.from(e.clipboardData?.files || []);\n\n if (threadCapabilities.attachments && files.length > 0) {\n try {\n e.preventDefault();\n await Promise.all(\n files.map((file) => api.composer().addAttachment(file)),\n );\n } catch (error) {\n console.error(\"Error adding attachment:\", error);\n }\n }\n };\n\n const autoFocusEnabled = autoFocus && !isDisabled;\n const focus = useCallback(() => {\n const textarea = textareaRef.current;\n if (!textarea || !autoFocusEnabled) return;\n\n textarea.focus({ preventScroll: true });\n textarea.setSelectionRange(textarea.value.length, textarea.value.length);\n }, [autoFocusEnabled]);\n\n useEffect(() => focus(), [focus]);\n\n useOnScrollToBottom(() => {\n if (\n api.composer().getState().type === \"thread\" &&\n unstable_focusOnScrollToBottom\n ) {\n focus();\n }\n });\n\n useEffect(() => {\n if (\n api.composer().getState().type !== \"thread\" ||\n !unstable_focusOnRunStart\n )\n return undefined;\n\n return api.on(\"thread.run-start\", focus);\n }, [unstable_focusOnRunStart, focus, api]);\n\n useEffect(() => {\n if (\n api.composer().getState().type !== \"thread\" ||\n !unstable_focusOnThreadSwitched\n )\n return undefined;\n\n return api.on(\"thread-list-item.switched-to\", focus);\n }, [unstable_focusOnThreadSwitched, focus, api]);\n\n return (\n <Component\n name=\"input\"\n value={value}\n {...rest}\n ref={ref as React.ForwardedRef<HTMLTextAreaElement>}\n disabled={isDisabled}\n onChange={composeEventHandlers(onChange, (e) => {\n if (!api.composer().getState().isEditing) return;\n api.composer().setText(e.target.value);\n api.flushSync();\n })}\n onKeyDown={composeEventHandlers(onKeyDown, handleKeyPress)}\n onPaste={composeEventHandlers(onPaste, handlePaste)}\n />\n );\n },\n);\n\nComposerPrimitiveInput.displayName = \"ComposerPrimitive.Input\";\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/primitives/composer/ComposerInput.tsx"],"sourcesContent":["\"use client\";\n\nimport { composeEventHandlers } from \"@radix-ui/primitive\";\nimport { useComposedRefs } from \"@radix-ui/react-compose-refs\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport {\n ClipboardEvent,\n type KeyboardEvent,\n forwardRef,\n useCallback,\n useEffect,\n useRef,\n} from \"react\";\nimport TextareaAutosize, {\n type TextareaAutosizeProps,\n} from \"react-textarea-autosize\";\nimport { useEscapeKeydown } from \"@radix-ui/react-use-escape-keydown\";\nimport { useOnScrollToBottom } from \"../../utils/hooks/useOnScrollToBottom\";\nimport { useAssistantState, useAssistantApi } from \"../../context\";\n\nexport namespace ComposerPrimitiveInput {\n export type Element = HTMLTextAreaElement;\n export type Props = TextareaAutosizeProps & {\n /**\n * Whether to render as a child component using Slot.\n * When true, the component will merge its props with its child.\n */\n asChild?: boolean | undefined;\n /**\n * Whether to submit the message when Enter is pressed (without Shift).\n * @default true\n */\n submitOnEnter?: boolean | undefined;\n /**\n * Whether to cancel message composition when Escape is pressed.\n * @default true\n */\n cancelOnEscape?: boolean | undefined;\n /**\n * Whether to automatically focus the input when a new run starts.\n * @default true\n */\n unstable_focusOnRunStart?: boolean | undefined;\n /**\n * Whether to automatically focus the input when scrolling to bottom.\n * @default true\n */\n unstable_focusOnScrollToBottom?: boolean | undefined;\n /**\n * Whether to automatically focus the input when switching threads.\n * @default true\n */\n unstable_focusOnThreadSwitched?: boolean | undefined;\n /**\n * Whether to automatically add pasted files as attachments.\n * @default true\n */\n addAttachmentOnPaste?: boolean | undefined;\n };\n}\n\n/**\n * A text input component for composing messages.\n *\n * This component provides a rich text input experience with automatic resizing,\n * keyboard shortcuts, file paste support, and intelligent focus management.\n * It integrates with the composer context to manage message state and submission.\n *\n * @example\n * ```tsx\n * <ComposerPrimitive.Input\n * placeholder=\"Type your message...\"\n * submitOnEnter={true}\n * addAttachmentOnPaste={true}\n * />\n * ```\n */\nexport const ComposerPrimitiveInput = forwardRef<\n ComposerPrimitiveInput.Element,\n ComposerPrimitiveInput.Props\n>(\n (\n {\n autoFocus = false,\n asChild,\n disabled: disabledProp,\n onChange,\n onKeyDown,\n onPaste,\n submitOnEnter = true,\n cancelOnEscape = true,\n unstable_focusOnRunStart = true,\n unstable_focusOnScrollToBottom = true,\n unstable_focusOnThreadSwitched = true,\n addAttachmentOnPaste = true,\n ...rest\n },\n forwardedRef,\n ) => {\n const api = useAssistantApi();\n\n const value = useAssistantState(({ composer }) => {\n if (!composer.isEditing) return \"\";\n return composer.text;\n });\n\n const Component = asChild ? Slot : TextareaAutosize;\n\n const isDisabled =\n useAssistantState(({ thread }) => thread.isDisabled) || disabledProp;\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const ref = useComposedRefs(forwardedRef, textareaRef);\n\n useEscapeKeydown((e) => {\n if (!cancelOnEscape) return;\n\n // Only handle ESC if it originated from within this input\n if (!textareaRef.current?.contains(e.target as Node)) return;\n\n const composer = api.composer();\n if (composer.getState().canCancel) {\n composer.cancel();\n e.preventDefault();\n }\n });\n\n const handleKeyPress = (e: KeyboardEvent) => {\n if (isDisabled || !submitOnEnter) return;\n\n // ignore IME composition events\n if (e.nativeEvent.isComposing) return;\n\n if (e.key === \"Enter\" && e.shiftKey === false) {\n const isRunning = api.thread().getState().isRunning;\n\n if (!isRunning) {\n e.preventDefault();\n\n textareaRef.current?.closest(\"form\")?.requestSubmit();\n }\n }\n };\n\n const handlePaste = async (e: ClipboardEvent<HTMLTextAreaElement>) => {\n if (!addAttachmentOnPaste) return;\n const threadCapabilities = api.thread().getState().capabilities;\n const files = Array.from(e.clipboardData?.files || []);\n\n if (threadCapabilities.attachments && files.length > 0) {\n try {\n e.preventDefault();\n await Promise.all(\n files.map((file) => api.composer().addAttachment(file)),\n );\n } catch (error) {\n console.error(\"Error adding attachment:\", error);\n }\n }\n };\n\n const autoFocusEnabled = autoFocus && !isDisabled;\n const focus = useCallback(() => {\n const textarea = textareaRef.current;\n if (!textarea || !autoFocusEnabled) return;\n\n textarea.focus({ preventScroll: true });\n textarea.setSelectionRange(textarea.value.length, textarea.value.length);\n }, [autoFocusEnabled]);\n\n useEffect(() => focus(), [focus]);\n\n useOnScrollToBottom(() => {\n if (\n api.composer().getState().type === \"thread\" &&\n unstable_focusOnScrollToBottom\n ) {\n focus();\n }\n });\n\n useEffect(() => {\n if (\n api.composer().getState().type !== \"thread\" ||\n !unstable_focusOnRunStart\n )\n return undefined;\n\n return api.on(\"thread.run-start\", focus);\n }, [unstable_focusOnRunStart, focus, api]);\n\n useEffect(() => {\n if (\n api.composer().getState().type !== \"thread\" ||\n !unstable_focusOnThreadSwitched\n )\n return undefined;\n\n return api.on(\"thread-list-item.switched-to\", focus);\n }, [unstable_focusOnThreadSwitched, focus, api]);\n\n return (\n <Component\n name=\"input\"\n value={value}\n {...rest}\n ref={ref as React.ForwardedRef<HTMLTextAreaElement>}\n disabled={isDisabled}\n onChange={composeEventHandlers(onChange, (e) => {\n if (!api.composer().getState().isEditing) return;\n api.composer().setText(e.target.value);\n api.flushSync();\n })}\n onKeyDown={composeEventHandlers(onKeyDown, handleKeyPress)}\n onPaste={composeEventHandlers(onPaste, handlePaste)}\n />\n );\n },\n);\n\nComposerPrimitiveInput.displayName = \"ComposerPrimitive.Input\";\n"],"mappings":"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","names":[]}
@@ -9,6 +9,7 @@ export * as MessagePrimitive from "./message";
9
9
  export * as ThreadPrimitive from "./thread";
10
10
  export * as ThreadListPrimitive from "./threadList";
11
11
  export * as ThreadListItemPrimitive from "./threadListItem";
12
+ export { AssistantIf } from "./assistant/AssistantIf";
12
13
  export { useMessagePartText } from "./messagePart/useMessagePartText";
13
14
  export { useMessagePartReasoning } from "./messagePart/useMessagePartReasoning";
14
15
  export { useMessagePartSource } from "./messagePart/useMessagePartSource";
@@ -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,cAAc,MAAM,SAAS,CAAC;AAC1C,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,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,2BAA2B,EAAE,MAAM,sCAAsC,CAAC;AACnF,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,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,cAAc,MAAM,SAAS,CAAC;AAC1C,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,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,kBAAkB,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,EAAE,2BAA2B,EAAE,MAAM,sCAAsC,CAAC;AACnF,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
@@ -10,6 +10,7 @@ import * as MessagePrimitive from "./message/index.js";
10
10
  import * as ThreadPrimitive from "./thread/index.js";
11
11
  import * as ThreadListPrimitive from "./threadList/index.js";
12
12
  import * as ThreadListItemPrimitive from "./threadListItem/index.js";
13
+ import { AssistantIf } from "./assistant/AssistantIf.js";
13
14
  import { useMessagePartText } from "./messagePart/useMessagePartText.js";
14
15
  import { useMessagePartReasoning } from "./messagePart/useMessagePartReasoning.js";
15
16
  import { useMessagePartSource } from "./messagePart/useMessagePartSource.js";
@@ -20,6 +21,7 @@ import { useThreadViewportAutoScroll } from "./thread/useThreadViewportAutoScrol
20
21
  import { useScrollLock } from "./reasoning/index.js";
21
22
  export {
22
23
  ActionBarPrimitive,
24
+ AssistantIf,
23
25
  AssistantModalPrimitive,
24
26
  AttachmentPrimitive,
25
27
  BranchPickerPrimitive,
@@ -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 MessagePartPrimitive from \"./messagePart\";\nexport * as ErrorPrimitive from \"./error\";\nexport * as MessagePrimitive from \"./message\";\nexport * as ThreadPrimitive from \"./thread\";\nexport * as ThreadListPrimitive from \"./threadList\";\nexport * as ThreadListItemPrimitive from \"./threadListItem\";\n\nexport { useMessagePartText } from \"./messagePart/useMessagePartText\";\nexport { useMessagePartReasoning } from \"./messagePart/useMessagePartReasoning\";\nexport { useMessagePartSource } from \"./messagePart/useMessagePartSource\";\nexport { useMessagePartFile } from \"./messagePart/useMessagePartFile\";\nexport { useMessagePartImage } from \"./messagePart/useMessagePartImage\";\nexport { useMessagePartData } from \"./messagePart/useMessagePartData\";\nexport { useThreadViewportAutoScroll } from \"./thread/useThreadViewportAutoScroll\";\nexport { useScrollLock } from \"./reasoning\";\n"],"mappings":";AAAA,YAAY,wBAAwB;AACpC,YAAY,6BAA6B;AACzC,YAAY,yBAAyB;AACrC,YAAY,2BAA2B;AACvC,YAAY,uBAAuB;AACnC,YAAY,0BAA0B;AACtC,YAAY,oBAAoB;AAChC,YAAY,sBAAsB;AAClC,YAAY,qBAAqB;AACjC,YAAY,yBAAyB;AACrC,YAAY,6BAA6B;AAEzC,SAAS,0BAA0B;AACnC,SAAS,+BAA+B;AACxC,SAAS,4BAA4B;AACrC,SAAS,0BAA0B;AACnC,SAAS,2BAA2B;AACpC,SAAS,0BAA0B;AACnC,SAAS,mCAAmC;AAC5C,SAAS,qBAAqB;","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 MessagePartPrimitive from \"./messagePart\";\nexport * as ErrorPrimitive from \"./error\";\nexport * as MessagePrimitive from \"./message\";\nexport * as ThreadPrimitive from \"./thread\";\nexport * as ThreadListPrimitive from \"./threadList\";\nexport * as ThreadListItemPrimitive from \"./threadListItem\";\n\nexport { AssistantIf } from \"./assistant/AssistantIf\";\n\nexport { useMessagePartText } from \"./messagePart/useMessagePartText\";\nexport { useMessagePartReasoning } from \"./messagePart/useMessagePartReasoning\";\nexport { useMessagePartSource } from \"./messagePart/useMessagePartSource\";\nexport { useMessagePartFile } from \"./messagePart/useMessagePartFile\";\nexport { useMessagePartImage } from \"./messagePart/useMessagePartImage\";\nexport { useMessagePartData } from \"./messagePart/useMessagePartData\";\nexport { useThreadViewportAutoScroll } from \"./thread/useThreadViewportAutoScroll\";\nexport { useScrollLock } from \"./reasoning\";\n"],"mappings":";AAAA,YAAY,wBAAwB;AACpC,YAAY,6BAA6B;AACzC,YAAY,yBAAyB;AACrC,YAAY,2BAA2B;AACvC,YAAY,uBAAuB;AACnC,YAAY,0BAA0B;AACtC,YAAY,oBAAoB;AAChC,YAAY,sBAAsB;AAClC,YAAY,qBAAqB;AACjC,YAAY,yBAAyB;AACrC,YAAY,6BAA6B;AAEzC,SAAS,mBAAmB;AAE5B,SAAS,0BAA0B;AACnC,SAAS,+BAA+B;AACxC,SAAS,4BAA4B;AACrC,SAAS,0BAA0B;AACnC,SAAS,2BAA2B;AACpC,SAAS,0BAA0B;AACnC,SAAS,mCAAmC;AAC5C,SAAS,qBAAqB;","names":[]}
@@ -17,6 +17,9 @@ type UseMessageIfProps = RequireAtLeastOne<MessageIfFilters>;
17
17
  export declare namespace MessagePrimitiveIf {
18
18
  type Props = PropsWithChildren<UseMessageIfProps>;
19
19
  }
20
+ /**
21
+ * @deprecated Use `<AssistantIf condition={({ message }) => ...} />` instead.
22
+ */
20
23
  export declare const MessagePrimitiveIf: FC<MessagePrimitiveIf.Props>;
21
24
  export {};
22
25
  //# sourceMappingURL=MessageIf.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MessageIf.d.ts","sourceRoot":"","sources":["../../../src/primitives/message/MessageIf.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAE,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAEnD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAEvE,KAAK,gBAAgB,GAAG;IACtB,IAAI,EAAE,OAAO,GAAG,SAAS,CAAC;IAC1B,SAAS,EAAE,OAAO,GAAG,SAAS,CAAC;IAC/B,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,WAAW,EAAE,OAAO,GAAG,SAAS,CAAC;IACjC,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,WAAW,EAAE,OAAO,GAAG,SAAS,CAAC;IACjC,IAAI,EAAE,OAAO,GAAG,SAAS,CAAC;IAC1B,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,cAAc,EAAE,OAAO,GAAG,SAAS,CAAC;IACpC,UAAU,EAAE,OAAO,GAAG,SAAS,CAAC;IAChC,iBAAiB,EAAE,UAAU,GAAG,UAAU,GAAG,IAAI,GAAG,SAAS,CAAC;CAC/D,CAAC;AACF,KAAK,iBAAiB,GAAG,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;AAwD7D,yBAAiB,kBAAkB,CAAC;IAClC,KAAY,KAAK,GAAG,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;CAC1D;AAED,eAAO,MAAM,kBAAkB,EAAE,EAAE,CAAC,kBAAkB,CAAC,KAAK,CAM3D,CAAC"}
1
+ {"version":3,"file":"MessageIf.d.ts","sourceRoot":"","sources":["../../../src/primitives/message/MessageIf.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAE,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAEnD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAEvE,KAAK,gBAAgB,GAAG;IACtB,IAAI,EAAE,OAAO,GAAG,SAAS,CAAC;IAC1B,SAAS,EAAE,OAAO,GAAG,SAAS,CAAC;IAC/B,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,WAAW,EAAE,OAAO,GAAG,SAAS,CAAC;IACjC,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,WAAW,EAAE,OAAO,GAAG,SAAS,CAAC;IACjC,IAAI,EAAE,OAAO,GAAG,SAAS,CAAC;IAC1B,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,cAAc,EAAE,OAAO,GAAG,SAAS,CAAC;IACpC,UAAU,EAAE,OAAO,GAAG,SAAS,CAAC;IAChC,iBAAiB,EAAE,UAAU,GAAG,UAAU,GAAG,IAAI,GAAG,SAAS,CAAC;CAC/D,CAAC;AACF,KAAK,iBAAiB,GAAG,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;AAwD7D,yBAAiB,kBAAkB,CAAC;IAClC,KAAY,KAAK,GAAG,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;CAC1D;AAED;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,EAAE,CAAC,kBAAkB,CAAC,KAAK,CAM3D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/primitives/message/MessageIf.tsx"],"sourcesContent":["\"use client\";\n\nimport type { FC, PropsWithChildren } from \"react\";\nimport { useAssistantState } from \"../../context\";\nimport type { RequireAtLeastOne } from \"../../utils/RequireAtLeastOne\";\n\ntype MessageIfFilters = {\n user: boolean | undefined;\n assistant: boolean | undefined;\n system: boolean | undefined;\n hasBranches: boolean | undefined;\n copied: boolean | undefined;\n lastOrHover: boolean | undefined;\n last: boolean | undefined;\n speaking: boolean | undefined;\n hasAttachments: boolean | undefined;\n hasContent: boolean | undefined;\n submittedFeedback: \"positive\" | \"negative\" | null | undefined;\n};\ntype UseMessageIfProps = RequireAtLeastOne<MessageIfFilters>;\n\nconst useMessageIf = (props: UseMessageIfProps) => {\n return useAssistantState(({ message }) => {\n const {\n role,\n attachments,\n parts,\n branchCount,\n isLast,\n speech,\n isCopied,\n isHovering,\n } = message;\n\n if (props.hasBranches === true && branchCount < 2) return false;\n\n if (props.user && role !== \"user\") return false;\n if (props.assistant && role !== \"assistant\") return false;\n if (props.system && role !== \"system\") return false;\n\n if (props.lastOrHover === true && !isHovering && !isLast) return false;\n if (props.last !== undefined && props.last !== isLast) return false;\n\n if (props.copied === true && !isCopied) return false;\n if (props.copied === false && isCopied) return false;\n\n if (props.speaking === true && speech == null) return false;\n if (props.speaking === false && speech != null) return false;\n\n if (\n props.hasAttachments === true &&\n (role !== \"user\" || !attachments?.length)\n )\n return false;\n if (\n props.hasAttachments === false &&\n role === \"user\" &&\n !!attachments?.length\n )\n return false;\n\n if (props.hasContent === true && parts.length === 0) return false;\n if (props.hasContent === false && parts.length > 0) return false;\n\n if (\n props.submittedFeedback !== undefined &&\n (message.metadata.submittedFeedback?.type ?? null) !==\n props.submittedFeedback\n )\n return false;\n\n return true;\n });\n};\n\nexport namespace MessagePrimitiveIf {\n export type Props = PropsWithChildren<UseMessageIfProps>;\n}\n\nexport const MessagePrimitiveIf: FC<MessagePrimitiveIf.Props> = ({\n children,\n ...query\n}) => {\n const result = useMessageIf(query);\n return result ? children : null;\n};\n\nMessagePrimitiveIf.displayName = \"MessagePrimitive.If\";\n"],"mappings":";;;AAGA,SAAS,yBAAyB;AAkBlC,IAAM,eAAe,CAAC,UAA6B;AACjD,SAAO,kBAAkB,CAAC,EAAE,QAAQ,MAAM;AACxC,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,IAAI;AAEJ,QAAI,MAAM,gBAAgB,QAAQ,cAAc,EAAG,QAAO;AAE1D,QAAI,MAAM,QAAQ,SAAS,OAAQ,QAAO;AAC1C,QAAI,MAAM,aAAa,SAAS,YAAa,QAAO;AACpD,QAAI,MAAM,UAAU,SAAS,SAAU,QAAO;AAE9C,QAAI,MAAM,gBAAgB,QAAQ,CAAC,cAAc,CAAC,OAAQ,QAAO;AACjE,QAAI,MAAM,SAAS,UAAa,MAAM,SAAS,OAAQ,QAAO;AAE9D,QAAI,MAAM,WAAW,QAAQ,CAAC,SAAU,QAAO;AAC/C,QAAI,MAAM,WAAW,SAAS,SAAU,QAAO;AAE/C,QAAI,MAAM,aAAa,QAAQ,UAAU,KAAM,QAAO;AACtD,QAAI,MAAM,aAAa,SAAS,UAAU,KAAM,QAAO;AAEvD,QACE,MAAM,mBAAmB,SACxB,SAAS,UAAU,CAAC,aAAa;AAElC,aAAO;AACT,QACE,MAAM,mBAAmB,SACzB,SAAS,UACT,CAAC,CAAC,aAAa;AAEf,aAAO;AAET,QAAI,MAAM,eAAe,QAAQ,MAAM,WAAW,EAAG,QAAO;AAC5D,QAAI,MAAM,eAAe,SAAS,MAAM,SAAS,EAAG,QAAO;AAE3D,QACE,MAAM,sBAAsB,WAC3B,QAAQ,SAAS,mBAAmB,QAAQ,UAC3C,MAAM;AAER,aAAO;AAET,WAAO;AAAA,EACT,CAAC;AACH;AAMO,IAAM,qBAAmD,CAAC;AAAA,EAC/D;AAAA,EACA,GAAG;AACL,MAAM;AACJ,QAAM,SAAS,aAAa,KAAK;AACjC,SAAO,SAAS,WAAW;AAC7B;AAEA,mBAAmB,cAAc;","names":[]}
1
+ {"version":3,"sources":["../../../src/primitives/message/MessageIf.tsx"],"sourcesContent":["\"use client\";\n\nimport type { FC, PropsWithChildren } from \"react\";\nimport { useAssistantState } from \"../../context\";\nimport type { RequireAtLeastOne } from \"../../utils/RequireAtLeastOne\";\n\ntype MessageIfFilters = {\n user: boolean | undefined;\n assistant: boolean | undefined;\n system: boolean | undefined;\n hasBranches: boolean | undefined;\n copied: boolean | undefined;\n lastOrHover: boolean | undefined;\n last: boolean | undefined;\n speaking: boolean | undefined;\n hasAttachments: boolean | undefined;\n hasContent: boolean | undefined;\n submittedFeedback: \"positive\" | \"negative\" | null | undefined;\n};\ntype UseMessageIfProps = RequireAtLeastOne<MessageIfFilters>;\n\nconst useMessageIf = (props: UseMessageIfProps) => {\n return useAssistantState(({ message }) => {\n const {\n role,\n attachments,\n parts,\n branchCount,\n isLast,\n speech,\n isCopied,\n isHovering,\n } = message;\n\n if (props.hasBranches === true && branchCount < 2) return false;\n\n if (props.user && role !== \"user\") return false;\n if (props.assistant && role !== \"assistant\") return false;\n if (props.system && role !== \"system\") return false;\n\n if (props.lastOrHover === true && !isHovering && !isLast) return false;\n if (props.last !== undefined && props.last !== isLast) return false;\n\n if (props.copied === true && !isCopied) return false;\n if (props.copied === false && isCopied) return false;\n\n if (props.speaking === true && speech == null) return false;\n if (props.speaking === false && speech != null) return false;\n\n if (\n props.hasAttachments === true &&\n (role !== \"user\" || !attachments?.length)\n )\n return false;\n if (\n props.hasAttachments === false &&\n role === \"user\" &&\n !!attachments?.length\n )\n return false;\n\n if (props.hasContent === true && parts.length === 0) return false;\n if (props.hasContent === false && parts.length > 0) return false;\n\n if (\n props.submittedFeedback !== undefined &&\n (message.metadata.submittedFeedback?.type ?? null) !==\n props.submittedFeedback\n )\n return false;\n\n return true;\n });\n};\n\nexport namespace MessagePrimitiveIf {\n export type Props = PropsWithChildren<UseMessageIfProps>;\n}\n\n/**\n * @deprecated Use `<AssistantIf condition={({ message }) => ...} />` instead.\n */\nexport const MessagePrimitiveIf: FC<MessagePrimitiveIf.Props> = ({\n children,\n ...query\n}) => {\n const result = useMessageIf(query);\n return result ? children : null;\n};\n\nMessagePrimitiveIf.displayName = \"MessagePrimitive.If\";\n"],"mappings":";;;AAGA,SAAS,yBAAyB;AAkBlC,IAAM,eAAe,CAAC,UAA6B;AACjD,SAAO,kBAAkB,CAAC,EAAE,QAAQ,MAAM;AACxC,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,IAAI;AAEJ,QAAI,MAAM,gBAAgB,QAAQ,cAAc,EAAG,QAAO;AAE1D,QAAI,MAAM,QAAQ,SAAS,OAAQ,QAAO;AAC1C,QAAI,MAAM,aAAa,SAAS,YAAa,QAAO;AACpD,QAAI,MAAM,UAAU,SAAS,SAAU,QAAO;AAE9C,QAAI,MAAM,gBAAgB,QAAQ,CAAC,cAAc,CAAC,OAAQ,QAAO;AACjE,QAAI,MAAM,SAAS,UAAa,MAAM,SAAS,OAAQ,QAAO;AAE9D,QAAI,MAAM,WAAW,QAAQ,CAAC,SAAU,QAAO;AAC/C,QAAI,MAAM,WAAW,SAAS,SAAU,QAAO;AAE/C,QAAI,MAAM,aAAa,QAAQ,UAAU,KAAM,QAAO;AACtD,QAAI,MAAM,aAAa,SAAS,UAAU,KAAM,QAAO;AAEvD,QACE,MAAM,mBAAmB,SACxB,SAAS,UAAU,CAAC,aAAa;AAElC,aAAO;AACT,QACE,MAAM,mBAAmB,SACzB,SAAS,UACT,CAAC,CAAC,aAAa;AAEf,aAAO;AAET,QAAI,MAAM,eAAe,QAAQ,MAAM,WAAW,EAAG,QAAO;AAC5D,QAAI,MAAM,eAAe,SAAS,MAAM,SAAS,EAAG,QAAO;AAE3D,QACE,MAAM,sBAAsB,WAC3B,QAAQ,SAAS,mBAAmB,QAAQ,UAC3C,MAAM;AAER,aAAO;AAET,WAAO;AAAA,EACT,CAAC;AACH;AASO,IAAM,qBAAmD,CAAC;AAAA,EAC/D;AAAA,EACA,GAAG;AACL,MAAM;AACJ,QAAM,SAAS,aAAa,KAAK;AACjC,SAAO,SAAS,WAAW;AAC7B;AAEA,mBAAmB,cAAc;","names":[]}
@@ -207,7 +207,7 @@ var MessagePrimitiveParts = ({
207
207
  range.index
208
208
  );
209
209
  } else if (range.type === "toolGroup") {
210
- const ToolGroupComponent = components.ToolGroup ?? defaultComponents.ToolGroup;
210
+ const ToolGroupComponent = components?.ToolGroup ?? defaultComponents.ToolGroup;
211
211
  return /* @__PURE__ */ jsx(
212
212
  ToolGroupComponent,
213
213
  {
@@ -228,7 +228,7 @@ var MessagePrimitiveParts = ({
228
228
  `tool-${range.startIndex}`
229
229
  );
230
230
  } else {
231
- const ReasoningGroupComponent = components.ReasoningGroup ?? defaultComponents.ReasoningGroup;
231
+ const ReasoningGroupComponent = components?.ReasoningGroup ?? defaultComponents.ReasoningGroup;
232
232
  return /* @__PURE__ */ jsx(
233
233
  ReasoningGroupComponent,
234
234
  {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/primitives/message/MessageParts.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type ComponentType,\n type FC,\n memo,\n PropsWithChildren,\n useMemo,\n} from \"react\";\nimport {\n useAssistantState,\n useAssistantApi,\n PartByIndexProvider,\n TextMessagePartProvider,\n} from \"../../context\";\nimport { MessagePartPrimitiveText } from \"../messagePart/MessagePartText\";\nimport { MessagePartPrimitiveImage } from \"../messagePart/MessagePartImage\";\nimport type {\n Unstable_AudioMessagePartComponent,\n EmptyMessagePartComponent,\n TextMessagePartComponent,\n ImageMessagePartComponent,\n SourceMessagePartComponent,\n ToolCallMessagePartComponent,\n ToolCallMessagePartProps,\n FileMessagePartComponent,\n ReasoningMessagePartComponent,\n ReasoningGroupComponent,\n} from \"../../types/MessagePartComponentTypes\";\nimport { MessagePartPrimitiveInProgress } from \"../messagePart/MessagePartInProgress\";\nimport { MessagePartStatus } from \"../../types/AssistantTypes\";\nimport { useShallow } from \"zustand/shallow\";\n\ntype MessagePartRange =\n | { type: \"single\"; index: number }\n | { type: \"toolGroup\"; startIndex: number; endIndex: number }\n | { type: \"reasoningGroup\"; startIndex: number; endIndex: number };\n\n/**\n * Creates a group state manager for a specific part type.\n * Returns functions to start, end, and finalize groups.\n */\nconst createGroupState = <T extends \"toolGroup\" | \"reasoningGroup\">(\n groupType: T,\n) => {\n let start = -1;\n\n return {\n startGroup: (index: number) => {\n if (start === -1) {\n start = index;\n }\n },\n endGroup: (endIndex: number, ranges: MessagePartRange[]) => {\n if (start !== -1) {\n ranges.push({\n type: groupType,\n startIndex: start,\n endIndex,\n } as MessagePartRange);\n start = -1;\n }\n },\n finalize: (endIndex: number, ranges: MessagePartRange[]) => {\n if (start !== -1) {\n ranges.push({\n type: groupType,\n startIndex: start,\n endIndex,\n } as MessagePartRange);\n }\n },\n };\n};\n\n/**\n * Groups consecutive tool-call and reasoning message parts into ranges.\n * Always groups tool calls and reasoning parts, even if there's only one.\n */\nconst groupMessageParts = (\n messageTypes: readonly string[],\n): MessagePartRange[] => {\n const ranges: MessagePartRange[] = [];\n const toolGroup = createGroupState(\"toolGroup\");\n const reasoningGroup = createGroupState(\"reasoningGroup\");\n\n for (let i = 0; i < messageTypes.length; i++) {\n const type = messageTypes[i];\n\n if (type === \"tool-call\") {\n reasoningGroup.endGroup(i - 1, ranges);\n toolGroup.startGroup(i);\n } else if (type === \"reasoning\") {\n toolGroup.endGroup(i - 1, ranges);\n reasoningGroup.startGroup(i);\n } else {\n toolGroup.endGroup(i - 1, ranges);\n reasoningGroup.endGroup(i - 1, ranges);\n ranges.push({ type: \"single\", index: i });\n }\n }\n\n toolGroup.finalize(messageTypes.length - 1, ranges);\n reasoningGroup.finalize(messageTypes.length - 1, ranges);\n\n return ranges;\n};\n\nconst useMessagePartsGroups = (): MessagePartRange[] => {\n const messageTypes = useAssistantState(\n useShallow((s) => s.message.parts.map((c: any) => c.type)),\n );\n\n return useMemo(() => {\n if (messageTypes.length === 0) {\n return [];\n }\n return groupMessageParts(messageTypes);\n }, [messageTypes]);\n};\n\nexport namespace MessagePrimitiveParts {\n export type Props = {\n /**\n * Component configuration for rendering different types of message content.\n *\n * You can provide custom components for each content type (text, image, file, etc.)\n * and configure tool rendering behavior. If not provided, default components will be used.\n */\n components?:\n | {\n /** Component for rendering empty messages */\n Empty?: EmptyMessagePartComponent | undefined;\n /** Component for rendering text content */\n Text?: TextMessagePartComponent | undefined;\n /** Component for rendering reasoning content (typically hidden) */\n Reasoning?: ReasoningMessagePartComponent | undefined;\n /** Component for rendering source content */\n Source?: SourceMessagePartComponent | undefined;\n /** Component for rendering image content */\n Image?: ImageMessagePartComponent | undefined;\n /** Component for rendering file content */\n File?: FileMessagePartComponent | undefined;\n /** Component for rendering audio content (experimental) */\n Unstable_Audio?: Unstable_AudioMessagePartComponent | undefined;\n /** Configuration for tool call rendering */\n tools?:\n | {\n /** Map of tool names to their specific components */\n by_name?:\n | Record<string, ToolCallMessagePartComponent | undefined>\n | undefined;\n /** Fallback component for unregistered tools */\n Fallback?: ComponentType<ToolCallMessagePartProps> | undefined;\n }\n | {\n /** Override component that handles all tool calls */\n Override: ComponentType<ToolCallMessagePartProps>;\n }\n | undefined;\n\n /**\n * Component for rendering grouped consecutive tool calls.\n *\n * When provided, this component will automatically wrap consecutive tool-call\n * message parts, allowing you to create collapsible sections, custom styling,\n * or other grouped presentations for multiple tool calls.\n *\n * The component receives:\n * - `startIndex`: The index of the first tool call in the group\n * - `endIndex`: The index of the last tool call in the group\n * - `children`: The rendered tool call components\n *\n * @example\n * ```tsx\n * // Collapsible tool group\n * ToolGroup: ({ startIndex, endIndex, children }) => (\n * <details className=\"tool-group\">\n * <summary>\n * {endIndex - startIndex + 1} tool calls\n * </summary>\n * <div className=\"tool-group-content\">\n * {children}\n * </div>\n * </details>\n * )\n * ```\n *\n * @example\n * ```tsx\n * // Custom styled tool group with header\n * ToolGroup: ({ startIndex, endIndex, children }) => (\n * <div className=\"border rounded-lg p-4 my-2\">\n * <div className=\"text-sm text-gray-600 mb-2\">\n * Tool execution #{startIndex + 1}-{endIndex + 1}\n * </div>\n * <div className=\"space-y-2\">\n * {children}\n * </div>\n * </div>\n * )\n * ```\n *\n * @param startIndex - Index of the first tool call in the group\n * @param endIndex - Index of the last tool call in the group\n * @param children - Rendered tool call components to display within the group\n *\n * @deprecated This feature is still experimental and subject to change.\n */\n ToolGroup?: ComponentType<\n PropsWithChildren<{ startIndex: number; endIndex: number }>\n >;\n\n /**\n * Component for rendering grouped reasoning parts.\n *\n * When provided, this component will automatically wrap reasoning message parts\n * (one or more consecutive) in a group container. Each reasoning part inside\n * renders its own text independently - no text merging occurs.\n *\n * The component receives:\n * - `startIndex`: The index of the first reasoning part in the group\n * - `endIndex`: The index of the last reasoning part in the group\n * - `children`: The rendered Reasoning components (one per part)\n *\n * @example\n * ```tsx\n * // Collapsible reasoning group\n * ReasoningGroup: ({ children }) => (\n * <details className=\"reasoning-group\">\n * <summary>Reasoning</summary>\n * <div className=\"reasoning-content\">\n * {children}\n * </div>\n * </details>\n * )\n * ```\n *\n * @param startIndex - Index of the first reasoning part in the group\n * @param endIndex - Index of the last reasoning part in the group\n * @param children - Rendered reasoning part components\n */\n ReasoningGroup?: ReasoningGroupComponent;\n }\n | undefined;\n };\n}\n\nconst ToolUIDisplay = ({\n Fallback,\n ...props\n}: {\n Fallback: ToolCallMessagePartComponent | undefined;\n} & ToolCallMessagePartProps) => {\n const Render = useAssistantState(({ tools }) => {\n const Render = tools.tools[props.toolName] ?? Fallback;\n if (Array.isArray(Render)) return Render[0] ?? Fallback;\n return Render;\n });\n if (!Render) return null;\n return <Render {...props} />;\n};\n\nconst defaultComponents = {\n Text: () => (\n <p style={{ whiteSpace: \"pre-line\" }}>\n <MessagePartPrimitiveText />\n <MessagePartPrimitiveInProgress>\n <span style={{ fontFamily: \"revert\" }}>{\" \\u25CF\"}</span>\n </MessagePartPrimitiveInProgress>\n </p>\n ),\n Reasoning: () => null,\n Source: () => null,\n Image: () => <MessagePartPrimitiveImage />,\n File: () => null,\n Unstable_Audio: () => null,\n ToolGroup: ({ children }) => children,\n ReasoningGroup: ({ children }) => children,\n} satisfies MessagePrimitiveParts.Props[\"components\"];\n\ntype MessagePartComponentProps = {\n components: MessagePrimitiveParts.Props[\"components\"];\n};\n\nconst MessagePartComponent: FC<MessagePartComponentProps> = ({\n components: {\n Text = defaultComponents.Text,\n Reasoning = defaultComponents.Reasoning,\n Image = defaultComponents.Image,\n Source = defaultComponents.Source,\n File = defaultComponents.File,\n Unstable_Audio: Audio = defaultComponents.Unstable_Audio,\n tools = {},\n } = {},\n}) => {\n const api = useAssistantApi();\n const part = useAssistantState(({ part }) => part);\n\n const type = part.type;\n if (type === \"tool-call\") {\n const addResult = api.part().addToolResult;\n const resume = api.part().resumeToolCall;\n if (\"Override\" in tools)\n return <tools.Override {...part} addResult={addResult} resume={resume} />;\n const Tool = tools.by_name?.[part.toolName] ?? tools.Fallback;\n return (\n <ToolUIDisplay\n {...part}\n Fallback={Tool}\n addResult={addResult}\n resume={resume}\n />\n );\n }\n\n if (part.status?.type === \"requires-action\")\n throw new Error(\"Encountered unexpected requires-action status\");\n\n switch (type) {\n case \"text\":\n return <Text {...part} />;\n\n case \"reasoning\":\n return <Reasoning {...part} />;\n\n case \"source\":\n return <Source {...part} />;\n\n case \"image\":\n return <Image {...part} />;\n\n case \"file\":\n return <File {...part} />;\n\n case \"audio\":\n return <Audio {...part} />;\n\n case \"data\":\n return null;\n\n default:\n const unhandledType: never = type;\n throw new Error(`Unknown message part type: ${unhandledType}`);\n }\n};\n\nexport namespace MessagePrimitivePartByIndex {\n export type Props = {\n index: number;\n components: MessagePrimitiveParts.Props[\"components\"];\n };\n}\n\n/**\n * Renders a single message part at the specified index.\n *\n * This component provides direct access to render a specific message part\n * within the current message context, using the provided component configuration.\n *\n * @example\n * ```tsx\n * <MessagePrimitive.PartByIndex\n * index={0}\n * components={{\n * Text: MyTextComponent,\n * Image: MyImageComponent\n * }}\n * />\n * ```\n */\nexport const MessagePrimitivePartByIndex: FC<MessagePrimitivePartByIndex.Props> =\n memo(\n ({ index, components }) => {\n return (\n <PartByIndexProvider index={index}>\n <MessagePartComponent components={components} />\n </PartByIndexProvider>\n );\n },\n (prev, next) =>\n prev.index === next.index &&\n prev.components?.Text === next.components?.Text &&\n prev.components?.Reasoning === next.components?.Reasoning &&\n prev.components?.Source === next.components?.Source &&\n prev.components?.Image === next.components?.Image &&\n prev.components?.File === next.components?.File &&\n prev.components?.Unstable_Audio === next.components?.Unstable_Audio &&\n prev.components?.tools === next.components?.tools &&\n prev.components?.ToolGroup === next.components?.ToolGroup &&\n prev.components?.ReasoningGroup === next.components?.ReasoningGroup,\n );\n\nMessagePrimitivePartByIndex.displayName = \"MessagePrimitive.PartByIndex\";\n\nconst EmptyPartFallback: FC<{\n status: MessagePartStatus;\n component: TextMessagePartComponent;\n}> = ({ status, component: Component }) => {\n return (\n <TextMessagePartProvider text=\"\" isRunning={status.type === \"running\"}>\n <Component type=\"text\" text=\"\" status={status} />\n </TextMessagePartProvider>\n );\n};\n\nconst COMPLETE_STATUS: MessagePartStatus = Object.freeze({\n type: \"complete\",\n});\n\nconst EmptyPartsImpl: FC<MessagePartComponentProps> = ({ components }) => {\n const status = useAssistantState(\n (s) => (s.message.status ?? COMPLETE_STATUS) as MessagePartStatus,\n );\n\n if (components?.Empty) return <components.Empty status={status} />;\n\n return (\n <EmptyPartFallback\n status={status}\n component={components?.Text ?? defaultComponents.Text}\n />\n );\n};\n\nconst EmptyParts = memo(\n EmptyPartsImpl,\n (prev, next) =>\n prev.components?.Empty === next.components?.Empty &&\n prev.components?.Text === next.components?.Text,\n);\n\n/**\n * Renders the parts of a message with support for multiple content types.\n *\n * This component automatically handles different types of message content including\n * text, images, files, tool calls, and more. It provides a flexible component\n * system for customizing how each content type is rendered.\n *\n * @example\n * ```tsx\n * <MessagePrimitive.Parts\n * components={{\n * Text: ({ text }) => <p className=\"message-text\">{text}</p>,\n * Image: ({ image }) => <img src={image} alt=\"Message image\" />,\n * tools: {\n * by_name: {\n * calculator: CalculatorTool,\n * weather: WeatherTool,\n * },\n * Fallback: DefaultToolComponent\n * }\n * }}\n * />\n * ```\n */\nexport const MessagePrimitiveParts: FC<MessagePrimitiveParts.Props> = ({\n components,\n}) => {\n const contentLength = useAssistantState(\n ({ message }) => message.parts.length,\n );\n const messageRanges = useMessagePartsGroups();\n\n const partsElements = useMemo(() => {\n if (contentLength === 0) {\n return <EmptyParts components={components} />;\n }\n\n return messageRanges.map((range) => {\n if (range.type === \"single\") {\n return (\n <MessagePrimitivePartByIndex\n key={range.index}\n index={range.index}\n components={components}\n />\n );\n } else if (range.type === \"toolGroup\") {\n const ToolGroupComponent =\n components!.ToolGroup ?? defaultComponents.ToolGroup;\n return (\n <ToolGroupComponent\n key={`tool-${range.startIndex}`}\n startIndex={range.startIndex}\n endIndex={range.endIndex}\n >\n {Array.from(\n { length: range.endIndex - range.startIndex + 1 },\n (_, i) => (\n <MessagePrimitivePartByIndex\n key={i}\n index={range.startIndex + i}\n components={components}\n />\n ),\n )}\n </ToolGroupComponent>\n );\n } else {\n // reasoningGroup\n const ReasoningGroupComponent =\n components!.ReasoningGroup ?? defaultComponents.ReasoningGroup;\n return (\n <ReasoningGroupComponent\n key={`reasoning-${range.startIndex}`}\n startIndex={range.startIndex}\n endIndex={range.endIndex}\n >\n {Array.from(\n { length: range.endIndex - range.startIndex + 1 },\n (_, i) => (\n <MessagePrimitivePartByIndex\n key={i}\n index={range.startIndex + i}\n components={components}\n />\n ),\n )}\n </ReasoningGroupComponent>\n );\n }\n });\n }, [messageRanges, components, contentLength]);\n\n return <>{partsElements}</>;\n};\n\nMessagePrimitiveParts.displayName = \"MessagePrimitive.Parts\";\n"],"mappings":";;;AAEA;AAAA,EAGE;AAAA,EAEA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,gCAAgC;AACzC,SAAS,iCAAiC;AAa1C,SAAS,sCAAsC;AAE/C,SAAS,kBAAkB;AAqOlB,SAyQA,UAzQA,KAKL,YALK;AA1NT,IAAM,mBAAmB,CACvB,cACG;AACH,MAAI,QAAQ;AAEZ,SAAO;AAAA,IACL,YAAY,CAAC,UAAkB;AAC7B,UAAI,UAAU,IAAI;AAChB,gBAAQ;AAAA,MACV;AAAA,IACF;AAAA,IACA,UAAU,CAAC,UAAkB,WAA+B;AAC1D,UAAI,UAAU,IAAI;AAChB,eAAO,KAAK;AAAA,UACV,MAAM;AAAA,UACN,YAAY;AAAA,UACZ;AAAA,QACF,CAAqB;AACrB,gBAAQ;AAAA,MACV;AAAA,IACF;AAAA,IACA,UAAU,CAAC,UAAkB,WAA+B;AAC1D,UAAI,UAAU,IAAI;AAChB,eAAO,KAAK;AAAA,UACV,MAAM;AAAA,UACN,YAAY;AAAA,UACZ;AAAA,QACF,CAAqB;AAAA,MACvB;AAAA,IACF;AAAA,EACF;AACF;AAMA,IAAM,oBAAoB,CACxB,iBACuB;AACvB,QAAM,SAA6B,CAAC;AACpC,QAAM,YAAY,iBAAiB,WAAW;AAC9C,QAAM,iBAAiB,iBAAiB,gBAAgB;AAExD,WAAS,IAAI,GAAG,IAAI,aAAa,QAAQ,KAAK;AAC5C,UAAM,OAAO,aAAa,CAAC;AAE3B,QAAI,SAAS,aAAa;AACxB,qBAAe,SAAS,IAAI,GAAG,MAAM;AACrC,gBAAU,WAAW,CAAC;AAAA,IACxB,WAAW,SAAS,aAAa;AAC/B,gBAAU,SAAS,IAAI,GAAG,MAAM;AAChC,qBAAe,WAAW,CAAC;AAAA,IAC7B,OAAO;AACL,gBAAU,SAAS,IAAI,GAAG,MAAM;AAChC,qBAAe,SAAS,IAAI,GAAG,MAAM;AACrC,aAAO,KAAK,EAAE,MAAM,UAAU,OAAO,EAAE,CAAC;AAAA,IAC1C;AAAA,EACF;AAEA,YAAU,SAAS,aAAa,SAAS,GAAG,MAAM;AAClD,iBAAe,SAAS,aAAa,SAAS,GAAG,MAAM;AAEvD,SAAO;AACT;AAEA,IAAM,wBAAwB,MAA0B;AACtD,QAAM,eAAe;AAAA,IACnB,WAAW,CAAC,MAAM,EAAE,QAAQ,MAAM,IAAI,CAAC,MAAW,EAAE,IAAI,CAAC;AAAA,EAC3D;AAEA,SAAO,QAAQ,MAAM;AACnB,QAAI,aAAa,WAAW,GAAG;AAC7B,aAAO,CAAC;AAAA,IACV;AACA,WAAO,kBAAkB,YAAY;AAAA,EACvC,GAAG,CAAC,YAAY,CAAC;AACnB;AAiIA,IAAM,gBAAgB,CAAC;AAAA,EACrB;AAAA,EACA,GAAG;AACL,MAEiC;AAC/B,QAAM,SAAS,kBAAkB,CAAC,EAAE,MAAM,MAAM;AAC9C,UAAMA,UAAS,MAAM,MAAM,MAAM,QAAQ,KAAK;AAC9C,QAAI,MAAM,QAAQA,OAAM,EAAG,QAAOA,QAAO,CAAC,KAAK;AAC/C,WAAOA;AAAA,EACT,CAAC;AACD,MAAI,CAAC,OAAQ,QAAO;AACpB,SAAO,oBAAC,UAAQ,GAAG,OAAO;AAC5B;AAEA,IAAM,oBAAoB;AAAA,EACxB,MAAM,MACJ,qBAAC,OAAE,OAAO,EAAE,YAAY,WAAW,GACjC;AAAA,wBAAC,4BAAyB;AAAA,IAC1B,oBAAC,kCACC,8BAAC,UAAK,OAAO,EAAE,YAAY,SAAS,GAAI,qBAAU,GACpD;AAAA,KACF;AAAA,EAEF,WAAW,MAAM;AAAA,EACjB,QAAQ,MAAM;AAAA,EACd,OAAO,MAAM,oBAAC,6BAA0B;AAAA,EACxC,MAAM,MAAM;AAAA,EACZ,gBAAgB,MAAM;AAAA,EACtB,WAAW,CAAC,EAAE,SAAS,MAAM;AAAA,EAC7B,gBAAgB,CAAC,EAAE,SAAS,MAAM;AACpC;AAMA,IAAM,uBAAsD,CAAC;AAAA,EAC3D,YAAY;AAAA,IACV,OAAO,kBAAkB;AAAA,IACzB,YAAY,kBAAkB;AAAA,IAC9B,QAAQ,kBAAkB;AAAA,IAC1B,SAAS,kBAAkB;AAAA,IAC3B,OAAO,kBAAkB;AAAA,IACzB,gBAAgB,QAAQ,kBAAkB;AAAA,IAC1C,QAAQ,CAAC;AAAA,EACX,IAAI,CAAC;AACP,MAAM;AACJ,QAAM,MAAM,gBAAgB;AAC5B,QAAM,OAAO,kBAAkB,CAAC,EAAE,MAAAC,MAAK,MAAMA,KAAI;AAEjD,QAAM,OAAO,KAAK;AAClB,MAAI,SAAS,aAAa;AACxB,UAAM,YAAY,IAAI,KAAK,EAAE;AAC7B,UAAM,SAAS,IAAI,KAAK,EAAE;AAC1B,QAAI,cAAc;AAChB,aAAO,oBAAC,MAAM,UAAN,EAAgB,GAAG,MAAM,WAAsB,QAAgB;AACzE,UAAM,OAAO,MAAM,UAAU,KAAK,QAAQ,KAAK,MAAM;AACrD,WACE;AAAA,MAAC;AAAA;AAAA,QACE,GAAG;AAAA,QACJ,UAAU;AAAA,QACV;AAAA,QACA;AAAA;AAAA,IACF;AAAA,EAEJ;AAEA,MAAI,KAAK,QAAQ,SAAS;AACxB,UAAM,IAAI,MAAM,+CAA+C;AAEjE,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO,oBAAC,QAAM,GAAG,MAAM;AAAA,IAEzB,KAAK;AACH,aAAO,oBAAC,aAAW,GAAG,MAAM;AAAA,IAE9B,KAAK;AACH,aAAO,oBAAC,UAAQ,GAAG,MAAM;AAAA,IAE3B,KAAK;AACH,aAAO,oBAAC,SAAO,GAAG,MAAM;AAAA,IAE1B,KAAK;AACH,aAAO,oBAAC,QAAM,GAAG,MAAM;AAAA,IAEzB,KAAK;AACH,aAAO,oBAAC,SAAO,GAAG,MAAM;AAAA,IAE1B,KAAK;AACH,aAAO;AAAA,IAET;AACE,YAAM,gBAAuB;AAC7B,YAAM,IAAI,MAAM,8BAA8B,aAAa,EAAE;AAAA,EACjE;AACF;AA0BO,IAAM,8BACX;AAAA,EACE,CAAC,EAAE,OAAO,WAAW,MAAM;AACzB,WACE,oBAAC,uBAAoB,OACnB,8BAAC,wBAAqB,YAAwB,GAChD;AAAA,EAEJ;AAAA,EACA,CAAC,MAAM,SACL,KAAK,UAAU,KAAK,SACpB,KAAK,YAAY,SAAS,KAAK,YAAY,QAC3C,KAAK,YAAY,cAAc,KAAK,YAAY,aAChD,KAAK,YAAY,WAAW,KAAK,YAAY,UAC7C,KAAK,YAAY,UAAU,KAAK,YAAY,SAC5C,KAAK,YAAY,SAAS,KAAK,YAAY,QAC3C,KAAK,YAAY,mBAAmB,KAAK,YAAY,kBACrD,KAAK,YAAY,UAAU,KAAK,YAAY,SAC5C,KAAK,YAAY,cAAc,KAAK,YAAY,aAChD,KAAK,YAAY,mBAAmB,KAAK,YAAY;AACzD;AAEF,4BAA4B,cAAc;AAE1C,IAAM,oBAGD,CAAC,EAAE,QAAQ,WAAW,UAAU,MAAM;AACzC,SACE,oBAAC,2BAAwB,MAAK,IAAG,WAAW,OAAO,SAAS,WAC1D,8BAAC,aAAU,MAAK,QAAO,MAAK,IAAG,QAAgB,GACjD;AAEJ;AAEA,IAAM,kBAAqC,OAAO,OAAO;AAAA,EACvD,MAAM;AACR,CAAC;AAED,IAAM,iBAAgD,CAAC,EAAE,WAAW,MAAM;AACxE,QAAM,SAAS;AAAA,IACb,CAAC,MAAO,EAAE,QAAQ,UAAU;AAAA,EAC9B;AAEA,MAAI,YAAY,MAAO,QAAO,oBAAC,WAAW,OAAX,EAAiB,QAAgB;AAEhE,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,WAAW,YAAY,QAAQ,kBAAkB;AAAA;AAAA,EACnD;AAEJ;AAEA,IAAM,aAAa;AAAA,EACjB;AAAA,EACA,CAAC,MAAM,SACL,KAAK,YAAY,UAAU,KAAK,YAAY,SAC5C,KAAK,YAAY,SAAS,KAAK,YAAY;AAC/C;AA0BO,IAAM,wBAAyD,CAAC;AAAA,EACrE;AACF,MAAM;AACJ,QAAM,gBAAgB;AAAA,IACpB,CAAC,EAAE,QAAQ,MAAM,QAAQ,MAAM;AAAA,EACjC;AACA,QAAM,gBAAgB,sBAAsB;AAE5C,QAAM,gBAAgB,QAAQ,MAAM;AAClC,QAAI,kBAAkB,GAAG;AACvB,aAAO,oBAAC,cAAW,YAAwB;AAAA,IAC7C;AAEA,WAAO,cAAc,IAAI,CAAC,UAAU;AAClC,UAAI,MAAM,SAAS,UAAU;AAC3B,eACE;AAAA,UAAC;AAAA;AAAA,YAEC,OAAO,MAAM;AAAA,YACb;AAAA;AAAA,UAFK,MAAM;AAAA,QAGb;AAAA,MAEJ,WAAW,MAAM,SAAS,aAAa;AACrC,cAAM,qBACJ,WAAY,aAAa,kBAAkB;AAC7C,eACE;AAAA,UAAC;AAAA;AAAA,YAEC,YAAY,MAAM;AAAA,YAClB,UAAU,MAAM;AAAA,YAEf,gBAAM;AAAA,cACL,EAAE,QAAQ,MAAM,WAAW,MAAM,aAAa,EAAE;AAAA,cAChD,CAAC,GAAG,MACF;AAAA,gBAAC;AAAA;AAAA,kBAEC,OAAO,MAAM,aAAa;AAAA,kBAC1B;AAAA;AAAA,gBAFK;AAAA,cAGP;AAAA,YAEJ;AAAA;AAAA,UAbK,QAAQ,MAAM,UAAU;AAAA,QAc/B;AAAA,MAEJ,OAAO;AAEL,cAAM,0BACJ,WAAY,kBAAkB,kBAAkB;AAClD,eACE;AAAA,UAAC;AAAA;AAAA,YAEC,YAAY,MAAM;AAAA,YAClB,UAAU,MAAM;AAAA,YAEf,gBAAM;AAAA,cACL,EAAE,QAAQ,MAAM,WAAW,MAAM,aAAa,EAAE;AAAA,cAChD,CAAC,GAAG,MACF;AAAA,gBAAC;AAAA;AAAA,kBAEC,OAAO,MAAM,aAAa;AAAA,kBAC1B;AAAA;AAAA,gBAFK;AAAA,cAGP;AAAA,YAEJ;AAAA;AAAA,UAbK,aAAa,MAAM,UAAU;AAAA,QAcpC;AAAA,MAEJ;AAAA,IACF,CAAC;AAAA,EACH,GAAG,CAAC,eAAe,YAAY,aAAa,CAAC;AAE7C,SAAO,gCAAG,yBAAc;AAC1B;AAEA,sBAAsB,cAAc;","names":["Render","part"]}
1
+ {"version":3,"sources":["../../../src/primitives/message/MessageParts.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type ComponentType,\n type FC,\n memo,\n PropsWithChildren,\n useMemo,\n} from \"react\";\nimport {\n useAssistantState,\n useAssistantApi,\n PartByIndexProvider,\n TextMessagePartProvider,\n} from \"../../context\";\nimport { MessagePartPrimitiveText } from \"../messagePart/MessagePartText\";\nimport { MessagePartPrimitiveImage } from \"../messagePart/MessagePartImage\";\nimport type {\n Unstable_AudioMessagePartComponent,\n EmptyMessagePartComponent,\n TextMessagePartComponent,\n ImageMessagePartComponent,\n SourceMessagePartComponent,\n ToolCallMessagePartComponent,\n ToolCallMessagePartProps,\n FileMessagePartComponent,\n ReasoningMessagePartComponent,\n ReasoningGroupComponent,\n} from \"../../types/MessagePartComponentTypes\";\nimport { MessagePartPrimitiveInProgress } from \"../messagePart/MessagePartInProgress\";\nimport { MessagePartStatus } from \"../../types/AssistantTypes\";\nimport { useShallow } from \"zustand/shallow\";\n\ntype MessagePartRange =\n | { type: \"single\"; index: number }\n | { type: \"toolGroup\"; startIndex: number; endIndex: number }\n | { type: \"reasoningGroup\"; startIndex: number; endIndex: number };\n\n/**\n * Creates a group state manager for a specific part type.\n * Returns functions to start, end, and finalize groups.\n */\nconst createGroupState = <T extends \"toolGroup\" | \"reasoningGroup\">(\n groupType: T,\n) => {\n let start = -1;\n\n return {\n startGroup: (index: number) => {\n if (start === -1) {\n start = index;\n }\n },\n endGroup: (endIndex: number, ranges: MessagePartRange[]) => {\n if (start !== -1) {\n ranges.push({\n type: groupType,\n startIndex: start,\n endIndex,\n } as MessagePartRange);\n start = -1;\n }\n },\n finalize: (endIndex: number, ranges: MessagePartRange[]) => {\n if (start !== -1) {\n ranges.push({\n type: groupType,\n startIndex: start,\n endIndex,\n } as MessagePartRange);\n }\n },\n };\n};\n\n/**\n * Groups consecutive tool-call and reasoning message parts into ranges.\n * Always groups tool calls and reasoning parts, even if there's only one.\n */\nconst groupMessageParts = (\n messageTypes: readonly string[],\n): MessagePartRange[] => {\n const ranges: MessagePartRange[] = [];\n const toolGroup = createGroupState(\"toolGroup\");\n const reasoningGroup = createGroupState(\"reasoningGroup\");\n\n for (let i = 0; i < messageTypes.length; i++) {\n const type = messageTypes[i];\n\n if (type === \"tool-call\") {\n reasoningGroup.endGroup(i - 1, ranges);\n toolGroup.startGroup(i);\n } else if (type === \"reasoning\") {\n toolGroup.endGroup(i - 1, ranges);\n reasoningGroup.startGroup(i);\n } else {\n toolGroup.endGroup(i - 1, ranges);\n reasoningGroup.endGroup(i - 1, ranges);\n ranges.push({ type: \"single\", index: i });\n }\n }\n\n toolGroup.finalize(messageTypes.length - 1, ranges);\n reasoningGroup.finalize(messageTypes.length - 1, ranges);\n\n return ranges;\n};\n\nconst useMessagePartsGroups = (): MessagePartRange[] => {\n const messageTypes = useAssistantState(\n useShallow((s) => s.message.parts.map((c: any) => c.type)),\n );\n\n return useMemo(() => {\n if (messageTypes.length === 0) {\n return [];\n }\n return groupMessageParts(messageTypes);\n }, [messageTypes]);\n};\n\nexport namespace MessagePrimitiveParts {\n export type Props = {\n /**\n * Component configuration for rendering different types of message content.\n *\n * You can provide custom components for each content type (text, image, file, etc.)\n * and configure tool rendering behavior. If not provided, default components will be used.\n */\n components?:\n | {\n /** Component for rendering empty messages */\n Empty?: EmptyMessagePartComponent | undefined;\n /** Component for rendering text content */\n Text?: TextMessagePartComponent | undefined;\n /** Component for rendering reasoning content (typically hidden) */\n Reasoning?: ReasoningMessagePartComponent | undefined;\n /** Component for rendering source content */\n Source?: SourceMessagePartComponent | undefined;\n /** Component for rendering image content */\n Image?: ImageMessagePartComponent | undefined;\n /** Component for rendering file content */\n File?: FileMessagePartComponent | undefined;\n /** Component for rendering audio content (experimental) */\n Unstable_Audio?: Unstable_AudioMessagePartComponent | undefined;\n /** Configuration for tool call rendering */\n tools?:\n | {\n /** Map of tool names to their specific components */\n by_name?:\n | Record<string, ToolCallMessagePartComponent | undefined>\n | undefined;\n /** Fallback component for unregistered tools */\n Fallback?: ComponentType<ToolCallMessagePartProps> | undefined;\n }\n | {\n /** Override component that handles all tool calls */\n Override: ComponentType<ToolCallMessagePartProps>;\n }\n | undefined;\n\n /**\n * Component for rendering grouped consecutive tool calls.\n *\n * When provided, this component will automatically wrap consecutive tool-call\n * message parts, allowing you to create collapsible sections, custom styling,\n * or other grouped presentations for multiple tool calls.\n *\n * The component receives:\n * - `startIndex`: The index of the first tool call in the group\n * - `endIndex`: The index of the last tool call in the group\n * - `children`: The rendered tool call components\n *\n * @example\n * ```tsx\n * // Collapsible tool group\n * ToolGroup: ({ startIndex, endIndex, children }) => (\n * <details className=\"tool-group\">\n * <summary>\n * {endIndex - startIndex + 1} tool calls\n * </summary>\n * <div className=\"tool-group-content\">\n * {children}\n * </div>\n * </details>\n * )\n * ```\n *\n * @example\n * ```tsx\n * // Custom styled tool group with header\n * ToolGroup: ({ startIndex, endIndex, children }) => (\n * <div className=\"border rounded-lg p-4 my-2\">\n * <div className=\"text-sm text-gray-600 mb-2\">\n * Tool execution #{startIndex + 1}-{endIndex + 1}\n * </div>\n * <div className=\"space-y-2\">\n * {children}\n * </div>\n * </div>\n * )\n * ```\n *\n * @param startIndex - Index of the first tool call in the group\n * @param endIndex - Index of the last tool call in the group\n * @param children - Rendered tool call components to display within the group\n *\n * @deprecated This feature is still experimental and subject to change.\n */\n ToolGroup?: ComponentType<\n PropsWithChildren<{ startIndex: number; endIndex: number }>\n >;\n\n /**\n * Component for rendering grouped reasoning parts.\n *\n * When provided, this component will automatically wrap reasoning message parts\n * (one or more consecutive) in a group container. Each reasoning part inside\n * renders its own text independently - no text merging occurs.\n *\n * The component receives:\n * - `startIndex`: The index of the first reasoning part in the group\n * - `endIndex`: The index of the last reasoning part in the group\n * - `children`: The rendered Reasoning components (one per part)\n *\n * @example\n * ```tsx\n * // Collapsible reasoning group\n * ReasoningGroup: ({ children }) => (\n * <details className=\"reasoning-group\">\n * <summary>Reasoning</summary>\n * <div className=\"reasoning-content\">\n * {children}\n * </div>\n * </details>\n * )\n * ```\n *\n * @param startIndex - Index of the first reasoning part in the group\n * @param endIndex - Index of the last reasoning part in the group\n * @param children - Rendered reasoning part components\n */\n ReasoningGroup?: ReasoningGroupComponent;\n }\n | undefined;\n };\n}\n\nconst ToolUIDisplay = ({\n Fallback,\n ...props\n}: {\n Fallback: ToolCallMessagePartComponent | undefined;\n} & ToolCallMessagePartProps) => {\n const Render = useAssistantState(({ tools }) => {\n const Render = tools.tools[props.toolName] ?? Fallback;\n if (Array.isArray(Render)) return Render[0] ?? Fallback;\n return Render;\n });\n if (!Render) return null;\n return <Render {...props} />;\n};\n\nconst defaultComponents = {\n Text: () => (\n <p style={{ whiteSpace: \"pre-line\" }}>\n <MessagePartPrimitiveText />\n <MessagePartPrimitiveInProgress>\n <span style={{ fontFamily: \"revert\" }}>{\" \\u25CF\"}</span>\n </MessagePartPrimitiveInProgress>\n </p>\n ),\n Reasoning: () => null,\n Source: () => null,\n Image: () => <MessagePartPrimitiveImage />,\n File: () => null,\n Unstable_Audio: () => null,\n ToolGroup: ({ children }) => children,\n ReasoningGroup: ({ children }) => children,\n} satisfies MessagePrimitiveParts.Props[\"components\"];\n\ntype MessagePartComponentProps = {\n components: MessagePrimitiveParts.Props[\"components\"];\n};\n\nconst MessagePartComponent: FC<MessagePartComponentProps> = ({\n components: {\n Text = defaultComponents.Text,\n Reasoning = defaultComponents.Reasoning,\n Image = defaultComponents.Image,\n Source = defaultComponents.Source,\n File = defaultComponents.File,\n Unstable_Audio: Audio = defaultComponents.Unstable_Audio,\n tools = {},\n } = {},\n}) => {\n const api = useAssistantApi();\n const part = useAssistantState(({ part }) => part);\n\n const type = part.type;\n if (type === \"tool-call\") {\n const addResult = api.part().addToolResult;\n const resume = api.part().resumeToolCall;\n if (\"Override\" in tools)\n return <tools.Override {...part} addResult={addResult} resume={resume} />;\n const Tool = tools.by_name?.[part.toolName] ?? tools.Fallback;\n return (\n <ToolUIDisplay\n {...part}\n Fallback={Tool}\n addResult={addResult}\n resume={resume}\n />\n );\n }\n\n if (part.status?.type === \"requires-action\")\n throw new Error(\"Encountered unexpected requires-action status\");\n\n switch (type) {\n case \"text\":\n return <Text {...part} />;\n\n case \"reasoning\":\n return <Reasoning {...part} />;\n\n case \"source\":\n return <Source {...part} />;\n\n case \"image\":\n return <Image {...part} />;\n\n case \"file\":\n return <File {...part} />;\n\n case \"audio\":\n return <Audio {...part} />;\n\n case \"data\":\n return null;\n\n default:\n const unhandledType: never = type;\n throw new Error(`Unknown message part type: ${unhandledType}`);\n }\n};\n\nexport namespace MessagePrimitivePartByIndex {\n export type Props = {\n index: number;\n components: MessagePrimitiveParts.Props[\"components\"];\n };\n}\n\n/**\n * Renders a single message part at the specified index.\n *\n * This component provides direct access to render a specific message part\n * within the current message context, using the provided component configuration.\n *\n * @example\n * ```tsx\n * <MessagePrimitive.PartByIndex\n * index={0}\n * components={{\n * Text: MyTextComponent,\n * Image: MyImageComponent\n * }}\n * />\n * ```\n */\nexport const MessagePrimitivePartByIndex: FC<MessagePrimitivePartByIndex.Props> =\n memo(\n ({ index, components }) => {\n return (\n <PartByIndexProvider index={index}>\n <MessagePartComponent components={components} />\n </PartByIndexProvider>\n );\n },\n (prev, next) =>\n prev.index === next.index &&\n prev.components?.Text === next.components?.Text &&\n prev.components?.Reasoning === next.components?.Reasoning &&\n prev.components?.Source === next.components?.Source &&\n prev.components?.Image === next.components?.Image &&\n prev.components?.File === next.components?.File &&\n prev.components?.Unstable_Audio === next.components?.Unstable_Audio &&\n prev.components?.tools === next.components?.tools &&\n prev.components?.ToolGroup === next.components?.ToolGroup &&\n prev.components?.ReasoningGroup === next.components?.ReasoningGroup,\n );\n\nMessagePrimitivePartByIndex.displayName = \"MessagePrimitive.PartByIndex\";\n\nconst EmptyPartFallback: FC<{\n status: MessagePartStatus;\n component: TextMessagePartComponent;\n}> = ({ status, component: Component }) => {\n return (\n <TextMessagePartProvider text=\"\" isRunning={status.type === \"running\"}>\n <Component type=\"text\" text=\"\" status={status} />\n </TextMessagePartProvider>\n );\n};\n\nconst COMPLETE_STATUS: MessagePartStatus = Object.freeze({\n type: \"complete\",\n});\n\nconst EmptyPartsImpl: FC<MessagePartComponentProps> = ({ components }) => {\n const status = useAssistantState(\n (s) => (s.message.status ?? COMPLETE_STATUS) as MessagePartStatus,\n );\n\n if (components?.Empty) return <components.Empty status={status} />;\n\n return (\n <EmptyPartFallback\n status={status}\n component={components?.Text ?? defaultComponents.Text}\n />\n );\n};\n\nconst EmptyParts = memo(\n EmptyPartsImpl,\n (prev, next) =>\n prev.components?.Empty === next.components?.Empty &&\n prev.components?.Text === next.components?.Text,\n);\n\n/**\n * Renders the parts of a message with support for multiple content types.\n *\n * This component automatically handles different types of message content including\n * text, images, files, tool calls, and more. It provides a flexible component\n * system for customizing how each content type is rendered.\n *\n * @example\n * ```tsx\n * <MessagePrimitive.Parts\n * components={{\n * Text: ({ text }) => <p className=\"message-text\">{text}</p>,\n * Image: ({ image }) => <img src={image} alt=\"Message image\" />,\n * tools: {\n * by_name: {\n * calculator: CalculatorTool,\n * weather: WeatherTool,\n * },\n * Fallback: DefaultToolComponent\n * }\n * }}\n * />\n * ```\n */\nexport const MessagePrimitiveParts: FC<MessagePrimitiveParts.Props> = ({\n components,\n}) => {\n const contentLength = useAssistantState(\n ({ message }) => message.parts.length,\n );\n const messageRanges = useMessagePartsGroups();\n\n const partsElements = useMemo(() => {\n if (contentLength === 0) {\n return <EmptyParts components={components} />;\n }\n\n return messageRanges.map((range) => {\n if (range.type === \"single\") {\n return (\n <MessagePrimitivePartByIndex\n key={range.index}\n index={range.index}\n components={components}\n />\n );\n } else if (range.type === \"toolGroup\") {\n const ToolGroupComponent =\n components?.ToolGroup ?? defaultComponents.ToolGroup;\n return (\n <ToolGroupComponent\n key={`tool-${range.startIndex}`}\n startIndex={range.startIndex}\n endIndex={range.endIndex}\n >\n {Array.from(\n { length: range.endIndex - range.startIndex + 1 },\n (_, i) => (\n <MessagePrimitivePartByIndex\n key={i}\n index={range.startIndex + i}\n components={components}\n />\n ),\n )}\n </ToolGroupComponent>\n );\n } else {\n // reasoningGroup\n const ReasoningGroupComponent =\n components?.ReasoningGroup ?? defaultComponents.ReasoningGroup;\n return (\n <ReasoningGroupComponent\n key={`reasoning-${range.startIndex}`}\n startIndex={range.startIndex}\n endIndex={range.endIndex}\n >\n {Array.from(\n { length: range.endIndex - range.startIndex + 1 },\n (_, i) => (\n <MessagePrimitivePartByIndex\n key={i}\n index={range.startIndex + i}\n components={components}\n />\n ),\n )}\n </ReasoningGroupComponent>\n );\n }\n });\n }, [messageRanges, components, contentLength]);\n\n return <>{partsElements}</>;\n};\n\nMessagePrimitiveParts.displayName = \"MessagePrimitive.Parts\";\n"],"mappings":"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","names":["Render","part"]}
@@ -9,6 +9,9 @@ type UseThreadIfProps = RequireAtLeastOne<ThreadIfFilters>;
9
9
  export declare namespace ThreadPrimitiveIf {
10
10
  type Props = PropsWithChildren<UseThreadIfProps>;
11
11
  }
12
+ /**
13
+ * @deprecated Use `<AssistantIf condition={({ thread }) => ...} />` instead.
14
+ */
12
15
  export declare const ThreadPrimitiveIf: FC<ThreadPrimitiveIf.Props>;
13
16
  export {};
14
17
  //# sourceMappingURL=ThreadIf.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ThreadIf.d.ts","sourceRoot":"","sources":["../../../src/primitives/thread/ThreadIf.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAE,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAEnD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAEvE,KAAK,eAAe,GAAG;IACrB,KAAK,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3B,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;CAC/B,CAAC;AAEF,KAAK,gBAAgB,GAAG,iBAAiB,CAAC,eAAe,CAAC,CAAC;AAiB3D,yBAAiB,iBAAiB,CAAC;IACjC,KAAY,KAAK,GAAG,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;CACzD;AAED,eAAO,MAAM,iBAAiB,EAAE,EAAE,CAAC,iBAAiB,CAAC,KAAK,CAMzD,CAAC"}
1
+ {"version":3,"file":"ThreadIf.d.ts","sourceRoot":"","sources":["../../../src/primitives/thread/ThreadIf.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAE,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAEnD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAEvE,KAAK,eAAe,GAAG;IACrB,KAAK,EAAE,OAAO,GAAG,SAAS,CAAC;IAC3B,OAAO,EAAE,OAAO,GAAG,SAAS,CAAC;IAC7B,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;CAC/B,CAAC;AAEF,KAAK,gBAAgB,GAAG,iBAAiB,CAAC,eAAe,CAAC,CAAC;AAgB3D,yBAAiB,iBAAiB,CAAC;IACjC,KAAY,KAAK,GAAG,iBAAiB,CAAC,gBAAgB,CAAC,CAAC;CACzD;AAED;;GAEG;AACH,eAAO,MAAM,iBAAiB,EAAE,EAAE,CAAC,iBAAiB,CAAC,KAAK,CAMzD,CAAC"}
@@ -4,9 +4,8 @@
4
4
  import { useAssistantState } from "../../context/index.js";
5
5
  var useThreadIf = (props) => {
6
6
  return useAssistantState(({ thread }) => {
7
- const isEmpty = thread.messages.length === 0 && !thread.isLoading;
8
- if (props.empty === true && !isEmpty) return false;
9
- if (props.empty === false && isEmpty) return false;
7
+ if (props.empty === true && !thread.isEmpty) return false;
8
+ if (props.empty === false && thread.isEmpty) return false;
10
9
  if (props.running === true && !thread.isRunning) return false;
11
10
  if (props.running === false && thread.isRunning) return false;
12
11
  if (props.disabled === true && !thread.isDisabled) return false;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/primitives/thread/ThreadIf.tsx"],"sourcesContent":["\"use client\";\n\nimport type { FC, PropsWithChildren } from \"react\";\nimport { useAssistantState } from \"../../context\";\nimport type { RequireAtLeastOne } from \"../../utils/RequireAtLeastOne\";\n\ntype ThreadIfFilters = {\n empty: boolean | undefined;\n running: boolean | undefined;\n disabled: boolean | undefined;\n};\n\ntype UseThreadIfProps = RequireAtLeastOne<ThreadIfFilters>;\n\nconst useThreadIf = (props: UseThreadIfProps) => {\n return useAssistantState(({ thread }) => {\n const isEmpty = thread.messages.length === 0 && !thread.isLoading;\n if (props.empty === true && !isEmpty) return false;\n if (props.empty === false && isEmpty) return false;\n\n if (props.running === true && !thread.isRunning) return false;\n if (props.running === false && thread.isRunning) return false;\n if (props.disabled === true && !thread.isDisabled) return false;\n if (props.disabled === false && thread.isDisabled) return false;\n\n return true;\n });\n};\n\nexport namespace ThreadPrimitiveIf {\n export type Props = PropsWithChildren<UseThreadIfProps>;\n}\n\nexport const ThreadPrimitiveIf: FC<ThreadPrimitiveIf.Props> = ({\n children,\n ...query\n}) => {\n const result = useThreadIf(query);\n return result ? children : null;\n};\n\nThreadPrimitiveIf.displayName = \"ThreadPrimitive.If\";\n"],"mappings":";;;AAGA,SAAS,yBAAyB;AAWlC,IAAM,cAAc,CAAC,UAA4B;AAC/C,SAAO,kBAAkB,CAAC,EAAE,OAAO,MAAM;AACvC,UAAM,UAAU,OAAO,SAAS,WAAW,KAAK,CAAC,OAAO;AACxD,QAAI,MAAM,UAAU,QAAQ,CAAC,QAAS,QAAO;AAC7C,QAAI,MAAM,UAAU,SAAS,QAAS,QAAO;AAE7C,QAAI,MAAM,YAAY,QAAQ,CAAC,OAAO,UAAW,QAAO;AACxD,QAAI,MAAM,YAAY,SAAS,OAAO,UAAW,QAAO;AACxD,QAAI,MAAM,aAAa,QAAQ,CAAC,OAAO,WAAY,QAAO;AAC1D,QAAI,MAAM,aAAa,SAAS,OAAO,WAAY,QAAO;AAE1D,WAAO;AAAA,EACT,CAAC;AACH;AAMO,IAAM,oBAAiD,CAAC;AAAA,EAC7D;AAAA,EACA,GAAG;AACL,MAAM;AACJ,QAAM,SAAS,YAAY,KAAK;AAChC,SAAO,SAAS,WAAW;AAC7B;AAEA,kBAAkB,cAAc;","names":[]}
1
+ {"version":3,"sources":["../../../src/primitives/thread/ThreadIf.tsx"],"sourcesContent":["\"use client\";\n\nimport type { FC, PropsWithChildren } from \"react\";\nimport { useAssistantState } from \"../../context\";\nimport type { RequireAtLeastOne } from \"../../utils/RequireAtLeastOne\";\n\ntype ThreadIfFilters = {\n empty: boolean | undefined;\n running: boolean | undefined;\n disabled: boolean | undefined;\n};\n\ntype UseThreadIfProps = RequireAtLeastOne<ThreadIfFilters>;\n\nconst useThreadIf = (props: UseThreadIfProps) => {\n return useAssistantState(({ thread }) => {\n if (props.empty === true && !thread.isEmpty) return false;\n if (props.empty === false && thread.isEmpty) return false;\n\n if (props.running === true && !thread.isRunning) return false;\n if (props.running === false && thread.isRunning) return false;\n if (props.disabled === true && !thread.isDisabled) return false;\n if (props.disabled === false && thread.isDisabled) return false;\n\n return true;\n });\n};\n\nexport namespace ThreadPrimitiveIf {\n export type Props = PropsWithChildren<UseThreadIfProps>;\n}\n\n/**\n * @deprecated Use `<AssistantIf condition={({ thread }) => ...} />` instead.\n */\nexport const ThreadPrimitiveIf: FC<ThreadPrimitiveIf.Props> = ({\n children,\n ...query\n}) => {\n const result = useThreadIf(query);\n return result ? children : null;\n};\n\nThreadPrimitiveIf.displayName = \"ThreadPrimitive.If\";\n"],"mappings":";;;AAGA,SAAS,yBAAyB;AAWlC,IAAM,cAAc,CAAC,UAA4B;AAC/C,SAAO,kBAAkB,CAAC,EAAE,OAAO,MAAM;AACvC,QAAI,MAAM,UAAU,QAAQ,CAAC,OAAO,QAAS,QAAO;AACpD,QAAI,MAAM,UAAU,SAAS,OAAO,QAAS,QAAO;AAEpD,QAAI,MAAM,YAAY,QAAQ,CAAC,OAAO,UAAW,QAAO;AACxD,QAAI,MAAM,YAAY,SAAS,OAAO,UAAW,QAAO;AACxD,QAAI,MAAM,aAAa,QAAQ,CAAC,OAAO,WAAY,QAAO;AAC1D,QAAI,MAAM,aAAa,SAAS,OAAO,WAAY,QAAO;AAE1D,WAAO;AAAA,EACT,CAAC;AACH;AASO,IAAM,oBAAiD,CAAC;AAAA,EAC7D;AAAA,EACA,GAAG;AACL,MAAM;AACJ,QAAM,SAAS,YAAY,KAAK;AAChC,SAAO,SAAS,WAAW;AAC7B;AAEA,kBAAkB,cAAc;","names":[]}
@@ -16,6 +16,24 @@ export declare namespace ThreadPrimitiveViewport {
16
16
  * - "top": New user messages anchor at the top of the viewport for a focused reading experience.
17
17
  */
18
18
  turnAnchor?: "top" | "bottom" | undefined;
19
+ /**
20
+ * Whether to scroll to bottom when a new run starts.
21
+ *
22
+ * Defaults to true.
23
+ */
24
+ scrollToBottomOnRunStart?: boolean | undefined;
25
+ /**
26
+ * Whether to scroll to bottom when thread history is first loaded.
27
+ *
28
+ * Defaults to true.
29
+ */
30
+ scrollToBottomOnInitialize?: boolean | undefined;
31
+ /**
32
+ * Whether to scroll to bottom when switching to a different thread.
33
+ *
34
+ * Defaults to true.
35
+ */
36
+ scrollToBottomOnThreadSwitch?: boolean | undefined;
19
37
  };
20
38
  }
21
39
  /**
@@ -48,5 +66,23 @@ export declare const ThreadPrimitiveViewport: import("react").ForwardRefExoticCo
48
66
  * - "top": New user messages anchor at the top of the viewport for a focused reading experience.
49
67
  */
50
68
  turnAnchor?: "top" | "bottom" | undefined;
69
+ /**
70
+ * Whether to scroll to bottom when a new run starts.
71
+ *
72
+ * Defaults to true.
73
+ */
74
+ scrollToBottomOnRunStart?: boolean | undefined;
75
+ /**
76
+ * Whether to scroll to bottom when thread history is first loaded.
77
+ *
78
+ * Defaults to true.
79
+ */
80
+ scrollToBottomOnInitialize?: boolean | undefined;
81
+ /**
82
+ * Whether to scroll to bottom when switching to a different thread.
83
+ *
84
+ * Defaults to true.
85
+ */
86
+ scrollToBottomOnThreadSwitch?: boolean | undefined;
51
87
  } & import("react").RefAttributes<HTMLDivElement>>;
52
88
  //# sourceMappingURL=ThreadViewport.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ThreadViewport.d.ts","sourceRoot":"","sources":["../../../src/primitives/thread/ThreadViewport.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EACL,KAAK,YAAY,EAEjB,wBAAwB,EAEzB,MAAM,OAAO,CAAC;AAMf,yBAAiB,uBAAuB,CAAC;IACvC,KAAY,OAAO,GAAG,YAAY,CAAC,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC;IACzD,KAAY,KAAK,GAAG,wBAAwB,CAAC,OAAO,SAAS,CAAC,GAAG,CAAC,GAAG;QACnE;;;;;WAKG;QACH,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAEjC;;;;WAIG;QACH,UAAU,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,SAAS,CAAC;KAC3C,CAAC;CACH;AAiCD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,uBAAuB;;;IA9DhC;;;;;OAKG;iBACU,OAAO,GAAG,SAAS;IAEhC;;;;OAIG;iBACU,KAAK,GAAG,QAAQ,GAAG,SAAS;kDA0D3C,CAAC"}
1
+ {"version":3,"file":"ThreadViewport.d.ts","sourceRoot":"","sources":["../../../src/primitives/thread/ThreadViewport.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EACL,KAAK,YAAY,EAEjB,wBAAwB,EAEzB,MAAM,OAAO,CAAC;AAMf,yBAAiB,uBAAuB,CAAC;IACvC,KAAY,OAAO,GAAG,YAAY,CAAC,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC;IACzD,KAAY,KAAK,GAAG,wBAAwB,CAAC,OAAO,SAAS,CAAC,GAAG,CAAC,GAAG;QACnE;;;;;WAKG;QACH,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAEjC;;;;WAIG;QACH,UAAU,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,SAAS,CAAC;QAE1C;;;;WAIG;QACH,wBAAwB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAE/C;;;;WAIG;QACH,0BAA0B,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;QAEjD;;;;WAIG;QACH,4BAA4B,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;KACpD,CAAC;CACH;AA2CD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,uBAAuB;;;IA7FhC;;;;;OAKG;iBACU,OAAO,GAAG,SAAS;IAEhC;;;;OAIG;iBACU,KAAK,GAAG,QAAQ,GAAG,SAAS;IAEzC;;;;OAIG;+BACwB,OAAO,GAAG,SAAS;IAE9C;;;;OAIG;iCAC0B,OAAO,GAAG,SAAS;IAEhD;;;;OAIG;mCAC4B,OAAO,GAAG,SAAS;kDAoEpD,CAAC"}
@@ -14,20 +14,29 @@ import { useThreadViewport } from "../../context/react/ThreadViewportContext.js"
14
14
  import { jsx } from "react/jsx-runtime";
15
15
  var useViewportSizeRef = () => {
16
16
  const register = useThreadViewport((s) => s.registerViewport);
17
- const getHeight = useCallback(
18
- (el) => el.clientHeight - parseFloat(getComputedStyle(el).paddingTop),
19
- []
20
- );
17
+ const getHeight = useCallback((el) => el.clientHeight, []);
21
18
  return useSizeHandle(register, getHeight);
22
19
  };
23
- var ThreadPrimitiveViewportScrollable = forwardRef(({ autoScroll, children, ...rest }, forwardedRef) => {
24
- const autoScrollRef = useThreadViewportAutoScroll({
25
- autoScroll
26
- });
27
- const viewportSizeRef = useViewportSizeRef();
28
- const ref = useComposedRefs(forwardedRef, autoScrollRef, viewportSizeRef);
29
- return /* @__PURE__ */ jsx(Primitive.div, { ...rest, ref, children });
30
- });
20
+ var ThreadPrimitiveViewportScrollable = forwardRef(
21
+ ({
22
+ autoScroll,
23
+ scrollToBottomOnRunStart,
24
+ scrollToBottomOnInitialize,
25
+ scrollToBottomOnThreadSwitch,
26
+ children,
27
+ ...rest
28
+ }, forwardedRef) => {
29
+ const autoScrollRef = useThreadViewportAutoScroll({
30
+ autoScroll,
31
+ scrollToBottomOnRunStart,
32
+ scrollToBottomOnInitialize,
33
+ scrollToBottomOnThreadSwitch
34
+ });
35
+ const viewportSizeRef = useViewportSizeRef();
36
+ const ref = useComposedRefs(forwardedRef, autoScrollRef, viewportSizeRef);
37
+ return /* @__PURE__ */ jsx(Primitive.div, { ...rest, ref, children });
38
+ }
39
+ );
31
40
  ThreadPrimitiveViewportScrollable.displayName = "ThreadPrimitive.ViewportScrollable";
32
41
  var ThreadPrimitiveViewport = forwardRef(({ turnAnchor, ...props }, ref) => {
33
42
  return /* @__PURE__ */ jsx(ThreadPrimitiveViewportProvider, { options: { turnAnchor }, children: /* @__PURE__ */ jsx(ThreadPrimitiveViewportScrollable, { ...props, ref }) });