rdesign/frontend/node_modules/@copilotkitnext/react/dist/a2ui/A2UIMessageRenderer.mjs

131 lines
4.2 KiB
JavaScript

import "../providers/index.mjs";
import { useCopilotKit } from "../providers/CopilotKitProvider.mjs";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { jsx, jsxs } from "react/jsx-runtime";
import { z } from "zod";
import { A2UIProvider, A2UIRenderer, DEFAULT_SURFACE_ID, initializeDefaultCatalog, injectStyles, useA2UIActions } from "@copilotkit/a2ui-renderer";
//#region src/a2ui/A2UIMessageRenderer.tsx
let initialized = false;
function ensureInitialized() {
if (!initialized) {
initializeDefaultCatalog();
injectStyles();
initialized = true;
}
}
function createA2UIMessageRenderer(options) {
const { theme } = options;
return {
activityType: "a2ui-surface",
content: z.any(),
render: ({ content, agent }) => {
ensureInitialized();
const [operations, setOperations] = useState([]);
const lastSignatureRef = useRef(null);
const { copilotkit } = useCopilotKit();
useEffect(() => {
if (!content || !Array.isArray(content.operations)) {
lastSignatureRef.current = null;
setOperations([]);
return;
}
const incoming = content.operations;
const signature = stringifyOperations(incoming);
if (signature && signature === lastSignatureRef.current) return;
lastSignatureRef.current = signature;
setOperations(incoming);
}, [content]);
const groupedOperations = useMemo(() => {
const groups = /* @__PURE__ */ new Map();
for (const operation of operations) {
const surfaceId = getOperationSurfaceId(operation) ?? DEFAULT_SURFACE_ID;
if (!groups.has(surfaceId)) groups.set(surfaceId, []);
groups.get(surfaceId).push(operation);
}
return groups;
}, [operations]);
if (!groupedOperations.size) return null;
return /* @__PURE__ */ jsx("div", {
className: "cpk:flex cpk:min-h-0 cpk:flex-1 cpk:flex-col cpk:gap-6 cpk:overflow-auto cpk:py-6",
children: Array.from(groupedOperations.entries()).map(([surfaceId, ops]) => /* @__PURE__ */ jsx(ReactSurfaceHost, {
surfaceId,
operations: ops,
theme,
agent,
copilotkit
}, surfaceId))
});
}
};
}
/**
* Renders a single A2UI surface using the React renderer.
* Wraps A2UIProvider + A2UIRenderer and bridges actions back to CopilotKit.
*/
function ReactSurfaceHost({ surfaceId, operations, theme, agent, copilotkit }) {
return /* @__PURE__ */ jsx("div", {
className: "cpk:flex cpk:w-full cpk:flex-none cpk:flex-col cpk:gap-4",
children: /* @__PURE__ */ jsxs(A2UIProvider, {
onAction: useCallback(async (message) => {
if (!agent) return;
try {
console.info("[A2UI] Action dispatched", message.userAction);
copilotkit.setProperties({
...copilotkit.properties ?? {},
a2uiAction: message
});
await copilotkit.runAgent({ agent });
} finally {
if (copilotkit.properties) {
const { a2uiAction, ...rest } = copilotkit.properties;
copilotkit.setProperties(rest);
}
}
}, [agent, copilotkit]),
theme,
children: [/* @__PURE__ */ jsx(SurfaceMessageProcessor, {
surfaceId,
operations
}), /* @__PURE__ */ jsx(A2UIRenderer, {
surfaceId,
className: "cpk:flex cpk:flex-1"
})]
})
});
}
/**
* Processes A2UI operations into the provider's message processor.
* Must be a child of A2UIProvider to access the actions context.
*/
function SurfaceMessageProcessor({ surfaceId, operations }) {
const { processMessages } = useA2UIActions();
const lastProcessedRef = useRef("");
useEffect(() => {
const key = `${surfaceId}-${JSON.stringify(operations)}`;
if (key === lastProcessedRef.current) return;
lastProcessedRef.current = key;
processMessages(operations);
}, [
processMessages,
surfaceId,
operations
]);
return null;
}
function getOperationSurfaceId(operation) {
if (!operation || typeof operation !== "object") return null;
if (typeof operation.surfaceId === "string") return operation.surfaceId;
return operation?.beginRendering?.surfaceId ?? operation?.surfaceUpdate?.surfaceId ?? operation?.dataModelUpdate?.surfaceId ?? operation?.deleteSurface?.surfaceId ?? null;
}
function stringifyOperations(ops) {
try {
return JSON.stringify(ops);
} catch (error) {
return null;
}
}
//#endregion
export { createA2UIMessageRenderer };
//# sourceMappingURL=A2UIMessageRenderer.mjs.map