UNPKG

@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;" />

142 lines (140 loc) 5.05 kB
import { useAsyncCallback } from "./chunk-N4WEHORG.mjs"; import { useToast } from "./chunk-EFL5OBKN.mjs"; import { useCopilotContext } from "./chunk-EUX2P2E7.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 activatingMessageIdRef = 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) ) { action._isRenderAndWait = true; const renderAndWait = action.renderAndWait || action.renderAndWaitForResponse; action.renderAndWait = void 0; action.renderAndWaitForResponse = void 0; action._setActivatingMessageId = (id) => { activatingMessageIdRef.current = id; }; action.handler = useAsyncCallback(() => __async(this, null, function* () { const currentActivatingId = activatingMessageIdRef.current; let resolve; let reject; const promise = new Promise((resolvePromise, rejectPromise) => { resolve = resolvePromise; reject = rejectPromise; }); renderAndWaitRef.current = { promise, resolve, reject, messageId: currentActivatingId }; const result = yield promise; return result; }), []); action.render = (props) => { const currentRenderMessageId = props.messageId; let status = props.status; if (props.status === "executing") { if (!renderAndWaitRef.current || !renderAndWaitRef.current.promise) { status = "inProgress"; } else if (renderAndWaitRef.current.messageId !== currentRenderMessageId && activatingMessageIdRef.current !== currentRenderMessageId) { status = "inProgress"; } } const waitProps = { status, args: props.args, result: props.result, // handler and respond should only be provided if this is the truly active instance // and its promise infrastructure is ready. handler: status === "executing" && renderAndWaitRef.current && renderAndWaitRef.current.messageId === currentRenderMessageId ? renderAndWaitRef.current.resolve : void 0, respond: status === "executing" && renderAndWaitRef.current && renderAndWaitRef.current.messageId === currentRenderMessageId ? 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-T3376SZS.mjs.map