@copilotkitnext/react 1.52.0-next.6 → 1.52.0-next.7
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/components/chat/CopilotChatMessageView.cjs +18 -5
- package/dist/components/chat/CopilotChatMessageView.cjs.map +1 -1
- package/dist/components/chat/CopilotChatMessageView.d.cts +1 -0
- package/dist/components/chat/CopilotChatMessageView.d.cts.map +1 -1
- package/dist/components/chat/CopilotChatMessageView.d.mts +1 -0
- package/dist/components/chat/CopilotChatMessageView.d.mts.map +1 -1
- package/dist/components/chat/CopilotChatMessageView.mjs +19 -6
- package/dist/components/chat/CopilotChatMessageView.mjs.map +1 -1
- package/dist/hooks/index.cjs +1 -0
- package/dist/hooks/index.d.cts +2 -1
- package/dist/hooks/index.d.mts +2 -1
- package/dist/hooks/index.mjs +1 -0
- package/dist/hooks/use-interrupt.cjs +171 -0
- package/dist/hooks/use-interrupt.cjs.map +1 -0
- package/dist/hooks/use-interrupt.d.cts +102 -0
- package/dist/hooks/use-interrupt.d.cts.map +1 -0
- package/dist/hooks/use-interrupt.d.mts +102 -0
- package/dist/hooks/use-interrupt.d.mts.map +1 -0
- package/dist/hooks/use-interrupt.mjs +170 -0
- package/dist/hooks/use-interrupt.mjs.map +1 -0
- package/dist/index.cjs +2 -0
- package/dist/index.d.cts +3 -1
- package/dist/index.d.mts +3 -1
- package/dist/index.mjs +2 -1
- package/dist/index.umd.js +198 -5
- package/dist/index.umd.js.map +1 -1
- package/dist/lib/react-core.cjs +13 -0
- package/dist/lib/react-core.cjs.map +1 -1
- package/dist/lib/react-core.d.cts +8 -0
- package/dist/lib/react-core.d.cts.map +1 -1
- package/dist/lib/react-core.d.mts +8 -0
- package/dist/lib/react-core.d.mts.map +1 -1
- package/dist/lib/react-core.mjs +13 -0
- package/dist/lib/react-core.mjs.map +1 -1
- package/dist/types/index.d.cts +2 -1
- package/dist/types/index.d.mts +2 -1
- package/dist/types/interrupt.d.cts +17 -0
- package/dist/types/interrupt.d.cts.map +1 -0
- package/dist/types/interrupt.d.mts +17 -0
- package/dist/types/interrupt.d.mts.map +1 -0
- package/package.json +6 -6
package/dist/index.umd.js
CHANGED
|
@@ -1798,6 +1798,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
1798
1798
|
_defineProperty(this, "_renderToolCalls", []);
|
|
1799
1799
|
_defineProperty(this, "_renderCustomMessages", []);
|
|
1800
1800
|
_defineProperty(this, "_renderActivityMessages", []);
|
|
1801
|
+
_defineProperty(this, "_interruptElement", null);
|
|
1801
1802
|
this._renderToolCalls = (_config$renderToolCal = config.renderToolCalls) !== null && _config$renderToolCal !== void 0 ? _config$renderToolCal : [];
|
|
1802
1803
|
this._renderCustomMessages = (_config$renderCustomM = config.renderCustomMessages) !== null && _config$renderCustomM !== void 0 ? _config$renderCustomM : [];
|
|
1803
1804
|
this._renderActivityMessages = (_config$renderActivit = config.renderActivityMessages) !== null && _config$renderActivit !== void 0 ? _config$renderActivit : [];
|
|
@@ -1821,6 +1822,20 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
1821
1822
|
});
|
|
1822
1823
|
}, "Subscriber onRenderToolCallsChanged error:");
|
|
1823
1824
|
}
|
|
1825
|
+
get interruptElement() {
|
|
1826
|
+
return this._interruptElement;
|
|
1827
|
+
}
|
|
1828
|
+
setInterruptElement(element) {
|
|
1829
|
+
this._interruptElement = element;
|
|
1830
|
+
this.notifySubscribers((subscriber) => {
|
|
1831
|
+
var _reactSubscriber$onIn;
|
|
1832
|
+
const reactSubscriber = subscriber;
|
|
1833
|
+
(_reactSubscriber$onIn = reactSubscriber.onInterruptElementChanged) === null || _reactSubscriber$onIn === void 0 || _reactSubscriber$onIn.call(reactSubscriber, {
|
|
1834
|
+
copilotkit: this,
|
|
1835
|
+
interruptElement: this._interruptElement
|
|
1836
|
+
});
|
|
1837
|
+
}, "Subscriber onInterruptElementChanged error:");
|
|
1838
|
+
}
|
|
1824
1839
|
subscribe(subscriber) {
|
|
1825
1840
|
return super.subscribe(subscriber);
|
|
1826
1841
|
}
|
|
@@ -2956,6 +2971,170 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
2956
2971
|
});
|
|
2957
2972
|
}
|
|
2958
2973
|
|
|
2974
|
+
//#endregion
|
|
2975
|
+
//#region src/hooks/use-interrupt.tsx
|
|
2976
|
+
const INTERRUPT_EVENT_NAME = "on_interrupt";
|
|
2977
|
+
function isPromiseLike(value) {
|
|
2978
|
+
return (typeof value === "object" || typeof value === "function") && value !== null && typeof Reflect.get(value, "then") === "function";
|
|
2979
|
+
}
|
|
2980
|
+
/**
|
|
2981
|
+
* Handles agent interrupts (`on_interrupt`) with optional filtering, preprocessing, and resume behavior.
|
|
2982
|
+
*
|
|
2983
|
+
* The hook listens to custom events on the active agent, stores interrupt payloads per run,
|
|
2984
|
+
* and surfaces a render callback once the run finalizes. Call `resolve` from your UI to resume
|
|
2985
|
+
* execution with user-provided data.
|
|
2986
|
+
*
|
|
2987
|
+
* - `renderInChat: true` (default): the element is published into `<CopilotChat>` and this hook returns `void`.
|
|
2988
|
+
* - `renderInChat: false`: the hook returns the interrupt element so you can place it anywhere in your component tree.
|
|
2989
|
+
*
|
|
2990
|
+
* `event.value` is typed as `any` since the interrupt payload shape depends on your agent.
|
|
2991
|
+
* Type-narrow it in your callbacks (e.g. `handler`, `enabled`, `render`) as needed.
|
|
2992
|
+
*
|
|
2993
|
+
* @typeParam TResult - Inferred from `handler` return type. Exposed as `result` in `render`.
|
|
2994
|
+
* @param config - Interrupt configuration (renderer, optional handler/filter, and render mode).
|
|
2995
|
+
* @returns When `renderInChat` is `false`, returns the interrupt element (or `null` when idle).
|
|
2996
|
+
* Otherwise returns `void` and publishes the element into chat. In `render`, `result` is always
|
|
2997
|
+
* either the handler's resolved return value or `null` (including when no handler is provided,
|
|
2998
|
+
* when filtering skips the interrupt, or when handler execution fails).
|
|
2999
|
+
*
|
|
3000
|
+
* @example
|
|
3001
|
+
* ```tsx
|
|
3002
|
+
* import { useInterrupt } from "@copilotkitnext/react";
|
|
3003
|
+
*
|
|
3004
|
+
* function InterruptUI() {
|
|
3005
|
+
* useInterrupt({
|
|
3006
|
+
* render: ({ event, resolve }) => (
|
|
3007
|
+
* <div>
|
|
3008
|
+
* <p>{event.value.question}</p>
|
|
3009
|
+
* <button onClick={() => resolve({ approved: true })}>Approve</button>
|
|
3010
|
+
* <button onClick={() => resolve({ approved: false })}>Reject</button>
|
|
3011
|
+
* </div>
|
|
3012
|
+
* ),
|
|
3013
|
+
* });
|
|
3014
|
+
*
|
|
3015
|
+
* return null;
|
|
3016
|
+
* }
|
|
3017
|
+
* ```
|
|
3018
|
+
*
|
|
3019
|
+
* @example
|
|
3020
|
+
* ```tsx
|
|
3021
|
+
* import { useInterrupt } from "@copilotkitnext/react";
|
|
3022
|
+
*
|
|
3023
|
+
* function CustomPanel() {
|
|
3024
|
+
* const interruptElement = useInterrupt({
|
|
3025
|
+
* renderInChat: false,
|
|
3026
|
+
* enabled: (event) => event.value.startsWith("approval:"),
|
|
3027
|
+
* handler: async ({ event }) => ({ label: event.value.toUpperCase() }),
|
|
3028
|
+
* render: ({ event, result, resolve }) => (
|
|
3029
|
+
* <aside>
|
|
3030
|
+
* <strong>{result?.label ?? ""}</strong>
|
|
3031
|
+
* <button onClick={() => resolve({ value: event.value })}>Continue</button>
|
|
3032
|
+
* </aside>
|
|
3033
|
+
* ),
|
|
3034
|
+
* });
|
|
3035
|
+
*
|
|
3036
|
+
* return <>{interruptElement}</>;
|
|
3037
|
+
* }
|
|
3038
|
+
* ```
|
|
3039
|
+
*/
|
|
3040
|
+
function useInterrupt(config) {
|
|
3041
|
+
const { copilotkit } = useCopilotKit();
|
|
3042
|
+
const { agent } = useAgent({ agentId: config.agentId });
|
|
3043
|
+
const [pendingEvent, setPendingEvent] = (0, react.useState)(null);
|
|
3044
|
+
const [handlerResult, setHandlerResult] = (0, react.useState)(null);
|
|
3045
|
+
(0, react.useEffect)(() => {
|
|
3046
|
+
let localInterrupt = null;
|
|
3047
|
+
const subscription = agent.subscribe({
|
|
3048
|
+
onCustomEvent: ({ event }) => {
|
|
3049
|
+
if (event.name === INTERRUPT_EVENT_NAME) localInterrupt = {
|
|
3050
|
+
name: event.name,
|
|
3051
|
+
value: event.value
|
|
3052
|
+
};
|
|
3053
|
+
},
|
|
3054
|
+
onRunStartedEvent: () => {
|
|
3055
|
+
localInterrupt = null;
|
|
3056
|
+
setPendingEvent(null);
|
|
3057
|
+
},
|
|
3058
|
+
onRunFinalized: () => {
|
|
3059
|
+
if (localInterrupt) {
|
|
3060
|
+
setPendingEvent(localInterrupt);
|
|
3061
|
+
localInterrupt = null;
|
|
3062
|
+
}
|
|
3063
|
+
},
|
|
3064
|
+
onRunFailed: () => {
|
|
3065
|
+
localInterrupt = null;
|
|
3066
|
+
}
|
|
3067
|
+
});
|
|
3068
|
+
return () => subscription.unsubscribe();
|
|
3069
|
+
}, [agent]);
|
|
3070
|
+
const resolve = (0, react.useCallback)((response) => {
|
|
3071
|
+
setPendingEvent(null);
|
|
3072
|
+
copilotkit.runAgent({
|
|
3073
|
+
agent,
|
|
3074
|
+
forwardedProps: { command: { resume: response } }
|
|
3075
|
+
});
|
|
3076
|
+
}, [agent, copilotkit]);
|
|
3077
|
+
(0, react.useEffect)(() => {
|
|
3078
|
+
if (!pendingEvent) {
|
|
3079
|
+
setHandlerResult(null);
|
|
3080
|
+
return;
|
|
3081
|
+
}
|
|
3082
|
+
if (config.enabled && !config.enabled(pendingEvent)) {
|
|
3083
|
+
setHandlerResult(null);
|
|
3084
|
+
return;
|
|
3085
|
+
}
|
|
3086
|
+
const handler = config.handler;
|
|
3087
|
+
if (!handler) {
|
|
3088
|
+
setHandlerResult(null);
|
|
3089
|
+
return;
|
|
3090
|
+
}
|
|
3091
|
+
let cancelled = false;
|
|
3092
|
+
const maybePromise = handler({
|
|
3093
|
+
event: pendingEvent,
|
|
3094
|
+
resolve
|
|
3095
|
+
});
|
|
3096
|
+
if (isPromiseLike(maybePromise)) Promise.resolve(maybePromise).then((resolved) => {
|
|
3097
|
+
if (!cancelled) setHandlerResult(resolved);
|
|
3098
|
+
}).catch(() => {
|
|
3099
|
+
if (!cancelled) setHandlerResult(null);
|
|
3100
|
+
});
|
|
3101
|
+
else setHandlerResult(maybePromise);
|
|
3102
|
+
return () => {
|
|
3103
|
+
cancelled = true;
|
|
3104
|
+
};
|
|
3105
|
+
}, [
|
|
3106
|
+
pendingEvent,
|
|
3107
|
+
config.enabled,
|
|
3108
|
+
config.handler,
|
|
3109
|
+
resolve
|
|
3110
|
+
]);
|
|
3111
|
+
const element = (0, react.useMemo)(() => {
|
|
3112
|
+
if (!pendingEvent) return null;
|
|
3113
|
+
if (config.enabled && !config.enabled(pendingEvent)) return null;
|
|
3114
|
+
return config.render({
|
|
3115
|
+
event: pendingEvent,
|
|
3116
|
+
result: handlerResult,
|
|
3117
|
+
resolve
|
|
3118
|
+
});
|
|
3119
|
+
}, [
|
|
3120
|
+
pendingEvent,
|
|
3121
|
+
handlerResult,
|
|
3122
|
+
config.enabled,
|
|
3123
|
+
config.render,
|
|
3124
|
+
resolve
|
|
3125
|
+
]);
|
|
3126
|
+
(0, react.useEffect)(() => {
|
|
3127
|
+
if (config.renderInChat === false) return;
|
|
3128
|
+
copilotkit.setInterruptElement(element);
|
|
3129
|
+
return () => copilotkit.setInterruptElement(null);
|
|
3130
|
+
}, [
|
|
3131
|
+
element,
|
|
3132
|
+
config.renderInChat,
|
|
3133
|
+
copilotkit
|
|
3134
|
+
]);
|
|
3135
|
+
if (config.renderInChat === false) return element;
|
|
3136
|
+
}
|
|
3137
|
+
|
|
2959
3138
|
//#endregion
|
|
2960
3139
|
//#region src/components/chat/CopilotChatToolCallsView.tsx
|
|
2961
3140
|
function CopilotChatToolCallsView({ message, messages = [] }) {
|
|
@@ -3645,6 +3824,14 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
3645
3824
|
copilotkit,
|
|
3646
3825
|
forceUpdate
|
|
3647
3826
|
]);
|
|
3827
|
+
const [interruptElement, setInterruptElement] = (0, react.useState)(null);
|
|
3828
|
+
(0, react.useEffect)(() => {
|
|
3829
|
+
setInterruptElement(copilotkit.interruptElement);
|
|
3830
|
+
const subscription = copilotkit.subscribe({ onInterruptElementChanged: ({ interruptElement }) => {
|
|
3831
|
+
setInterruptElement(interruptElement);
|
|
3832
|
+
} });
|
|
3833
|
+
return () => subscription.unsubscribe();
|
|
3834
|
+
}, [copilotkit]);
|
|
3648
3835
|
const getStateSnapshotForMessage = (messageId) => {
|
|
3649
3836
|
var _copilotkit$getRunIdF;
|
|
3650
3837
|
if (!config) return void 0;
|
|
@@ -3719,7 +3906,8 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
3719
3906
|
children: children({
|
|
3720
3907
|
messageElements,
|
|
3721
3908
|
messages,
|
|
3722
|
-
isRunning
|
|
3909
|
+
isRunning,
|
|
3910
|
+
interruptElement
|
|
3723
3911
|
})
|
|
3724
3912
|
});
|
|
3725
3913
|
const lastMessage = messages[messages.length - 1];
|
|
@@ -3728,10 +3916,14 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
3728
3916
|
"data-copilotkit": true,
|
|
3729
3917
|
className: (0, tailwind_merge.twMerge)("cpk:flex cpk:flex-col", className),
|
|
3730
3918
|
...props,
|
|
3731
|
-
children: [
|
|
3732
|
-
|
|
3733
|
-
|
|
3734
|
-
|
|
3919
|
+
children: [
|
|
3920
|
+
messageElements,
|
|
3921
|
+
interruptElement,
|
|
3922
|
+
showCursor && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
3923
|
+
className: "cpk:mt-2",
|
|
3924
|
+
children: renderSlot(cursor, CopilotChatMessageView.Cursor, {})
|
|
3925
|
+
})
|
|
3926
|
+
]
|
|
3735
3927
|
});
|
|
3736
3928
|
}
|
|
3737
3929
|
CopilotChatMessageView.Cursor = function Cursor({ className, ...props }) {
|
|
@@ -4952,6 +5144,7 @@ exports.useCopilotKit = useCopilotKit;
|
|
|
4952
5144
|
exports.useDefaultRenderTool = useDefaultRenderTool;
|
|
4953
5145
|
exports.useFrontendTool = useFrontendTool;
|
|
4954
5146
|
exports.useHumanInTheLoop = useHumanInTheLoop;
|
|
5147
|
+
exports.useInterrupt = useInterrupt;
|
|
4955
5148
|
exports.useRenderActivityMessage = useRenderActivityMessage;
|
|
4956
5149
|
exports.useRenderCustomMessages = useRenderCustomMessages;
|
|
4957
5150
|
exports.useRenderTool = useRenderTool;
|