@copilotkit/react-core
Version:
<div align="center"> <a href="https://copilotkit.ai" target="_blank"> <img src="https://github.com/copilotkit/copilotkit/raw/main/assets/banner.png" alt="CopilotKit Logo"> </a>
121 lines (119 loc) • 4.05 kB
JavaScript
import {
useCopilotContext
} from "./chunk-PTSWFERP.mjs";
import {
useAsyncCallback,
useToast
} from "./chunk-22ENANUU.mjs";
import {
__async,
__spreadValues
} from "./chunk-SKC7AJIV.mjs";
// src/hooks/use-copilot-action.ts
import { randomId } from "@copilotkit/shared";
import { createElement, Fragment, useEffect, useRef } from "react";
function useCopilotAction(action, dependencies) {
const { setAction, removeAction, actions, chatComponentsCache } = useCopilotContext();
const idRef = useRef(randomId());
const renderAndWaitRef = useRef(null);
const { addToast } = useToast();
action = __spreadValues({}, action);
if (
// renderAndWaitForResponse is not available for catch all actions
isFrontendAction(action) && // check if renderAndWaitForResponse is set
(action.renderAndWait || action.renderAndWaitForResponse)
) {
const renderAndWait = action.renderAndWait || action.renderAndWaitForResponse;
action.renderAndWait = void 0;
action.renderAndWaitForResponse = void 0;
action.handler = useAsyncCallback(() => __async(this, null, function* () {
let resolve;
let reject;
const promise = new Promise((resolvePromise, rejectPromise) => {
resolve = resolvePromise;
reject = rejectPromise;
});
renderAndWaitRef.current = { promise, resolve, reject };
return yield promise;
}), []);
action.render = (props) => {
let status = props.status;
if (props.status === "executing" && !renderAndWaitRef.current) {
status = "inProgress";
}
const waitProps = {
status,
args: props.args,
result: props.result,
handler: status === "executing" ? renderAndWaitRef.current.resolve : void 0,
respond: status === "executing" ? renderAndWaitRef.current.resolve : void 0
};
const isNoArgsRenderWait = (_fn) => {
var _a;
return ((_a = action.parameters) == null ? void 0 : _a.length) === 0;
};
if (renderAndWait) {
if (isNoArgsRenderWait(renderAndWait)) {
return renderAndWait(waitProps);
} else {
return renderAndWait(waitProps);
}
}
return createElement(Fragment);
};
}
if (dependencies === void 0) {
if (actions[idRef.current]) {
if (isFrontendAction(action)) {
actions[idRef.current].handler = action.handler;
}
if (typeof action.render === "function") {
if (chatComponentsCache.current !== null) {
chatComponentsCache.current.actions[action.name] = action.render;
}
}
}
}
useEffect(() => {
const hasDuplicate = Object.values(actions).some(
(otherAction) => otherAction.name === action.name && otherAction !== actions[idRef.current]
);
if (hasDuplicate) {
addToast({
type: "warning",
message: `Found an already registered action with name ${action.name}.`,
id: `dup-action-${action.name}`
});
}
}, [actions]);
useEffect(() => {
setAction(idRef.current, action);
if (chatComponentsCache.current !== null && action.render !== void 0) {
chatComponentsCache.current.actions[action.name] = action.render;
}
return () => {
removeAction(idRef.current);
};
}, [
setAction,
removeAction,
isFrontendAction(action) ? action.description : void 0,
action.name,
isFrontendAction(action) ? action.disabled : void 0,
isFrontendAction(action) ? action.available : void 0,
// This should be faster than deep equality checking
// In addition, all major JS engines guarantee the order of object keys
JSON.stringify(isFrontendAction(action) ? action.parameters : []),
// include render only if it's a string
typeof action.render === "string" ? action.render : void 0,
// dependencies set by the developer
...dependencies || []
]);
}
function isFrontendAction(action) {
return action.name !== "*";
}
export {
useCopilotAction
};
//# sourceMappingURL=chunk-NY3BUYYZ.mjs.map