@assistant-ui/core 0.2.5 → 0.2.7
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.
- package/dist/index.d.ts +4 -2
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/duplicate-detection.d.ts +5 -0
- package/dist/internal/duplicate-detection.d.ts.map +1 -0
- package/dist/internal/duplicate-detection.js +11 -0
- package/dist/internal/duplicate-detection.js.map +1 -0
- package/dist/react/AssistantProvider.d.ts.map +1 -1
- package/dist/react/AssistantProvider.js.map +1 -1
- package/dist/react/index.d.ts +3 -2
- package/dist/react/index.js +2 -2
- package/dist/react/primitives/chainOfThought/ChainOfThoughtParts.js.map +1 -1
- package/dist/react/primitives/message/MessageGroupedParts.d.ts +25 -21
- package/dist/react/primitives/message/MessageGroupedParts.d.ts.map +1 -1
- package/dist/react/primitives/message/MessageGroupedParts.js +6 -7
- package/dist/react/primitives/message/MessageGroupedParts.js.map +1 -1
- package/dist/react/primitives/message/MessageParts.d.ts +2 -1
- package/dist/react/primitives/message/MessageParts.d.ts.map +1 -1
- package/dist/react/primitives/message/MessageParts.js +9 -4
- package/dist/react/primitives/message/MessageParts.js.map +1 -1
- package/dist/react/providers/TextMessagePartProvider.d.ts.map +1 -1
- package/dist/react/providers/TextMessagePartProvider.js +3 -0
- package/dist/react/providers/TextMessagePartProvider.js.map +1 -1
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts +3 -1
- package/dist/react/runtimes/RemoteThreadListHookInstanceManager.d.ts.map +1 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts +3 -1
- package/dist/react/runtimes/RemoteThreadListThreadListRuntimeCore.d.ts.map +1 -1
- package/dist/react/runtimes/external-message-converter.d.ts +1 -1
- package/dist/react/runtimes/external-message-converter.d.ts.map +1 -1
- package/dist/react/runtimes/external-message-converter.js +7 -3
- package/dist/react/runtimes/external-message-converter.js.map +1 -1
- package/dist/react/types/MessagePartComponentTypes.d.ts +8 -0
- package/dist/react/types/MessagePartComponentTypes.d.ts.map +1 -1
- package/dist/react/utils/groupParts.d.ts +40 -12
- package/dist/react/utils/groupParts.d.ts.map +1 -1
- package/dist/react/utils/groupParts.js +51 -9
- package/dist/react/utils/groupParts.js.map +1 -1
- package/dist/runtime/api/attachment-runtime.d.ts.map +1 -1
- package/dist/runtime/api/attachment-runtime.js.map +1 -1
- package/dist/runtime/api/message-part-runtime.d.ts +8 -0
- package/dist/runtime/api/message-part-runtime.d.ts.map +1 -1
- package/dist/runtime/api/message-part-runtime.js +13 -0
- package/dist/runtime/api/message-part-runtime.js.map +1 -1
- package/dist/runtime/api/thread-runtime.d.ts +2 -1
- package/dist/runtime/api/thread-runtime.d.ts.map +1 -1
- package/dist/runtime/base/base-thread-runtime-core.d.ts +2 -1
- package/dist/runtime/base/base-thread-runtime-core.d.ts.map +1 -1
- package/dist/runtime/base/base-thread-runtime-core.js.map +1 -1
- package/dist/runtime/interfaces/thread-runtime-core.d.ts +15 -1
- package/dist/runtime/interfaces/thread-runtime-core.d.ts.map +1 -1
- package/dist/runtime/utils/thread-message-like.d.ts +10 -0
- package/dist/runtime/utils/thread-message-like.d.ts.map +1 -1
- package/dist/runtime/utils/thread-message-like.js.map +1 -1
- package/dist/runtimes/external-store/external-store-adapter.d.ts +33 -1
- package/dist/runtimes/external-store/external-store-adapter.d.ts.map +1 -1
- package/dist/runtimes/external-store/external-store-thread-list-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/external-store/external-store-thread-list-runtime-core.js.map +1 -1
- package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts +27 -1
- package/dist/runtimes/external-store/external-store-thread-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/external-store/external-store-thread-runtime-core.js +98 -3
- package/dist/runtimes/external-store/external-store-thread-runtime-core.js.map +1 -1
- package/dist/runtimes/local/local-thread-runtime-core.d.ts +2 -1
- package/dist/runtimes/local/local-thread-runtime-core.d.ts.map +1 -1
- package/dist/runtimes/local/local-thread-runtime-core.js +3 -0
- package/dist/runtimes/local/local-thread-runtime-core.js.map +1 -1
- package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts +1 -0
- package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.d.ts.map +1 -1
- package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js +3 -0
- package/dist/runtimes/readonly/ReadonlyThreadRuntimeCore.js.map +1 -1
- package/dist/runtimes/remote-thread-list/empty-thread-core.d.ts.map +1 -1
- package/dist/runtimes/remote-thread-list/empty-thread-core.js +3 -0
- package/dist/runtimes/remote-thread-list/empty-thread-core.js.map +1 -1
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts +168 -0
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.d.ts.map +1 -0
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.js +449 -0
- package/dist/runtimes/tool-invocations/ToolInvocationTracker.js.map +1 -0
- package/dist/store/clients/thread-message-client.d.ts.map +1 -1
- package/dist/store/clients/thread-message-client.js +3 -0
- package/dist/store/clients/thread-message-client.js.map +1 -1
- package/dist/store/runtime-clients/message-part-runtime-client.js +1 -0
- package/dist/store/runtime-clients/message-part-runtime-client.js.map +1 -1
- package/dist/store/scopes/part.d.ts +7 -0
- package/dist/store/scopes/part.d.ts.map +1 -1
- package/dist/subscribable/subscribable.d.ts.map +1 -1
- package/dist/subscribable/subscribable.js.map +1 -1
- package/dist/types/message.d.ts +6 -0
- package/dist/types/message.d.ts.map +1 -1
- package/dist/types/message.js.map +1 -1
- package/package.json +4 -4
- package/src/adapters/index.ts +1 -4
- package/src/index.ts +11 -0
- package/src/internal/duplicate-detection.ts +26 -0
- package/src/react/AssistantProvider.tsx +2 -3
- package/src/react/index.ts +2 -6
- package/src/react/primitives/chainOfThought/ChainOfThoughtParts.tsx +1 -2
- package/src/react/primitives/message/MessageAttachments.test.tsx +1 -1
- package/src/react/primitives/message/MessageGroupedParts.tsx +38 -31
- package/src/react/primitives/message/MessageParts.tsx +14 -1
- package/src/react/providers/TextMessagePartProvider.tsx +3 -0
- package/src/react/runtimes/external-message-converter.ts +26 -13
- package/src/react/types/MessagePartComponentTypes.ts +8 -0
- package/src/react/utils/groupParts.ts +67 -22
- package/src/runtime/api/attachment-runtime.ts +1 -2
- package/src/runtime/api/message-part-runtime.ts +26 -0
- package/src/runtime/base/base-thread-runtime-core.ts +4 -0
- package/src/runtime/interfaces/thread-runtime-core.ts +15 -0
- package/src/runtime/internal.ts +1 -4
- package/src/runtime/utils/thread-message-like.ts +7 -0
- package/src/runtimes/external-store/external-store-adapter.ts +37 -0
- package/src/runtimes/external-store/external-store-thread-list-runtime-core.ts +1 -3
- package/src/runtimes/external-store/external-store-thread-runtime-core.ts +168 -4
- package/src/runtimes/local/local-thread-runtime-core.ts +5 -0
- package/src/runtimes/readonly/ReadonlyThreadRuntimeCore.ts +4 -0
- package/src/runtimes/remote-thread-list/empty-thread-core.ts +4 -0
- package/src/runtimes/tool-invocations/EDGE_CASES.md +194 -0
- package/src/runtimes/tool-invocations/ToolInvocationTracker.test.ts +1054 -0
- package/src/runtimes/tool-invocations/ToolInvocationTracker.ts +783 -0
- package/src/store/clients/thread-message-client.ts +3 -0
- package/src/store/runtime-clients/message-part-runtime-client.ts +2 -0
- package/src/store/scopes/part.ts +4 -0
- package/src/subscribable/subscribable.ts +3 -3
- package/src/tests/OptimisticState-delete-crash.test.ts +2 -0
- package/src/tests/OptimisticState-list-race.test.ts +2 -0
- package/src/tests/RemoteThreadListThreadListRuntimeCore-loadMore.test.ts +5 -5
- package/src/tests/auiV0Encode.test.ts +1 -1
- package/src/tests/composer-can-send.test.ts +8 -4
- package/src/tests/duplicate-detection.test.ts +34 -0
- package/src/tests/external-store-thread-list-runtime-core.test.ts +1 -1
- package/src/tests/external-store-thread-runtime-core.test.ts +7 -6
- package/src/tests/groupParts.test.ts +118 -32
- package/src/tests/no-unsafe-process-env.test.ts +1 -0
- package/src/tests/remote-thread-list-isLoading.test.ts +2 -0
- package/src/tests/thread-message-like.test.ts +4 -1
- package/src/types/index.ts +1 -4
- package/src/types/message.ts +7 -0
- package/dist/react/runtimes/useToolInvocations.d.ts +0 -53
- package/dist/react/runtimes/useToolInvocations.d.ts.map +0 -1
- package/dist/react/runtimes/useToolInvocations.js +0 -380
- package/dist/react/runtimes/useToolInvocations.js.map +0 -1
- package/src/react/runtimes/useToolInvocations.ts +0 -694
|
@@ -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":";;;
|
|
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"}
|
|
@@ -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
|
|
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"}
|
|
@@ -4,7 +4,7 @@ import { ModelContext, ModelContextProvider } 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 { RemoteThreadInitializeResponse, RemoteThreadListOptions } from "../../runtimes/remote-thread-list/types.js";
|
|
@@ -51,6 +51,7 @@ declare class RemoteThreadListThreadListRuntimeCore extends BaseSubscribable imp
|
|
|
51
51
|
cancelRun: () => void;
|
|
52
52
|
addToolResult: (options: AddToolResultOptions) => void;
|
|
53
53
|
resumeToolCall: (options: ResumeToolCallOptions) => void;
|
|
54
|
+
respondToToolApproval: (options: RespondToToolApprovalOptions) => void;
|
|
54
55
|
speak: (messageId: string) => void;
|
|
55
56
|
stopSpeaking: () => void;
|
|
56
57
|
connectVoice: () => void;
|
|
@@ -97,6 +98,7 @@ declare class RemoteThreadListThreadListRuntimeCore extends BaseSubscribable imp
|
|
|
97
98
|
cancelRun: () => void;
|
|
98
99
|
addToolResult: (options: AddToolResultOptions) => void;
|
|
99
100
|
resumeToolCall: (options: ResumeToolCallOptions) => void;
|
|
101
|
+
respondToToolApproval: (options: RespondToToolApprovalOptions) => void;
|
|
100
102
|
speak: (messageId: string) => void;
|
|
101
103
|
stopSpeaking: () => void;
|
|
102
104
|
connectVoice: () => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RemoteThreadListThreadListRuntimeCore.d.ts","names":[],"sources":["../../../src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx"],"mappings":";;;;;;;;;;;;;;cAwBa,qCAAA,SACH,gBAAA,YACG,qBAAA;EAAA,QAEH,QAAA;EAAA,iBACS,YAAA;EAAA,QAET,mBAAA;EAAA,QACA,gBAAA;EAAA,QACA,eAAA;EAAA,QAEA,aAAA;EAAA,iBACS,MAAA;EAAA,IAWN,WAAA,CAAA,GAAW,QAAA,CAAA,MAAA,CAtBtB,iBAAA,EAsBsB,gBAAA;EAIf,qBAAA,CAAA,GAAqB,OAAA;EAuDrB,QAAA,CAAA,GAAY,OAAA;EAAA,iBAoDF,eAAA;cAGf,OAAA,EAAS,uBAAA,EACT,eAAA,EAAiB,oBAAA;EAAA,QAiBX,oBAAA;EAAA,QACA,WAAA;EAED,qBAAA,CAAsB,OAAA,EAAS,uBAAA;EA0B/B,eAAA,CAAA;EAUA,MAAA,CAAA,GAAM,OAAA;EAAA,IAWF,SAAA,CAAA;EAAA,IAIA,aAAA,CAAA;EAAA,IAIA,OAAA,CAAA;EAAA,IAIA,SAAA,CAAA;EAAA,IAIA,iBAAA,CAAA;EAAA,IAIA,WAAA,CAAA;EAAA,IAIA,YAAA,CAAA;EAIJ,wBAAA,CAAA,GAAwB,QAAA;;;eAvClB,aAAA
|
|
1
|
+
{"version":3,"file":"RemoteThreadListThreadListRuntimeCore.d.ts","names":[],"sources":["../../../src/react/runtimes/RemoteThreadListThreadListRuntimeCore.tsx"],"mappings":";;;;;;;;;;;;;;cAwBa,qCAAA,SACH,gBAAA,YACG,qBAAA;EAAA,QAEH,QAAA;EAAA,iBACS,YAAA;EAAA,QAET,mBAAA;EAAA,QACA,gBAAA;EAAA,QACA,eAAA;EAAA,QAEA,aAAA;EAAA,iBACS,MAAA;EAAA,IAWN,WAAA,CAAA,GAAW,QAAA,CAAA,MAAA,CAtBtB,iBAAA,EAsBsB,gBAAA;EAIf,qBAAA,CAAA,GAAqB,OAAA;EAuDrB,QAAA,CAAA,GAAY,OAAA;EAAA,iBAoDF,eAAA;cAGf,OAAA,EAAS,uBAAA,EACT,eAAA,EAAiB,oBAAA;EAAA,QAiBX,oBAAA;EAAA,QACA,WAAA;EAED,qBAAA,CAAsB,OAAA,EAAS,uBAAA;EA0B/B,eAAA,CAAA;EAUA,MAAA,CAAA,GAAM,OAAA;EAAA,IAWF,SAAA,CAAA;EAAA,IAIA,aAAA,CAAA;EAAA,IAIA,OAAA,CAAA;EAAA,IAIA,SAAA,CAAA;EAAA,IAIA,iBAAA,CAAA;EAAA,IAIA,WAAA,CAAA;EAAA,IAIA,YAAA,CAAA;EAIJ,wBAAA,CAAA,GAAwB,QAAA;;;eAvClB,aAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6CN,oBAAA,CAAqB,kBAAA,WAA0B,QAAA;;;eANvB,aAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAexB,WAAA,CAAY,kBAAA,WAA0B,gBAAA;EAIhC,cAAA,CACX,kBAAA,UACA,OAAA;IAAY,SAAA;EAAA,IACX,OAAA;EA6EU,iBAAA,CAAA,GAAqB,OAAA;EAyC3B,UAAA,GAAoB,QAAA,aAAgB,OAAA,CAzCF,8BAAA;EA+FlC,aAAA,GAAuB,QAAA,aAAgB,OAAA;EAkCvC,MAAA,CAAO,kBAAA,UAA4B,QAAA,WAAmB,OAAA;EAAA,QA4B/C,sBAAA;EASD,OAAA,CAAQ,kBAAA,WAA0B,OAAA;EAmBxC,SAAA,CAAU,kBAAA,WAA6B,OAAA;EAqBjC,MAAA,CAAO,kBAAA,WAA0B,OAAA;EAoBjC,MAAA,CAAO,kBAAA,WAA6B,OAAA;EAAA,QAUzC,WAAA;EAED,0BAAA,EAA4B,EAAA;AAAA"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { MessageTiming, ThreadMessage } from "../../types/message.js";
|
|
2
2
|
import { ThreadMessageLike } from "../../runtime/utils/thread-message-like.js";
|
|
3
|
-
import { ToolExecutionStatus } from "
|
|
3
|
+
import { ToolExecutionStatus } from "../../runtimes/tool-invocations/ToolInvocationTracker.js";
|
|
4
4
|
import { ReadonlyJSONValue } from "assistant-stream/utils";
|
|
5
5
|
|
|
6
6
|
//#region src/react/runtimes/external-message-converter.d.ts
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"external-message-converter.d.ts","names":[],"sources":["../../../src/react/runtimes/external-message-converter.ts"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"external-message-converter.d.ts","names":[],"sources":["../../../src/react/runtimes/external-message-converter.ts"],"mappings":";;;;;;kBAwCiB,2BAAA;EAAA,KACH,OAAA,IACP,iBAAA;IAAA,SACU,aAAA;MAAA,SACE,YAAA;IAAA;EAAA;IAIX,IAAA;IACA,UAAA;IACA,QAAA;IACA,MAAA;IACA,QAAA;IACA,OAAA;IACA,QAAA,YAAoB,aAAA;EAAA;EAAA,KAGd,QAAA;IAAA,SACD,YAAA,GAAe,MAAA,SAAe,mBAAA;IAAA,SAC9B,KAAA,GAAQ,iBAAA;IAAA,SACR,aAAA,GAAgB,MAAA,SAAe,aAAA;EAAA;EAAA,KAG9B,QAAA,OACV,OAAA,EAAS,CAAA,EACT,QAAA,EAAU,QAAA,KACP,OAAA,GAAU,OAAA;AAAA;AAAA,cA4QJ,uBAAA,aAAqC,OAAA,EAChD,QAAA,EAAU,CAAA,IACV,QAAA,EAAU,2BAAA,CAA4B,QAAA,CAAS,CAAA,GAC/C,SAAA,WACA,QAAA,EAAU,2BAAA,CAA4B,QAAA,KAAQ,aAAA;AAAA,cA+CnC,2BAAA,aAAyC,OAAA;EAAS,QAAA;EAAA,QAAA;EAAA,SAAA;EAAA,YAAA;EAAA;AAAA;EAO7D,QAAA,EAAU,2BAAA,CAA4B,QAAA,CAAS,CAAA;EAC/C,QAAA,EAAU,CAAA;EACV,SAAA;EACA,YAAA;EACA,QAAA,GAAW,2BAAA,CAA4B,QAAA;AAAA,MACxC,aAAA"}
|
|
@@ -6,6 +6,11 @@ import { fromThreadMessageLike } from "../../runtime/utils/thread-message-like.j
|
|
|
6
6
|
import { ThreadMessageConverter } from "../../runtimes/external-store/thread-message-converter.js";
|
|
7
7
|
import { useMemo } from "react";
|
|
8
8
|
//#region src/react/runtimes/external-message-converter.ts
|
|
9
|
+
const isPendingToolCall = (c) => c.type === "tool-call" && c.result === void 0;
|
|
10
|
+
const isInterruptedToolCall = (c) => {
|
|
11
|
+
if (c.type !== "tool-call" || c.result !== void 0) return false;
|
|
12
|
+
return c.interrupt != null || c.approval != null && c.approval.approved === void 0;
|
|
13
|
+
};
|
|
9
14
|
const mergeInnerMessages = (existing, incoming) => ({ [symbolInnerMessage]: [...existing[symbolInnerMessage] ?? [], ...incoming[symbolInnerMessage] ?? []] });
|
|
10
15
|
const joinExternalMessages = (messages) => {
|
|
11
16
|
const assistantMessage = {
|
|
@@ -158,8 +163,7 @@ const convertExternalMessages = (messages, callback, isRunning, metadata) => {
|
|
|
158
163
|
const result = chunks.map((message, idx) => {
|
|
159
164
|
const isLast = idx === chunks.length - 1;
|
|
160
165
|
const joined = joinExternalMessages(message.outputs);
|
|
161
|
-
const
|
|
162
|
-
const autoStatus = getAutoStatus(isLast, isRunning, hasPendingToolCalls, hasPendingToolCalls, isLast ? metadata.error : void 0);
|
|
166
|
+
const autoStatus = getAutoStatus(isLast, isRunning, typeof joined.content === "object" && joined.content.some(isInterruptedToolCall), typeof joined.content === "object" && joined.content.some(isPendingToolCall), isLast ? metadata.error : void 0);
|
|
163
167
|
const newMessage = fromThreadMessageLike(joined, idx.toString(), autoStatus);
|
|
164
168
|
bindExternalStoreMessage(newMessage, message.inputs);
|
|
165
169
|
return newMessage;
|
|
@@ -203,7 +207,7 @@ const useExternalMessageConverter = ({ callback, messages, isRunning, joinStrate
|
|
|
203
207
|
const threadMessages = state.converterCache.convertMessages(chunks, (cache, message, idx) => {
|
|
204
208
|
const isLast = idx === chunks.length - 1;
|
|
205
209
|
const joined = joinExternalMessages(message.outputs);
|
|
206
|
-
const autoStatus = getAutoStatus(isLast, isRunning, typeof joined.content === "object" && joined.content.some(
|
|
210
|
+
const autoStatus = getAutoStatus(isLast, isRunning, typeof joined.content === "object" && joined.content.some(isInterruptedToolCall), typeof joined.content === "object" && joined.content.some(isPendingToolCall), isLast ? state.metadata.error : void 0);
|
|
207
211
|
if (cache && (cache.role !== "assistant" || !isAutoStatus(cache.status) || cache.status === autoStatus)) {
|
|
208
212
|
if (shallowArrayEqual(getExternalStoreMessages(cache), message.inputs)) return cache;
|
|
209
213
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"external-message-converter.js","names":["unsupportedRole"],"sources":["../../../src/react/runtimes/external-message-converter.ts"],"sourcesContent":["\"use client\";\n\nimport { useMemo } from \"react\";\nimport { ThreadMessageConverter } from \"../../runtimes/external-store/thread-message-converter\";\nimport {\n getExternalStoreMessages,\n symbolInnerMessage,\n bindExternalStoreMessage,\n} from \"../../runtime/utils/external-store-message\";\nimport {\n fromThreadMessageLike,\n type ThreadMessageLike,\n} from \"../../runtime/utils/thread-message-like\";\nimport { getAutoStatus, isAutoStatus } from \"../../runtime/utils/auto-status\";\nimport type { ToolExecutionStatus } from \"./useToolInvocations\";\nimport type { ReadonlyJSONValue } from \"assistant-stream/utils\";\nimport { generateErrorMessageId } from \"../../utils/id\";\nimport type {\n ThreadAssistantMessage,\n ThreadMessage,\n ToolCallMessagePart,\n} from \"../../types/message\";\nimport type { MessageTiming } from \"../../types/message\";\n\nexport namespace useExternalMessageConverter {\n export type Message =\n | (ThreadMessageLike & {\n readonly convertConfig?: {\n readonly joinStrategy?: \"concat-content\" | \"none\";\n };\n })\n | {\n role: \"tool\";\n toolCallId: string;\n toolName?: string | undefined;\n result: any;\n artifact?: any;\n isError?: boolean;\n messages?: readonly ThreadMessage[];\n };\n\n export type Metadata = {\n readonly toolStatuses?: Record<string, ToolExecutionStatus>;\n readonly error?: ReadonlyJSONValue;\n readonly messageTiming?: Record<string, MessageTiming>;\n };\n\n export type Callback<T> = (\n message: T,\n metadata: Metadata,\n ) => Message | Message[];\n}\n\ntype CallbackResult<T> = {\n input: T;\n outputs: useExternalMessageConverter.Message[];\n};\n\ntype ChunkResult<T> = {\n inputs: T[];\n outputs: useExternalMessageConverter.Message[];\n};\n\ntype Mutable<T> = {\n -readonly [P in keyof T]: T[P];\n};\n\nconst mergeInnerMessages = (existing: object, incoming: object) => ({\n [symbolInnerMessage]: [\n ...((existing as any)[symbolInnerMessage] ?? []),\n ...((incoming as any)[symbolInnerMessage] ?? []),\n ],\n});\n\nconst joinExternalMessages = (\n messages: readonly useExternalMessageConverter.Message[],\n): ThreadMessageLike => {\n const assistantMessage: Mutable<Omit<ThreadMessageLike, \"metadata\">> & {\n content: Exclude<ThreadMessageLike[\"content\"][0], string>[];\n metadata?: Mutable<ThreadMessageLike[\"metadata\"]>;\n } = {\n role: \"assistant\",\n content: [],\n };\n for (const output of messages) {\n if (output.role === \"tool\") {\n const toolCallIdx = assistantMessage.content.findIndex(\n (c) => c.type === \"tool-call\" && c.toolCallId === output.toolCallId,\n );\n // Ignore orphaned tool results so one bad tool message does not\n // prevent rendering the rest of the conversation.\n if (toolCallIdx !== -1) {\n const toolCall = assistantMessage.content[\n toolCallIdx\n ]! as ToolCallMessagePart;\n if (output.toolName !== undefined) {\n if (toolCall.toolName !== output.toolName)\n throw new Error(\n `Tool call name ${output.toolCallId} ${output.toolName} does not match existing tool call ${toolCall.toolName}`,\n );\n }\n assistantMessage.content[toolCallIdx] = {\n ...toolCall,\n ...{\n [symbolInnerMessage]: [\n ...((toolCall as any)[symbolInnerMessage] ?? []),\n output,\n ],\n },\n result: output.result,\n artifact: output.artifact,\n isError: output.isError,\n messages: output.messages,\n };\n }\n } else {\n const role = output.role;\n const content = (\n typeof output.content === \"string\"\n ? [{ type: \"text\" as const, text: output.content }]\n : output.content\n ).map((c) => ({\n ...c,\n ...{ [symbolInnerMessage]: [output] },\n }));\n switch (role) {\n case \"system\":\n case \"user\":\n return {\n ...output,\n content,\n };\n case \"assistant\":\n if (assistantMessage.content.length === 0) {\n assistantMessage.id = output.id;\n assistantMessage.createdAt ??= output.createdAt;\n assistantMessage.status ??= output.status;\n\n if (output.attachments) {\n assistantMessage.attachments = [\n ...(assistantMessage.attachments ?? []),\n ...output.attachments,\n ];\n }\n\n if (output.metadata) {\n assistantMessage.metadata ??= {};\n if (output.metadata.unstable_state) {\n assistantMessage.metadata.unstable_state =\n output.metadata.unstable_state;\n }\n if (output.metadata.unstable_annotations) {\n assistantMessage.metadata.unstable_annotations = [\n ...(assistantMessage.metadata.unstable_annotations ?? []),\n ...output.metadata.unstable_annotations,\n ];\n }\n if (output.metadata.unstable_data) {\n assistantMessage.metadata.unstable_data = [\n ...(assistantMessage.metadata.unstable_data ?? []),\n ...output.metadata.unstable_data,\n ];\n }\n if (output.metadata.steps) {\n assistantMessage.metadata.steps = [\n ...(assistantMessage.metadata.steps ?? []),\n ...output.metadata.steps,\n ];\n }\n if (output.metadata.custom) {\n assistantMessage.metadata.custom = {\n ...(assistantMessage.metadata.custom ?? {}),\n ...output.metadata.custom,\n };\n }\n\n if (output.metadata.timing) {\n assistantMessage.metadata.timing = output.metadata.timing;\n }\n\n if (output.metadata.submittedFeedback) {\n assistantMessage.metadata.submittedFeedback =\n output.metadata.submittedFeedback;\n }\n }\n // TODO keep this in sync\n }\n\n // Add content parts, merging reasoning parts with same parentId\n for (const part of content) {\n if (part.type === \"tool-call\") {\n const existingIdx = assistantMessage.content.findIndex(\n (c) =>\n c.type === \"tool-call\" && c.toolCallId === part.toolCallId,\n );\n if (existingIdx !== -1) {\n const existing = assistantMessage.content[\n existingIdx\n ] as typeof part;\n assistantMessage.content[existingIdx] = {\n ...existing,\n ...part,\n ...mergeInnerMessages(existing, part),\n };\n continue;\n }\n }\n\n if (\n part.type === \"reasoning\" &&\n \"parentId\" in part &&\n part.parentId\n ) {\n const existingIdx = assistantMessage.content.findIndex(\n (c) =>\n c.type === \"reasoning\" &&\n \"parentId\" in c &&\n c.parentId === part.parentId,\n );\n if (existingIdx !== -1) {\n const existing = assistantMessage.content[\n existingIdx\n ] as typeof part;\n assistantMessage.content[existingIdx] = {\n ...existing,\n text: `${existing.text}\\n\\n${part.text}`,\n ...mergeInnerMessages(existing, part),\n };\n continue;\n }\n }\n assistantMessage.content.push(part);\n }\n break;\n default: {\n const unsupportedRole: never = role;\n throw new Error(`Unknown message role: ${unsupportedRole}`);\n }\n }\n }\n }\n return assistantMessage;\n};\n\nconst chunkExternalMessages = <T>(\n callbackResults: CallbackResult<T>[],\n joinStrategy?: \"concat-content\" | \"none\",\n) => {\n const results: ChunkResult<T>[] = [];\n let isAssistant = false;\n let pendingNone = false; // true if the previous assistant message had joinStrategy \"none\"\n let inputs: T[] = [];\n let outputs: useExternalMessageConverter.Message[] = [];\n\n const flush = () => {\n if (outputs.length) {\n results.push({\n inputs,\n outputs,\n });\n }\n inputs = [];\n outputs = [];\n isAssistant = false;\n pendingNone = false;\n };\n\n for (const callbackResult of callbackResults) {\n for (const output of callbackResult.outputs) {\n if (\n (pendingNone && output.role !== \"tool\") ||\n !isAssistant ||\n output.role === \"user\" ||\n output.role === \"system\"\n ) {\n flush();\n }\n isAssistant = output.role === \"assistant\" || output.role === \"tool\";\n\n if (inputs.at(-1) !== callbackResult.input) {\n inputs.push(callbackResult.input);\n }\n outputs.push(output);\n\n if (\n output.role === \"assistant\" &&\n (output.convertConfig?.joinStrategy === \"none\" ||\n joinStrategy === \"none\")\n ) {\n pendingNone = true;\n }\n }\n }\n flush();\n return results;\n};\n\nfunction createErrorAssistantMessage(\n error: ReadonlyJSONValue,\n): ThreadAssistantMessage {\n const msg: ThreadAssistantMessage = {\n id: generateErrorMessageId(),\n role: \"assistant\",\n content: [],\n status: { type: \"incomplete\", reason: \"error\", error },\n createdAt: new Date(),\n metadata: {\n unstable_state: null,\n unstable_annotations: [],\n unstable_data: [],\n custom: {},\n steps: [],\n },\n };\n bindExternalStoreMessage(msg, []);\n return msg;\n}\n\nexport const convertExternalMessages = <T extends WeakKey>(\n messages: T[],\n callback: useExternalMessageConverter.Callback<T>,\n isRunning: boolean,\n metadata: useExternalMessageConverter.Metadata,\n) => {\n const callbackResults: CallbackResult<T>[] = [];\n for (const message of messages) {\n const output = callback(message, metadata);\n const outputs = Array.isArray(output) ? output : [output];\n const result = { input: message, outputs };\n callbackResults.push(result);\n }\n\n const chunks = chunkExternalMessages(callbackResults);\n\n const result = chunks.map((message, idx) => {\n const isLast = idx === chunks.length - 1;\n const joined = joinExternalMessages(message.outputs);\n const hasPendingToolCalls =\n typeof joined.content === \"object\" &&\n joined.content.some(\n (c) => c.type === \"tool-call\" && c.result === undefined,\n );\n const autoStatus = getAutoStatus(\n isLast,\n isRunning,\n hasPendingToolCalls,\n hasPendingToolCalls,\n isLast ? metadata.error : undefined,\n );\n const newMessage = fromThreadMessageLike(\n joined,\n idx.toString(),\n autoStatus,\n );\n bindExternalStoreMessage(newMessage, message.inputs);\n return newMessage;\n });\n\n if (metadata.error) {\n const lastMessage = result.at(-1);\n if (!lastMessage || lastMessage.role !== \"assistant\") {\n result.push(createErrorAssistantMessage(metadata.error));\n }\n }\n\n return result;\n};\n\nexport const useExternalMessageConverter = <T extends WeakKey>({\n callback,\n messages,\n isRunning,\n joinStrategy,\n metadata,\n}: {\n callback: useExternalMessageConverter.Callback<T>;\n messages: T[];\n isRunning: boolean;\n joinStrategy?: \"concat-content\" | \"none\" | undefined;\n metadata?: useExternalMessageConverter.Metadata | undefined;\n}) => {\n const state = useMemo(\n () => ({\n metadata: metadata ?? {},\n callback,\n callbackCache: new WeakMap<T, CallbackResult<T>>(),\n chunkCache: new WeakMap<\n useExternalMessageConverter.Message,\n ChunkResult<T>\n >(),\n converterCache: new ThreadMessageConverter(),\n }),\n [callback, metadata],\n );\n\n return useMemo(() => {\n const callbackResults: CallbackResult<T>[] = [];\n for (const message of messages) {\n let result = state.callbackCache.get(message);\n if (!result) {\n const output = state.callback(message, state.metadata);\n const outputs = Array.isArray(output) ? output : [output];\n result = { input: message, outputs };\n state.callbackCache.set(message, result);\n }\n callbackResults.push(result);\n }\n\n const chunks = chunkExternalMessages(callbackResults, joinStrategy).map(\n (m) => {\n const key = m.outputs[0];\n if (!key) return m;\n\n const cached = state.chunkCache.get(key);\n if (cached && shallowArrayEqual(cached.outputs, m.outputs))\n return cached;\n state.chunkCache.set(key, m);\n return m;\n },\n );\n\n const threadMessages = state.converterCache.convertMessages(\n chunks,\n (cache, message, idx) => {\n const isLast = idx === chunks.length - 1;\n\n const joined = joinExternalMessages(message.outputs);\n const hasSuspendedToolCalls =\n typeof joined.content === \"object\" &&\n joined.content.some(\n (c) => c.type === \"tool-call\" && c.result === undefined,\n );\n const hasPendingToolCalls =\n typeof joined.content === \"object\" &&\n joined.content.some(\n (c) => c.type === \"tool-call\" && c.result === undefined,\n );\n const autoStatus = getAutoStatus(\n isLast,\n isRunning,\n hasSuspendedToolCalls,\n hasPendingToolCalls,\n isLast ? state.metadata.error : undefined,\n );\n\n if (\n cache &&\n (cache.role !== \"assistant\" ||\n !isAutoStatus(cache.status) ||\n cache.status === autoStatus)\n ) {\n const inputs = getExternalStoreMessages<T>(cache);\n if (shallowArrayEqual(inputs, message.inputs)) {\n return cache;\n }\n }\n\n const newMessage = fromThreadMessageLike(\n joined,\n idx.toString(),\n autoStatus,\n );\n bindExternalStoreMessage(newMessage, message.inputs);\n return newMessage;\n },\n );\n\n bindExternalStoreMessage(threadMessages, messages);\n\n if (state.metadata.error) {\n const lastMessage = threadMessages.at(-1);\n if (!lastMessage || lastMessage.role !== \"assistant\") {\n threadMessages.push(createErrorAssistantMessage(state.metadata.error));\n }\n }\n\n return threadMessages;\n }, [state, messages, isRunning, joinStrategy]);\n};\n\nconst shallowArrayEqual = (a: unknown[], b: unknown[]) => {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"external-message-converter.js","names":["unsupportedRole"],"sources":["../../../src/react/runtimes/external-message-converter.ts"],"sourcesContent":["\"use client\";\n\nimport { useMemo } from \"react\";\nimport { ThreadMessageConverter } from \"../../runtimes/external-store/thread-message-converter\";\nimport {\n getExternalStoreMessages,\n symbolInnerMessage,\n bindExternalStoreMessage,\n} from \"../../runtime/utils/external-store-message\";\nimport {\n fromThreadMessageLike,\n type ThreadMessageLike,\n} from \"../../runtime/utils/thread-message-like\";\nimport { getAutoStatus, isAutoStatus } from \"../../runtime/utils/auto-status\";\nimport type { ToolExecutionStatus } from \"../../runtimes/tool-invocations/ToolInvocationTracker\";\nimport type { ReadonlyJSONValue } from \"assistant-stream/utils\";\nimport { generateErrorMessageId } from \"../../utils/id\";\nimport type {\n ThreadAssistantMessage,\n ThreadMessage,\n ToolCallMessagePart,\n} from \"../../types/message\";\nimport type { MessageTiming } from \"../../types/message\";\n\ntype ThreadMessageLikeContentItem = Exclude<\n ThreadMessageLike[\"content\"],\n string\n>[number];\n\nconst isPendingToolCall = (c: ThreadMessageLikeContentItem): boolean =>\n c.type === \"tool-call\" && c.result === undefined;\n\nconst isInterruptedToolCall = (c: ThreadMessageLikeContentItem): boolean => {\n if (c.type !== \"tool-call\" || c.result !== undefined) return false;\n return (\n c.interrupt != null ||\n (c.approval != null && c.approval.approved === undefined)\n );\n};\n\nexport namespace useExternalMessageConverter {\n export type Message =\n | (ThreadMessageLike & {\n readonly convertConfig?: {\n readonly joinStrategy?: \"concat-content\" | \"none\";\n };\n })\n | {\n role: \"tool\";\n toolCallId: string;\n toolName?: string | undefined;\n result: any;\n artifact?: any;\n isError?: boolean;\n messages?: readonly ThreadMessage[];\n };\n\n export type Metadata = {\n readonly toolStatuses?: Record<string, ToolExecutionStatus>;\n readonly error?: ReadonlyJSONValue;\n readonly messageTiming?: Record<string, MessageTiming>;\n };\n\n export type Callback<T> = (\n message: T,\n metadata: Metadata,\n ) => Message | Message[];\n}\n\ntype CallbackResult<T> = {\n input: T;\n outputs: useExternalMessageConverter.Message[];\n};\n\ntype ChunkResult<T> = {\n inputs: T[];\n outputs: useExternalMessageConverter.Message[];\n};\n\ntype Mutable<T> = {\n -readonly [P in keyof T]: T[P];\n};\n\nconst mergeInnerMessages = (existing: object, incoming: object) => ({\n [symbolInnerMessage]: [\n ...((existing as any)[symbolInnerMessage] ?? []),\n ...((incoming as any)[symbolInnerMessage] ?? []),\n ],\n});\n\nconst joinExternalMessages = (\n messages: readonly useExternalMessageConverter.Message[],\n): ThreadMessageLike => {\n const assistantMessage: Mutable<Omit<ThreadMessageLike, \"metadata\">> & {\n content: Exclude<ThreadMessageLike[\"content\"][0], string>[];\n metadata?: Mutable<ThreadMessageLike[\"metadata\"]>;\n } = {\n role: \"assistant\",\n content: [],\n };\n for (const output of messages) {\n if (output.role === \"tool\") {\n const toolCallIdx = assistantMessage.content.findIndex(\n (c) => c.type === \"tool-call\" && c.toolCallId === output.toolCallId,\n );\n // Ignore orphaned tool results so one bad tool message does not\n // prevent rendering the rest of the conversation.\n if (toolCallIdx !== -1) {\n const toolCall = assistantMessage.content[\n toolCallIdx\n ]! as ToolCallMessagePart;\n if (output.toolName !== undefined) {\n if (toolCall.toolName !== output.toolName)\n throw new Error(\n `Tool call name ${output.toolCallId} ${output.toolName} does not match existing tool call ${toolCall.toolName}`,\n );\n }\n assistantMessage.content[toolCallIdx] = {\n ...toolCall,\n ...{\n [symbolInnerMessage]: [\n ...((toolCall as any)[symbolInnerMessage] ?? []),\n output,\n ],\n },\n result: output.result,\n artifact: output.artifact,\n isError: output.isError,\n messages: output.messages,\n };\n }\n } else {\n const role = output.role;\n const content = (\n typeof output.content === \"string\"\n ? [{ type: \"text\" as const, text: output.content }]\n : output.content\n ).map((c) => ({\n ...c,\n ...{ [symbolInnerMessage]: [output] },\n }));\n switch (role) {\n case \"system\":\n case \"user\":\n return {\n ...output,\n content,\n };\n case \"assistant\":\n if (assistantMessage.content.length === 0) {\n assistantMessage.id = output.id;\n assistantMessage.createdAt ??= output.createdAt;\n assistantMessage.status ??= output.status;\n\n if (output.attachments) {\n assistantMessage.attachments = [\n ...(assistantMessage.attachments ?? []),\n ...output.attachments,\n ];\n }\n\n if (output.metadata) {\n assistantMessage.metadata ??= {};\n if (output.metadata.unstable_state) {\n assistantMessage.metadata.unstable_state =\n output.metadata.unstable_state;\n }\n if (output.metadata.unstable_annotations) {\n assistantMessage.metadata.unstable_annotations = [\n ...(assistantMessage.metadata.unstable_annotations ?? []),\n ...output.metadata.unstable_annotations,\n ];\n }\n if (output.metadata.unstable_data) {\n assistantMessage.metadata.unstable_data = [\n ...(assistantMessage.metadata.unstable_data ?? []),\n ...output.metadata.unstable_data,\n ];\n }\n if (output.metadata.steps) {\n assistantMessage.metadata.steps = [\n ...(assistantMessage.metadata.steps ?? []),\n ...output.metadata.steps,\n ];\n }\n if (output.metadata.custom) {\n assistantMessage.metadata.custom = {\n ...(assistantMessage.metadata.custom ?? {}),\n ...output.metadata.custom,\n };\n }\n\n if (output.metadata.timing) {\n assistantMessage.metadata.timing = output.metadata.timing;\n }\n\n if (output.metadata.submittedFeedback) {\n assistantMessage.metadata.submittedFeedback =\n output.metadata.submittedFeedback;\n }\n }\n // TODO keep this in sync\n }\n\n // Add content parts, merging reasoning parts with same parentId\n for (const part of content) {\n if (part.type === \"tool-call\") {\n const existingIdx = assistantMessage.content.findIndex(\n (c) =>\n c.type === \"tool-call\" && c.toolCallId === part.toolCallId,\n );\n if (existingIdx !== -1) {\n const existing = assistantMessage.content[\n existingIdx\n ] as typeof part;\n assistantMessage.content[existingIdx] = {\n ...existing,\n ...part,\n ...mergeInnerMessages(existing, part),\n };\n continue;\n }\n }\n\n if (\n part.type === \"reasoning\" &&\n \"parentId\" in part &&\n part.parentId\n ) {\n const existingIdx = assistantMessage.content.findIndex(\n (c) =>\n c.type === \"reasoning\" &&\n \"parentId\" in c &&\n c.parentId === part.parentId,\n );\n if (existingIdx !== -1) {\n const existing = assistantMessage.content[\n existingIdx\n ] as typeof part;\n assistantMessage.content[existingIdx] = {\n ...existing,\n text: `${existing.text}\\n\\n${part.text}`,\n ...mergeInnerMessages(existing, part),\n };\n continue;\n }\n }\n assistantMessage.content.push(part);\n }\n break;\n default: {\n const unsupportedRole: never = role;\n throw new Error(`Unknown message role: ${unsupportedRole}`);\n }\n }\n }\n }\n return assistantMessage;\n};\n\nconst chunkExternalMessages = <T>(\n callbackResults: CallbackResult<T>[],\n joinStrategy?: \"concat-content\" | \"none\",\n) => {\n const results: ChunkResult<T>[] = [];\n let isAssistant = false;\n let pendingNone = false; // true if the previous assistant message had joinStrategy \"none\"\n let inputs: T[] = [];\n let outputs: useExternalMessageConverter.Message[] = [];\n\n const flush = () => {\n if (outputs.length) {\n results.push({\n inputs,\n outputs,\n });\n }\n inputs = [];\n outputs = [];\n isAssistant = false;\n pendingNone = false;\n };\n\n for (const callbackResult of callbackResults) {\n for (const output of callbackResult.outputs) {\n if (\n (pendingNone && output.role !== \"tool\") ||\n !isAssistant ||\n output.role === \"user\" ||\n output.role === \"system\"\n ) {\n flush();\n }\n isAssistant = output.role === \"assistant\" || output.role === \"tool\";\n\n if (inputs.at(-1) !== callbackResult.input) {\n inputs.push(callbackResult.input);\n }\n outputs.push(output);\n\n if (\n output.role === \"assistant\" &&\n (output.convertConfig?.joinStrategy === \"none\" ||\n joinStrategy === \"none\")\n ) {\n pendingNone = true;\n }\n }\n }\n flush();\n return results;\n};\n\nfunction createErrorAssistantMessage(\n error: ReadonlyJSONValue,\n): ThreadAssistantMessage {\n const msg: ThreadAssistantMessage = {\n id: generateErrorMessageId(),\n role: \"assistant\",\n content: [],\n status: { type: \"incomplete\", reason: \"error\", error },\n createdAt: new Date(),\n metadata: {\n unstable_state: null,\n unstable_annotations: [],\n unstable_data: [],\n custom: {},\n steps: [],\n },\n };\n bindExternalStoreMessage(msg, []);\n return msg;\n}\n\nexport const convertExternalMessages = <T extends WeakKey>(\n messages: T[],\n callback: useExternalMessageConverter.Callback<T>,\n isRunning: boolean,\n metadata: useExternalMessageConverter.Metadata,\n) => {\n const callbackResults: CallbackResult<T>[] = [];\n for (const message of messages) {\n const output = callback(message, metadata);\n const outputs = Array.isArray(output) ? output : [output];\n const result = { input: message, outputs };\n callbackResults.push(result);\n }\n\n const chunks = chunkExternalMessages(callbackResults);\n\n const result = chunks.map((message, idx) => {\n const isLast = idx === chunks.length - 1;\n const joined = joinExternalMessages(message.outputs);\n const hasInterruptedToolCalls =\n typeof joined.content === \"object\" &&\n joined.content.some(isInterruptedToolCall);\n const hasPendingToolCalls =\n typeof joined.content === \"object\" &&\n joined.content.some(isPendingToolCall);\n const autoStatus = getAutoStatus(\n isLast,\n isRunning,\n hasInterruptedToolCalls,\n hasPendingToolCalls,\n isLast ? metadata.error : undefined,\n );\n const newMessage = fromThreadMessageLike(\n joined,\n idx.toString(),\n autoStatus,\n );\n bindExternalStoreMessage(newMessage, message.inputs);\n return newMessage;\n });\n\n if (metadata.error) {\n const lastMessage = result.at(-1);\n if (!lastMessage || lastMessage.role !== \"assistant\") {\n result.push(createErrorAssistantMessage(metadata.error));\n }\n }\n\n return result;\n};\n\nexport const useExternalMessageConverter = <T extends WeakKey>({\n callback,\n messages,\n isRunning,\n joinStrategy,\n metadata,\n}: {\n callback: useExternalMessageConverter.Callback<T>;\n messages: T[];\n isRunning: boolean;\n joinStrategy?: \"concat-content\" | \"none\" | undefined;\n metadata?: useExternalMessageConverter.Metadata | undefined;\n}) => {\n const state = useMemo(\n () => ({\n metadata: metadata ?? {},\n callback,\n callbackCache: new WeakMap<T, CallbackResult<T>>(),\n chunkCache: new WeakMap<\n useExternalMessageConverter.Message,\n ChunkResult<T>\n >(),\n converterCache: new ThreadMessageConverter(),\n }),\n [callback, metadata],\n );\n\n return useMemo(() => {\n const callbackResults: CallbackResult<T>[] = [];\n for (const message of messages) {\n let result = state.callbackCache.get(message);\n if (!result) {\n const output = state.callback(message, state.metadata);\n const outputs = Array.isArray(output) ? output : [output];\n result = { input: message, outputs };\n state.callbackCache.set(message, result);\n }\n callbackResults.push(result);\n }\n\n const chunks = chunkExternalMessages(callbackResults, joinStrategy).map(\n (m) => {\n const key = m.outputs[0];\n if (!key) return m;\n\n const cached = state.chunkCache.get(key);\n if (cached && shallowArrayEqual(cached.outputs, m.outputs))\n return cached;\n state.chunkCache.set(key, m);\n return m;\n },\n );\n\n const threadMessages = state.converterCache.convertMessages(\n chunks,\n (cache, message, idx) => {\n const isLast = idx === chunks.length - 1;\n\n const joined = joinExternalMessages(message.outputs);\n const hasInterruptedToolCalls =\n typeof joined.content === \"object\" &&\n joined.content.some(isInterruptedToolCall);\n const hasPendingToolCalls =\n typeof joined.content === \"object\" &&\n joined.content.some(isPendingToolCall);\n const autoStatus = getAutoStatus(\n isLast,\n isRunning,\n hasInterruptedToolCalls,\n hasPendingToolCalls,\n isLast ? state.metadata.error : undefined,\n );\n\n if (\n cache &&\n (cache.role !== \"assistant\" ||\n !isAutoStatus(cache.status) ||\n cache.status === autoStatus)\n ) {\n const inputs = getExternalStoreMessages<T>(cache);\n if (shallowArrayEqual(inputs, message.inputs)) {\n return cache;\n }\n }\n\n const newMessage = fromThreadMessageLike(\n joined,\n idx.toString(),\n autoStatus,\n );\n bindExternalStoreMessage(newMessage, message.inputs);\n return newMessage;\n },\n );\n\n bindExternalStoreMessage(threadMessages, messages);\n\n if (state.metadata.error) {\n const lastMessage = threadMessages.at(-1);\n if (!lastMessage || lastMessage.role !== \"assistant\") {\n threadMessages.push(createErrorAssistantMessage(state.metadata.error));\n }\n }\n\n return threadMessages;\n }, [state, messages, isRunning, joinStrategy]);\n};\n\nconst shallowArrayEqual = (a: unknown[], b: unknown[]) => {\n if (a.length !== b.length) return false;\n for (let i = 0; i < a.length; i++) {\n if (a[i] !== b[i]) return false;\n }\n return true;\n};\n"],"mappings":"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"}
|
|
@@ -41,6 +41,14 @@ type ToolCallMessagePartProps<TArgs = any, TResult = unknown> = MessagePartState
|
|
|
41
41
|
* paused frontend tool execution.
|
|
42
42
|
*/
|
|
43
43
|
resume: (payload: unknown) => void;
|
|
44
|
+
/**
|
|
45
|
+
* Responds to a server-side tool approval gate. Only valid while
|
|
46
|
+
* `approval` is set on the part and `approval.approved === undefined`.
|
|
47
|
+
*/
|
|
48
|
+
respondToApproval: (response: {
|
|
49
|
+
approved: boolean;
|
|
50
|
+
reason?: string;
|
|
51
|
+
}) => void;
|
|
44
52
|
};
|
|
45
53
|
/** Component used to render a tool-call message part. */
|
|
46
54
|
type ToolCallMessagePartComponent<TArgs = any, TResult = any> = ComponentType<ToolCallMessagePartProps<TArgs, TResult>>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessagePartComponentTypes.d.ts","names":[],"sources":["../../../src/react/types/MessagePartComponentTypes.ts"],"mappings":";;;;;;;KAkBY,qBAAA;EACV,MAAA,EAAQ,iBAAiB;AAAA;AAAA,KAEf,yBAAA,GAA4B,aAAa,CAAC,qBAAA;AAAA,KAE1C,oBAAA,GAAuB,gBAAA,GAAmB,eAAe;AAAA,KACzD,wBAAA,GAA2B,aAAa,CAAC,oBAAA;AAAA,KAEzC,yBAAA,GAA4B,gBAAA,GAAmB,oBAAoB;AAAA,KACnE,6BAAA,GACV,aAAa,CAAC,yBAAA;AAAA,KAEJ,mBAAA,GAAsB,iBAAiB;EACjD,UAAA;EACA,QAAA;AAAA;AAAA,KAEU,uBAAA,GAA0B,aAAa,CAAC,mBAAA;AAAA,KAExC,sBAAA,GAAyB,gBAAA,GAAmB,iBAAiB;AAAA,KAC7D,0BAAA,GAA6B,aAAa,CAAC,sBAAA;AAAA,KAE3C,qBAAA,GAAwB,gBAAA,GAAmB,gBAAgB;AAAA,KAC3D,yBAAA,GAA4B,aAAa,CAAC,qBAAA;AAAA,KAE1C,oBAAA,GAAuB,gBAAA,GAAmB,eAAe;AAAA,KACzD,wBAAA,GAA2B,aAAa,CAAC,oBAAA;AAAA,KAEzC,8BAAA,GAAiC,gBAAA,GAC3C,yBAAyB;AAAA,KACf,kCAAA,GACV,aAAa,CAAC,8BAAA;AAAA,KAEJ,oBAAA,YAAgC,gBAAA,GAC1C,eAAA,CAAgB,CAAA;AAAA,KACN,wBAAA,YAAoC,aAAA,CAC9C,oBAAA,CAAqB,CAAA;AAAA,KAGX,wBAAA,mCAGR,gBAAA,GACF,mBAAA,CAAoB,KAAA,EAAO,OAAA;EAlCjB;;;;AAAmE;AAC/E;EAwCI,SAAA,GAAY,MAAA,EAAQ,OAAA,GAAU,YAAA,CAAa,OAAA;;;AAvCN;AAEzC;EA0CI,MAAA,GAAS,OAAA;AAAA;;
|
|
1
|
+
{"version":3,"file":"MessagePartComponentTypes.d.ts","names":[],"sources":["../../../src/react/types/MessagePartComponentTypes.ts"],"mappings":";;;;;;;KAkBY,qBAAA;EACV,MAAA,EAAQ,iBAAiB;AAAA;AAAA,KAEf,yBAAA,GAA4B,aAAa,CAAC,qBAAA;AAAA,KAE1C,oBAAA,GAAuB,gBAAA,GAAmB,eAAe;AAAA,KACzD,wBAAA,GAA2B,aAAa,CAAC,oBAAA;AAAA,KAEzC,yBAAA,GAA4B,gBAAA,GAAmB,oBAAoB;AAAA,KACnE,6BAAA,GACV,aAAa,CAAC,yBAAA;AAAA,KAEJ,mBAAA,GAAsB,iBAAiB;EACjD,UAAA;EACA,QAAA;AAAA;AAAA,KAEU,uBAAA,GAA0B,aAAa,CAAC,mBAAA;AAAA,KAExC,sBAAA,GAAyB,gBAAA,GAAmB,iBAAiB;AAAA,KAC7D,0BAAA,GAA6B,aAAa,CAAC,sBAAA;AAAA,KAE3C,qBAAA,GAAwB,gBAAA,GAAmB,gBAAgB;AAAA,KAC3D,yBAAA,GAA4B,aAAa,CAAC,qBAAA;AAAA,KAE1C,oBAAA,GAAuB,gBAAA,GAAmB,eAAe;AAAA,KACzD,wBAAA,GAA2B,aAAa,CAAC,oBAAA;AAAA,KAEzC,8BAAA,GAAiC,gBAAA,GAC3C,yBAAyB;AAAA,KACf,kCAAA,GACV,aAAa,CAAC,8BAAA;AAAA,KAEJ,oBAAA,YAAgC,gBAAA,GAC1C,eAAA,CAAgB,CAAA;AAAA,KACN,wBAAA,YAAoC,aAAA,CAC9C,oBAAA,CAAqB,CAAA;AAAA,KAGX,wBAAA,mCAGR,gBAAA,GACF,mBAAA,CAAoB,KAAA,EAAO,OAAA;EAlCjB;;;;AAAmE;AAC/E;EAwCI,SAAA,GAAY,MAAA,EAAQ,OAAA,GAAU,YAAA,CAAa,OAAA;;;AAvCN;AAEzC;EA0CI,MAAA,GAAS,OAAA;;;;;EAKT,iBAAA,GAAoB,QAAA;IAClB,QAAA;IACA,MAAA;EAAA;AAAA;;KAKM,4BAAA,+BAGR,aAAA,CAAc,wBAAA,CAAyB,KAAA,EAAO,OAAA;AAAA,KAEtC,qBAAA,GAAwB,SAAS;AAAA,KACjC,yBAAA,GAA4B,aAAa,CAAC,qBAAA;;;;AAtDmB;AACzE;;;;KA+DY,6BAAA,GAAgC,MAAM,SAAS,aAAA;AAAA,KAE/C,4BAAA,GAA+B,gBAAA,GACzC,uBAAuB;AAAA,KACb,gCAAA,GACV,aAAa,CAAC,4BAAA;AAAA,KAEJ,uBAAA;EApEwB,+BAsElC,IAAA,EAAM,gBAAA,EArEI;EAuEV,UAAA,EAAY,6BAAA;EAEZ,QAAA,GAAW,aAAA;IAAgB,SAAA;IAAmB,KAAA;EAAA;AAAA"}
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { PartState } from "../../store/scopes/part.js";
|
|
2
|
+
|
|
1
3
|
//#region src/react/utils/groupParts.d.ts
|
|
2
4
|
/**
|
|
3
5
|
* Hierarchical adjacent-coalescing grouping for message parts.
|
|
@@ -11,12 +13,44 @@
|
|
|
11
13
|
* (`"0.1.0"`), stable under append-only streaming.
|
|
12
14
|
*/
|
|
13
15
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
16
|
+
* Symbol attached to memoizable `groupBy` functions (e.g. those returned
|
|
17
|
+
* by {@link groupPartByType}). Carries a string fingerprint of the config
|
|
18
|
+
* so `MessagePrimitive.GroupedParts` can memo the tree on
|
|
19
|
+
* `[parts, memoKey]` across renders — even when the helper call site
|
|
20
|
+
* reconstructs the function each render.
|
|
18
21
|
*/
|
|
19
|
-
|
|
22
|
+
declare const GROUPBY_MEMO_KEY: unique symbol;
|
|
23
|
+
/**
|
|
24
|
+
* Synthetic part-type key recognized by {@link groupPartByType}: a
|
|
25
|
+
* tool-call whose `mcp.app.resourceUri` points at an assistant-ui MCP
|
|
26
|
+
* app. Map this key to control how MCP-app tool calls are grouped —
|
|
27
|
+
* separately from regular `"tool-call"` parts.
|
|
28
|
+
*/
|
|
29
|
+
type GroupPartType = PartState["type"] | "mcp-app";
|
|
30
|
+
/**
|
|
31
|
+
* Build a `groupBy` from a `part.type → group-key path` lookup.
|
|
32
|
+
* Parts whose type isn't in the map are left ungrouped. The returned
|
|
33
|
+
* function carries a stable {@link GROUPBY_MEMO_KEY} fingerprint so
|
|
34
|
+
* `<MessagePrimitive.GroupedParts>` can memoize its tree across renders.
|
|
35
|
+
*
|
|
36
|
+
* Special key `"mcp-app"` matches tool-call parts that point at an
|
|
37
|
+
* assistant-ui MCP app resource (`ui://...`) and takes precedence over
|
|
38
|
+
* the `"tool-call"` entry for those parts.
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```tsx
|
|
42
|
+
* <MessagePrimitive.GroupedParts
|
|
43
|
+
* groupBy={groupPartByType({
|
|
44
|
+
* reasoning: ["group-thought", "group-reasoning"],
|
|
45
|
+
* "tool-call": ["group-thought", "group-tool"],
|
|
46
|
+
* "mcp-app": [],
|
|
47
|
+
* })}
|
|
48
|
+
* >
|
|
49
|
+
* {({ part, children }) => { ... }}
|
|
50
|
+
* </MessagePrimitive.GroupedParts>
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
declare const groupPartByType: <TKey extends `group-${string}`>(map: Partial<Readonly<Record<GroupPartType, readonly TKey[]>>>) => ((part: PartState) => readonly TKey[]);
|
|
20
54
|
type GroupNode = GroupNodeGroup | GroupNodePart;
|
|
21
55
|
interface GroupNodeGroup {
|
|
22
56
|
readonly type: "group";
|
|
@@ -35,12 +69,6 @@ interface GroupNodePart {
|
|
|
35
69
|
/** Structural React key: sibling-index path within parent. */
|
|
36
70
|
readonly nodeKey: string;
|
|
37
71
|
}
|
|
38
|
-
/**
|
|
39
|
-
* Normalize a `groupBy` return value to a path array.
|
|
40
|
-
* `null`/`undefined`/`[]` → `[]` (ungrouped).
|
|
41
|
-
* `"foo"` → `["foo"]`. Arrays pass through.
|
|
42
|
-
*/
|
|
43
|
-
declare const normalizeGroupKey: (key: GroupKey) => readonly string[];
|
|
44
72
|
/**
|
|
45
73
|
* Build the group tree from an array of normalized group paths.
|
|
46
74
|
* `paths[i]` is the path for part `i`. The output tree contains one
|
|
@@ -48,5 +76,5 @@ declare const normalizeGroupKey: (key: GroupKey) => readonly string[];
|
|
|
48
76
|
*/
|
|
49
77
|
declare const buildGroupTree: (paths: readonly (readonly string[])[]) => readonly GroupNode[];
|
|
50
78
|
//#endregion
|
|
51
|
-
export {
|
|
79
|
+
export { GROUPBY_MEMO_KEY, GroupNode, GroupNodeGroup, GroupNodePart, buildGroupTree, groupPartByType };
|
|
52
80
|
//# sourceMappingURL=groupParts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"groupParts.d.ts","names":[],"sources":["../../../src/react/utils/groupParts.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"groupParts.d.ts","names":[],"sources":["../../../src/react/utils/groupParts.ts"],"mappings":";;;;;AAsBA;;;;AAEC;AAAC;;;;AAQ4B;AAyB9B;;;;;;AAzB8B,cAVjB,gBAAA;;;;;;;KAUR,aAAA,GAAgB,SAAS;;;;;;;;;;AA2BQ;AAuBtC;;;;AAAsD;AAEtD;;;;;;;;cA3Ba,eAAA,mCACX,GAAA,EAAK,OAAA,CAAQ,QAAA,CAAS,MAAA,CAAO,aAAA,WAAwB,IAAA,YAClD,IAAA,EAAM,SAAA,cAAuB,IAAA;AAAA,KAuBtB,SAAA,GAAY,cAAA,GAAiB,aAAa;AAAA,UAErC,cAAA;EAAA,SACN,IAAA;EAUM;EAAA,SARN,GAAA;;WAEA,OAAA;EAOA;EAAA,SALA,OAAA;EAAA,SACA,QAAA,WAAmB,SAAS;AAAA;AAAA,UAGtB,aAAA;EAAA,SACN,IAAA;EAoGV;EAAA,SAlGU,KAAA;EAwBT;EAAA,SAtBS,OAAA;AAAA;;;;;;cAqBE,cAAA,GACX,KAAA,8CACU,SAAS"}
|