@copilotkit/react-core
Version:
<img src="https://github.com/user-attachments/assets/0a6b64d9-e193-4940-a3f6-60334ac34084" alt="banner" style="border-radius: 12px; border: 2px solid #d6d4fa;" />
500 lines (478 loc) • 16.7 kB
JavaScript
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __async = (__this, __arguments, generator) => {
return new Promise((resolve, reject) => {
var fulfilled = (value) => {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
};
var rejected = (value) => {
try {
step(generator.throw(value));
} catch (e) {
reject(e);
}
};
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
step((generator = generator.apply(__this, __arguments)).next());
});
};
// src/components/error-boundary/error-boundary.tsx
var error_boundary_exports = {};
__export(error_boundary_exports, {
CopilotErrorBoundary: () => CopilotErrorBoundary,
ErrorToast: () => ErrorToast2
});
module.exports = __toCommonJS(error_boundary_exports);
var import_react3 = __toESM(require("react"));
var import_shared4 = require("@copilotkit/shared");
// src/lib/status-checker.ts
var import_shared = require("@copilotkit/shared");
var STATUS_CHECK_INTERVAL = 1e3 * 60 * 5;
var StatusChecker = class {
constructor() {
this.activeKey = null;
this.intervalId = null;
this.instanceCount = 0;
this.lastResponse = null;
}
start(publicApiKey, onUpdate) {
return __async(this, null, function* () {
this.instanceCount++;
if (this.activeKey === publicApiKey)
return;
if (this.intervalId)
clearInterval(this.intervalId);
const checkStatus = () => __async(this, null, function* () {
try {
const response = yield fetch(`${import_shared.COPILOT_CLOUD_API_URL}/ciu`, {
method: "GET",
headers: {
[import_shared.COPILOT_CLOUD_PUBLIC_API_KEY_HEADER]: publicApiKey
}
}).then((response2) => response2.json());
this.lastResponse = response;
onUpdate == null ? void 0 : onUpdate(response);
return response;
} catch (error) {
return null;
}
});
const initialResponse = yield checkStatus();
this.intervalId = setInterval(checkStatus, STATUS_CHECK_INTERVAL);
this.activeKey = publicApiKey;
return initialResponse;
});
}
getLastResponse() {
return this.lastResponse;
}
stop() {
this.instanceCount--;
if (this.instanceCount === 0) {
if (this.intervalId) {
clearInterval(this.intervalId);
this.intervalId = null;
this.activeKey = null;
this.lastResponse = null;
}
}
}
};
// src/components/usage-banner.tsx
var import_shared2 = require("@copilotkit/shared");
var import_jsx_runtime = require("react/jsx-runtime");
function UsageBanner({
severity = import_shared2.Severity.CRITICAL,
message = "",
onClose,
actions
}) {
if (!message || !severity) {
return null;
}
const themes = {
[import_shared2.Severity.INFO]: {
bg: "#f8fafc",
border: "#e2e8f0",
text: "#475569",
accent: "#3b82f6"
},
[import_shared2.Severity.WARNING]: {
bg: "#fffbeb",
border: "#fbbf24",
text: "#92400e",
accent: "#f59e0b"
},
[import_shared2.Severity.CRITICAL]: {
bg: "#fef2f2",
border: "#fecaca",
text: "#dc2626",
accent: "#ef4444"
}
};
const theme = themes[severity];
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("style", { children: `
@keyframes slideUp {
from { opacity: 0; transform: translateX(-50%) translateY(8px); }
to { opacity: 1; transform: translateX(-50%) translateY(0); }
}
.usage-banner {
position: fixed;
bottom: 24px;
left: 50%;
transform: translateX(-50%);
width: min(600px, calc(100vw - 32px));
z-index: 10000;
animation: slideUp 0.2s cubic-bezier(0.16, 1, 0.3, 1);
}
.banner-content {
background: linear-gradient(135deg, ${theme.bg} 0%, ${theme.bg}f5 100%);
border: 1px solid ${theme.border};
border-radius: 12px;
padding: 18px 20px;
box-shadow:
0 4px 24px rgba(0, 0, 0, 0.08),
0 2px 8px rgba(0, 0, 0, 0.04),
inset 0 1px 0 rgba(255, 255, 255, 0.7);
display: flex;
align-items: center;
gap: 16px;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
backdrop-filter: blur(12px);
position: relative;
overflow: hidden;
}
.banner-content::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 1px;
background: linear-gradient(90deg, transparent, ${theme.accent}40, transparent);
}
.banner-message {
color: ${theme.text};
font-size: 14px;
line-height: 1.5;
font-weight: 500;
flex: 1;
letter-spacing: -0.01em;
}
.close-btn {
background: rgba(0, 0, 0, 0.05);
border: none;
color: ${theme.text};
cursor: pointer;
padding: 0;
border-radius: 6px;
opacity: 0.6;
transition: all 0.15s cubic-bezier(0.16, 1, 0.3, 1);
font-size: 14px;
line-height: 1;
flex-shrink: 0;
width: 24px;
height: 24px;
display: flex;
align-items: center;
justify-content: center;
}
.close-btn:hover {
opacity: 1;
background: rgba(0, 0, 0, 0.08);
transform: scale(1.05);
}
.btn-primary {
background: linear-gradient(135deg, ${theme.accent} 0%, ${theme.accent}e6 100%);
color: white;
border: none;
border-radius: 8px;
padding: 10px 18px;
font-size: 13px;
font-weight: 600;
cursor: pointer;
transition: all 0.15s cubic-bezier(0.16, 1, 0.3, 1);
font-family: inherit;
flex-shrink: 0;
box-shadow:
0 2px 8px ${theme.accent}30,
inset 0 1px 0 rgba(255, 255, 255, 0.2);
letter-spacing: -0.01em;
}
.btn-primary:hover {
transform: translateY(-1px) scale(1.02);
box-shadow:
0 4px 12px ${theme.accent}40,
inset 0 1px 0 rgba(255, 255, 255, 0.25);
}
.btn-primary:active {
transform: translateY(0) scale(0.98);
transition: all 0.08s cubic-bezier(0.16, 1, 0.3, 1);
}
@media (max-width: 640px) {
.usage-banner {
width: calc(100vw - 24px);
}
.banner-content {
padding: 16px;
gap: 12px;
}
.banner-message {
font-size: 13px;
line-height: 1.45;
}
.btn-primary {
padding: 8px 14px;
font-size: 12px;
}
.close-btn {
width: 22px;
height: 22px;
font-size: 12px;
}
}
` }),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "usage-banner", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "banner-content", children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "banner-message", children: message }),
(actions == null ? void 0 : actions.primary) && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { className: "btn-primary", onClick: actions.primary.onClick, children: actions.primary.label }),
onClose && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { className: "close-btn", onClick: onClose, title: "Close", children: "\xD7" })
] }) })
] });
}
var getErrorActions = (error) => {
switch (error.code) {
case import_shared2.CopilotKitErrorCode.MISSING_PUBLIC_API_KEY_ERROR:
return {
primary: {
label: "Show me how",
onClick: () => window.open(
"https://docs.copilotkit.ai/premium#how-do-i-get-access-to-premium-features",
"_blank",
"noopener,noreferrer"
)
}
};
case import_shared2.CopilotKitErrorCode.UPGRADE_REQUIRED_ERROR:
return {
primary: {
label: "Upgrade",
onClick: () => window.open("https://cloud.copilotkit.ai", "_blank", "noopener,noreferrer")
}
};
default:
return void 0;
}
};
// src/components/error-boundary/error-utils.tsx
var import_react2 = require("react");
// src/components/toast/toast-provider.tsx
var import_react = require("react");
var import_shared3 = require("@copilotkit/shared");
var import_jsx_runtime2 = require("react/jsx-runtime");
var ToastContext = (0, import_react.createContext)(void 0);
function useToast() {
const context = (0, import_react.useContext)(ToastContext);
if (!context) {
throw new Error("useToast must be used within a ToastProvider");
}
return context;
}
// src/components/toast/exclamation-mark-icon.tsx
var import_jsx_runtime3 = require("react/jsx-runtime");
var ExclamationMarkIcon = ({
className,
style
}) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
"svg",
{
xmlns: "http://www.w3.org/2000/svg",
width: "24",
height: "24",
viewBox: "0 0 24 24",
fill: "none",
stroke: "currentColor",
strokeWidth: "2",
strokeLinecap: "round",
strokeLinejoin: "round",
className: `lucide lucide-circle-alert ${className ? className : ""}`,
style,
children: [
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "12", x2: "12", y1: "8", y2: "12" }),
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "12", x2: "12.01", y1: "16", y2: "16" })
]
}
);
// src/components/error-boundary/error-utils.tsx
var import_react_markdown = __toESM(require("react-markdown"));
var import_jsx_runtime4 = require("react/jsx-runtime");
function ErrorToast({ errors }) {
const errorsToRender = errors.map((error, idx) => {
var _a, _b, _c;
const originalError = "extensions" in error ? (_a = error.extensions) == null ? void 0 : _a.originalError : {};
const message = (_b = originalError == null ? void 0 : originalError.message) != null ? _b : error.message;
const code = "extensions" in error ? (_c = error.extensions) == null ? void 0 : _c.code : null;
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
"div",
{
style: {
marginTop: idx === 0 ? 0 : 10,
marginBottom: 14
},
children: [
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ExclamationMarkIcon, { style: { marginBottom: 4 } }),
code && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
"div",
{
style: {
fontWeight: "600",
marginBottom: 4
},
children: [
"Copilot Runtime Error:",
" ",
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: { fontFamily: "monospace", fontWeight: "normal" }, children: code })
]
}
),
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_markdown.default, { children: message })
]
},
idx
);
});
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
"div",
{
style: {
fontSize: "13px",
maxWidth: "600px"
},
children: [
errorsToRender,
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { fontSize: "11px", opacity: 0.75 }, children: "NOTE: This error only displays during local development." })
]
}
);
}
function useErrorToast() {
const { addToast } = useToast();
return (0, import_react2.useCallback)(
(error) => {
const errorId = error.map((err) => {
var _a, _b;
const message = "extensions" in err ? ((_b = (_a = err.extensions) == null ? void 0 : _a.originalError) == null ? void 0 : _b.message) || err.message : err.message;
const stack = err.stack || "";
return btoa(message + stack).slice(0, 32);
}).join("|");
addToast({
type: "error",
id: errorId,
// Toast libraries typically dedupe by id
message: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ErrorToast, { errors: error })
});
},
[addToast]
);
}
// src/components/error-boundary/error-boundary.tsx
var import_jsx_runtime5 = require("react/jsx-runtime");
var statusChecker = new StatusChecker();
var CopilotErrorBoundary = class extends import_react3.default.Component {
constructor(props) {
super(props);
this.state = {
hasError: false
};
}
static getDerivedStateFromError(error) {
return { hasError: true, error };
}
componentDidMount() {
if (this.props.publicApiKey) {
statusChecker.start(this.props.publicApiKey, (newStatus) => {
this.setState((prevState) => {
var _a;
if ((newStatus == null ? void 0 : newStatus.severity) !== ((_a = prevState.status) == null ? void 0 : _a.severity)) {
return { status: newStatus != null ? newStatus : void 0 };
}
return null;
});
});
}
}
componentWillUnmount() {
statusChecker.stop();
}
componentDidCatch(error, errorInfo) {
console.error("CopilotKit Error:", error, errorInfo);
}
render() {
var _a, _b, _c, _d;
if (this.state.hasError) {
if (this.state.error instanceof import_shared4.CopilotKitError) {
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
this.props.children,
this.props.showUsageBanner && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
UsageBanner,
{
severity: (_b = (_a = this.state.status) == null ? void 0 : _a.severity) != null ? _b : this.state.error.severity,
message: (_d = (_c = this.state.status) == null ? void 0 : _c.message) != null ? _d : this.state.error.message,
actions: getErrorActions(this.state.error)
}
)
] });
}
throw this.state.error;
}
return this.props.children;
}
};
function ErrorToast2({ error, children }) {
const addErrorToast = useErrorToast();
(0, import_react3.useEffect)(() => {
if (error) {
addErrorToast([error]);
}
}, [error, addErrorToast]);
if (!error)
throw error;
return children;
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
CopilotErrorBoundary,
ErrorToast
});
//# sourceMappingURL=error-boundary.js.map
;