@copilotkit/react-core 1.55.3 → 1.56.0
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-Cd-NrDyp.mjs → copilotkit-BebqQrYT.mjs} +94 -44
- package/dist/copilotkit-BebqQrYT.mjs.map +1 -0
- package/dist/{copilotkit-Dgdpbqjt.cjs → copilotkit-Cvb6WpAX.cjs} +98 -42
- package/dist/copilotkit-Cvb6WpAX.cjs.map +1 -0
- package/dist/{copilotkit-dwDWYpya.d.cts → copilotkit-Dv8zU8_U.d.cts} +47 -10
- package/dist/copilotkit-Dv8zU8_U.d.cts.map +1 -0
- package/dist/{copilotkit-BuhSUZHb.d.mts → copilotkit-f2Uq0RwG.d.mts} +47 -10
- package/dist/copilotkit-f2Uq0RwG.d.mts.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.umd.js +41 -17
- package/dist/index.umd.js.map +1 -1
- package/dist/v2/index.cjs +2 -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 +92 -42
- package/dist/v2/index.umd.js.map +1 -1
- package/package.json +6 -6
- package/src/components/copilot-provider/__tests__/error-visibility-prod.test.tsx +70 -0
- package/src/components/copilot-provider/copilot-messages.tsx +39 -24
- package/src/components/copilot-provider/copilotkit-props.tsx +26 -6
- package/src/components/copilot-provider/copilotkit.tsx +4 -1
- package/src/v2/components/chat/CopilotChatAssistantMessage.tsx +18 -15
- package/src/v2/components/chat/CopilotChatReasoningMessage.tsx +17 -4
- package/src/v2/components/chat/CopilotChatUserMessage.tsx +13 -10
- package/src/v2/components/chat/__tests__/CopilotChat.e2e.test.tsx +131 -5
- package/src/v2/components/chat/__tests__/CopilotChatAssistantMessage.test.tsx +1 -1
- package/src/v2/components/chat/__tests__/CopilotChatCopyButton.clipboard.test.tsx +241 -0
- package/src/v2/hooks/__tests__/use-agent-throttle.test.tsx +10 -10
- package/src/v2/hooks/__tests__/use-capabilities.test.tsx +76 -0
- package/src/v2/hooks/index.ts +1 -0
- package/src/v2/hooks/use-agent.tsx +23 -4
- package/src/v2/hooks/use-capabilities.tsx +25 -0
- package/src/v2/providers/CopilotKitProvider.tsx +15 -2
- package/dist/copilotkit-BuhSUZHb.d.mts.map +0 -1
- package/dist/copilotkit-Cd-NrDyp.mjs.map +0 -1
- package/dist/copilotkit-Dgdpbqjt.cjs.map +0 -1
- package/dist/copilotkit-dwDWYpya.d.cts.map +0 -1
|
@@ -3072,7 +3072,7 @@ function useStableArrayProp(prop, warningMessage, isMeaningfulChange) {
|
|
|
3072
3072
|
}, [value, warningMessage]);
|
|
3073
3073
|
return value;
|
|
3074
3074
|
}
|
|
3075
|
-
const CopilotKitProvider = ({ children, runtimeUrl, headers = {}, credentials, publicApiKey, publicLicenseKey, licenseToken, properties = {}, agents__unsafe_dev_only: agents = {}, selfManagedAgents = {}, renderToolCalls, renderActivityMessages, renderCustomMessages, frontendTools, humanInTheLoop, openGenerativeUI, showDevConsole = false, useSingleEndpoint, onError, a2ui, defaultThrottleMs, inspectorDefaultAnchor }) => {
|
|
3075
|
+
const CopilotKitProvider = ({ children, runtimeUrl, headers: headersProp = {}, credentials, publicApiKey, publicLicenseKey, licenseToken, properties = {}, agents__unsafe_dev_only: agents = {}, selfManagedAgents = {}, renderToolCalls, renderActivityMessages, renderCustomMessages, frontendTools, humanInTheLoop, openGenerativeUI, showDevConsole = false, useSingleEndpoint, onError, a2ui, defaultThrottleMs, inspectorDefaultAnchor, debug }) => {
|
|
3076
3076
|
const [shouldRenderInspector, setShouldRenderInspector] = (0, react.useState)(false);
|
|
3077
3077
|
const [runtimeA2UIEnabled, setRuntimeA2UIEnabled] = (0, react.useState)(false);
|
|
3078
3078
|
const [runtimeOpenGenUIEnabled, setRuntimeOpenGenUIEnabled] = (0, react.useState)(false);
|
|
@@ -3127,6 +3127,7 @@ const CopilotKitProvider = ({ children, runtimeUrl, headers = {}, credentials, p
|
|
|
3127
3127
|
...selfManagedAgents
|
|
3128
3128
|
}), [agents, selfManagedAgents]);
|
|
3129
3129
|
const hasLocalAgents = mergedAgents && Object.keys(mergedAgents).length > 0;
|
|
3130
|
+
const headers = typeof headersProp === "function" ? headersProp() : headersProp;
|
|
3130
3131
|
const mergedHeaders = (0, react.useMemo)(() => {
|
|
3131
3132
|
if (!resolvedPublicKey) return headers;
|
|
3132
3133
|
if (headers[HEADER_NAME]) return headers;
|
|
@@ -3228,7 +3229,8 @@ const CopilotKitProvider = ({ children, runtimeUrl, headers = {}, credentials, p
|
|
|
3228
3229
|
tools: allTools,
|
|
3229
3230
|
renderToolCalls: allRenderToolCalls,
|
|
3230
3231
|
renderActivityMessages: allActivityRenderers,
|
|
3231
|
-
renderCustomMessages: renderCustomMessagesList
|
|
3232
|
+
renderCustomMessages: renderCustomMessagesList,
|
|
3233
|
+
debug
|
|
3232
3234
|
});
|
|
3233
3235
|
if (defaultThrottleMs !== void 0) copilotkitRef.current.setDefaultThrottleMs(defaultThrottleMs);
|
|
3234
3236
|
}
|
|
@@ -3301,6 +3303,7 @@ const CopilotKitProvider = ({ children, runtimeUrl, headers = {}, credentials, p
|
|
|
3301
3303
|
copilotkit.setCredentials(credentials);
|
|
3302
3304
|
copilotkit.setProperties(properties);
|
|
3303
3305
|
copilotkit.setAgents__unsafe_dev_only(mergedAgents);
|
|
3306
|
+
copilotkit.setDebug(debug);
|
|
3304
3307
|
}, [
|
|
3305
3308
|
copilotkit,
|
|
3306
3309
|
chatApiEndpoint,
|
|
@@ -3308,7 +3311,8 @@ const CopilotKitProvider = ({ children, runtimeUrl, headers = {}, credentials, p
|
|
|
3308
3311
|
credentials,
|
|
3309
3312
|
properties,
|
|
3310
3313
|
mergedAgents,
|
|
3311
|
-
useSingleEndpoint
|
|
3314
|
+
useSingleEndpoint,
|
|
3315
|
+
debug
|
|
3312
3316
|
]);
|
|
3313
3317
|
const didMountRef = (0, react.useRef)(false);
|
|
3314
3318
|
(0, react.useEffect)(() => {
|
|
@@ -3619,6 +3623,17 @@ function useAgent({ agentId, threadId, updates, throttleMs } = {}) {
|
|
|
3619
3623
|
const handlers = {};
|
|
3620
3624
|
let timerId = null;
|
|
3621
3625
|
let active = true;
|
|
3626
|
+
let batchScheduled = false;
|
|
3627
|
+
const batchedForceUpdate = () => {
|
|
3628
|
+
if (!active) return;
|
|
3629
|
+
if (!batchScheduled) {
|
|
3630
|
+
batchScheduled = true;
|
|
3631
|
+
queueMicrotask(() => {
|
|
3632
|
+
batchScheduled = false;
|
|
3633
|
+
if (active) forceUpdate();
|
|
3634
|
+
});
|
|
3635
|
+
}
|
|
3636
|
+
};
|
|
3622
3637
|
if (updateFlags.includes(UseAgentUpdate.OnMessagesChanged)) {
|
|
3623
3638
|
const ms = effectiveThrottleMs;
|
|
3624
3639
|
if (ms > 0) {
|
|
@@ -3643,11 +3658,11 @@ function useAgent({ agentId, threadId, updates, throttleMs } = {}) {
|
|
|
3643
3658
|
handlers.onMessagesChanged = throttledNotify;
|
|
3644
3659
|
} else handlers.onMessagesChanged = forceUpdate;
|
|
3645
3660
|
}
|
|
3646
|
-
if (updateFlags.includes(UseAgentUpdate.OnStateChanged)) handlers.onStateChanged =
|
|
3661
|
+
if (updateFlags.includes(UseAgentUpdate.OnStateChanged)) handlers.onStateChanged = batchedForceUpdate;
|
|
3647
3662
|
if (updateFlags.includes(UseAgentUpdate.OnRunStatusChanged)) {
|
|
3648
|
-
handlers.onRunInitialized =
|
|
3649
|
-
handlers.onRunFinalized =
|
|
3650
|
-
handlers.onRunFailed =
|
|
3663
|
+
handlers.onRunInitialized = batchedForceUpdate;
|
|
3664
|
+
handlers.onRunFinalized = batchedForceUpdate;
|
|
3665
|
+
handlers.onRunFailed = batchedForceUpdate;
|
|
3651
3666
|
}
|
|
3652
3667
|
const subscription = agent.subscribe(handlers);
|
|
3653
3668
|
return () => {
|
|
@@ -4184,6 +4199,24 @@ function useHumanInTheLoop(tool, deps) {
|
|
|
4184
4199
|
]);
|
|
4185
4200
|
}
|
|
4186
4201
|
|
|
4202
|
+
//#endregion
|
|
4203
|
+
//#region src/v2/hooks/use-capabilities.tsx
|
|
4204
|
+
/**
|
|
4205
|
+
* Returns the capabilities declared by the given agent (or the default agent).
|
|
4206
|
+
* Capabilities are populated from the runtime `/info` response at connection
|
|
4207
|
+
* time. The hook reads them synchronously from the agent instance — there is
|
|
4208
|
+
* no separate loading state, but the value will be `undefined` until the
|
|
4209
|
+
* runtime handshake completes.
|
|
4210
|
+
*
|
|
4211
|
+
* @param agentId - Optional agent ID. If omitted, uses the default agent.
|
|
4212
|
+
* @returns The agent's capabilities, or `undefined` if the agent doesn't
|
|
4213
|
+
* declare capabilities.
|
|
4214
|
+
*/
|
|
4215
|
+
function useCapabilities(agentId) {
|
|
4216
|
+
const { agent } = useAgent({ agentId });
|
|
4217
|
+
if (agent && "capabilities" in agent) return agent.capabilities;
|
|
4218
|
+
}
|
|
4219
|
+
|
|
4187
4220
|
//#endregion
|
|
4188
4221
|
//#region src/v2/hooks/use-suggestions.tsx
|
|
4189
4222
|
function useSuggestions({ agentId } = {}) {
|
|
@@ -4835,11 +4868,8 @@ function CopilotChatAssistantMessage({ message, messages, isRunning, onThumbsUp,
|
|
|
4835
4868
|
useKatexStyles();
|
|
4836
4869
|
const boundMarkdownRenderer = renderSlot(markdownRenderer, CopilotChatAssistantMessage.MarkdownRenderer, { content: message.content || "" });
|
|
4837
4870
|
const boundCopyButton = renderSlot(copyButton, CopilotChatAssistantMessage.CopyButton, { onClick: async () => {
|
|
4838
|
-
if (message.content)
|
|
4839
|
-
|
|
4840
|
-
} catch (err) {
|
|
4841
|
-
console.error("Failed to copy message:", err);
|
|
4842
|
-
}
|
|
4871
|
+
if (message.content) return await (0, _copilotkit_shared.copyToClipboard)(message.content);
|
|
4872
|
+
return false;
|
|
4843
4873
|
} });
|
|
4844
4874
|
const boundThumbsUpButton = renderSlot(thumbsUpButton, CopilotChatAssistantMessage.ThumbsUpButton, { onClick: onThumbsUp });
|
|
4845
4875
|
const boundThumbsDownButton = renderSlot(thumbsDownButton, CopilotChatAssistantMessage.ThumbsDownButton, { onClick: onThumbsDown });
|
|
@@ -4937,14 +4967,17 @@ function CopilotChatAssistantMessage({ message, messages, isRunning, onThumbsUp,
|
|
|
4937
4967
|
if (timerRef.current !== null) clearTimeout(timerRef.current);
|
|
4938
4968
|
};
|
|
4939
4969
|
}, []);
|
|
4940
|
-
const handleClick = (event) => {
|
|
4941
|
-
|
|
4942
|
-
if (
|
|
4943
|
-
|
|
4944
|
-
|
|
4945
|
-
|
|
4946
|
-
|
|
4947
|
-
|
|
4970
|
+
const handleClick = async (event) => {
|
|
4971
|
+
let success = false;
|
|
4972
|
+
if (onClick) success = await Promise.resolve(onClick(event)) === true;
|
|
4973
|
+
if (success) {
|
|
4974
|
+
setCopied(true);
|
|
4975
|
+
if (timerRef.current !== null) clearTimeout(timerRef.current);
|
|
4976
|
+
timerRef.current = setTimeout(() => {
|
|
4977
|
+
timerRef.current = null;
|
|
4978
|
+
setCopied(false);
|
|
4979
|
+
}, 2e3);
|
|
4980
|
+
}
|
|
4948
4981
|
};
|
|
4949
4982
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolbarButton, {
|
|
4950
4983
|
"data-testid": "copilot-copy-button",
|
|
@@ -5097,11 +5130,8 @@ function CopilotChatUserMessage({ message, onEditMessage, branchIndex, numberOfB
|
|
|
5097
5130
|
const mediaParts = (0, react.useMemo)(() => getMediaParts(message.content), [message.content]);
|
|
5098
5131
|
const BoundMessageRenderer = renderSlot(messageRenderer, CopilotChatUserMessage.MessageRenderer, { content: flattenedContent });
|
|
5099
5132
|
const BoundCopyButton = renderSlot(copyButton, CopilotChatUserMessage.CopyButton, { onClick: async () => {
|
|
5100
|
-
if (flattenedContent)
|
|
5101
|
-
|
|
5102
|
-
} catch (err) {
|
|
5103
|
-
console.error("Failed to copy message:", err);
|
|
5104
|
-
}
|
|
5133
|
+
if (flattenedContent) return await (0, _copilotkit_shared.copyToClipboard)(flattenedContent);
|
|
5134
|
+
return false;
|
|
5105
5135
|
} });
|
|
5106
5136
|
const BoundEditButton = renderSlot(editButton, CopilotChatUserMessage.EditButton, { onClick: () => onEditMessage?.({ message }) });
|
|
5107
5137
|
const BoundBranchNavigation = renderSlot(branchNavigation, CopilotChatUserMessage.BranchNavigation, {
|
|
@@ -5189,10 +5219,13 @@ function CopilotChatUserMessage({ message, onEditMessage, branchIndex, numberOfB
|
|
|
5189
5219
|
_CopilotChatUserMessage.CopyButton = ({ className, title, onClick, ...props }) => {
|
|
5190
5220
|
const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
|
|
5191
5221
|
const [copied, setCopied] = (0, react.useState)(false);
|
|
5192
|
-
const handleClick = (event) => {
|
|
5193
|
-
|
|
5194
|
-
|
|
5195
|
-
if (
|
|
5222
|
+
const handleClick = async (event) => {
|
|
5223
|
+
let success = false;
|
|
5224
|
+
if (onClick) success = await Promise.resolve(onClick(event)) === true;
|
|
5225
|
+
if (success) {
|
|
5226
|
+
setCopied(true);
|
|
5227
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
5228
|
+
}
|
|
5196
5229
|
};
|
|
5197
5230
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolbarButton, {
|
|
5198
5231
|
"data-testid": "copilot-user-copy-button",
|
|
@@ -5299,17 +5332,24 @@ function CopilotChatReasoningMessage({ message, messages, isRunning, header, con
|
|
|
5299
5332
|
return () => clearInterval(timer);
|
|
5300
5333
|
}, [isStreaming]);
|
|
5301
5334
|
const [isOpen, setIsOpen] = (0, react.useState)(isStreaming);
|
|
5335
|
+
const userToggledRef = (0, react.useRef)(false);
|
|
5302
5336
|
(0, react.useEffect)(() => {
|
|
5303
|
-
if (isStreaming)
|
|
5304
|
-
|
|
5337
|
+
if (isStreaming) {
|
|
5338
|
+
userToggledRef.current = false;
|
|
5339
|
+
setIsOpen(true);
|
|
5340
|
+
} else if (!userToggledRef.current) setIsOpen(false);
|
|
5305
5341
|
}, [isStreaming]);
|
|
5342
|
+
const handleToggle = hasContent ? () => {
|
|
5343
|
+
userToggledRef.current = true;
|
|
5344
|
+
setIsOpen((prev) => !prev);
|
|
5345
|
+
} : void 0;
|
|
5306
5346
|
const label = isStreaming ? "Thinking…" : `Thought for ${formatDuration(elapsed)}`;
|
|
5307
5347
|
const boundHeader = renderSlot(header, CopilotChatReasoningMessage.Header, {
|
|
5308
5348
|
isOpen,
|
|
5309
5349
|
label,
|
|
5310
5350
|
hasContent,
|
|
5311
5351
|
isStreaming,
|
|
5312
|
-
onClick:
|
|
5352
|
+
onClick: handleToggle
|
|
5313
5353
|
});
|
|
5314
5354
|
const boundContent = renderSlot(contentView, CopilotChatReasoningMessage.Content, {
|
|
5315
5355
|
isStreaming,
|
|
@@ -8013,6 +8053,20 @@ function shouldShowDevConsole(showDevConsole) {
|
|
|
8013
8053
|
/**
|
|
8014
8054
|
* An internal context to separate the messages state (which is constantly changing) from the rest of CopilotKit context
|
|
8015
8055
|
*/
|
|
8056
|
+
/**
|
|
8057
|
+
* Determine whether a GraphQL error should be suppressed based on its visibility
|
|
8058
|
+
* and whether the dev console is active.
|
|
8059
|
+
*
|
|
8060
|
+
* Returns `null` when the error should be surfaced to the UI, or a log prefix
|
|
8061
|
+
* string when the error should be suppressed (logged to console only).
|
|
8062
|
+
*
|
|
8063
|
+
* Exported for unit testing.
|
|
8064
|
+
*/
|
|
8065
|
+
function getErrorSuppression(visibility, isDev) {
|
|
8066
|
+
if (visibility === _copilotkit_shared.ErrorVisibility.SILENT) return "CopilotKit Silent Error:";
|
|
8067
|
+
if (!isDev && visibility === _copilotkit_shared.ErrorVisibility.DEV_ONLY) return "CopilotKit Error (hidden in production):";
|
|
8068
|
+
return null;
|
|
8069
|
+
}
|
|
8016
8070
|
const MessagesTapContext = (0, react.createContext)(null);
|
|
8017
8071
|
function useMessagesTap() {
|
|
8018
8072
|
const tap = (0, react.useContext)(MessagesTapContext);
|
|
@@ -8096,12 +8150,9 @@ function CopilotMessages({ children }) {
|
|
|
8096
8150
|
const graphQLErrors = error.graphQLErrors;
|
|
8097
8151
|
const routeError = (gqlError) => {
|
|
8098
8152
|
const visibility = gqlError.extensions?.visibility;
|
|
8099
|
-
|
|
8100
|
-
|
|
8101
|
-
|
|
8102
|
-
}
|
|
8103
|
-
if (visibility === _copilotkit_shared.ErrorVisibility.SILENT) {
|
|
8104
|
-
console.error("CopilotKit Silent Error:", gqlError.message);
|
|
8153
|
+
const suppression = getErrorSuppression(visibility, shouldShowDevConsole(showDevConsole));
|
|
8154
|
+
if (suppression) {
|
|
8155
|
+
console.error(suppression, gqlError.message);
|
|
8105
8156
|
return;
|
|
8106
8157
|
}
|
|
8107
8158
|
const ckError = createStructuredError(gqlError);
|
|
@@ -8118,8 +8169,7 @@ function CopilotMessages({ children }) {
|
|
|
8118
8169
|
}
|
|
8119
8170
|
};
|
|
8120
8171
|
graphQLErrors.forEach(routeError);
|
|
8121
|
-
} else
|
|
8122
|
-
else {
|
|
8172
|
+
} else {
|
|
8123
8173
|
const fallbackError = new _copilotkit_shared.CopilotKitError({
|
|
8124
8174
|
message: error?.message || String(error),
|
|
8125
8175
|
code: _copilotkit_shared.CopilotKitErrorCode.UNKNOWN
|
|
@@ -9186,7 +9236,7 @@ function CopilotKitInternal(cpkProps) {
|
|
|
9186
9236
|
publicApiKey,
|
|
9187
9237
|
...cloud ? { cloud } : {},
|
|
9188
9238
|
chatApiEndpoint,
|
|
9189
|
-
headers: props.headers || {},
|
|
9239
|
+
headers: typeof props.headers === "function" ? props.headers() : props.headers || {},
|
|
9190
9240
|
properties: props.properties || {},
|
|
9191
9241
|
transcribeAudioUrl: props.transcribeAudioUrl,
|
|
9192
9242
|
textToSpeechUrl: props.textToSpeechUrl,
|
|
@@ -9826,6 +9876,12 @@ Object.defineProperty(exports, 'useAttachments', {
|
|
|
9826
9876
|
return useAttachments;
|
|
9827
9877
|
}
|
|
9828
9878
|
});
|
|
9879
|
+
Object.defineProperty(exports, 'useCapabilities', {
|
|
9880
|
+
enumerable: true,
|
|
9881
|
+
get: function () {
|
|
9882
|
+
return useCapabilities;
|
|
9883
|
+
}
|
|
9884
|
+
});
|
|
9829
9885
|
Object.defineProperty(exports, 'useCoAgentStateRenders', {
|
|
9830
9886
|
enumerable: true,
|
|
9831
9887
|
get: function () {
|
|
@@ -9946,4 +10002,4 @@ Object.defineProperty(exports, 'useToast', {
|
|
|
9946
10002
|
return useToast;
|
|
9947
10003
|
}
|
|
9948
10004
|
});
|
|
9949
|
-
//# sourceMappingURL=copilotkit-
|
|
10005
|
+
//# sourceMappingURL=copilotkit-Cvb6WpAX.cjs.map
|