@copilotkit/react-core 1.70.1 → 1.70.3
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-DiUK2Bhq.mjs → copilotkit-Ap_yisA5.mjs} +470 -98
- package/dist/copilotkit-Ap_yisA5.mjs.map +1 -0
- package/dist/{copilotkit-CxLT6zFx.cjs → copilotkit-BU3OvveB.cjs} +468 -96
- package/dist/copilotkit-BU3OvveB.cjs.map +1 -0
- package/dist/{copilotkit-DsWuxPUQ.d.mts → copilotkit-Bs98akp9.d.mts} +32 -2
- package/dist/{copilotkit-DsWuxPUQ.d.mts.map → copilotkit-Bs98akp9.d.mts.map} +1 -1
- package/dist/{copilotkit-CtF2clxZ.d.cts → copilotkit-X2eGbOwf.d.cts} +32 -2
- package/dist/{copilotkit-CtF2clxZ.d.cts.map → copilotkit-X2eGbOwf.d.cts.map} +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +273 -15
- package/dist/index.umd.js.map +1 -1
- package/dist/v2/headless.cjs +97 -2
- package/dist/v2/headless.cjs.map +1 -1
- package/dist/v2/headless.d.cts.map +1 -1
- package/dist/v2/headless.d.mts.map +1 -1
- package/dist/v2/headless.mjs +98 -3
- package/dist/v2/headless.mjs.map +1 -1
- package/dist/v2/index.cjs +1 -1
- package/dist/v2/index.css +1 -1
- package/dist/v2/index.d.cts +1 -1
- package/dist/v2/index.d.mts +1 -1
- package/dist/v2/index.mjs +1 -1
- package/dist/v2/index.umd.js +468 -96
- package/dist/v2/index.umd.js.map +1 -1
- package/package.json +7 -7
- package/skills/react-core/SKILL.md +1 -1
- package/skills/react-core/references/attachments.md +20 -0
- package/dist/copilotkit-CxLT6zFx.cjs.map +0 -1
- package/dist/copilotkit-DiUK2Bhq.mjs.map +0 -1
package/dist/v2/headless.cjs
CHANGED
|
@@ -281,6 +281,62 @@ const CopilotChatConfigurationProvider = ({ children, labels, agentId, threadId,
|
|
|
281
281
|
const useCopilotChatConfiguration = () => {
|
|
282
282
|
return (0, react.useContext)(CopilotChatConfiguration);
|
|
283
283
|
};
|
|
284
|
+
/**
|
|
285
|
+
* Reports modal open/close requests to the host, and — when `open` is
|
|
286
|
+
* supplied — makes the modal state of an already-established chat
|
|
287
|
+
* configuration **controlled** for the subtree it wraps.
|
|
288
|
+
*
|
|
289
|
+
* This is deliberately a scope component rather than another mode inside
|
|
290
|
+
* {@link CopilotChatConfigurationProvider}. The provider resolves modal state
|
|
291
|
+
* across a nested chain (own state, parent sync, drawer mutual-exclusion, the
|
|
292
|
+
* modal-closer registry); a controlled branch inside that resolution would add
|
|
293
|
+
* a fourth interacting mode. Overriding the context for the subtree instead
|
|
294
|
+
* leaves every one of those paths untouched:
|
|
295
|
+
*
|
|
296
|
+
* - `isModalOpen` is replaced with the host's `open`, so the rendered surface
|
|
297
|
+
* follows the prop from the very first frame (no open-then-close flash).
|
|
298
|
+
* - `setModalOpen` still calls the underlying setter, so the existing
|
|
299
|
+
* parent-sync and drawer mutual-exclusion side effects continue to run, and
|
|
300
|
+
* *then* reports the request through `onOpenChange`.
|
|
301
|
+
* - The wrapped setter is registered as the modal closer, so the drawer's
|
|
302
|
+
* mobile mutual-exclusion reaches the host instead of silently flipping
|
|
303
|
+
* state that nothing displays.
|
|
304
|
+
*
|
|
305
|
+
* A host that supplies `open` and ignores `onOpenChange` gets a modal pinned
|
|
306
|
+
* to `open`, which is the standard controlled-component contract. A host that
|
|
307
|
+
* supplies only `onOpenChange` is notified while the modal keeps managing
|
|
308
|
+
* itself.
|
|
309
|
+
*
|
|
310
|
+
* Renders `children` unchanged when no chat configuration is in scope.
|
|
311
|
+
*/
|
|
312
|
+
const ControlledModalOpenScope = ({ children, open, onOpenChange }) => {
|
|
313
|
+
const parentConfig = (0, react.useContext)(CopilotChatConfiguration);
|
|
314
|
+
const parentSetModalOpen = parentConfig?.setModalOpen;
|
|
315
|
+
const registerModalCloser = parentConfig?.ɵregisterModalCloser;
|
|
316
|
+
const setModalOpen = (0, react.useCallback)((next) => {
|
|
317
|
+
parentSetModalOpen?.(next);
|
|
318
|
+
onOpenChange?.(next);
|
|
319
|
+
}, [parentSetModalOpen, onOpenChange]);
|
|
320
|
+
(0, react.useEffect)(() => {
|
|
321
|
+
if (!registerModalCloser) return;
|
|
322
|
+
return registerModalCloser(setModalOpen);
|
|
323
|
+
}, [registerModalCloser, setModalOpen]);
|
|
324
|
+
const configurationValue = (0, react.useMemo)(() => parentConfig ? {
|
|
325
|
+
...parentConfig,
|
|
326
|
+
isModalOpen: open ?? parentConfig.isModalOpen,
|
|
327
|
+
setModalOpen
|
|
328
|
+
} : null, [
|
|
329
|
+
parentConfig,
|
|
330
|
+
open,
|
|
331
|
+
setModalOpen
|
|
332
|
+
]);
|
|
333
|
+
if (!configurationValue) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children });
|
|
334
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotChatConfiguration.Provider, {
|
|
335
|
+
value: configurationValue,
|
|
336
|
+
children
|
|
337
|
+
});
|
|
338
|
+
};
|
|
339
|
+
ControlledModalOpenScope.displayName = "ControlledModalOpenScope";
|
|
284
340
|
|
|
285
341
|
//#endregion
|
|
286
342
|
//#region src/v2/hooks/use-agent.tsx
|
|
@@ -1522,6 +1578,29 @@ const ToolCallRenderer = react.default.memo(function ToolCallRenderer({ toolCall
|
|
|
1522
1578
|
if (prevProps.RenderComponent !== nextProps.RenderComponent) return false;
|
|
1523
1579
|
return true;
|
|
1524
1580
|
});
|
|
1581
|
+
const IS_DEVELOPMENT = process.env.NODE_ENV !== "production";
|
|
1582
|
+
/**
|
|
1583
|
+
* Reports tool calls that resolved to no renderer.
|
|
1584
|
+
*
|
|
1585
|
+
* A tool call with no renderer paints an empty message container and says
|
|
1586
|
+
* nothing else, so the only signal a developer gets today is a blank space in
|
|
1587
|
+
* the chat. This names the call and the renderers that *are* registered, which
|
|
1588
|
+
* is the whole diagnosis when the cause is a name that does not match.
|
|
1589
|
+
*
|
|
1590
|
+
* @param toolNames - The unmatched tool names collected during render.
|
|
1591
|
+
* @param registered - The registry as it stands now, re-read at report time.
|
|
1592
|
+
* @param alreadyWarned - Names already reported, mutated to keep this once per name.
|
|
1593
|
+
*/
|
|
1594
|
+
function warnAboutUnrenderedToolCalls(toolNames, registered, alreadyWarned) {
|
|
1595
|
+
const registeredNames = Array.from(new Set(registered.map((rc) => rc.name)));
|
|
1596
|
+
const hasWildcard = registeredNames.includes("*");
|
|
1597
|
+
for (const toolName of toolNames) {
|
|
1598
|
+
if (hasWildcard || registeredNames.includes(toolName)) continue;
|
|
1599
|
+
if (alreadyWarned.has(toolName)) continue;
|
|
1600
|
+
alreadyWarned.add(toolName);
|
|
1601
|
+
console.warn(`[CopilotKit] The agent called the tool "${toolName}", and no renderer is registered for it, so that message rendered nothing. ` + (registeredNames.length === 0 ? "No tool-call renderers are registered. " : `Registered renderers: ${registeredNames.map((name) => `"${name}"`).join(", ")}. `) + `Register one with useRenderTool({ name: "${toolName}", ... }), or call useDefaultRenderTool() for a built-in card that covers every tool the agent calls. This warning is development-only.`);
|
|
1602
|
+
}
|
|
1603
|
+
}
|
|
1525
1604
|
/**
|
|
1526
1605
|
* Hook that returns a function to render tool calls based on the render functions
|
|
1527
1606
|
* defined in CopilotKitProvider.
|
|
@@ -1531,13 +1610,18 @@ const ToolCallRenderer = react.default.memo(function ToolCallRenderer({ toolCall
|
|
|
1531
1610
|
function useRenderToolCall() {
|
|
1532
1611
|
const { copilotkit, executingToolCallIds } = (0, _copilotkit_react_core_v2_context.useCopilotKit)();
|
|
1533
1612
|
const agentId = useCopilotChatConfiguration()?.agentId ?? _copilotkit_shared.DEFAULT_AGENT_ID;
|
|
1613
|
+
const unrenderedToolNames = (0, react.useRef)(/* @__PURE__ */ new Set());
|
|
1614
|
+
const warnedToolNames = (0, react.useRef)(/* @__PURE__ */ new Set());
|
|
1534
1615
|
const renderToolCalls = (0, react.useSyncExternalStore)((callback) => {
|
|
1535
1616
|
return copilotkit.subscribe({ onRenderToolCallsChanged: callback }).unsubscribe;
|
|
1536
1617
|
}, () => copilotkit.renderToolCalls, () => copilotkit.renderToolCalls);
|
|
1537
|
-
|
|
1618
|
+
const renderToolCall = (0, react.useCallback)(({ toolCall, toolMessage }) => {
|
|
1538
1619
|
const exactMatches = renderToolCalls.filter((rc) => rc.name === toolCall.function.name);
|
|
1539
1620
|
const renderConfig = exactMatches.find((rc) => rc.agentId === agentId) || exactMatches.find((rc) => !rc.agentId) || exactMatches[0] || renderToolCalls.find((rc) => rc.name === "*");
|
|
1540
|
-
if (!renderConfig)
|
|
1621
|
+
if (!renderConfig) {
|
|
1622
|
+
if (IS_DEVELOPMENT) unrenderedToolNames.current.add(toolCall.function.name);
|
|
1623
|
+
return null;
|
|
1624
|
+
}
|
|
1541
1625
|
const RenderComponent = renderConfig.render;
|
|
1542
1626
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolCallRenderer, {
|
|
1543
1627
|
toolCall,
|
|
@@ -1550,6 +1634,17 @@ function useRenderToolCall() {
|
|
|
1550
1634
|
executingToolCallIds,
|
|
1551
1635
|
agentId
|
|
1552
1636
|
]);
|
|
1637
|
+
(0, react.useEffect)(() => {
|
|
1638
|
+
if (!IS_DEVELOPMENT) return;
|
|
1639
|
+
if (unrenderedToolNames.current.size === 0) return;
|
|
1640
|
+
const timer = setTimeout(() => {
|
|
1641
|
+
const pending = Array.from(unrenderedToolNames.current);
|
|
1642
|
+
unrenderedToolNames.current.clear();
|
|
1643
|
+
warnAboutUnrenderedToolCalls(pending, copilotkit.renderToolCalls, warnedToolNames.current);
|
|
1644
|
+
}, 0);
|
|
1645
|
+
return () => clearTimeout(timer);
|
|
1646
|
+
});
|
|
1647
|
+
return renderToolCall;
|
|
1553
1648
|
}
|
|
1554
1649
|
|
|
1555
1650
|
//#endregion
|