@assistant-ui/react
Version:
React components for AI chat.
100 lines (99 loc) • 4.08 kB
JavaScript
"use client";
// src/primitives/message/MessageContent.tsx
import { memo, useMemo } from "react";
import {
useContentPart,
useContentPartRuntime,
useToolUIs
} from "../../context/index.mjs";
import {
useMessage,
useMessageRuntime
} from "../../context/react/MessageContext.mjs";
import { ContentPartRuntimeProvider } from "../../context/providers/ContentPartRuntimeProvider.mjs";
import { ContentPartPrimitiveText } from "../contentPart/ContentPartText.mjs";
import { ContentPartPrimitiveImage } from "../contentPart/ContentPartImage.mjs";
import { ContentPartPrimitiveDisplay } from "../contentPart/ContentPartDisplay.mjs";
import { ContentPartPrimitiveInProgress } from "../contentPart/ContentPartInProgress.mjs";
import { EMPTY_CONTENT } from "../../api/MessageRuntime.mjs";
import { jsx, jsxs } from "react/jsx-runtime";
var ToolUIDisplay = ({
UI,
...props
}) => {
const Render = useToolUIs((s) => s.getToolUI(props.toolName)) ?? UI;
if (!Render) return null;
return /* @__PURE__ */ jsx(Render, { ...props });
};
var defaultComponents = {
Text: () => /* @__PURE__ */ jsxs("p", { style: { whiteSpace: "pre-line" }, children: [
/* @__PURE__ */ jsx(ContentPartPrimitiveText, {}),
/* @__PURE__ */ jsx(ContentPartPrimitiveInProgress, { children: /* @__PURE__ */ jsx("span", { style: { fontFamily: "revert" }, children: " \u25CF" }) })
] }),
Image: () => /* @__PURE__ */ jsx(ContentPartPrimitiveImage, {}),
Unstable_Audio: () => null,
UI: () => /* @__PURE__ */ jsx(ContentPartPrimitiveDisplay, {})
};
var MessageContentPartComponent = ({
components: {
Text = defaultComponents.Text,
Empty,
Image = defaultComponents.Image,
UI = defaultComponents.UI,
Unstable_Audio: Audio = defaultComponents.Unstable_Audio,
tools: { by_name = {}, Fallback = void 0 } = {}
} = {}
}) => {
const contentPartRuntime = useContentPartRuntime();
const part = useContentPart();
const type = part.type;
if (type === "tool-call") {
const Tool = by_name[part.toolName] || Fallback;
const addResult = (result) => contentPartRuntime.addToolResult(result);
return /* @__PURE__ */ jsx(ToolUIDisplay, { ...part, part, UI: Tool, addResult });
}
if (part.status.type === "requires-action")
throw new Error("Encountered unexpected requires-action status");
switch (type) {
case "text":
if (part.part === EMPTY_CONTENT && !!Empty) {
return /* @__PURE__ */ jsx(Empty, { status: part.status });
}
return /* @__PURE__ */ jsx(Text, { ...part, part });
case "image":
return /* @__PURE__ */ jsx(Image, { ...part, part });
case "audio":
return /* @__PURE__ */ jsx(Audio, { ...part, part });
case "ui":
return /* @__PURE__ */ jsx(UI, { ...part, part });
default:
const unhandledType = type;
throw new Error(`Unknown content part type: ${unhandledType}`);
}
};
var MessageContentPartImpl = ({
partIndex,
components
}) => {
const messageRuntime = useMessageRuntime();
const runtime = useMemo(
() => messageRuntime.getContentPartByIndex(partIndex),
[messageRuntime, partIndex]
);
return /* @__PURE__ */ jsx(ContentPartRuntimeProvider, { runtime, children: /* @__PURE__ */ jsx(MessageContentPartComponent, { components }) });
};
var MessageContentPart = memo(
MessageContentPartImpl,
(prev, next) => prev.partIndex === next.partIndex && prev.components?.Text === next.components?.Text && prev.components?.Image === next.components?.Image && prev.components?.Unstable_Audio === next.components?.Unstable_Audio && prev.components?.UI === next.components?.UI && prev.components?.tools === next.components?.tools
);
var MessagePrimitiveContent = ({
components
}) => {
const contentLength = useMessage((s) => s.content.length) || 1;
return Array.from({ length: contentLength }, (_, index) => /* @__PURE__ */ jsx(MessageContentPart, { partIndex: index, components }, index));
};
MessagePrimitiveContent.displayName = "MessagePrimitive.Content";
export {
MessagePrimitiveContent
};
//# sourceMappingURL=MessageContent.mjs.map