@assistant-ui/react 0.15.2 → 0.15.4
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/client/ExternalThread.d.ts.map +1 -1
- package/dist/client/ExternalThread.js +1 -0
- package/dist/client/ExternalThread.js.map +1 -1
- package/dist/client/InMemoryThreadList.d.ts.map +1 -1
- package/dist/client/InMemoryThreadList.js +199 -176
- package/dist/client/InMemoryThreadList.js.map +1 -1
- package/dist/client/SingleThreadList.d.ts.map +1 -1
- package/dist/client/SingleThreadList.js +56 -48
- package/dist/client/SingleThreadList.js.map +1 -1
- package/dist/legacy-runtime/cloud/auiV0.d.ts +2 -0
- package/dist/legacy-runtime/cloud/auiV0.d.ts.map +1 -1
- package/dist/legacy-runtime/cloud/auiV0.js +6 -4
- package/dist/legacy-runtime/cloud/auiV0.js.map +1 -1
- package/dist/legacy-runtime/runtime-cores/assistant-transport/types.d.ts +6 -0
- package/dist/legacy-runtime/runtime-cores/assistant-transport/types.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.d.ts.map +1 -1
- package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.js +20 -15
- package/dist/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.js.map +1 -1
- package/dist/mcp-apps/McpAppRenderer.d.ts.map +1 -1
- package/dist/mcp-apps/McpAppRenderer.js +25 -14
- package/dist/mcp-apps/McpAppRenderer.js.map +1 -1
- package/dist/mcp-apps/McpAppsRemoteHost.d.ts.map +1 -1
- package/dist/mcp-apps/McpAppsRemoteHost.js +17 -6
- package/dist/mcp-apps/McpAppsRemoteHost.js.map +1 -1
- package/dist/primitives/message/MessagePartsGrouped.d.ts +6 -1
- package/dist/primitives/message/MessagePartsGrouped.d.ts.map +1 -1
- package/dist/primitives/message/MessagePartsGrouped.js.map +1 -1
- package/dist/primitives/suggestion/SuggestionTrigger.d.ts +4 -2
- package/dist/primitives/suggestion/SuggestionTrigger.d.ts.map +1 -1
- package/dist/primitives/suggestion/SuggestionTrigger.js +21 -42
- package/dist/primitives/suggestion/SuggestionTrigger.js.map +1 -1
- package/dist/primitives/thread/ThreadSuggestion.d.ts +4 -2
- package/dist/primitives/thread/ThreadSuggestion.d.ts.map +1 -1
- package/dist/primitives/thread/ThreadSuggestion.js.map +1 -1
- package/package.json +6 -6
- package/src/client/ExternalThread.ts +1 -0
- package/src/client/InMemoryThreadList.ts +27 -7
- package/src/client/SingleThreadList.ts +10 -2
- package/src/legacy-runtime/cloud/auiV0.ts +8 -2
- package/src/legacy-runtime/runtime-cores/assistant-transport/types.ts +6 -0
- package/src/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.test.tsx +31 -0
- package/src/legacy-runtime/runtime-cores/assistant-transport/useAssistantTransportRuntime.ts +26 -17
- package/src/mcp-apps/McpAppRenderer.test.tsx +262 -3
- package/src/mcp-apps/McpAppRenderer.tsx +27 -15
- package/src/mcp-apps/McpAppsRemoteHost.ts +18 -9
- package/src/primitives/message/MessagePartsGrouped.tsx +6 -1
- package/src/primitives/suggestion/SuggestionTrigger.ts +11 -32
- package/src/primitives/thread/ThreadSuggestion.ts +2 -1
- package/src/tests/RemoteThreadListRuntime.reloadMainThread.test.tsx +115 -0
- package/src/tests/threadListItemIsRunning.test.tsx +198 -0
|
@@ -3,6 +3,7 @@ import { McpAppFrame } from "./app-frame.js";
|
|
|
3
3
|
import { getMcpAppFromToolPart } from "./utils.js";
|
|
4
4
|
import { useAui } from "@assistant-ui/store";
|
|
5
5
|
import { useEffect, useMemo, useRef, useState } from "@assistant-ui/tap/react-shim";
|
|
6
|
+
import { create } from "zustand";
|
|
6
7
|
import { Fragment, jsx } from "react/jsx-runtime";
|
|
7
8
|
import { resource, useResource } from "@assistant-ui/tap";
|
|
8
9
|
import { isRecord } from "@assistant-ui/core/internal";
|
|
@@ -22,7 +23,7 @@ function extractSendMessageText(params) {
|
|
|
22
23
|
if (typeof obj["text"] === "string") return obj["text"];
|
|
23
24
|
if (typeof obj["message"] === "string") return obj["message"];
|
|
24
25
|
}
|
|
25
|
-
function InlineRenderer({ part,
|
|
26
|
+
function InlineRenderer({ part, useHostStore, optionsRef }) {
|
|
26
27
|
const opts = optionsRef.current;
|
|
27
28
|
const aui = useAui();
|
|
28
29
|
const app = getMcpAppFromToolPart(part);
|
|
@@ -30,26 +31,30 @@ function InlineRenderer({ part, internalsRef, optionsRef }) {
|
|
|
30
31
|
if (app != null && (cachedAppRef.current?.resourceUri !== app.resourceUri || cachedAppRef.current?.serverId !== app.serverId)) cachedAppRef.current = app;
|
|
31
32
|
const appForRender = app ?? cachedAppRef.current;
|
|
32
33
|
const [loadedResource, setLoadedResource] = useState();
|
|
34
|
+
const host = useHostStore((state) => state.host);
|
|
33
35
|
const resourceUri = appForRender?.resourceUri;
|
|
34
36
|
const serverId = appForRender?.serverId;
|
|
35
37
|
const serverIdRef = useRef(void 0);
|
|
36
38
|
serverIdRef.current = serverId;
|
|
37
39
|
useEffect(() => {
|
|
38
|
-
if (
|
|
40
|
+
if (resourceUri == null) return;
|
|
39
41
|
let cancelled = false;
|
|
42
|
+
const targetHost = host;
|
|
40
43
|
const targetUri = resourceUri;
|
|
41
44
|
const targetServerId = serverId;
|
|
42
|
-
|
|
45
|
+
targetHost.loadResource({
|
|
43
46
|
uri: targetUri,
|
|
44
47
|
...targetServerId ? { serverId: targetServerId } : {}
|
|
45
48
|
}).then((res) => {
|
|
46
49
|
if (!cancelled) setLoadedResource({
|
|
50
|
+
host: targetHost,
|
|
47
51
|
resourceUri: targetUri,
|
|
48
52
|
...targetServerId !== void 0 ? { serverId: targetServerId } : {},
|
|
49
53
|
resource: res
|
|
50
54
|
});
|
|
51
55
|
}).catch((error) => {
|
|
52
56
|
if (!cancelled) setLoadedResource({
|
|
57
|
+
host: targetHost,
|
|
53
58
|
resourceUri: targetUri,
|
|
54
59
|
...targetServerId !== void 0 ? { serverId: targetServerId } : {},
|
|
55
60
|
error: error instanceof Error ? error : new Error(String(error))
|
|
@@ -58,7 +63,11 @@ function InlineRenderer({ part, internalsRef, optionsRef }) {
|
|
|
58
63
|
return () => {
|
|
59
64
|
cancelled = true;
|
|
60
65
|
};
|
|
61
|
-
}, [
|
|
66
|
+
}, [
|
|
67
|
+
host,
|
|
68
|
+
resourceUri,
|
|
69
|
+
serverId
|
|
70
|
+
]);
|
|
62
71
|
const bridgeHandlers = useMemo(() => ({
|
|
63
72
|
openLink: defaultOpenLink,
|
|
64
73
|
sendMessage: (params) => {
|
|
@@ -73,23 +82,23 @@ function InlineRenderer({ part, internalsRef, optionsRef }) {
|
|
|
73
82
|
}] });
|
|
74
83
|
return { ok: true };
|
|
75
84
|
},
|
|
76
|
-
callTool: (params_0) =>
|
|
85
|
+
callTool: (params_0) => useHostStore.getState().host.callTool({
|
|
77
86
|
...params_0,
|
|
78
87
|
...serverIdRef.current ? { serverId: serverIdRef.current } : {}
|
|
79
88
|
}),
|
|
80
|
-
readResource: (params_1) =>
|
|
89
|
+
readResource: (params_1) => useHostStore.getState().host.readResource({
|
|
81
90
|
...params_1,
|
|
82
91
|
...serverIdRef.current ? { serverId: serverIdRef.current } : {}
|
|
83
92
|
}),
|
|
84
93
|
listResources: (params_2) => {
|
|
85
|
-
if (!serverIdRef.current) return
|
|
86
|
-
return
|
|
94
|
+
if (!serverIdRef.current) return useHostStore.getState().host.listResources(params_2);
|
|
95
|
+
return useHostStore.getState().host.listResources({
|
|
87
96
|
...isRecord(params_2) ? params_2 : {},
|
|
88
97
|
serverId: serverIdRef.current
|
|
89
98
|
});
|
|
90
99
|
}
|
|
91
|
-
}), [aui,
|
|
92
|
-
const loadedResourceForApp = loadedResource?.resourceUri === appForRender?.resourceUri && loadedResource?.serverId === appForRender?.serverId ? loadedResource : void 0;
|
|
100
|
+
}), [aui, useHostStore]);
|
|
101
|
+
const loadedResourceForApp = loadedResource?.host === host && loadedResource?.resourceUri === appForRender?.resourceUri && loadedResource?.serverId === appForRender?.serverId ? loadedResource : void 0;
|
|
93
102
|
const appResource = loadedResourceForApp?.resource;
|
|
94
103
|
const error_0 = loadedResourceForApp?.error;
|
|
95
104
|
const fallback = opts.fallback ?? null;
|
|
@@ -125,17 +134,19 @@ const useMcpAppRenderer = (options) => {
|
|
|
125
134
|
const host = useResource(options.host);
|
|
126
135
|
const optionsRef = useRef(options);
|
|
127
136
|
optionsRef.current = options;
|
|
128
|
-
const
|
|
129
|
-
|
|
137
|
+
const [useHostStore] = useState(() => create(() => ({ host })));
|
|
138
|
+
useEffect(() => {
|
|
139
|
+
useHostStore.setState({ host });
|
|
140
|
+
}, [host, useHostStore]);
|
|
130
141
|
return { render: useMemo(() => {
|
|
131
142
|
const Render = (props) => /* @__PURE__ */ jsx(InlineRenderer, {
|
|
132
143
|
part: props,
|
|
133
|
-
|
|
144
|
+
useHostStore,
|
|
134
145
|
optionsRef
|
|
135
146
|
});
|
|
136
147
|
Render.displayName = "McpAppRenderer";
|
|
137
148
|
return Render;
|
|
138
|
-
}, []) };
|
|
149
|
+
}, [useHostStore]) };
|
|
139
150
|
};
|
|
140
151
|
const McpAppRenderer = resource(useMcpAppRenderer);
|
|
141
152
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"McpAppRenderer.js","names":["useEffect","useMemo","useRef","useState","MutableRefObject","ReactNode","McpAppMetadata","ToolCallMessagePartComponent","ToolCallMessagePartProps","useAui","useResource","resource","ResourceElement","McpAppFrame","McpAppBridgeHandlers","McpAppHostContext","McpAppHostInfo","McpAppResource","McpAppSandboxConfig","McpAppsHost","getMcpAppFromToolPart","isRecord","McpAppRendererOptions","host","sandbox","maxHeight","hostInfo","hostContext","fallback","loadingFallback","errorFallback","error","Error","LoadedResourceState","resourceUri","serverId","getInput","part","status","type","argsText","args","undefined","defaultOpenLink","url","window","open","extractSendMessageText","params","obj","Record","InlineRenderer","internalsRef","optionsRef","opts","current","aui","app","cachedAppRef","appForRender","loadedResource","setLoadedResource","serverIdRef","cancelled","targetUri","targetServerId","loadResource","uri","then","res","catch","String","bridgeHandlers","openLink","sendMessage","text","ok","reason","thread","append","content","callTool","readResource","listResources","loadedResourceForApp","appResource","result","useMcpAppRenderer","options","render","Render","props","displayName","McpAppRenderer"],"sources":["../../src/mcp-apps/McpAppRenderer.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n useEffect,\n useMemo,\n useRef,\n useState,\n type MutableRefObject,\n type ReactNode,\n} from \"react\";\nimport type { McpAppMetadata } from \"@assistant-ui/core\";\nimport type {\n ToolCallMessagePartComponent,\n ToolCallMessagePartProps,\n} from \"@assistant-ui/core/react\";\nimport { useAui } from \"@assistant-ui/store\";\n\nimport { useResource, resource, type ResourceElement } from \"@assistant-ui/tap\";\nimport { McpAppFrame } from \"./app-frame\";\nimport type {\n McpAppBridgeHandlers,\n McpAppHostContext,\n McpAppHostInfo,\n McpAppResource,\n McpAppSandboxConfig,\n McpAppsHost,\n} from \"./types\";\nimport { getMcpAppFromToolPart } from \"./utils\";\nimport { isRecord } from \"@assistant-ui/core/internal\";\n\nexport type McpAppRendererOptions = {\n /**\n * Provides the data-plane operations the widget can request\n * (`loadResource`, `callTool`, `readResource`, `listResources`). Use\n * `McpAppsRemoteHost({ url })` for the default HTTP-route convention.\n */\n host: ResourceElement<McpAppsHost>;\n /** Sandbox + container styling. Passes through to SafeContentFrame. */\n sandbox?: McpAppSandboxConfig;\n /**\n * Upper bound (in pixels) applied to the widget-driven auto-resize height.\n * Defaults to 800.\n */\n maxHeight?: number;\n /** Identifies the host to the widget in the `ui/initialize` response. */\n hostInfo?: McpAppHostInfo;\n /** Delivered to the widget on initialize and pushed via `notifications/host_context/changed` on change. */\n hostContext?: McpAppHostContext;\n /** Rendered when no MCP app is on the part, or while load is in flight / failed (unless overridden). */\n fallback?: ReactNode;\n /** Rendered while the resource is loading. Defaults to `fallback`. */\n loadingFallback?: ReactNode;\n /** Rendered when the resource load rejects. Defaults to `fallback`. */\n errorFallback?: ReactNode | ((error: Error) => ReactNode);\n};\n\ntype LoadedResourceState = {\n resourceUri: string;\n serverId?: string;\n resource?: McpAppResource;\n error?: Error;\n};\n\nfunction getInput(part: {\n status: { type: string };\n argsText: string;\n args: unknown;\n}): unknown {\n if (\n part.status.type === \"running\" &&\n (part.argsText === \"\" || part.argsText === \"{}\")\n ) {\n return undefined;\n }\n return part.args;\n}\n\nconst defaultOpenLink = ({ url }: { url: string }) => {\n window.open(url, \"_blank\", \"noopener,noreferrer\");\n};\n\nfunction extractSendMessageText(params: unknown): string | undefined {\n if (typeof params === \"string\") return params;\n if (!params || typeof params !== \"object\") return undefined;\n const obj = params as Record<string, unknown>;\n if (typeof obj[\"prompt\"] === \"string\") return obj[\"prompt\"];\n if (typeof obj[\"text\"] === \"string\") return obj[\"text\"];\n if (typeof obj[\"message\"] === \"string\") return obj[\"message\"];\n return undefined;\n}\n\nfunction InlineRenderer({\n part,\n internalsRef,\n optionsRef,\n}: {\n part: ToolCallMessagePartProps;\n internalsRef: MutableRefObject<{ host: McpAppsHost }>;\n optionsRef: MutableRefObject<McpAppRendererOptions>;\n}) {\n const opts = optionsRef.current;\n const aui = useAui();\n const app = getMcpAppFromToolPart(part);\n const cachedAppRef = useRef<McpAppMetadata | undefined>(undefined);\n if (\n app != null &&\n (cachedAppRef.current?.resourceUri !== app.resourceUri ||\n cachedAppRef.current?.serverId !== app.serverId)\n ) {\n cachedAppRef.current = app;\n }\n const appForRender = app ?? cachedAppRef.current;\n\n const [loadedResource, setLoadedResource] = useState<LoadedResourceState>();\n\n const resourceUri = appForRender?.resourceUri;\n const serverId = appForRender?.serverId;\n const serverIdRef = useRef<string | undefined>(undefined);\n serverIdRef.current = serverId;\n useEffect(() => {\n if (appForRender == null || resourceUri == null) return;\n let cancelled = false;\n const targetUri = resourceUri;\n const targetServerId = serverId;\n\n internalsRef.current.host\n .loadResource({\n uri: targetUri,\n ...(targetServerId ? { serverId: targetServerId } : {}),\n })\n .then((res) => {\n if (!cancelled)\n setLoadedResource({\n resourceUri: targetUri,\n ...(targetServerId !== undefined\n ? { serverId: targetServerId }\n : {}),\n resource: res,\n });\n })\n .catch((error: unknown) => {\n if (!cancelled) {\n setLoadedResource({\n resourceUri: targetUri,\n ...(targetServerId !== undefined\n ? { serverId: targetServerId }\n : {}),\n error: error instanceof Error ? error : new Error(String(error)),\n });\n }\n });\n\n return () => {\n cancelled = true;\n };\n // oxlint-disable-next-line react/exhaustive-deps -- re-fetch only when URI or server identity changes; appForRender identity is unstable and internalsRef is a stable ref\n }, [resourceUri, serverId]);\n\n const bridgeHandlers = useMemo<McpAppBridgeHandlers>(\n () => ({\n openLink: defaultOpenLink,\n sendMessage: (params) => {\n const text = extractSendMessageText(params);\n if (!text) return { ok: false, reason: \"unrecognised params shape\" };\n aui.thread.append({ content: [{ type: \"text\", text }] });\n return { ok: true };\n },\n callTool: (params) =>\n internalsRef.current.host.callTool({\n ...params,\n ...(serverIdRef.current ? { serverId: serverIdRef.current } : {}),\n }),\n readResource: (params) =>\n internalsRef.current.host.readResource({\n ...params,\n ...(serverIdRef.current ? { serverId: serverIdRef.current } : {}),\n }),\n listResources: (params) => {\n if (!serverIdRef.current) {\n return internalsRef.current.host.listResources(params);\n }\n return internalsRef.current.host.listResources({\n ...(isRecord(params) ? params : {}),\n serverId: serverIdRef.current,\n });\n },\n }),\n [aui, internalsRef],\n );\n\n const loadedResourceForApp =\n loadedResource?.resourceUri === appForRender?.resourceUri &&\n loadedResource?.serverId === appForRender?.serverId\n ? loadedResource\n : undefined;\n const appResource = loadedResourceForApp?.resource;\n const error = loadedResourceForApp?.error;\n\n const fallback = opts.fallback ?? null;\n if (appForRender == null) {\n return <>{fallback}</>;\n }\n if (error != null) {\n const errorFallback = opts.errorFallback;\n if (errorFallback === undefined) return <>{fallback}</>;\n if (typeof errorFallback === \"function\") return <>{errorFallback(error)}</>;\n return <>{errorFallback}</>;\n }\n if (appResource == null) {\n return <>{opts.loadingFallback ?? fallback}</>;\n }\n\n return (\n <McpAppFrame\n app={appForRender}\n resource={appResource}\n input={getInput(part)}\n output={part.result}\n sandbox={opts.sandbox}\n handlers={bridgeHandlers}\n hostInfo={opts.hostInfo}\n hostContext={opts.hostContext}\n maxHeight={opts.maxHeight}\n />\n );\n}\n\n/**\n * Creates a tool-call renderer for MCP Apps embedded in assistant messages.\n *\n * Compose this into the `Tools` resource through its `mcpApp` option. When a\n * tool-call part carries `mcp.app` metadata for a `ui://` resource, the\n * renderer loads that resource from the configured host and displays it in a\n * sandboxed frame.\n */\nconst useMcpAppRenderer = (\n options: McpAppRendererOptions,\n): { readonly render: ToolCallMessagePartComponent } => {\n const host = useResource(options.host);\n\n const optionsRef = useRef<McpAppRendererOptions>(options);\n optionsRef.current = options;\n\n const internalsRef = useRef<{ host: McpAppsHost }>({ host });\n internalsRef.current = { host };\n\n const render = useMemo((): ToolCallMessagePartComponent => {\n const Render: ToolCallMessagePartComponent = (props) => (\n <InlineRenderer\n part={props}\n internalsRef={internalsRef}\n optionsRef={optionsRef}\n />\n );\n Render.displayName = \"McpAppRenderer\";\n return Render;\n }, []);\n\n return { render };\n};\n\nexport const McpAppRenderer = resource(useMcpAppRenderer);\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"McpAppRenderer.js","names":["useEffect","useMemo","useRef","useState","MutableRefObject","ReactNode","McpAppMetadata","ToolCallMessagePartComponent","ToolCallMessagePartProps","useAui","create","StoreApi","UseBoundStore","useResource","resource","ResourceElement","McpAppFrame","McpAppBridgeHandlers","McpAppHostContext","McpAppHostInfo","McpAppResource","McpAppSandboxConfig","McpAppsHost","getMcpAppFromToolPart","isRecord","McpAppRendererOptions","host","sandbox","maxHeight","hostInfo","hostContext","fallback","loadingFallback","errorFallback","error","Error","LoadedResourceState","resourceUri","serverId","UseHostStore","getInput","part","status","type","argsText","args","undefined","defaultOpenLink","url","window","open","extractSendMessageText","params","obj","Record","InlineRenderer","useHostStore","optionsRef","opts","current","aui","app","cachedAppRef","appForRender","loadedResource","setLoadedResource","state","serverIdRef","cancelled","targetHost","targetUri","targetServerId","loadResource","uri","then","res","catch","String","bridgeHandlers","openLink","sendMessage","text","ok","reason","thread","append","content","callTool","getState","readResource","listResources","loadedResourceForApp","appResource","result","useMcpAppRenderer","options","render","setState","Render","props","displayName","McpAppRenderer"],"sources":["../../src/mcp-apps/McpAppRenderer.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n useEffect,\n useMemo,\n useRef,\n useState,\n type MutableRefObject,\n type ReactNode,\n} from \"react\";\nimport type { McpAppMetadata } from \"@assistant-ui/core\";\nimport type {\n ToolCallMessagePartComponent,\n ToolCallMessagePartProps,\n} from \"@assistant-ui/core/react\";\nimport { useAui } from \"@assistant-ui/store\";\nimport { create, type StoreApi, type UseBoundStore } from \"zustand\";\n\nimport { useResource, resource, type ResourceElement } from \"@assistant-ui/tap\";\nimport { McpAppFrame } from \"./app-frame\";\nimport type {\n McpAppBridgeHandlers,\n McpAppHostContext,\n McpAppHostInfo,\n McpAppResource,\n McpAppSandboxConfig,\n McpAppsHost,\n} from \"./types\";\nimport { getMcpAppFromToolPart } from \"./utils\";\nimport { isRecord } from \"@assistant-ui/core/internal\";\n\nexport type McpAppRendererOptions = {\n /**\n * Provides the data-plane operations the widget can request\n * (`loadResource`, `callTool`, `readResource`, `listResources`). Use\n * `McpAppsRemoteHost({ url })` for the default HTTP-route convention.\n */\n host: ResourceElement<McpAppsHost>;\n /** Sandbox + container styling. Passes through to SafeContentFrame. */\n sandbox?: McpAppSandboxConfig;\n /**\n * Upper bound (in pixels) applied to the widget-driven auto-resize height.\n * Defaults to 800.\n */\n maxHeight?: number;\n /** Identifies the host to the widget in the `ui/initialize` response. */\n hostInfo?: McpAppHostInfo;\n /** Delivered to the widget on initialize and pushed via `notifications/host_context/changed` on change. */\n hostContext?: McpAppHostContext;\n /** Rendered when no MCP app is on the part, or while load is in flight / failed (unless overridden). */\n fallback?: ReactNode;\n /** Rendered while the resource is loading. Defaults to `fallback`. */\n loadingFallback?: ReactNode;\n /** Rendered when the resource load rejects. Defaults to `fallback`. */\n errorFallback?: ReactNode | ((error: Error) => ReactNode);\n};\n\ntype LoadedResourceState = {\n host: McpAppsHost;\n resourceUri: string;\n serverId?: string;\n resource?: McpAppResource;\n error?: Error;\n};\n\ntype UseHostStore = UseBoundStore<StoreApi<{ host: McpAppsHost }>>;\n\nfunction getInput(part: {\n status: { type: string };\n argsText: string;\n args: unknown;\n}): unknown {\n if (\n part.status.type === \"running\" &&\n (part.argsText === \"\" || part.argsText === \"{}\")\n ) {\n return undefined;\n }\n return part.args;\n}\n\nconst defaultOpenLink = ({ url }: { url: string }) => {\n window.open(url, \"_blank\", \"noopener,noreferrer\");\n};\n\nfunction extractSendMessageText(params: unknown): string | undefined {\n if (typeof params === \"string\") return params;\n if (!params || typeof params !== \"object\") return undefined;\n const obj = params as Record<string, unknown>;\n if (typeof obj[\"prompt\"] === \"string\") return obj[\"prompt\"];\n if (typeof obj[\"text\"] === \"string\") return obj[\"text\"];\n if (typeof obj[\"message\"] === \"string\") return obj[\"message\"];\n return undefined;\n}\n\nfunction InlineRenderer({\n part,\n useHostStore,\n optionsRef,\n}: {\n part: ToolCallMessagePartProps;\n useHostStore: UseHostStore;\n optionsRef: MutableRefObject<McpAppRendererOptions>;\n}) {\n const opts = optionsRef.current;\n const aui = useAui();\n const app = getMcpAppFromToolPart(part);\n const cachedAppRef = useRef<McpAppMetadata | undefined>(undefined);\n if (\n app != null &&\n (cachedAppRef.current?.resourceUri !== app.resourceUri ||\n cachedAppRef.current?.serverId !== app.serverId)\n ) {\n cachedAppRef.current = app;\n }\n const appForRender = app ?? cachedAppRef.current;\n\n const [loadedResource, setLoadedResource] = useState<LoadedResourceState>();\n\n const host = useHostStore((state) => state.host);\n const resourceUri = appForRender?.resourceUri;\n const serverId = appForRender?.serverId;\n const serverIdRef = useRef<string | undefined>(undefined);\n serverIdRef.current = serverId;\n useEffect(() => {\n if (resourceUri == null) return;\n let cancelled = false;\n const targetHost = host;\n const targetUri = resourceUri;\n const targetServerId = serverId;\n\n targetHost\n .loadResource({\n uri: targetUri,\n ...(targetServerId ? { serverId: targetServerId } : {}),\n })\n .then((res) => {\n if (!cancelled)\n setLoadedResource({\n host: targetHost,\n resourceUri: targetUri,\n ...(targetServerId !== undefined\n ? { serverId: targetServerId }\n : {}),\n resource: res,\n });\n })\n .catch((error: unknown) => {\n if (!cancelled) {\n setLoadedResource({\n host: targetHost,\n resourceUri: targetUri,\n ...(targetServerId !== undefined\n ? { serverId: targetServerId }\n : {}),\n error: error instanceof Error ? error : new Error(String(error)),\n });\n }\n });\n\n return () => {\n cancelled = true;\n };\n }, [host, resourceUri, serverId]);\n\n const bridgeHandlers = useMemo<McpAppBridgeHandlers>(\n () => ({\n openLink: defaultOpenLink,\n sendMessage: (params) => {\n const text = extractSendMessageText(params);\n if (!text) return { ok: false, reason: \"unrecognised params shape\" };\n aui.thread.append({ content: [{ type: \"text\", text }] });\n return { ok: true };\n },\n callTool: (params) =>\n useHostStore.getState().host.callTool({\n ...params,\n ...(serverIdRef.current ? { serverId: serverIdRef.current } : {}),\n }),\n readResource: (params) =>\n useHostStore.getState().host.readResource({\n ...params,\n ...(serverIdRef.current ? { serverId: serverIdRef.current } : {}),\n }),\n listResources: (params) => {\n if (!serverIdRef.current) {\n return useHostStore.getState().host.listResources(params);\n }\n return useHostStore.getState().host.listResources({\n ...(isRecord(params) ? params : {}),\n serverId: serverIdRef.current,\n });\n },\n }),\n [aui, useHostStore],\n );\n\n const loadedResourceForApp =\n loadedResource?.host === host &&\n loadedResource?.resourceUri === appForRender?.resourceUri &&\n loadedResource?.serverId === appForRender?.serverId\n ? loadedResource\n : undefined;\n const appResource = loadedResourceForApp?.resource;\n const error = loadedResourceForApp?.error;\n\n const fallback = opts.fallback ?? null;\n if (appForRender == null) {\n return <>{fallback}</>;\n }\n if (error != null) {\n const errorFallback = opts.errorFallback;\n if (errorFallback === undefined) return <>{fallback}</>;\n if (typeof errorFallback === \"function\") return <>{errorFallback(error)}</>;\n return <>{errorFallback}</>;\n }\n if (appResource == null) {\n return <>{opts.loadingFallback ?? fallback}</>;\n }\n\n return (\n <McpAppFrame\n app={appForRender}\n resource={appResource}\n input={getInput(part)}\n output={part.result}\n sandbox={opts.sandbox}\n handlers={bridgeHandlers}\n hostInfo={opts.hostInfo}\n hostContext={opts.hostContext}\n maxHeight={opts.maxHeight}\n />\n );\n}\n\n/**\n * Creates a tool-call renderer for MCP Apps embedded in assistant messages.\n *\n * Compose this into the `Tools` resource through its `mcpApp` option. When a\n * tool-call part carries `mcp.app` metadata for a `ui://` resource, the\n * renderer loads that resource from the configured host and displays it in a\n * sandboxed frame.\n */\nconst useMcpAppRenderer = (\n options: McpAppRendererOptions,\n): { readonly render: ToolCallMessagePartComponent } => {\n const host = useResource(options.host);\n\n const optionsRef = useRef<McpAppRendererOptions>(options);\n optionsRef.current = options;\n\n const [useHostStore] = useState(() =>\n create<{ host: McpAppsHost }>(() => ({ host })),\n );\n useEffect(() => {\n useHostStore.setState({ host });\n }, [host, useHostStore]);\n\n const render = useMemo((): ToolCallMessagePartComponent => {\n const Render: ToolCallMessagePartComponent = (props) => (\n <InlineRenderer\n part={props}\n useHostStore={useHostStore}\n optionsRef={optionsRef}\n />\n );\n Render.displayName = \"McpAppRenderer\";\n return Render;\n }, [useHostStore]);\n\n return { render };\n};\n\nexport const McpAppRenderer = resource(useMcpAppRenderer);\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"McpAppsRemoteHost.d.ts","names":[],"sources":["../../src/mcp-apps/McpAppsRemoteHost.ts"],"mappings":";;
|
|
1
|
+
{"version":3,"file":"McpAppsRemoteHost.d.ts","names":[],"sources":["../../src/mcp-apps/McpAppsRemoteHost.ts"],"mappings":";;cA6Ga,+CAAiB,SAAA,cAAA,SAAA"}
|
|
@@ -59,12 +59,23 @@ async function postToHost(options, method, params) {
|
|
|
59
59
|
const useMcpAppsRemoteHost = (options) => {
|
|
60
60
|
const optionsRef = useRef(options);
|
|
61
61
|
optionsRef.current = options;
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
62
|
+
const url = options.url;
|
|
63
|
+
return useMemo(() => {
|
|
64
|
+
const getCurrentOptions = () => {
|
|
65
|
+
const current = optionsRef.current;
|
|
66
|
+
return {
|
|
67
|
+
url,
|
|
68
|
+
...current.fetch !== void 0 ? { fetch: current.fetch } : {},
|
|
69
|
+
...current.headers !== void 0 ? { headers: current.headers } : {}
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
return {
|
|
73
|
+
loadResource: (params) => postToHost(getCurrentOptions(), "mcp-apps/read-resource", params),
|
|
74
|
+
callTool: (params_0) => postToHost(getCurrentOptions(), "tools/call", params_0),
|
|
75
|
+
readResource: (params_1) => postToHost(getCurrentOptions(), "resources/read", params_1),
|
|
76
|
+
listResources: (params_2) => postToHost(getCurrentOptions(), "resources/list", params_2)
|
|
77
|
+
};
|
|
78
|
+
}, [url]);
|
|
68
79
|
};
|
|
69
80
|
const McpAppsRemoteHost = resource(useMcpAppsRemoteHost);
|
|
70
81
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"McpAppsRemoteHost.js","names":["useMemo","useRef","resource","McpAppResource","McpAppsHost","McpAppsRemoteHostOptions","truncateBody","body","length","slice","extractErrorBody","trimmed","trim","undefined","parsed","JSON","parse","record","Record","message","error","readErrorBody","res","Response","Promise","text","postToHost","options","method","params","doFetch","fetch","extraHeaders","headers","url","stringify","ok","status","statusText","Error","json","useMcpAppsRemoteHost","optionsRef","current","loadResource","callTool","readResource","listResources","McpAppsRemoteHost"],"sources":["../../src/mcp-apps/McpAppsRemoteHost.ts"],"sourcesContent":["import { useMemo, useRef } from \"react\";\nimport { resource } from \"@assistant-ui/tap\";\nimport type {\n McpAppResource,\n McpAppsHost,\n McpAppsRemoteHostOptions,\n} from \"./types\";\n\nconst truncateBody = (body: string) =>\n body.length > 500 ? `${body.slice(0, 500)}...` : body;\n\nconst extractErrorBody = (body: string): string | undefined => {\n const trimmed = body.trim();\n if (!trimmed) return undefined;\n\n try {\n const parsed = JSON.parse(trimmed) as unknown;\n if (parsed && typeof parsed === \"object\") {\n const record = parsed as Record<string, unknown>;\n if (typeof record.message === \"string\") return record.message;\n if (typeof record.error === \"string\") return record.error;\n if (record.error && typeof record.error === \"object\") {\n const error = record.error as Record<string, unknown>;\n if (typeof error.message === \"string\") return error.message;\n }\n }\n } catch {\n return truncateBody(trimmed);\n }\n\n return truncateBody(trimmed);\n};\n\nconst readErrorBody = async (res: Response): Promise<string | undefined> => {\n try {\n return extractErrorBody(await res.text());\n } catch {\n return undefined;\n }\n};\n\nasync function postToHost(\n options: McpAppsRemoteHostOptions,\n method: string,\n params: unknown,\n): Promise<unknown> {\n const doFetch = options.fetch ?? fetch;\n const extraHeaders =\n typeof options.headers === \"function\"\n ? await options.headers()\n : (options.headers ?? {});\n const res = await doFetch(options.url, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\", ...extraHeaders },\n body: JSON.stringify({ method, params }),\n });\n if (!res.ok) {\n const status = res.statusText\n ? `${res.status} ${res.statusText}`\n : `${res.status}`;\n const body = await readErrorBody(res);\n throw new Error(\n `MCP App host request \"${method}\" to \"${options.url}\" failed with ${status}${body ? `: ${body}` : \"\"}`,\n );\n }\n return res.json();\n}\n\n/**\n * Creates the default HTTP host for MCP App widgets.\n *\n * The host POSTs widget requests to the configured route as `{ method,\n * params }`, using the method names expected by the assistant-ui MCP Apps\n * guide.\n */\nconst useMcpAppsRemoteHost = (\n options: McpAppsRemoteHostOptions,\n): McpAppsHost => {\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n return useMemo(\n ():
|
|
1
|
+
{"version":3,"file":"McpAppsRemoteHost.js","names":["useMemo","useRef","resource","McpAppResource","McpAppsHost","McpAppsRemoteHostOptions","truncateBody","body","length","slice","extractErrorBody","trimmed","trim","undefined","parsed","JSON","parse","record","Record","message","error","readErrorBody","res","Response","Promise","text","postToHost","options","method","params","doFetch","fetch","extraHeaders","headers","url","stringify","ok","status","statusText","Error","json","useMcpAppsRemoteHost","optionsRef","current","getCurrentOptions","loadResource","callTool","readResource","listResources","McpAppsRemoteHost"],"sources":["../../src/mcp-apps/McpAppsRemoteHost.ts"],"sourcesContent":["import { useMemo, useRef } from \"react\";\nimport { resource } from \"@assistant-ui/tap\";\nimport type {\n McpAppResource,\n McpAppsHost,\n McpAppsRemoteHostOptions,\n} from \"./types\";\n\nconst truncateBody = (body: string) =>\n body.length > 500 ? `${body.slice(0, 500)}...` : body;\n\nconst extractErrorBody = (body: string): string | undefined => {\n const trimmed = body.trim();\n if (!trimmed) return undefined;\n\n try {\n const parsed = JSON.parse(trimmed) as unknown;\n if (parsed && typeof parsed === \"object\") {\n const record = parsed as Record<string, unknown>;\n if (typeof record.message === \"string\") return record.message;\n if (typeof record.error === \"string\") return record.error;\n if (record.error && typeof record.error === \"object\") {\n const error = record.error as Record<string, unknown>;\n if (typeof error.message === \"string\") return error.message;\n }\n }\n } catch {\n return truncateBody(trimmed);\n }\n\n return truncateBody(trimmed);\n};\n\nconst readErrorBody = async (res: Response): Promise<string | undefined> => {\n try {\n return extractErrorBody(await res.text());\n } catch {\n return undefined;\n }\n};\n\nasync function postToHost(\n options: McpAppsRemoteHostOptions,\n method: string,\n params: unknown,\n): Promise<unknown> {\n const doFetch = options.fetch ?? fetch;\n const extraHeaders =\n typeof options.headers === \"function\"\n ? await options.headers()\n : (options.headers ?? {});\n const res = await doFetch(options.url, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\", ...extraHeaders },\n body: JSON.stringify({ method, params }),\n });\n if (!res.ok) {\n const status = res.statusText\n ? `${res.status} ${res.statusText}`\n : `${res.status}`;\n const body = await readErrorBody(res);\n throw new Error(\n `MCP App host request \"${method}\" to \"${options.url}\" failed with ${status}${body ? `: ${body}` : \"\"}`,\n );\n }\n return res.json();\n}\n\n/**\n * Creates the default HTTP host for MCP App widgets.\n *\n * The host POSTs widget requests to the configured route as `{ method,\n * params }`, using the method names expected by the assistant-ui MCP Apps\n * guide.\n */\nconst useMcpAppsRemoteHost = (\n options: McpAppsRemoteHostOptions,\n): McpAppsHost => {\n const optionsRef = useRef(options);\n optionsRef.current = options;\n\n const url = options.url;\n\n return useMemo((): McpAppsHost => {\n const getCurrentOptions = (): McpAppsRemoteHostOptions => {\n const current = optionsRef.current;\n return {\n url,\n ...(current.fetch !== undefined ? { fetch: current.fetch } : {}),\n ...(current.headers !== undefined ? { headers: current.headers } : {}),\n };\n };\n return {\n loadResource: (params) =>\n postToHost(\n getCurrentOptions(),\n \"mcp-apps/read-resource\",\n params,\n ) as Promise<McpAppResource>,\n callTool: (params) =>\n postToHost(getCurrentOptions(), \"tools/call\", params),\n readResource: (params) =>\n postToHost(getCurrentOptions(), \"resources/read\", params),\n listResources: (params) =>\n postToHost(getCurrentOptions(), \"resources/list\", params),\n };\n }, [url]);\n};\n\nexport const McpAppsRemoteHost = resource(useMcpAppsRemoteHost);\n"],"mappings":";;;AAQA,MAAMM,gBAAgBC,SACpBA,KAAKC,SAAS,MAAM,GAAGD,KAAKE,MAAM,GAAG,GAAG,EAAC,OAAQF;AAEnD,MAAMG,oBAAoBH,SAAqC;CAC7D,MAAMI,UAAUJ,KAAKK,KAAK;CAC1B,IAAI,CAACD,SAAS,OAAOE,KAAAA;CAErB,IAAI;EACF,MAAMC,SAASC,KAAKC,MAAML,OAAO;EACjC,IAAIG,UAAU,OAAOA,WAAW,UAAU;GACxC,MAAMG,SAASH;GACf,IAAI,OAAOG,OAAOE,YAAY,UAAU,OAAOF,OAAOE;GACtD,IAAI,OAAOF,OAAOG,UAAU,UAAU,OAAOH,OAAOG;GACpD,IAAIH,OAAOG,SAAS,OAAOH,OAAOG,UAAU,UAAU;IACpD,MAAMA,QAAQH,OAAOG;IACrB,IAAI,OAAOA,MAAMD,YAAY,UAAU,OAAOC,MAAMD;GACtD;EACF;CACF,QAAQ;EACN,OAAOb,aAAaK,OAAO;CAC7B;CAEA,OAAOL,aAAaK,OAAO;AAC7B;AAEA,MAAMU,gBAAgB,OAAOC,QAA+C;CAC1E,IAAI;EACF,OAAOZ,iBAAiB,MAAMY,IAAIG,KAAK,CAAC;CAC1C,QAAQ;EACN;CACF;AACF;AAEA,eAAeC,WACbC,SACAC,QACAC,QACkB;CAClB,MAAMC,UAAUH,QAAQI,SAASA;CACjC,MAAMC,eACJ,OAAOL,QAAQM,YAAY,aACvB,MAAMN,QAAQM,QAAQ,IACrBN,QAAQM,WAAW,CAAC;CAC3B,MAAMX,MAAM,MAAMQ,QAAQH,QAAQO,KAAK;EACrCN,QAAQ;EACRK,SAAS;GAAE,gBAAgB;GAAoB,GAAGD;EAAa;EAC/DzB,MAAMQ,KAAKoB,UAAU;GAAEP;GAAQC;EAAO,CAAC;CACzC,CAAC;CACD,IAAI,CAACP,IAAIc,IAAI;EACX,MAAMC,SAASf,IAAIgB,aACf,GAAGhB,IAAIe,OAAM,GAAIf,IAAIgB,eACrB,GAAGhB,IAAIe;EACX,MAAM9B,OAAO,MAAMc,cAAcC,GAAG;EACpC,MAAM,IAAIiB,MACR,yBAAyBX,OAAM,QAASD,QAAQO,IAAG,gBAAiBG,SAAS9B,OAAO,KAAKA,SAAS,IACpG;CACF;CACA,OAAOe,IAAIkB,KAAK;AAClB;;;;;;;;AASA,MAAMC,wBACJd,YACgB;CAChB,MAAMe,aAAazC,OAAO0B,OAAO;CACjCe,WAAWC,UAAUhB;CAErB,MAAMO,MAAMP,QAAQO;CAEpB,OAAOlC,cAA2B;EAChC,MAAM4C,0BAAoD;GACxD,MAAMD,UAAUD,WAAWC;GAC3B,OAAO;IACLT;IACA,GAAIS,QAAQZ,UAAUlB,KAAAA,IAAY,EAAEkB,OAAOY,QAAQZ,MAAM,IAAI,CAAC;IAC9D,GAAIY,QAAQV,YAAYpB,KAAAA,IAAY,EAAEoB,SAASU,QAAQV,QAAQ,IAAI,CAAC;GACtE;EACF;EACA,OAAO;GACLY,eAAehB,WACbH,WACEkB,kBAAkB,GAClB,0BACAf,MACF;GACFiB,WAAWjB,aACTH,WAAWkB,kBAAkB,GAAG,cAAcf,QAAM;GACtDkB,eAAelB,aACbH,WAAWkB,kBAAkB,GAAG,kBAAkBf,QAAM;GAC1DmB,gBAAgBnB,aACdH,WAAWkB,kBAAkB,GAAG,kBAAkBf,QAAM;EAC5D;CACF,GAAG,CAACK,GAAG,CAAC;AACV;AAEA,MAAae,oBAAoB/C,SAASuC,oBAAoB"}
|
|
@@ -71,7 +71,12 @@ declare namespace MessagePrimitiveUnstable_PartsGrouped {
|
|
|
71
71
|
Image?: ImageMessagePartComponent | undefined;
|
|
72
72
|
/** Component for rendering file content */
|
|
73
73
|
File?: FileMessagePartComponent | undefined;
|
|
74
|
-
/**
|
|
74
|
+
/**
|
|
75
|
+
* Component for rendering audio content.
|
|
76
|
+
*
|
|
77
|
+
* @deprecated Render audio through the `File` slot instead, branching
|
|
78
|
+
* on an `audio/*` mime type.
|
|
79
|
+
*/
|
|
75
80
|
Unstable_Audio?: Unstable_AudioMessagePartComponent | undefined;
|
|
76
81
|
/** Configuration for data part rendering */
|
|
77
82
|
data?: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessagePartsGrouped.d.ts","names":[],"sources":["../../../src/primitives/message/MessagePartsGrouped.tsx"],"mappings":";;;KA8BK;EACH;EACA;;KAGU,oBAAoB,0BAA0B;kBAmDzC;OACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA4CV,kBAAkB;;;;;;;IAQlB;;MAGM,QAAQ;;MAER,OAAO;;MAEP,YAAY;;MAEZ,SAAS;;MAET,QAAQ;;MAER,OAAO
|
|
1
|
+
{"version":3,"file":"MessagePartsGrouped.d.ts","names":[],"sources":["../../../src/primitives/message/MessagePartsGrouped.tsx"],"mappings":";;;KA8BK;EACH;EACA;;KAGU,oBAAoB,0BAA0B;kBAmDzC;OACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA4CV,kBAAkB;;;;;;;IAQlB;;MAGM,QAAQ;;MAER,OAAO;;MAEP,YAAY;;MAEZ,SAAS;;MAET,QAAQ;;MAER,OAAO;;;;;;;MAOP,iBAAiB;;MAEjB;;QAGM,UACI,eAAe;;QAGnB,WAAW;;;MAIjB;;QAGM,UACI,eAAe;;QAGnB,WAAW,cAAc;;;QAIzB,UAAU,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAqC9B,QAAQ,cACN;QACE;QACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;cAqOD,uCAAuC,GAClD,sCAAsC;;;;;;;cA2C3B,iDAAiD,GAC5D,KAAK,sCAAsC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessagePartsGrouped.js","names":["c","_c","ComponentType","FC","memo","PropsWithChildren","useMemo","useAuiState","useAui","PartByIndexProvider","TextMessagePartProvider","MessagePartPrimitiveText","MessagePartPrimitiveImage","Unstable_AudioMessagePartComponent","DataMessagePartComponent","DataMessagePartProps","EmptyMessagePartComponent","TextMessagePartComponent","ImageMessagePartComponent","SourceMessagePartComponent","ToolCallMessagePartComponent","ToolCallMessagePartProps","FileMessagePartComponent","ReasoningMessagePartComponent","MessagePartPrimitiveInProgress","MessagePartStatus","MessagePartGroup","groupKey","indices","GroupingFunction","parts","groupMessagePartsByParentId","groupMap","Map","i","length","part","parentId","groupId","get","push","set","groups","startsWith","undefined","useMessagePartsGrouped","groupingFunction","$","_temp","t0","bb0","t1","Symbol","for","MessagePrimitiveUnstable_PartsGrouped","Props","components","Empty","Text","Reasoning","Source","Image","File","Unstable_Audio","data","by_name","Record","Fallback","tools","Override","Group","ToolUIDisplay","props","toolName","s","toolUIs","render","Render","t2","DataUIDisplay","name","dataRenderers","renderers","Array","isArray","Render_0","defaultComponents","whiteSpace","fontFamily","children","MessagePartComponentProps","MessagePartComponent","t3","t4","t5","t6","t7","t8","t9","Audio","t10","aui","_temp2","type","addResult","addToolResult","resume","resumeToolCall","respondToApproval","respondToToolApproval","t11","Tool","status","Error","Data","console","warn","MessagePartProps","partIndex","MessagePartImpl","MessagePart","prev","next","EmptyPartFallback","component","Component","COMPLETE_STATUS","Object","freeze","EmptyPartsImpl","_temp3","EmptyParts","contentLength","_temp4","messageGroups","group","groupIndex","GroupComponent","map","partsElements","displayName","MessagePrimitiveUnstable_PartsGroupedByParentId","Omit","message"],"sources":["../../../src/primitives/message/MessagePartsGrouped.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type ComponentType,\n type FC,\n memo,\n type PropsWithChildren,\n useMemo,\n} from \"react\";\nimport { useAuiState, useAui } from \"@assistant-ui/store\";\nimport { PartByIndexProvider } from \"../../context/providers/PartByIndexProvider\";\nimport { TextMessagePartProvider } from \"../../context/providers/TextMessagePartProvider\";\nimport { MessagePartPrimitiveText } from \"../messagePart/MessagePartText\";\nimport { MessagePartPrimitiveImage } from \"../messagePart/MessagePartImage\";\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} from \"@assistant-ui/core/react\";\nimport { MessagePartPrimitiveInProgress } from \"../messagePart/MessagePartInProgress\";\nimport type { MessagePartStatus } from \"@assistant-ui/core\";\n\ntype MessagePartGroup = {\n groupKey: string | undefined;\n indices: number[];\n};\n\nexport type GroupingFunction = (parts: readonly any[]) => MessagePartGroup[];\n\n/**\n * Groups message parts by their parent ID.\n * Parts without a parent ID appear in their chronological position as individual groups.\n * Parts with the same parent ID are grouped together at the position of their first occurrence.\n */\nconst groupMessagePartsByParentId: GroupingFunction = (\n parts: readonly any[],\n): MessagePartGroup[] => {\n // Map maintains insertion order, so groups appear in order of first occurrence\n const groupMap = new Map<string, number[]>();\n\n // Process each part in order\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i];\n const parentId = part?.parentId as string | undefined;\n\n // For parts without parentId, assign a unique group ID to maintain their position\n const groupId = parentId ?? `__ungrouped_${i}`;\n\n // Get or create the indices array for this group\n const indices = groupMap.get(groupId) ?? [];\n indices.push(i);\n groupMap.set(groupId, indices);\n }\n\n // Convert map to array of groups\n const groups: MessagePartGroup[] = [];\n for (const [groupId, indices] of groupMap) {\n // Extract parentId (undefined for ungrouped parts)\n const groupKey = groupId.startsWith(\"__ungrouped_\") ? undefined : groupId;\n groups.push({ groupKey, indices });\n }\n\n return groups;\n};\n\nconst useMessagePartsGrouped = (\n groupingFunction: GroupingFunction,\n): MessagePartGroup[] => {\n const parts = useAuiState((s) => s.message.parts);\n\n return useMemo(() => {\n if (parts.length === 0) {\n return [];\n }\n return groupingFunction(parts);\n }, [parts, groupingFunction]);\n};\n\nexport namespace MessagePrimitiveUnstable_PartsGrouped {\n export type Props = {\n /**\n * Function that takes an array of message parts and returns an array of groups.\n * Each group contains a key (for identification) and an array of indices.\n *\n * @example\n * ```tsx\n * // Group by parent ID (default behavior)\n * groupingFunction={(parts) => {\n * const groups = new Map<string, number[]>();\n * parts.forEach((part, i) => {\n * const key = part.parentId ?? `__ungrouped_${i}`;\n * const indices = groups.get(key) ?? [];\n * indices.push(i);\n * groups.set(key, indices);\n * });\n * return Array.from(groups.entries()).map(([key, indices]) => ({\n * key: key.startsWith(\"__ungrouped_\") ? undefined : key,\n * indices\n * }));\n * }}\n * ```\n *\n * @example\n * ```tsx\n * // Group by tool name\n * import { groupMessagePartsByToolName } from \"@assistant-ui/react\";\n *\n * <MessagePrimitive.Unstable_PartsGrouped\n * groupingFunction={groupMessagePartsByToolName}\n * components={{\n * Group: ({ key, indices, children }) => {\n * if (!key) return <>{children}</>;\n * return (\n * <div className=\"tool-group\">\n * <h4>Tool: {key}</h4>\n * {children}\n * </div>\n * );\n * }\n * }}\n * />\n * ```\n */\n groupingFunction: GroupingFunction;\n\n /**\n * Component configuration for rendering different types of message content.\n *\n * You can provide custom components for each content type (text, image, file, etc.)\n * and configure tool rendering behavior. If not provided, default components will be used.\n */\n components:\n | {\n /** Component for rendering empty messages */\n Empty?: EmptyMessagePartComponent | undefined;\n /** Component for rendering text content */\n Text?: TextMessagePartComponent | undefined;\n /** Component for rendering reasoning content (typically hidden) */\n Reasoning?: ReasoningMessagePartComponent | undefined;\n /** Component for rendering source content */\n Source?: SourceMessagePartComponent | undefined;\n /** Component for rendering image content */\n Image?: ImageMessagePartComponent | undefined;\n /** Component for rendering file content */\n File?: FileMessagePartComponent | undefined;\n /** Component for rendering audio content (experimental) */\n Unstable_Audio?: Unstable_AudioMessagePartComponent | undefined;\n /** Configuration for data part rendering */\n data?:\n | {\n /** Map data event names to specific components */\n by_name?:\n | Record<string, DataMessagePartComponent | undefined>\n | undefined;\n /** Fallback component for unmatched data events */\n Fallback?: DataMessagePartComponent | undefined;\n }\n | undefined;\n /** Configuration for tool call rendering */\n tools?:\n | {\n /** Map of tool names to their specific components */\n by_name?:\n | Record<string, ToolCallMessagePartComponent | undefined>\n | undefined;\n /** Fallback component for unregistered tools */\n Fallback?: ComponentType<ToolCallMessagePartProps> | undefined;\n }\n | {\n /** Override component that handles all tool calls */\n Override: ComponentType<ToolCallMessagePartProps>;\n }\n | undefined;\n\n /**\n * Component for rendering grouped message parts.\n *\n * When provided, this component will automatically wrap message parts that share\n * the same group key as determined by the groupingFunction.\n *\n * The component receives:\n * - `groupKey`: The group key (or undefined for ungrouped parts)\n * - `indices`: Array of indices for the parts in this group\n * - `children`: The rendered message part components\n *\n * @example\n * ```tsx\n * // Collapsible group\n * Group: ({ groupKey, indices, children }) => {\n * if (!groupKey) return <>{children}</>;\n * return (\n * <details className=\"message-group\">\n * <summary>\n * Group {groupKey} ({indices.length} parts)\n * </summary>\n * <div className=\"group-content\">\n * {children}\n * </div>\n * </details>\n * );\n * }\n * ```\n *\n * @param groupKey - The group key (undefined for ungrouped parts)\n * @param indices - Array of indices for the parts in this group\n * @param children - Rendered message part components to display within the group\n */\n Group?: ComponentType<\n PropsWithChildren<{\n groupKey: string | undefined;\n indices: number[];\n }>\n >;\n }\n | undefined;\n };\n}\n\nconst ToolUIDisplay = ({\n Fallback,\n ...props\n}: {\n Fallback: ToolCallMessagePartComponent | undefined;\n} & ToolCallMessagePartProps) => {\n const Render = useAuiState(\n (s) => s.tools.toolUIs[props.toolName]?.[0]?.render ?? Fallback,\n );\n if (!Render) return null;\n return <Render {...props} />;\n};\n\nconst DataUIDisplay = ({\n Fallback,\n ...props\n}: {\n Fallback: DataMessagePartComponent | undefined;\n} & DataMessagePartProps) => {\n const Render = useAuiState((s) => {\n const Render = s.dataRenderers.renderers[props.name] ?? Fallback;\n if (Array.isArray(Render)) return Render[0] ?? Fallback;\n return Render;\n });\n if (!Render) return null;\n return <Render {...props} />;\n};\n\nconst defaultComponents = {\n Text: () => (\n <p style={{ whiteSpace: \"pre-line\" }}>\n <MessagePartPrimitiveText />\n <MessagePartPrimitiveInProgress>\n <span style={{ fontFamily: \"revert\" }}>{\" \\u25CF\"}</span>\n </MessagePartPrimitiveInProgress>\n </p>\n ),\n Reasoning: () => null,\n Source: () => null,\n Image: () => <MessagePartPrimitiveImage />,\n File: () => null,\n Unstable_Audio: () => null,\n Group: ({ children }) => children,\n} satisfies MessagePrimitiveUnstable_PartsGrouped.Props[\"components\"];\n\ntype MessagePartComponentProps = {\n components: MessagePrimitiveUnstable_PartsGrouped.Props[\"components\"];\n};\n\nconst MessagePartComponent: FC<MessagePartComponentProps> = ({\n components: {\n Text = defaultComponents.Text,\n Reasoning = defaultComponents.Reasoning,\n Image = defaultComponents.Image,\n Source = defaultComponents.Source,\n File = defaultComponents.File,\n Unstable_Audio: Audio = defaultComponents.Unstable_Audio,\n tools = {},\n data,\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 default:\n console.warn(`Unknown message part type: ${type}`);\n return null;\n }\n};\n\ntype MessagePartProps = {\n partIndex: number;\n components: MessagePrimitiveUnstable_PartsGrouped.Props[\"components\"];\n};\n\nconst MessagePartImpl: FC<MessagePartProps> = ({ partIndex, components }) => {\n return (\n <PartByIndexProvider index={partIndex}>\n <MessagePartComponent components={components} />\n </PartByIndexProvider>\n );\n};\n\nconst MessagePart = memo(\n MessagePartImpl,\n (prev, next) =>\n prev.partIndex === next.partIndex &&\n prev.components?.Text === next.components?.Text &&\n prev.components?.Reasoning === next.components?.Reasoning &&\n prev.components?.Source === next.components?.Source &&\n prev.components?.Image === next.components?.Image &&\n prev.components?.File === next.components?.File &&\n prev.components?.Unstable_Audio === next.components?.Unstable_Audio &&\n prev.components?.tools === next.components?.tools &&\n prev.components?.data === next.components?.data &&\n prev.components?.Group === next.components?.Group,\n);\n\nconst EmptyPartFallback: FC<{\n status: MessagePartStatus;\n component: TextMessagePartComponent;\n}> = ({ status, component: Component }) => {\n return (\n <TextMessagePartProvider text=\"\" isRunning={status.type === \"running\"}>\n <Component type=\"text\" text=\"\" status={status} />\n </TextMessagePartProvider>\n );\n};\n\nconst COMPLETE_STATUS: MessagePartStatus = Object.freeze({\n type: \"complete\",\n});\n\nconst EmptyPartsImpl: FC<MessagePartComponentProps> = ({ components }) => {\n const status = useAuiState(\n (s) => (s.message.status ?? COMPLETE_STATUS) as MessagePartStatus,\n );\n\n if (components?.Empty) return <components.Empty status={status} />;\n\n return (\n <EmptyPartFallback\n status={status}\n component={components?.Text ?? defaultComponents.Text}\n />\n );\n};\n\nconst EmptyParts = memo(\n EmptyPartsImpl,\n (prev, next) =>\n prev.components?.Empty === next.components?.Empty &&\n prev.components?.Text === next.components?.Text,\n);\n\n/**\n * Renders the parts of a message grouped by a custom grouping function.\n *\n * This component allows you to group message parts based on any criteria you define.\n * The grouping function receives all message parts and returns an array of groups,\n * where each group has a key and an array of part indices.\n *\n * @deprecated Prefer `<MessagePrimitive.GroupedParts>` for adjacent\n * grouping — it dispatches all rendering through one `switch (part.type)`\n * and supports nested group paths. Keep this primitive only for\n * non-adjacent clustering (e.g., gathering parts with the same parent-id\n * across the message).\n *\n * @example\n * ```tsx\n * // Group by parent ID (default behavior)\n * <MessagePrimitive.Unstable_PartsGrouped\n * components={{\n * Text: ({ text }) => <p className=\"message-text\">{text}</p>,\n * Image: ({ image }) => <img src={image} alt=\"Message image\" />,\n * Group: ({ groupKey, indices, children }) => {\n * if (!groupKey) return <>{children}</>;\n * return (\n * <div className=\"parent-group border rounded p-4\">\n * <h4>Parent ID: {groupKey}</h4>\n * {children}\n * </div>\n * );\n * }\n * }}\n * />\n * ```\n */\nexport const MessagePrimitiveUnstable_PartsGrouped: FC<\n MessagePrimitiveUnstable_PartsGrouped.Props\n> = ({ groupingFunction, components }) => {\n const contentLength = useAuiState((s) => s.message.parts.length);\n const messageGroups = useMessagePartsGrouped(groupingFunction);\n\n const partsElements = useMemo(() => {\n if (contentLength === 0) {\n return <EmptyParts components={components} />;\n }\n\n return messageGroups.map((group, groupIndex) => {\n const GroupComponent = components?.Group ?? defaultComponents.Group;\n\n return (\n <GroupComponent\n key={`group-${groupIndex}-${group.groupKey ?? \"ungrouped\"}`}\n groupKey={group.groupKey}\n indices={group.indices}\n >\n {group.indices.map((partIndex) => (\n <MessagePart\n key={partIndex}\n partIndex={partIndex}\n components={components}\n />\n ))}\n </GroupComponent>\n );\n });\n }, [messageGroups, components, contentLength]);\n\n return <>{partsElements}</>;\n};\n\nMessagePrimitiveUnstable_PartsGrouped.displayName =\n \"MessagePrimitive.Unstable_PartsGrouped\";\n\n/**\n * Renders the parts of a message grouped by their parent ID.\n * This is a convenience wrapper around Unstable_PartsGrouped with parent ID grouping.\n *\n * @deprecated Use MessagePrimitive.Unstable_PartsGrouped instead for more flexibility\n */\nexport const MessagePrimitiveUnstable_PartsGroupedByParentId: FC<\n Omit<MessagePrimitiveUnstable_PartsGrouped.Props, \"groupingFunction\">\n> = ({ components, ...props }) => {\n return (\n <MessagePrimitiveUnstable_PartsGrouped\n {...props}\n components={components}\n groupingFunction={groupMessagePartsByParentId}\n />\n );\n};\n\nMessagePrimitiveUnstable_PartsGroupedByParentId.displayName =\n \"MessagePrimitive.Unstable_PartsGroupedByParentId\";\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MessagePartsGrouped.js","names":["c","_c","ComponentType","FC","memo","PropsWithChildren","useMemo","useAuiState","useAui","PartByIndexProvider","TextMessagePartProvider","MessagePartPrimitiveText","MessagePartPrimitiveImage","Unstable_AudioMessagePartComponent","DataMessagePartComponent","DataMessagePartProps","EmptyMessagePartComponent","TextMessagePartComponent","ImageMessagePartComponent","SourceMessagePartComponent","ToolCallMessagePartComponent","ToolCallMessagePartProps","FileMessagePartComponent","ReasoningMessagePartComponent","MessagePartPrimitiveInProgress","MessagePartStatus","MessagePartGroup","groupKey","indices","GroupingFunction","parts","groupMessagePartsByParentId","groupMap","Map","i","length","part","parentId","groupId","get","push","set","groups","startsWith","undefined","useMessagePartsGrouped","groupingFunction","$","_temp","t0","bb0","t1","Symbol","for","MessagePrimitiveUnstable_PartsGrouped","Props","components","Empty","Text","Reasoning","Source","Image","File","Unstable_Audio","data","by_name","Record","Fallback","tools","Override","Group","ToolUIDisplay","props","toolName","s","toolUIs","render","Render","t2","DataUIDisplay","name","dataRenderers","renderers","Array","isArray","Render_0","defaultComponents","whiteSpace","fontFamily","children","MessagePartComponentProps","MessagePartComponent","t3","t4","t5","t6","t7","t8","t9","Audio","t10","aui","_temp2","type","addResult","addToolResult","resume","resumeToolCall","respondToApproval","respondToToolApproval","t11","Tool","status","Error","Data","console","warn","MessagePartProps","partIndex","MessagePartImpl","MessagePart","prev","next","EmptyPartFallback","component","Component","COMPLETE_STATUS","Object","freeze","EmptyPartsImpl","_temp3","EmptyParts","contentLength","_temp4","messageGroups","group","groupIndex","GroupComponent","map","partsElements","displayName","MessagePrimitiveUnstable_PartsGroupedByParentId","Omit","message"],"sources":["../../../src/primitives/message/MessagePartsGrouped.tsx"],"sourcesContent":["\"use client\";\n\nimport {\n type ComponentType,\n type FC,\n memo,\n type PropsWithChildren,\n useMemo,\n} from \"react\";\nimport { useAuiState, useAui } from \"@assistant-ui/store\";\nimport { PartByIndexProvider } from \"../../context/providers/PartByIndexProvider\";\nimport { TextMessagePartProvider } from \"../../context/providers/TextMessagePartProvider\";\nimport { MessagePartPrimitiveText } from \"../messagePart/MessagePartText\";\nimport { MessagePartPrimitiveImage } from \"../messagePart/MessagePartImage\";\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} from \"@assistant-ui/core/react\";\nimport { MessagePartPrimitiveInProgress } from \"../messagePart/MessagePartInProgress\";\nimport type { MessagePartStatus } from \"@assistant-ui/core\";\n\ntype MessagePartGroup = {\n groupKey: string | undefined;\n indices: number[];\n};\n\nexport type GroupingFunction = (parts: readonly any[]) => MessagePartGroup[];\n\n/**\n * Groups message parts by their parent ID.\n * Parts without a parent ID appear in their chronological position as individual groups.\n * Parts with the same parent ID are grouped together at the position of their first occurrence.\n */\nconst groupMessagePartsByParentId: GroupingFunction = (\n parts: readonly any[],\n): MessagePartGroup[] => {\n // Map maintains insertion order, so groups appear in order of first occurrence\n const groupMap = new Map<string, number[]>();\n\n // Process each part in order\n for (let i = 0; i < parts.length; i++) {\n const part = parts[i];\n const parentId = part?.parentId as string | undefined;\n\n // For parts without parentId, assign a unique group ID to maintain their position\n const groupId = parentId ?? `__ungrouped_${i}`;\n\n // Get or create the indices array for this group\n const indices = groupMap.get(groupId) ?? [];\n indices.push(i);\n groupMap.set(groupId, indices);\n }\n\n // Convert map to array of groups\n const groups: MessagePartGroup[] = [];\n for (const [groupId, indices] of groupMap) {\n // Extract parentId (undefined for ungrouped parts)\n const groupKey = groupId.startsWith(\"__ungrouped_\") ? undefined : groupId;\n groups.push({ groupKey, indices });\n }\n\n return groups;\n};\n\nconst useMessagePartsGrouped = (\n groupingFunction: GroupingFunction,\n): MessagePartGroup[] => {\n const parts = useAuiState((s) => s.message.parts);\n\n return useMemo(() => {\n if (parts.length === 0) {\n return [];\n }\n return groupingFunction(parts);\n }, [parts, groupingFunction]);\n};\n\nexport namespace MessagePrimitiveUnstable_PartsGrouped {\n export type Props = {\n /**\n * Function that takes an array of message parts and returns an array of groups.\n * Each group contains a key (for identification) and an array of indices.\n *\n * @example\n * ```tsx\n * // Group by parent ID (default behavior)\n * groupingFunction={(parts) => {\n * const groups = new Map<string, number[]>();\n * parts.forEach((part, i) => {\n * const key = part.parentId ?? `__ungrouped_${i}`;\n * const indices = groups.get(key) ?? [];\n * indices.push(i);\n * groups.set(key, indices);\n * });\n * return Array.from(groups.entries()).map(([key, indices]) => ({\n * key: key.startsWith(\"__ungrouped_\") ? undefined : key,\n * indices\n * }));\n * }}\n * ```\n *\n * @example\n * ```tsx\n * // Group by tool name\n * import { groupMessagePartsByToolName } from \"@assistant-ui/react\";\n *\n * <MessagePrimitive.Unstable_PartsGrouped\n * groupingFunction={groupMessagePartsByToolName}\n * components={{\n * Group: ({ key, indices, children }) => {\n * if (!key) return <>{children}</>;\n * return (\n * <div className=\"tool-group\">\n * <h4>Tool: {key}</h4>\n * {children}\n * </div>\n * );\n * }\n * }}\n * />\n * ```\n */\n groupingFunction: GroupingFunction;\n\n /**\n * Component configuration for rendering different types of message content.\n *\n * You can provide custom components for each content type (text, image, file, etc.)\n * and configure tool rendering behavior. If not provided, default components will be used.\n */\n components:\n | {\n /** Component for rendering empty messages */\n Empty?: EmptyMessagePartComponent | undefined;\n /** Component for rendering text content */\n Text?: TextMessagePartComponent | undefined;\n /** Component for rendering reasoning content (typically hidden) */\n Reasoning?: ReasoningMessagePartComponent | undefined;\n /** Component for rendering source content */\n Source?: SourceMessagePartComponent | undefined;\n /** Component for rendering image content */\n Image?: ImageMessagePartComponent | undefined;\n /** Component for rendering file content */\n File?: FileMessagePartComponent | undefined;\n /**\n * Component for rendering audio content.\n *\n * @deprecated Render audio through the `File` slot instead, branching\n * on an `audio/*` mime type.\n */\n Unstable_Audio?: Unstable_AudioMessagePartComponent | undefined;\n /** Configuration for data part rendering */\n data?:\n | {\n /** Map data event names to specific components */\n by_name?:\n | Record<string, DataMessagePartComponent | undefined>\n | undefined;\n /** Fallback component for unmatched data events */\n Fallback?: DataMessagePartComponent | undefined;\n }\n | undefined;\n /** Configuration for tool call rendering */\n tools?:\n | {\n /** Map of tool names to their specific components */\n by_name?:\n | Record<string, ToolCallMessagePartComponent | undefined>\n | undefined;\n /** Fallback component for unregistered tools */\n Fallback?: ComponentType<ToolCallMessagePartProps> | undefined;\n }\n | {\n /** Override component that handles all tool calls */\n Override: ComponentType<ToolCallMessagePartProps>;\n }\n | undefined;\n\n /**\n * Component for rendering grouped message parts.\n *\n * When provided, this component will automatically wrap message parts that share\n * the same group key as determined by the groupingFunction.\n *\n * The component receives:\n * - `groupKey`: The group key (or undefined for ungrouped parts)\n * - `indices`: Array of indices for the parts in this group\n * - `children`: The rendered message part components\n *\n * @example\n * ```tsx\n * // Collapsible group\n * Group: ({ groupKey, indices, children }) => {\n * if (!groupKey) return <>{children}</>;\n * return (\n * <details className=\"message-group\">\n * <summary>\n * Group {groupKey} ({indices.length} parts)\n * </summary>\n * <div className=\"group-content\">\n * {children}\n * </div>\n * </details>\n * );\n * }\n * ```\n *\n * @param groupKey - The group key (undefined for ungrouped parts)\n * @param indices - Array of indices for the parts in this group\n * @param children - Rendered message part components to display within the group\n */\n Group?: ComponentType<\n PropsWithChildren<{\n groupKey: string | undefined;\n indices: number[];\n }>\n >;\n }\n | undefined;\n };\n}\n\nconst ToolUIDisplay = ({\n Fallback,\n ...props\n}: {\n Fallback: ToolCallMessagePartComponent | undefined;\n} & ToolCallMessagePartProps) => {\n const Render = useAuiState(\n (s) => s.tools.toolUIs[props.toolName]?.[0]?.render ?? Fallback,\n );\n if (!Render) return null;\n return <Render {...props} />;\n};\n\nconst DataUIDisplay = ({\n Fallback,\n ...props\n}: {\n Fallback: DataMessagePartComponent | undefined;\n} & DataMessagePartProps) => {\n const Render = useAuiState((s) => {\n const Render = s.dataRenderers.renderers[props.name] ?? Fallback;\n if (Array.isArray(Render)) return Render[0] ?? Fallback;\n return Render;\n });\n if (!Render) return null;\n return <Render {...props} />;\n};\n\nconst defaultComponents = {\n Text: () => (\n <p style={{ whiteSpace: \"pre-line\" }}>\n <MessagePartPrimitiveText />\n <MessagePartPrimitiveInProgress>\n <span style={{ fontFamily: \"revert\" }}>{\" \\u25CF\"}</span>\n </MessagePartPrimitiveInProgress>\n </p>\n ),\n Reasoning: () => null,\n Source: () => null,\n Image: () => <MessagePartPrimitiveImage />,\n File: () => null,\n Unstable_Audio: () => null,\n Group: ({ children }) => children,\n} satisfies MessagePrimitiveUnstable_PartsGrouped.Props[\"components\"];\n\ntype MessagePartComponentProps = {\n components: MessagePrimitiveUnstable_PartsGrouped.Props[\"components\"];\n};\n\nconst MessagePartComponent: FC<MessagePartComponentProps> = ({\n components: {\n Text = defaultComponents.Text,\n Reasoning = defaultComponents.Reasoning,\n Image = defaultComponents.Image,\n Source = defaultComponents.Source,\n File = defaultComponents.File,\n Unstable_Audio: Audio = defaultComponents.Unstable_Audio,\n tools = {},\n data,\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 default:\n console.warn(`Unknown message part type: ${type}`);\n return null;\n }\n};\n\ntype MessagePartProps = {\n partIndex: number;\n components: MessagePrimitiveUnstable_PartsGrouped.Props[\"components\"];\n};\n\nconst MessagePartImpl: FC<MessagePartProps> = ({ partIndex, components }) => {\n return (\n <PartByIndexProvider index={partIndex}>\n <MessagePartComponent components={components} />\n </PartByIndexProvider>\n );\n};\n\nconst MessagePart = memo(\n MessagePartImpl,\n (prev, next) =>\n prev.partIndex === next.partIndex &&\n prev.components?.Text === next.components?.Text &&\n prev.components?.Reasoning === next.components?.Reasoning &&\n prev.components?.Source === next.components?.Source &&\n prev.components?.Image === next.components?.Image &&\n prev.components?.File === next.components?.File &&\n prev.components?.Unstable_Audio === next.components?.Unstable_Audio &&\n prev.components?.tools === next.components?.tools &&\n prev.components?.data === next.components?.data &&\n prev.components?.Group === next.components?.Group,\n);\n\nconst EmptyPartFallback: FC<{\n status: MessagePartStatus;\n component: TextMessagePartComponent;\n}> = ({ status, component: Component }) => {\n return (\n <TextMessagePartProvider text=\"\" isRunning={status.type === \"running\"}>\n <Component type=\"text\" text=\"\" status={status} />\n </TextMessagePartProvider>\n );\n};\n\nconst COMPLETE_STATUS: MessagePartStatus = Object.freeze({\n type: \"complete\",\n});\n\nconst EmptyPartsImpl: FC<MessagePartComponentProps> = ({ components }) => {\n const status = useAuiState(\n (s) => (s.message.status ?? COMPLETE_STATUS) as MessagePartStatus,\n );\n\n if (components?.Empty) return <components.Empty status={status} />;\n\n return (\n <EmptyPartFallback\n status={status}\n component={components?.Text ?? defaultComponents.Text}\n />\n );\n};\n\nconst EmptyParts = memo(\n EmptyPartsImpl,\n (prev, next) =>\n prev.components?.Empty === next.components?.Empty &&\n prev.components?.Text === next.components?.Text,\n);\n\n/**\n * Renders the parts of a message grouped by a custom grouping function.\n *\n * This component allows you to group message parts based on any criteria you define.\n * The grouping function receives all message parts and returns an array of groups,\n * where each group has a key and an array of part indices.\n *\n * @deprecated Prefer `<MessagePrimitive.GroupedParts>` for adjacent\n * grouping — it dispatches all rendering through one `switch (part.type)`\n * and supports nested group paths. Keep this primitive only for\n * non-adjacent clustering (e.g., gathering parts with the same parent-id\n * across the message).\n *\n * @example\n * ```tsx\n * // Group by parent ID (default behavior)\n * <MessagePrimitive.Unstable_PartsGrouped\n * components={{\n * Text: ({ text }) => <p className=\"message-text\">{text}</p>,\n * Image: ({ image }) => <img src={image} alt=\"Message image\" />,\n * Group: ({ groupKey, indices, children }) => {\n * if (!groupKey) return <>{children}</>;\n * return (\n * <div className=\"parent-group border rounded p-4\">\n * <h4>Parent ID: {groupKey}</h4>\n * {children}\n * </div>\n * );\n * }\n * }}\n * />\n * ```\n */\nexport const MessagePrimitiveUnstable_PartsGrouped: FC<\n MessagePrimitiveUnstable_PartsGrouped.Props\n> = ({ groupingFunction, components }) => {\n const contentLength = useAuiState((s) => s.message.parts.length);\n const messageGroups = useMessagePartsGrouped(groupingFunction);\n\n const partsElements = useMemo(() => {\n if (contentLength === 0) {\n return <EmptyParts components={components} />;\n }\n\n return messageGroups.map((group, groupIndex) => {\n const GroupComponent = components?.Group ?? defaultComponents.Group;\n\n return (\n <GroupComponent\n key={`group-${groupIndex}-${group.groupKey ?? \"ungrouped\"}`}\n groupKey={group.groupKey}\n indices={group.indices}\n >\n {group.indices.map((partIndex) => (\n <MessagePart\n key={partIndex}\n partIndex={partIndex}\n components={components}\n />\n ))}\n </GroupComponent>\n );\n });\n }, [messageGroups, components, contentLength]);\n\n return <>{partsElements}</>;\n};\n\nMessagePrimitiveUnstable_PartsGrouped.displayName =\n \"MessagePrimitive.Unstable_PartsGrouped\";\n\n/**\n * Renders the parts of a message grouped by their parent ID.\n * This is a convenience wrapper around Unstable_PartsGrouped with parent ID grouping.\n *\n * @deprecated Use MessagePrimitive.Unstable_PartsGrouped instead for more flexibility\n */\nexport const MessagePrimitiveUnstable_PartsGroupedByParentId: FC<\n Omit<MessagePrimitiveUnstable_PartsGrouped.Props, \"groupingFunction\">\n> = ({ components, ...props }) => {\n return (\n <MessagePrimitiveUnstable_PartsGrouped\n {...props}\n components={components}\n groupingFunction={groupMessagePartsByParentId}\n />\n );\n};\n\nMessagePrimitiveUnstable_PartsGroupedByParentId.displayName =\n \"MessagePrimitive.Unstable_PartsGroupedByParentId\";\n"],"mappings":"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"}
|
|
@@ -7,7 +7,8 @@ declare const useSuggestionTrigger: ({ send, clearComposer }: {
|
|
|
7
7
|
*/
|
|
8
8
|
send?: boolean | undefined;
|
|
9
9
|
/**
|
|
10
|
-
* Whether to clear the composer after sending.
|
|
10
|
+
* Whether to clear the composer after sending. A send queued while a run is
|
|
11
|
+
* in progress never clears the composer.
|
|
11
12
|
* When send is set to false, determines if composer text is replaced with suggestion (true, default),
|
|
12
13
|
* or if it's appended to the composer text (false).
|
|
13
14
|
*
|
|
@@ -40,7 +41,8 @@ declare const SuggestionPrimitiveTrigger: import("react").ForwardRefExoticCompon
|
|
|
40
41
|
*/
|
|
41
42
|
send?: boolean | undefined;
|
|
42
43
|
/**
|
|
43
|
-
* Whether to clear the composer after sending.
|
|
44
|
+
* Whether to clear the composer after sending. A send queued while a run is
|
|
45
|
+
* in progress never clears the composer.
|
|
44
46
|
* When send is set to false, determines if composer text is replaced with suggestion (true, default),
|
|
45
47
|
* or if it's appended to the composer text (false).
|
|
46
48
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SuggestionTrigger.d.ts","names":[],"sources":["../../../src/primitives/suggestion/SuggestionTrigger.ts"],"mappings":";;cAUM,yBAAwB,MAAA;;;;;EAQ5B
|
|
1
|
+
{"version":3,"file":"SuggestionTrigger.d.ts","names":[],"sources":["../../../src/primitives/suggestion/SuggestionTrigger.ts"],"mappings":";;cAUM,yBAAwB,MAAA;;;;;EAQ5B;;;;;;;;;EAUA;;kBAae;OACH,UAAU;OACV,QAAQ,yBAAyB;;;;;;;;;;;;cAalC,4CAA0B,0BAAA,KAAA,qBAAA,gBAAA,qCAAA,qBAAA;;;;;;;;;EAtC9B;;;;;;;;;EAUS;oBAgCjB,cAAA"}
|
|
@@ -1,46 +1,28 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { createActionButton } from "../../utils/createActionButton.js";
|
|
3
|
-
import {
|
|
3
|
+
import { useAuiState } from "@assistant-ui/store";
|
|
4
4
|
import { c } from "@assistant-ui/tap/react-shim/compiler-runtime";
|
|
5
|
-
import "@assistant-ui/
|
|
5
|
+
import { useSuggestionTrigger } from "@assistant-ui/core/react";
|
|
6
6
|
//#region src/primitives/suggestion/SuggestionTrigger.ts
|
|
7
|
-
const useSuggestionTrigger = (t0) => {
|
|
8
|
-
const $ = c(
|
|
9
|
-
const { send, clearComposer
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
t2 = () => {
|
|
18
|
-
const isRunning = aui.thread.getState().isRunning;
|
|
19
|
-
if (resolvedSend && !isRunning) {
|
|
20
|
-
aui.thread.append({
|
|
21
|
-
content: [{
|
|
22
|
-
type: "text",
|
|
23
|
-
text: prompt
|
|
24
|
-
}],
|
|
25
|
-
runConfig: aui.composer.getState().runConfig
|
|
26
|
-
});
|
|
27
|
-
if (clearComposer) aui.composer.setText("");
|
|
28
|
-
} else if (clearComposer) aui.composer.setText(prompt);
|
|
29
|
-
else {
|
|
30
|
-
const currentText = aui.composer.getState().text;
|
|
31
|
-
aui.composer.setText(currentText.trim() ? `${currentText} ${prompt}` : prompt);
|
|
32
|
-
}
|
|
7
|
+
const useSuggestionTrigger$1 = (t0) => {
|
|
8
|
+
const $ = c(4);
|
|
9
|
+
const { send, clearComposer } = t0;
|
|
10
|
+
const prompt = useAuiState(_temp);
|
|
11
|
+
let t1;
|
|
12
|
+
if ($[0] !== clearComposer || $[1] !== prompt || $[2] !== send) {
|
|
13
|
+
t1 = {
|
|
14
|
+
prompt,
|
|
15
|
+
send,
|
|
16
|
+
clearComposer
|
|
33
17
|
};
|
|
34
|
-
$[0] =
|
|
35
|
-
$[1] =
|
|
36
|
-
$[2] =
|
|
37
|
-
$[3] =
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
} else t2 = $[5];
|
|
41
|
-
const callback = t2;
|
|
18
|
+
$[0] = clearComposer;
|
|
19
|
+
$[1] = prompt;
|
|
20
|
+
$[2] = send;
|
|
21
|
+
$[3] = t1;
|
|
22
|
+
} else t1 = $[3];
|
|
23
|
+
const { trigger, disabled } = useSuggestionTrigger(t1);
|
|
42
24
|
if (disabled) return null;
|
|
43
|
-
return
|
|
25
|
+
return trigger;
|
|
44
26
|
};
|
|
45
27
|
/**
|
|
46
28
|
* A button that triggers the suggestion action (send or insert into composer).
|
|
@@ -52,12 +34,9 @@ const useSuggestionTrigger = (t0) => {
|
|
|
52
34
|
* </SuggestionPrimitive.Trigger>
|
|
53
35
|
* ```
|
|
54
36
|
*/
|
|
55
|
-
const SuggestionPrimitiveTrigger = createActionButton("SuggestionPrimitive.Trigger", useSuggestionTrigger, ["send", "clearComposer"]);
|
|
37
|
+
const SuggestionPrimitiveTrigger = createActionButton("SuggestionPrimitive.Trigger", useSuggestionTrigger$1, ["send", "clearComposer"]);
|
|
56
38
|
function _temp(s) {
|
|
57
|
-
return s.
|
|
58
|
-
}
|
|
59
|
-
function _temp2(s_0) {
|
|
60
|
-
return s_0.suggestion.prompt;
|
|
39
|
+
return s.suggestion.prompt;
|
|
61
40
|
}
|
|
62
41
|
//#endregion
|
|
63
42
|
export { SuggestionPrimitiveTrigger };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SuggestionTrigger.js","names":["c","_c","ActionButtonElement","ActionButtonProps","createActionButton","
|
|
1
|
+
{"version":3,"file":"SuggestionTrigger.js","names":["c","_c","ActionButtonElement","ActionButtonProps","createActionButton","useAuiState","useSuggestionTrigger","useSuggestionTriggerBehavior","t0","$","send","clearComposer","prompt","_temp","t1","trigger","disabled","SuggestionPrimitiveTrigger","Element","Props","s","suggestion"],"sources":["../../../src/primitives/suggestion/SuggestionTrigger.ts"],"sourcesContent":["\"use client\";\n\nimport {\n type ActionButtonElement,\n type ActionButtonProps,\n createActionButton,\n} from \"../../utils/createActionButton\";\nimport { useAuiState } from \"@assistant-ui/store\";\nimport { useSuggestionTrigger as useSuggestionTriggerBehavior } from \"@assistant-ui/core/react\";\n\nconst useSuggestionTrigger = ({\n send,\n clearComposer,\n}: {\n /**\n * When true, automatically sends the message.\n * When false, replaces or appends the composer text with the suggestion - depending on the value of `clearComposer`.\n */\n send?: boolean | undefined;\n\n /**\n * Whether to clear the composer after sending. A send queued while a run is\n * in progress never clears the composer.\n * When send is set to false, determines if composer text is replaced with suggestion (true, default),\n * or if it's appended to the composer text (false).\n *\n * @default true\n */\n clearComposer?: boolean | undefined;\n}) => {\n const prompt = useAuiState((s) => s.suggestion.prompt);\n const { trigger, disabled } = useSuggestionTriggerBehavior({\n prompt,\n send,\n clearComposer,\n });\n\n if (disabled) return null;\n return trigger;\n};\n\nexport namespace SuggestionPrimitiveTrigger {\n export type Element = ActionButtonElement;\n export type Props = ActionButtonProps<typeof useSuggestionTrigger>;\n}\n\n/**\n * A button that triggers the suggestion action (send or insert into composer).\n *\n * @example\n * ```tsx\n * <SuggestionPrimitive.Trigger send>\n * Click me\n * </SuggestionPrimitive.Trigger>\n * ```\n */\nexport const SuggestionPrimitiveTrigger = createActionButton(\n \"SuggestionPrimitive.Trigger\",\n useSuggestionTrigger,\n [\"send\", \"clearComposer\"],\n);\n"],"mappings":";;;;;;AAUA,MAAMM,0BAAuBE,OAAA;CAAA,MAAAC,IAAAR,EAAA,CAAA;CAAC,MAAA,EAAAS,MAAAC,kBAAAH;CAoB5B,MAAAI,SAAeP,YAAYQ,KAA0B;CAAE,IAAAC;CAAA,IAAAL,EAAA,OAAAE,iBAAAF,EAAA,OAAAG,UAAAH,EAAA,OAAAC,MAAA;EACII,KAAA;GAAAF;GAAAF;GAAAC;EAI3D;EAACF,EAAA,KAAAE;EAAAF,EAAA,KAAAG;EAAAH,EAAA,KAAAC;EAAAD,EAAA,KAAAK;CAAA,OAAAA,KAAAL,EAAA;CAJD,MAAA,EAAAM,SAAAC,aAA8BT,qBAA6BO,EAI1D;CAED,IAAIE,UAAQ,OAAS;CAAK,OACnBD;AAAO;;;;;;;;;;;AAkBhB,MAAaE,6BAA6Bb,mBACxC,+BACAE,wBACA,CAAC,QAAQ,eAAe,CAC1B;AAlD6B,SAAAO,MAAAO,GAAA;CAAA,OAoBOA,EAACC,WAAWT;AAAO"}
|
|
@@ -9,7 +9,8 @@ declare const useThreadSuggestion: ({ prompt, send, clearComposer, autoSend, met
|
|
|
9
9
|
*/
|
|
10
10
|
send?: boolean | undefined;
|
|
11
11
|
/**
|
|
12
|
-
* Whether to clear the composer after sending.
|
|
12
|
+
* Whether to clear the composer after sending. A send queued while a run is
|
|
13
|
+
* in progress never clears the composer.
|
|
13
14
|
* When send is set to false, determines if composer text is replaced with suggestion (true, default),
|
|
14
15
|
* or if it's appended to the composer text (false).
|
|
15
16
|
*
|
|
@@ -38,7 +39,8 @@ declare const ThreadPrimitiveSuggestion: import("react").ForwardRefExoticCompone
|
|
|
38
39
|
*/
|
|
39
40
|
send?: boolean | undefined;
|
|
40
41
|
/**
|
|
41
|
-
* Whether to clear the composer after sending.
|
|
42
|
+
* Whether to clear the composer after sending. A send queued while a run is
|
|
43
|
+
* in progress never clears the composer.
|
|
42
44
|
* When send is set to false, determines if composer text is replaced with suggestion (true, default),
|
|
43
45
|
* or if it's appended to the composer text (false).
|
|
44
46
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThreadSuggestion.d.ts","names":[],"sources":["../../../src/primitives/thread/ThreadSuggestion.ts"],"mappings":";;cASM,wBAAuB,QAAA,MAAA,eAAA,UAAA,QAAA;;EAQ3B;;;;;EAMA
|
|
1
|
+
{"version":3,"file":"ThreadSuggestion.d.ts","names":[],"sources":["../../../src/primitives/thread/ThreadSuggestion.ts"],"mappings":";;cASM,wBAAuB,QAAA,MAAA,eAAA,UAAA,QAAA;;EAQ3B;;;;;EAMA;;;;;;;;;EAUA;;EAGA;;EAGA;;kBAae;OACH,UAAU;OACV,QAAQ,yBAAyB;;cAGlC,2CAAyB,0BAAA,KAAA,qBAAA,gBAAA,qCAAA,qBAAA;;;;;;EAxC5B;;;;;EAMD;;;;;;;;;EAUS;;EAGL;;EAGF;oBAsBV,cAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThreadSuggestion.js","names":["c","_c","ActionButtonElement","ActionButtonProps","createActionButton","useSuggestionTrigger","useSuggestionTriggerBehavior","useThreadSuggestion","t0","$","prompt","send","clearComposer","autoSend","resolvedSend","t1","disabled","trigger","ThreadPrimitiveSuggestion","Element","Props"],"sources":["../../../src/primitives/thread/ThreadSuggestion.ts"],"sourcesContent":["\"use client\";\n\nimport {\n type ActionButtonElement,\n type ActionButtonProps,\n createActionButton,\n} from \"../../utils/createActionButton\";\nimport { useSuggestionTrigger as useSuggestionTriggerBehavior } from \"@assistant-ui/core/react\";\n\nconst useThreadSuggestion = ({\n prompt,\n send,\n clearComposer,\n autoSend,\n method: _method,\n}: {\n /** The suggestion prompt. */\n prompt: string;\n\n /**\n * When true, automatically sends the message.\n * When false, replaces or appends the composer text with the suggestion - depending on the value of `clearComposer`.\n */\n send?: boolean | undefined;\n\n /**\n * Whether to clear the composer after sending.\n * When send is set to false, determines if composer text is replaced with suggestion (true, default),\n * or if it's appended to the composer text (false).\n *\n * @default true\n */\n clearComposer?: boolean | undefined;\n\n /** @deprecated Use `send` instead. */\n autoSend?: boolean | undefined;\n\n /** @deprecated Use `clearComposer` instead. */\n method?: \"replace\";\n}) => {\n const resolvedSend = send ?? autoSend ?? false;\n\n const { disabled, trigger } = useSuggestionTriggerBehavior({\n prompt,\n send: resolvedSend,\n clearComposer,\n });\n if (disabled) return null;\n return trigger;\n};\n\nexport namespace ThreadPrimitiveSuggestion {\n export type Element = ActionButtonElement;\n export type Props = ActionButtonProps<typeof useThreadSuggestion>;\n}\n\nexport const ThreadPrimitiveSuggestion = createActionButton(\n \"ThreadPrimitive.Suggestion\",\n useThreadSuggestion,\n [\"prompt\", \"send\", \"clearComposer\", \"autoSend\", \"method\"],\n);\n"],"mappings":";;;;;AASA,MAAMO,uBAAsBC,OAAA;CAAA,MAAAC,IAAAR,EAAA,CAAA;CAAC,MAAA,EAAAS,QAAAC,MAAAC,eAAAC,aAAAL;
|
|
1
|
+
{"version":3,"file":"ThreadSuggestion.js","names":["c","_c","ActionButtonElement","ActionButtonProps","createActionButton","useSuggestionTrigger","useSuggestionTriggerBehavior","useThreadSuggestion","t0","$","prompt","send","clearComposer","autoSend","resolvedSend","t1","disabled","trigger","ThreadPrimitiveSuggestion","Element","Props"],"sources":["../../../src/primitives/thread/ThreadSuggestion.ts"],"sourcesContent":["\"use client\";\n\nimport {\n type ActionButtonElement,\n type ActionButtonProps,\n createActionButton,\n} from \"../../utils/createActionButton\";\nimport { useSuggestionTrigger as useSuggestionTriggerBehavior } from \"@assistant-ui/core/react\";\n\nconst useThreadSuggestion = ({\n prompt,\n send,\n clearComposer,\n autoSend,\n method: _method,\n}: {\n /** The suggestion prompt. */\n prompt: string;\n\n /**\n * When true, automatically sends the message.\n * When false, replaces or appends the composer text with the suggestion - depending on the value of `clearComposer`.\n */\n send?: boolean | undefined;\n\n /**\n * Whether to clear the composer after sending. A send queued while a run is\n * in progress never clears the composer.\n * When send is set to false, determines if composer text is replaced with suggestion (true, default),\n * or if it's appended to the composer text (false).\n *\n * @default true\n */\n clearComposer?: boolean | undefined;\n\n /** @deprecated Use `send` instead. */\n autoSend?: boolean | undefined;\n\n /** @deprecated Use `clearComposer` instead. */\n method?: \"replace\";\n}) => {\n const resolvedSend = send ?? autoSend ?? false;\n\n const { disabled, trigger } = useSuggestionTriggerBehavior({\n prompt,\n send: resolvedSend,\n clearComposer,\n });\n if (disabled) return null;\n return trigger;\n};\n\nexport namespace ThreadPrimitiveSuggestion {\n export type Element = ActionButtonElement;\n export type Props = ActionButtonProps<typeof useThreadSuggestion>;\n}\n\nexport const ThreadPrimitiveSuggestion = createActionButton(\n \"ThreadPrimitive.Suggestion\",\n useThreadSuggestion,\n [\"prompt\", \"send\", \"clearComposer\", \"autoSend\", \"method\"],\n);\n"],"mappings":";;;;;AASA,MAAMO,uBAAsBC,OAAA;CAAA,MAAAC,IAAAR,EAAA,CAAA;CAAC,MAAA,EAAAS,QAAAC,MAAAC,eAAAC,aAAAL;CAgC3B,MAAAM,eAAqBH,QAAAE,YAAA;CAA0B,IAAAE;CAAA,IAAAN,EAAA,OAAAG,iBAAAH,EAAA,OAAAC,UAAAD,EAAA,OAAAK,cAAA;EAEYC,KAAA;GAAAL;GAAAC,MAEnDG;GAAYF;EAEpB;EAACH,EAAA,KAAAG;EAAAH,EAAA,KAAAC;EAAAD,EAAA,KAAAK;EAAAL,EAAA,KAAAM;CAAA,OAAAA,KAAAN,EAAA;CAJD,MAAA,EAAAO,UAAAC,YAA8BX,qBAA6BS,EAI1D;CACD,IAAIC,UAAQ,OAAS;CAAK,OACnBC;AAAO;AAQhB,MAAaC,4BAA4Bd,mBACvC,8BACAG,qBACA;CAAC;CAAU;CAAQ;CAAiB;CAAY;AAAQ,CAC1D"}
|