@assistant-ui/react 0.11.35 → 0.11.36

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 (199) hide show
  1. package/dist/client/AssistantClient.d.ts +13 -57
  2. package/dist/client/AssistantClient.d.ts.map +1 -1
  3. package/dist/client/AssistantClient.js +49 -26
  4. package/dist/client/AssistantClient.js.map +1 -1
  5. package/dist/client/ModelContext.d.ts +8 -0
  6. package/dist/client/ModelContext.d.ts.map +1 -0
  7. package/dist/client/ModelContext.js +21 -0
  8. package/dist/client/ModelContext.js.map +1 -0
  9. package/dist/client/ModelContextClient.d.ts +7 -0
  10. package/dist/client/ModelContextClient.d.ts.map +1 -0
  11. package/dist/client/ModelContextClient.js +18 -0
  12. package/dist/client/ModelContextClient.js.map +1 -0
  13. package/dist/client/ToolUIClient.d.ts.map +1 -1
  14. package/dist/client/ToolUIClient.js +45 -3
  15. package/dist/client/ToolUIClient.js.map +1 -1
  16. package/dist/client/ToolUIContext.d.ts +4 -0
  17. package/dist/client/ToolUIContext.d.ts.map +1 -0
  18. package/dist/client/ToolUIContext.js +20 -0
  19. package/dist/client/ToolUIContext.js.map +1 -0
  20. package/dist/client/Tools.d.ts +10 -0
  21. package/dist/client/Tools.d.ts.map +1 -0
  22. package/dist/client/Tools.js +55 -0
  23. package/dist/client/Tools.js.map +1 -0
  24. package/dist/client/types/ModelContext.d.ts +12 -0
  25. package/dist/client/types/ModelContext.d.ts.map +1 -0
  26. package/dist/client/types/ModelContext.js +1 -0
  27. package/dist/client/types/ModelContext.js.map +1 -0
  28. package/dist/client/types/ThreadList.d.ts.map +1 -1
  29. package/dist/client/types/ToolUI.d.ts +12 -1
  30. package/dist/client/types/ToolUI.d.ts.map +1 -1
  31. package/dist/client/types/Tools.d.ts +9 -0
  32. package/dist/client/types/Tools.d.ts.map +1 -0
  33. package/dist/client/types/Tools.js +1 -0
  34. package/dist/client/types/Tools.js.map +1 -0
  35. package/dist/context/providers/AttachmentByIndexProvider.d.ts.map +1 -1
  36. package/dist/context/providers/AttachmentByIndexProvider.js +20 -24
  37. package/dist/context/providers/AttachmentByIndexProvider.js.map +1 -1
  38. package/dist/context/providers/MessageByIndexProvider.d.ts.map +1 -1
  39. package/dist/context/providers/MessageByIndexProvider.js +27 -29
  40. package/dist/context/providers/MessageByIndexProvider.js.map +1 -1
  41. package/dist/context/providers/MessageProvider.d.ts.map +1 -1
  42. package/dist/context/providers/MessageProvider.js +11 -13
  43. package/dist/context/providers/MessageProvider.js.map +1 -1
  44. package/dist/context/providers/PartByIndexProvider.d.ts.map +1 -1
  45. package/dist/context/providers/PartByIndexProvider.js +11 -13
  46. package/dist/context/providers/PartByIndexProvider.js.map +1 -1
  47. package/dist/context/providers/TextMessagePartProvider.d.ts.map +1 -1
  48. package/dist/context/providers/TextMessagePartProvider.js +11 -13
  49. package/dist/context/providers/TextMessagePartProvider.js.map +1 -1
  50. package/dist/context/providers/ThreadListItemProvider.d.ts.map +1 -1
  51. package/dist/context/providers/ThreadListItemProvider.js +41 -45
  52. package/dist/context/providers/ThreadListItemProvider.js.map +1 -1
  53. package/dist/context/react/AssistantApiContext.d.ts +33 -4
  54. package/dist/context/react/AssistantApiContext.d.ts.map +1 -1
  55. package/dist/context/react/AssistantApiContext.js +35 -17
  56. package/dist/context/react/AssistantApiContext.js.map +1 -1
  57. package/dist/context/react/index.d.ts +1 -1
  58. package/dist/context/react/index.d.ts.map +1 -1
  59. package/dist/context/react/index.js +5 -1
  60. package/dist/context/react/index.js.map +1 -1
  61. package/dist/legacy-runtime/AssistantRuntimeProvider.d.ts.map +1 -1
  62. package/dist/legacy-runtime/AssistantRuntimeProvider.js +7 -9
  63. package/dist/legacy-runtime/AssistantRuntimeProvider.js.map +1 -1
  64. package/dist/legacy-runtime/RuntimeAdapter.d.ts +7 -0
  65. package/dist/legacy-runtime/RuntimeAdapter.d.ts.map +1 -0
  66. package/dist/legacy-runtime/RuntimeAdapter.js +20 -0
  67. package/dist/legacy-runtime/RuntimeAdapter.js.map +1 -0
  68. package/dist/legacy-runtime/client/ThreadListRuntimeClient.d.ts +2 -0
  69. package/dist/legacy-runtime/client/ThreadListRuntimeClient.d.ts.map +1 -1
  70. package/dist/legacy-runtime/client/ThreadListRuntimeClient.js +6 -2
  71. package/dist/legacy-runtime/client/ThreadListRuntimeClient.js.map +1 -1
  72. package/dist/legacy-runtime/hooks/AssistantContext.d.ts +14 -1
  73. package/dist/legacy-runtime/hooks/AssistantContext.d.ts.map +1 -1
  74. package/dist/legacy-runtime/hooks/AssistantContext.js +1 -1
  75. package/dist/legacy-runtime/hooks/AssistantContext.js.map +1 -1
  76. package/dist/legacy-runtime/hooks/AttachmentContext.d.ts +6 -0
  77. package/dist/legacy-runtime/hooks/AttachmentContext.d.ts.map +1 -1
  78. package/dist/legacy-runtime/hooks/AttachmentContext.js.map +1 -1
  79. package/dist/legacy-runtime/hooks/ComposerContext.d.ts +41 -2
  80. package/dist/legacy-runtime/hooks/ComposerContext.d.ts.map +1 -1
  81. package/dist/legacy-runtime/hooks/ComposerContext.js.map +1 -1
  82. package/dist/legacy-runtime/hooks/MessageContext.d.ts +36 -2
  83. package/dist/legacy-runtime/hooks/MessageContext.d.ts.map +1 -1
  84. package/dist/legacy-runtime/hooks/MessageContext.js.map +1 -1
  85. package/dist/legacy-runtime/hooks/MessagePartContext.d.ts +6 -0
  86. package/dist/legacy-runtime/hooks/MessagePartContext.d.ts.map +1 -1
  87. package/dist/legacy-runtime/hooks/MessagePartContext.js.map +1 -1
  88. package/dist/legacy-runtime/hooks/ThreadContext.d.ts +26 -1
  89. package/dist/legacy-runtime/hooks/ThreadContext.d.ts.map +1 -1
  90. package/dist/legacy-runtime/hooks/ThreadContext.js.map +1 -1
  91. package/dist/legacy-runtime/hooks/ThreadListItemContext.d.ts +6 -0
  92. package/dist/legacy-runtime/hooks/ThreadListItemContext.d.ts.map +1 -1
  93. package/dist/legacy-runtime/hooks/ThreadListItemContext.js.map +1 -1
  94. package/dist/legacy-runtime/runtime-cores/core/AssistantRuntimeCore.d.ts +1 -0
  95. package/dist/legacy-runtime/runtime-cores/core/AssistantRuntimeCore.d.ts.map +1 -1
  96. package/dist/legacy-runtime/runtime-cores/core/BaseAssistantRuntimeCore.d.ts +1 -0
  97. package/dist/legacy-runtime/runtime-cores/core/BaseAssistantRuntimeCore.d.ts.map +1 -1
  98. package/dist/legacy-runtime/runtime-cores/core/BaseAssistantRuntimeCore.js +3 -0
  99. package/dist/legacy-runtime/runtime-cores/core/BaseAssistantRuntimeCore.js.map +1 -1
  100. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadListRuntimeCore.d.ts +4 -1
  101. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadListRuntimeCore.d.ts.map +1 -1
  102. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadListRuntimeCore.js +2 -2
  103. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadListRuntimeCore.js.map +1 -1
  104. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadRuntimeCore.d.ts.map +1 -1
  105. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadRuntimeCore.js +7 -1
  106. package/dist/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadRuntimeCore.js.map +1 -1
  107. package/dist/legacy-runtime/runtime-cores/external-store/auto-status.d.ts +2 -12
  108. package/dist/legacy-runtime/runtime-cores/external-store/auto-status.d.ts.map +1 -1
  109. package/dist/legacy-runtime/runtime-cores/external-store/auto-status.js +45 -15
  110. package/dist/legacy-runtime/runtime-cores/external-store/auto-status.js.map +1 -1
  111. package/dist/legacy-runtime/runtime-cores/external-store/external-message-converter.d.ts +2 -0
  112. package/dist/legacy-runtime/runtime-cores/external-store/external-message-converter.d.ts.map +1 -1
  113. package/dist/legacy-runtime/runtime-cores/external-store/external-message-converter.js +4 -2
  114. package/dist/legacy-runtime/runtime-cores/external-store/external-message-converter.js.map +1 -1
  115. package/dist/legacy-runtime/runtime-cores/local/LocalThreadListRuntimeCore.d.ts +4 -1
  116. package/dist/legacy-runtime/runtime-cores/local/LocalThreadListRuntimeCore.d.ts.map +1 -1
  117. package/dist/legacy-runtime/runtime-cores/local/LocalThreadListRuntimeCore.js +2 -2
  118. package/dist/legacy-runtime/runtime-cores/local/LocalThreadListRuntimeCore.js.map +1 -1
  119. package/dist/legacy-runtime/runtime-cores/utils/MessageRepository.js +1 -1
  120. package/dist/legacy-runtime/runtime-cores/utils/MessageRepository.js.map +1 -1
  121. package/dist/model-context/index.d.ts +2 -0
  122. package/dist/model-context/index.d.ts.map +1 -1
  123. package/dist/model-context/index.js +6 -0
  124. package/dist/model-context/index.js.map +1 -1
  125. package/dist/model-context/makeAssistantVisible.js +1 -1
  126. package/dist/model-context/makeAssistantVisible.js.map +1 -1
  127. package/dist/model-context/toolbox.d.ts +28 -0
  128. package/dist/model-context/toolbox.d.ts.map +1 -0
  129. package/dist/model-context/toolbox.js +15 -0
  130. package/dist/model-context/toolbox.js.map +1 -0
  131. package/dist/model-context/useAssistantInstructions.js +1 -1
  132. package/dist/model-context/useAssistantInstructions.js.map +1 -1
  133. package/dist/model-context/useAssistantTool.js +1 -1
  134. package/dist/model-context/useAssistantTool.js.map +1 -1
  135. package/dist/primitives/message/MessageParts.d.ts.map +1 -1
  136. package/dist/primitives/message/MessageParts.js +2 -2
  137. package/dist/primitives/message/MessageParts.js.map +1 -1
  138. package/dist/primitives/message/MessagePartsGrouped.d.ts.map +1 -1
  139. package/dist/primitives/message/MessagePartsGrouped.js +2 -2
  140. package/dist/primitives/message/MessagePartsGrouped.js.map +1 -1
  141. package/dist/tests/setup.js +7 -7
  142. package/dist/tests/setup.js.map +1 -1
  143. package/dist/utils/tap-store/derived-scopes.d.ts +81 -0
  144. package/dist/utils/tap-store/derived-scopes.d.ts.map +1 -0
  145. package/dist/utils/tap-store/derived-scopes.js +67 -0
  146. package/dist/utils/tap-store/derived-scopes.js.map +1 -0
  147. package/dist/utils/tap-store/index.d.ts +1 -0
  148. package/dist/utils/tap-store/index.d.ts.map +1 -1
  149. package/dist/utils/tap-store/index.js +4 -0
  150. package/dist/utils/tap-store/index.js.map +1 -1
  151. package/dist/utils/tap-store/tap-api.js +1 -1
  152. package/dist/utils/tap-store/tap-api.js.map +1 -1
  153. package/package.json +9 -9
  154. package/src/client/AssistantClient.ts +64 -38
  155. package/src/client/ModelContext.ts +28 -0
  156. package/src/client/ModelContextClient.ts +16 -0
  157. package/src/client/ToolUIClient.ts +50 -3
  158. package/src/client/ToolUIContext.ts +22 -0
  159. package/src/client/Tools.ts +68 -0
  160. package/src/client/types/ModelContext.ts +15 -0
  161. package/src/client/types/ThreadList.ts +4 -0
  162. package/src/client/types/ToolUI.ts +10 -1
  163. package/src/client/types/Tools.ts +11 -0
  164. package/src/context/providers/AttachmentByIndexProvider.tsx +21 -25
  165. package/src/context/providers/MessageByIndexProvider.tsx +31 -33
  166. package/src/context/providers/MessageProvider.tsx +12 -14
  167. package/src/context/providers/PartByIndexProvider.tsx +12 -14
  168. package/src/context/providers/TextMessagePartProvider.tsx +12 -14
  169. package/src/context/providers/ThreadListItemProvider.tsx +42 -46
  170. package/src/context/react/AssistantApiContext.tsx +69 -29
  171. package/src/context/react/index.ts +5 -1
  172. package/src/legacy-runtime/AssistantRuntimeProvider.tsx +7 -9
  173. package/src/legacy-runtime/RuntimeAdapter.ts +19 -0
  174. package/src/legacy-runtime/client/ThreadListRuntimeClient.ts +10 -1
  175. package/src/legacy-runtime/hooks/AssistantContext.ts +16 -2
  176. package/src/legacy-runtime/hooks/AttachmentContext.ts +6 -0
  177. package/src/legacy-runtime/hooks/ComposerContext.ts +41 -2
  178. package/src/legacy-runtime/hooks/MessageContext.ts +37 -2
  179. package/src/legacy-runtime/hooks/MessagePartContext.ts +6 -0
  180. package/src/legacy-runtime/hooks/ThreadContext.ts +27 -1
  181. package/src/legacy-runtime/hooks/ThreadListItemContext.ts +6 -0
  182. package/src/legacy-runtime/runtime-cores/core/AssistantRuntimeCore.tsx +1 -0
  183. package/src/legacy-runtime/runtime-cores/core/BaseAssistantRuntimeCore.tsx +4 -0
  184. package/src/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadListRuntimeCore.tsx +4 -2
  185. package/src/legacy-runtime/runtime-cores/external-store/ExternalStoreThreadRuntimeCore.tsx +7 -1
  186. package/src/legacy-runtime/runtime-cores/external-store/auto-status.tsx +49 -16
  187. package/src/legacy-runtime/runtime-cores/external-store/external-message-converter.tsx +4 -0
  188. package/src/legacy-runtime/runtime-cores/local/LocalThreadListRuntimeCore.tsx +4 -2
  189. package/src/legacy-runtime/runtime-cores/utils/MessageRepository.tsx +1 -1
  190. package/src/model-context/index.ts +9 -0
  191. package/src/model-context/makeAssistantVisible.tsx +1 -1
  192. package/src/model-context/toolbox.tsx +37 -0
  193. package/src/model-context/useAssistantInstructions.tsx +1 -1
  194. package/src/model-context/useAssistantTool.tsx +1 -1
  195. package/src/primitives/message/MessageParts.tsx +3 -2
  196. package/src/primitives/message/MessagePartsGrouped.tsx +3 -2
  197. package/src/utils/tap-store/derived-scopes.ts +185 -0
  198. package/src/utils/tap-store/index.ts +9 -0
  199. package/src/utils/tap-store/tap-api.ts +1 -1
@@ -62,8 +62,8 @@ var ToolUIDisplay = ({
62
62
  ...props
63
63
  }) => {
64
64
  const Render = useAssistantState(({ toolUIs }) => {
65
- const Render2 = toolUIs[props.toolName] ?? Fallback;
66
- if (Array.isArray(Render2)) return Render2[0];
65
+ const Render2 = toolUIs.tools[props.toolName] ?? toolUIs.fallback ?? Fallback;
66
+ if (Array.isArray(Render2)) return Render2[0] ?? Fallback;
67
67
  return Render2;
68
68
  });
69
69
  if (!Render) return null;
@@ -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} 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\n/**\n * Groups consecutive tool-call message parts into ranges.\n * Always groups tool calls, even if there's only one.\n */\nconst groupMessageParts = (\n messageTypes: readonly string[],\n): MessagePartRange[] => {\n const ranges: MessagePartRange[] = [];\n let currentToolGroupStart = -1;\n\n for (let i = 0; i < messageTypes.length; i++) {\n const type = messageTypes[i];\n\n if (type === \"tool-call\") {\n // Start a new tool group if we haven't started one\n if (currentToolGroupStart === -1) {\n currentToolGroupStart = i;\n }\n } else {\n // End current tool group if it exists\n if (currentToolGroupStart !== -1) {\n ranges.push({\n type: \"toolGroup\",\n startIndex: currentToolGroupStart,\n endIndex: i - 1,\n });\n currentToolGroupStart = -1;\n }\n\n // Add non-tool-call part individually\n ranges.push({ type: \"single\", index: i });\n }\n }\n\n // Handle any remaining tool group at the end\n if (currentToolGroupStart !== -1) {\n ranges.push({\n type: \"toolGroup\",\n startIndex: currentToolGroupStart,\n endIndex: messageTypes.length - 1,\n });\n }\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 | undefined;\n };\n}\n\nconst ToolUIDisplay = ({\n Fallback,\n ...props\n}: {\n Fallback: ToolCallMessagePartComponent | undefined;\n} & ToolCallMessagePartProps) => {\n const Render = useAssistantState(({ toolUIs }) => {\n const Render = toolUIs[props.toolName] ?? Fallback;\n if (Array.isArray(Render)) return Render[0];\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} 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 // eslint-disable-next-line jsx-a11y/alt-text\n return <Image {...part} />;\n\n case \"file\":\n return <File {...part} />;\n\n case \"audio\":\n return <Audio {...part} />;\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 );\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 {\n const ToolGroupComponent =\n components!.ToolGroup ?? defaultComponents.ToolGroup;\n return (\n <ToolGroupComponent\n key={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 }\n });\n }, [messageRanges, components, contentLength]);\n\n return <>{partsElements}</>;\n};\n\nMessagePrimitiveParts.displayName = \"MessagePrimitive.Parts\";\n"],"mappings":"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","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} 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\n/**\n * Groups consecutive tool-call message parts into ranges.\n * Always groups tool calls, even if there's only one.\n */\nconst groupMessageParts = (\n messageTypes: readonly string[],\n): MessagePartRange[] => {\n const ranges: MessagePartRange[] = [];\n let currentToolGroupStart = -1;\n\n for (let i = 0; i < messageTypes.length; i++) {\n const type = messageTypes[i];\n\n if (type === \"tool-call\") {\n // Start a new tool group if we haven't started one\n if (currentToolGroupStart === -1) {\n currentToolGroupStart = i;\n }\n } else {\n // End current tool group if it exists\n if (currentToolGroupStart !== -1) {\n ranges.push({\n type: \"toolGroup\",\n startIndex: currentToolGroupStart,\n endIndex: i - 1,\n });\n currentToolGroupStart = -1;\n }\n\n // Add non-tool-call part individually\n ranges.push({ type: \"single\", index: i });\n }\n }\n\n // Handle any remaining tool group at the end\n if (currentToolGroupStart !== -1) {\n ranges.push({\n type: \"toolGroup\",\n startIndex: currentToolGroupStart,\n endIndex: messageTypes.length - 1,\n });\n }\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 | undefined;\n };\n}\n\nconst ToolUIDisplay = ({\n Fallback,\n ...props\n}: {\n Fallback: ToolCallMessagePartComponent | undefined;\n} & ToolCallMessagePartProps) => {\n const Render = useAssistantState(({ toolUIs }) => {\n const Render =\n toolUIs.tools[props.toolName] ?? toolUIs.fallback ?? 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} 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 // eslint-disable-next-line jsx-a11y/alt-text\n return <Image {...part} />;\n\n case \"file\":\n return <File {...part} />;\n\n case \"audio\":\n return <Audio {...part} />;\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 );\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 {\n const ToolGroupComponent =\n components!.ToolGroup ?? defaultComponents.ToolGroup;\n return (\n <ToolGroupComponent\n key={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 }\n });\n }, [messageRanges, components, contentLength]);\n\n return <>{partsElements}</>;\n};\n\nMessagePrimitiveParts.displayName = \"MessagePrimitive.Parts\";\n"],"mappings":"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","names":["Render","part"]}
@@ -1 +1 @@
1
- {"version":3,"file":"MessagePartsGrouped.d.ts","sourceRoot":"","sources":["../../../src/primitives/message/MessagePartsGrouped.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,EAAE,EAEP,iBAAiB,EAElB,MAAM,OAAO,CAAC;AASf,OAAO,KAAK,EACV,kCAAkC,EAClC,yBAAyB,EACzB,wBAAwB,EACxB,yBAAyB,EACzB,0BAA0B,EAC1B,4BAA4B,EAC5B,wBAAwB,EACxB,wBAAwB,EACxB,6BAA6B,EAC9B,MAAM,uCAAuC,CAAC;AAI/C,KAAK,gBAAgB,GAAG;IACtB,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,SAAS,GAAG,EAAE,KAAK,gBAAgB,EAAE,CAAC;AAmD7E,yBAAiB,qCAAqC,CAAC;IACrD,KAAY,KAAK,GAAG;QAClB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WA0CG;QACH,gBAAgB,EAAE,gBAAgB,CAAC;QAEnC;;;;;WAKG;QACH,UAAU,EACN;YACE,6CAA6C;YAC7C,KAAK,CAAC,EAAE,yBAAyB,GAAG,SAAS,CAAC;YAC9C,2CAA2C;YAC3C,IAAI,CAAC,EAAE,wBAAwB,GAAG,SAAS,CAAC;YAC5C,mEAAmE;YACnE,SAAS,CAAC,EAAE,6BAA6B,GAAG,SAAS,CAAC;YACtD,6CAA6C;YAC7C,MAAM,CAAC,EAAE,0BAA0B,GAAG,SAAS,CAAC;YAChD,4CAA4C;YAC5C,KAAK,CAAC,EAAE,yBAAyB,GAAG,SAAS,CAAC;YAC9C,2CAA2C;YAC3C,IAAI,CAAC,EAAE,wBAAwB,GAAG,SAAS,CAAC;YAC5C,2DAA2D;YAC3D,cAAc,CAAC,EAAE,kCAAkC,GAAG,SAAS,CAAC;YAChE,4CAA4C;YAC5C,KAAK,CAAC,EACF;gBACE,qDAAqD;gBACrD,OAAO,CAAC,EACJ,MAAM,CAAC,MAAM,EAAE,4BAA4B,GAAG,SAAS,CAAC,GACxD,SAAS,CAAC;gBACd,gDAAgD;gBAChD,QAAQ,CAAC,EAAE,aAAa,CAAC,wBAAwB,CAAC,GAAG,SAAS,CAAC;aAChE,GACD;gBACE,qDAAqD;gBACrD,QAAQ,EAAE,aAAa,CAAC,wBAAwB,CAAC,CAAC;aACnD,GACD,SAAS,CAAC;YAEd;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAgCG;YACH,KAAK,CAAC,EAAE,aAAa,CACnB,iBAAiB,CAAC;gBAChB,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;gBAC7B,OAAO,EAAE,MAAM,EAAE,CAAC;aACnB,CAAC,CACH,CAAC;SACH,GACD,SAAS,CAAC;KACf,CAAC;CACH;AAkKD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACH,eAAO,MAAM,qCAAqC,EAAE,EAAE,CACpD,qCAAqC,CAAC,KAAK,CAkC5C,CAAC;AAKF;;;;;GAKG;AACH,eAAO,MAAM,+CAA+C,EAAE,EAAE,CAC9D,IAAI,CAAC,qCAAqC,CAAC,KAAK,EAAE,kBAAkB,CAAC,CAStE,CAAC"}
1
+ {"version":3,"file":"MessagePartsGrouped.d.ts","sourceRoot":"","sources":["../../../src/primitives/message/MessagePartsGrouped.tsx"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,EAAE,EAEP,iBAAiB,EAElB,MAAM,OAAO,CAAC;AASf,OAAO,KAAK,EACV,kCAAkC,EAClC,yBAAyB,EACzB,wBAAwB,EACxB,yBAAyB,EACzB,0BAA0B,EAC1B,4BAA4B,EAC5B,wBAAwB,EACxB,wBAAwB,EACxB,6BAA6B,EAC9B,MAAM,uCAAuC,CAAC;AAI/C,KAAK,gBAAgB,GAAG;IACtB,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,SAAS,GAAG,EAAE,KAAK,gBAAgB,EAAE,CAAC;AAmD7E,yBAAiB,qCAAqC,CAAC;IACrD,KAAY,KAAK,GAAG;QAClB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WA0CG;QACH,gBAAgB,EAAE,gBAAgB,CAAC;QAEnC;;;;;WAKG;QACH,UAAU,EACN;YACE,6CAA6C;YAC7C,KAAK,CAAC,EAAE,yBAAyB,GAAG,SAAS,CAAC;YAC9C,2CAA2C;YAC3C,IAAI,CAAC,EAAE,wBAAwB,GAAG,SAAS,CAAC;YAC5C,mEAAmE;YACnE,SAAS,CAAC,EAAE,6BAA6B,GAAG,SAAS,CAAC;YACtD,6CAA6C;YAC7C,MAAM,CAAC,EAAE,0BAA0B,GAAG,SAAS,CAAC;YAChD,4CAA4C;YAC5C,KAAK,CAAC,EAAE,yBAAyB,GAAG,SAAS,CAAC;YAC9C,2CAA2C;YAC3C,IAAI,CAAC,EAAE,wBAAwB,GAAG,SAAS,CAAC;YAC5C,2DAA2D;YAC3D,cAAc,CAAC,EAAE,kCAAkC,GAAG,SAAS,CAAC;YAChE,4CAA4C;YAC5C,KAAK,CAAC,EACF;gBACE,qDAAqD;gBACrD,OAAO,CAAC,EACJ,MAAM,CAAC,MAAM,EAAE,4BAA4B,GAAG,SAAS,CAAC,GACxD,SAAS,CAAC;gBACd,gDAAgD;gBAChD,QAAQ,CAAC,EAAE,aAAa,CAAC,wBAAwB,CAAC,GAAG,SAAS,CAAC;aAChE,GACD;gBACE,qDAAqD;gBACrD,QAAQ,EAAE,aAAa,CAAC,wBAAwB,CAAC,CAAC;aACnD,GACD,SAAS,CAAC;YAEd;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;eAgCG;YACH,KAAK,CAAC,EAAE,aAAa,CACnB,iBAAiB,CAAC;gBAChB,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;gBAC7B,OAAO,EAAE,MAAM,EAAE,CAAC;aACnB,CAAC,CACH,CAAC;SACH,GACD,SAAS,CAAC;KACf,CAAC;CACH;AAmKD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AACH,eAAO,MAAM,qCAAqC,EAAE,EAAE,CACpD,qCAAqC,CAAC,KAAK,CAkC5C,CAAC;AAKF;;;;;GAKG;AACH,eAAO,MAAM,+CAA+C,EAAE,EAAE,CAC9D,IAAI,CAAC,qCAAqC,CAAC,KAAK,EAAE,kBAAkB,CAAC,CAStE,CAAC"}
@@ -46,8 +46,8 @@ var ToolUIDisplay = ({
46
46
  ...props
47
47
  }) => {
48
48
  const Render = useAssistantState(({ toolUIs }) => {
49
- const Render2 = toolUIs[props.toolName] ?? Fallback;
50
- if (Array.isArray(Render2)) return Render2[0];
49
+ const Render2 = toolUIs.tools[props.toolName] ?? toolUIs.fallback ?? Fallback;
50
+ if (Array.isArray(Render2)) return Render2[0] ?? Fallback;
51
51
  return Render2;
52
52
  });
53
53
  if (!Render) return null;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/primitives/message/MessagePartsGrouped.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 PartByIndexProvider,\n useAssistantApi,\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} from \"../../types/MessagePartComponentTypes\";\nimport { MessagePartPrimitiveInProgress } from \"../messagePart/MessagePartInProgress\";\nimport { MessagePartStatus } from \"../../types/AssistantTypes\";\n\ntype MessagePartGroup = {\n groupKey: string | undefined;\n indices: number[];\n};\n\nexport type GroupingFunction = (parts: readonly any[]) => MessagePartGroup[];\n\n/**\n * Groups message parts by their parent ID.\n * Parts without a parent ID appear in their chronological position as individual groups.\n * Parts with the same parent ID are grouped together at the position of their first occurrence.\n */\nconst groupMessagePartsByParentId: GroupingFunction = (\n parts: readonly any[],\n): MessagePartGroup[] => {\n // Map maintains insertion order, so groups appear in order of first occurrence\n const groupMap = new Map<string, number[]>();\n\n // Process each part in order\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i];\n const parentId = part?.parentId as string | undefined;\n\n // For parts without parentId, assign a unique group ID to maintain their position\n const groupId = parentId ?? `__ungrouped_${i}`;\n\n // Get or create the indices array for this group\n const indices = groupMap.get(groupId) ?? [];\n indices.push(i);\n groupMap.set(groupId, indices);\n }\n\n // Convert map to array of groups\n const groups: MessagePartGroup[] = [];\n for (const [groupId, indices] of groupMap) {\n // Extract parentId (undefined for ungrouped parts)\n const groupKey = groupId.startsWith(\"__ungrouped_\") ? undefined : groupId;\n groups.push({ groupKey, indices });\n }\n\n return groups;\n};\n\nconst useMessagePartsGrouped = (\n groupingFunction: GroupingFunction,\n): MessagePartGroup[] => {\n const parts = useAssistantState(({ message }) => message.parts);\n\n return useMemo(() => {\n if (parts.length === 0) {\n return [];\n }\n return groupingFunction(parts);\n }, [parts, groupingFunction]);\n};\n\nexport namespace MessagePrimitiveUnstable_PartsGrouped {\n export type Props = {\n /**\n * Function that takes an array of message parts and returns an array of groups.\n * Each group contains a key (for identification) and an array of indices.\n *\n * @example\n * ```tsx\n * // Group by parent ID (default behavior)\n * groupingFunction={(parts) => {\n * const groups = new Map<string, number[]>();\n * parts.forEach((part, i) => {\n * const key = part.parentId ?? `__ungrouped_${i}`;\n * const indices = groups.get(key) ?? [];\n * indices.push(i);\n * groups.set(key, indices);\n * });\n * return Array.from(groups.entries()).map(([key, indices]) => ({\n * key: key.startsWith(\"__ungrouped_\") ? undefined : key,\n * indices\n * }));\n * }}\n * ```\n *\n * @example\n * ```tsx\n * // Group by tool name\n * import { groupMessagePartsByToolName } from \"@assistant-ui/react\";\n *\n * <MessagePrimitive.Unstable_PartsGrouped\n * groupingFunction={groupMessagePartsByToolName}\n * components={{\n * Group: ({ key, indices, children }) => {\n * if (!key) return <>{children}</>;\n * return (\n * <div className=\"tool-group\">\n * <h4>Tool: {key}</h4>\n * {children}\n * </div>\n * );\n * }\n * }}\n * />\n * ```\n */\n groupingFunction: GroupingFunction;\n\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 message parts.\n *\n * When provided, this component will automatically wrap message parts that share\n * the same group key as determined by the groupingFunction.\n *\n * The component receives:\n * - `groupKey`: The group key (or undefined for ungrouped parts)\n * - `indices`: Array of indices for the parts in this group\n * - `children`: The rendered message part components\n *\n * @example\n * ```tsx\n * // Collapsible group\n * Group: ({ groupKey, indices, children }) => {\n * if (!groupKey) return <>{children}</>;\n * return (\n * <details className=\"message-group\">\n * <summary>\n * Group {groupKey} ({indices.length} parts)\n * </summary>\n * <div className=\"group-content\">\n * {children}\n * </div>\n * </details>\n * );\n * }\n * ```\n *\n * @param groupKey - The group key (undefined for ungrouped parts)\n * @param indices - Array of indices for the parts in this group\n * @param children - Rendered message part components to display within the group\n */\n Group?: ComponentType<\n PropsWithChildren<{\n groupKey: string | undefined;\n indices: number[];\n }>\n >;\n }\n | undefined;\n };\n}\n\nconst ToolUIDisplay = ({\n Fallback,\n ...props\n}: {\n Fallback: ToolCallMessagePartComponent | undefined;\n} & ToolCallMessagePartProps) => {\n const Render = useAssistantState(({ toolUIs }) => {\n const Render = toolUIs[props.toolName] ?? Fallback;\n if (Array.isArray(Render)) return Render[0];\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 Group: ({ children }) => children,\n} satisfies MessagePrimitiveUnstable_PartsGrouped.Props[\"components\"];\n\ntype MessagePartComponentProps = {\n components: MessagePrimitiveUnstable_PartsGrouped.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 = (result: any) => api.part().addToolResult(result);\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 // eslint-disable-next-line jsx-a11y/alt-text\n return <Image {...part} />;\n\n case \"file\":\n return <File {...part} />;\n\n case \"audio\":\n return <Audio {...part} />;\n\n default:\n const unhandledType: never = type;\n throw new Error(`Unknown message part type: ${unhandledType}`);\n }\n};\n\ntype MessagePartProps = {\n partIndex: number;\n components: MessagePrimitiveUnstable_PartsGrouped.Props[\"components\"];\n};\n\nconst MessagePartImpl: FC<MessagePartProps> = ({ partIndex, components }) => {\n return (\n <PartByIndexProvider index={partIndex}>\n <MessagePartComponent components={components} />\n </PartByIndexProvider>\n );\n};\n\nconst MessagePart = memo(\n MessagePartImpl,\n (prev, next) =>\n prev.partIndex === next.partIndex &&\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?.Group === next.components?.Group,\n);\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 grouped by a custom grouping function.\n *\n * This component allows you to group message parts based on any criteria you define.\n * The grouping function receives all message parts and returns an array of groups,\n * where each group has a key and an array of part indices.\n *\n * @example\n * ```tsx\n * // Group by parent ID (default behavior)\n * <MessagePrimitive.Unstable_PartsGrouped\n * components={{\n * Text: ({ text }) => <p className=\"message-text\">{text}</p>,\n * Image: ({ image }) => <img src={image} alt=\"Message image\" />,\n * Group: ({ groupKey, indices, children }) => {\n * if (!groupKey) return <>{children}</>;\n * return (\n * <div className=\"parent-group border rounded p-4\">\n * <h4>Parent ID: {groupKey}</h4>\n * {children}\n * </div>\n * );\n * }\n * }}\n * />\n * ```\n *\n * @example\n * ```tsx\n * // Group by tool name\n * import { groupMessagePartsByToolName } from \"@assistant-ui/react\";\n *\n * <MessagePrimitive.Unstable_PartsGrouped\n * groupingFunction={groupMessagePartsByToolName}\n * components={{\n * Group: ({ groupKey, indices, children }) => {\n * if (!groupKey) return <>{children}</>;\n * return (\n * <div className=\"tool-group\">\n * <h4>Tool: {groupKey}</h4>\n * {children}\n * </div>\n * );\n * }\n * }}\n * />\n * ```\n */\nexport const MessagePrimitiveUnstable_PartsGrouped: FC<\n MessagePrimitiveUnstable_PartsGrouped.Props\n> = ({ groupingFunction, components }) => {\n const contentLength = useAssistantState(\n ({ message }) => message.parts.length,\n );\n const messageGroups = useMessagePartsGrouped(groupingFunction);\n\n const partsElements = useMemo(() => {\n if (contentLength === 0) {\n return <EmptyParts components={components} />;\n }\n\n return messageGroups.map((group, groupIndex) => {\n const GroupComponent = components?.Group ?? defaultComponents.Group;\n\n return (\n <GroupComponent\n key={`group-${groupIndex}-${group.groupKey ?? \"ungrouped\"}`}\n groupKey={group.groupKey}\n indices={group.indices}\n >\n {group.indices.map((partIndex) => (\n <MessagePart\n key={partIndex}\n partIndex={partIndex}\n components={components}\n />\n ))}\n </GroupComponent>\n );\n });\n }, [messageGroups, components, contentLength]);\n\n return <>{partsElements}</>;\n};\n\nMessagePrimitiveUnstable_PartsGrouped.displayName =\n \"MessagePrimitive.Unstable_PartsGrouped\";\n\n/**\n * Renders the parts of a message grouped by their parent ID.\n * This is a convenience wrapper around Unstable_PartsGrouped with parent ID grouping.\n *\n * @deprecated Use MessagePrimitive.Unstable_PartsGrouped instead for more flexibility\n */\nexport const MessagePrimitiveUnstable_PartsGroupedByParentId: FC<\n Omit<MessagePrimitiveUnstable_PartsGrouped.Props, \"groupingFunction\">\n> = ({ components, ...props }) => {\n return (\n <MessagePrimitiveUnstable_PartsGrouped\n {...props}\n components={components}\n groupingFunction={groupMessagePartsByParentId}\n />\n );\n};\n\nMessagePrimitiveUnstable_PartsGroupedByParentId.displayName =\n \"MessagePrimitive.Unstable_PartsGroupedByParentId\";\n"],"mappings":"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","names":["Render","part"]}
1
+ {"version":3,"sources":["../../../src/primitives/message/MessagePartsGrouped.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 PartByIndexProvider,\n useAssistantApi,\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} from \"../../types/MessagePartComponentTypes\";\nimport { MessagePartPrimitiveInProgress } from \"../messagePart/MessagePartInProgress\";\nimport { MessagePartStatus } from \"../../types/AssistantTypes\";\n\ntype MessagePartGroup = {\n groupKey: string | undefined;\n indices: number[];\n};\n\nexport type GroupingFunction = (parts: readonly any[]) => MessagePartGroup[];\n\n/**\n * Groups message parts by their parent ID.\n * Parts without a parent ID appear in their chronological position as individual groups.\n * Parts with the same parent ID are grouped together at the position of their first occurrence.\n */\nconst groupMessagePartsByParentId: GroupingFunction = (\n parts: readonly any[],\n): MessagePartGroup[] => {\n // Map maintains insertion order, so groups appear in order of first occurrence\n const groupMap = new Map<string, number[]>();\n\n // Process each part in order\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i];\n const parentId = part?.parentId as string | undefined;\n\n // For parts without parentId, assign a unique group ID to maintain their position\n const groupId = parentId ?? `__ungrouped_${i}`;\n\n // Get or create the indices array for this group\n const indices = groupMap.get(groupId) ?? [];\n indices.push(i);\n groupMap.set(groupId, indices);\n }\n\n // Convert map to array of groups\n const groups: MessagePartGroup[] = [];\n for (const [groupId, indices] of groupMap) {\n // Extract parentId (undefined for ungrouped parts)\n const groupKey = groupId.startsWith(\"__ungrouped_\") ? undefined : groupId;\n groups.push({ groupKey, indices });\n }\n\n return groups;\n};\n\nconst useMessagePartsGrouped = (\n groupingFunction: GroupingFunction,\n): MessagePartGroup[] => {\n const parts = useAssistantState(({ message }) => message.parts);\n\n return useMemo(() => {\n if (parts.length === 0) {\n return [];\n }\n return groupingFunction(parts);\n }, [parts, groupingFunction]);\n};\n\nexport namespace MessagePrimitiveUnstable_PartsGrouped {\n export type Props = {\n /**\n * Function that takes an array of message parts and returns an array of groups.\n * Each group contains a key (for identification) and an array of indices.\n *\n * @example\n * ```tsx\n * // Group by parent ID (default behavior)\n * groupingFunction={(parts) => {\n * const groups = new Map<string, number[]>();\n * parts.forEach((part, i) => {\n * const key = part.parentId ?? `__ungrouped_${i}`;\n * const indices = groups.get(key) ?? [];\n * indices.push(i);\n * groups.set(key, indices);\n * });\n * return Array.from(groups.entries()).map(([key, indices]) => ({\n * key: key.startsWith(\"__ungrouped_\") ? undefined : key,\n * indices\n * }));\n * }}\n * ```\n *\n * @example\n * ```tsx\n * // Group by tool name\n * import { groupMessagePartsByToolName } from \"@assistant-ui/react\";\n *\n * <MessagePrimitive.Unstable_PartsGrouped\n * groupingFunction={groupMessagePartsByToolName}\n * components={{\n * Group: ({ key, indices, children }) => {\n * if (!key) return <>{children}</>;\n * return (\n * <div className=\"tool-group\">\n * <h4>Tool: {key}</h4>\n * {children}\n * </div>\n * );\n * }\n * }}\n * />\n * ```\n */\n groupingFunction: GroupingFunction;\n\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 message parts.\n *\n * When provided, this component will automatically wrap message parts that share\n * the same group key as determined by the groupingFunction.\n *\n * The component receives:\n * - `groupKey`: The group key (or undefined for ungrouped parts)\n * - `indices`: Array of indices for the parts in this group\n * - `children`: The rendered message part components\n *\n * @example\n * ```tsx\n * // Collapsible group\n * Group: ({ groupKey, indices, children }) => {\n * if (!groupKey) return <>{children}</>;\n * return (\n * <details className=\"message-group\">\n * <summary>\n * Group {groupKey} ({indices.length} parts)\n * </summary>\n * <div className=\"group-content\">\n * {children}\n * </div>\n * </details>\n * );\n * }\n * ```\n *\n * @param groupKey - The group key (undefined for ungrouped parts)\n * @param indices - Array of indices for the parts in this group\n * @param children - Rendered message part components to display within the group\n */\n Group?: ComponentType<\n PropsWithChildren<{\n groupKey: string | undefined;\n indices: number[];\n }>\n >;\n }\n | undefined;\n };\n}\n\nconst ToolUIDisplay = ({\n Fallback,\n ...props\n}: {\n Fallback: ToolCallMessagePartComponent | undefined;\n} & ToolCallMessagePartProps) => {\n const Render = useAssistantState(({ toolUIs }) => {\n const Render =\n toolUIs.tools[props.toolName] ?? toolUIs.fallback ?? 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 Group: ({ children }) => children,\n} satisfies MessagePrimitiveUnstable_PartsGrouped.Props[\"components\"];\n\ntype MessagePartComponentProps = {\n components: MessagePrimitiveUnstable_PartsGrouped.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 = (result: any) => api.part().addToolResult(result);\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 // eslint-disable-next-line jsx-a11y/alt-text\n return <Image {...part} />;\n\n case \"file\":\n return <File {...part} />;\n\n case \"audio\":\n return <Audio {...part} />;\n\n default:\n const unhandledType: never = type;\n throw new Error(`Unknown message part type: ${unhandledType}`);\n }\n};\n\ntype MessagePartProps = {\n partIndex: number;\n components: MessagePrimitiveUnstable_PartsGrouped.Props[\"components\"];\n};\n\nconst MessagePartImpl: FC<MessagePartProps> = ({ partIndex, components }) => {\n return (\n <PartByIndexProvider index={partIndex}>\n <MessagePartComponent components={components} />\n </PartByIndexProvider>\n );\n};\n\nconst MessagePart = memo(\n MessagePartImpl,\n (prev, next) =>\n prev.partIndex === next.partIndex &&\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?.Group === next.components?.Group,\n);\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 grouped by a custom grouping function.\n *\n * This component allows you to group message parts based on any criteria you define.\n * The grouping function receives all message parts and returns an array of groups,\n * where each group has a key and an array of part indices.\n *\n * @example\n * ```tsx\n * // Group by parent ID (default behavior)\n * <MessagePrimitive.Unstable_PartsGrouped\n * components={{\n * Text: ({ text }) => <p className=\"message-text\">{text}</p>,\n * Image: ({ image }) => <img src={image} alt=\"Message image\" />,\n * Group: ({ groupKey, indices, children }) => {\n * if (!groupKey) return <>{children}</>;\n * return (\n * <div className=\"parent-group border rounded p-4\">\n * <h4>Parent ID: {groupKey}</h4>\n * {children}\n * </div>\n * );\n * }\n * }}\n * />\n * ```\n *\n * @example\n * ```tsx\n * // Group by tool name\n * import { groupMessagePartsByToolName } from \"@assistant-ui/react\";\n *\n * <MessagePrimitive.Unstable_PartsGrouped\n * groupingFunction={groupMessagePartsByToolName}\n * components={{\n * Group: ({ groupKey, indices, children }) => {\n * if (!groupKey) return <>{children}</>;\n * return (\n * <div className=\"tool-group\">\n * <h4>Tool: {groupKey}</h4>\n * {children}\n * </div>\n * );\n * }\n * }}\n * />\n * ```\n */\nexport const MessagePrimitiveUnstable_PartsGrouped: FC<\n MessagePrimitiveUnstable_PartsGrouped.Props\n> = ({ groupingFunction, components }) => {\n const contentLength = useAssistantState(\n ({ message }) => message.parts.length,\n );\n const messageGroups = useMessagePartsGrouped(groupingFunction);\n\n const partsElements = useMemo(() => {\n if (contentLength === 0) {\n return <EmptyParts components={components} />;\n }\n\n return messageGroups.map((group, groupIndex) => {\n const GroupComponent = components?.Group ?? defaultComponents.Group;\n\n return (\n <GroupComponent\n key={`group-${groupIndex}-${group.groupKey ?? \"ungrouped\"}`}\n groupKey={group.groupKey}\n indices={group.indices}\n >\n {group.indices.map((partIndex) => (\n <MessagePart\n key={partIndex}\n partIndex={partIndex}\n components={components}\n />\n ))}\n </GroupComponent>\n );\n });\n }, [messageGroups, components, contentLength]);\n\n return <>{partsElements}</>;\n};\n\nMessagePrimitiveUnstable_PartsGrouped.displayName =\n \"MessagePrimitive.Unstable_PartsGrouped\";\n\n/**\n * Renders the parts of a message grouped by their parent ID.\n * This is a convenience wrapper around Unstable_PartsGrouped with parent ID grouping.\n *\n * @deprecated Use MessagePrimitive.Unstable_PartsGrouped instead for more flexibility\n */\nexport const MessagePrimitiveUnstable_PartsGroupedByParentId: FC<\n Omit<MessagePrimitiveUnstable_PartsGrouped.Props, \"groupingFunction\">\n> = ({ components, ...props }) => {\n return (\n <MessagePrimitiveUnstable_PartsGrouped\n {...props}\n components={components}\n groupingFunction={groupMessagePartsByParentId}\n />\n );\n};\n\nMessagePrimitiveUnstable_PartsGroupedByParentId.displayName =\n \"MessagePrimitive.Unstable_PartsGroupedByParentId\";\n"],"mappings":"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","names":["Render","part"]}
@@ -1,9 +1,9 @@
1
- // ../../node_modules/.pnpm/vitest@4.0.1_@types+debug@4.1.12_@types+node@24.9.1_@vitest+ui@4.0.1_jiti@2.6.1_jsdom@2_f7e90f889c75ea518901b8d845576f89/node_modules/vitest/dist/chunks/vi.BZvkKVkM.js
1
+ // ../../node_modules/.pnpm/vitest@4.0.6_@types+debug@4.1.12_@types+node@24.10.0_@vitest+ui@4.0.6_jiti@2.6.1_jsdom@_38fcb34f3d4da47a9b9d4b13a6949560/node_modules/vitest/dist/chunks/vi.BZvkKVkM.js
2
2
  import { chai, equals, iterableEquality, subsetEquality, JestExtend, JestChaiExpect, JestAsymmetricMatchers, GLOBAL_EXPECT, ASYMMETRIC_MATCHERS_OBJECT, getState, setState, addCustomEqualityTesters, customMatchers } from "@vitest/expect.js";
3
3
  import { getCurrentTest } from "@vitest/runner.js";
4
4
  import { getNames, getTestName } from "@vitest/runner/utils.js";
5
5
 
6
- // ../../node_modules/.pnpm/vitest@4.0.1_@types+debug@4.1.12_@types+node@24.9.1_@vitest+ui@4.0.1_jiti@2.6.1_jsdom@2_f7e90f889c75ea518901b8d845576f89/node_modules/vitest/dist/chunks/utils.CG9h5ccR.js
6
+ // ../../node_modules/.pnpm/vitest@4.0.6_@types+debug@4.1.12_@types+node@24.10.0_@vitest+ui@4.0.6_jiti@2.6.1_jsdom@_38fcb34f3d4da47a9b9d4b13a6949560/node_modules/vitest/dist/chunks/utils.CG9h5ccR.js
7
7
  import { getSafeTimers } from "@vitest/utils/timers.js";
8
8
  var NAME_WORKER_STATE = "__vitest_worker__";
9
9
  function getWorkerState() {
@@ -36,7 +36,7 @@ async function waitForImportsToResolve() {
36
36
  !promises.length && !resolvingCount || (await Promise.allSettled(promises), await waitForImportsToResolve());
37
37
  }
38
38
 
39
- // ../../node_modules/.pnpm/vitest@4.0.1_@types+debug@4.1.12_@types+node@24.9.1_@vitest+ui@4.0.1_jiti@2.6.1_jsdom@2_f7e90f889c75ea518901b8d845576f89/node_modules/vitest/dist/chunks/vi.BZvkKVkM.js
39
+ // ../../node_modules/.pnpm/vitest@4.0.6_@types+debug@4.1.12_@types+node@24.10.0_@vitest+ui@4.0.6_jiti@2.6.1_jsdom@_38fcb34f3d4da47a9b9d4b13a6949560/node_modules/vitest/dist/chunks/vi.BZvkKVkM.js
40
40
  import { getSafeTimers as getSafeTimers2 } from "@vitest/utils/timers.js";
41
41
  import { stripSnapshotIndentation, addSerializer, SnapshotClient } from "@vitest/snapshot.js";
42
42
  import "@vitest/utils/error.js";
@@ -45,10 +45,10 @@ import { fn, spyOn, restoreAllMocks, resetAllMocks, clearAllMocks, isMockFunctio
45
45
  import "@vitest/utils/offset.js";
46
46
  import { parseSingleStack } from "@vitest/utils/source-map.js";
47
47
 
48
- // ../../node_modules/.pnpm/vitest@4.0.1_@types+debug@4.1.12_@types+node@24.9.1_@vitest+ui@4.0.1_jiti@2.6.1_jsdom@2_f7e90f889c75ea518901b8d845576f89/node_modules/vitest/dist/chunks/_commonjsHelpers.BFTU3MAI.js
48
+ // ../../node_modules/.pnpm/vitest@4.0.6_@types+debug@4.1.12_@types+node@24.10.0_@vitest+ui@4.0.6_jiti@2.6.1_jsdom@_38fcb34f3d4da47a9b9d4b13a6949560/node_modules/vitest/dist/chunks/_commonjsHelpers.BFTU3MAI.js
49
49
  var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
50
50
 
51
- // ../../node_modules/.pnpm/vitest@4.0.1_@types+debug@4.1.12_@types+node@24.9.1_@vitest+ui@4.0.1_jiti@2.6.1_jsdom@2_f7e90f889c75ea518901b8d845576f89/node_modules/vitest/dist/chunks/date.-jtEtIeV.js
51
+ // ../../node_modules/.pnpm/vitest@4.0.6_@types+debug@4.1.12_@types+node@24.10.0_@vitest+ui@4.0.6_jiti@2.6.1_jsdom@_38fcb34f3d4da47a9b9d4b13a6949560/node_modules/vitest/dist/chunks/date.-jtEtIeV.js
52
52
  var RealDate = Date;
53
53
  var now = null;
54
54
  var MockDate = class _MockDate extends RealDate {
@@ -86,7 +86,7 @@ function resetDate() {
86
86
  globalThis.Date = RealDate;
87
87
  }
88
88
 
89
- // ../../node_modules/.pnpm/vitest@4.0.1_@types+debug@4.1.12_@types+node@24.9.1_@vitest+ui@4.0.1_jiti@2.6.1_jsdom@2_f7e90f889c75ea518901b8d845576f89/node_modules/vitest/dist/chunks/vi.BZvkKVkM.js
89
+ // ../../node_modules/.pnpm/vitest@4.0.6_@types+debug@4.1.12_@types+node@24.10.0_@vitest+ui@4.0.6_jiti@2.6.1_jsdom@_38fcb34f3d4da47a9b9d4b13a6949560/node_modules/vitest/dist/chunks/vi.BZvkKVkM.js
90
90
  var unsupported = [
91
91
  "matchSnapshot",
92
92
  "toMatchSnapshot",
@@ -2534,7 +2534,7 @@ function getImporter(name) {
2534
2534
  return parseSingleStack(stackArray[importerStackIndex + 1])?.file || "";
2535
2535
  }
2536
2536
 
2537
- // ../../node_modules/.pnpm/vitest@4.0.1_@types+debug@4.1.12_@types+node@24.9.1_@vitest+ui@4.0.1_jiti@2.6.1_jsdom@2_f7e90f889c75ea518901b8d845576f89/node_modules/vitest/dist/index.js
2537
+ // ../../node_modules/.pnpm/vitest@4.0.6_@types+debug@4.1.12_@types+node@24.10.0_@vitest+ui@4.0.6_jiti@2.6.1_jsdom@_38fcb34f3d4da47a9b9d4b13a6949560/node_modules/vitest/dist/index.js
2538
2538
  import { expectTypeOf } from "expect-type.js";
2539
2539
  import { afterAll, afterEach, beforeAll, beforeEach, describe, it, onTestFailed, onTestFinished, suite, test } from "@vitest/runner.js";
2540
2540
  import { chai as chai2 } from "@vitest/expect.js";