@copilotkit/react-core 1.59.3 → 1.59.5-canary.1781104893
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/{copilotkit-CEJz6krE.d.mts → copilotkit-B83H_vWJ.d.mts} +412 -64
- package/dist/copilotkit-B83H_vWJ.d.mts.map +1 -0
- package/dist/{copilotkit-D16eCFkt.d.cts → copilotkit-CD3EqiJ4.d.cts} +412 -64
- package/dist/copilotkit-CD3EqiJ4.d.cts.map +1 -0
- package/dist/{copilotkit-DhONbYmz.cjs → copilotkit-CWGR3Ict.cjs} +1002 -345
- package/dist/copilotkit-CWGR3Ict.cjs.map +1 -0
- package/dist/{copilotkit-BRNy5UvX.mjs → copilotkit-DBOofUYQ.mjs} +950 -335
- package/dist/copilotkit-DBOofUYQ.mjs.map +1 -0
- package/dist/index.cjs +10 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -5
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +5 -5
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +10 -7
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +350 -210
- package/dist/index.umd.js.map +1 -1
- package/dist/v2/index.cjs +8 -1
- package/dist/v2/index.css +1 -1
- package/dist/v2/index.d.cts +2 -2
- package/dist/v2/index.d.mts +2 -2
- package/dist/v2/index.mjs +2 -2
- package/dist/v2/index.umd.js +956 -334
- package/dist/v2/index.umd.js.map +1 -1
- package/package.json +8 -8
- package/dist/copilotkit-BRNy5UvX.mjs.map +0 -1
- package/dist/copilotkit-CEJz6krE.d.mts.map +0 -1
- package/dist/copilotkit-D16eCFkt.d.cts.map +0 -1
- package/dist/copilotkit-DhONbYmz.cjs.map +0 -1
package/dist/index.umd.js
CHANGED
|
@@ -773,7 +773,7 @@ react_markdown = __toESM(react_markdown);
|
|
|
773
773
|
severity: "warning",
|
|
774
774
|
message: `Your CopilotKit license expires in ${graceRemaining} day${graceRemaining !== 1 ? "s" : ""}. Please renew.`,
|
|
775
775
|
actionLabel: "Renew",
|
|
776
|
-
actionUrl: "https://
|
|
776
|
+
actionUrl: "https://dashboard.operations.copilotkit.ai",
|
|
777
777
|
onDismiss
|
|
778
778
|
});
|
|
779
779
|
case "expired": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BannerShell, {
|
|
@@ -1673,210 +1673,110 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
1673
1673
|
};
|
|
1674
1674
|
|
|
1675
1675
|
//#endregion
|
|
1676
|
-
//#region src/v2/a2ui/
|
|
1676
|
+
//#region src/v2/a2ui/A2UIRecoveryStates.tsx
|
|
1677
1677
|
/**
|
|
1678
|
-
* The
|
|
1679
|
-
*
|
|
1678
|
+
* The pre-paint lifecycle fields the middleware stamps onto the `a2ui-surface`
|
|
1679
|
+
* activity content (alongside `a2ui_operations` on paint). `.passthrough()` keeps
|
|
1680
|
+
* `a2ui_operations` and any future fields intact.
|
|
1680
1681
|
*/
|
|
1681
|
-
const
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
lastContentRef.current = content;
|
|
1703
|
-
const incoming = content?.[A2UI_OPERATIONS_KEY];
|
|
1704
|
-
if (!content || !Array.isArray(incoming)) {
|
|
1705
|
-
setOperations([]);
|
|
1706
|
-
return;
|
|
1707
|
-
}
|
|
1708
|
-
setOperations(incoming);
|
|
1709
|
-
}, [content]);
|
|
1710
|
-
const groupedOperations = (0, react.useMemo)(() => {
|
|
1711
|
-
const groups = /* @__PURE__ */ new Map();
|
|
1712
|
-
for (const operation of operations) {
|
|
1713
|
-
const surfaceId = getOperationSurfaceId(operation) ?? _copilotkit_a2ui_renderer.DEFAULT_SURFACE_ID;
|
|
1714
|
-
if (!groups.has(surfaceId)) groups.set(surfaceId, []);
|
|
1715
|
-
groups.get(surfaceId).push(operation);
|
|
1716
|
-
}
|
|
1717
|
-
return groups;
|
|
1718
|
-
}, [operations]);
|
|
1719
|
-
if (!groupedOperations.size) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(loadingComponent ?? DefaultA2UILoading, {});
|
|
1720
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1721
|
-
className: "cpk:flex cpk:min-h-0 cpk:flex-1 cpk:flex-col cpk:gap-6 cpk:overflow-auto cpk:py-6",
|
|
1722
|
-
children: Array.from(groupedOperations.entries()).map(([surfaceId, ops]) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReactSurfaceHost, {
|
|
1723
|
-
surfaceId,
|
|
1724
|
-
operations: ops,
|
|
1725
|
-
theme,
|
|
1726
|
-
agent,
|
|
1727
|
-
copilotkit,
|
|
1728
|
-
catalog
|
|
1729
|
-
}, surfaceId))
|
|
1730
|
-
});
|
|
1731
|
-
}
|
|
1732
|
-
};
|
|
1682
|
+
const A2UILifecycleFields = {
|
|
1683
|
+
status: zod.z.enum([
|
|
1684
|
+
"building",
|
|
1685
|
+
"retrying",
|
|
1686
|
+
"failed"
|
|
1687
|
+
]).optional(),
|
|
1688
|
+
attempt: zod.z.number().optional(),
|
|
1689
|
+
maxAttempts: zod.z.number().optional(),
|
|
1690
|
+
progressTokens: zod.z.number().optional(),
|
|
1691
|
+
error: zod.z.string().optional(),
|
|
1692
|
+
errors: zod.z.array(zod.z.any()).optional(),
|
|
1693
|
+
attempts: zod.z.array(zod.z.any()).optional(),
|
|
1694
|
+
debugExposure: zod.z.enum([
|
|
1695
|
+
"hidden",
|
|
1696
|
+
"collapsed",
|
|
1697
|
+
"verbose"
|
|
1698
|
+
]).optional()
|
|
1699
|
+
};
|
|
1700
|
+
/** Server-stamped debugExposure wins; else the client option; else "collapsed". */
|
|
1701
|
+
function resolveDebugExposure(content, optionDebugExposure) {
|
|
1702
|
+
return content?.debugExposure ?? optionDebugExposure;
|
|
1733
1703
|
}
|
|
1734
|
-
/**
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1740
|
-
className: "cpk:flex cpk:w-full cpk:flex-none cpk:flex-col cpk:gap-4",
|
|
1741
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_copilotkit_a2ui_renderer.A2UIProvider, {
|
|
1742
|
-
onAction: (0, react.useCallback)(async (message) => {
|
|
1743
|
-
if (!agent) return;
|
|
1744
|
-
message.userAction;
|
|
1745
|
-
try {
|
|
1746
|
-
copilotkit.setProperties({
|
|
1747
|
-
...copilotkit.properties,
|
|
1748
|
-
a2uiAction: message
|
|
1749
|
-
});
|
|
1750
|
-
await copilotkit.runAgent({ agent });
|
|
1751
|
-
} finally {
|
|
1752
|
-
if (copilotkit.properties) {
|
|
1753
|
-
const { a2uiAction, ...rest } = copilotkit.properties;
|
|
1754
|
-
copilotkit.setProperties(rest);
|
|
1755
|
-
}
|
|
1756
|
-
}
|
|
1757
|
-
}, [agent, copilotkit]),
|
|
1758
|
-
theme,
|
|
1759
|
-
catalog,
|
|
1760
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SurfaceMessageProcessor, {
|
|
1761
|
-
surfaceId,
|
|
1762
|
-
operations
|
|
1763
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(A2UISurfaceOrError, { surfaceId })]
|
|
1764
|
-
})
|
|
1704
|
+
/** building: the generic skeleton + optional live token count. */
|
|
1705
|
+
function A2UIBuildingState({ content }) {
|
|
1706
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(A2UIGeneratingSkeleton, {
|
|
1707
|
+
label: "Building interface",
|
|
1708
|
+
tokens: typeof content?.progressTokens === "number" ? content.progressTokens : void 0
|
|
1765
1709
|
});
|
|
1766
1710
|
}
|
|
1767
1711
|
/**
|
|
1768
|
-
*
|
|
1769
|
-
*
|
|
1712
|
+
* retrying: stays the generic skeleton through fast/transient retries; only once
|
|
1713
|
+
* the retry is perceptible (after `showAfterMs`, or once `attempt` crosses
|
|
1714
|
+
* `showAfterAttempts`) does the sub-label reveal "Retrying generation… (N/M)".
|
|
1770
1715
|
*/
|
|
1771
|
-
function
|
|
1772
|
-
const
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1716
|
+
function A2UIRetryingState({ content, showAfterMs, showAfterAttempts, debugExposure }) {
|
|
1717
|
+
const attempt = typeof content?.attempt === "number" ? content.attempt : void 0;
|
|
1718
|
+
const maxAttempts = typeof content?.maxAttempts === "number" ? content.maxAttempts : void 0;
|
|
1719
|
+
const immediate = attempt !== void 0 && attempt >= showAfterAttempts;
|
|
1720
|
+
const [revealed, setRevealed] = (0, react.useState)(immediate);
|
|
1721
|
+
(0, react.useEffect)(() => {
|
|
1722
|
+
if (immediate) {
|
|
1723
|
+
setRevealed(true);
|
|
1724
|
+
return;
|
|
1725
|
+
}
|
|
1726
|
+
const timer = setTimeout(() => setRevealed(true), showAfterMs);
|
|
1727
|
+
return () => clearTimeout(timer);
|
|
1728
|
+
}, [immediate, showAfterMs]);
|
|
1729
|
+
const tokens = typeof content?.progressTokens === "number" ? content.progressTokens : void 0;
|
|
1730
|
+
if (!revealed) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(A2UIGeneratingSkeleton, {
|
|
1731
|
+
label: "Building interface",
|
|
1732
|
+
tokens
|
|
1776
1733
|
});
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1734
|
+
const label = attempt !== void 0 && maxAttempts !== void 0 ? `Retrying generation… (${attempt}/${maxAttempts} attempts)` : "Retrying generation…";
|
|
1735
|
+
const errors = Array.isArray(content?.errors) ? content.errors : [];
|
|
1736
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(A2UIGeneratingSkeleton, {
|
|
1737
|
+
label,
|
|
1738
|
+
tokens,
|
|
1739
|
+
children: debugExposure !== "hidden" && errors.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(A2UIDebugDetails, {
|
|
1740
|
+
label: "validation issues",
|
|
1741
|
+
open: debugExposure === "verbose",
|
|
1742
|
+
payload: {
|
|
1743
|
+
attempt: content?.attempt,
|
|
1744
|
+
errors
|
|
1745
|
+
}
|
|
1746
|
+
})
|
|
1780
1747
|
});
|
|
1781
1748
|
}
|
|
1782
|
-
/**
|
|
1783
|
-
|
|
1784
|
-
* Must be a child of A2UIProvider to access the actions context.
|
|
1785
|
-
*/
|
|
1786
|
-
function SurfaceMessageProcessor({ surfaceId, operations }) {
|
|
1787
|
-
const { processMessages, getSurface } = (0, _copilotkit_a2ui_renderer.useA2UIActions)();
|
|
1788
|
-
const lastHashRef = (0, react.useRef)("");
|
|
1789
|
-
(0, react.useEffect)(() => {
|
|
1790
|
-
const hash = JSON.stringify(operations);
|
|
1791
|
-
if (hash === lastHashRef.current) return;
|
|
1792
|
-
lastHashRef.current = hash;
|
|
1793
|
-
processMessages(getSurface(surfaceId) ? operations.filter((op) => !op?.createSurface) : operations);
|
|
1794
|
-
}, [
|
|
1795
|
-
processMessages,
|
|
1796
|
-
getSurface,
|
|
1797
|
-
surfaceId,
|
|
1798
|
-
operations
|
|
1799
|
-
]);
|
|
1800
|
-
return null;
|
|
1801
|
-
}
|
|
1802
|
-
/**
|
|
1803
|
-
* Default loading component shown while an A2UI surface is generating.
|
|
1804
|
-
* Displays an animated shimmer skeleton.
|
|
1805
|
-
*/
|
|
1806
|
-
function DefaultA2UILoading() {
|
|
1749
|
+
/** failed: a clean hard-failure card that replaces the skeleton in place. */
|
|
1750
|
+
function A2UIRecoveryFailure({ content, debugExposure }) {
|
|
1807
1751
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1808
|
-
className: "cpk:
|
|
1809
|
-
style: { minHeight: 120 },
|
|
1752
|
+
className: "cpk:rounded-lg cpk:border cpk:border-amber-200 cpk:bg-amber-50 cpk:p-3 cpk:text-sm cpk:text-amber-800",
|
|
1810
1753
|
children: [
|
|
1811
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
1812
|
-
className: "cpk:
|
|
1813
|
-
children:
|
|
1814
|
-
className: "cpk:h-3 cpk:w-3 cpk:rounded-full cpk:bg-gray-200",
|
|
1815
|
-
style: { animation: "cpk-a2ui-pulse 1.5s ease-in-out infinite" }
|
|
1816
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
1817
|
-
className: "cpk:text-xs cpk:font-medium cpk:text-gray-400",
|
|
1818
|
-
children: "Generating UI..."
|
|
1819
|
-
})]
|
|
1754
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1755
|
+
className: "cpk:font-medium",
|
|
1756
|
+
children: "Couldn't generate the UI"
|
|
1820
1757
|
}),
|
|
1821
1758
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1822
|
-
className: "cpk:
|
|
1823
|
-
children:
|
|
1824
|
-
.8,
|
|
1825
|
-
.6,
|
|
1826
|
-
.4
|
|
1827
|
-
].map((width, i) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1828
|
-
className: "cpk:h-3 cpk:rounded cpk:bg-gray-200/70",
|
|
1829
|
-
style: {
|
|
1830
|
-
width: `${width * 100}%`,
|
|
1831
|
-
animation: `cpk-a2ui-pulse 1.5s ease-in-out ${i * .15}s infinite`
|
|
1832
|
-
}
|
|
1833
|
-
}, i))
|
|
1759
|
+
className: "cpk:mt-1 cpk:text-xs cpk:text-amber-700",
|
|
1760
|
+
children: "Something went wrong rendering this. You can keep chatting and try again."
|
|
1834
1761
|
}),
|
|
1835
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1762
|
+
debugExposure !== "hidden" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(A2UIDebugDetails, {
|
|
1763
|
+
label: "developer details",
|
|
1764
|
+
open: debugExposure === "verbose",
|
|
1765
|
+
payload: {
|
|
1766
|
+
error: content?.error,
|
|
1767
|
+
attempts: content?.attempts
|
|
1768
|
+
}
|
|
1769
|
+
})
|
|
1841
1770
|
]
|
|
1842
1771
|
});
|
|
1843
1772
|
}
|
|
1844
|
-
function getOperationSurfaceId(operation) {
|
|
1845
|
-
if (!operation || typeof operation !== "object") return null;
|
|
1846
|
-
if (typeof operation.surfaceId === "string") return operation.surfaceId;
|
|
1847
|
-
return operation?.createSurface?.surfaceId ?? operation?.updateComponents?.surfaceId ?? operation?.updateDataModel?.surfaceId ?? operation?.deleteSurface?.surfaceId ?? null;
|
|
1848
|
-
}
|
|
1849
|
-
|
|
1850
|
-
//#endregion
|
|
1851
|
-
//#region src/v2/a2ui/A2UIToolCallRenderer.tsx
|
|
1852
|
-
/**
|
|
1853
|
-
* Tool name used by the dynamic A2UI generation secondary LLM.
|
|
1854
|
-
* This renderer is auto-registered when A2UI is enabled.
|
|
1855
|
-
*/
|
|
1856
|
-
const RENDER_A2UI_TOOL_NAME = "render_a2ui";
|
|
1857
1773
|
/**
|
|
1858
|
-
*
|
|
1859
|
-
*
|
|
1860
|
-
*
|
|
1861
|
-
* Registered automatically when A2UI is enabled. Users can override by
|
|
1862
|
-
* providing their own `useRenderTool({ name: "render_a2ui", ... })`.
|
|
1774
|
+
* Animated wireframe skeleton with a label, an optional live token count, and an
|
|
1775
|
+
* optional debug-detail slot below it. Pure CSS animation (no data dependency).
|
|
1776
|
+
* The `tokens` count drives a progressive reveal of skeleton rows.
|
|
1863
1777
|
*/
|
|
1864
|
-
function
|
|
1865
|
-
const
|
|
1866
|
-
time: 0,
|
|
1867
|
-
tokens: 0
|
|
1868
|
-
});
|
|
1869
|
-
const now = Date.now();
|
|
1870
|
-
let { tokens } = lastRef.current;
|
|
1871
|
-
if (now - lastRef.current.time > 200) {
|
|
1872
|
-
const chars = JSON.stringify(parameters ?? {}).length;
|
|
1873
|
-
tokens = Math.round(chars / 4);
|
|
1874
|
-
lastRef.current = {
|
|
1875
|
-
time: now,
|
|
1876
|
-
tokens
|
|
1877
|
-
};
|
|
1878
|
-
}
|
|
1879
|
-
const phase = tokens < 50 ? 0 : tokens < 200 ? 1 : tokens < 400 ? 2 : 3;
|
|
1778
|
+
function A2UIGeneratingSkeleton({ label, tokens, children }) {
|
|
1779
|
+
const phase = tokens == null ? 3 : tokens < 50 ? 0 : tokens < 200 ? 1 : tokens < 400 ? 2 : 3;
|
|
1880
1780
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1881
1781
|
style: {
|
|
1882
1782
|
margin: "12px 0",
|
|
@@ -2084,8 +1984,8 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
2084
1984
|
color: "#a1a1aa",
|
|
2085
1985
|
letterSpacing: "0.025em"
|
|
2086
1986
|
},
|
|
2087
|
-
children:
|
|
2088
|
-
}), tokens > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
1987
|
+
children: label
|
|
1988
|
+
}), typeof tokens === "number" && tokens > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
2089
1989
|
style: {
|
|
2090
1990
|
fontSize: 11,
|
|
2091
1991
|
color: "#d4d4d8",
|
|
@@ -2098,6 +1998,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
2098
1998
|
]
|
|
2099
1999
|
})]
|
|
2100
2000
|
}),
|
|
2001
|
+
children,
|
|
2101
2002
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("style", { children: `
|
|
2102
2003
|
@keyframes cpk-a2ui-fade {
|
|
2103
2004
|
0%, 100% { opacity: 1; }
|
|
@@ -2111,6 +2012,20 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
2111
2012
|
]
|
|
2112
2013
|
});
|
|
2113
2014
|
}
|
|
2015
|
+
function A2UIDebugDetails({ label, open, payload }) {
|
|
2016
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", {
|
|
2017
|
+
open,
|
|
2018
|
+
className: "cpk:mt-2 cpk:text-xs",
|
|
2019
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("summary", {
|
|
2020
|
+
className: "cpk:cursor-pointer cpk:text-gray-500",
|
|
2021
|
+
children: label
|
|
2022
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
|
|
2023
|
+
className: "cpk:mt-1 cpk:overflow-auto cpk:rounded cpk:bg-gray-100 cpk:p-2 cpk:text-gray-700",
|
|
2024
|
+
style: { fontSize: 11 },
|
|
2025
|
+
children: JSON.stringify(payload, null, 2)
|
|
2026
|
+
})]
|
|
2027
|
+
});
|
|
2028
|
+
}
|
|
2114
2029
|
function Dot() {
|
|
2115
2030
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { style: {
|
|
2116
2031
|
width: 7,
|
|
@@ -2146,13 +2061,242 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
2146
2061
|
children
|
|
2147
2062
|
});
|
|
2148
2063
|
}
|
|
2064
|
+
|
|
2065
|
+
//#endregion
|
|
2066
|
+
//#region src/v2/a2ui/A2UIMessageRenderer.tsx
|
|
2067
|
+
/**
|
|
2068
|
+
* The container key used to wrap A2UI operations for explicit detection.
|
|
2069
|
+
* Must match A2UI_OPERATIONS_KEY in @ag-ui/a2ui-middleware and copilotkit.a2ui (Python).
|
|
2070
|
+
*/
|
|
2071
|
+
const A2UI_OPERATIONS_KEY = "a2ui_operations";
|
|
2072
|
+
let initialized = false;
|
|
2073
|
+
function ensureInitialized() {
|
|
2074
|
+
if (!initialized) {
|
|
2075
|
+
(0, _copilotkit_a2ui_renderer.initializeDefaultCatalog)();
|
|
2076
|
+
(0, _copilotkit_a2ui_renderer.injectStyles)();
|
|
2077
|
+
initialized = true;
|
|
2078
|
+
}
|
|
2079
|
+
}
|
|
2080
|
+
/**
|
|
2081
|
+
* The `a2ui-surface` activity carries the WHOLE generative-UI lifecycle on one
|
|
2082
|
+
* stable messageId (OSS-162): pre-paint `status` ("building" | "retrying" |
|
|
2083
|
+
* "failed") with recovery detail, then `a2ui_operations` on paint. The states
|
|
2084
|
+
* swap in place, so the painted surface replaces the skeleton with no extra
|
|
2085
|
+
* coordination. `.passthrough()` preserves operations + any future fields.
|
|
2086
|
+
*/
|
|
2087
|
+
const A2UISurfaceContentSchema = zod.z.object({
|
|
2088
|
+
a2ui_operations: zod.z.array(zod.z.any()).optional(),
|
|
2089
|
+
...A2UILifecycleFields
|
|
2090
|
+
}).passthrough();
|
|
2091
|
+
function createA2UIMessageRenderer(options) {
|
|
2092
|
+
const { theme, catalog, loadingComponent, recovery } = options;
|
|
2093
|
+
const showAfterMs = recovery?.showAfterMs ?? 2e3;
|
|
2094
|
+
const showAfterAttempts = recovery?.showAfterAttempts ?? 2;
|
|
2095
|
+
const optionDebugExposure = recovery?.debugExposure ?? "collapsed";
|
|
2096
|
+
return {
|
|
2097
|
+
activityType: "a2ui-surface",
|
|
2098
|
+
content: A2UISurfaceContentSchema,
|
|
2099
|
+
render: ({ content, agent }) => {
|
|
2100
|
+
ensureInitialized();
|
|
2101
|
+
const [operations, setOperations] = (0, react.useState)([]);
|
|
2102
|
+
const { copilotkit } = useCopilotKit();
|
|
2103
|
+
const lastContentRef = (0, react.useRef)(null);
|
|
2104
|
+
(0, react.useEffect)(() => {
|
|
2105
|
+
if (content === lastContentRef.current) return;
|
|
2106
|
+
lastContentRef.current = content;
|
|
2107
|
+
const incoming = content?.[A2UI_OPERATIONS_KEY];
|
|
2108
|
+
if (!content || !Array.isArray(incoming)) {
|
|
2109
|
+
setOperations([]);
|
|
2110
|
+
return;
|
|
2111
|
+
}
|
|
2112
|
+
setOperations(incoming);
|
|
2113
|
+
}, [content]);
|
|
2114
|
+
const groupedOperations = (0, react.useMemo)(() => {
|
|
2115
|
+
const groups = /* @__PURE__ */ new Map();
|
|
2116
|
+
for (const operation of operations) {
|
|
2117
|
+
const surfaceId = getOperationSurfaceId(operation) ?? _copilotkit_a2ui_renderer.DEFAULT_SURFACE_ID;
|
|
2118
|
+
if (!groups.has(surfaceId)) groups.set(surfaceId, []);
|
|
2119
|
+
groups.get(surfaceId).push(operation);
|
|
2120
|
+
}
|
|
2121
|
+
return groups;
|
|
2122
|
+
}, [operations]);
|
|
2123
|
+
const hasOps = groupedOperations.size > 0;
|
|
2124
|
+
const renderLifecycle = (c) => {
|
|
2125
|
+
const status = c?.status;
|
|
2126
|
+
const debugExposure = resolveDebugExposure(c, optionDebugExposure);
|
|
2127
|
+
if (status === "failed") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(A2UIRecoveryFailure, {
|
|
2128
|
+
content: c,
|
|
2129
|
+
debugExposure
|
|
2130
|
+
});
|
|
2131
|
+
if (status === "retrying") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(A2UIRetryingState, {
|
|
2132
|
+
content: c,
|
|
2133
|
+
showAfterMs,
|
|
2134
|
+
showAfterAttempts,
|
|
2135
|
+
debugExposure
|
|
2136
|
+
});
|
|
2137
|
+
if (loadingComponent) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(loadingComponent, {});
|
|
2138
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(A2UIBuildingState, { content: c });
|
|
2139
|
+
};
|
|
2140
|
+
const lastLoaderContentRef = (0, react.useRef)(null);
|
|
2141
|
+
if (!(Array.isArray(content?.[A2UI_OPERATIONS_KEY]) && content[A2UI_OPERATIONS_KEY].length > 0)) lastLoaderContentRef.current = content;
|
|
2142
|
+
const [surfaceReady, setSurfaceReady] = (0, react.useState)(false);
|
|
2143
|
+
const readyRef = (0, react.useRef)(false);
|
|
2144
|
+
const markSurfaceReady = (0, react.useCallback)(() => {
|
|
2145
|
+
if (readyRef.current) return;
|
|
2146
|
+
readyRef.current = true;
|
|
2147
|
+
requestAnimationFrame(() => setSurfaceReady(true));
|
|
2148
|
+
}, []);
|
|
2149
|
+
(0, react.useEffect)(() => {
|
|
2150
|
+
if (!hasOps) {
|
|
2151
|
+
setSurfaceReady(false);
|
|
2152
|
+
readyRef.current = false;
|
|
2153
|
+
return;
|
|
2154
|
+
}
|
|
2155
|
+
const t = setTimeout(() => setSurfaceReady(true), 8e3);
|
|
2156
|
+
return () => clearTimeout(t);
|
|
2157
|
+
}, [hasOps]);
|
|
2158
|
+
if (!hasOps) return renderLifecycle(content);
|
|
2159
|
+
const surfaces = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2160
|
+
className: "cpk:flex cpk:min-h-0 cpk:flex-1 cpk:flex-col cpk:gap-6 cpk:overflow-auto cpk:py-6",
|
|
2161
|
+
children: Array.from(groupedOperations.entries()).map(([surfaceId, ops]) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ReactSurfaceHost, {
|
|
2162
|
+
surfaceId,
|
|
2163
|
+
operations: ops,
|
|
2164
|
+
theme,
|
|
2165
|
+
agent,
|
|
2166
|
+
copilotkit,
|
|
2167
|
+
catalog,
|
|
2168
|
+
onReady: markSurfaceReady
|
|
2169
|
+
}, surfaceId))
|
|
2170
|
+
});
|
|
2171
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2172
|
+
style: { position: "relative" },
|
|
2173
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2174
|
+
"aria-hidden": !surfaceReady,
|
|
2175
|
+
style: surfaceReady ? void 0 : {
|
|
2176
|
+
position: "absolute",
|
|
2177
|
+
inset: 0,
|
|
2178
|
+
opacity: 0,
|
|
2179
|
+
pointerEvents: "none"
|
|
2180
|
+
},
|
|
2181
|
+
children: surfaces
|
|
2182
|
+
}), !surfaceReady && renderLifecycle(lastLoaderContentRef.current ?? content)]
|
|
2183
|
+
});
|
|
2184
|
+
}
|
|
2185
|
+
};
|
|
2186
|
+
}
|
|
2187
|
+
/**
|
|
2188
|
+
* Renders a single A2UI surface using the React renderer.
|
|
2189
|
+
* Wraps A2UIProvider + A2UIRenderer and bridges actions back to CopilotKit.
|
|
2190
|
+
*/
|
|
2191
|
+
function ReactSurfaceHost({ surfaceId, operations, theme, agent, copilotkit, catalog, onReady }) {
|
|
2192
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2193
|
+
className: "cpk:flex cpk:w-full cpk:flex-none cpk:flex-col cpk:gap-4",
|
|
2194
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(_copilotkit_a2ui_renderer.A2UIProvider, {
|
|
2195
|
+
onAction: (0, react.useCallback)(async (message) => {
|
|
2196
|
+
if (!agent) return;
|
|
2197
|
+
message.userAction;
|
|
2198
|
+
try {
|
|
2199
|
+
copilotkit.setProperties({
|
|
2200
|
+
...copilotkit.properties,
|
|
2201
|
+
a2uiAction: message
|
|
2202
|
+
});
|
|
2203
|
+
await copilotkit.runAgent({ agent });
|
|
2204
|
+
} finally {
|
|
2205
|
+
if (copilotkit.properties) {
|
|
2206
|
+
const { a2uiAction, ...rest } = copilotkit.properties;
|
|
2207
|
+
copilotkit.setProperties(rest);
|
|
2208
|
+
}
|
|
2209
|
+
}
|
|
2210
|
+
}, [agent, copilotkit]),
|
|
2211
|
+
theme,
|
|
2212
|
+
catalog,
|
|
2213
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SurfaceMessageProcessor, {
|
|
2214
|
+
surfaceId,
|
|
2215
|
+
operations,
|
|
2216
|
+
onReady
|
|
2217
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(A2UISurfaceOrError, { surfaceId })]
|
|
2218
|
+
})
|
|
2219
|
+
});
|
|
2220
|
+
}
|
|
2149
2221
|
/**
|
|
2150
|
-
*
|
|
2151
|
-
*
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2222
|
+
* Renders the A2UI surface, or an error message if processing failed.
|
|
2223
|
+
* Must be a child of A2UIProvider to access the error state.
|
|
2224
|
+
*/
|
|
2225
|
+
function A2UISurfaceOrError({ surfaceId }) {
|
|
2226
|
+
const error = (0, _copilotkit_a2ui_renderer.useA2UIError)();
|
|
2227
|
+
if (error) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2228
|
+
className: "cpk:rounded-lg cpk:border cpk:border-red-200 cpk:bg-red-50 cpk:p-3 cpk:text-sm cpk:text-red-700",
|
|
2229
|
+
children: ["A2UI render error: ", error]
|
|
2230
|
+
});
|
|
2231
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_copilotkit_a2ui_renderer.A2UIRenderer, {
|
|
2232
|
+
surfaceId,
|
|
2233
|
+
className: "cpk:flex cpk:flex-1"
|
|
2234
|
+
});
|
|
2235
|
+
}
|
|
2236
|
+
/**
|
|
2237
|
+
* Processes A2UI operations into the provider's message processor.
|
|
2238
|
+
* Must be a child of A2UIProvider to access the actions context.
|
|
2239
|
+
*/
|
|
2240
|
+
function SurfaceMessageProcessor({ surfaceId, operations, onReady }) {
|
|
2241
|
+
const { processMessages, getSurface } = (0, _copilotkit_a2ui_renderer.useA2UIActions)();
|
|
2242
|
+
const lastHashRef = (0, react.useRef)("");
|
|
2243
|
+
(0, react.useEffect)(() => {
|
|
2244
|
+
const hash = JSON.stringify(operations);
|
|
2245
|
+
if (hash === lastHashRef.current) return;
|
|
2246
|
+
lastHashRef.current = hash;
|
|
2247
|
+
processMessages(getSurface(surfaceId) ? operations.filter((op) => !op?.createSurface) : operations);
|
|
2248
|
+
if (onReady && surfaceHasRenderableContent(operations)) onReady();
|
|
2249
|
+
}, [
|
|
2250
|
+
processMessages,
|
|
2251
|
+
getSurface,
|
|
2252
|
+
surfaceId,
|
|
2253
|
+
operations,
|
|
2254
|
+
onReady
|
|
2255
|
+
]);
|
|
2256
|
+
return null;
|
|
2257
|
+
}
|
|
2258
|
+
/**
|
|
2259
|
+
* Whether the surface's operations are enough to paint a visible card yet.
|
|
2260
|
+
* A data-bound surface references its data via `path` and renders nothing until
|
|
2261
|
+
* the data model has ≥1 value; a static surface (no path refs) paints from its
|
|
2262
|
+
* components alone. Used to time the loader→surface cross-over to actual content
|
|
2263
|
+
* arrival rather than a fixed delay. (OSS-162)
|
|
2264
|
+
*/
|
|
2265
|
+
function surfaceHasRenderableContent(operations) {
|
|
2266
|
+
const componentOps = operations.filter((o) => o?.updateComponents);
|
|
2267
|
+
if (!componentOps.length) return false;
|
|
2268
|
+
if (!JSON.stringify(componentOps).includes("\"path\"")) return true;
|
|
2269
|
+
return operations.some((o) => {
|
|
2270
|
+
const v = o?.updateDataModel?.value;
|
|
2271
|
+
if (!v || typeof v !== "object") return false;
|
|
2272
|
+
return Object.values(v).some((x) => Array.isArray(x) ? x.length > 0 : x !== null && x !== void 0 && x !== "");
|
|
2273
|
+
});
|
|
2274
|
+
}
|
|
2275
|
+
function getOperationSurfaceId(operation) {
|
|
2276
|
+
if (!operation || typeof operation !== "object") return null;
|
|
2277
|
+
if (typeof operation.surfaceId === "string") return operation.surfaceId;
|
|
2278
|
+
return operation?.createSurface?.surfaceId ?? operation?.updateComponents?.surfaceId ?? operation?.updateDataModel?.surfaceId ?? operation?.deleteSurface?.surfaceId ?? null;
|
|
2279
|
+
}
|
|
2280
|
+
|
|
2281
|
+
//#endregion
|
|
2282
|
+
//#region src/v2/a2ui/A2UIToolCallRenderer.tsx
|
|
2283
|
+
/**
|
|
2284
|
+
* Tool name used by the dynamic A2UI generation secondary LLM.
|
|
2285
|
+
*/
|
|
2286
|
+
const RENDER_A2UI_TOOL_NAME = "render_a2ui";
|
|
2287
|
+
/**
|
|
2288
|
+
* Registers a no-op renderer for the `render_a2ui` tool call so its raw streamed
|
|
2289
|
+
* args are never surfaced in the transcript.
|
|
2290
|
+
*
|
|
2291
|
+
* The generation skeleton / retry / failure UX is NO LONGER owned here (OSS-162):
|
|
2292
|
+
* the A2UI middleware drives the whole lifecycle on the `a2ui-surface` activity
|
|
2293
|
+
* (one stable messageId, building → retrying → failed → painted), rendered in
|
|
2294
|
+
* place by `createA2UIMessageRenderer`. Owning a skeleton per tool call caused a
|
|
2295
|
+
* duplicate skeleton on retries / multi-call generations and a skeleton that
|
|
2296
|
+
* lingered after the surface painted — both fixed by retiring it here.
|
|
2297
|
+
*
|
|
2298
|
+
* Users can still override with their own `useRenderTool({ name: "render_a2ui" })`
|
|
2299
|
+
* (hook-based entries take priority over this prop-based registration).
|
|
2156
2300
|
*/
|
|
2157
2301
|
function A2UIBuiltInToolCallRenderer() {
|
|
2158
2302
|
const { copilotkit } = useCopilotKit();
|
|
@@ -2160,15 +2304,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
2160
2304
|
const renderer = defineToolCallRenderer({
|
|
2161
2305
|
name: RENDER_A2UI_TOOL_NAME,
|
|
2162
2306
|
args: zod.z.any(),
|
|
2163
|
-
render: (
|
|
2164
|
-
if (status === "complete") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, {});
|
|
2165
|
-
const params = parameters;
|
|
2166
|
-
const items = params?.items;
|
|
2167
|
-
if (Array.isArray(items) && items.length > 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, {});
|
|
2168
|
-
const components = params?.components;
|
|
2169
|
-
if (Array.isArray(components) && components.length > 2) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, {});
|
|
2170
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(A2UIProgressIndicator, { parameters });
|
|
2171
|
-
}
|
|
2307
|
+
render: () => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, {})
|
|
2172
2308
|
});
|
|
2173
2309
|
const existing = copilotkit._renderToolCalls ?? [];
|
|
2174
2310
|
copilotkit.setRenderToolCalls([...existing.filter((rc) => rc.name !== RENDER_A2UI_TOOL_NAME), renderer]);
|
|
@@ -2305,7 +2441,8 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
2305
2441
|
if (runtimeA2UIEnabled) renderers.unshift(createA2UIMessageRenderer({
|
|
2306
2442
|
theme: a2ui?.theme ?? _copilotkit_a2ui_renderer.viewerTheme,
|
|
2307
2443
|
catalog: a2ui?.catalog,
|
|
2308
|
-
loadingComponent: a2ui?.loadingComponent
|
|
2444
|
+
loadingComponent: a2ui?.loadingComponent,
|
|
2445
|
+
recovery: a2ui?.recovery
|
|
2309
2446
|
}));
|
|
2310
2447
|
return renderers;
|
|
2311
2448
|
}, [
|
|
@@ -4195,7 +4332,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
4195
4332
|
} };
|
|
4196
4333
|
case _copilotkit_shared.CopilotKitErrorCode.UPGRADE_REQUIRED_ERROR: return { primary: {
|
|
4197
4334
|
label: "Upgrade",
|
|
4198
|
-
onClick: () => window.open("https://
|
|
4335
|
+
onClick: () => window.open("https://dashboard.operations.copilotkit.ai", "_blank", "noopener,noreferrer")
|
|
4199
4336
|
} };
|
|
4200
4337
|
default: return;
|
|
4201
4338
|
}
|
|
@@ -5758,7 +5895,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
5758
5895
|
* `useCopilotChatHeadless_c` is for building fully custom UI (headless UI) implementations.
|
|
5759
5896
|
*
|
|
5760
5897
|
* <Callout title="This is a premium-only feature">
|
|
5761
|
-
* Sign up for free on [Copilot Cloud](https://
|
|
5898
|
+
* Sign up for free on [Copilot Cloud](https://dashboard.operations.copilotkit.ai) to get your public license key or read more about <a href="/premium/overview">premium features</a>.
|
|
5762
5899
|
*
|
|
5763
5900
|
* Usage is generous, **free** to get started, and works with **either self-hosted or Copilot Cloud** environments.
|
|
5764
5901
|
* </Callout>
|
|
@@ -5940,7 +6077,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
5940
6077
|
* Enterprise React hook that provides complete chat functionality for fully custom UI implementations.
|
|
5941
6078
|
* Includes all advanced features like direct message access, suggestions array, interrupt handling, and MCP support.
|
|
5942
6079
|
*
|
|
5943
|
-
* **Requires a publicApiKey** - Sign up for free at https://
|
|
6080
|
+
* **Requires a publicApiKey** - Sign up for free at https://dashboard.operations.copilotkit.ai/
|
|
5944
6081
|
*
|
|
5945
6082
|
* @param options - Configuration options for the chat
|
|
5946
6083
|
* @returns Complete chat interface with all enterprise features
|
|
@@ -6566,7 +6703,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6566
6703
|
/**
|
|
6567
6704
|
* <Callout type="info">
|
|
6568
6705
|
* Usage of this hook assumes some additional setup in your application, for more information
|
|
6569
|
-
* on that see the CoAgents <span className="text-blue-500">[getting started guide](/
|
|
6706
|
+
* on that see the CoAgents <span className="text-blue-500">[getting started guide](/langgraph-python/quickstart)</span>.
|
|
6570
6707
|
* </Callout>
|
|
6571
6708
|
* <Frame className="my-12">
|
|
6572
6709
|
* <img
|
|
@@ -6600,18 +6737,21 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6600
6737
|
*
|
|
6601
6738
|
* ```
|
|
6602
6739
|
*
|
|
6603
|
-
* `useCoAgent`
|
|
6740
|
+
* In CopilotKit v2, `useCoAgent` is a thin compatibility wrapper over the v2
|
|
6741
|
+
* [`useAgent`](/reference/hooks/useAgent) hook. It returns an object with the
|
|
6742
|
+
* following properties:
|
|
6604
6743
|
*
|
|
6605
6744
|
* ```tsx
|
|
6606
6745
|
* const {
|
|
6607
6746
|
* name, // The name of the agent currently being used.
|
|
6608
6747
|
* nodeName, // The name of the current LangGraph node.
|
|
6748
|
+
* threadId, // The ID of the thread the agent is running in.
|
|
6609
6749
|
* state, // The current state of the agent.
|
|
6610
6750
|
* setState, // A function to update the state of the agent.
|
|
6611
6751
|
* running, // A boolean indicating if the agent is currently running.
|
|
6612
6752
|
* start, // A function to start the agent.
|
|
6613
6753
|
* stop, // A function to stop the agent.
|
|
6614
|
-
* run, // A function to re-run the agent.
|
|
6754
|
+
* run, // A function to (re-)run the agent. Maps to the v2 agent's `runAgent()`.
|
|
6615
6755
|
* } = agent;
|
|
6616
6756
|
* ```
|
|
6617
6757
|
*
|
|
@@ -6876,7 +7016,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6876
7016
|
*
|
|
6877
7017
|
* @remarks
|
|
6878
7018
|
* This feature is only available when using CopilotKit's hosted cloud service.
|
|
6879
|
-
* To use this feature, sign up at https://
|
|
7019
|
+
* To use this feature, sign up at https://dashboard.operations.copilotkit.ai to get your publicApiKey.
|
|
6880
7020
|
*
|
|
6881
7021
|
* @param action - The frontend action to be wrapped with authentication
|
|
6882
7022
|
* @param dependencies - Optional array of dependencies that will trigger recreation of the action when changed
|