@assistant-ui/core 0.2.5 → 0.2.6

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 (91) hide show
  1. package/dist/index.d.ts +2 -2
  2. package/dist/react/index.d.ts +2 -1
  3. package/dist/react/index.js +2 -1
  4. package/dist/react/primitives/message/MessageGroupedParts.d.ts +25 -21
  5. package/dist/react/primitives/message/MessageGroupedParts.d.ts.map +1 -1
  6. package/dist/react/primitives/message/MessageGroupedParts.js +6 -7
  7. package/dist/react/primitives/message/MessageGroupedParts.js.map +1 -1
  8. package/dist/react/primitives/message/MessageParts.d.ts +2 -1
  9. package/dist/react/primitives/message/MessageParts.d.ts.map +1 -1
  10. package/dist/react/primitives/message/MessageParts.js +9 -4
  11. package/dist/react/primitives/message/MessageParts.js.map +1 -1
  12. package/dist/react/providers/TextMessagePartProvider.d.ts.map +1 -1
  13. package/dist/react/providers/TextMessagePartProvider.js +3 -0
  14. package/dist/react/providers/TextMessagePartProvider.js.map +1 -1
  15. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts +3 -1
  16. package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
  17. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +3 -1
  18. package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
  19. package/dist/react/runtimes/external-message-converter.d.ts.map +1 -1
  20. package/dist/react/runtimes/external-message-converter.js +7 -3
  21. package/dist/react/runtimes/external-message-converter.js.map +1 -1
  22. package/dist/react/types/MessagePartComponentTypes.d.ts +8 -0
  23. package/dist/react/types/MessagePartComponentTypes.d.ts.map +1 -1
  24. package/dist/react/utils/groupParts.d.ts +40 -12
  25. package/dist/react/utils/groupParts.d.ts.map +1 -1
  26. package/dist/react/utils/groupParts.js +51 -9
  27. package/dist/react/utils/groupParts.js.map +1 -1
  28. package/dist/runtime/api/message-part-runtime.d.ts +8 -0
  29. package/dist/runtime/api/message-part-runtime.d.ts.map +1 -1
  30. package/dist/runtime/api/message-part-runtime.js +13 -0
  31. package/dist/runtime/api/message-part-runtime.js.map +1 -1
  32. package/dist/runtime/api/thread-runtime.d.ts +2 -1
  33. package/dist/runtime/api/thread-runtime.d.ts.map +1 -1
  34. package/dist/runtime/base/base-thread-runtime-core.d.ts +2 -1
  35. package/dist/runtime/base/base-thread-runtime-core.d.ts.map +1 -1
  36. package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
  37. package/dist/runtime/interfaces/thread-runtime-core.d.ts +7 -1
  38. package/dist/runtime/interfaces/thread-runtime-core.d.ts.map +1 -1
  39. package/dist/runtime/utils/thread-message-like.d.ts +10 -0
  40. package/dist/runtime/utils/thread-message-like.d.ts.map +1 -1
  41. package/dist/runtime/utils/thread-message-like.js.map +1 -1
  42. package/dist/runtimes/external-store/external-store-adapter.d.ts +2 -1
  43. package/dist/runtimes/external-store/external-store-adapter.d.ts.map +1 -1
  44. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts +2 -1
  45. package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
  46. package/dist/runtimes/external-store/external-store-thread-runtime-core.js +4 -0
  47. package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
  48. package/dist/runtimes/local/local-thread-runtime-core.d.ts +2 -1
  49. package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
  50. package/dist/runtimes/local/local-thread-runtime-core.js +3 -0
  51. package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
  52. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts +1 -0
  53. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts.map +1 -1
  54. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js +3 -0
  55. package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js.map +1 -1
  56. package/dist/runtimes/remote-thread-list/empty-thread-core.d.ts.map +1 -1
  57. package/dist/runtimes/remote-thread-list/empty-thread-core.js +3 -0
  58. package/dist/runtimes/remote-thread-list/empty-thread-core.js.map +1 -1
  59. package/dist/store/clients/thread-message-client.d.ts.map +1 -1
  60. package/dist/store/clients/thread-message-client.js +3 -0
  61. package/dist/store/clients/thread-message-client.js.map +1 -1
  62. package/dist/store/runtime-clients/message-part-runtime-client.js +1 -0
  63. package/dist/store/runtime-clients/message-part-runtime-client.js.map +1 -1
  64. package/dist/store/scopes/part.d.ts +7 -0
  65. package/dist/store/scopes/part.d.ts.map +1 -1
  66. package/dist/types/message.d.ts +6 -0
  67. package/dist/types/message.d.ts.map +1 -1
  68. package/dist/types/message.js.map +1 -1
  69. package/package.json +2 -2
  70. package/src/index.ts +1 -0
  71. package/src/react/index.ts +1 -0
  72. package/src/react/primitives/message/MessageGroupedParts.tsx +38 -31
  73. package/src/react/primitives/message/MessageParts.tsx +14 -1
  74. package/src/react/providers/TextMessagePartProvider.tsx +3 -0
  75. package/src/react/runtimes/external-message-converter.ts +25 -12
  76. package/src/react/types/MessagePartComponentTypes.ts +8 -0
  77. package/src/react/utils/groupParts.ts +67 -22
  78. package/src/runtime/api/message-part-runtime.ts +26 -0
  79. package/src/runtime/base/base-thread-runtime-core.ts +4 -0
  80. package/src/runtime/interfaces/thread-runtime-core.ts +7 -0
  81. package/src/runtime/utils/thread-message-like.ts +7 -0
  82. package/src/runtimes/external-store/external-store-adapter.ts +4 -0
  83. package/src/runtimes/external-store/external-store-thread-runtime-core.ts +7 -0
  84. package/src/runtimes/local/local-thread-runtime-core.ts +5 -0
  85. package/src/runtimes/readonly/ReadonlyThreadRuntimeCore.ts +4 -0
  86. package/src/runtimes/remote-thread-list/empty-thread-core.ts +4 -0
  87. package/src/store/clients/thread-message-client.ts +3 -0
  88. package/src/store/runtime-clients/message-part-runtime-client.ts +2 -0
  89. package/src/store/scopes/part.ts +4 -0
  90. package/src/tests/groupParts.test.ts +118 -32
  91. package/src/types/message.ts +7 -0
package/dist/index.d.ts CHANGED
@@ -14,7 +14,7 @@ import { ThreadMessageLike } from "./runtime/utils/thread-message-like.js";
14
14
  import { ExportedMessageRepository, ExportedMessageRepositoryItem } from "./runtime/utils/message-repository.js";
15
15
  import { QuoteInfo } from "./types/quote.js";
16
16
  import { AttachmentAddErrorEvent, AttachmentAddErrorReason, ComposerRuntimeCore, ComposerRuntimeEventCallback, ComposerRuntimeEventPayload, ComposerRuntimeEventType, DictationState, EditComposerRuntimeCore, SendOptions, ThreadComposerRuntimeCore } from "./runtime/interfaces/composer-runtime-core.js";
17
- import { AddToolResultOptions, ResumeRunConfig, ResumeToolCallOptions, RuntimeCapabilities, SpeechState, StartRunConfig, SubmitFeedbackOptions, SubmittedFeedback, ThreadRuntimeCore, ThreadRuntimeEventCallback, ThreadRuntimeEventPayload, ThreadRuntimeEventType, ThreadSuggestion, VoiceSessionState } from "./runtime/interfaces/thread-runtime-core.js";
17
+ import { AddToolResultOptions, RespondToToolApprovalOptions, ResumeRunConfig, ResumeToolCallOptions, RuntimeCapabilities, SpeechState, StartRunConfig, SubmitFeedbackOptions, SubmittedFeedback, ThreadRuntimeCore, ThreadRuntimeEventCallback, ThreadRuntimeEventPayload, ThreadRuntimeEventType, ThreadSuggestion, VoiceSessionState } from "./runtime/interfaces/thread-runtime-core.js";
18
18
  import { SuggestionAdapter } from "./adapters/suggestion.js";
19
19
  import { Unstable_TriggerAdapter } from "./adapters/trigger.js";
20
20
  import { GenericThreadHistoryAdapter, MessageFormatAdapter, MessageFormatItem, MessageFormatRepository, MessageStorageEntry, ThreadHistoryAdapter } from "./adapters/thread-history.js";
@@ -42,4 +42,4 @@ import { CreateAppendMessage, CreateResumeRunConfig, CreateStartRunConfig, Threa
42
42
  import { AssistantRuntime } from "./runtime/api/assistant-runtime.js";
43
43
  import { InMemoryThreadListAdapter } from "./runtimes/remote-thread-list/adapter/in-memory.js";
44
44
  import { createRequestHeaders } from "./runtimes/assistant-transport/utils.js";
45
- export { type AddToolResultOptions, type AppendMessage, type AssistantContextConfig, AssistantFrameHost, AssistantFrameProvider, type AssistantInstructionsConfig, type AssistantRuntime, type AssistantRuntimeCore, type AssistantToolProps, type Attachment, type AttachmentAdapter, type AttachmentAddErrorEvent, type AttachmentAddErrorReason, type AttachmentRuntime, type AttachmentRuntimePath, type AttachmentState, type AttachmentStatus, type ChatModelAdapter, type ChatModelRunOptions, type ChatModelRunResult, type ChatModelRunUpdate, type CompleteAttachment, type CompleteAttachmentStatus, type ComposerRuntime, type ComposerRuntimeCore, type ComposerRuntimeEventCallback, type ComposerRuntimeEventPayload, type ComposerRuntimeEventType, type ComposerRuntimePath, type ComposerState, CompositeAttachmentAdapter, type CoreChatModelRunResult, type CreateAppendMessage, type CreateAttachment, type CreateResumeRunConfig, type CreateStartRunConfig, type DataMessagePart, type DictationAdapter, type DictationState, type EditComposerRuntime, type EditComposerRuntimeCore, type EditComposerState, ExportedMessageRepository, type ExportedMessageRepositoryItem, type ExternalStoreAdapter, type ExternalStoreMessageConverter, type ExternalStoreThreadData, type ExternalStoreThreadListAdapter, FRAME_MESSAGE_CHANNEL, type FeedbackAdapter, type FileMessagePart, type FrameMessage, type FrameMessageType, type GenerativeUIMessagePart, type GenerativeUINode, type GenerativeUISpec, type GenericThreadHistoryAdapter, type ImageMessagePart, InMemoryThreadListAdapter, type LanguageModelConfig, type LanguageModelV1CallSettings, type LocalRuntimeOptionsBase, MCP_APP_URI_SCHEME, type McpAppMetadata, type MessageFormatAdapter, type MessageFormatItem, type MessageFormatRepository, type MessagePartRuntime, type MessagePartRuntimePath, type MessagePartState, type MessagePartStatus, type MessageRole, type MessageRuntime, type MessageRuntimePath, type MessageState, type MessageStatus, type MessageStorageEntry, type MessageTiming, type ModelContext, type ModelContextProvider, ModelContextRegistry, type ModelContextRegistryInstructionHandle, type ModelContextRegistryProviderHandle, type ModelContextRegistryToolHandle, type PendingAttachment, type PendingAttachmentStatus, type QuoteInfo, type RealtimeVoiceAdapter, type ReasoningMessagePart, type RemoteThreadInitializeResponse, type RemoteThreadListAdapter, type RemoteThreadListOptions, type RemoteThreadListPageOptions, type RemoteThreadListResponse, type RemoteThreadMetadata, type ResumeRunConfig, type ResumeToolCallOptions, type RunConfig, type RuntimeCapabilities, type SendOptions, type SerializedModelContext, type SerializedTool, SimpleImageAttachmentAdapter, SimpleTextAttachmentAdapter, type SourceMessagePart, type SourceProviderMetadata, type SpeechState, type SpeechSynthesisAdapter, type StartRunConfig, type SubmitFeedbackOptions, type SubmittedFeedback, type SuggestionAdapter, type TextMessagePart, type ThreadAssistantMessage, type ThreadAssistantMessagePart, type ThreadComposerRuntime, type ThreadComposerRuntimeCore, type ThreadComposerState, type ThreadHistoryAdapter, type ThreadListItemCoreState, type ThreadListItemEventCallback, type ThreadListItemEventPayload, type ThreadListItemEventType, type ThreadListItemRuntime, type ThreadListItemRuntimePath, type ThreadListItemState, type ThreadListItemStatus, type ThreadListRuntime, type ThreadListRuntimeCore, type ThreadListState, type ThreadMessage, type ThreadMessageLike, type ThreadRuntime, type ThreadRuntimeCore, type ThreadRuntimeEventCallback, type ThreadRuntimeEventPayload, type ThreadRuntimeEventType, type ThreadRuntimePath, type ThreadState, type ThreadStep, type ThreadSuggestion, type ThreadSystemMessage, type ThreadUserMessage, type ThreadUserMessagePart, type ToolCallMessagePart, type ToolCallMessagePartMcpMetadata, type ToolCallMessagePartStatus, type ToolModelContentPart, type Unstable_AudioMessagePart, type Unstable_DirectiveFormatter, type Unstable_DirectiveSegment, type Unstable_TriggerAdapter, type Unstable_TriggerCategory, type Unstable_TriggerItem, type Unsubscribe, type VoiceSessionControls, type VoiceSessionHelpers, type VoiceSessionState, WebSpeechDictationAdapter, WebSpeechSynthesisAdapter, bindExternalStoreMessage, createRequestHeaders, createVoiceSession, getExternalStoreMessages, isMcpAppUri, mergeModelContexts, tool, unstable_defaultDirectiveFormatter };
45
+ export { type AddToolResultOptions, type AppendMessage, type AssistantContextConfig, AssistantFrameHost, AssistantFrameProvider, type AssistantInstructionsConfig, type AssistantRuntime, type AssistantRuntimeCore, type AssistantToolProps, type Attachment, type AttachmentAdapter, type AttachmentAddErrorEvent, type AttachmentAddErrorReason, type AttachmentRuntime, type AttachmentRuntimePath, type AttachmentState, type AttachmentStatus, type ChatModelAdapter, type ChatModelRunOptions, type ChatModelRunResult, type ChatModelRunUpdate, type CompleteAttachment, type CompleteAttachmentStatus, type ComposerRuntime, type ComposerRuntimeCore, type ComposerRuntimeEventCallback, type ComposerRuntimeEventPayload, type ComposerRuntimeEventType, type ComposerRuntimePath, type ComposerState, CompositeAttachmentAdapter, type CoreChatModelRunResult, type CreateAppendMessage, type CreateAttachment, type CreateResumeRunConfig, type CreateStartRunConfig, type DataMessagePart, type DictationAdapter, type DictationState, type EditComposerRuntime, type EditComposerRuntimeCore, type EditComposerState, ExportedMessageRepository, type ExportedMessageRepositoryItem, type ExternalStoreAdapter, type ExternalStoreMessageConverter, type ExternalStoreThreadData, type ExternalStoreThreadListAdapter, FRAME_MESSAGE_CHANNEL, type FeedbackAdapter, type FileMessagePart, type FrameMessage, type FrameMessageType, type GenerativeUIMessagePart, type GenerativeUINode, type GenerativeUISpec, type GenericThreadHistoryAdapter, type ImageMessagePart, InMemoryThreadListAdapter, type LanguageModelConfig, type LanguageModelV1CallSettings, type LocalRuntimeOptionsBase, MCP_APP_URI_SCHEME, type McpAppMetadata, type MessageFormatAdapter, type MessageFormatItem, type MessageFormatRepository, type MessagePartRuntime, type MessagePartRuntimePath, type MessagePartState, type MessagePartStatus, type MessageRole, type MessageRuntime, type MessageRuntimePath, type MessageState, type MessageStatus, type MessageStorageEntry, type MessageTiming, type ModelContext, type ModelContextProvider, ModelContextRegistry, type ModelContextRegistryInstructionHandle, type ModelContextRegistryProviderHandle, type ModelContextRegistryToolHandle, type PendingAttachment, type PendingAttachmentStatus, type QuoteInfo, type RealtimeVoiceAdapter, type ReasoningMessagePart, type RemoteThreadInitializeResponse, type RemoteThreadListAdapter, type RemoteThreadListOptions, type RemoteThreadListPageOptions, type RemoteThreadListResponse, type RemoteThreadMetadata, type RespondToToolApprovalOptions, type ResumeRunConfig, type ResumeToolCallOptions, type RunConfig, type RuntimeCapabilities, type SendOptions, type SerializedModelContext, type SerializedTool, SimpleImageAttachmentAdapter, SimpleTextAttachmentAdapter, type SourceMessagePart, type SourceProviderMetadata, type SpeechState, type SpeechSynthesisAdapter, type StartRunConfig, type SubmitFeedbackOptions, type SubmittedFeedback, type SuggestionAdapter, type TextMessagePart, type ThreadAssistantMessage, type ThreadAssistantMessagePart, type ThreadComposerRuntime, type ThreadComposerRuntimeCore, type ThreadComposerState, type ThreadHistoryAdapter, type ThreadListItemCoreState, type ThreadListItemEventCallback, type ThreadListItemEventPayload, type ThreadListItemEventType, type ThreadListItemRuntime, type ThreadListItemRuntimePath, type ThreadListItemState, type ThreadListItemStatus, type ThreadListRuntime, type ThreadListRuntimeCore, type ThreadListState, type ThreadMessage, type ThreadMessageLike, type ThreadRuntime, type ThreadRuntimeCore, type ThreadRuntimeEventCallback, type ThreadRuntimeEventPayload, type ThreadRuntimeEventType, type ThreadRuntimePath, type ThreadState, type ThreadStep, type ThreadSuggestion, type ThreadSystemMessage, type ThreadUserMessage, type ThreadUserMessagePart, type ToolCallMessagePart, type ToolCallMessagePartMcpMetadata, type ToolCallMessagePartStatus, type ToolModelContentPart, type Unstable_AudioMessagePart, type Unstable_DirectiveFormatter, type Unstable_DirectiveSegment, type Unstable_TriggerAdapter, type Unstable_TriggerCategory, type Unstable_TriggerItem, type Unsubscribe, type VoiceSessionControls, type VoiceSessionHelpers, type VoiceSessionState, WebSpeechDictationAdapter, WebSpeechSynthesisAdapter, bindExternalStoreMessage, createRequestHeaders, createVoiceSession, getExternalStoreMessages, isMcpAppUri, mergeModelContexts, tool, unstable_defaultDirectiveFormatter };
@@ -51,6 +51,7 @@ import { PartState } from "../store/scopes/part.js";
51
51
  import { ThreadPrimitiveMessageByIndex, ThreadPrimitiveMessages, ThreadPrimitiveMessagesImpl } from "./primitives/thread/ThreadMessages.js";
52
52
  import { EnrichedPartState, MessagePartComponent, MessagePrimitivePartByIndex, MessagePrimitiveParts, defaultComponents } from "./primitives/message/MessageParts.js";
53
53
  import { MessagePrimitiveGroupedParts } from "./primitives/message/MessageGroupedParts.js";
54
+ import { groupPartByType } from "./utils/groupParts.js";
54
55
  import { GenerativeUIRender, GenerativeUIRenderError, MessagePrimitiveGenerativeUI } from "./primitives/generativeUI/GenerativeUI.js";
55
56
  import { MessagePrimitiveQuote } from "./primitives/message/MessageQuote.js";
56
57
  import { MessagePrimitiveAttachmentByIndex, MessagePrimitiveAttachments } from "./primitives/message/MessageAttachments.js";
@@ -93,4 +94,4 @@ import { useEditComposerCancel } from "./primitive-hooks/useEditComposerCancel.j
93
94
  import { useEditComposerSend } from "./primitive-hooks/useEditComposerSend.js";
94
95
  import { useMessageError } from "./primitive-hooks/useMessageError.js";
95
96
  import { LocalRuntimeOptions, splitLocalRuntimeOptions, useLocalRuntime } from "./runtimes/useLocalRuntime.js";
96
- export { type AddToolResultCommand, type AssistantContextConfig, type AssistantDataUI, type AssistantDataUIProps, type AssistantInteractableProps, AssistantProviderBase, type AssistantProviderBaseProps, AssistantRuntimeProvider, type AssistantTool, type AssistantToolProps, type AssistantToolUI, type AssistantToolUIProps, type AssistantTransportState, type AsyncStorageLike, ChainOfThoughtByIndicesProvider, ChainOfThoughtPartByIndexProvider, ChainOfThoughtPrimitiveParts, CloudFileAttachmentAdapter, ComposerAttachmentByIndexProvider, ComposerPrimitiveAttachmentByIndex, ComposerPrimitiveAttachments, ComposerPrimitiveIf, ComposerPrimitiveQueue, type DataMessagePartComponent, type DataMessagePartProps, DataRenderers, type DataRenderersClientSchema, type DataRenderersMethods, type DataRenderersState, type EmptyMessagePartComponent, type EmptyMessagePartProps, type EnrichedPartState, type FileMessagePartComponent, type FileMessagePartProps, type GenerativeUIComponentRegistry, type GenerativeUIMessagePartComponent, type GenerativeUIMessagePartProps, GenerativeUIRender, GenerativeUIRenderError, type GenerativeUIRenderProps, type ImageMessagePartComponent, type ImageMessagePartProps, type InteractableDefinition, type InteractablePersistedState, type InteractablePersistenceAdapter, type InteractablePersistenceStatus, type InteractableRegistration, type InteractableStateSchema, Interactables, type InteractablesClientSchema, type InteractablesMethods, type InteractablesState, type LocalRuntimeOptions, type McpAppResourceOutput, MessageAttachmentByIndexProvider, MessageByIndexProvider, MessagePartComponent, MessagePartPrimitiveInProgress, MessagePrimitiveAttachmentByIndex, MessagePrimitiveAttachments, MessagePrimitiveGenerativeUI, MessagePrimitiveGroupedParts, MessagePrimitivePartByIndex, MessagePrimitiveParts, MessagePrimitiveQuote, PartByIndexProvider, PartPrimitiveMessages, PartPrimitiveMessagesImpl, type PartState, QueueItemByIndexProvider, type QueueItemByIndexProviderProps, type QuoteMessagePartComponent, type QuoteMessagePartProps, ReadonlyThreadProvider, type ReasoningGroupComponent, type ReasoningGroupProps, type ReasoningMessagePartComponent, type ReasoningMessagePartProps, RemoteThreadListHookInstanceManager, RemoteThreadListThreadListRuntimeCore, RuntimeAdapter, RuntimeAdapterProvider, type RuntimeAdapters, type SourceMessagePartComponent, type SourceMessagePartProps, SuggestionByIndexProvider, type SuggestionByIndexProviderProps, type TextMessagePartComponent, type TextMessagePartProps, TextMessagePartProvider, ThreadListItemByIndexProvider, ThreadListItemPrimitiveTitle, ThreadListItemRuntimeProvider, ThreadListPrimitiveItemByIndex, ThreadListPrimitiveItems, ThreadPrimitiveMessageByIndex, ThreadPrimitiveMessages, ThreadPrimitiveMessagesImpl, ThreadPrimitiveSuggestionByIndex, ThreadPrimitiveSuggestions, ThreadPrimitiveSuggestionsImpl, type TitleGenerationAdapter, type ToolArgsStatus, type ToolCallMessagePartComponent, type ToolCallMessagePartProps, type ToolDefinition, type ToolExecutionStatus, type Toolkit, Tools, type ToolsClientSchema, type ToolsMethods, type ToolsState, type Unstable_AudioMessagePartComponent, type Unstable_AudioMessagePartProps, type UseActionBarCopyOptions, type UseComposerIfProps, type UseSuggestionTriggerOptions, convertExternalMessages, createLocalStorageAdapter, createMessageConverter, createSimpleTitleAdapter, getMessageQuote, getRenderComponent, makeAssistantDataUI, makeAssistantTool, makeAssistantToolUI, defaultComponents as messagePartsDefaultComponents, splitLocalRuntimeOptions, useActionBarCopy, useActionBarEdit, useActionBarFeedbackNegative, useActionBarFeedbackPositive, useActionBarReload, useActionBarSpeak, useActionBarStopSpeaking, useAssistantCloudThreadHistoryAdapter, useAssistantContext, useAssistantDataUI, useAssistantInstructions, useAssistantInteractable, useAssistantTool, useAssistantToolUI, useBranchPickerNext, useBranchPickerPrevious, useCloudThreadListAdapter, useComposerAddAttachment, useComposerCancel, useComposerDictate, useComposerSend, useEditComposerCancel, useEditComposerSend, useExternalMessageConverter, useExternalStoreRuntime, useInlineRender, useInteractableState, useLocalRuntime, useMessageBranching, useMessageError, useMessageReload, useRemoteThreadListRuntime, useRuntimeAdapters, useSuggestionTrigger, useThreadIsEmpty, useThreadIsRunning, useThreadListItemArchive, useThreadListItemDelete, useThreadListItemTrigger, useThreadListItemUnarchive, useThreadListLoadMore, useThreadListNew, useThreadMessages, useToolArgsStatus, useToolInvocations, useVoiceControls, useVoiceState, useVoiceVolume };
97
+ export { type AddToolResultCommand, type AssistantContextConfig, type AssistantDataUI, type AssistantDataUIProps, type AssistantInteractableProps, AssistantProviderBase, type AssistantProviderBaseProps, AssistantRuntimeProvider, type AssistantTool, type AssistantToolProps, type AssistantToolUI, type AssistantToolUIProps, type AssistantTransportState, type AsyncStorageLike, ChainOfThoughtByIndicesProvider, ChainOfThoughtPartByIndexProvider, ChainOfThoughtPrimitiveParts, CloudFileAttachmentAdapter, ComposerAttachmentByIndexProvider, ComposerPrimitiveAttachmentByIndex, ComposerPrimitiveAttachments, ComposerPrimitiveIf, ComposerPrimitiveQueue, type DataMessagePartComponent, type DataMessagePartProps, DataRenderers, type DataRenderersClientSchema, type DataRenderersMethods, type DataRenderersState, type EmptyMessagePartComponent, type EmptyMessagePartProps, type EnrichedPartState, type FileMessagePartComponent, type FileMessagePartProps, type GenerativeUIComponentRegistry, type GenerativeUIMessagePartComponent, type GenerativeUIMessagePartProps, GenerativeUIRender, GenerativeUIRenderError, type GenerativeUIRenderProps, type ImageMessagePartComponent, type ImageMessagePartProps, type InteractableDefinition, type InteractablePersistedState, type InteractablePersistenceAdapter, type InteractablePersistenceStatus, type InteractableRegistration, type InteractableStateSchema, Interactables, type InteractablesClientSchema, type InteractablesMethods, type InteractablesState, type LocalRuntimeOptions, type McpAppResourceOutput, MessageAttachmentByIndexProvider, MessageByIndexProvider, MessagePartComponent, MessagePartPrimitiveInProgress, MessagePrimitiveAttachmentByIndex, MessagePrimitiveAttachments, MessagePrimitiveGenerativeUI, MessagePrimitiveGroupedParts, MessagePrimitivePartByIndex, MessagePrimitiveParts, MessagePrimitiveQuote, PartByIndexProvider, PartPrimitiveMessages, PartPrimitiveMessagesImpl, type PartState, QueueItemByIndexProvider, type QueueItemByIndexProviderProps, type QuoteMessagePartComponent, type QuoteMessagePartProps, ReadonlyThreadProvider, type ReasoningGroupComponent, type ReasoningGroupProps, type ReasoningMessagePartComponent, type ReasoningMessagePartProps, RemoteThreadListHookInstanceManager, RemoteThreadListThreadListRuntimeCore, RuntimeAdapter, RuntimeAdapterProvider, type RuntimeAdapters, type SourceMessagePartComponent, type SourceMessagePartProps, SuggestionByIndexProvider, type SuggestionByIndexProviderProps, type TextMessagePartComponent, type TextMessagePartProps, TextMessagePartProvider, ThreadListItemByIndexProvider, ThreadListItemPrimitiveTitle, ThreadListItemRuntimeProvider, ThreadListPrimitiveItemByIndex, ThreadListPrimitiveItems, ThreadPrimitiveMessageByIndex, ThreadPrimitiveMessages, ThreadPrimitiveMessagesImpl, ThreadPrimitiveSuggestionByIndex, ThreadPrimitiveSuggestions, ThreadPrimitiveSuggestionsImpl, type TitleGenerationAdapter, type ToolArgsStatus, type ToolCallMessagePartComponent, type ToolCallMessagePartProps, type ToolDefinition, type ToolExecutionStatus, type Toolkit, Tools, type ToolsClientSchema, type ToolsMethods, type ToolsState, type Unstable_AudioMessagePartComponent, type Unstable_AudioMessagePartProps, type UseActionBarCopyOptions, type UseComposerIfProps, type UseSuggestionTriggerOptions, convertExternalMessages, createLocalStorageAdapter, createMessageConverter, createSimpleTitleAdapter, getMessageQuote, getRenderComponent, groupPartByType, makeAssistantDataUI, makeAssistantTool, makeAssistantToolUI, defaultComponents as messagePartsDefaultComponents, splitLocalRuntimeOptions, useActionBarCopy, useActionBarEdit, useActionBarFeedbackNegative, useActionBarFeedbackPositive, useActionBarReload, useActionBarSpeak, useActionBarStopSpeaking, useAssistantCloudThreadHistoryAdapter, useAssistantContext, useAssistantDataUI, useAssistantInstructions, useAssistantInteractable, useAssistantTool, useAssistantToolUI, useBranchPickerNext, useBranchPickerPrevious, useCloudThreadListAdapter, useComposerAddAttachment, useComposerCancel, useComposerDictate, useComposerSend, useEditComposerCancel, useEditComposerSend, useExternalMessageConverter, useExternalStoreRuntime, useInlineRender, useInteractableState, useLocalRuntime, useMessageBranching, useMessageError, useMessageReload, useRemoteThreadListRuntime, useRuntimeAdapters, useSuggestionTrigger, useThreadIsEmpty, useThreadIsRunning, useThreadListItemArchive, useThreadListItemDelete, useThreadListItemTrigger, useThreadListItemUnarchive, useThreadListLoadMore, useThreadListNew, useThreadMessages, useToolArgsStatus, useToolInvocations, useVoiceControls, useVoiceState, useVoiceVolume };
@@ -44,6 +44,7 @@ import { ThreadPrimitiveMessageByIndex, ThreadPrimitiveMessages, ThreadPrimitive
44
44
  import { getMessageQuote } from "./utils/getMessageQuote.js";
45
45
  import { GenerativeUIRender, GenerativeUIRenderError, MessagePrimitiveGenerativeUI } from "./primitives/generativeUI/GenerativeUI.js";
46
46
  import { MessagePartComponent, MessagePrimitivePartByIndex, MessagePrimitiveParts, defaultComponents } from "./primitives/message/MessageParts.js";
47
+ import { groupPartByType } from "./utils/groupParts.js";
47
48
  import { MessagePrimitiveGroupedParts } from "./primitives/message/MessageGroupedParts.js";
48
49
  import { MessagePrimitiveQuote } from "./primitives/message/MessageQuote.js";
49
50
  import { MessagePrimitiveAttachmentByIndex, MessagePrimitiveAttachments } from "./primitives/message/MessageAttachments.js";
@@ -85,4 +86,4 @@ import { useEditComposerCancel } from "./primitive-hooks/useEditComposerCancel.j
85
86
  import { useEditComposerSend } from "./primitive-hooks/useEditComposerSend.js";
86
87
  import { useMessageError } from "./primitive-hooks/useMessageError.js";
87
88
  import { splitLocalRuntimeOptions, useLocalRuntime } from "./runtimes/useLocalRuntime.js";
88
- export { AssistantProviderBase, AssistantRuntimeProvider, ChainOfThoughtByIndicesProvider, ChainOfThoughtPartByIndexProvider, ChainOfThoughtPrimitiveParts, CloudFileAttachmentAdapter, ComposerAttachmentByIndexProvider, ComposerPrimitiveAttachmentByIndex, ComposerPrimitiveAttachments, ComposerPrimitiveIf, ComposerPrimitiveQueue, DataRenderers, GenerativeUIRender, GenerativeUIRenderError, Interactables, MessageAttachmentByIndexProvider, MessageByIndexProvider, MessagePartComponent, MessagePartPrimitiveInProgress, MessagePrimitiveAttachmentByIndex, MessagePrimitiveAttachments, MessagePrimitiveGenerativeUI, MessagePrimitiveGroupedParts, MessagePrimitivePartByIndex, MessagePrimitiveParts, MessagePrimitiveQuote, PartByIndexProvider, PartPrimitiveMessages, PartPrimitiveMessagesImpl, QueueItemByIndexProvider, ReadonlyThreadProvider, RemoteThreadListHookInstanceManager, RemoteThreadListThreadListRuntimeCore, RuntimeAdapter, RuntimeAdapterProvider, SuggestionByIndexProvider, TextMessagePartProvider, ThreadListItemByIndexProvider, ThreadListItemPrimitiveTitle, ThreadListItemRuntimeProvider, ThreadListPrimitiveItemByIndex, ThreadListPrimitiveItems, ThreadPrimitiveMessageByIndex, ThreadPrimitiveMessages, ThreadPrimitiveMessagesImpl, ThreadPrimitiveSuggestionByIndex, ThreadPrimitiveSuggestions, ThreadPrimitiveSuggestionsImpl, Tools, convertExternalMessages, createLocalStorageAdapter, createMessageConverter, createSimpleTitleAdapter, getMessageQuote, getRenderComponent, makeAssistantDataUI, makeAssistantTool, makeAssistantToolUI, defaultComponents as messagePartsDefaultComponents, splitLocalRuntimeOptions, useActionBarCopy, useActionBarEdit, useActionBarFeedbackNegative, useActionBarFeedbackPositive, useActionBarReload, useActionBarSpeak, useActionBarStopSpeaking, useAssistantCloudThreadHistoryAdapter, useAssistantContext, useAssistantDataUI, useAssistantInstructions, useAssistantInteractable, useAssistantTool, useAssistantToolUI, useBranchPickerNext, useBranchPickerPrevious, useCloudThreadListAdapter, useComposerAddAttachment, useComposerCancel, useComposerDictate, useComposerSend, useEditComposerCancel, useEditComposerSend, useExternalMessageConverter, useExternalStoreRuntime, useInlineRender, useInteractableState, useLocalRuntime, useMessageBranching, useMessageError, useMessageReload, useRemoteThreadListRuntime, useRuntimeAdapters, useSuggestionTrigger, useThreadIsEmpty, useThreadIsRunning, useThreadListItemArchive, useThreadListItemDelete, useThreadListItemTrigger, useThreadListItemUnarchive, useThreadListLoadMore, useThreadListNew, useThreadMessages, useToolArgsStatus, useToolInvocations, useVoiceControls, useVoiceState, useVoiceVolume };
89
+ export { AssistantProviderBase, AssistantRuntimeProvider, ChainOfThoughtByIndicesProvider, ChainOfThoughtPartByIndexProvider, ChainOfThoughtPrimitiveParts, CloudFileAttachmentAdapter, ComposerAttachmentByIndexProvider, ComposerPrimitiveAttachmentByIndex, ComposerPrimitiveAttachments, ComposerPrimitiveIf, ComposerPrimitiveQueue, DataRenderers, GenerativeUIRender, GenerativeUIRenderError, Interactables, MessageAttachmentByIndexProvider, MessageByIndexProvider, MessagePartComponent, MessagePartPrimitiveInProgress, MessagePrimitiveAttachmentByIndex, MessagePrimitiveAttachments, MessagePrimitiveGenerativeUI, MessagePrimitiveGroupedParts, MessagePrimitivePartByIndex, MessagePrimitiveParts, MessagePrimitiveQuote, PartByIndexProvider, PartPrimitiveMessages, PartPrimitiveMessagesImpl, QueueItemByIndexProvider, ReadonlyThreadProvider, RemoteThreadListHookInstanceManager, RemoteThreadListThreadListRuntimeCore, RuntimeAdapter, RuntimeAdapterProvider, SuggestionByIndexProvider, TextMessagePartProvider, ThreadListItemByIndexProvider, ThreadListItemPrimitiveTitle, ThreadListItemRuntimeProvider, ThreadListPrimitiveItemByIndex, ThreadListPrimitiveItems, ThreadPrimitiveMessageByIndex, ThreadPrimitiveMessages, ThreadPrimitiveMessagesImpl, ThreadPrimitiveSuggestionByIndex, ThreadPrimitiveSuggestions, ThreadPrimitiveSuggestionsImpl, Tools, convertExternalMessages, createLocalStorageAdapter, createMessageConverter, createSimpleTitleAdapter, getMessageQuote, getRenderComponent, groupPartByType, makeAssistantDataUI, makeAssistantTool, makeAssistantToolUI, defaultComponents as messagePartsDefaultComponents, splitLocalRuntimeOptions, useActionBarCopy, useActionBarEdit, useActionBarFeedbackNegative, useActionBarFeedbackPositive, useActionBarReload, useActionBarSpeak, useActionBarStopSpeaking, useAssistantCloudThreadHistoryAdapter, useAssistantContext, useAssistantDataUI, useAssistantInstructions, useAssistantInteractable, useAssistantTool, useAssistantToolUI, useBranchPickerNext, useBranchPickerPrevious, useCloudThreadListAdapter, useComposerAddAttachment, useComposerCancel, useComposerDictate, useComposerSend, useEditComposerCancel, useEditComposerSend, useExternalMessageConverter, useExternalStoreRuntime, useInlineRender, useInteractableState, useLocalRuntime, useMessageBranching, useMessageError, useMessageReload, useRemoteThreadListRuntime, useRuntimeAdapters, useSuggestionTrigger, useThreadIsEmpty, useThreadIsRunning, useThreadListItemArchive, useThreadListItemDelete, useThreadListItemTrigger, useThreadListItemUnarchive, useThreadListLoadMore, useThreadListNew, useThreadMessages, useToolArgsStatus, useToolInvocations, useVoiceControls, useVoiceState, useVoiceVolume };
@@ -1,7 +1,6 @@
1
1
  import { MessagePartStatus, ToolCallMessagePartStatus } from "../../../types/message.js";
2
2
  import { PartState } from "../../../store/scopes/part.js";
3
3
  import { EnrichedPartState } from "./MessageParts.js";
4
- import { GroupKey } from "../../utils/groupParts.js";
5
4
  import { ReactNode } from "react";
6
5
 
7
6
  //#region src/react/primitives/message/MessageGroupedParts.d.ts
@@ -34,26 +33,32 @@ declare namespace MessagePrimitiveGroupedParts {
34
33
  };
35
34
  type Props<TKey extends `group-${string}` = `group-${string}`> = {
36
35
  /**
37
- * Maps each part to its group key path. Adjacent parts that share a
38
- * prefix coalesce up to that prefix. Return `null`, `undefined`, or
39
- * `[]` to leave a part ungrouped — it will be rendered as a leaf
40
- * through `children` with `part` set to its {@link EnrichedPartState}.
36
+ * Maps each part to a group-key path. Adjacent parts that share a
37
+ * prefix coalesce into the same group. Return `[]` (or `null`) to
38
+ * leave a part ungrouped.
41
39
  *
42
- * Keys must start with `"group-"` so the renderer's
43
- * `switch (part.type)` can distinguish groups from real part types.
40
+ * Group keys must start with `"group-"` so the renderer's
41
+ * `switch (part.type)` can tell groups apart from real part types.
44
42
  *
45
- * For best performance, pass a stable reference (module-level
46
- * constant or `useCallback`).
43
+ * **Prefer {@link groupPartByType}** for the common case of mapping by
44
+ * `part.type` it ships a stable memo fingerprint so the tree
45
+ * survives unrelated re-renders. Use an inline function only when
46
+ * the helper isn't expressive enough (e.g. branching on
47
+ * `part.toolName` or part metadata).
47
48
  *
48
49
  * @example
49
- * ```ts
50
- * const groupBy = (part) =>
51
- * part.type === "reasoning" ? ["group-thought", "group-reasoning"] :
52
- * part.type === "tool-call" ? ["group-thought", "group-tool"] :
53
- * null;
50
+ * ```tsx
51
+ * import { groupPartByType } from "@assistant-ui/react";
52
+ *
53
+ * <MessagePrimitive.GroupedParts
54
+ * groupBy={groupPartByType({
55
+ * reasoning: ["group-thought", "group-reasoning"],
56
+ * "tool-call": ["group-thought", "group-tool"],
57
+ * })}
58
+ * >
54
59
  * ```
55
60
  */
56
- readonly groupBy: (part: PartState, index: number, parts: readonly PartState[]) => GroupKey<TKey>;
61
+ readonly groupBy: (part: PartState) => readonly TKey[] | null;
57
62
  /**
58
63
  * Render function called once per group node and once per leaf part.
59
64
  * Switch on `part.type`: `"group-…"` cases wrap `children`; real
@@ -61,7 +66,7 @@ declare namespace MessagePrimitiveGroupedParts {
61
66
  *
62
67
  * Leaf parts receive the same {@link EnrichedPartState} that
63
68
  * `<MessagePrimitive.Parts>` would produce (`toolUI`, `addResult`,
64
- * `resume`, `dataRendererUI`).
69
+ * `resume`, `respondToApproval`, `dataRendererUI`).
65
70
  */
66
71
  readonly children: (info: RenderInfo<TKey>) => ReactNode;
67
72
  };
@@ -80,11 +85,10 @@ declare namespace MessagePrimitiveGroupedParts {
80
85
  * @example
81
86
  * ```tsx
82
87
  * <MessagePrimitive.GroupedParts
83
- * groupBy={(part) =>
84
- * part.type === "reasoning" ? ["group-thought", "group-reasoning"] :
85
- * part.type === "tool-call" ? ["group-thought", "group-tool"] :
86
- * null
87
- * }
88
+ * groupBy={groupPartByType({
89
+ * reasoning: ["group-thought", "group-reasoning"],
90
+ * "tool-call": ["group-thought", "group-tool"],
91
+ * })}
88
92
  * >
89
93
  * {({ part, children }) => {
90
94
  * switch (part.type) {
@@ -1 +1 @@
1
- {"version":3,"file":"MessageGroupedParts.d.ts","names":[],"sources":["../../../../src/react/primitives/message/MessageGroupedParts.tsx"],"mappings":";;;;;;;kBAkBiB,4BAAA;;AAAjB;;;;;OAOc,SAAA;IAAA,SACD,IAAA,EAAM,IAAA;IAAA,SACN,MAAA,EAAQ,iBAAA,GAAoB,yBAAA;IAAA,SAC5B,OAAA;EAAA;EAAA,KAGC,UAAA;IAwCQ;;;;;IAAA,SAlCT,IAAA,EAAM,SAAA,CAAU,IAAA,IAAQ,iBAAA;IA8CuB;;;;;;IAAA,SAvC/C,QAAA,EAAU,SAAA;EAAA;EAAA,KAGT,KAAA;IAnBD;;;;;;;;;;;;;;;;;;;;IAAA,SAwCA,OAAA,GACP,IAAA,EAAM,SAAA,EACN,KAAA,UACA,KAAA,WAAgB,SAAA,OACb,QAAA,CAAS,IAAA;IAWuB;;;;AAAmB;AAsF5D;;;;IAtFyC,SAA5B,QAAA,GAAW,IAAA,EAAM,UAAA,CAAW,IAAA,MAAU,SAAA;EAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAsFtC,4BAAA;EAAA;IAA8D,OAAA;IAAA;EAAA,GAGxE,4BAAA,CAA6B,KAAA,CAAM,IAAA,IAAQ,SAAA"}
1
+ {"version":3,"file":"MessageGroupedParts.d.ts","names":[],"sources":["../../../../src/react/primitives/message/MessageGroupedParts.tsx"],"mappings":";;;;;;kBAiBiB,4BAAA;;AAAjB;;;;;OAOc,SAAA;IAAA,SACD,IAAA,EAAM,IAAA;IAAA,SACN,MAAA,EAAQ,iBAAA,GAAoB,yBAAA;IAAA,SAC5B,OAAA;EAAA;EAAA,KAGC,UAAA;IA2CsC;;;;;IAAA,SArCvC,IAAA,EAAM,SAAA,CAAU,IAAA,IAAQ,iBAAA;IAZvB;;;;;;IAAA,SAmBD,QAAA,EAAU,SAAA;EAAA;EAAA,KAGT,KAAA;IAhBW;;;;;;;;;;;;;;;;;;;AAsDmC;AAqF5D;;;;;;IA3IyB,SA2CZ,OAAA,GAAU,IAAA,EAAM,SAAA,cAAuB,IAAA;IAmGN;;;;;;;;;IAAA,SAxFjC,QAAA,GAAW,IAAA,EAAM,UAAA,CAAW,IAAA,MAAU,SAAA;EAAA;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAqFtC,4BAAA;EAAA;IAA8D,OAAA;IAAA;EAAA,GAGxE,4BAAA,CAA6B,KAAA,CAAM,IAAA,IAAQ,SAAA"}
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
  import { MessagePartChildren } from "./MessageParts.js";
3
- import { buildGroupTree, normalizeGroupKey } from "../../utils/groupParts.js";
3
+ import { GROUPBY_MEMO_KEY, buildGroupTree } from "../../utils/groupParts.js";
4
4
  import { Fragment, useMemo } from "react";
5
5
  import { useAuiState } from "@assistant-ui/store";
6
6
  import { Fragment as Fragment$1, jsx } from "react/jsx-runtime";
@@ -48,11 +48,10 @@ const renderNode = (node, parts, render) => {
48
48
  * @example
49
49
  * ```tsx
50
50
  * <MessagePrimitive.GroupedParts
51
- * groupBy={(part) =>
52
- * part.type === "reasoning" ? ["group-thought", "group-reasoning"] :
53
- * part.type === "tool-call" ? ["group-thought", "group-tool"] :
54
- * null
55
- * }
51
+ * groupBy={groupPartByType({
52
+ * reasoning: ["group-thought", "group-reasoning"],
53
+ * "tool-call": ["group-thought", "group-tool"],
54
+ * })}
56
55
  * >
57
56
  * {({ part, children }) => {
58
57
  * switch (part.type) {
@@ -69,7 +68,7 @@ const renderNode = (node, parts, render) => {
69
68
  */
70
69
  const MessagePrimitiveGroupedParts = ({ groupBy, children }) => {
71
70
  const parts = useAuiState(useShallow((s) => s.message.parts));
72
- return /* @__PURE__ */ jsx(Fragment$1, { children: useMemo(() => buildGroupTree(parts.map((part, i) => normalizeGroupKey(groupBy(part, i, parts)))), [parts, groupBy]).map((node) => renderNode(node, parts, children)) });
71
+ return /* @__PURE__ */ jsx(Fragment$1, { children: useMemo(() => buildGroupTree(parts.map((part) => groupBy(part) ?? [])), [parts, groupBy[GROUPBY_MEMO_KEY] ?? groupBy]).map((node) => renderNode(node, parts, children)) });
73
72
  };
74
73
  MessagePrimitiveGroupedParts.displayName = "MessagePrimitive.GroupedParts";
75
74
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"MessageGroupedParts.js","names":[],"sources":["../../../../src/react/primitives/message/MessageGroupedParts.tsx"],"sourcesContent":["\"use client\";\n\nimport { Fragment, type FC, type ReactNode, useMemo } from \"react\";\nimport { useAuiState } from \"@assistant-ui/store\";\nimport { useShallow } from \"zustand/shallow\";\nimport type { PartState } from \"../../../store/scopes/part\";\nimport type {\n MessagePartStatus,\n ToolCallMessagePartStatus,\n} from \"../../../types/message\";\nimport {\n buildGroupTree,\n type GroupKey,\n type GroupNode,\n normalizeGroupKey,\n} from \"../../utils/groupParts\";\nimport { MessagePartChildren, type EnrichedPartState } from \"./MessageParts\";\n\nexport namespace MessagePrimitiveGroupedParts {\n /**\n * A coalesced group of adjacent parts. Surfaced through the same\n * `{ part }` channel as a leaf {@link EnrichedPartState} so consumers\n * dispatch on a single `switch (part.type)`. `type` is the group key\n * (always `\"group-…\"`); `status` mirrors the last contained part.\n */\n export type GroupPart<TKey extends `group-${string}` = `group-${string}`> = {\n readonly type: TKey;\n readonly status: MessagePartStatus | ToolCallMessagePartStatus;\n readonly indices: readonly number[];\n };\n\n export type RenderInfo<TKey extends `group-${string}` = `group-${string}`> = {\n /**\n * Either a coalesced group ({@link GroupPart}, identified by a\n * `group-…` `type`) or a single enriched part. Use one switch over\n * `part.type` to handle both.\n */\n readonly part: GroupPart<TKey> | EnrichedPartState;\n /**\n * For group nodes: the recursively-rendered subtree (subgroups +\n * leaf parts). For leaf parts: a sentinel that throws when rendered\n * — accidental fall-through (`default: return children;`) errors\n * loudly instead of silently rendering nothing.\n */\n readonly children: ReactNode;\n };\n\n export type Props<TKey extends `group-${string}` = `group-${string}`> = {\n /**\n * Maps each part to its group key path. Adjacent parts that share a\n * prefix coalesce up to that prefix. Return `null`, `undefined`, or\n * `[]` to leave a part ungrouped — it will be rendered as a leaf\n * through `children` with `part` set to its {@link EnrichedPartState}.\n *\n * Keys must start with `\"group-\"` so the renderer's\n * `switch (part.type)` can distinguish groups from real part types.\n *\n * For best performance, pass a stable reference (module-level\n * constant or `useCallback`).\n *\n * @example\n * ```ts\n * const groupBy = (part) =>\n * part.type === \"reasoning\" ? [\"group-thought\", \"group-reasoning\"] :\n * part.type === \"tool-call\" ? [\"group-thought\", \"group-tool\"] :\n * null;\n * ```\n */\n readonly groupBy: (\n part: PartState,\n index: number,\n parts: readonly PartState[],\n ) => GroupKey<TKey>;\n\n /**\n * Render function called once per group node and once per leaf part.\n * Switch on `part.type`: `\"group-…\"` cases wrap `children`; real\n * part types (`\"text\"`, `\"tool-call\"`, …) render the part directly.\n *\n * Leaf parts receive the same {@link EnrichedPartState} that\n * `<MessagePrimitive.Parts>` would produce (`toolUI`, `addResult`,\n * `resume`, `dataRendererUI`).\n */\n readonly children: (info: RenderInfo<TKey>) => ReactNode;\n };\n}\n\nconst COMPLETE_STATUS: MessagePartStatus = Object.freeze({ type: \"complete\" });\n\n/**\n * `children` placeholder passed for leaf-part renders. Leaf parts have no\n * inner subtree; rendering this sentinel signals the consumer wrote\n * `default: return children;` and accidentally fell through for a part —\n * surface the bug loudly instead of silently rendering nothing.\n */\nconst PartChildrenSentinel: FC = () => {\n throw new Error(\n \"MessagePrimitive.GroupedParts: rendered `children` under a leaf \" +\n \"part. `children` is only meaningful for `group-…` cases — add a \" +\n \"matching case for the part type or return `null` to skip it.\",\n );\n};\n\nconst renderNode = <TKey extends `group-${string}`>(\n node: GroupNode,\n parts: readonly PartState[],\n render: (info: MessagePrimitiveGroupedParts.RenderInfo<TKey>) => ReactNode,\n): ReactNode => {\n if (node.type === \"part\") {\n // Key by absolute part index, not structural nodeKey — prevents zombie fiber subscriptions when parts reshape (#4051).\n return (\n <MessagePartChildren key={`part-${node.index}`} index={node.index}>\n {({ part }) => render({ part, children: <PartChildrenSentinel /> })}\n </MessagePartChildren>\n );\n }\n\n const status = parts[node.indices.at(-1)!]?.status ?? COMPLETE_STATUS;\n const groupPart: MessagePrimitiveGroupedParts.GroupPart<TKey> = {\n type: node.key as TKey,\n status,\n indices: node.indices,\n };\n\n return (\n <Fragment key={node.nodeKey}>\n {render({\n part: groupPart,\n children: (\n <>{node.children.map((child) => renderNode(child, parts, render))}</>\n ),\n })}\n </Fragment>\n );\n};\n\n/**\n * Groups adjacent message parts into a tree of coalesced runs and\n * renders each node — group or part — through a single `children`\n * function.\n *\n * The render function receives `{ part, children }` where `part.type`\n * is either a `\"group-…\"` literal (for a group, `children` is the\n * recursively-rendered subtree) or a real part type (`\"text\"`,\n * `\"tool-call\"`, …) for a leaf (`children` is a sentinel that throws\n * if rendered — use `part.type` to distinguish).\n *\n * @example\n * ```tsx\n * <MessagePrimitive.GroupedParts\n * groupBy={(part) =>\n * part.type === \"reasoning\" ? [\"group-thought\", \"group-reasoning\"] :\n * part.type === \"tool-call\" ? [\"group-thought\", \"group-tool\"] :\n * null\n * }\n * >\n * {({ part, children }) => {\n * switch (part.type) {\n * case \"group-thought\": return <Thought>{children}</Thought>;\n * case \"group-reasoning\": return <Reasoning>{children}</Reasoning>;\n * case \"group-tool\": return <ToolStack>{children}</ToolStack>;\n * case \"text\": return <MarkdownText />;\n * case \"tool-call\": return part.toolUI ?? <ToolFallback {...part} />;\n * default: return null;\n * }\n * }}\n * </MessagePrimitive.GroupedParts>\n * ```\n */\nexport const MessagePrimitiveGroupedParts = <TKey extends `group-${string}`>({\n groupBy,\n children,\n}: MessagePrimitiveGroupedParts.Props<TKey>): ReactNode => {\n const parts = useAuiState(useShallow((s) => s.message.parts));\n\n const tree = useMemo(\n () =>\n buildGroupTree(\n parts.map((part, i) => normalizeGroupKey(groupBy(part, i, parts))),\n ),\n [parts, groupBy],\n );\n\n return <>{tree.map((node) => renderNode(node, parts, children))}</>;\n};\n\nMessagePrimitiveGroupedParts.displayName = \"MessagePrimitive.GroupedParts\";\n"],"mappings":";;;;;;;;AAuFA,MAAM,kBAAqC,OAAO,OAAO,EAAE,MAAM,WAAW,CAAC;;;;;;;AAQ7E,MAAM,6BAAiC;CACrC,MAAM,IAAI,MACR,8LAGF;AACF;AAEA,MAAM,cACJ,MACA,OACA,WACc;CACd,IAAI,KAAK,SAAS,QAEhB,OACE,oBAAC,qBAAD;EAAgD,OAAO,KAAK;aACxD,EAAE,WAAW,OAAO;GAAE;GAAM,UAAU,oBAAC,sBAAD,CAAuB,CAAA;EAAE,CAAC;CAC/C,GAFK,QAAQ,KAAK,OAElB;CAIzB,MAAM,SAAS,MAAM,KAAK,QAAQ,GAAG,EAAE,IAAK,UAAU;CAOtD,OACE,oBAAC,UAAD,EAAA,UACG,OAAO;EACN,MAAM;GARV,MAAM,KAAK;GACX;GACA,SAAS,KAAK;EAMI;EACd,UACE,oBAAA,YAAA,EAAA,UAAG,KAAK,SAAS,KAAK,UAAU,WAAW,OAAO,OAAO,MAAM,CAAC,EAAI,CAAA;CAExE,CAAC,EACO,GAPK,KAAK,OAOV;AAEd;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCA,MAAa,gCAAgE,EAC3E,SACA,eACyD;CACzD,MAAM,QAAQ,YAAY,YAAY,MAAM,EAAE,QAAQ,KAAK,CAAC;CAU5D,OAAO,oBAAA,YAAA,EAAA,UARM,cAET,eACE,MAAM,KAAK,MAAM,MAAM,kBAAkB,QAAQ,MAAM,GAAG,KAAK,CAAC,CAAC,CACnE,GACF,CAAC,OAAO,OAAO,CAGJ,EAAE,KAAK,SAAS,WAAW,MAAM,OAAO,QAAQ,CAAC,EAAI,CAAA;AACpE;AAEA,6BAA6B,cAAc"}
1
+ {"version":3,"file":"MessageGroupedParts.js","names":[],"sources":["../../../../src/react/primitives/message/MessageGroupedParts.tsx"],"sourcesContent":["\"use client\";\n\nimport { Fragment, type FC, type ReactNode, useMemo } from \"react\";\nimport { useAuiState } from \"@assistant-ui/store\";\nimport { useShallow } from \"zustand/shallow\";\nimport type { PartState } from \"../../../store/scopes/part\";\nimport type {\n MessagePartStatus,\n ToolCallMessagePartStatus,\n} from \"../../../types/message\";\nimport {\n buildGroupTree,\n GROUPBY_MEMO_KEY,\n type GroupNode,\n} from \"../../utils/groupParts\";\nimport { MessagePartChildren, type EnrichedPartState } from \"./MessageParts\";\n\nexport namespace MessagePrimitiveGroupedParts {\n /**\n * A coalesced group of adjacent parts. Surfaced through the same\n * `{ part }` channel as a leaf {@link EnrichedPartState} so consumers\n * dispatch on a single `switch (part.type)`. `type` is the group key\n * (always `\"group-…\"`); `status` mirrors the last contained part.\n */\n export type GroupPart<TKey extends `group-${string}` = `group-${string}`> = {\n readonly type: TKey;\n readonly status: MessagePartStatus | ToolCallMessagePartStatus;\n readonly indices: readonly number[];\n };\n\n export type RenderInfo<TKey extends `group-${string}` = `group-${string}`> = {\n /**\n * Either a coalesced group ({@link GroupPart}, identified by a\n * `group-…` `type`) or a single enriched part. Use one switch over\n * `part.type` to handle both.\n */\n readonly part: GroupPart<TKey> | EnrichedPartState;\n /**\n * For group nodes: the recursively-rendered subtree (subgroups +\n * leaf parts). For leaf parts: a sentinel that throws when rendered\n * — accidental fall-through (`default: return children;`) errors\n * loudly instead of silently rendering nothing.\n */\n readonly children: ReactNode;\n };\n\n export type Props<TKey extends `group-${string}` = `group-${string}`> = {\n /**\n * Maps each part to a group-key path. Adjacent parts that share a\n * prefix coalesce into the same group. Return `[]` (or `null`) to\n * leave a part ungrouped.\n *\n * Group keys must start with `\"group-\"` so the renderer's\n * `switch (part.type)` can tell groups apart from real part types.\n *\n * **Prefer {@link groupPartByType}** for the common case of mapping by\n * `part.type` — it ships a stable memo fingerprint so the tree\n * survives unrelated re-renders. Use an inline function only when\n * the helper isn't expressive enough (e.g. branching on\n * `part.toolName` or part metadata).\n *\n * @example\n * ```tsx\n * import { groupPartByType } from \"@assistant-ui/react\";\n *\n * <MessagePrimitive.GroupedParts\n * groupBy={groupPartByType({\n * reasoning: [\"group-thought\", \"group-reasoning\"],\n * \"tool-call\": [\"group-thought\", \"group-tool\"],\n * })}\n * >\n * ```\n */\n readonly groupBy: (part: PartState) => readonly TKey[] | null;\n\n /**\n * Render function called once per group node and once per leaf part.\n * Switch on `part.type`: `\"group-…\"` cases wrap `children`; real\n * part types (`\"text\"`, `\"tool-call\"`, …) render the part directly.\n *\n * Leaf parts receive the same {@link EnrichedPartState} that\n * `<MessagePrimitive.Parts>` would produce (`toolUI`, `addResult`,\n * `resume`, `respondToApproval`, `dataRendererUI`).\n */\n readonly children: (info: RenderInfo<TKey>) => ReactNode;\n };\n}\n\nconst COMPLETE_STATUS: MessagePartStatus = Object.freeze({ type: \"complete\" });\n\n/**\n * `children` placeholder passed for leaf-part renders. Leaf parts have no\n * inner subtree; rendering this sentinel signals the consumer wrote\n * `default: return children;` and accidentally fell through for a part —\n * surface the bug loudly instead of silently rendering nothing.\n */\nconst PartChildrenSentinel: FC = () => {\n throw new Error(\n \"MessagePrimitive.GroupedParts: rendered `children` under a leaf \" +\n \"part. `children` is only meaningful for `group-…` cases — add a \" +\n \"matching case for the part type or return `null` to skip it.\",\n );\n};\n\nconst renderNode = <TKey extends `group-${string}`>(\n node: GroupNode,\n parts: readonly PartState[],\n render: (info: MessagePrimitiveGroupedParts.RenderInfo<TKey>) => ReactNode,\n): ReactNode => {\n if (node.type === \"part\") {\n // Key by absolute part index, not structural nodeKey — prevents zombie fiber subscriptions when parts reshape (#4051).\n return (\n <MessagePartChildren key={`part-${node.index}`} index={node.index}>\n {({ part }) => render({ part, children: <PartChildrenSentinel /> })}\n </MessagePartChildren>\n );\n }\n\n const status = parts[node.indices.at(-1)!]?.status ?? COMPLETE_STATUS;\n const groupPart: MessagePrimitiveGroupedParts.GroupPart<TKey> = {\n type: node.key as TKey,\n status,\n indices: node.indices,\n };\n\n return (\n <Fragment key={node.nodeKey}>\n {render({\n part: groupPart,\n children: (\n <>{node.children.map((child) => renderNode(child, parts, render))}</>\n ),\n })}\n </Fragment>\n );\n};\n\n/**\n * Groups adjacent message parts into a tree of coalesced runs and\n * renders each node — group or part — through a single `children`\n * function.\n *\n * The render function receives `{ part, children }` where `part.type`\n * is either a `\"group-…\"` literal (for a group, `children` is the\n * recursively-rendered subtree) or a real part type (`\"text\"`,\n * `\"tool-call\"`, …) for a leaf (`children` is a sentinel that throws\n * if rendered — use `part.type` to distinguish).\n *\n * @example\n * ```tsx\n * <MessagePrimitive.GroupedParts\n * groupBy={groupPartByType({\n * reasoning: [\"group-thought\", \"group-reasoning\"],\n * \"tool-call\": [\"group-thought\", \"group-tool\"],\n * })}\n * >\n * {({ part, children }) => {\n * switch (part.type) {\n * case \"group-thought\": return <Thought>{children}</Thought>;\n * case \"group-reasoning\": return <Reasoning>{children}</Reasoning>;\n * case \"group-tool\": return <ToolStack>{children}</ToolStack>;\n * case \"text\": return <MarkdownText />;\n * case \"tool-call\": return part.toolUI ?? <ToolFallback {...part} />;\n * default: return null;\n * }\n * }}\n * </MessagePrimitive.GroupedParts>\n * ```\n */\nexport const MessagePrimitiveGroupedParts = <TKey extends `group-${string}`>({\n groupBy,\n children,\n}: MessagePrimitiveGroupedParts.Props<TKey>): ReactNode => {\n const parts = useAuiState(useShallow((s) => s.message.parts));\n\n // Helpers like `groupPartByType` tag the function with `GROUPBY_MEMO_KEY`\n // (a stable string fingerprint of the helper config). When present,\n // memo on `[parts, memoKey]` so the tree survives unrelated renders.\n // For inline `groupBy`, fall back to recomputing each render — O(n)\n // and cheap.\n const memoKey = (groupBy as { [GROUPBY_MEMO_KEY]?: string })[\n GROUPBY_MEMO_KEY\n ];\n const memoDep = memoKey ?? groupBy;\n // biome-ignore lint/correctness/useExhaustiveDependencies: groupBy is captured via memoDep — either as its identity (no memoKey) or as the helper's memoKey fingerprint. Listing groupBy directly would defeat the helper-tagged memo path.\n const tree = useMemo(\n () => buildGroupTree(parts.map((part) => groupBy(part) ?? [])),\n [parts, memoDep],\n );\n\n return <>{tree.map((node) => renderNode(node, parts, children))}</>;\n};\n\nMessagePrimitiveGroupedParts.displayName = \"MessagePrimitive.GroupedParts\";\n"],"mappings":";;;;;;;;AAwFA,MAAM,kBAAqC,OAAO,OAAO,EAAE,MAAM,WAAW,CAAC;;;;;;;AAQ7E,MAAM,6BAAiC;CACrC,MAAM,IAAI,MACR,8LAGF;AACF;AAEA,MAAM,cACJ,MACA,OACA,WACc;CACd,IAAI,KAAK,SAAS,QAEhB,OACE,oBAAC,qBAAD;EAAgD,OAAO,KAAK;aACxD,EAAE,WAAW,OAAO;GAAE;GAAM,UAAU,oBAAC,sBAAD,CAAuB,CAAA;EAAE,CAAC;CAC/C,GAFK,QAAQ,KAAK,OAElB;CAIzB,MAAM,SAAS,MAAM,KAAK,QAAQ,GAAG,EAAE,IAAK,UAAU;CAOtD,OACE,oBAAC,UAAD,EAAA,UACG,OAAO;EACN,MAAM;GARV,MAAM,KAAK;GACX;GACA,SAAS,KAAK;EAMI;EACd,UACE,oBAAA,YAAA,EAAA,UAAG,KAAK,SAAS,KAAK,UAAU,WAAW,OAAO,OAAO,MAAM,CAAC,EAAI,CAAA;CAExE,CAAC,EACO,GAPK,KAAK,OAOV;AAEd;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCA,MAAa,gCAAgE,EAC3E,SACA,eACyD;CACzD,MAAM,QAAQ,YAAY,YAAY,MAAM,EAAE,QAAQ,KAAK,CAAC;CAiB5D,OAAO,oBAAA,YAAA,EAAA,UALM,cACL,eAAe,MAAM,KAAK,SAAS,QAAQ,IAAI,KAAK,CAAC,CAAC,CAAC,GAC7D,CAAC,OAPc,QACf,qBAEyB,OAIV,CAGJ,EAAE,KAAK,SAAS,WAAW,MAAM,OAAO,QAAQ,CAAC,EAAI,CAAA;AACpE;AAEA,6BAA6B,cAAc"}
@@ -168,7 +168,8 @@ type EnrichedPartState = (Extract<PartState, {
168
168
  }> & {
169
169
  /** The registered tool UI element, or null if none registered. */readonly toolUI: ReactNode; /** Add a tool result to this tool call. */
170
170
  addResult: ToolCallMessagePartProps["addResult"]; /** Resume a tool call waiting for human input. */
171
- resume: ToolCallMessagePartProps["resume"];
171
+ resume: ToolCallMessagePartProps["resume"]; /** Respond to a server-side tool approval gate. */
172
+ respondToApproval: ToolCallMessagePartProps["respondToApproval"];
172
173
  }) | (Extract<PartState, {
173
174
  type: "data";
174
175
  }> & {
@@ -1 +1 @@
1
- {"version":3,"file":"MessageParts.d.ts","names":[],"sources":["../../../../src/react/primitives/message/MessageParts.tsx"],"mappings":";;;;;kBA6JiB,qBAAA;EAAA,KACV,UAAA;IADU,kDAGb,OAAA,GAAU,MAAA,SAAe,wBAAA,2BAHS;IAKlC,QAAA,GAAW,wBAAA;EAAA;EAAA,KAGR,cAAA;IAEK,6CAAR,KAAA,GAAQ,yBAAA,cAIC;IAFT,IAAA,GAAO,wBAAA,cAMA;IAJP,MAAA,GAAS,0BAAA,cAQF;IANP,KAAA,GAAQ,yBAAA,cAoBU;IAlBlB,IAAA,GAAO,wBAAA,cA+BgB;IA7BvB,cAAA,GAAiB,kCAAA,cAgCY;IA9B7B,IAAA,GAAO,UAAA,cAkCqB;IAhC5B,KAAA,GAAQ,yBAAA;IAyCgB;;;;;;;;IAhCxB,YAAA;MA+FsC,uDA5FhC,UAAA,EAAY,6BAAA,EAyGoC;MAvGhD,QAAA,GACI,aAAA;QAAgB,SAAA;QAAmB,KAAA;MAAA;IAAA;EAAA;EAAA,KAM1C,WAAA;IAxCQ,qDA2CP,OAAA,GACI,MAAA,SAAe,4BAAA,2BAvCvB;IA0CI,QAAA,GAAW,aAAA,CAAc,wBAAA;EAAA;IAxCtB,qDA4CH,QAAA,EAAU,aAAA,CAAc,wBAAA;EAAA;EAxC5B;;;;;;EAAA,KAiDG,kBAAA,GAAqB,cAAA;IA3CjB,mEA6CP,SAAA,GAAY,6BAAA,cA3CJ;IA6CR,KAAA,GAAQ,WAAA;IAjCF;;;;;;;;;IA4CN,SAAA,GAAY,aAAA,CACV,iBAAA;MAAoB,UAAA;MAAoB,QAAA;IAAA;IAzBtC;;;;;;;;;IAqCJ,cAAA,GAAiB,uBAAA;IAEjB,cAAA;EAAA;EAdsB;;;;;;;EAAA,KAwBnB,wBAAA,GAA2B,cAAA;IAMd;;;;;IAAhB,cAAA,EAAgB,aAAA;IAEhB,SAAA;IACA,KAAA;IACA,SAAA;IACA,cAAA;EAAA;EAAA,YAGU,KAAA;IAsBc;;;;;;;IAbpB,UAAA,GAAa,kBAAA,GAAqB,wBAAA;IA6D7B;;;;;;;IArDL,8BAAA;IACA,QAAA;EAAA;IA4D0C,8EAxD1C,QAAA,GAAW,KAAA;MAAS,IAAA,EAAM,iBAAA;IAAA,MAAwB,SAAA;IAClD,UAAA;IACA,8BAAA;EAAA;EAAA;AAAA;;;;;cA8CK,iBAAA;;;;;;;;;KAOe,iBAAA,KAAiB,SAAA;;;KACZ,iBAAA,KAAiB,SAAA;AAAA;AAAA,KAG7C,yBAAA;EACH,UAAA,EAAY,qBAAA,CAAsB,KAAK;AAAA;AAAA,cAG5B,oBAAA,EAAsB,EAAE,CAAC,yBAAA;AAAA,kBAyFrB,2BAAA;EAAA,KACH,KAAA;IACV,KAAA;IACA,UAAA,EAAY,qBAAA,CAAsB,KAAK;EAAA;AAAA;AAH3C;;;AAAA,cAUa,2BAAA,EAA6B,EAAE,CAAC,2BAAA,CAA4B,KAAA;;;;;;AAP9B;AAO3C;;;;;;KA+LY,iBAAA,IACP,OAAA,CAAQ,SAAA;EAAa,IAAA;AAAA;EADd,2EAGG,MAAA,EAAQ,SAAA;EAEjB,SAAA,EAAW,wBAAA,eAJZ;EAMC,MAAA,EAAQ,wBAAA;AAAA,MAET,OAAA,CAAQ,SAAA;EAAa,IAAA;AAAA;EAArB,oFAEU,cAAA,EAAgB,SAAA;AAAA,KAE3B,OAAA,CAAQ,SAAA;EAAa,IAAA;AAAA;EAAwB,IAAA;AAAA;;;;;;;cAmGpC,qBAAA,EAAuB,EAAE,CAAC,qBAAA,CAAsB,KAAA"}
1
+ {"version":3,"file":"MessageParts.d.ts","names":[],"sources":["../../../../src/react/primitives/message/MessageParts.tsx"],"mappings":";;;;;kBA6JiB,qBAAA;EAAA,KACV,UAAA;IADU,kDAGb,OAAA,GAAU,MAAA,SAAe,wBAAA,2BAHS;IAKlC,QAAA,GAAW,wBAAA;EAAA;EAAA,KAGR,cAAA;IAEK,6CAAR,KAAA,GAAQ,yBAAA,cAIC;IAFT,IAAA,GAAO,wBAAA,cAMA;IAJP,MAAA,GAAS,0BAAA,cAQF;IANP,KAAA,GAAQ,yBAAA,cAoBU;IAlBlB,IAAA,GAAO,wBAAA,cA+BgB;IA7BvB,cAAA,GAAiB,kCAAA,cAgCY;IA9B7B,IAAA,GAAO,UAAA,cAkCqB;IAhC5B,KAAA,GAAQ,yBAAA;IAyCgB;;;;;;;;IAhCxB,YAAA;MA+FsC,uDA5FhC,UAAA,EAAY,6BAAA,EAyGoC;MAvGhD,QAAA,GACI,aAAA;QAAgB,SAAA;QAAmB,KAAA;MAAA;IAAA;EAAA;EAAA,KAM1C,WAAA;IAxCQ,qDA2CP,OAAA,GACI,MAAA,SAAe,4BAAA,2BAvCvB;IA0CI,QAAA,GAAW,aAAA,CAAc,wBAAA;EAAA;IAxCtB,qDA4CH,QAAA,EAAU,aAAA,CAAc,wBAAA;EAAA;EAxC5B;;;;;;EAAA,KAiDG,kBAAA,GAAqB,cAAA;IA3CjB,mEA6CP,SAAA,GAAY,6BAAA,cA3CJ;IA6CR,KAAA,GAAQ,WAAA;IAjCF;;;;;;;;;IA4CN,SAAA,GAAY,aAAA,CACV,iBAAA;MAAoB,UAAA;MAAoB,QAAA;IAAA;IAzBtC;;;;;;;;;IAqCJ,cAAA,GAAiB,uBAAA;IAEjB,cAAA;EAAA;EAdsB;;;;;;;EAAA,KAwBnB,wBAAA,GAA2B,cAAA;IAMd;;;;;IAAhB,cAAA,EAAgB,aAAA;IAEhB,SAAA;IACA,KAAA;IACA,SAAA;IACA,cAAA;EAAA;EAAA,YAGU,KAAA;IAsBc;;;;;;;IAbpB,UAAA,GAAa,kBAAA,GAAqB,wBAAA;IA6D7B;;;;;;;IArDL,8BAAA;IACA,QAAA;EAAA;IA4D0C,8EAxD1C,QAAA,GAAW,KAAA;MAAS,IAAA,EAAM,iBAAA;IAAA,MAAwB,SAAA;IAClD,UAAA;IACA,8BAAA;EAAA;EAAA;AAAA;;;;;cA8CK,iBAAA;;;;;;;;;KAOe,iBAAA,KAAiB,SAAA;;;KACZ,iBAAA,KAAiB,SAAA;AAAA;AAAA,KAG7C,yBAAA;EACH,UAAA,EAAY,qBAAA,CAAsB,KAAK;AAAA;AAAA,cAG5B,oBAAA,EAAsB,EAAE,CAAC,yBAAA;AAAA,kBAkGrB,2BAAA;EAAA,KACH,KAAA;IACV,KAAA;IACA,UAAA,EAAY,qBAAA,CAAsB,KAAK;EAAA;AAAA;AAH3C;;;AAAA,cAUa,2BAAA,EAA6B,EAAE,CAAC,2BAAA,CAA4B,KAAA;;;;;;AAP9B;AAO3C;;;;;;KAgMY,iBAAA,IACP,OAAA,CAAQ,SAAA;EAAa,IAAA;AAAA;EADd,2EAGG,MAAA,EAAQ,SAAA;EAEjB,SAAA,EAAW,wBAAA,eAJZ;EAMC,MAAA,EAAQ,wBAAA,YAFG;EAIX,iBAAA,EAAmB,wBAAA;AAAA,MAEpB,OAAA,CAAQ,SAAA;EAAa,IAAA;AAAA;EAEK,oFAAhB,cAAA,EAAgB,SAAA;AAAA,KAE3B,OAAA,CAAQ,SAAA;EAAa,IAAA;AAAA;EAAwB,IAAA;AAAA;;;;;;;cAoGpC,qBAAA,EAAuB,EAAE,CAAC,qBAAA,CAAsB,KAAA"}
@@ -131,17 +131,20 @@ const MessagePartComponent = ({ components: { Text = defaultComponents.Text, Rea
131
131
  if (type === "tool-call") {
132
132
  const addResult = aui.part().addToolResult;
133
133
  const resume = aui.part().resumeToolCall;
134
+ const respondToApproval = aui.part().respondToToolApproval;
134
135
  if ("Override" in tools) return /* @__PURE__ */ jsx(tools.Override, {
135
136
  ...part,
136
137
  addResult,
137
- resume
138
+ resume,
139
+ respondToApproval
138
140
  });
139
141
  const Tool = tools.by_name?.[part.toolName] ?? tools.Fallback;
140
142
  return /* @__PURE__ */ jsx(ToolUIDisplay, {
141
143
  ...part,
142
144
  Fallback: Tool,
143
145
  addResult,
144
- resume
146
+ resume,
147
+ respondToApproval
145
148
  });
146
149
  }
147
150
  if (part.status?.type === "requires-action") throw new Error("Encountered unexpected requires-action status");
@@ -245,7 +248,8 @@ const RegisteredToolUI = () => {
245
248
  return /* @__PURE__ */ jsx(Render, {
246
249
  ...part,
247
250
  addResult: aui.part().addToolResult,
248
- resume: aui.part().resumeToolCall
251
+ resume: aui.part().resumeToolCall,
252
+ respondToApproval: aui.part().respondToToolApproval
249
253
  });
250
254
  };
251
255
  /**
@@ -306,7 +310,8 @@ const MessagePartChildren = ({ index, children }) => {
306
310
  ...state,
307
311
  toolUI: hasUI ? /* @__PURE__ */ jsx(RegisteredToolUI, {}) : null,
308
312
  addResult: partMethods.addToolResult,
309
- resume: partMethods.resumeToolCall
313
+ resume: partMethods.resumeToolCall,
314
+ respondToApproval: partMethods.respondToToolApproval
310
315
  };
311
316
  }
312
317
  if (state.type === "data") {
@@ -1 +1 @@
1
- {"version":3,"file":"MessageParts.js","names":[],"sources":["../../../../src/react/primitives/message/MessageParts.tsx"],"sourcesContent":["import {\n type ComponentType,\n type FC,\n type ReactNode,\n memo,\n type PropsWithChildren,\n useMemo,\n} from \"react\";\nimport {\n RenderChildrenWithAccessor,\n useAuiState,\n useAui,\n} from \"@assistant-ui/store\";\nimport type { PartState } from \"../../../store/scopes/part\";\nimport { PartByIndexProvider } from \"../../providers/PartByIndexProvider\";\nimport { TextMessagePartProvider } from \"../../providers/TextMessagePartProvider\";\nimport { ChainOfThoughtByIndicesProvider } from \"../../providers/ChainOfThoughtByIndicesProvider\";\nimport { getMessageQuote } from \"../../utils/getMessageQuote\";\nimport type {\n Unstable_AudioMessagePartComponent,\n DataMessagePartComponent,\n DataMessagePartProps,\n EmptyMessagePartComponent,\n TextMessagePartComponent,\n ImageMessagePartComponent,\n SourceMessagePartComponent,\n ToolCallMessagePartComponent,\n ToolCallMessagePartProps,\n FileMessagePartComponent,\n ReasoningMessagePartComponent,\n ReasoningGroupComponent,\n QuoteMessagePartComponent,\n GenerativeUIComponentRegistry,\n} from \"../../types/MessagePartComponentTypes\";\nimport { GenerativeUIRender } from \"../generativeUI/GenerativeUI\";\nimport {\n isMcpAppUri,\n type MessagePartStatus,\n type GenerativeUIMessagePart,\n} from \"../../../types/message\";\nimport type { DataRenderersState } from \"../../types/scopes/dataRenderers\";\nimport type { ToolsState } from \"../../types/scopes/tools\";\nimport { useShallow } from \"zustand/shallow\";\n\ntype MessagePartRange =\n | { type: \"single\"; index: number }\n | { type: \"toolGroup\"; startIndex: number; endIndex: number }\n | { type: \"reasoningGroup\"; startIndex: number; endIndex: number }\n | { type: \"chainOfThoughtGroup\"; startIndex: number; endIndex: number };\n\n/**\n * Creates a group state manager for a specific part type.\n * Returns functions to start, end, and finalize groups.\n */\nconst createGroupState = <\n T extends \"toolGroup\" | \"reasoningGroup\" | \"chainOfThoughtGroup\",\n>(\n groupType: T,\n) => {\n let start = -1;\n\n return {\n startGroup: (index: number) => {\n if (start === -1) {\n start = index;\n }\n },\n endGroup: (endIndex: number, ranges: MessagePartRange[]) => {\n if (start !== -1) {\n ranges.push({\n type: groupType,\n startIndex: start,\n endIndex,\n } as MessagePartRange);\n start = -1;\n }\n },\n finalize: (endIndex: number, ranges: MessagePartRange[]) => {\n if (start !== -1) {\n ranges.push({\n type: groupType,\n startIndex: start,\n endIndex,\n } as MessagePartRange);\n }\n },\n };\n};\n\n/**\n * Groups consecutive tool-call and reasoning message parts into ranges.\n * Always groups tool calls and reasoning parts, even if there's only one.\n * When useChainOfThought is true, groups tool-call and reasoning parts together.\n */\nconst groupMessageParts = (\n messageTypes: readonly string[],\n useChainOfThought: boolean,\n): MessagePartRange[] => {\n const ranges: MessagePartRange[] = [];\n\n if (useChainOfThought) {\n const chainOfThoughtGroup = createGroupState(\"chainOfThoughtGroup\");\n\n for (let i = 0; i < messageTypes.length; i++) {\n const type = messageTypes[i];\n\n if (type === \"tool-call\" || type === \"reasoning\") {\n chainOfThoughtGroup.startGroup(i);\n } else {\n chainOfThoughtGroup.endGroup(i - 1, ranges);\n ranges.push({ type: \"single\", index: i });\n }\n }\n\n chainOfThoughtGroup.finalize(messageTypes.length - 1, ranges);\n } else {\n const toolGroup = createGroupState(\"toolGroup\");\n const reasoningGroup = createGroupState(\"reasoningGroup\");\n\n for (let i = 0; i < messageTypes.length; i++) {\n const type = messageTypes[i];\n\n if (type === \"tool-call\") {\n reasoningGroup.endGroup(i - 1, ranges);\n toolGroup.startGroup(i);\n } else if (type === \"reasoning\") {\n toolGroup.endGroup(i - 1, ranges);\n reasoningGroup.startGroup(i);\n } else {\n toolGroup.endGroup(i - 1, ranges);\n reasoningGroup.endGroup(i - 1, ranges);\n ranges.push({ type: \"single\", index: i });\n }\n }\n\n toolGroup.finalize(messageTypes.length - 1, ranges);\n reasoningGroup.finalize(messageTypes.length - 1, ranges);\n }\n\n return ranges;\n};\n\nconst useMessagePartsGroups = (\n useChainOfThought: boolean,\n): MessagePartRange[] => {\n const messageTypes = useAuiState(\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, useChainOfThought);\n }, [messageTypes, useChainOfThought]);\n};\n\nexport namespace MessagePrimitiveParts {\n type DataConfig = {\n /** Map data event names to specific components */\n by_name?: Record<string, DataMessagePartComponent | undefined> | undefined;\n /** Fallback component for unmatched data events */\n Fallback?: DataMessagePartComponent | undefined;\n };\n\n type BaseComponents = {\n /** Component for rendering empty messages */\n Empty?: EmptyMessagePartComponent | undefined;\n /** Component for rendering text content */\n Text?: TextMessagePartComponent | 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 data part rendering */\n data?: DataConfig | undefined;\n /** Component for rendering a quoted message reference (from metadata, not parts) */\n Quote?: QuoteMessagePartComponent | undefined;\n /**\n * Configuration for generative-ui part rendering.\n *\n * `components` is the consumer-provided allowlist of React components\n * the agent's JSON spec is permitted to render. Any name not present in\n * the registry is rejected with a typed `GenerativeUIRenderError` —\n * this is the security boundary in the same-realm rendering path.\n */\n generativeUI?:\n | {\n /** The component allowlist (the security boundary). */\n components: GenerativeUIComponentRegistry;\n /** Optional fallback for unknown component names. */\n Fallback?:\n | ComponentType<{ component: string; props?: unknown }>\n | undefined;\n }\n | undefined;\n };\n\n type ToolsConfig =\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\n /**\n * Standard component configuration for rendering reasoning and tool-call parts\n * individually (with optional grouping).\n *\n * Cannot be combined with `ChainOfThought`.\n */\n type StandardComponents = BaseComponents & {\n /** Component for rendering reasoning content (typically hidden) */\n Reasoning?: ReasoningMessagePartComponent | undefined;\n /** Configuration for tool call rendering */\n tools?: ToolsConfig | undefined;\n\n /**\n * Component for rendering grouped consecutive tool calls.\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 Use `<MessagePrimitive.GroupedParts>` with a custom `groupBy` instead.\n */\n ToolGroup?: ComponentType<\n PropsWithChildren<{ startIndex: number; endIndex: number }>\n >;\n\n /**\n * Component for rendering grouped reasoning parts.\n *\n * @param startIndex - Index of the first reasoning part in the group\n * @param endIndex - Index of the last reasoning part in the group\n * @param children - Rendered reasoning part components\n *\n * @deprecated Use `<MessagePrimitive.GroupedParts>` with a custom `groupBy` instead.\n */\n ReasoningGroup?: ReasoningGroupComponent;\n\n ChainOfThought?: never;\n };\n\n /**\n * Chain of thought component configuration.\n *\n * When `ChainOfThought` is set, it takes control of rendering ALL reasoning and\n * tool-call parts in the message. The `Reasoning`, `tools`, `ReasoningGroup`, and\n * `ToolGroup` components cannot be used alongside it.\n */\n type ChainOfThoughtComponents = BaseComponents & {\n /**\n * @deprecated Use `<MessagePrimitive.GroupedParts>` with a `groupBy`\n * that returns `[\"group-thought\", ...]` for reasoning and tool-call\n * parts. See `@assistant-ui/ui` for a worked example.\n */\n ChainOfThought: ComponentType;\n\n Reasoning?: never;\n tools?: never;\n ToolGroup?: never;\n ReasoningGroup?: never;\n };\n\n export type Props =\n | {\n /**\n * Component configuration for rendering different types of message content.\n *\n * Use either `Reasoning`/`tools`/`ToolGroup`/`ReasoningGroup` for standard rendering,\n * or `ChainOfThought` to group all reasoning and tool-call parts into a single\n * collapsible component. These two modes are mutually exclusive.\n */\n components?: StandardComponents | ChainOfThoughtComponents | undefined;\n /**\n * When enabled, shows the Empty component if the last part in the message\n * is anything other than Text or Reasoning.\n *\n * @experimental This API is experimental and may change in future versions.\n * @default true\n */\n unstable_showEmptyOnNonTextEnd?: boolean | undefined;\n children?: never;\n }\n | {\n /** Render function called for each part. Receives the enriched part state. */\n children: (value: { part: EnrichedPartState }) => ReactNode;\n components?: never;\n unstable_showEmptyOnNonTextEnd?: never;\n };\n}\n\nconst ToolUIDisplay = ({\n Fallback,\n ...props\n}: {\n Fallback: ToolCallMessagePartComponent | undefined;\n} & ToolCallMessagePartProps) => {\n const Render = useAuiState((s) => {\n const Render = s.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 getDataRenderer = (\n dataRenderers: DataRenderersState,\n name: string,\n inlineFallback: DataMessagePartComponent | undefined,\n): DataMessagePartComponent | undefined => {\n const named = dataRenderers.renderers[name]?.[0];\n if (named) return named;\n return dataRenderers.fallbacks[0] ?? inlineFallback;\n};\n\nconst DataUIDisplay = ({\n Fallback,\n ...props\n}: {\n Fallback: DataMessagePartComponent | undefined;\n} & DataMessagePartProps) => {\n const Render = useAuiState((s) =>\n getDataRenderer(s.dataRenderers, props.name, Fallback),\n );\n if (!Render) return null;\n return <Render {...props} />;\n};\n\n/**\n * Platform-agnostic no-op default components.\n * Each platform (web, RN) wraps MessagePrimitiveParts with its own defaults.\n */\nexport const defaultComponents = {\n Text: () => null,\n Reasoning: () => null,\n Source: () => null,\n Image: () => null,\n File: () => null,\n Unstable_Audio: () => null,\n ToolGroup: ({ children }: PropsWithChildren) => children,\n ReasoningGroup: ({ children }: PropsWithChildren) => children,\n} satisfies MessagePrimitiveParts.Props[\"components\"];\n\ntype MessagePartComponentProps = {\n components: MessagePrimitiveParts.Props[\"components\"];\n};\n\nexport const 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 data,\n generativeUI,\n } = {},\n}) => {\n const aui = useAui();\n const part = useAuiState((s) => s.part);\n\n const type = part.type;\n if (type === \"tool-call\") {\n const addResult = aui.part().addToolResult;\n const resume = aui.part().resumeToolCall;\n if (\"Override\" in tools)\n return <tools.Override {...part} addResult={addResult} resume={resume} />;\n const Tool = tools.by_name?.[part.toolName] ?? tools.Fallback;\n return (\n <ToolUIDisplay\n {...part}\n Fallback={Tool}\n addResult={addResult}\n resume={resume}\n />\n );\n }\n\n if (part.status?.type === \"requires-action\")\n throw new Error(\"Encountered unexpected requires-action status\");\n\n switch (type) {\n case \"text\":\n return <Text {...part} />;\n\n case \"reasoning\":\n return <Reasoning {...part} />;\n\n case \"source\":\n return <Source {...part} />;\n\n case \"image\":\n return <Image {...part} />;\n\n case \"file\":\n return <File {...part} />;\n\n case \"audio\":\n return <Audio {...part} />;\n\n case \"data\": {\n const Data = data?.by_name?.[part.name] ?? data?.Fallback;\n return <DataUIDisplay {...part} Fallback={Data} />;\n }\n\n case \"generative-ui\": {\n if (!generativeUI?.components) {\n if (\n typeof process !== \"undefined\" &&\n process.env?.NODE_ENV !== \"production\"\n ) {\n console.warn(\n \"MessagePrimitive.Parts received a generative-ui part but no \" +\n \"`components.generativeUI.components` allowlist was provided. \" +\n \"Pass an allowlist or render with <MessagePrimitive.GenerativeUI />.\",\n );\n }\n return null;\n }\n return (\n <GenerativeUIRender\n spec={(part as GenerativeUIMessagePart).spec}\n components={generativeUI.components}\n Fallback={generativeUI.Fallback}\n />\n );\n }\n\n default:\n console.warn(`Unknown message part type: ${type}`);\n return null;\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 */\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?.data === next.components?.data &&\n prev.components?.generativeUI === next.components?.generativeUI &&\n prev.components?.ToolGroup === next.components?.ToolGroup &&\n prev.components?.ReasoningGroup === next.components?.ReasoningGroup,\n );\n\nMessagePrimitivePartByIndex.displayName = \"MessagePrimitive.PartByIndex\";\n\nconst EmptyPartFallback: FC<{\n status: MessagePartStatus;\n component: TextMessagePartComponent;\n}> = ({ status, component: Component }) => {\n return (\n <TextMessagePartProvider text=\"\" isRunning={status.type === \"running\"}>\n <Component type=\"text\" text=\"\" status={status} />\n </TextMessagePartProvider>\n );\n};\n\nconst COMPLETE_STATUS: MessagePartStatus = Object.freeze({\n type: \"complete\",\n});\n\nconst RUNNING_STATUS: MessagePartStatus = Object.freeze({\n type: \"running\",\n});\n\nconst EmptyPartsImpl: FC<MessagePartComponentProps> = ({ components }) => {\n const status = useAuiState(\n (s) => (s.message.status ?? COMPLETE_STATUS) as MessagePartStatus,\n );\n\n if (components?.Empty) return <components.Empty status={status} />;\n\n if (status.type !== \"running\") return null;\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\nconst ConditionalEmptyImpl: FC<{\n components: MessagePrimitiveParts.Props[\"components\"];\n enabled: boolean;\n}> = ({ components, enabled }) => {\n const shouldShowEmpty = useAuiState((s) => {\n if (!enabled) return false;\n if (s.message.parts.length === 0) return false;\n\n const lastPart = s.message.parts[s.message.parts.length - 1];\n return lastPart?.type !== \"text\" && lastPart?.type !== \"reasoning\";\n });\n\n if (!shouldShowEmpty) return null;\n return <EmptyParts components={components} />;\n};\n\nconst ConditionalEmpty = memo(\n ConditionalEmptyImpl,\n (prev, next) =>\n prev.enabled === next.enabled &&\n prev.components?.Empty === next.components?.Empty &&\n prev.components?.Text === next.components?.Text,\n);\n\nconst QuoteRendererImpl: FC<{ Quote: QuoteMessagePartComponent }> = ({\n Quote,\n}) => {\n const quoteInfo = useAuiState(getMessageQuote);\n if (!quoteInfo) return null;\n return <Quote text={quoteInfo.text} messageId={quoteInfo.messageId} />;\n};\n\nconst QuoteRenderer = memo(QuoteRendererImpl);\n\nfunction resolveToolRender(\n toolsState: ToolsState,\n part: Extract<PartState, { type: \"tool-call\" }>,\n): ToolCallMessagePartComponent | null {\n const entry = toolsState.tools[part.toolName];\n const named = Array.isArray(entry) ? (entry[0] ?? null) : (entry ?? null);\n if (named) return named;\n if (isMcpAppUri(part.mcp?.app?.resourceUri) && toolsState.mcpApp) {\n return toolsState.mcpApp.render;\n }\n return null;\n}\n\n/**\n * Stable propless component that renders the registered tool UI for the\n * current part context. Reads tool registry and part state from context.\n */\nconst RegisteredToolUI: FC = () => {\n const aui = useAui();\n const part = useAuiState((s) => s.part);\n const Render = useAuiState((s) =>\n s.part.type === \"tool-call\" ? resolveToolRender(s.tools, s.part) : null,\n );\n\n if (!Render || part.type !== \"tool-call\") return null;\n\n return (\n <Render\n {...part}\n addResult={aui.part().addToolResult}\n resume={aui.part().resumeToolCall}\n />\n );\n};\n\n/**\n * Stable propless component that renders the registered data renderer UI\n * for the current part context.\n */\nconst RegisteredDataRendererUI: FC = () => {\n const part = useAuiState((s) => s.part);\n const Render = useAuiState((s) =>\n s.part.type === \"data\"\n ? (getDataRenderer(s.dataRenderers, s.part.name, undefined) ?? null)\n : null,\n );\n\n if (!Render || part.type !== \"data\") return null;\n\n return <Render {...(part as DataMessagePartProps)} />;\n};\n\n/**\n * Fallback component rendered when the children render function returns null.\n * Renders registered tool/data UIs via context.\n * For all other part types, renders nothing.\n *\n * This allows users to write:\n * {({ part }) => {\n * if (part.type === \"text\") return <MyText />;\n * return null; // tool UIs and data UIs still render via registry\n * }}\n *\n * To explicitly render nothing (suppressing registered UIs), return <></>.\n */\nconst DefaultPartFallback: FC = () => {\n const partType = useAuiState((s) => s.part.type);\n\n if (partType === \"tool-call\") return <RegisteredToolUI />;\n if (partType === \"data\") return <RegisteredDataRendererUI />;\n\n return null;\n};\n\nexport type { PartState };\n\n/**\n * Enriched part state passed to children render functions.\n *\n * For tool-call parts, adds `toolUI`, `addResult`, and `resume`.\n * For data parts, adds `dataRendererUI`.\n *\n * The render function is also invoked once with a synthetic empty text part\n * (`{ type: \"text\", text: \"\", status: { type: \"running\" } }`) when the\n * assistant message has no parts yet but is in the running state, so a\n * loading indicator can render. Differentiate this from a real empty text\n * via `part.status?.type === \"running\" && part.text === \"\"`.\n */\nexport type EnrichedPartState =\n | (Extract<PartState, { type: \"tool-call\" }> & {\n /** The registered tool UI element, or null if none registered. */\n readonly toolUI: ReactNode;\n /** Add a tool result to this tool call. */\n addResult: ToolCallMessagePartProps[\"addResult\"];\n /** Resume a tool call waiting for human input. */\n resume: ToolCallMessagePartProps[\"resume\"];\n })\n | (Extract<PartState, { type: \"data\" }> & {\n /** The registered data renderer UI element, or null if none registered. */\n readonly dataRendererUI: ReactNode;\n })\n | Exclude<PartState, { type: \"tool-call\" } | { type: \"data\" }>;\n\nconst EMPTY_RUNNING_TEXT_PART: Extract<EnrichedPartState, { type: \"text\" }> =\n Object.freeze({\n type: \"text\",\n text: \"\",\n status: RUNNING_STATUS,\n });\n\n/**\n * @internal\n * Renders a single part by index, calling `children` with the\n * {@link EnrichedPartState} (tool/data UI enrichments + addResult/resume\n * for tool calls). Shared between `<MessagePrimitive.Parts>` and\n * `<MessagePrimitive.GroupedParts>`. Returns whatever `children`\n * returns — callers decide how to handle a `null` return.\n */\nexport const MessagePartChildren: FC<{\n index: number;\n children: (value: { part: EnrichedPartState }) => ReactNode;\n}> = ({ index, children }) => {\n const aui = useAui();\n // Subscribed (not snapshotted like `tools`) so fallbacks registered\n // after the first render trigger a re-render and `hasUI` re-evaluates.\n const dataRenderers = useAuiState((s) => s.dataRenderers);\n\n return (\n <PartByIndexProvider index={index}>\n <RenderChildrenWithAccessor\n getItemState={(aui) => aui.message().part({ index }).getState()}\n >\n {(getItem) =>\n children({\n get part() {\n const state = getItem();\n if (state.type === \"tool-call\") {\n const toolsState = aui.tools().getState();\n const hasUI = resolveToolRender(toolsState, state) !== null;\n const partMethods = aui.message().part({ index });\n return {\n ...state,\n toolUI: hasUI ? <RegisteredToolUI /> : null,\n addResult: partMethods.addToolResult,\n resume: partMethods.resumeToolCall,\n };\n }\n if (state.type === \"data\") {\n const hasUI =\n getDataRenderer(dataRenderers, state.name, undefined) !==\n undefined;\n return {\n ...state,\n dataRendererUI: hasUI ? <RegisteredDataRendererUI /> : null,\n };\n }\n return state;\n },\n })\n }\n </RenderChildrenWithAccessor>\n </PartByIndexProvider>\n );\n};\n\nconst MessagePrimitivePartsInner: FC<{\n children: (value: { part: EnrichedPartState }) => ReactNode;\n}> = ({ children }) => {\n const contentLength = useAuiState((s) => s.message.parts.length);\n const isRunning = useAuiState(\n (s) => (s.message.status?.type ?? \"complete\") === \"running\",\n );\n const isEmptyRunning = contentLength === 0 && isRunning;\n\n if (contentLength === 0) {\n if (!isEmptyRunning) return null;\n return (\n <TextMessagePartProvider text=\"\" isRunning>\n {children({ part: EMPTY_RUNNING_TEXT_PART })}\n </TextMessagePartProvider>\n );\n }\n\n return (\n <>\n {Array.from({ length: contentLength }, (_, index) => (\n <MessagePartChildren key={index} index={index}>\n {(value) => children(value) ?? <DefaultPartFallback />}\n </MessagePartChildren>\n ))}\n </>\n );\n};\n\n/**\n * Renders the parts of a message with support for multiple content types.\n *\n * This is the platform-agnostic base. Each platform wraps this with its own\n * default components (web uses `<p>`, `<span>`; RN would use `<Text>`, etc.).\n */\nexport const MessagePrimitiveParts: FC<MessagePrimitiveParts.Props> = ({\n components,\n unstable_showEmptyOnNonTextEnd = true,\n children,\n}) => {\n if (children) {\n return <MessagePrimitivePartsInner>{children}</MessagePrimitivePartsInner>;\n }\n return (\n <MessagePrimitivePartsCompat\n components={components}\n unstable_showEmptyOnNonTextEnd={unstable_showEmptyOnNonTextEnd}\n />\n );\n};\n\nMessagePrimitiveParts.displayName = \"MessagePrimitive.Parts\";\n\nconst MessagePrimitivePartsCompat: FC<{\n components: MessagePrimitiveParts.Props[\"components\"];\n unstable_showEmptyOnNonTextEnd: boolean;\n}> = ({ components, unstable_showEmptyOnNonTextEnd }) => {\n const contentLength = useAuiState((s) => s.message.parts.length);\n const useChainOfThought = !!components?.ChainOfThought;\n const messageRanges = useMessagePartsGroups(useChainOfThought);\n\n const partsElements = useMemo(() => {\n if (contentLength === 0) {\n return <EmptyParts components={components} />;\n }\n\n return messageRanges.map((range) => {\n if (range.type === \"single\") {\n return (\n <MessagePrimitivePartByIndex\n key={range.index}\n index={range.index}\n components={components}\n />\n );\n } else if (range.type === \"chainOfThoughtGroup\") {\n const ChainOfThoughtComponent = components?.ChainOfThought;\n if (!ChainOfThoughtComponent) return null;\n return (\n <ChainOfThoughtByIndicesProvider\n key={`chainOfThought-${range.startIndex}`}\n startIndex={range.startIndex}\n endIndex={range.endIndex}\n >\n <ChainOfThoughtComponent />\n </ChainOfThoughtByIndicesProvider>\n );\n } else if (range.type === \"toolGroup\") {\n const ToolGroupComponent =\n components?.ToolGroup ?? defaultComponents.ToolGroup;\n return (\n <ToolGroupComponent\n key={`tool-${range.startIndex}`}\n startIndex={range.startIndex}\n endIndex={range.endIndex}\n >\n {Array.from(\n { length: range.endIndex - range.startIndex + 1 },\n (_, i) => {\n const partIndex = range.startIndex + i;\n return (\n <MessagePrimitivePartByIndex\n key={`part-${partIndex}`}\n index={partIndex}\n components={components}\n />\n );\n },\n )}\n </ToolGroupComponent>\n );\n } else {\n // reasoningGroup\n const ReasoningGroupComponent =\n components?.ReasoningGroup ?? defaultComponents.ReasoningGroup;\n return (\n <ReasoningGroupComponent\n key={`reasoning-${range.startIndex}`}\n startIndex={range.startIndex}\n endIndex={range.endIndex}\n >\n {Array.from(\n { length: range.endIndex - range.startIndex + 1 },\n (_, i) => {\n const partIndex = range.startIndex + i;\n return (\n <MessagePrimitivePartByIndex\n key={`part-${partIndex}`}\n index={partIndex}\n components={components}\n />\n );\n },\n )}\n </ReasoningGroupComponent>\n );\n }\n });\n }, [messageRanges, components, contentLength]);\n\n return (\n <>\n {components?.Quote && <QuoteRenderer Quote={components.Quote} />}\n {partsElements}\n <ConditionalEmpty\n components={components}\n enabled={unstable_showEmptyOnNonTextEnd}\n />\n </>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"MessageParts.js","names":[],"sources":["../../../../src/react/primitives/message/MessageParts.tsx"],"sourcesContent":["import {\n type ComponentType,\n type FC,\n type ReactNode,\n memo,\n type PropsWithChildren,\n useMemo,\n} from \"react\";\nimport {\n RenderChildrenWithAccessor,\n useAuiState,\n useAui,\n} from \"@assistant-ui/store\";\nimport type { PartState } from \"../../../store/scopes/part\";\nimport { PartByIndexProvider } from \"../../providers/PartByIndexProvider\";\nimport { TextMessagePartProvider } from \"../../providers/TextMessagePartProvider\";\nimport { ChainOfThoughtByIndicesProvider } from \"../../providers/ChainOfThoughtByIndicesProvider\";\nimport { getMessageQuote } from \"../../utils/getMessageQuote\";\nimport type {\n Unstable_AudioMessagePartComponent,\n DataMessagePartComponent,\n DataMessagePartProps,\n EmptyMessagePartComponent,\n TextMessagePartComponent,\n ImageMessagePartComponent,\n SourceMessagePartComponent,\n ToolCallMessagePartComponent,\n ToolCallMessagePartProps,\n FileMessagePartComponent,\n ReasoningMessagePartComponent,\n ReasoningGroupComponent,\n QuoteMessagePartComponent,\n GenerativeUIComponentRegistry,\n} from \"../../types/MessagePartComponentTypes\";\nimport { GenerativeUIRender } from \"../generativeUI/GenerativeUI\";\nimport {\n isMcpAppUri,\n type MessagePartStatus,\n type GenerativeUIMessagePart,\n} from \"../../../types/message\";\nimport type { DataRenderersState } from \"../../types/scopes/dataRenderers\";\nimport type { ToolsState } from \"../../types/scopes/tools\";\nimport { useShallow } from \"zustand/shallow\";\n\ntype MessagePartRange =\n | { type: \"single\"; index: number }\n | { type: \"toolGroup\"; startIndex: number; endIndex: number }\n | { type: \"reasoningGroup\"; startIndex: number; endIndex: number }\n | { type: \"chainOfThoughtGroup\"; startIndex: number; endIndex: number };\n\n/**\n * Creates a group state manager for a specific part type.\n * Returns functions to start, end, and finalize groups.\n */\nconst createGroupState = <\n T extends \"toolGroup\" | \"reasoningGroup\" | \"chainOfThoughtGroup\",\n>(\n groupType: T,\n) => {\n let start = -1;\n\n return {\n startGroup: (index: number) => {\n if (start === -1) {\n start = index;\n }\n },\n endGroup: (endIndex: number, ranges: MessagePartRange[]) => {\n if (start !== -1) {\n ranges.push({\n type: groupType,\n startIndex: start,\n endIndex,\n } as MessagePartRange);\n start = -1;\n }\n },\n finalize: (endIndex: number, ranges: MessagePartRange[]) => {\n if (start !== -1) {\n ranges.push({\n type: groupType,\n startIndex: start,\n endIndex,\n } as MessagePartRange);\n }\n },\n };\n};\n\n/**\n * Groups consecutive tool-call and reasoning message parts into ranges.\n * Always groups tool calls and reasoning parts, even if there's only one.\n * When useChainOfThought is true, groups tool-call and reasoning parts together.\n */\nconst groupMessageParts = (\n messageTypes: readonly string[],\n useChainOfThought: boolean,\n): MessagePartRange[] => {\n const ranges: MessagePartRange[] = [];\n\n if (useChainOfThought) {\n const chainOfThoughtGroup = createGroupState(\"chainOfThoughtGroup\");\n\n for (let i = 0; i < messageTypes.length; i++) {\n const type = messageTypes[i];\n\n if (type === \"tool-call\" || type === \"reasoning\") {\n chainOfThoughtGroup.startGroup(i);\n } else {\n chainOfThoughtGroup.endGroup(i - 1, ranges);\n ranges.push({ type: \"single\", index: i });\n }\n }\n\n chainOfThoughtGroup.finalize(messageTypes.length - 1, ranges);\n } else {\n const toolGroup = createGroupState(\"toolGroup\");\n const reasoningGroup = createGroupState(\"reasoningGroup\");\n\n for (let i = 0; i < messageTypes.length; i++) {\n const type = messageTypes[i];\n\n if (type === \"tool-call\") {\n reasoningGroup.endGroup(i - 1, ranges);\n toolGroup.startGroup(i);\n } else if (type === \"reasoning\") {\n toolGroup.endGroup(i - 1, ranges);\n reasoningGroup.startGroup(i);\n } else {\n toolGroup.endGroup(i - 1, ranges);\n reasoningGroup.endGroup(i - 1, ranges);\n ranges.push({ type: \"single\", index: i });\n }\n }\n\n toolGroup.finalize(messageTypes.length - 1, ranges);\n reasoningGroup.finalize(messageTypes.length - 1, ranges);\n }\n\n return ranges;\n};\n\nconst useMessagePartsGroups = (\n useChainOfThought: boolean,\n): MessagePartRange[] => {\n const messageTypes = useAuiState(\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, useChainOfThought);\n }, [messageTypes, useChainOfThought]);\n};\n\nexport namespace MessagePrimitiveParts {\n type DataConfig = {\n /** Map data event names to specific components */\n by_name?: Record<string, DataMessagePartComponent | undefined> | undefined;\n /** Fallback component for unmatched data events */\n Fallback?: DataMessagePartComponent | undefined;\n };\n\n type BaseComponents = {\n /** Component for rendering empty messages */\n Empty?: EmptyMessagePartComponent | undefined;\n /** Component for rendering text content */\n Text?: TextMessagePartComponent | 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 data part rendering */\n data?: DataConfig | undefined;\n /** Component for rendering a quoted message reference (from metadata, not parts) */\n Quote?: QuoteMessagePartComponent | undefined;\n /**\n * Configuration for generative-ui part rendering.\n *\n * `components` is the consumer-provided allowlist of React components\n * the agent's JSON spec is permitted to render. Any name not present in\n * the registry is rejected with a typed `GenerativeUIRenderError` —\n * this is the security boundary in the same-realm rendering path.\n */\n generativeUI?:\n | {\n /** The component allowlist (the security boundary). */\n components: GenerativeUIComponentRegistry;\n /** Optional fallback for unknown component names. */\n Fallback?:\n | ComponentType<{ component: string; props?: unknown }>\n | undefined;\n }\n | undefined;\n };\n\n type ToolsConfig =\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\n /**\n * Standard component configuration for rendering reasoning and tool-call parts\n * individually (with optional grouping).\n *\n * Cannot be combined with `ChainOfThought`.\n */\n type StandardComponents = BaseComponents & {\n /** Component for rendering reasoning content (typically hidden) */\n Reasoning?: ReasoningMessagePartComponent | undefined;\n /** Configuration for tool call rendering */\n tools?: ToolsConfig | undefined;\n\n /**\n * Component for rendering grouped consecutive tool calls.\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 Use `<MessagePrimitive.GroupedParts>` with a custom `groupBy` instead.\n */\n ToolGroup?: ComponentType<\n PropsWithChildren<{ startIndex: number; endIndex: number }>\n >;\n\n /**\n * Component for rendering grouped reasoning parts.\n *\n * @param startIndex - Index of the first reasoning part in the group\n * @param endIndex - Index of the last reasoning part in the group\n * @param children - Rendered reasoning part components\n *\n * @deprecated Use `<MessagePrimitive.GroupedParts>` with a custom `groupBy` instead.\n */\n ReasoningGroup?: ReasoningGroupComponent;\n\n ChainOfThought?: never;\n };\n\n /**\n * Chain of thought component configuration.\n *\n * When `ChainOfThought` is set, it takes control of rendering ALL reasoning and\n * tool-call parts in the message. The `Reasoning`, `tools`, `ReasoningGroup`, and\n * `ToolGroup` components cannot be used alongside it.\n */\n type ChainOfThoughtComponents = BaseComponents & {\n /**\n * @deprecated Use `<MessagePrimitive.GroupedParts>` with a `groupBy`\n * that returns `[\"group-thought\", ...]` for reasoning and tool-call\n * parts. See `@assistant-ui/ui` for a worked example.\n */\n ChainOfThought: ComponentType;\n\n Reasoning?: never;\n tools?: never;\n ToolGroup?: never;\n ReasoningGroup?: never;\n };\n\n export type Props =\n | {\n /**\n * Component configuration for rendering different types of message content.\n *\n * Use either `Reasoning`/`tools`/`ToolGroup`/`ReasoningGroup` for standard rendering,\n * or `ChainOfThought` to group all reasoning and tool-call parts into a single\n * collapsible component. These two modes are mutually exclusive.\n */\n components?: StandardComponents | ChainOfThoughtComponents | undefined;\n /**\n * When enabled, shows the Empty component if the last part in the message\n * is anything other than Text or Reasoning.\n *\n * @experimental This API is experimental and may change in future versions.\n * @default true\n */\n unstable_showEmptyOnNonTextEnd?: boolean | undefined;\n children?: never;\n }\n | {\n /** Render function called for each part. Receives the enriched part state. */\n children: (value: { part: EnrichedPartState }) => ReactNode;\n components?: never;\n unstable_showEmptyOnNonTextEnd?: never;\n };\n}\n\nconst ToolUIDisplay = ({\n Fallback,\n ...props\n}: {\n Fallback: ToolCallMessagePartComponent | undefined;\n} & ToolCallMessagePartProps) => {\n const Render = useAuiState((s) => {\n const Render = s.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 getDataRenderer = (\n dataRenderers: DataRenderersState,\n name: string,\n inlineFallback: DataMessagePartComponent | undefined,\n): DataMessagePartComponent | undefined => {\n const named = dataRenderers.renderers[name]?.[0];\n if (named) return named;\n return dataRenderers.fallbacks[0] ?? inlineFallback;\n};\n\nconst DataUIDisplay = ({\n Fallback,\n ...props\n}: {\n Fallback: DataMessagePartComponent | undefined;\n} & DataMessagePartProps) => {\n const Render = useAuiState((s) =>\n getDataRenderer(s.dataRenderers, props.name, Fallback),\n );\n if (!Render) return null;\n return <Render {...props} />;\n};\n\n/**\n * Platform-agnostic no-op default components.\n * Each platform (web, RN) wraps MessagePrimitiveParts with its own defaults.\n */\nexport const defaultComponents = {\n Text: () => null,\n Reasoning: () => null,\n Source: () => null,\n Image: () => null,\n File: () => null,\n Unstable_Audio: () => null,\n ToolGroup: ({ children }: PropsWithChildren) => children,\n ReasoningGroup: ({ children }: PropsWithChildren) => children,\n} satisfies MessagePrimitiveParts.Props[\"components\"];\n\ntype MessagePartComponentProps = {\n components: MessagePrimitiveParts.Props[\"components\"];\n};\n\nexport const 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 data,\n generativeUI,\n } = {},\n}) => {\n const aui = useAui();\n const part = useAuiState((s) => s.part);\n\n const type = part.type;\n if (type === \"tool-call\") {\n const addResult = aui.part().addToolResult;\n const resume = aui.part().resumeToolCall;\n const respondToApproval = aui.part().respondToToolApproval;\n if (\"Override\" in tools)\n return (\n <tools.Override\n {...part}\n addResult={addResult}\n resume={resume}\n respondToApproval={respondToApproval}\n />\n );\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 respondToApproval={respondToApproval}\n />\n );\n }\n\n if (part.status?.type === \"requires-action\")\n throw new Error(\"Encountered unexpected requires-action status\");\n\n switch (type) {\n case \"text\":\n return <Text {...part} />;\n\n case \"reasoning\":\n return <Reasoning {...part} />;\n\n case \"source\":\n return <Source {...part} />;\n\n case \"image\":\n return <Image {...part} />;\n\n case \"file\":\n return <File {...part} />;\n\n case \"audio\":\n return <Audio {...part} />;\n\n case \"data\": {\n const Data = data?.by_name?.[part.name] ?? data?.Fallback;\n return <DataUIDisplay {...part} Fallback={Data} />;\n }\n\n case \"generative-ui\": {\n if (!generativeUI?.components) {\n if (\n typeof process !== \"undefined\" &&\n process.env?.NODE_ENV !== \"production\"\n ) {\n console.warn(\n \"MessagePrimitive.Parts received a generative-ui part but no \" +\n \"`components.generativeUI.components` allowlist was provided. \" +\n \"Pass an allowlist or render with <MessagePrimitive.GenerativeUI />.\",\n );\n }\n return null;\n }\n return (\n <GenerativeUIRender\n spec={(part as GenerativeUIMessagePart).spec}\n components={generativeUI.components}\n Fallback={generativeUI.Fallback}\n />\n );\n }\n\n default:\n console.warn(`Unknown message part type: ${type}`);\n return null;\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 */\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?.data === next.components?.data &&\n prev.components?.generativeUI === next.components?.generativeUI &&\n prev.components?.ToolGroup === next.components?.ToolGroup &&\n prev.components?.ReasoningGroup === next.components?.ReasoningGroup,\n );\n\nMessagePrimitivePartByIndex.displayName = \"MessagePrimitive.PartByIndex\";\n\nconst EmptyPartFallback: FC<{\n status: MessagePartStatus;\n component: TextMessagePartComponent;\n}> = ({ status, component: Component }) => {\n return (\n <TextMessagePartProvider text=\"\" isRunning={status.type === \"running\"}>\n <Component type=\"text\" text=\"\" status={status} />\n </TextMessagePartProvider>\n );\n};\n\nconst COMPLETE_STATUS: MessagePartStatus = Object.freeze({\n type: \"complete\",\n});\n\nconst RUNNING_STATUS: MessagePartStatus = Object.freeze({\n type: \"running\",\n});\n\nconst EmptyPartsImpl: FC<MessagePartComponentProps> = ({ components }) => {\n const status = useAuiState(\n (s) => (s.message.status ?? COMPLETE_STATUS) as MessagePartStatus,\n );\n\n if (components?.Empty) return <components.Empty status={status} />;\n\n if (status.type !== \"running\") return null;\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\nconst ConditionalEmptyImpl: FC<{\n components: MessagePrimitiveParts.Props[\"components\"];\n enabled: boolean;\n}> = ({ components, enabled }) => {\n const shouldShowEmpty = useAuiState((s) => {\n if (!enabled) return false;\n if (s.message.parts.length === 0) return false;\n\n const lastPart = s.message.parts[s.message.parts.length - 1];\n return lastPart?.type !== \"text\" && lastPart?.type !== \"reasoning\";\n });\n\n if (!shouldShowEmpty) return null;\n return <EmptyParts components={components} />;\n};\n\nconst ConditionalEmpty = memo(\n ConditionalEmptyImpl,\n (prev, next) =>\n prev.enabled === next.enabled &&\n prev.components?.Empty === next.components?.Empty &&\n prev.components?.Text === next.components?.Text,\n);\n\nconst QuoteRendererImpl: FC<{ Quote: QuoteMessagePartComponent }> = ({\n Quote,\n}) => {\n const quoteInfo = useAuiState(getMessageQuote);\n if (!quoteInfo) return null;\n return <Quote text={quoteInfo.text} messageId={quoteInfo.messageId} />;\n};\n\nconst QuoteRenderer = memo(QuoteRendererImpl);\n\nfunction resolveToolRender(\n toolsState: ToolsState,\n part: Extract<PartState, { type: \"tool-call\" }>,\n): ToolCallMessagePartComponent | null {\n const entry = toolsState.tools[part.toolName];\n const named = Array.isArray(entry) ? (entry[0] ?? null) : (entry ?? null);\n if (named) return named;\n if (isMcpAppUri(part.mcp?.app?.resourceUri) && toolsState.mcpApp) {\n return toolsState.mcpApp.render;\n }\n return null;\n}\n\n/**\n * Stable propless component that renders the registered tool UI for the\n * current part context. Reads tool registry and part state from context.\n */\nconst RegisteredToolUI: FC = () => {\n const aui = useAui();\n const part = useAuiState((s) => s.part);\n const Render = useAuiState((s) =>\n s.part.type === \"tool-call\" ? resolveToolRender(s.tools, s.part) : null,\n );\n\n if (!Render || part.type !== \"tool-call\") return null;\n\n return (\n <Render\n {...part}\n addResult={aui.part().addToolResult}\n resume={aui.part().resumeToolCall}\n respondToApproval={aui.part().respondToToolApproval}\n />\n );\n};\n\n/**\n * Stable propless component that renders the registered data renderer UI\n * for the current part context.\n */\nconst RegisteredDataRendererUI: FC = () => {\n const part = useAuiState((s) => s.part);\n const Render = useAuiState((s) =>\n s.part.type === \"data\"\n ? (getDataRenderer(s.dataRenderers, s.part.name, undefined) ?? null)\n : null,\n );\n\n if (!Render || part.type !== \"data\") return null;\n\n return <Render {...(part as DataMessagePartProps)} />;\n};\n\n/**\n * Fallback component rendered when the children render function returns null.\n * Renders registered tool/data UIs via context.\n * For all other part types, renders nothing.\n *\n * This allows users to write:\n * {({ part }) => {\n * if (part.type === \"text\") return <MyText />;\n * return null; // tool UIs and data UIs still render via registry\n * }}\n *\n * To explicitly render nothing (suppressing registered UIs), return <></>.\n */\nconst DefaultPartFallback: FC = () => {\n const partType = useAuiState((s) => s.part.type);\n\n if (partType === \"tool-call\") return <RegisteredToolUI />;\n if (partType === \"data\") return <RegisteredDataRendererUI />;\n\n return null;\n};\n\nexport type { PartState };\n\n/**\n * Enriched part state passed to children render functions.\n *\n * For tool-call parts, adds `toolUI`, `addResult`, and `resume`.\n * For data parts, adds `dataRendererUI`.\n *\n * The render function is also invoked once with a synthetic empty text part\n * (`{ type: \"text\", text: \"\", status: { type: \"running\" } }`) when the\n * assistant message has no parts yet but is in the running state, so a\n * loading indicator can render. Differentiate this from a real empty text\n * via `part.status?.type === \"running\" && part.text === \"\"`.\n */\nexport type EnrichedPartState =\n | (Extract<PartState, { type: \"tool-call\" }> & {\n /** The registered tool UI element, or null if none registered. */\n readonly toolUI: ReactNode;\n /** Add a tool result to this tool call. */\n addResult: ToolCallMessagePartProps[\"addResult\"];\n /** Resume a tool call waiting for human input. */\n resume: ToolCallMessagePartProps[\"resume\"];\n /** Respond to a server-side tool approval gate. */\n respondToApproval: ToolCallMessagePartProps[\"respondToApproval\"];\n })\n | (Extract<PartState, { type: \"data\" }> & {\n /** The registered data renderer UI element, or null if none registered. */\n readonly dataRendererUI: ReactNode;\n })\n | Exclude<PartState, { type: \"tool-call\" } | { type: \"data\" }>;\n\nconst EMPTY_RUNNING_TEXT_PART: Extract<EnrichedPartState, { type: \"text\" }> =\n Object.freeze({\n type: \"text\",\n text: \"\",\n status: RUNNING_STATUS,\n });\n\n/**\n * @internal\n * Renders a single part by index, calling `children` with the\n * {@link EnrichedPartState} (tool/data UI enrichments + addResult/resume\n * for tool calls). Shared between `<MessagePrimitive.Parts>` and\n * `<MessagePrimitive.GroupedParts>`. Returns whatever `children`\n * returns — callers decide how to handle a `null` return.\n */\nexport const MessagePartChildren: FC<{\n index: number;\n children: (value: { part: EnrichedPartState }) => ReactNode;\n}> = ({ index, children }) => {\n const aui = useAui();\n // Subscribed (not snapshotted like `tools`) so fallbacks registered\n // after the first render trigger a re-render and `hasUI` re-evaluates.\n const dataRenderers = useAuiState((s) => s.dataRenderers);\n\n return (\n <PartByIndexProvider index={index}>\n <RenderChildrenWithAccessor\n getItemState={(aui) => aui.message().part({ index }).getState()}\n >\n {(getItem) =>\n children({\n get part() {\n const state = getItem();\n if (state.type === \"tool-call\") {\n const toolsState = aui.tools().getState();\n const hasUI = resolveToolRender(toolsState, state) !== null;\n const partMethods = aui.message().part({ index });\n return {\n ...state,\n toolUI: hasUI ? <RegisteredToolUI /> : null,\n addResult: partMethods.addToolResult,\n resume: partMethods.resumeToolCall,\n respondToApproval: partMethods.respondToToolApproval,\n };\n }\n if (state.type === \"data\") {\n const hasUI =\n getDataRenderer(dataRenderers, state.name, undefined) !==\n undefined;\n return {\n ...state,\n dataRendererUI: hasUI ? <RegisteredDataRendererUI /> : null,\n };\n }\n return state;\n },\n })\n }\n </RenderChildrenWithAccessor>\n </PartByIndexProvider>\n );\n};\n\nconst MessagePrimitivePartsInner: FC<{\n children: (value: { part: EnrichedPartState }) => ReactNode;\n}> = ({ children }) => {\n const contentLength = useAuiState((s) => s.message.parts.length);\n const isRunning = useAuiState(\n (s) => (s.message.status?.type ?? \"complete\") === \"running\",\n );\n const isEmptyRunning = contentLength === 0 && isRunning;\n\n if (contentLength === 0) {\n if (!isEmptyRunning) return null;\n return (\n <TextMessagePartProvider text=\"\" isRunning>\n {children({ part: EMPTY_RUNNING_TEXT_PART })}\n </TextMessagePartProvider>\n );\n }\n\n return (\n <>\n {Array.from({ length: contentLength }, (_, index) => (\n <MessagePartChildren key={index} index={index}>\n {(value) => children(value) ?? <DefaultPartFallback />}\n </MessagePartChildren>\n ))}\n </>\n );\n};\n\n/**\n * Renders the parts of a message with support for multiple content types.\n *\n * This is the platform-agnostic base. Each platform wraps this with its own\n * default components (web uses `<p>`, `<span>`; RN would use `<Text>`, etc.).\n */\nexport const MessagePrimitiveParts: FC<MessagePrimitiveParts.Props> = ({\n components,\n unstable_showEmptyOnNonTextEnd = true,\n children,\n}) => {\n if (children) {\n return <MessagePrimitivePartsInner>{children}</MessagePrimitivePartsInner>;\n }\n return (\n <MessagePrimitivePartsCompat\n components={components}\n unstable_showEmptyOnNonTextEnd={unstable_showEmptyOnNonTextEnd}\n />\n );\n};\n\nMessagePrimitiveParts.displayName = \"MessagePrimitive.Parts\";\n\nconst MessagePrimitivePartsCompat: FC<{\n components: MessagePrimitiveParts.Props[\"components\"];\n unstable_showEmptyOnNonTextEnd: boolean;\n}> = ({ components, unstable_showEmptyOnNonTextEnd }) => {\n const contentLength = useAuiState((s) => s.message.parts.length);\n const useChainOfThought = !!components?.ChainOfThought;\n const messageRanges = useMessagePartsGroups(useChainOfThought);\n\n const partsElements = useMemo(() => {\n if (contentLength === 0) {\n return <EmptyParts components={components} />;\n }\n\n return messageRanges.map((range) => {\n if (range.type === \"single\") {\n return (\n <MessagePrimitivePartByIndex\n key={range.index}\n index={range.index}\n components={components}\n />\n );\n } else if (range.type === \"chainOfThoughtGroup\") {\n const ChainOfThoughtComponent = components?.ChainOfThought;\n if (!ChainOfThoughtComponent) return null;\n return (\n <ChainOfThoughtByIndicesProvider\n key={`chainOfThought-${range.startIndex}`}\n startIndex={range.startIndex}\n endIndex={range.endIndex}\n >\n <ChainOfThoughtComponent />\n </ChainOfThoughtByIndicesProvider>\n );\n } else if (range.type === \"toolGroup\") {\n const ToolGroupComponent =\n components?.ToolGroup ?? defaultComponents.ToolGroup;\n return (\n <ToolGroupComponent\n key={`tool-${range.startIndex}`}\n startIndex={range.startIndex}\n endIndex={range.endIndex}\n >\n {Array.from(\n { length: range.endIndex - range.startIndex + 1 },\n (_, i) => {\n const partIndex = range.startIndex + i;\n return (\n <MessagePrimitivePartByIndex\n key={`part-${partIndex}`}\n index={partIndex}\n components={components}\n />\n );\n },\n )}\n </ToolGroupComponent>\n );\n } else {\n // reasoningGroup\n const ReasoningGroupComponent =\n components?.ReasoningGroup ?? defaultComponents.ReasoningGroup;\n return (\n <ReasoningGroupComponent\n key={`reasoning-${range.startIndex}`}\n startIndex={range.startIndex}\n endIndex={range.endIndex}\n >\n {Array.from(\n { length: range.endIndex - range.startIndex + 1 },\n (_, i) => {\n const partIndex = range.startIndex + i;\n return (\n <MessagePrimitivePartByIndex\n key={`part-${partIndex}`}\n index={partIndex}\n components={components}\n />\n );\n },\n )}\n </ReasoningGroupComponent>\n );\n }\n });\n }, [messageRanges, components, contentLength]);\n\n return (\n <>\n {components?.Quote && <QuoteRenderer Quote={components.Quote} />}\n {partsElements}\n <ConditionalEmpty\n components={components}\n enabled={unstable_showEmptyOnNonTextEnd}\n />\n </>\n );\n};\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"TextMessagePartProvider.d.ts","names":[],"sources":["../../../src/react/providers/TextMessagePartProvider.tsx"],"mappings":";;;cAkCa,uBAAA,EAAyB,EAAE,CACtC,iBAAA;EACE,IAAA;EACA,SAAA;AAAA"}
1
+ {"version":3,"file":"TextMessagePartProvider.d.ts","names":[],"sources":["../../../src/react/providers/TextMessagePartProvider.tsx"],"mappings":";;;cAqCa,uBAAA,EAAyB,EAAE,CACtC,iBAAA;EACE,IAAA;EACA,SAAA;AAAA"}
@@ -15,6 +15,9 @@ const TextMessagePartClient = resource(({ text, isRunning }) => {
15
15
  },
16
16
  resumeToolCall: () => {
17
17
  throw new Error("Not supported");
18
+ },
19
+ respondToToolApproval: () => {
20
+ throw new Error("Not supported");
18
21
  }
19
22
  };
20
23
  });
@@ -1 +1 @@
1
- {"version":3,"file":"TextMessagePartProvider.js","names":[],"sources":["../../../src/react/providers/TextMessagePartProvider.tsx"],"sourcesContent":["import type { FC, PropsWithChildren } from \"react\";\nimport { useAui, AuiProvider, type ClientOutput } from \"@assistant-ui/store\";\nimport type { PartState } from \"../../store/scopes/part\";\nimport { resource, tapMemo } from \"@assistant-ui/tap\";\n\nconst TextMessagePartClient = resource(\n ({\n text,\n isRunning,\n }: {\n text: string;\n isRunning: boolean;\n }): ClientOutput<\"part\"> => {\n const state = tapMemo<PartState>(\n () => ({\n type: \"text\",\n text,\n status: isRunning ? { type: \"running\" } : { type: \"complete\" },\n }),\n [text, isRunning],\n );\n\n return {\n getState: () => state,\n addToolResult: () => {\n throw new Error(\"Not supported\");\n },\n resumeToolCall: () => {\n throw new Error(\"Not supported\");\n },\n };\n },\n);\n\nexport const TextMessagePartProvider: FC<\n PropsWithChildren<{\n text: string;\n isRunning?: boolean;\n }>\n> = ({ text, isRunning = false, children }) => {\n const aui = useAui({\n part: TextMessagePartClient({ text, isRunning }),\n });\n\n return <AuiProvider value={aui}>{children}</AuiProvider>;\n};\n"],"mappings":";;;;AAKA,MAAM,wBAAwB,UAC3B,EACC,MACA,gBAI0B;CAC1B,MAAM,QAAQ,eACL;EACL,MAAM;EACN;EACA,QAAQ,YAAY,EAAE,MAAM,UAAU,IAAI,EAAE,MAAM,WAAW;CAC/D,IACA,CAAC,MAAM,SAAS,CAClB;CAEA,OAAO;EACL,gBAAgB;EAChB,qBAAqB;GACnB,MAAM,IAAI,MAAM,eAAe;EACjC;EACA,sBAAsB;GACpB,MAAM,IAAI,MAAM,eAAe;EACjC;CACF;AACF,CACF;AAEA,MAAa,2BAKR,EAAE,MAAM,YAAY,OAAO,eAAe;CAK7C,OAAO,oBAAC,aAAD;EAAa,OAJR,OAAO,EACjB,MAAM,sBAAsB;GAAE;GAAM;EAAU,CAAC,EACjD,CAE6B;EAAI;CAAsB,CAAA;AACzD"}
1
+ {"version":3,"file":"TextMessagePartProvider.js","names":[],"sources":["../../../src/react/providers/TextMessagePartProvider.tsx"],"sourcesContent":["import type { FC, PropsWithChildren } from \"react\";\nimport { useAui, AuiProvider, type ClientOutput } from \"@assistant-ui/store\";\nimport type { PartState } from \"../../store/scopes/part\";\nimport { resource, tapMemo } from \"@assistant-ui/tap\";\n\nconst TextMessagePartClient = resource(\n ({\n text,\n isRunning,\n }: {\n text: string;\n isRunning: boolean;\n }): ClientOutput<\"part\"> => {\n const state = tapMemo<PartState>(\n () => ({\n type: \"text\",\n text,\n status: isRunning ? { type: \"running\" } : { type: \"complete\" },\n }),\n [text, isRunning],\n );\n\n return {\n getState: () => state,\n addToolResult: () => {\n throw new Error(\"Not supported\");\n },\n resumeToolCall: () => {\n throw new Error(\"Not supported\");\n },\n respondToToolApproval: () => {\n throw new Error(\"Not supported\");\n },\n };\n },\n);\n\nexport const TextMessagePartProvider: FC<\n PropsWithChildren<{\n text: string;\n isRunning?: boolean;\n }>\n> = ({ text, isRunning = false, children }) => {\n const aui = useAui({\n part: TextMessagePartClient({ text, isRunning }),\n });\n\n return <AuiProvider value={aui}>{children}</AuiProvider>;\n};\n"],"mappings":";;;;AAKA,MAAM,wBAAwB,UAC3B,EACC,MACA,gBAI0B;CAC1B,MAAM,QAAQ,eACL;EACL,MAAM;EACN;EACA,QAAQ,YAAY,EAAE,MAAM,UAAU,IAAI,EAAE,MAAM,WAAW;CAC/D,IACA,CAAC,MAAM,SAAS,CAClB;CAEA,OAAO;EACL,gBAAgB;EAChB,qBAAqB;GACnB,MAAM,IAAI,MAAM,eAAe;EACjC;EACA,sBAAsB;GACpB,MAAM,IAAI,MAAM,eAAe;EACjC;EACA,6BAA6B;GAC3B,MAAM,IAAI,MAAM,eAAe;EACjC;CACF;AACF,CACF;AAEA,MAAa,2BAKR,EAAE,MAAM,YAAY,OAAO,eAAe;CAK7C,OAAO,oBAAC,aAAD;EAAa,OAJR,OAAO,EACjB,MAAM,sBAAsB;GAAE;GAAM;EAAU,CAAC,EACjD,CAE6B;EAAI;CAAsB,CAAA;AACzD"}
@@ -4,7 +4,7 @@ import { ModelContext } from "../../model-context/types.js";
4
4
  import { ThreadMessageLike } from "../../runtime/utils/thread-message-like.js";
5
5
  import { ExportedMessageRepository } from "../../runtime/utils/message-repository.js";
6
6
  import { EditComposerRuntimeCore, ThreadComposerRuntimeCore } from "../../runtime/interfaces/composer-runtime-core.js";
7
- import { AddToolResultOptions, ResumeRunConfig, ResumeToolCallOptions, RuntimeCapabilities, SpeechState, StartRunConfig, SubmitFeedbackOptions, ThreadRuntimeEventCallback, ThreadRuntimeEventType, ThreadSuggestion, VoiceSessionState } from "../../runtime/interfaces/thread-runtime-core.js";
7
+ import { AddToolResultOptions, RespondToToolApprovalOptions, ResumeRunConfig, ResumeToolCallOptions, RuntimeCapabilities, SpeechState, StartRunConfig, SubmitFeedbackOptions, ThreadRuntimeEventCallback, ThreadRuntimeEventType, ThreadSuggestion, VoiceSessionState } from "../../runtime/interfaces/thread-runtime-core.js";
8
8
  import { ThreadListRuntimeCore } from "../../runtime/interfaces/thread-list-runtime-core.js";
9
9
  import { BaseSubscribable } from "../../subscribable/subscribable.js";
10
10
  import { AssistantRuntime } from "../../runtime/api/assistant-runtime.js";
@@ -32,6 +32,7 @@ declare class RemoteThreadListHookInstanceManager extends BaseSubscribable {
32
32
  cancelRun: () => void;
33
33
  addToolResult: (options: AddToolResultOptions) => void;
34
34
  resumeToolCall: (options: ResumeToolCallOptions) => void;
35
+ respondToToolApproval: (options: RespondToToolApprovalOptions) => void;
35
36
  speak: (messageId: string) => void;
36
37
  stopSpeaking: () => void;
37
38
  connectVoice: () => void;
@@ -78,6 +79,7 @@ declare class RemoteThreadListHookInstanceManager extends BaseSubscribable {
78
79
  cancelRun: () => void;
79
80
  addToolResult: (options: AddToolResultOptions) => void;
80
81
  resumeToolCall: (options: ResumeToolCallOptions) => void;
82
+ respondToToolApproval: (options: RespondToToolApprovalOptions) => void;
81
83
  speak: (messageId: string) => void;
82
84
  stopSpeaking: () => void;
83
85
  connectVoice: () => void;
@@ -1 +1 @@
1
- {"version":3,"file":"RemoteThreadListHookInstanceManager.d.ts","names":[],"sources":["../../../src/react/runtimes/RemoteThreadListHookInstanceManager.tsx"],"mappings":";;;;;;;;;;;;;KAuBK,oBAAA,SAA6B,gBAAgB;AAAA,cAcrC,mCAAA,SAA4C,gBAAA;EAAA,QAC/C,cAAA;EAAA,QAGA,SAAA;EAAA,QACA,0BAAA;EAAA,QACA,MAAA;cAGN,WAAA,EAAa,oBAAA,EACb,MAAA,EAAQ,qBAAA;EAOH,kBAAA,CAAmB,QAAA,WAAgB,OAAA,CAAA,QAAA;;;eAPX,aAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+BxB,oBAAA,CAAqB,QAAA,WAAgB,QAAA;;;eAxBF,aAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8BnC,iBAAA,CAAkB,QAAA;EAKlB,cAAA,CAAe,cAAA,EAAgB,oBAAA;EAAA,QAS9B,cAAA;EAAA,QAgEA,0BAAA;EAqCD,+BAAA,EAAiC,EAAA;IACtC,QAAA,EAAU,aAAA,CAAc,iBAAA;EAAA;AAAA"}
1
+ {"version":3,"file":"RemoteThreadListHookInstanceManager.d.ts","names":[],"sources":["../../../src/react/runtimes/RemoteThreadListHookInstanceManager.tsx"],"mappings":";;;;;;;;;;;;;KAuBK,oBAAA,SAA6B,gBAAgB;AAAA,cAcrC,mCAAA,SAA4C,gBAAA;EAAA,QAC/C,cAAA;EAAA,QAGA,SAAA;EAAA,QACA,0BAAA;EAAA,QACA,MAAA;cAGN,WAAA,EAAa,oBAAA,EACb,MAAA,EAAQ,qBAAA;EAOH,kBAAA,CAAmB,QAAA,WAAgB,OAAA,CAAA,QAAA;;;eAPX,aAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+BxB,oBAAA,CAAqB,QAAA,WAAgB,QAAA;;;eAxBF,aAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8BnC,iBAAA,CAAkB,QAAA;EAKlB,cAAA,CAAe,cAAA,EAAgB,oBAAA;EAAA,QAS9B,cAAA;EAAA,QAgEA,0BAAA;EAqCD,+BAAA,EAAiC,EAAA;IACtC,QAAA,EAAU,aAAA,CAAc,iBAAA;EAAA;AAAA"}