@assistant-ui/react 0.11.38 → 0.11.41

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 (127) hide show
  1. package/dist/client/AssistantClient.d.ts.map +1 -1
  2. package/dist/client/AssistantClient.js +14 -30
  3. package/dist/client/AssistantClient.js.map +1 -1
  4. package/dist/client/ModelContextClient.d.ts +1 -1
  5. package/dist/client/NoOpComposerClient.d.ts +1 -1
  6. package/dist/client/ThreadMessageClient.d.ts +1 -1
  7. package/dist/client/Tools.d.ts +1 -1
  8. package/dist/client/Tools.d.ts.map +1 -1
  9. package/dist/client/Tools.js +29 -18
  10. package/dist/client/Tools.js.map +1 -1
  11. package/dist/client/types/Tools.d.ts +6 -1
  12. package/dist/client/types/Tools.d.ts.map +1 -1
  13. package/dist/context/react/AssistantApiContext.d.ts +2 -4
  14. package/dist/context/react/AssistantApiContext.d.ts.map +1 -1
  15. package/dist/context/react/AssistantApiContext.js +0 -7
  16. package/dist/context/react/AssistantApiContext.js.map +1 -1
  17. package/dist/context/react/hooks/useAssistantState.js +2 -2
  18. package/dist/context/react/hooks/useAssistantState.js.map +1 -1
  19. package/dist/legacy-runtime/RuntimeAdapter.d.ts +1 -1
  20. package/dist/legacy-runtime/client/AttachmentRuntimeClient.d.ts +1 -1
  21. package/dist/legacy-runtime/client/ComposerRuntimeClient.d.ts +1 -1
  22. package/dist/legacy-runtime/client/EventManagerRuntimeClient.d.ts +1 -1
  23. package/dist/legacy-runtime/client/MessagePartRuntimeClient.d.ts +1 -1
  24. package/dist/legacy-runtime/client/MessageRuntimeClient.d.ts +1 -1
  25. package/dist/legacy-runtime/client/ThreadListItemRuntimeClient.d.ts +1 -1
  26. package/dist/legacy-runtime/client/ThreadListRuntimeClient.d.ts +1 -1
  27. package/dist/legacy-runtime/client/ThreadRuntimeClient.d.ts +1 -1
  28. package/dist/legacy-runtime/cloud/auiV0.js.map +1 -1
  29. package/dist/legacy-runtime/runtime-cores/assistant-transport/runManager.d.ts +1 -1
  30. package/dist/legacy-runtime/runtime-cores/assistant-transport/runManager.d.ts.map +1 -1
  31. package/dist/legacy-runtime/runtime-cores/assistant-transport/runManager.js +1 -1
  32. package/dist/legacy-runtime/runtime-cores/assistant-transport/runManager.js.map +1 -1
  33. package/dist/legacy-runtime/runtime-cores/assistant-transport/types.d.ts +8 -1
  34. package/dist/legacy-runtime/runtime-cores/assistant-transport/types.d.ts.map +1 -1
  35. package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.d.ts.map +1 -1
  36. package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.js +23 -11
  37. package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.js.map +1 -1
  38. package/dist/legacy-runtime/runtime-cores/external-store/ThreadMessageLike.d.ts +2 -2
  39. package/dist/legacy-runtime/runtime-cores/external-store/ThreadMessageLike.d.ts.map +1 -1
  40. package/dist/legacy-runtime/runtime-cores/external-store/ThreadMessageLike.js +2 -0
  41. package/dist/legacy-runtime/runtime-cores/external-store/ThreadMessageLike.js.map +1 -1
  42. package/dist/legacy-runtime/runtime-cores/local/LocalThreadRuntimeCore.d.ts.map +1 -1
  43. package/dist/legacy-runtime/runtime-cores/local/LocalThreadRuntimeCore.js +7 -4
  44. package/dist/legacy-runtime/runtime-cores/local/LocalThreadRuntimeCore.js.map +1 -1
  45. package/dist/legacy-runtime/runtime-cores/utils/MessageRepository.d.ts +7 -2
  46. package/dist/legacy-runtime/runtime-cores/utils/MessageRepository.d.ts.map +1 -1
  47. package/dist/legacy-runtime/runtime-cores/utils/MessageRepository.js +17 -3
  48. package/dist/legacy-runtime/runtime-cores/utils/MessageRepository.js.map +1 -1
  49. package/dist/model-context/index.d.ts +1 -1
  50. package/dist/model-context/index.d.ts.map +1 -1
  51. package/dist/model-context/index.js +0 -4
  52. package/dist/model-context/index.js.map +1 -1
  53. package/dist/model-context/makeAssistantVisible.d.ts.map +1 -1
  54. package/dist/model-context/makeAssistantVisible.js +21 -8
  55. package/dist/model-context/makeAssistantVisible.js.map +1 -1
  56. package/dist/model-context/toolbox.d.ts +1 -19
  57. package/dist/model-context/toolbox.d.ts.map +1 -1
  58. package/dist/model-context/toolbox.js +0 -13
  59. package/dist/model-context/toolbox.js.map +1 -1
  60. package/dist/model-context/useAssistantTool.js +1 -1
  61. package/dist/model-context/useAssistantTool.js.map +1 -1
  62. package/dist/model-context/useAssistantToolUI.js +1 -1
  63. package/dist/model-context/useAssistantToolUI.js.map +1 -1
  64. package/dist/primitives/index.d.ts +1 -0
  65. package/dist/primitives/index.d.ts.map +1 -1
  66. package/dist/primitives/index.js +2 -0
  67. package/dist/primitives/index.js.map +1 -1
  68. package/dist/primitives/message/MessageParts.d.ts.map +1 -1
  69. package/dist/primitives/message/MessageParts.js +4 -2
  70. package/dist/primitives/message/MessageParts.js.map +1 -1
  71. package/dist/primitives/message/MessagePartsGrouped.d.ts.map +1 -1
  72. package/dist/primitives/message/MessagePartsGrouped.js +4 -2
  73. package/dist/primitives/message/MessagePartsGrouped.js.map +1 -1
  74. package/dist/primitives/messagePart/useMessagePartData.d.ts +3 -0
  75. package/dist/primitives/messagePart/useMessagePartData.d.ts.map +1 -0
  76. package/dist/primitives/messagePart/useMessagePartData.js +23 -0
  77. package/dist/primitives/messagePart/useMessagePartData.js.map +1 -0
  78. package/dist/tests/setup.js +14 -14
  79. package/dist/tests/setup.js.map +1 -1
  80. package/dist/types/AssistantTypes.d.ts +2 -2
  81. package/dist/types/AssistantTypes.d.ts.map +1 -1
  82. package/dist/types/MessagePartTypes.d.ts +6 -1
  83. package/dist/types/MessagePartTypes.d.ts.map +1 -1
  84. package/dist/types/index.d.ts +1 -1
  85. package/dist/types/index.d.ts.map +1 -1
  86. package/dist/utils/tap-store/derived-scopes.d.ts +1 -1
  87. package/dist/utils/tap-store/derived-scopes.d.ts.map +1 -1
  88. package/package.json +5 -5
  89. package/src/client/AssistantClient.ts +14 -33
  90. package/src/client/Tools.ts +31 -22
  91. package/src/client/types/Tools.ts +11 -2
  92. package/src/context/react/AssistantApiContext.tsx +2 -11
  93. package/src/context/react/hooks/useAssistantState.tsx +2 -2
  94. package/src/legacy-runtime/cloud/auiV0.ts +1 -1
  95. package/src/legacy-runtime/runtime-cores/assistant-transport/runManager.ts +2 -2
  96. package/src/legacy-runtime/runtime-cores/assistant-transport/types.ts +8 -1
  97. package/src/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.tsx +26 -11
  98. package/src/legacy-runtime/runtime-cores/external-store/ThreadMessageLike.tsx +10 -1
  99. package/src/legacy-runtime/runtime-cores/local/LocalThreadRuntimeCore.tsx +7 -3
  100. package/src/legacy-runtime/runtime-cores/utils/MessageRepository.tsx +27 -3
  101. package/src/model-context/index.ts +1 -6
  102. package/src/model-context/makeAssistantVisible.tsx +23 -12
  103. package/src/model-context/toolbox.tsx +1 -21
  104. package/src/model-context/useAssistantTool.tsx +1 -1
  105. package/src/model-context/useAssistantToolUI.tsx +1 -1
  106. package/src/primitives/index.ts +1 -0
  107. package/src/primitives/message/MessageParts.tsx +5 -3
  108. package/src/primitives/message/MessagePartsGrouped.tsx +5 -3
  109. package/src/primitives/messagePart/useMessagePartData.tsx +23 -0
  110. package/src/types/AssistantTypes.ts +2 -0
  111. package/src/types/MessagePartTypes.ts +8 -1
  112. package/src/types/index.ts +1 -0
  113. package/dist/client/ToolUIClient.d.ts +0 -7
  114. package/dist/client/ToolUIClient.d.ts.map +0 -1
  115. package/dist/client/ToolUIClient.js +0 -71
  116. package/dist/client/ToolUIClient.js.map +0 -1
  117. package/dist/client/ToolUIContext.d.ts +0 -4
  118. package/dist/client/ToolUIContext.d.ts.map +0 -1
  119. package/dist/client/ToolUIContext.js +0 -20
  120. package/dist/client/ToolUIContext.js.map +0 -1
  121. package/dist/client/types/ToolUI.d.ts +0 -23
  122. package/dist/client/types/ToolUI.d.ts.map +0 -1
  123. package/dist/client/types/ToolUI.js +0 -1
  124. package/dist/client/types/ToolUI.js.map +0 -1
  125. package/src/client/ToolUIClient.ts +0 -76
  126. package/src/client/ToolUIContext.ts +0 -22
  127. package/src/client/types/ToolUI.ts +0 -27
@@ -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 =\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":";;;AAEA;AAAA,EAGE;AAAA,EAEA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,gCAAgC;AACzC,SAAS,iCAAiC;AAY1C,SAAS,sCAAsC;AAyMtC,SAsOA,UAtOA,KAKL,YALK;AA1LT,IAAM,8BAAgD,CACpD,UACuB;AAEvB,QAAM,WAAW,oBAAI,IAAsB;AAG3C,WAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACrC,UAAM,OAAO,MAAM,CAAC;AACpB,UAAM,WAAW,MAAM;AAGvB,UAAM,UAAU,YAAY,eAAe,CAAC;AAG5C,UAAM,UAAU,SAAS,IAAI,OAAO,KAAK,CAAC;AAC1C,YAAQ,KAAK,CAAC;AACd,aAAS,IAAI,SAAS,OAAO;AAAA,EAC/B;AAGA,QAAM,SAA6B,CAAC;AACpC,aAAW,CAAC,SAAS,OAAO,KAAK,UAAU;AAEzC,UAAM,WAAW,QAAQ,WAAW,cAAc,IAAI,SAAY;AAClE,WAAO,KAAK,EAAE,UAAU,QAAQ,CAAC;AAAA,EACnC;AAEA,SAAO;AACT;AAEA,IAAM,yBAAyB,CAC7B,qBACuB;AACvB,QAAM,QAAQ,kBAAkB,CAAC,EAAE,QAAQ,MAAM,QAAQ,KAAK;AAE9D,SAAO,QAAQ,MAAM;AACnB,QAAI,MAAM,WAAW,GAAG;AACtB,aAAO,CAAC;AAAA,IACV;AACA,WAAO,iBAAiB,KAAK;AAAA,EAC/B,GAAG,CAAC,OAAO,gBAAgB,CAAC;AAC9B;AAmIA,IAAM,gBAAgB,CAAC;AAAA,EACrB;AAAA,EACA,GAAG;AACL,MAEiC;AAC/B,QAAM,SAAS,kBAAkB,CAAC,EAAE,QAAQ,MAAM;AAChD,UAAMA,UACJ,QAAQ,MAAM,MAAM,QAAQ,KAAK,QAAQ,YAAY;AACvD,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,OAAO,CAAC,EAAE,SAAS,MAAM;AAC3B;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,CAAC,WAAgB,IAAI,KAAK,EAAE,cAAc,MAAM;AAClE,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;AAEH,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;AACE,YAAM,gBAAuB;AAC7B,YAAM,IAAI,MAAM,8BAA8B,aAAa,EAAE;AAAA,EACjE;AACF;AAOA,IAAM,kBAAwC,CAAC,EAAE,WAAW,WAAW,MAAM;AAC3E,SACE,oBAAC,uBAAoB,OAAO,WAC1B,8BAAC,wBAAqB,YAAwB,GAChD;AAEJ;AAEA,IAAM,cAAc;AAAA,EAClB;AAAA,EACA,CAAC,MAAM,SACL,KAAK,cAAc,KAAK,aACxB,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,UAAU,KAAK,YAAY;AAChD;AAEA,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;AAkDO,IAAM,wCAET,CAAC,EAAE,kBAAkB,WAAW,MAAM;AACxC,QAAM,gBAAgB;AAAA,IACpB,CAAC,EAAE,QAAQ,MAAM,QAAQ,MAAM;AAAA,EACjC;AACA,QAAM,gBAAgB,uBAAuB,gBAAgB;AAE7D,QAAM,gBAAgB,QAAQ,MAAM;AAClC,QAAI,kBAAkB,GAAG;AACvB,aAAO,oBAAC,cAAW,YAAwB;AAAA,IAC7C;AAEA,WAAO,cAAc,IAAI,CAAC,OAAO,eAAe;AAC9C,YAAM,iBAAiB,YAAY,SAAS,kBAAkB;AAE9D,aACE;AAAA,QAAC;AAAA;AAAA,UAEC,UAAU,MAAM;AAAA,UAChB,SAAS,MAAM;AAAA,UAEd,gBAAM,QAAQ,IAAI,CAAC,cAClB;AAAA,YAAC;AAAA;AAAA,cAEC;AAAA,cACA;AAAA;AAAA,YAFK;AAAA,UAGP,CACD;AAAA;AAAA,QAVI,SAAS,UAAU,IAAI,MAAM,YAAY,WAAW;AAAA,MAW3D;AAAA,IAEJ,CAAC;AAAA,EACH,GAAG,CAAC,eAAe,YAAY,aAAa,CAAC;AAE7C,SAAO,gCAAG,yBAAc;AAC1B;AAEA,sCAAsC,cACpC;AAQK,IAAM,kDAET,CAAC,EAAE,YAAY,GAAG,MAAM,MAAM;AAChC,SACE;AAAA,IAAC;AAAA;AAAA,MACE,GAAG;AAAA,MACJ;AAAA,MACA,kBAAkB;AAAA;AAAA,EACpB;AAEJ;AAEA,gDAAgD,cAC9C;","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(({ 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 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 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\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"]}
@@ -0,0 +1,3 @@
1
+ import { DataMessagePart } from "../../types";
2
+ export declare const useMessagePartData: <T = any>(name?: string) => DataMessagePart<T> | null;
3
+ //# sourceMappingURL=useMessagePartData.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useMessagePartData.d.ts","sourceRoot":"","sources":["../../../src/primitives/messagePart/useMessagePartData.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,eAAO,MAAM,kBAAkB,GAAI,CAAC,GAAG,GAAG,EAAG,OAAO,MAAM,8BAiBzD,CAAC"}
@@ -0,0 +1,23 @@
1
+ "use client";
2
+
3
+ // src/primitives/messagePart/useMessagePartData.tsx
4
+ import { useAssistantState } from "../../context/index.js";
5
+ var useMessagePartData = (name) => {
6
+ const part = useAssistantState(({ part: part2 }) => {
7
+ if (part2.type !== "data") {
8
+ return null;
9
+ }
10
+ return part2;
11
+ });
12
+ if (!part) {
13
+ return null;
14
+ }
15
+ if (name && part.name !== name) {
16
+ return null;
17
+ }
18
+ return part;
19
+ };
20
+ export {
21
+ useMessagePartData
22
+ };
23
+ //# sourceMappingURL=useMessagePartData.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/primitives/messagePart/useMessagePartData.tsx"],"sourcesContent":["\"use client\";\n\nimport { useAssistantState } from \"../../context\";\nimport { DataMessagePart } from \"../../types\";\n\nexport const useMessagePartData = <T = any,>(name?: string) => {\n const part = useAssistantState(({ part }) => {\n if (part.type !== \"data\") {\n return null;\n }\n return part as DataMessagePart<T>;\n });\n\n if (!part) {\n return null;\n }\n\n if (name && part.name !== name) {\n return null;\n }\n\n return part;\n};\n"],"mappings":";;;AAEA,SAAS,yBAAyB;AAG3B,IAAM,qBAAqB,CAAW,SAAkB;AAC7D,QAAM,OAAO,kBAAkB,CAAC,EAAE,MAAAA,MAAK,MAAM;AAC3C,QAAIA,MAAK,SAAS,QAAQ;AACxB,aAAO;AAAA,IACT;AACA,WAAOA;AAAA,EACT,CAAC;AAED,MAAI,CAAC,MAAM;AACT,WAAO;AAAA,EACT;AAEA,MAAI,QAAQ,KAAK,SAAS,MAAM;AAC9B,WAAO;AAAA,EACT;AAEA,SAAO;AACT;","names":["part"]}
@@ -1,9 +1,9 @@
1
- // ../../node_modules/.pnpm/vitest@4.0.8_@types+debug@4.1.12_@types+node@24.10.1_@vitest+ui@4.0.8_jiti@2.6.1_jsdom@_c97fdea49f1663602bf3dfb16acdd85d/node_modules/vitest/dist/chunks/vi.Bgcdy3bQ.js
1
+ // ../../node_modules/.pnpm/vitest@4.0.10_@types+debug@4.1.12_@types+node@24.10.1_@vitest+ui@4.0.10_jiti@2.6.1_jsdo_8129e2874895056f7089688a9cfd0bc1/node_modules/vitest/dist/chunks/vi.BiaV1qII.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.8_@types+debug@4.1.12_@types+node@24.10.1_@vitest+ui@4.0.8_jiti@2.6.1_jsdom@_c97fdea49f1663602bf3dfb16acdd85d/node_modules/vitest/dist/chunks/utils.DvEY5TfP.js
6
+ // ../../node_modules/.pnpm/vitest@4.0.10_@types+debug@4.1.12_@types+node@24.10.1_@vitest+ui@4.0.10_jiti@2.6.1_jsdo_8129e2874895056f7089688a9cfd0bc1/node_modules/vitest/dist/chunks/utils.DvEY5TfP.js
7
7
  import { getSafeTimers } from "@vitest/utils/timers.js";
8
8
  var NAME_WORKER_STATE = "__vitest_worker__";
9
9
  function getWorkerState() {
@@ -44,7 +44,7 @@ async function waitForImportsToResolve() {
44
44
  await waitForImportsToResolve();
45
45
  }
46
46
 
47
- // ../../node_modules/.pnpm/vitest@4.0.8_@types+debug@4.1.12_@types+node@24.10.1_@vitest+ui@4.0.8_jiti@2.6.1_jsdom@_c97fdea49f1663602bf3dfb16acdd85d/node_modules/vitest/dist/chunks/vi.Bgcdy3bQ.js
47
+ // ../../node_modules/.pnpm/vitest@4.0.10_@types+debug@4.1.12_@types+node@24.10.1_@vitest+ui@4.0.10_jiti@2.6.1_jsdo_8129e2874895056f7089688a9cfd0bc1/node_modules/vitest/dist/chunks/vi.BiaV1qII.js
48
48
  import { getSafeTimers as getSafeTimers2 } from "@vitest/utils/timers.js";
49
49
  import { stripSnapshotIndentation, addSerializer, SnapshotClient } from "@vitest/snapshot.js";
50
50
  import "@vitest/utils/error.js";
@@ -53,10 +53,10 @@ import { fn, spyOn, restoreAllMocks, resetAllMocks, clearAllMocks, isMockFunctio
53
53
  import "@vitest/utils/offset.js";
54
54
  import { parseSingleStack } from "@vitest/utils/source-map.js";
55
55
 
56
- // ../../node_modules/.pnpm/vitest@4.0.8_@types+debug@4.1.12_@types+node@24.10.1_@vitest+ui@4.0.8_jiti@2.6.1_jsdom@_c97fdea49f1663602bf3dfb16acdd85d/node_modules/vitest/dist/chunks/_commonjsHelpers.BFTU3MAI.js
56
+ // ../../node_modules/.pnpm/vitest@4.0.10_@types+debug@4.1.12_@types+node@24.10.1_@vitest+ui@4.0.10_jiti@2.6.1_jsdo_8129e2874895056f7089688a9cfd0bc1/node_modules/vitest/dist/chunks/_commonjsHelpers.D26ty3Ew.js
57
57
  var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {};
58
58
 
59
- // ../../node_modules/.pnpm/vitest@4.0.8_@types+debug@4.1.12_@types+node@24.10.1_@vitest+ui@4.0.8_jiti@2.6.1_jsdom@_c97fdea49f1663602bf3dfb16acdd85d/node_modules/vitest/dist/chunks/date.Bq6ZW5rf.js
59
+ // ../../node_modules/.pnpm/vitest@4.0.10_@types+debug@4.1.12_@types+node@24.10.1_@vitest+ui@4.0.10_jiti@2.6.1_jsdo_8129e2874895056f7089688a9cfd0bc1/node_modules/vitest/dist/chunks/date.Bq6ZW5rf.js
60
60
  var RealDate = Date;
61
61
  var now = null;
62
62
  var MockDate = class _MockDate extends RealDate {
@@ -104,7 +104,7 @@ function resetDate() {
104
104
  globalThis.Date = RealDate;
105
105
  }
106
106
 
107
- // ../../node_modules/.pnpm/vitest@4.0.8_@types+debug@4.1.12_@types+node@24.10.1_@vitest+ui@4.0.8_jiti@2.6.1_jsdom@_c97fdea49f1663602bf3dfb16acdd85d/node_modules/vitest/dist/chunks/vi.Bgcdy3bQ.js
107
+ // ../../node_modules/.pnpm/vitest@4.0.10_@types+debug@4.1.12_@types+node@24.10.1_@vitest+ui@4.0.10_jiti@2.6.1_jsdo_8129e2874895056f7089688a9cfd0bc1/node_modules/vitest/dist/chunks/vi.BiaV1qII.js
108
108
  var unsupported = [
109
109
  "matchSnapshot",
110
110
  "toMatchSnapshot",
@@ -562,10 +562,10 @@ var hasRequiredDeprecated;
562
562
  function requireDeprecated() {
563
563
  if (hasRequiredDeprecated) return deprecated;
564
564
  hasRequiredDeprecated = 1;
565
- (function(exports) {
566
- exports.wrap = function(func, msg) {
565
+ (function(exports$1) {
566
+ exports$1.wrap = function(func, msg) {
567
567
  var wrapped = function() {
568
- exports.printWarning(msg);
568
+ exports$1.printWarning(msg);
569
569
  return func.apply(this, arguments);
570
570
  };
571
571
  if (func.prototype) {
@@ -573,10 +573,10 @@ function requireDeprecated() {
573
573
  }
574
574
  return wrapped;
575
575
  };
576
- exports.defaultMsg = function(packageName, funcName) {
576
+ exports$1.defaultMsg = function(packageName, funcName) {
577
577
  return `${packageName}.${funcName} is deprecated and will be removed from the public API in a future version of ${packageName}.`;
578
578
  };
579
- exports.printWarning = function(msg) {
579
+ exports$1.printWarning = function(msg) {
580
580
  if (typeof process === "object" && process.emitWarning) {
581
581
  process.emitWarning(msg);
582
582
  } else if (console.info) {
@@ -715,7 +715,7 @@ var hasRequiredTypeDetect;
715
715
  function requireTypeDetect() {
716
716
  if (hasRequiredTypeDetect) return typeDetect$1.exports;
717
717
  hasRequiredTypeDetect = 1;
718
- (function(module, exports) {
718
+ (function(module, exports$1) {
719
719
  (function(global3, factory) {
720
720
  module.exports = factory();
721
721
  })(typeDetect, (function() {
@@ -2692,11 +2692,11 @@ function _mocker() {
2692
2692
  function getImporter(name) {
2693
2693
  const stackArray = createSimpleStackTrace({ stackTraceLimit: 5 }).split("\n");
2694
2694
  return parseSingleStack(stackArray[stackArray.findLastIndex((stack) => {
2695
- return stack.includes(` at Object.${name}`) || stack.includes(`${name}@`);
2695
+ return stack.includes(` at Object.${name}`) || stack.includes(`${name}@`) || stack.includes(` at ${name} (`);
2696
2696
  }) + 1])?.file || "";
2697
2697
  }
2698
2698
 
2699
- // ../../node_modules/.pnpm/vitest@4.0.8_@types+debug@4.1.12_@types+node@24.10.1_@vitest+ui@4.0.8_jiti@2.6.1_jsdom@_c97fdea49f1663602bf3dfb16acdd85d/node_modules/vitest/dist/index.js
2699
+ // ../../node_modules/.pnpm/vitest@4.0.10_@types+debug@4.1.12_@types+node@24.10.1_@vitest+ui@4.0.10_jiti@2.6.1_jsdo_8129e2874895056f7089688a9cfd0bc1/node_modules/vitest/dist/index.js
2700
2700
  import { expectTypeOf } from "expect-type.js";
2701
2701
  import { afterAll, afterEach, beforeAll, beforeEach, describe, it, onTestFailed, onTestFinished, suite, test } from "@vitest/runner.js";
2702
2702
  import { chai as chai2 } from "@vitest/expect.js";