@copilotkit/react-core 1.79.2-canary.1792172552 → 1.80.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-DcENKLnJ.mjs → copilotkit-BNLtgOyD.mjs} +1783 -238
- package/dist/copilotkit-BNLtgOyD.mjs.map +1 -0
- package/dist/{copilotkit-kcYN96tM.d.mts → copilotkit-CWOSXhRO.d.mts} +278 -41
- package/dist/copilotkit-CWOSXhRO.d.mts.map +1 -0
- package/dist/{copilotkit-ConxFSB2.cjs → copilotkit-DKICi3nC.cjs} +1764 -206
- package/dist/copilotkit-DKICi3nC.cjs.map +1 -0
- package/dist/{copilotkit-BA0vyDds.d.cts → copilotkit-Dfw9HzO9.d.cts} +278 -41
- package/dist/copilotkit-Dfw9HzO9.d.cts.map +1 -0
- package/dist/index.cjs +15 -3
- 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 +15 -3
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +48 -11
- package/dist/index.umd.js.map +1 -1
- package/dist/v2/context.d.cts +7 -0
- package/dist/v2/context.d.cts.map +1 -1
- package/dist/v2/context.d.mts +7 -0
- package/dist/v2/context.d.mts.map +1 -1
- package/dist/v2/headless.cjs +23 -6
- package/dist/v2/headless.cjs.map +1 -1
- package/dist/v2/headless.d.cts +20 -2
- package/dist/v2/headless.d.cts.map +1 -1
- package/dist/v2/headless.d.mts +20 -2
- package/dist/v2/headless.d.mts.map +1 -1
- package/dist/v2/headless.mjs +23 -6
- package/dist/v2/headless.mjs.map +1 -1
- package/dist/v2/index.cjs +3 -7
- package/dist/v2/index.css +1 -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 +1756 -215
- package/dist/v2/index.umd.js.map +1 -1
- package/package.json +14 -11
- package/dist/copilotkit-BA0vyDds.d.cts.map +0 -1
- package/dist/copilotkit-ConxFSB2.cjs.map +0 -1
- package/dist/copilotkit-DcENKLnJ.mjs.map +0 -1
- package/dist/copilotkit-kcYN96tM.d.mts.map +0 -1
package/dist/v2/index.umd.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
(function(global, factory) {
|
|
4
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('./index.css'), require('@copilotkit/core'), require('@ag-ui/client'), require('react'), require('tailwind-merge'), require('lucide-react'), require('@copilotkit/shared'), require('react/jsx-runtime'), require('@radix-ui/react-slot'), require('class-variance-authority'), require('clsx'), require('@radix-ui/react-tooltip'), require('@radix-ui/react-dropdown-menu'), require('streamdown'), require('@ag-ui/core'), require('zod'), require('@copilotkit/mcp-apps-renderer/activity'), require('@copilotkit/a2ui-renderer'), require('zod-to-json-schema'), require('react-dom'), require('@tanstack/react-virtual'), require('use-stick-to-bottom'), require('@copilotkit/web-components/threads-drawer')) :
|
|
5
|
-
typeof define === 'function' && define.amd ? define(['exports', './index.css', '@copilotkit/core', '@ag-ui/client', 'react', 'tailwind-merge', 'lucide-react', '@copilotkit/shared', 'react/jsx-runtime', '@radix-ui/react-slot', 'class-variance-authority', 'clsx', '@radix-ui/react-tooltip', '@radix-ui/react-dropdown-menu', 'streamdown', '@ag-ui/core', 'zod', '@copilotkit/mcp-apps-renderer/activity', '@copilotkit/a2ui-renderer', 'zod-to-json-schema', 'react-dom', '@tanstack/react-virtual', 'use-stick-to-bottom', '@copilotkit/web-components/threads-drawer'], factory) :
|
|
6
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.CopilotKitReactCoreV2 = {}), global.src_v2_index_css,global.CopilotKitCore,global.AgUIClient,global.React,global.tailwindMerge,global.lucideReact,global.CopilotKitShared,global.ReactJsxRuntime,global.RadixReactSlot,global.classVarianceAuthority,global.clsx,global.RadixReactTooltip,global.RadixReactDropdownMenu,global.streamdown,global.AgUICore,global.Zod,global.CopilotKitMcpAppsRendererActivity,global.CopilotKitA2UIRenderer,global.zod_to_json_schema,global.ReactDOM,global._tanstack_react_virtual,global.useStickToBottom,global._copilotkit_web_components_threads_drawer));
|
|
7
|
-
})(this, function(exports, src_v2_index_css, _copilotkit_core, _ag_ui_client, react, tailwind_merge, lucide_react, _copilotkit_shared, react_jsx_runtime, _radix_ui_react_slot, class_variance_authority, clsx, _radix_ui_react_tooltip, _radix_ui_react_dropdown_menu, streamdown, _ag_ui_core, zod, _copilotkit_mcp_apps_renderer_activity, _copilotkit_a2ui_renderer, zod_to_json_schema, react_dom, _tanstack_react_virtual, use_stick_to_bottom, _copilotkit_web_components_threads_drawer) {
|
|
4
|
+
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('./index.css'), require('@copilotkit/core'), require('@ag-ui/client'), require('react'), require('tailwind-merge'), require('lucide-react'), require('@copilotkit/shared'), require('react/jsx-runtime'), require('@radix-ui/react-slot'), require('class-variance-authority'), require('clsx'), require('@radix-ui/react-tooltip'), require('@radix-ui/react-dropdown-menu'), require('streamdown'), require('@ag-ui/core'), require('zod'), require('@copilotkit/mcp-apps-renderer/activity'), require('@copilotkit/a2ui-renderer'), require('zod-to-json-schema'), require('@radix-ui/react-popover'), require('react-dom'), require('@tanstack/react-virtual'), require('use-stick-to-bottom'), require('@copilotkit/web-components/threads-drawer')) :
|
|
5
|
+
typeof define === 'function' && define.amd ? define(['exports', './index.css', '@copilotkit/core', '@ag-ui/client', 'react', 'tailwind-merge', 'lucide-react', '@copilotkit/shared', 'react/jsx-runtime', '@radix-ui/react-slot', 'class-variance-authority', 'clsx', '@radix-ui/react-tooltip', '@radix-ui/react-dropdown-menu', 'streamdown', '@ag-ui/core', 'zod', '@copilotkit/mcp-apps-renderer/activity', '@copilotkit/a2ui-renderer', 'zod-to-json-schema', '@radix-ui/react-popover', 'react-dom', '@tanstack/react-virtual', 'use-stick-to-bottom', '@copilotkit/web-components/threads-drawer'], factory) :
|
|
6
|
+
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.CopilotKitReactCoreV2 = {}), global.src_v2_index_css,global.CopilotKitCore,global.AgUIClient,global.React,global.tailwindMerge,global.lucideReact,global.CopilotKitShared,global.ReactJsxRuntime,global.RadixReactSlot,global.classVarianceAuthority,global.clsx,global.RadixReactTooltip,global.RadixReactDropdownMenu,global.streamdown,global.AgUICore,global.Zod,global.CopilotKitMcpAppsRendererActivity,global.CopilotKitA2UIRenderer,global.zod_to_json_schema,global._radix_ui_react_popover,global.ReactDOM,global._tanstack_react_virtual,global.useStickToBottom,global._copilotkit_web_components_threads_drawer));
|
|
7
|
+
})(this, function(exports, src_v2_index_css, _copilotkit_core, _ag_ui_client, react, tailwind_merge, lucide_react, _copilotkit_shared, react_jsx_runtime, _radix_ui_react_slot, class_variance_authority, clsx, _radix_ui_react_tooltip, _radix_ui_react_dropdown_menu, streamdown, _ag_ui_core, zod, _copilotkit_mcp_apps_renderer_activity, _copilotkit_a2ui_renderer, zod_to_json_schema, _radix_ui_react_popover, react_dom, _tanstack_react_virtual, use_stick_to_bottom, _copilotkit_web_components_threads_drawer) {
|
|
8
8
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
9
9
|
//#region \0rolldown/runtime.js
|
|
10
10
|
var __create = Object.create;
|
|
@@ -36,6 +36,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
36
36
|
react = __toESM(react);
|
|
37
37
|
_radix_ui_react_tooltip = __toESM(_radix_ui_react_tooltip);
|
|
38
38
|
_radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
39
|
+
_radix_ui_react_popover = __toESM(_radix_ui_react_popover);
|
|
39
40
|
|
|
40
41
|
//#region src/v2/lib/react-core.ts
|
|
41
42
|
var CopilotKitCoreReact = class extends _copilotkit_core.CopilotKitCore {
|
|
@@ -215,6 +216,8 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
215
216
|
chatInputToolbarFinishTranscribeButtonLabel: "Finish",
|
|
216
217
|
chatInputToolbarAddButtonLabel: "Add attachments",
|
|
217
218
|
chatInputToolbarToolsButtonLabel: "Tools",
|
|
219
|
+
chatInputToolbarSendButtonLabel: "Send message",
|
|
220
|
+
chatInputToolbarStopButtonLabel: "Stop",
|
|
218
221
|
assistantMessageToolbarCopyCodeLabel: "Copy",
|
|
219
222
|
assistantMessageToolbarCopyCodeCopiedLabel: "Copied",
|
|
220
223
|
assistantMessageToolbarCopyMessageLabel: "Copy",
|
|
@@ -227,13 +230,18 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
227
230
|
assistantMessageToolbarInspectorHideDescription: "Until you reload this page",
|
|
228
231
|
assistantMessageToolbarThumbsUpLabel: "Good response",
|
|
229
232
|
assistantMessageToolbarThumbsDownLabel: "Bad response",
|
|
233
|
+
assistantMessageFeedbackCommentPlaceholder: "Add a comment (optional)",
|
|
234
|
+
assistantMessageFeedbackCommentSubmitLabel: "Send comment",
|
|
230
235
|
assistantMessageToolbarReadAloudLabel: "Read aloud",
|
|
231
236
|
assistantMessageToolbarRegenerateLabel: "Regenerate",
|
|
232
237
|
userMessageToolbarCopyMessageLabel: "Copy",
|
|
233
238
|
userMessageToolbarEditMessageLabel: "Edit",
|
|
239
|
+
userMessageToolbarPreviousBranchLabel: "Previous branch",
|
|
240
|
+
userMessageToolbarNextBranchLabel: "Next branch",
|
|
234
241
|
chatDisclaimerText: "AI can make mistakes. Please verify important information.",
|
|
235
242
|
chatToggleOpenLabel: "Open chat",
|
|
236
243
|
chatToggleCloseLabel: "Close chat",
|
|
244
|
+
chatScrollToBottomLabel: "Scroll to bottom",
|
|
237
245
|
modalHeaderTitle: "CopilotKit Chat",
|
|
238
246
|
welcomeMessageText: "How can I help you today?"
|
|
239
247
|
};
|
|
@@ -495,9 +503,9 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
495
503
|
|
|
496
504
|
//#endregion
|
|
497
505
|
//#region src/v2/lib/utils.ts
|
|
498
|
-
const twMerge$
|
|
506
|
+
const twMerge$12 = (0, tailwind_merge.extendTailwindMerge)({ prefix: "cpk" });
|
|
499
507
|
function cn(...inputs) {
|
|
500
|
-
return twMerge$
|
|
508
|
+
return twMerge$12((0, clsx.clsx)(inputs));
|
|
501
509
|
}
|
|
502
510
|
|
|
503
511
|
//#endregion
|
|
@@ -945,6 +953,11 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
945
953
|
//#region src/v2/components/chat/CopilotChatInput.tsx
|
|
946
954
|
const SLASH_MENU_MAX_VISIBLE_ITEMS = 5;
|
|
947
955
|
const SLASH_MENU_ITEM_HEIGHT_PX = 40;
|
|
956
|
+
/**
|
|
957
|
+
* The chat composer: a text area with the add-menu, voice and send/stop
|
|
958
|
+
* buttons, and a slash-command menu that lists `toolsMenu` items once the text
|
|
959
|
+
* starts with "/".
|
|
960
|
+
*/
|
|
948
961
|
function CopilotChatInput({ mode = "input", onSubmitMessage, onStop, isRunning = false, onStartTranscribe, onCancelTranscribe, onFinishTranscribe, onFinishTranscribeWithAudio, onAddFile, onChange, value, toolsMenu, autoFocus = false, positioning = "static", keyboardHeight = 0, containerRef, showDisclaimer, bottomAnchored = false, textArea, sendButton, startTranscribeButton, cancelTranscribeButton, finishTranscribeButton, addMenuButton, audioRecorder, disclaimer, children, className, ...props }) {
|
|
949
962
|
const isControlled = value !== void 0;
|
|
950
963
|
const [internalValue, setInternalValue] = (0, react.useState)(() => value ?? "");
|
|
@@ -1164,10 +1177,12 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
1164
1177
|
send();
|
|
1165
1178
|
};
|
|
1166
1179
|
const BoundAudioRecorder = renderSlot(audioRecorder, CopilotChatAudioRecorder, { ref: audioRecorderRef });
|
|
1180
|
+
const showsStop = isProcessing && canStop;
|
|
1167
1181
|
const BoundSendButton = renderSlot(sendButton, CopilotChatInput.SendButton, {
|
|
1168
1182
|
onClick: handleSendButtonClick,
|
|
1169
1183
|
disabled: isProcessing ? !canStop : !canSend,
|
|
1170
|
-
|
|
1184
|
+
"aria-label": showsStop ? labels.chatInputToolbarStopButtonLabel : labels.chatInputToolbarSendButtonLabel,
|
|
1185
|
+
children: showsStop ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Square, { className: "cpk:size-[18px] cpk:fill-current" }) : void 0
|
|
1171
1186
|
});
|
|
1172
1187
|
const BoundStartTranscribeButton = renderSlot(startTranscribeButton, CopilotChatInput.StartTranscribeButton, { onClick: onStartTranscribe });
|
|
1173
1188
|
const BoundCancelTranscribeButton = renderSlot(cancelTranscribeButton, CopilotChatInput.CancelTranscribeButton, { onClick: onCancelTranscribe });
|
|
@@ -1479,18 +1494,22 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
1479
1494
|
});
|
|
1480
1495
|
}
|
|
1481
1496
|
(function(_CopilotChatInput) {
|
|
1482
|
-
_CopilotChatInput.SendButton = ({ className, children, ...props }) =>
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1497
|
+
_CopilotChatInput.SendButton = ({ className, children, ...props }) => {
|
|
1498
|
+
const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
|
|
1499
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1500
|
+
className: "cpk:mr-[10px]",
|
|
1501
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
|
|
1502
|
+
type: "button",
|
|
1503
|
+
"data-testid": "copilot-send-button",
|
|
1504
|
+
variant: "chatInputToolbarPrimary",
|
|
1505
|
+
size: "chatInputToolbarIcon",
|
|
1506
|
+
className,
|
|
1507
|
+
"aria-label": labels.chatInputToolbarSendButtonLabel,
|
|
1508
|
+
...props,
|
|
1509
|
+
children: children ?? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ArrowUp, { className: "cpk:size-[18px]" })
|
|
1510
|
+
})
|
|
1511
|
+
});
|
|
1512
|
+
};
|
|
1494
1513
|
const ToolbarButton = _CopilotChatInput.ToolbarButton = ({ icon, labelKey, defaultClassName, className, ...props }) => {
|
|
1495
1514
|
const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
|
|
1496
1515
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Tooltip, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(TooltipTrigger, {
|
|
@@ -1500,6 +1519,7 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
1500
1519
|
variant: "chatInputToolbarSecondary",
|
|
1501
1520
|
size: "chatInputToolbarIcon",
|
|
1502
1521
|
className: (0, tailwind_merge.twMerge)(defaultClassName, className),
|
|
1522
|
+
"aria-label": labels[labelKey],
|
|
1503
1523
|
...props,
|
|
1504
1524
|
children: icon
|
|
1505
1525
|
})
|
|
@@ -1570,6 +1590,7 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
1570
1590
|
size: "chatInputToolbarIcon",
|
|
1571
1591
|
className: (0, tailwind_merge.twMerge)("cpk:ml-1", className),
|
|
1572
1592
|
disabled: isDisabled,
|
|
1593
|
+
"aria-label": labels.chatInputToolbarAddButtonLabel,
|
|
1573
1594
|
...props,
|
|
1574
1595
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Plus, { className: "cpk:size-[20px]" })
|
|
1575
1596
|
});
|
|
@@ -1719,6 +1740,32 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
1719
1740
|
}
|
|
1720
1741
|
}
|
|
1721
1742
|
/**
|
|
1743
|
+
* The tool-call renderers registered on the provider, kept current.
|
|
1744
|
+
* @internal
|
|
1745
|
+
*/
|
|
1746
|
+
function useToolCallRenderers() {
|
|
1747
|
+
const { copilotkit } = useCopilotKit();
|
|
1748
|
+
return (0, react.useSyncExternalStore)((callback) => copilotkit.subscribe({ onRenderToolCallsChanged: callback }).unsubscribe, () => copilotkit.renderToolCalls, () => copilotkit.renderToolCalls);
|
|
1749
|
+
}
|
|
1750
|
+
/**
|
|
1751
|
+
* Which tool names have a renderer of their own, whether a wildcard (`"*"`)
|
|
1752
|
+
* renderer is registered, and which of them opted into grouping.
|
|
1753
|
+
* @internal
|
|
1754
|
+
*/
|
|
1755
|
+
function useToolCallRendererNames() {
|
|
1756
|
+
const renderers = useToolCallRenderers();
|
|
1757
|
+
return (0, react.useMemo)(() => {
|
|
1758
|
+
const named = renderers.filter((rc) => rc.name !== "*");
|
|
1759
|
+
const wildcards = renderers.filter((rc) => rc.name === "*");
|
|
1760
|
+
return {
|
|
1761
|
+
named: new Set(named.map((rc) => rc.name)),
|
|
1762
|
+
groupedNames: new Set(named.filter((rc) => rc.group).map((rc) => rc.name)),
|
|
1763
|
+
wildcard: wildcards.length > 0,
|
|
1764
|
+
wildcardGroups: wildcards.some((rc) => rc.group)
|
|
1765
|
+
};
|
|
1766
|
+
}, [renderers]);
|
|
1767
|
+
}
|
|
1768
|
+
/**
|
|
1722
1769
|
* Hook that returns a function to render tool calls based on the render functions
|
|
1723
1770
|
* defined in CopilotKitProvider.
|
|
1724
1771
|
*
|
|
@@ -1729,9 +1776,7 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
1729
1776
|
const agentId = useCopilotChatConfiguration()?.agentId ?? _copilotkit_shared.DEFAULT_AGENT_ID;
|
|
1730
1777
|
const unrenderedToolNames = (0, react.useRef)(/* @__PURE__ */ new Set());
|
|
1731
1778
|
const warnedToolNames = (0, react.useRef)(/* @__PURE__ */ new Set());
|
|
1732
|
-
const renderToolCalls = (
|
|
1733
|
-
return copilotkit.subscribe({ onRenderToolCallsChanged: callback }).unsubscribe;
|
|
1734
|
-
}, () => copilotkit.renderToolCalls, () => copilotkit.renderToolCalls);
|
|
1779
|
+
const renderToolCalls = useToolCallRenderers();
|
|
1735
1780
|
const renderToolCall = (0, react.useCallback)(({ toolCall, toolMessage }) => {
|
|
1736
1781
|
const exactMatches = renderToolCalls.filter((rc) => rc.name === toolCall.function.name);
|
|
1737
1782
|
const renderConfig = exactMatches.find((rc) => rc.agentId === agentId) || exactMatches.find((rc) => !rc.agentId) || exactMatches[0] || renderToolCalls.find((rc) => rc.name === "*");
|
|
@@ -1766,7 +1811,7 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
1766
1811
|
|
|
1767
1812
|
//#endregion
|
|
1768
1813
|
//#region package.json
|
|
1769
|
-
var version = "1.
|
|
1814
|
+
var version = "1.80.0";
|
|
1770
1815
|
|
|
1771
1816
|
//#endregion
|
|
1772
1817
|
//#region src/v2/components/CopilotKitInspector.tsx
|
|
@@ -2002,7 +2047,7 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
2002
2047
|
* Fetches resource content on-demand via proxied MCP requests. The React shell
|
|
2003
2048
|
* owns the iframe; `bindMcpApp` owns the protocol.
|
|
2004
2049
|
*/
|
|
2005
|
-
const MCPAppsActivityRenderer = function MCPAppsActivityRenderer({ content, message, agent }) {
|
|
2050
|
+
const MCPAppsActivityRenderer = function MCPAppsActivityRenderer({ content, message, agent, allowSameOriginFallback }) {
|
|
2006
2051
|
const { copilotkit } = useCopilotKit();
|
|
2007
2052
|
const messageId = message?.id;
|
|
2008
2053
|
const containerRef = (0, react.useRef)(null);
|
|
@@ -2052,6 +2097,7 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
2052
2097
|
getAgent: () => agentRef.current,
|
|
2053
2098
|
host: copilotkit,
|
|
2054
2099
|
messageId,
|
|
2100
|
+
options: { allowSameOriginFallback },
|
|
2055
2101
|
hooks: {
|
|
2056
2102
|
onResource: (resource) => {
|
|
2057
2103
|
if (!mounted) return;
|
|
@@ -2093,6 +2139,7 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
2093
2139
|
agent,
|
|
2094
2140
|
copilotkit,
|
|
2095
2141
|
messageId,
|
|
2142
|
+
allowSameOriginFallback,
|
|
2096
2143
|
content.resourceUri,
|
|
2097
2144
|
content.serverHash,
|
|
2098
2145
|
content.serverId
|
|
@@ -3307,7 +3354,8 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
3307
3354
|
name: def.name,
|
|
3308
3355
|
args: argsSchema,
|
|
3309
3356
|
render: def.render,
|
|
3310
|
-
...def.agentId ? { agentId: def.agentId } : {}
|
|
3357
|
+
...def.agentId ? { agentId: def.agentId } : {},
|
|
3358
|
+
...def.group ? { group: true } : {}
|
|
3311
3359
|
};
|
|
3312
3360
|
}
|
|
3313
3361
|
|
|
@@ -3427,6 +3475,11 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
3427
3475
|
- Use CSS Grid or Flexbox for layout. Ensure the UI looks good at any width.
|
|
3428
3476
|
- Minimal transitions (150ms) for hover/focus states only. No decorative animations.
|
|
3429
3477
|
- Keep the UI focused and dense — avoid excessive padding. Use compact spacing (8–12px gaps, 10–14px padding in controls).`;
|
|
3478
|
+
/** The MCP Apps renderer with `mcpApps.allowSameOriginFallback` applied. */
|
|
3479
|
+
const SameOriginMCPAppsActivityRenderer = (props) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MCPAppsActivityRenderer, {
|
|
3480
|
+
...props,
|
|
3481
|
+
allowSameOriginFallback: true
|
|
3482
|
+
});
|
|
3430
3483
|
const DEFAULT_LEARNING = Object.freeze({});
|
|
3431
3484
|
function toLearningConfig(learning) {
|
|
3432
3485
|
if (learning === true) return DEFAULT_LEARNING;
|
|
@@ -3443,7 +3496,8 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
3443
3496
|
}, [value, warningMessage]);
|
|
3444
3497
|
return value;
|
|
3445
3498
|
}
|
|
3446
|
-
|
|
3499
|
+
/** Provide a shared core instance and synchronize runtime, tool, and UI configuration. */
|
|
3500
|
+
const CopilotKitProvider = ({ children, runtimeUrl, headers: headersProp = EMPTY_HEADERS, credentials, messageFilter, publicApiKey, publicLicenseKey, licenseToken, properties = EMPTY_PROPERTIES, agents__unsafe_dev_only: agents = EMPTY_AGENTS, selfManagedAgents = EMPTY_AGENTS, renderToolCalls, renderActivityMessages, renderCustomMessages, frontendTools, humanInTheLoop, openGenerativeUI, enableInspector, agentId, showIntelligenceIndicator = true, useSingleEndpoint, onError, a2ui, mcpApps, defaultThrottleMs, debug, learning }) => {
|
|
3447
3501
|
const learningConfig = (0, react.useMemo)(() => toLearningConfig(learning), [learning]);
|
|
3448
3502
|
const [shouldRenderInspector, setShouldRenderInspector] = (0, react.useState)(false);
|
|
3449
3503
|
const [inspectorVisible, setInspectorVisible] = (0, react.useState)(false);
|
|
@@ -3500,11 +3554,12 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
3500
3554
|
const core = copilotkitRef.current;
|
|
3501
3555
|
return (0, _copilotkit_a2ui_renderer.filterCatalog)(rawCatalog, (name) => core ? core.isCatalogComponentEnabled(name) : true);
|
|
3502
3556
|
}, [rawCatalog, catalogToggleVersion]);
|
|
3557
|
+
const mcpAppsAllowSameOrigin = mcpApps?.allowSameOriginFallback === true;
|
|
3503
3558
|
const builtInActivityRenderers = (0, react.useMemo)(() => {
|
|
3504
3559
|
const renderers = [{
|
|
3505
3560
|
activityType: _copilotkit_mcp_apps_renderer_activity.MCPAppsActivityType,
|
|
3506
3561
|
content: _copilotkit_mcp_apps_renderer_activity.MCPAppsActivityContentSchema,
|
|
3507
|
-
render: MCPAppsActivityRenderer
|
|
3562
|
+
render: mcpAppsAllowSameOrigin ? SameOriginMCPAppsActivityRenderer : MCPAppsActivityRenderer
|
|
3508
3563
|
}];
|
|
3509
3564
|
if (openGenUIActive) renderers.push({
|
|
3510
3565
|
activityType: OpenGenerativeUIActivityType,
|
|
@@ -3522,7 +3577,8 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
3522
3577
|
a2uiActive,
|
|
3523
3578
|
openGenUIActive,
|
|
3524
3579
|
a2ui,
|
|
3525
|
-
filteredCatalog
|
|
3580
|
+
filteredCatalog,
|
|
3581
|
+
mcpAppsAllowSameOrigin
|
|
3526
3582
|
]);
|
|
3527
3583
|
const allActivityRenderers = (0, react.useMemo)(() => {
|
|
3528
3584
|
return [...renderActivityMessagesList, ...builtInActivityRenderers];
|
|
@@ -3630,6 +3686,7 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
3630
3686
|
description: _copilotkit_shared.GENERATE_SANDBOXED_UI_DESCRIPTION,
|
|
3631
3687
|
parameters: GenerateSandboxedUiArgsSchema,
|
|
3632
3688
|
handler: async () => "UI generated",
|
|
3689
|
+
reconnectBehavior: "resume-pending",
|
|
3633
3690
|
followUp: true,
|
|
3634
3691
|
render: OpenGenerativeUIToolRenderer
|
|
3635
3692
|
}];
|
|
@@ -4361,7 +4418,8 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
4361
4418
|
...props,
|
|
4362
4419
|
parameters: props.args
|
|
4363
4420
|
}),
|
|
4364
|
-
...config.agentId ? { agentId: config.agentId } : {}
|
|
4421
|
+
...config.agentId ? { agentId: config.agentId } : {},
|
|
4422
|
+
group: config.group
|
|
4365
4423
|
}) : defineToolCallRenderer({
|
|
4366
4424
|
name: config.name,
|
|
4367
4425
|
args: config.parameters,
|
|
@@ -4379,16 +4437,395 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
4379
4437
|
parameters: props.args
|
|
4380
4438
|
});
|
|
4381
4439
|
},
|
|
4382
|
-
...config.agentId ? { agentId: config.agentId } : {}
|
|
4440
|
+
...config.agentId ? { agentId: config.agentId } : {},
|
|
4441
|
+
group: config.group
|
|
4383
4442
|
});
|
|
4384
4443
|
copilotkit.addHookRenderToolCall(renderer);
|
|
4385
4444
|
}, [
|
|
4386
4445
|
config.name,
|
|
4446
|
+
config.group,
|
|
4387
4447
|
copilotkit,
|
|
4388
4448
|
depsVersion
|
|
4389
4449
|
]);
|
|
4390
4450
|
}
|
|
4391
4451
|
|
|
4452
|
+
//#endregion
|
|
4453
|
+
//#region src/v2/components/chat/CopilotChatToolCallGroup.tsx
|
|
4454
|
+
/**
|
|
4455
|
+
* Set by a group around the calls it shows, so CopilotKit's built-in tool card
|
|
4456
|
+
* draws itself as a compact row that fits the group instead of a card.
|
|
4457
|
+
* @internal
|
|
4458
|
+
*/
|
|
4459
|
+
const ToolCallGroupContext = (0, react.createContext)(null);
|
|
4460
|
+
/**
|
|
4461
|
+
* A call without a result is running only while the group is active: once
|
|
4462
|
+
* the run has moved on or ended, its result is never coming.
|
|
4463
|
+
*/
|
|
4464
|
+
const entryStatus = ({ toolMessage }, active) => toolMessage ? toolMessage.error ? "failed" : "done" : active ? "running" : "stopped";
|
|
4465
|
+
/** @internal */
|
|
4466
|
+
const statusLabels = {
|
|
4467
|
+
running: "Running",
|
|
4468
|
+
done: "Done",
|
|
4469
|
+
failed: "Failed",
|
|
4470
|
+
stopped: "Stopped"
|
|
4471
|
+
};
|
|
4472
|
+
/** The first non-empty string argument: usually a command, path or query. */
|
|
4473
|
+
function argumentPreview(parameters) {
|
|
4474
|
+
if (!parameters || typeof parameters !== "object") return void 0;
|
|
4475
|
+
return Object.values(parameters).find((v) => typeof v === "string" && v.trim().length > 0)?.replace(/\s+/g, " ");
|
|
4476
|
+
}
|
|
4477
|
+
const entryPreview = (entry) => argumentPreview((0, _copilotkit_shared.partialJSONParse)(entry.toolCall.function.arguments));
|
|
4478
|
+
/** "run_command ×2, read_file" */
|
|
4479
|
+
function toolNames(calls) {
|
|
4480
|
+
const counts = /* @__PURE__ */ new Map();
|
|
4481
|
+
for (const { toolCall } of calls) {
|
|
4482
|
+
const name = toolCall.function.name;
|
|
4483
|
+
counts.set(name, (counts.get(name) ?? 0) + 1);
|
|
4484
|
+
}
|
|
4485
|
+
return [...counts].map(([name, count]) => count > 1 ? `${name} ×${count}` : name).join(", ");
|
|
4486
|
+
}
|
|
4487
|
+
const pluralize = (count, noun) => `${count} ${noun}${count === 1 ? "" : "s"}`;
|
|
4488
|
+
/**
|
|
4489
|
+
* Height transition between closed and its content's height. Closed content
|
|
4490
|
+
* stays mounted (so its state survives) but is inert.
|
|
4491
|
+
* @internal
|
|
4492
|
+
*/
|
|
4493
|
+
function Collapsible({ open, id, className, children }) {
|
|
4494
|
+
const ref = (0, react.useRef)(null);
|
|
4495
|
+
(0, react.useLayoutEffect)(() => {
|
|
4496
|
+
ref.current?.toggleAttribute("inert", !open);
|
|
4497
|
+
}, [open]);
|
|
4498
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4499
|
+
ref,
|
|
4500
|
+
id,
|
|
4501
|
+
className: (0, tailwind_merge.twMerge)("cpk:grid cpk:transition-[grid-template-rows] cpk:duration-300 cpk:ease-[cubic-bezier(0.16,1,0.3,1)] cpk:motion-reduce:transition-none", className),
|
|
4502
|
+
style: { gridTemplateRows: open ? "1fr" : "0fr" },
|
|
4503
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4504
|
+
className: "cpk:min-h-0 cpk:overflow-hidden",
|
|
4505
|
+
children
|
|
4506
|
+
})
|
|
4507
|
+
});
|
|
4508
|
+
}
|
|
4509
|
+
function StatusIcon({ status, className }) {
|
|
4510
|
+
const Icon = {
|
|
4511
|
+
running: lucide_react.Loader2,
|
|
4512
|
+
done: lucide_react.Check,
|
|
4513
|
+
failed: lucide_react.X,
|
|
4514
|
+
stopped: lucide_react.Circle
|
|
4515
|
+
}[status];
|
|
4516
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, {
|
|
4517
|
+
"aria-hidden": "true",
|
|
4518
|
+
className: (0, tailwind_merge.twMerge)("cpk:size-3.5 cpk:shrink-0 cpk:text-muted-foreground", status === "running" && "cpk:animate-spin", status === "failed" && "cpk:text-destructive", className)
|
|
4519
|
+
});
|
|
4520
|
+
}
|
|
4521
|
+
function Chevron({ open, className }) {
|
|
4522
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronRight, {
|
|
4523
|
+
"aria-hidden": "true",
|
|
4524
|
+
className: (0, tailwind_merge.twMerge)("cpk:size-3.5 cpk:shrink-0 cpk:transition-transform cpk:duration-200", open && "cpk:rotate-90", className)
|
|
4525
|
+
});
|
|
4526
|
+
}
|
|
4527
|
+
function FailedCount({ calls }) {
|
|
4528
|
+
const failed = calls.filter((call) => call.toolMessage?.error).length;
|
|
4529
|
+
if (!failed) return null;
|
|
4530
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
4531
|
+
className: "cpk:shrink-0 cpk:text-destructive",
|
|
4532
|
+
children: [failed, " failed"]
|
|
4533
|
+
});
|
|
4534
|
+
}
|
|
4535
|
+
/**
|
|
4536
|
+
* Guarded JSON.stringify for the payload blocks. A circular reference would
|
|
4537
|
+
* otherwise crash the entire React tree on render.
|
|
4538
|
+
*/
|
|
4539
|
+
function stringifyPayload(value) {
|
|
4540
|
+
if (typeof value === "string") return value;
|
|
4541
|
+
try {
|
|
4542
|
+
return JSON.stringify(value, null, 2);
|
|
4543
|
+
} catch (err) {
|
|
4544
|
+
console.warn("[CopilotKit] Failed to JSON.stringify tool-call payload; falling back to String():", err);
|
|
4545
|
+
try {
|
|
4546
|
+
return String(value);
|
|
4547
|
+
} catch {
|
|
4548
|
+
return "[unserializable]";
|
|
4549
|
+
}
|
|
4550
|
+
}
|
|
4551
|
+
}
|
|
4552
|
+
function Payload({ label, value }) {
|
|
4553
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4554
|
+
className: "cpk:text-[11px] cpk:font-medium cpk:uppercase cpk:tracking-wide cpk:text-muted-foreground",
|
|
4555
|
+
children: label
|
|
4556
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
|
|
4557
|
+
className: "cpk:m-0 cpk:mt-1.5 cpk:max-h-[200px] cpk:overflow-auto cpk:rounded-lg cpk:bg-muted cpk:p-2.5 cpk:font-mono cpk:text-xs cpk:leading-relaxed cpk:text-foreground cpk:whitespace-pre-wrap cpk:break-words",
|
|
4558
|
+
children: stringifyPayload(value)
|
|
4559
|
+
})] });
|
|
4560
|
+
}
|
|
4561
|
+
/**
|
|
4562
|
+
* A tool call's arguments and, once it has one, its result.
|
|
4563
|
+
* @internal
|
|
4564
|
+
*/
|
|
4565
|
+
function ToolCallPayloads({ parameters, result, className }) {
|
|
4566
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4567
|
+
className: (0, tailwind_merge.twMerge)("cpk:grid cpk:gap-3", className),
|
|
4568
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Payload, {
|
|
4569
|
+
label: "Arguments",
|
|
4570
|
+
value: parameters ?? {}
|
|
4571
|
+
}), result !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Payload, {
|
|
4572
|
+
label: "Result",
|
|
4573
|
+
value: result
|
|
4574
|
+
})]
|
|
4575
|
+
});
|
|
4576
|
+
}
|
|
4577
|
+
/**
|
|
4578
|
+
* The built-in tool card drawn as a row inside a group: status, name and main
|
|
4579
|
+
* argument, opening to the payloads.
|
|
4580
|
+
* @internal
|
|
4581
|
+
*/
|
|
4582
|
+
function ToolCallRow({ name, parameters, result, status, appearance, className, ...props }) {
|
|
4583
|
+
const [open, setOpen] = (0, react.useState)(false);
|
|
4584
|
+
const detailsId = (0, react.useId)();
|
|
4585
|
+
const preview = argumentPreview(parameters);
|
|
4586
|
+
const line = appearance === "line";
|
|
4587
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4588
|
+
"data-copilotkit": true,
|
|
4589
|
+
className: (0, tailwind_merge.twMerge)(!line && "cpk:border-t cpk:border-border", className),
|
|
4590
|
+
...props,
|
|
4591
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
4592
|
+
type: "button",
|
|
4593
|
+
"aria-expanded": open,
|
|
4594
|
+
"aria-controls": detailsId,
|
|
4595
|
+
onClick: () => setOpen((value) => !value),
|
|
4596
|
+
className: (0, tailwind_merge.twMerge)("cpk:group/row cpk:m-0 cpk:flex cpk:min-w-0 cpk:cursor-pointer cpk:items-center cpk:gap-2 cpk:border-none cpk:bg-transparent cpk:text-left cpk:text-[13px] cpk:text-inherit cpk:transition-colors cpk:hover:bg-accent/60 cpk:focus-visible:outline-2 cpk:focus-visible:-outline-offset-2 cpk:focus-visible:outline-ring", line ? "cpk:-mx-1.5 cpk:w-[calc(100%+0.75rem)] cpk:rounded-md cpk:px-1.5 cpk:py-1" : "cpk:w-full cpk:px-3.5 cpk:py-2"),
|
|
4597
|
+
children: [
|
|
4598
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatusIcon, { status }),
|
|
4599
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4600
|
+
"data-testid": "copilot-tool-render-name",
|
|
4601
|
+
className: (0, tailwind_merge.twMerge)("cpk:shrink-0 cpk:font-mono cpk:text-[13px] cpk:font-medium cpk:text-foreground", status === "running" && "cpk-shimmer"),
|
|
4602
|
+
children: name
|
|
4603
|
+
}),
|
|
4604
|
+
preview && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4605
|
+
className: "cpk:min-w-0 cpk:truncate cpk:font-mono cpk:text-[13px] cpk:text-muted-foreground",
|
|
4606
|
+
children: preview
|
|
4607
|
+
}),
|
|
4608
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4609
|
+
"data-testid": "copilot-tool-render-status",
|
|
4610
|
+
className: "cpk:sr-only",
|
|
4611
|
+
children: statusLabels[status]
|
|
4612
|
+
}),
|
|
4613
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Chevron, {
|
|
4614
|
+
open,
|
|
4615
|
+
className: (0, tailwind_merge.twMerge)("cpk:ml-auto cpk:text-muted-foreground", !open && "cpk:opacity-0 cpk:group-hover/row:opacity-100 cpk:group-focus-visible/row:opacity-100")
|
|
4616
|
+
})
|
|
4617
|
+
]
|
|
4618
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Collapsible, {
|
|
4619
|
+
open,
|
|
4620
|
+
id: detailsId,
|
|
4621
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolCallPayloads, {
|
|
4622
|
+
parameters,
|
|
4623
|
+
result,
|
|
4624
|
+
className: line ? "cpk:mt-1 cpk:mb-2 cpk:ml-5.5" : "cpk:px-3.5 cpk:pt-1 cpk:pb-3"
|
|
4625
|
+
})
|
|
4626
|
+
})]
|
|
4627
|
+
});
|
|
4628
|
+
}
|
|
4629
|
+
/**
|
|
4630
|
+
* Tool calls made in a row, collapsed into one summary. While a call runs the
|
|
4631
|
+
* summary names it ("Running read_file src/app.ts"); once they're all done it
|
|
4632
|
+
* reads "Used 3 tools" and opens to the calls.
|
|
4633
|
+
*
|
|
4634
|
+
* Each call is drawn by its registered renderer. CopilotKit's built-in card
|
|
4635
|
+
* (`useDefaultRenderTool`) draws a compact row inside the card and line
|
|
4636
|
+
* appearances; a custom wildcard renderer draws whatever it draws.
|
|
4637
|
+
*/
|
|
4638
|
+
function CopilotChatToolCallGroup({ calls, renderCall, appearance = "card", isActive = false, className, ...props }) {
|
|
4639
|
+
const [open, setOpen] = (0, react.useState)(false);
|
|
4640
|
+
const bodyId = (0, react.useId)();
|
|
4641
|
+
const latest = calls[calls.length - 1];
|
|
4642
|
+
if (!latest) return null;
|
|
4643
|
+
const current = isActive ? calls.find((call) => !call.toolMessage) ?? latest : void 0;
|
|
4644
|
+
const preview = current ? entryPreview(current) : void 0;
|
|
4645
|
+
const done = calls.filter((call) => call.toolMessage).length;
|
|
4646
|
+
const statuses = calls.map((call) => entryStatus(call, isActive));
|
|
4647
|
+
const failedIds = new Set(calls.filter((_, index) => statuses[index] === "failed").map((call) => call.toolCall.id));
|
|
4648
|
+
const status = current ? "running" : failedIds.size > 0 ? "failed" : statuses.includes("stopped") ? "stopped" : "done";
|
|
4649
|
+
const rows = (rowAppearance) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolCallGroupContext.Provider, {
|
|
4650
|
+
value: {
|
|
4651
|
+
appearance: rowAppearance,
|
|
4652
|
+
failedIds,
|
|
4653
|
+
active: isActive
|
|
4654
|
+
},
|
|
4655
|
+
children: calls.map((call) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.default.Fragment, { children: renderCall(call) }, call.toolCall.id))
|
|
4656
|
+
});
|
|
4657
|
+
const groupProps = {
|
|
4658
|
+
"data-copilotkit": true,
|
|
4659
|
+
"data-testid": "copilot-tool-call-group",
|
|
4660
|
+
"data-appearance": appearance,
|
|
4661
|
+
"data-state": status,
|
|
4662
|
+
...props
|
|
4663
|
+
};
|
|
4664
|
+
const runningLabel = current && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
4665
|
+
className: "cpk:shrink-0 cpk:font-medium cpk-shimmer",
|
|
4666
|
+
children: ["Running ", current.toolCall.function.name]
|
|
4667
|
+
}), preview && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4668
|
+
className: "cpk:min-w-0 cpk:truncate cpk:font-mono cpk:text-xs cpk:opacity-70",
|
|
4669
|
+
children: preview
|
|
4670
|
+
})] });
|
|
4671
|
+
if (appearance === "line") {
|
|
4672
|
+
if (calls.length === 1 && !current) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4673
|
+
...groupProps,
|
|
4674
|
+
className: (0, tailwind_merge.twMerge)("cpk:my-2", className),
|
|
4675
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolCallGroupContext.Provider, {
|
|
4676
|
+
value: {
|
|
4677
|
+
appearance: "line",
|
|
4678
|
+
failedIds,
|
|
4679
|
+
active: isActive
|
|
4680
|
+
},
|
|
4681
|
+
children: renderCall(latest)
|
|
4682
|
+
})
|
|
4683
|
+
});
|
|
4684
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4685
|
+
...groupProps,
|
|
4686
|
+
className: (0, tailwind_merge.twMerge)("cpk:my-3", className),
|
|
4687
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
4688
|
+
type: "button",
|
|
4689
|
+
"aria-expanded": open,
|
|
4690
|
+
"aria-controls": bodyId,
|
|
4691
|
+
onClick: () => setOpen((value) => !value),
|
|
4692
|
+
className: "cpk:m-0 cpk:inline-flex cpk:max-w-full cpk:min-w-0 cpk:cursor-pointer cpk:items-center cpk:gap-1.5 cpk:rounded-md cpk:border-none cpk:bg-transparent cpk:p-0 cpk:py-0.5 cpk:text-sm cpk:text-muted-foreground cpk:transition-colors cpk:hover:text-foreground cpk:focus-visible:outline-2 cpk:focus-visible:outline-ring",
|
|
4693
|
+
children: [runningLabel || /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
4694
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
4695
|
+
className: "cpk:shrink-0 cpk:font-medium",
|
|
4696
|
+
children: ["Used ", pluralize(calls.length, "tool")]
|
|
4697
|
+
}),
|
|
4698
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4699
|
+
className: "cpk:min-w-0 cpk:truncate cpk:font-mono cpk:text-xs cpk:opacity-70",
|
|
4700
|
+
children: toolNames(calls)
|
|
4701
|
+
}),
|
|
4702
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(FailedCount, { calls })
|
|
4703
|
+
] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Chevron, { open })]
|
|
4704
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Collapsible, {
|
|
4705
|
+
open,
|
|
4706
|
+
id: bodyId,
|
|
4707
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4708
|
+
className: "cpk:mt-1 cpk:ml-1 cpk:border-l-2 cpk:border-border cpk:py-0.5 cpk:pl-3",
|
|
4709
|
+
children: rows("line")
|
|
4710
|
+
})
|
|
4711
|
+
})]
|
|
4712
|
+
});
|
|
4713
|
+
}
|
|
4714
|
+
if (appearance === "stack") {
|
|
4715
|
+
if (calls.length === 1) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4716
|
+
...groupProps,
|
|
4717
|
+
className: (0, tailwind_merge.twMerge)("cpk:py-1", className),
|
|
4718
|
+
children: renderCall(latest)
|
|
4719
|
+
});
|
|
4720
|
+
const behind = open ? 0 : Math.min(calls.length - 1, 2);
|
|
4721
|
+
const layer = "cpk:rounded-xl cpk:border cpk:border-border cpk:bg-card cpk:text-card-foreground";
|
|
4722
|
+
const latestStatus = entryStatus(latest, isActive);
|
|
4723
|
+
const latestPreview = entryPreview(latest);
|
|
4724
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4725
|
+
...groupProps,
|
|
4726
|
+
className: (0, tailwind_merge.twMerge)("cpk:my-3", className),
|
|
4727
|
+
style: {
|
|
4728
|
+
paddingBottom: behind * 6,
|
|
4729
|
+
...props.style
|
|
4730
|
+
},
|
|
4731
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4732
|
+
className: "cpk:relative cpk:isolate",
|
|
4733
|
+
children: [Array.from({ length: behind }, (_, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4734
|
+
"aria-hidden": "true",
|
|
4735
|
+
className: (0, tailwind_merge.twMerge)(layer, "cpk:absolute cpk:inset-0"),
|
|
4736
|
+
style: {
|
|
4737
|
+
transform: `translateY(${(index + 1) * 6}px) scaleX(${1 - (index + 1) * .045})`,
|
|
4738
|
+
zIndex: -1 - index,
|
|
4739
|
+
opacity: 1 - (index + 1) * .28
|
|
4740
|
+
}
|
|
4741
|
+
}, index)), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4742
|
+
type: "button",
|
|
4743
|
+
"aria-expanded": open,
|
|
4744
|
+
"aria-controls": open ? bodyId : void 0,
|
|
4745
|
+
onClick: () => setOpen((value) => !value),
|
|
4746
|
+
className: (0, tailwind_merge.twMerge)("cpk:relative cpk:m-0 cpk:flex cpk:min-w-0 cpk:cursor-pointer cpk:items-center cpk:text-left cpk:transition-colors cpk:focus-visible:outline-2 cpk:focus-visible:outline-ring", open ? "cpk:mb-1 cpk:gap-1.5 cpk:rounded-md cpk:border-none cpk:bg-transparent cpk:p-0 cpk:py-0.5 cpk:text-xs cpk:text-muted-foreground cpk:hover:text-foreground" : (0, tailwind_merge.twMerge)(layer, "cpk:w-full cpk:gap-2 cpk:px-3.5 cpk:py-2.5 cpk:text-[13px] cpk:shadow-[0_1px_2px_rgb(0_0_0/0.04)] cpk:hover:bg-accent")),
|
|
4747
|
+
children: open ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
4748
|
+
pluralize(calls.length, "tool call"),
|
|
4749
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(FailedCount, { calls }),
|
|
4750
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Chevron, {
|
|
4751
|
+
open: true,
|
|
4752
|
+
className: "cpk:-rotate-90"
|
|
4753
|
+
}),
|
|
4754
|
+
"Collapse"
|
|
4755
|
+
] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
4756
|
+
className: "cpk:flex cpk:min-w-0 cpk:flex-1 cpk:items-center cpk:gap-2 cpk:animate-[cpk-stack-drop_260ms_cubic-bezier(0.16,1,0.3,1)] cpk:motion-reduce:animate-none",
|
|
4757
|
+
children: [
|
|
4758
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatusIcon, { status: latestStatus }),
|
|
4759
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4760
|
+
className: (0, tailwind_merge.twMerge)("cpk:shrink-0 cpk:font-mono cpk:font-medium cpk:text-foreground", latestStatus === "running" && "cpk-shimmer"),
|
|
4761
|
+
children: latest.toolCall.function.name
|
|
4762
|
+
}),
|
|
4763
|
+
latestPreview && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4764
|
+
className: "cpk:min-w-0 cpk:truncate cpk:font-mono cpk:text-muted-foreground",
|
|
4765
|
+
children: latestPreview
|
|
4766
|
+
})
|
|
4767
|
+
]
|
|
4768
|
+
}, latest.toolCall.id), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
4769
|
+
className: "cpk:ml-2 cpk:inline-flex cpk:shrink-0 cpk:items-center cpk:gap-2 cpk:text-xs cpk:text-muted-foreground",
|
|
4770
|
+
children: [
|
|
4771
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(FailedCount, { calls }),
|
|
4772
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4773
|
+
className: "cpk:tabular-nums",
|
|
4774
|
+
children: pluralize(calls.length, "call")
|
|
4775
|
+
}),
|
|
4776
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Chevron, {
|
|
4777
|
+
open: false,
|
|
4778
|
+
className: "cpk:rotate-90"
|
|
4779
|
+
})
|
|
4780
|
+
]
|
|
4781
|
+
})] })
|
|
4782
|
+
})]
|
|
4783
|
+
}), open && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4784
|
+
id: bodyId,
|
|
4785
|
+
className: "cpk:[&>*]:animate-[cpk-stack-fan_300ms_cubic-bezier(0.16,1,0.3,1)_both] cpk:motion-reduce:[&>*]:animate-none",
|
|
4786
|
+
children: calls.map((call) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.default.Fragment, { children: renderCall(call) }, call.toolCall.id))
|
|
4787
|
+
})]
|
|
4788
|
+
});
|
|
4789
|
+
}
|
|
4790
|
+
if (calls.length === 1) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4791
|
+
...groupProps,
|
|
4792
|
+
className: (0, tailwind_merge.twMerge)("cpk:py-1", className),
|
|
4793
|
+
children: renderCall(latest)
|
|
4794
|
+
});
|
|
4795
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4796
|
+
...groupProps,
|
|
4797
|
+
className: (0, tailwind_merge.twMerge)("cpk:my-3 cpk:overflow-hidden cpk:rounded-xl cpk:border cpk:border-border cpk:bg-card cpk:text-card-foreground", className),
|
|
4798
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
4799
|
+
type: "button",
|
|
4800
|
+
"aria-expanded": open,
|
|
4801
|
+
"aria-controls": bodyId,
|
|
4802
|
+
onClick: () => setOpen((value) => !value),
|
|
4803
|
+
className: "cpk:m-0 cpk:flex cpk:w-full cpk:min-w-0 cpk:cursor-pointer cpk:items-center cpk:gap-2.5 cpk:border-none cpk:bg-transparent cpk:px-3.5 cpk:py-2.5 cpk:text-left cpk:text-[13px] cpk:text-inherit cpk:transition-colors cpk:hover:bg-accent/60 cpk:focus-visible:outline-2 cpk:focus-visible:-outline-offset-2 cpk:focus-visible:outline-ring",
|
|
4804
|
+
children: [
|
|
4805
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(StatusIcon, { status }),
|
|
4806
|
+
runningLabel || /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
4807
|
+
className: "cpk:shrink-0 cpk:font-medium cpk:text-foreground",
|
|
4808
|
+
children: ["Used ", pluralize(calls.length, "tool")]
|
|
4809
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4810
|
+
className: "cpk:min-w-0 cpk:truncate cpk:font-mono cpk:text-xs cpk:text-muted-foreground",
|
|
4811
|
+
children: toolNames(calls)
|
|
4812
|
+
})] }),
|
|
4813
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
4814
|
+
className: "cpk:ml-auto cpk:flex cpk:shrink-0 cpk:items-center cpk:gap-2 cpk:pl-2 cpk:text-xs cpk:text-muted-foreground",
|
|
4815
|
+
children: [status === "failed" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FailedCount, { calls }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4816
|
+
className: "cpk:tabular-nums",
|
|
4817
|
+
children: status === "running" ? `${done} done` : statusLabels[status]
|
|
4818
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Chevron, { open })]
|
|
4819
|
+
})
|
|
4820
|
+
]
|
|
4821
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Collapsible, {
|
|
4822
|
+
open,
|
|
4823
|
+
id: bodyId,
|
|
4824
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { children: rows("card") })
|
|
4825
|
+
})]
|
|
4826
|
+
});
|
|
4827
|
+
}
|
|
4828
|
+
|
|
4392
4829
|
//#endregion
|
|
4393
4830
|
//#region src/v2/hooks/use-default-render-tool.tsx
|
|
4394
4831
|
/**
|
|
@@ -4472,7 +4909,8 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
4472
4909
|
const userRender = config?.render;
|
|
4473
4910
|
useRenderTool({
|
|
4474
4911
|
name: "*",
|
|
4475
|
-
render: userRender ? (raw) => userRender(adaptRendererProps(raw)) : (raw) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DefaultToolCallRenderer, { ...adaptRendererProps(raw) })
|
|
4912
|
+
render: userRender ? (raw) => userRender(adaptRendererProps(raw)) : (raw) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DefaultToolCallRenderer, { ...adaptRendererProps(raw) }),
|
|
4913
|
+
group: userRender ? config?.group === true : true
|
|
4476
4914
|
}, deps);
|
|
4477
4915
|
}
|
|
4478
4916
|
/**
|
|
@@ -4493,9 +4931,23 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
4493
4931
|
}
|
|
4494
4932
|
}
|
|
4495
4933
|
function DefaultToolCallRenderer({ name, toolCallId, parameters, status, result }) {
|
|
4934
|
+
const group = (0, react.useContext)(ToolCallGroupContext);
|
|
4496
4935
|
const [isExpanded, setIsExpanded] = (0, react.useState)(false);
|
|
4497
4936
|
const isActive = status === "inProgress" || status === "executing";
|
|
4498
4937
|
const isComplete = status === "complete";
|
|
4938
|
+
if (group) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolCallRow, {
|
|
4939
|
+
"data-testid": "copilot-tool-render",
|
|
4940
|
+
"data-tool-name": name,
|
|
4941
|
+
"data-tool-call-id": toolCallId,
|
|
4942
|
+
"data-status": status,
|
|
4943
|
+
"data-args": safeStringifyForAttr(parameters),
|
|
4944
|
+
"data-result": safeStringifyForAttr(result),
|
|
4945
|
+
name,
|
|
4946
|
+
parameters,
|
|
4947
|
+
result,
|
|
4948
|
+
status: isComplete ? group.failedIds.has(toolCallId) ? "failed" : "done" : group.active ? "running" : "stopped",
|
|
4949
|
+
appearance: group.appearance
|
|
4950
|
+
});
|
|
4499
4951
|
const statusLabel = isActive ? "Running" : isComplete ? "Done" : status;
|
|
4500
4952
|
const dotClassName = isActive ? "cpk:bg-amber-500" : isComplete ? "cpk:bg-emerald-500" : "cpk:bg-zinc-400";
|
|
4501
4953
|
const badgeClassName = isActive ? "cpk:bg-amber-100 cpk:text-amber-800 cpk:dark:bg-amber-500/15 cpk:dark:text-amber-400" : isComplete ? "cpk:bg-emerald-100 cpk:text-emerald-800 cpk:dark:bg-emerald-500/15 cpk:dark:text-emerald-400" : "cpk:bg-zinc-100 cpk:text-zinc-800 cpk:dark:bg-zinc-700/40 cpk:dark:text-zinc-300";
|
|
@@ -6192,38 +6644,227 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
6192
6644
|
});
|
|
6193
6645
|
}
|
|
6194
6646
|
|
|
6647
|
+
//#endregion
|
|
6648
|
+
//#region src/v2/components/chat/tool-call-display-context.ts
|
|
6649
|
+
/** @internal */
|
|
6650
|
+
const ToolCallDisplayContext = (0, react.createContext)(null);
|
|
6651
|
+
|
|
6652
|
+
//#endregion
|
|
6653
|
+
//#region src/v2/components/chat/tool-call-layout.ts
|
|
6654
|
+
function contentLength(content) {
|
|
6655
|
+
return typeof content === "string" ? content.length : JSON.stringify(content ?? "").length;
|
|
6656
|
+
}
|
|
6657
|
+
const entrySignature = ({ toolCall, toolMessage }) => [
|
|
6658
|
+
toolCall.id,
|
|
6659
|
+
toolCall.function.name,
|
|
6660
|
+
toolCall.function.arguments.length,
|
|
6661
|
+
toolMessage ? `${contentLength(toolMessage.content)}${toolMessage.error ? "!" : ""}` : "-"
|
|
6662
|
+
].join(":");
|
|
6663
|
+
function signatureOf(segments) {
|
|
6664
|
+
return segments.map((segment) => segment.kind === "call" ? `c(${entrySignature(segment.call)})` : `g${segment.trailing ? "*" : ""}(${segment.calls.map(entrySignature).join(",")})`).join("|");
|
|
6665
|
+
}
|
|
6666
|
+
/** Index of tool results by the call they answer. */
|
|
6667
|
+
function getToolResults(messages) {
|
|
6668
|
+
const results = /* @__PURE__ */ new Map();
|
|
6669
|
+
for (const message of messages) if (message.role === "tool") results.set(message.toolCallId, message);
|
|
6670
|
+
return results;
|
|
6671
|
+
}
|
|
6672
|
+
/**
|
|
6673
|
+
* Lays out the tool calls of every assistant message in `rendered`.
|
|
6674
|
+
*
|
|
6675
|
+
* Calls drawn by a renderer that opted into grouping join the group that's
|
|
6676
|
+
* open; anything else that shows between them closes it: assistant text, a
|
|
6677
|
+
* user, reasoning or activity message, or a call drawn by any other renderer. A group belongs to
|
|
6678
|
+
* the message where it starts, so later messages whose calls joined it render
|
|
6679
|
+
* no tool calls themselves.
|
|
6680
|
+
*
|
|
6681
|
+
* @param rendered - The messages as the chat renders them, in order.
|
|
6682
|
+
* @param all - Every message, for finding tool results (a transform may hide them).
|
|
6683
|
+
* @param renderers - The registered renderers.
|
|
6684
|
+
*/
|
|
6685
|
+
function getToolCallLayouts(rendered, all, renderers) {
|
|
6686
|
+
const results = getToolResults(all);
|
|
6687
|
+
const layouts = /* @__PURE__ */ new Map();
|
|
6688
|
+
let open;
|
|
6689
|
+
for (const message of rendered) {
|
|
6690
|
+
if (message.role === "tool") continue;
|
|
6691
|
+
if (message.role !== "assistant") {
|
|
6692
|
+
open = void 0;
|
|
6693
|
+
continue;
|
|
6694
|
+
}
|
|
6695
|
+
if (typeof message.content === "string" && message.content.trim()) open = void 0;
|
|
6696
|
+
const segments = [];
|
|
6697
|
+
layouts.set(message.id, segments);
|
|
6698
|
+
const toolCalls = /* @__PURE__ */ new Map();
|
|
6699
|
+
for (const toolCall of message.toolCalls ?? []) toolCalls.set(toolCall.id, toolCall);
|
|
6700
|
+
for (const toolCall of toolCalls.values()) {
|
|
6701
|
+
const entry = {
|
|
6702
|
+
toolCall,
|
|
6703
|
+
toolMessage: results.get(toolCall.id)
|
|
6704
|
+
};
|
|
6705
|
+
const name = toolCall.function.name;
|
|
6706
|
+
const named = renderers.named.has(name);
|
|
6707
|
+
const rendered = named || renderers.wildcard;
|
|
6708
|
+
const groups = named ? renderers.groupedNames.has(name) : renderers.wildcardGroups;
|
|
6709
|
+
if (!rendered || !groups) {
|
|
6710
|
+
if (rendered) open = void 0;
|
|
6711
|
+
segments.push({
|
|
6712
|
+
kind: "call",
|
|
6713
|
+
id: toolCall.id,
|
|
6714
|
+
call: entry,
|
|
6715
|
+
rendered
|
|
6716
|
+
});
|
|
6717
|
+
} else if (open) open.calls.push(entry);
|
|
6718
|
+
else {
|
|
6719
|
+
open = {
|
|
6720
|
+
kind: "group",
|
|
6721
|
+
id: toolCall.id,
|
|
6722
|
+
calls: [entry],
|
|
6723
|
+
trailing: false
|
|
6724
|
+
};
|
|
6725
|
+
segments.push(open);
|
|
6726
|
+
}
|
|
6727
|
+
}
|
|
6728
|
+
}
|
|
6729
|
+
if (open) open.trailing = true;
|
|
6730
|
+
const layout = /* @__PURE__ */ new Map();
|
|
6731
|
+
for (const [id, segments] of layouts) layout.set(id, {
|
|
6732
|
+
segments,
|
|
6733
|
+
signature: signatureOf(segments)
|
|
6734
|
+
});
|
|
6735
|
+
return layout;
|
|
6736
|
+
}
|
|
6737
|
+
/**
|
|
6738
|
+
* Finds the working phase of every reply in `rendered`: its messages up to the
|
|
6739
|
+
* last one that calls a tool. Text in there was narration; what follows is the
|
|
6740
|
+
* reply itself. Replies that called no tools are omitted, except the latest,
|
|
6741
|
+
* which may be about to.
|
|
6742
|
+
*/
|
|
6743
|
+
function getTurnWork(rendered, layouts) {
|
|
6744
|
+
const turns = /* @__PURE__ */ new Map();
|
|
6745
|
+
let start = 0;
|
|
6746
|
+
while (start < rendered.length) {
|
|
6747
|
+
let end = start;
|
|
6748
|
+
while (end < rendered.length && rendered[end].role !== "user") end++;
|
|
6749
|
+
const key = start > 0 ? rendered[start - 1].id : "start";
|
|
6750
|
+
const visible = rendered.slice(start, end).filter((message) => message.role !== "tool");
|
|
6751
|
+
const isLatest = end === rendered.length;
|
|
6752
|
+
const calls = [];
|
|
6753
|
+
for (const message of visible) for (const segment of layouts.get(message.id)?.segments ?? []) if (segment.kind === "group") calls.push(...segment.calls);
|
|
6754
|
+
else if (segment.rendered) calls.push(segment.call);
|
|
6755
|
+
const shown = new Set(calls.map((entry) => entry.toolCall.id));
|
|
6756
|
+
let lastWork = -1;
|
|
6757
|
+
visible.forEach((message, index) => {
|
|
6758
|
+
if (message.role === "assistant" && message.toolCalls?.some((call) => shown.has(call.id))) lastWork = index;
|
|
6759
|
+
});
|
|
6760
|
+
const first = visible[0];
|
|
6761
|
+
if (first && (calls.length > 0 || isLatest)) {
|
|
6762
|
+
let lastAssistant = -1;
|
|
6763
|
+
visible.forEach((message, index) => {
|
|
6764
|
+
if (message.role === "assistant") lastAssistant = index;
|
|
6765
|
+
});
|
|
6766
|
+
const replyText = visible[lastAssistant]?.content;
|
|
6767
|
+
const endsWithWork = lastAssistant >= 0 && lastAssistant <= lastWork && typeof replyText === "string" && replyText.trim().length > 0;
|
|
6768
|
+
turns.set(key, {
|
|
6769
|
+
key,
|
|
6770
|
+
firstMessageId: first.id,
|
|
6771
|
+
workMessageIds: new Set(visible.slice(0, lastWork + 1).map((message) => message.id)),
|
|
6772
|
+
replyTextMessageId: endsWithWork ? visible[lastAssistant].id : void 0,
|
|
6773
|
+
calls,
|
|
6774
|
+
isLatest
|
|
6775
|
+
});
|
|
6776
|
+
}
|
|
6777
|
+
start = end + 1;
|
|
6778
|
+
}
|
|
6779
|
+
return turns;
|
|
6780
|
+
}
|
|
6781
|
+
|
|
6195
6782
|
//#endregion
|
|
6196
6783
|
//#region src/v2/components/chat/CopilotChatToolCallsView.tsx
|
|
6197
|
-
|
|
6784
|
+
const appearances = {
|
|
6785
|
+
grouped: "card",
|
|
6786
|
+
line: "line",
|
|
6787
|
+
stacked: "stack"
|
|
6788
|
+
};
|
|
6789
|
+
function CopilotChatToolCallsView({ message, messages = [], display: displayProp, group }) {
|
|
6198
6790
|
const renderToolCall = useRenderToolCall();
|
|
6791
|
+
const rendererNames = useToolCallRendererNames();
|
|
6199
6792
|
const { copilotkit } = useCopilotKit();
|
|
6200
6793
|
const subscribe = (0, react.useCallback)((onChange) => copilotkit.ɵsubscribeToLearningConfigured(onChange), [copilotkit]);
|
|
6201
6794
|
const getSnapshot = () => copilotkit.ɵlearningConfigured;
|
|
6202
6795
|
const learningConfigured = (0, react.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
6796
|
+
const context = (0, react.useContext)(ToolCallDisplayContext);
|
|
6797
|
+
const display = displayProp ?? context?.display ?? "grouped";
|
|
6798
|
+
const viewLayout = context?.layouts.get(message.id);
|
|
6799
|
+
const layout = (0, react.useMemo)(() => {
|
|
6800
|
+
if (display === "separate") return void 0;
|
|
6801
|
+
return viewLayout ?? getToolCallLayouts([message], messages, rendererNames).get(message.id);
|
|
6802
|
+
}, [
|
|
6803
|
+
display,
|
|
6804
|
+
viewLayout,
|
|
6805
|
+
message,
|
|
6806
|
+
messages,
|
|
6807
|
+
rendererNames
|
|
6808
|
+
]);
|
|
6203
6809
|
if (!message.toolCalls || message.toolCalls.length === 0) return null;
|
|
6204
|
-
|
|
6810
|
+
const renderCall = (entry) => {
|
|
6205
6811
|
const rendered = renderToolCall({
|
|
6206
|
-
toolCall,
|
|
6207
|
-
toolMessage:
|
|
6812
|
+
toolCall: entry.toolCall,
|
|
6813
|
+
toolMessage: entry.toolMessage
|
|
6208
6814
|
});
|
|
6209
|
-
if (rendered === null) return
|
|
6210
|
-
if (!learningConfigured) return rendered;
|
|
6815
|
+
if (rendered === null || !learningConfigured) return rendered;
|
|
6211
6816
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6212
|
-
"data-tool-call-id": toolCall.id,
|
|
6817
|
+
"data-tool-call-id": entry.toolCall.id,
|
|
6213
6818
|
style: { display: "contents" },
|
|
6214
6819
|
children: rendered
|
|
6215
|
-
}
|
|
6820
|
+
});
|
|
6821
|
+
};
|
|
6822
|
+
if (!layout) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: message.toolCalls.map((toolCall) => {
|
|
6823
|
+
const toolMessage = messages.find((m) => m.role === "tool" && m.toolCallId === toolCall.id);
|
|
6824
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.default.Fragment, { children: renderCall({
|
|
6825
|
+
toolCall,
|
|
6826
|
+
toolMessage
|
|
6827
|
+
}) }, toolCall.id);
|
|
6828
|
+
}) });
|
|
6829
|
+
const workOpen = context?.workOpen.get(message.id);
|
|
6830
|
+
const groupActive = (trailing) => trailing && (context ? context.isRunning : true);
|
|
6831
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: layout.segments.map((segment) => {
|
|
6832
|
+
if (segment.kind === "call") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.default.Fragment, { children: renderCall(segment.call) }, segment.id);
|
|
6833
|
+
if (display === "turn") {
|
|
6834
|
+
const failedIds = new Set(segment.calls.filter((call) => call.toolMessage?.error).map((call) => call.toolCall.id));
|
|
6835
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Collapsible, {
|
|
6836
|
+
open: workOpen ?? true,
|
|
6837
|
+
className: "cpk:-mx-2",
|
|
6838
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6839
|
+
className: "cpk:px-2 cpk:py-1.5",
|
|
6840
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolCallGroupContext.Provider, {
|
|
6841
|
+
value: {
|
|
6842
|
+
appearance: "line",
|
|
6843
|
+
failedIds,
|
|
6844
|
+
active: groupActive(segment.trailing)
|
|
6845
|
+
},
|
|
6846
|
+
children: segment.calls.map((call) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.default.Fragment, { children: renderCall(call) }, call.toolCall.id))
|
|
6847
|
+
})
|
|
6848
|
+
})
|
|
6849
|
+
}, segment.id);
|
|
6850
|
+
}
|
|
6851
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.default.Fragment, { children: renderSlot(group, CopilotChatToolCallGroup, {
|
|
6852
|
+
calls: segment.calls,
|
|
6853
|
+
renderCall,
|
|
6854
|
+
appearance: appearances[display] ?? "card",
|
|
6855
|
+
isActive: groupActive(segment.trailing)
|
|
6856
|
+
}) }, segment.id);
|
|
6216
6857
|
}) });
|
|
6217
6858
|
}
|
|
6218
6859
|
|
|
6219
6860
|
//#endregion
|
|
6220
6861
|
//#region src/v2/components/chat/CopilotChatInspectorButton.tsx
|
|
6221
6862
|
let shortcutsHidden = false;
|
|
6222
|
-
const listeners = /* @__PURE__ */ new Set();
|
|
6863
|
+
const listeners$1 = /* @__PURE__ */ new Set();
|
|
6223
6864
|
const subscribe = (listener) => {
|
|
6224
|
-
listeners.add(listener);
|
|
6865
|
+
listeners$1.add(listener);
|
|
6225
6866
|
return () => {
|
|
6226
|
-
listeners.delete(listener);
|
|
6867
|
+
listeners$1.delete(listener);
|
|
6227
6868
|
};
|
|
6228
6869
|
};
|
|
6229
6870
|
const getSnapshot = () => shortcutsHidden;
|
|
@@ -6233,7 +6874,7 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
6233
6874
|
}
|
|
6234
6875
|
function hideShortcuts() {
|
|
6235
6876
|
shortcutsHidden = true;
|
|
6236
|
-
listeners.forEach((listener) => listener());
|
|
6877
|
+
listeners$1.forEach((listener) => listener());
|
|
6237
6878
|
}
|
|
6238
6879
|
function InspectorKiteIcon({ className, ...props }) {
|
|
6239
6880
|
const id = (0, react.useId)();
|
|
@@ -6499,9 +7140,321 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
6499
7140
|
});
|
|
6500
7141
|
}
|
|
6501
7142
|
|
|
7143
|
+
//#endregion
|
|
7144
|
+
//#region src/v2/components/ui/popover.tsx
|
|
7145
|
+
function Popover({ ...props }) {
|
|
7146
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_radix_ui_react_popover.Root, {
|
|
7147
|
+
"data-slot": "popover",
|
|
7148
|
+
...props
|
|
7149
|
+
});
|
|
7150
|
+
}
|
|
7151
|
+
function PopoverAnchor({ ...props }) {
|
|
7152
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_radix_ui_react_popover.Anchor, {
|
|
7153
|
+
"data-slot": "popover-anchor",
|
|
7154
|
+
...props
|
|
7155
|
+
});
|
|
7156
|
+
}
|
|
7157
|
+
/**
|
|
7158
|
+
* Popover content in a portal, so it floats over the page instead of taking
|
|
7159
|
+
* room in the layout, with the CopilotKit style scope on it.
|
|
7160
|
+
*/
|
|
7161
|
+
const PopoverContent = react.forwardRef(({ className, align = "start", sideOffset = 6, ...props }, ref) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_radix_ui_react_popover.Portal, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_radix_ui_react_popover.Content, {
|
|
7162
|
+
ref,
|
|
7163
|
+
"data-copilotkit": true,
|
|
7164
|
+
"data-copilotkit-popover": true,
|
|
7165
|
+
"data-slot": "popover-content",
|
|
7166
|
+
align,
|
|
7167
|
+
sideOffset,
|
|
7168
|
+
className: cn("cpk:z-50 cpk:outline-none cpk:data-[state=open]:animate-in cpk:data-[state=open]:fade-in-0 cpk:data-[state=open]:zoom-in-95 cpk:data-[side=bottom]:slide-in-from-top-1 cpk:data-[side=top]:slide-in-from-bottom-1", className),
|
|
7169
|
+
...props
|
|
7170
|
+
}) }));
|
|
7171
|
+
PopoverContent.displayName = "PopoverContent";
|
|
7172
|
+
|
|
7173
|
+
//#endregion
|
|
7174
|
+
//#region src/v2/lib/message-feedback.ts
|
|
7175
|
+
/** Trajectory event name for a rating of one assistant message. */
|
|
7176
|
+
const MESSAGE_FEEDBACK_EVENT_NAME = "message.feedback";
|
|
7177
|
+
/** Longest comment kept, in characters; the rest is cut so the event stays small. */
|
|
7178
|
+
const MESSAGE_FEEDBACK_MAX_COMMENT_LENGTH = 1e3;
|
|
7179
|
+
/** Longest excerpt of the rated response sent with the rating, in characters. */
|
|
7180
|
+
const RESPONSE_EXCERPT_LENGTH = 500;
|
|
7181
|
+
const ratings = /* @__PURE__ */ new Map();
|
|
7182
|
+
const listeners = /* @__PURE__ */ new Map();
|
|
7183
|
+
const threadKey = (agentId, threadId) => JSON.stringify([agentId, threadId]);
|
|
7184
|
+
const messageKey = (agentId, threadId, messageId) => JSON.stringify([
|
|
7185
|
+
agentId,
|
|
7186
|
+
threadId,
|
|
7187
|
+
messageId
|
|
7188
|
+
]);
|
|
7189
|
+
/** Cuts `text` to `max` characters without splitting a surrogate pair. */
|
|
7190
|
+
const clip = (text, max) => {
|
|
7191
|
+
const characters = Array.from(text);
|
|
7192
|
+
return characters.length > max ? characters.slice(0, max).join("") : text;
|
|
7193
|
+
};
|
|
7194
|
+
/** The comment as kept and sent: trimmed and capped, or none. */
|
|
7195
|
+
const normalizeComment = (comment) => {
|
|
7196
|
+
if (typeof comment !== "string") return void 0;
|
|
7197
|
+
const text = clip(comment.trim(), MESSAGE_FEEDBACK_MAX_COMMENT_LENGTH);
|
|
7198
|
+
return text === "" ? void 0 : text;
|
|
7199
|
+
};
|
|
7200
|
+
/** The rating this page gave one message, if any. */
|
|
7201
|
+
function getMessageFeedback(agentId, threadId, messageId) {
|
|
7202
|
+
return ratings.get(messageKey(agentId, threadId, messageId));
|
|
7203
|
+
}
|
|
7204
|
+
/** Calls `listener` whenever a rating in this Thread changes. */
|
|
7205
|
+
function subscribeToMessageFeedback(agentId, threadId, listener) {
|
|
7206
|
+
const key = threadKey(agentId, threadId);
|
|
7207
|
+
let set = listeners.get(key);
|
|
7208
|
+
if (set === void 0) {
|
|
7209
|
+
set = /* @__PURE__ */ new Set();
|
|
7210
|
+
listeners.set(key, set);
|
|
7211
|
+
}
|
|
7212
|
+
set.add(listener);
|
|
7213
|
+
return () => {
|
|
7214
|
+
set.delete(listener);
|
|
7215
|
+
if (set.size === 0) listeners.delete(key);
|
|
7216
|
+
};
|
|
7217
|
+
}
|
|
7218
|
+
/**
|
|
7219
|
+
* Sets (or, with `null`, clears) this page's rating of one message and sends
|
|
7220
|
+
* it to the active Trajectory. Every change is a new event; the newest event
|
|
7221
|
+
* for a `feedbackId` is the current one. Like any Trajectory event, a change
|
|
7222
|
+
* made while no Trajectory captures, for example during a reconnect, is not
|
|
7223
|
+
* sent; the page still shows it.
|
|
7224
|
+
*/
|
|
7225
|
+
function setMessageFeedback(params) {
|
|
7226
|
+
const { copilotkit, agentId, threadId, message } = params;
|
|
7227
|
+
const comment = normalizeComment(params.feedback?.comment);
|
|
7228
|
+
const feedback = params.feedback && {
|
|
7229
|
+
rating: params.feedback.rating,
|
|
7230
|
+
...comment ? { comment } : {}
|
|
7231
|
+
};
|
|
7232
|
+
const key = messageKey(agentId, threadId, message.id);
|
|
7233
|
+
if (feedback) ratings.set(key, feedback);
|
|
7234
|
+
else ratings.delete(key);
|
|
7235
|
+
for (const listener of listeners.get(threadKey(agentId, threadId)) ?? []) listener();
|
|
7236
|
+
const runId = copilotkit.getRunIdForMessage(agentId, threadId, message.id);
|
|
7237
|
+
copilotkit.emitTrajectoryEvent(MESSAGE_FEEDBACK_EVENT_NAME, {
|
|
7238
|
+
feedbackId: `${threadId}:${message.id}`,
|
|
7239
|
+
threadId,
|
|
7240
|
+
messageId: message.id,
|
|
7241
|
+
agentId,
|
|
7242
|
+
...runId ? { runId } : {},
|
|
7243
|
+
rating: feedback?.rating ?? null,
|
|
7244
|
+
...feedback?.comment ? { comment: feedback.comment } : {},
|
|
7245
|
+
...copilotkit.ɵlearningCapturesAgentText ? { response: clip(message.content ?? "", RESPONSE_EXCERPT_LENGTH) } : {}
|
|
7246
|
+
});
|
|
7247
|
+
}
|
|
7248
|
+
|
|
7249
|
+
//#endregion
|
|
7250
|
+
//#region src/v2/components/chat/message-feedback.tsx
|
|
7251
|
+
/**
|
|
7252
|
+
* Set by the message view while Learning is on for this chat. Assistant
|
|
7253
|
+
* messages without it show thumbs only when the app passes its own handlers
|
|
7254
|
+
* or thumb slots.
|
|
7255
|
+
*/
|
|
7256
|
+
const MessageFeedbackScopeContext = (0, react.createContext)(null);
|
|
7257
|
+
const capturedCores = /* @__PURE__ */ new WeakSet();
|
|
7258
|
+
const rememberCapture = (copilotkit) => {
|
|
7259
|
+
if (capturedCores.has(copilotkit)) return;
|
|
7260
|
+
capturedCores.add(copilotkit);
|
|
7261
|
+
const unsubscribe = copilotkit.ɵsubscribeToLearningConfigured(() => {
|
|
7262
|
+
if (copilotkit.ɵlearningConfigured) return;
|
|
7263
|
+
capturedCores.delete(copilotkit);
|
|
7264
|
+
unsubscribe();
|
|
7265
|
+
});
|
|
7266
|
+
};
|
|
7267
|
+
/**
|
|
7268
|
+
* Whether the thumbs record feedback for Learning. True once a Trajectory of
|
|
7269
|
+
* this Core has started and as long as Learning stays configured, also while
|
|
7270
|
+
* capture reconnects or is stopped, so the buttons do not flicker. Ratings
|
|
7271
|
+
* given meanwhile still show but, like any Trajectory event, are not
|
|
7272
|
+
* sent. A capture that never starts (for example without a license) leaves it
|
|
7273
|
+
* false.
|
|
7274
|
+
*/
|
|
7275
|
+
function useLearningFeedbackEnabled(copilotkit) {
|
|
7276
|
+
const configured = (0, react.useSyncExternalStore)((0, react.useCallback)((onChange) => copilotkit.ɵsubscribeToLearningConfigured(onChange), [copilotkit]), () => copilotkit.ɵlearningConfigured, () => false);
|
|
7277
|
+
const capturing = (0, react.useSyncExternalStore)((0, react.useCallback)((onChange) => copilotkit.subscribe({ onTrajectoryChanged: onChange }).unsubscribe, [copilotkit]), () => copilotkit.trajectoryId !== null, () => false);
|
|
7278
|
+
(0, react.useEffect)(() => {
|
|
7279
|
+
if (capturing) rememberCapture(copilotkit);
|
|
7280
|
+
}, [capturing, copilotkit]);
|
|
7281
|
+
return configured && (capturing || capturedCores.has(copilotkit));
|
|
7282
|
+
}
|
|
7283
|
+
const noSubscription = () => () => {};
|
|
7284
|
+
/** Feedback controls for `message`, or `null` when this chat collects none. */
|
|
7285
|
+
function useMessageFeedback(message) {
|
|
7286
|
+
const scope = (0, react.useContext)(MessageFeedbackScopeContext);
|
|
7287
|
+
const subscribe = (0, react.useCallback)((onChange) => scope ? subscribeToMessageFeedback(scope.agentId, scope.threadId, onChange) : noSubscription(), [scope]);
|
|
7288
|
+
const getSnapshot = () => scope ? getMessageFeedback(scope.agentId, scope.threadId, message.id) : void 0;
|
|
7289
|
+
const feedback = (0, react.useSyncExternalStore)(subscribe, getSnapshot, getSnapshot);
|
|
7290
|
+
if (!scope) return null;
|
|
7291
|
+
const save = (next) => setMessageFeedback({
|
|
7292
|
+
...scope,
|
|
7293
|
+
message,
|
|
7294
|
+
feedback: next
|
|
7295
|
+
});
|
|
7296
|
+
return {
|
|
7297
|
+
feedback,
|
|
7298
|
+
rate: (rating) => {
|
|
7299
|
+
if (feedback?.rating !== rating) save({ rating });
|
|
7300
|
+
},
|
|
7301
|
+
clear: () => {
|
|
7302
|
+
if (feedback) save(null);
|
|
7303
|
+
},
|
|
7304
|
+
comment: (comment) => {
|
|
7305
|
+
if (feedback) save({
|
|
7306
|
+
rating: feedback.rating,
|
|
7307
|
+
comment
|
|
7308
|
+
});
|
|
7309
|
+
}
|
|
7310
|
+
};
|
|
7311
|
+
}
|
|
7312
|
+
/**
|
|
7313
|
+
* How long the pointer may be away from the rating and its comment before the
|
|
7314
|
+
* comment closes: enough to cross the gap between them, short enough that
|
|
7315
|
+
* passing over a rating does not leave it open.
|
|
7316
|
+
*/
|
|
7317
|
+
const FEEDBACK_COMMENT_CLOSE_DELAY_MS = 150;
|
|
7318
|
+
/**
|
|
7319
|
+
* Drives the comment popover of a rated message.
|
|
7320
|
+
*
|
|
7321
|
+
* It opens when a rating is given and whenever the pointer or keyboard focus
|
|
7322
|
+
* reaches the chosen thumb, with the saved comment in the field. It closes by
|
|
7323
|
+
* itself shortly after the pointer leaves the thumb and the popover, unless
|
|
7324
|
+
* focus is in the field: then it stays until focus moves away, Enter, or
|
|
7325
|
+
* Escape. Closing saves a changed comment; Escape, a click on a thumb, and
|
|
7326
|
+
* removing the rating discard it.
|
|
7327
|
+
*/
|
|
7328
|
+
function useFeedbackComment(controls) {
|
|
7329
|
+
const [open, setOpen] = (0, react.useState)(false);
|
|
7330
|
+
const [draft, setDraft] = (0, react.useState)("");
|
|
7331
|
+
const [focusRequest, setFocusRequest] = (0, react.useState)(0);
|
|
7332
|
+
const inputRef = (0, react.useRef)(null);
|
|
7333
|
+
const timer = (0, react.useRef)(void 0);
|
|
7334
|
+
const editing = (0, react.useRef)(false);
|
|
7335
|
+
const focusWaiting = (0, react.useRef)(false);
|
|
7336
|
+
const pointerOver = (0, react.useRef)(false);
|
|
7337
|
+
const returning = (0, react.useRef)(false);
|
|
7338
|
+
const latest = (0, react.useRef)({
|
|
7339
|
+
controls,
|
|
7340
|
+
draft,
|
|
7341
|
+
open
|
|
7342
|
+
});
|
|
7343
|
+
latest.current = {
|
|
7344
|
+
...latest.current,
|
|
7345
|
+
controls,
|
|
7346
|
+
draft,
|
|
7347
|
+
open
|
|
7348
|
+
};
|
|
7349
|
+
const takeFocusRequest = (0, react.useCallback)(() => {
|
|
7350
|
+
const waiting = focusWaiting.current;
|
|
7351
|
+
focusWaiting.current = false;
|
|
7352
|
+
return waiting;
|
|
7353
|
+
}, []);
|
|
7354
|
+
const cancelClose = (0, react.useCallback)(() => {
|
|
7355
|
+
if (timer.current === void 0) return;
|
|
7356
|
+
clearTimeout(timer.current);
|
|
7357
|
+
timer.current = void 0;
|
|
7358
|
+
}, []);
|
|
7359
|
+
(0, react.useEffect)(() => cancelClose, [cancelClose]);
|
|
7360
|
+
const savedComment = (0, react.useCallback)(() => latest.current.controls?.feedback?.comment ?? "", []);
|
|
7361
|
+
(0, react.useEffect)(() => () => {
|
|
7362
|
+
const { open: wasOpen, controls: current, draft: text } = latest.current;
|
|
7363
|
+
if (wasOpen && current?.feedback && text.trim() !== savedComment()) current.comment(text);
|
|
7364
|
+
}, []);
|
|
7365
|
+
const close = (0, react.useCallback)(({ save = true } = {}) => {
|
|
7366
|
+
cancelClose();
|
|
7367
|
+
focusWaiting.current = false;
|
|
7368
|
+
pointerOver.current = false;
|
|
7369
|
+
if (!latest.current.open) return;
|
|
7370
|
+
const current = latest.current.controls;
|
|
7371
|
+
if (save && current?.feedback && latest.current.draft.trim() !== savedComment()) current.comment(latest.current.draft);
|
|
7372
|
+
editing.current = false;
|
|
7373
|
+
latest.current = {
|
|
7374
|
+
...latest.current,
|
|
7375
|
+
open: false
|
|
7376
|
+
};
|
|
7377
|
+
setOpen(false);
|
|
7378
|
+
}, [cancelClose, savedComment]);
|
|
7379
|
+
const show = ({ comment, focus }) => {
|
|
7380
|
+
cancelClose();
|
|
7381
|
+
latest.current = {
|
|
7382
|
+
...latest.current,
|
|
7383
|
+
open: true,
|
|
7384
|
+
draft: comment
|
|
7385
|
+
};
|
|
7386
|
+
setDraft(comment);
|
|
7387
|
+
if (focus) {
|
|
7388
|
+
focusWaiting.current = true;
|
|
7389
|
+
setFocusRequest((request) => request + 1);
|
|
7390
|
+
}
|
|
7391
|
+
setOpen(true);
|
|
7392
|
+
};
|
|
7393
|
+
return {
|
|
7394
|
+
open,
|
|
7395
|
+
draft,
|
|
7396
|
+
setDraft,
|
|
7397
|
+
focusRequest,
|
|
7398
|
+
takeFocusRequest,
|
|
7399
|
+
inputRef,
|
|
7400
|
+
show,
|
|
7401
|
+
enter: (via = "focus") => {
|
|
7402
|
+
cancelClose();
|
|
7403
|
+
if (via === "pointer") pointerOver.current = true;
|
|
7404
|
+
if (returning.current) return;
|
|
7405
|
+
if (!latest.current.open && latest.current.controls?.feedback) show({
|
|
7406
|
+
comment: savedComment(),
|
|
7407
|
+
focus: false
|
|
7408
|
+
});
|
|
7409
|
+
},
|
|
7410
|
+
leave: (via = "focus") => {
|
|
7411
|
+
if (via === "pointer") pointerOver.current = false;
|
|
7412
|
+
else if (pointerOver.current) return;
|
|
7413
|
+
cancelClose();
|
|
7414
|
+
timer.current = setTimeout(() => {
|
|
7415
|
+
timer.current = void 0;
|
|
7416
|
+
if (!editing.current) close();
|
|
7417
|
+
}, FEEDBACK_COMMENT_CLOSE_DELAY_MS);
|
|
7418
|
+
},
|
|
7419
|
+
setEditing: (value) => {
|
|
7420
|
+
editing.current = value;
|
|
7421
|
+
},
|
|
7422
|
+
close,
|
|
7423
|
+
returnFocus: (target) => {
|
|
7424
|
+
returning.current = true;
|
|
7425
|
+
try {
|
|
7426
|
+
target?.focus();
|
|
7427
|
+
} finally {
|
|
7428
|
+
returning.current = false;
|
|
7429
|
+
}
|
|
7430
|
+
}
|
|
7431
|
+
};
|
|
7432
|
+
}
|
|
7433
|
+
|
|
6502
7434
|
//#endregion
|
|
6503
7435
|
//#region src/v2/components/chat/CopilotChatAssistantMessage.tsx
|
|
6504
7436
|
/**
|
|
7437
|
+
* In the `"turn"` tool-call display, text in a reply's working phase was
|
|
7438
|
+
* narration: it fades to muted once a call follows it, and folds away with the
|
|
7439
|
+
* rest of the work when the reply is done. The wrapper is there for every
|
|
7440
|
+
* message in that display, so text that turns into narration keeps its node
|
|
7441
|
+
* (and its place) rather than remounting.
|
|
7442
|
+
*/
|
|
7443
|
+
function WorkText({ messageId, children }) {
|
|
7444
|
+
const context = (0, react.useContext)(ToolCallDisplayContext);
|
|
7445
|
+
if (context?.display !== "turn") return children;
|
|
7446
|
+
const open = context.workTextOpen.get(messageId);
|
|
7447
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Collapsible, {
|
|
7448
|
+
open: open ?? true,
|
|
7449
|
+
className: "cpk:-mx-2",
|
|
7450
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7451
|
+
className: "cpk:px-2",
|
|
7452
|
+
"data-work-text": open === void 0 ? "reply" : "narration",
|
|
7453
|
+
children
|
|
7454
|
+
})
|
|
7455
|
+
});
|
|
7456
|
+
}
|
|
7457
|
+
/**
|
|
6505
7458
|
* Binds the Inspector action to the active chat without making the full
|
|
6506
7459
|
* assistant message subscribe to chat configuration changes.
|
|
6507
7460
|
*/
|
|
@@ -6516,31 +7469,216 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
6516
7469
|
})
|
|
6517
7470
|
});
|
|
6518
7471
|
}
|
|
6519
|
-
|
|
7472
|
+
/** Whether focus came from the keyboard; a pointer click also focuses buttons. */
|
|
7473
|
+
function isFocusVisible(element) {
|
|
7474
|
+
try {
|
|
7475
|
+
return element.matches(":focus-visible");
|
|
7476
|
+
} catch {
|
|
7477
|
+
return false;
|
|
7478
|
+
}
|
|
7479
|
+
}
|
|
7480
|
+
const HIDDEN_TOO = {
|
|
7481
|
+
checkVisibilityCSS: true,
|
|
7482
|
+
visibilityProperty: true
|
|
7483
|
+
};
|
|
7484
|
+
const FOCUSABLE = [
|
|
7485
|
+
"a[href]",
|
|
7486
|
+
"button:not([disabled])",
|
|
7487
|
+
"input:not([disabled])",
|
|
7488
|
+
"select:not([disabled])",
|
|
7489
|
+
"textarea:not([disabled])",
|
|
7490
|
+
"[tabindex]"
|
|
7491
|
+
].map((selector) => `${selector}:not([tabindex="-1"]):not([data-radix-focus-guard])`).join(", ");
|
|
7492
|
+
/** Approximately the element Tab reaches after `element`, outside `skip`. */
|
|
7493
|
+
function nextFocusable(element, skip) {
|
|
7494
|
+
const all = Array.from(element.ownerDocument.querySelectorAll(FOCUSABLE)).filter((candidate) => candidate === element || !skip?.contains(candidate) && !candidate.closest("[hidden], [inert]"));
|
|
7495
|
+
const index = all.indexOf(element);
|
|
7496
|
+
return index === -1 ? null : all[index + 1] ?? null;
|
|
7497
|
+
}
|
|
7498
|
+
/**
|
|
7499
|
+
* The comment popover of a rated message, pointing at the chosen thumb. Kept
|
|
7500
|
+
* apart so only it, not the whole message, follows chat configuration.
|
|
7501
|
+
*
|
|
7502
|
+
* The popover lives in a portal, so it keeps keyboard order by hand: Shift+Tab
|
|
7503
|
+
* from its start returns to the thumb, Tab from its end moves on to the
|
|
7504
|
+
* control after the thumb, and Enter or Escape inside it returns to the thumb.
|
|
7505
|
+
*/
|
|
7506
|
+
function FeedbackCommentPopover({ feedbackComment, comment, savedComment, rating, anchor, messageId }) {
|
|
7507
|
+
const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
|
|
7508
|
+
const contentRef = (0, react.useRef)(null);
|
|
7509
|
+
const focusInside = () => contentRef.current?.contains(document.activeElement) ?? false;
|
|
7510
|
+
const { focusRequest, takeFocusRequest, inputRef } = comment;
|
|
7511
|
+
const focusField = (0, react.useCallback)(() => {
|
|
7512
|
+
if (inputRef.current && takeFocusRequest()) inputRef.current.focus();
|
|
7513
|
+
}, [inputRef, takeFocusRequest]);
|
|
7514
|
+
(0, react.useEffect)(() => focusField(), [focusRequest, focusField]);
|
|
7515
|
+
/** Whether `target` is a thumb of this message, whose click decides itself. */
|
|
7516
|
+
const isOwnThumb = (target) => {
|
|
7517
|
+
return (target instanceof Element ? target.closest("[data-copilotkit-rating]") : null)?.closest("[data-message-id]")?.getAttribute("data-message-id") === messageId;
|
|
7518
|
+
};
|
|
7519
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Popover, {
|
|
7520
|
+
open: comment.open,
|
|
7521
|
+
onOpenChange: (open) => {
|
|
7522
|
+
if (!open) comment.close();
|
|
7523
|
+
},
|
|
7524
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(PopoverAnchor, { virtualRef: anchor }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PopoverContent, {
|
|
7525
|
+
ref: contentRef,
|
|
7526
|
+
side: "bottom",
|
|
7527
|
+
collisionPadding: 8,
|
|
7528
|
+
hideWhenDetached: true,
|
|
7529
|
+
"aria-label": labels.assistantMessageFeedbackCommentPlaceholder,
|
|
7530
|
+
"data-copilotkit-ignore": true,
|
|
7531
|
+
onOpenAutoFocus: (event) => {
|
|
7532
|
+
event.preventDefault();
|
|
7533
|
+
focusField();
|
|
7534
|
+
},
|
|
7535
|
+
onCloseAutoFocus: (event) => event.preventDefault(),
|
|
7536
|
+
onInteractOutside: (event) => {
|
|
7537
|
+
if (isOwnThumb(event.target)) event.preventDefault();
|
|
7538
|
+
},
|
|
7539
|
+
onEscapeKeyDown: (event) => {
|
|
7540
|
+
const returnFocus = focusInside();
|
|
7541
|
+
if (returnFocus) event.stopPropagation();
|
|
7542
|
+
comment.close({ save: false });
|
|
7543
|
+
if (returnFocus) comment.returnFocus(anchor.current);
|
|
7544
|
+
},
|
|
7545
|
+
onKeyDown: (event) => {
|
|
7546
|
+
if (event.key !== "Tab") return;
|
|
7547
|
+
const focusables = Array.from(contentRef.current?.querySelectorAll(FOCUSABLE) ?? []);
|
|
7548
|
+
if (!(event.shiftKey ? document.activeElement === focusables[0] : document.activeElement === focusables[focusables.length - 1]) || !anchor.current?.isConnected) return;
|
|
7549
|
+
event.preventDefault();
|
|
7550
|
+
const target = event.shiftKey ? anchor.current : nextFocusable(anchor.current, contentRef.current) ?? anchor.current;
|
|
7551
|
+
comment.close();
|
|
7552
|
+
if (target === anchor.current) comment.returnFocus(target);
|
|
7553
|
+
else target.focus();
|
|
7554
|
+
},
|
|
7555
|
+
onPointerEnter: () => comment.enter("pointer"),
|
|
7556
|
+
onPointerLeave: () => comment.leave("pointer"),
|
|
7557
|
+
className: "cpk:z-[1300]",
|
|
7558
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react.Fragment, { children: renderSlot(feedbackComment, CopilotChatAssistantMessage.FeedbackComment, {
|
|
7559
|
+
value: comment.draft,
|
|
7560
|
+
savedComment,
|
|
7561
|
+
inputRef: comment.inputRef,
|
|
7562
|
+
onChange: comment.setDraft,
|
|
7563
|
+
onSubmit: () => {
|
|
7564
|
+
comment.close();
|
|
7565
|
+
comment.returnFocus(anchor.current);
|
|
7566
|
+
},
|
|
7567
|
+
onEditingChange: comment.setEditing,
|
|
7568
|
+
onLeave: (next) => {
|
|
7569
|
+
if (next && (contentRef.current?.contains(next) || isOwnThumb(next))) return;
|
|
7570
|
+
comment.leave();
|
|
7571
|
+
}
|
|
7572
|
+
}) }, rating)
|
|
7573
|
+
})]
|
|
7574
|
+
});
|
|
7575
|
+
}
|
|
7576
|
+
function CopilotChatAssistantMessage({ message, messages, isRunning, isLatest, onThumbsUp, onThumbsDown, onReadAloud, onRegenerate, additionalToolbarItems, toolbarVisible = true, markdownRenderer, toolbar, copyButton, inspectorButton, thumbsUpButton, thumbsDownButton, readAloudButton, regenerateButton, feedbackComment: feedbackCommentSlot, toolCallsView, children, className, ...props }) {
|
|
6520
7577
|
useKatexStyles();
|
|
6521
7578
|
const { isInspectorEnabled, openInspector } = useCopilotKitInspector();
|
|
6522
7579
|
const shortcutsHidden = useInspectorShortcutsHidden();
|
|
6523
7580
|
const showInspectorShortcut = isInspectorEnabled && !shortcutsHidden;
|
|
7581
|
+
const feedback = useMessageFeedback(message);
|
|
7582
|
+
const comment = useFeedbackComment(feedback);
|
|
7583
|
+
const rating = feedback?.feedback?.rating;
|
|
7584
|
+
const root = (0, react.useRef)(null);
|
|
7585
|
+
const commentAnchor = (0, react.useRef)(null);
|
|
7586
|
+
const commentRating = (0, react.useRef)(rating);
|
|
7587
|
+
(0, react.useLayoutEffect)(() => {
|
|
7588
|
+
if (comment.open && !commentAnchor.current?.isConnected && rating) commentAnchor.current = root.current?.querySelector(`[data-copilotkit-rating="${rating}"]`) ?? root.current?.querySelector("button[aria-pressed=\"true\"]") ?? null;
|
|
7589
|
+
});
|
|
7590
|
+
/**
|
|
7591
|
+
* Thumbs are toggles: a new rating is saved and opens its comment, and
|
|
7592
|
+
* clicking the chosen thumb again removes the rating. A keyboard click
|
|
7593
|
+
* (`detail` 0) moves focus into the comment, as there is no pointer.
|
|
7594
|
+
* Custom thumb slots may call `onClick` without an event.
|
|
7595
|
+
*
|
|
7596
|
+
* @returns Whether the app's handler should run: true for a new rating and
|
|
7597
|
+
* whenever this chat does not record ratings, false when one is removed.
|
|
7598
|
+
*/
|
|
7599
|
+
const rate = (value, event) => {
|
|
7600
|
+
if (!feedback) return true;
|
|
7601
|
+
if (rating === value) {
|
|
7602
|
+
comment.close({ save: false });
|
|
7603
|
+
feedback.clear();
|
|
7604
|
+
return false;
|
|
7605
|
+
}
|
|
7606
|
+
feedback.rate(value);
|
|
7607
|
+
commentRating.current = value;
|
|
7608
|
+
commentAnchor.current = event?.currentTarget ?? null;
|
|
7609
|
+
comment.show({
|
|
7610
|
+
comment: "",
|
|
7611
|
+
focus: event?.detail === 0
|
|
7612
|
+
});
|
|
7613
|
+
return true;
|
|
7614
|
+
};
|
|
7615
|
+
/** Props that let the chosen thumb open and point at its comment. */
|
|
7616
|
+
const thumbFeedbackProps = (value) => {
|
|
7617
|
+
if (!feedback) return {};
|
|
7618
|
+
const thumb = { "data-copilotkit-rating": value };
|
|
7619
|
+
if (rating !== value) return {
|
|
7620
|
+
...thumb,
|
|
7621
|
+
"aria-pressed": false
|
|
7622
|
+
};
|
|
7623
|
+
const enter = (target, via) => {
|
|
7624
|
+
if (!comment.open) commentRating.current = value;
|
|
7625
|
+
commentAnchor.current = target;
|
|
7626
|
+
comment.enter(via);
|
|
7627
|
+
};
|
|
7628
|
+
return {
|
|
7629
|
+
...thumb,
|
|
7630
|
+
"aria-pressed": true,
|
|
7631
|
+
"aria-haspopup": "dialog",
|
|
7632
|
+
"aria-expanded": comment.open,
|
|
7633
|
+
onPointerEnter: (event) => {
|
|
7634
|
+
if (event.pointerType !== "touch") enter(event.currentTarget, "pointer");
|
|
7635
|
+
},
|
|
7636
|
+
onPointerLeave: (event) => {
|
|
7637
|
+
if (event.pointerType !== "touch") comment.leave("pointer");
|
|
7638
|
+
},
|
|
7639
|
+
onFocus: (event) => {
|
|
7640
|
+
if (isFocusVisible(event.currentTarget)) enter(event.currentTarget, "focus");
|
|
7641
|
+
},
|
|
7642
|
+
onBlur: () => comment.leave(),
|
|
7643
|
+
onKeyDown: (event) => {
|
|
7644
|
+
const input = comment.inputRef.current;
|
|
7645
|
+
if (event.key === "Tab" && !event.shiftKey && comment.open && input && input.checkVisibility?.(HIDDEN_TOO) !== false) {
|
|
7646
|
+
event.preventDefault();
|
|
7647
|
+
input.focus();
|
|
7648
|
+
}
|
|
7649
|
+
}
|
|
7650
|
+
};
|
|
7651
|
+
};
|
|
6524
7652
|
const boundMarkdownRenderer = renderSlot(markdownRenderer, CopilotChatAssistantMessage.MarkdownRenderer, { content: message.content || "" });
|
|
6525
7653
|
const boundCopyButton = renderSlot(copyButton, CopilotChatAssistantMessage.CopyButton, { onClick: async () => {
|
|
6526
7654
|
if (message.content) return await (0, _copilotkit_shared.copyToClipboard)(message.content);
|
|
6527
7655
|
return false;
|
|
6528
7656
|
} });
|
|
6529
|
-
const boundThumbsUpButton = renderSlot(thumbsUpButton, CopilotChatAssistantMessage.ThumbsUpButton, {
|
|
7657
|
+
const boundThumbsUpButton = renderSlot(thumbsUpButton, CopilotChatAssistantMessage.ThumbsUpButton, {
|
|
7658
|
+
onClick: onThumbsUp || feedback ? (event) => {
|
|
7659
|
+
if (rate("up", event)) onThumbsUp?.(message);
|
|
7660
|
+
} : void 0,
|
|
7661
|
+
...thumbFeedbackProps("up")
|
|
7662
|
+
});
|
|
6530
7663
|
const boundInspectorButton = showInspectorShortcut ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(BoundInspectorButton, {
|
|
6531
7664
|
inspectorButton,
|
|
6532
7665
|
messageId: message.id,
|
|
6533
7666
|
openInspector
|
|
6534
7667
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, {});
|
|
6535
|
-
const boundThumbsDownButton = renderSlot(thumbsDownButton, CopilotChatAssistantMessage.ThumbsDownButton, {
|
|
7668
|
+
const boundThumbsDownButton = renderSlot(thumbsDownButton, CopilotChatAssistantMessage.ThumbsDownButton, {
|
|
7669
|
+
onClick: onThumbsDown || feedback ? (event) => {
|
|
7670
|
+
if (rate("down", event)) onThumbsDown?.(message);
|
|
7671
|
+
} : void 0,
|
|
7672
|
+
...thumbFeedbackProps("down")
|
|
7673
|
+
});
|
|
6536
7674
|
const boundReadAloudButton = renderSlot(readAloudButton, CopilotChatAssistantMessage.ReadAloudButton, { onClick: onReadAloud ? () => onReadAloud(message) : void 0 });
|
|
6537
7675
|
const boundRegenerateButton = renderSlot(regenerateButton, CopilotChatAssistantMessage.RegenerateButton, { onClick: onRegenerate ? () => onRegenerate(message) : void 0 });
|
|
6538
7676
|
const boundToolbar = renderSlot(toolbar, CopilotChatAssistantMessage.Toolbar, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6539
7677
|
className: "cpk:flex cpk:w-full cpk:items-center cpk:gap-1",
|
|
6540
7678
|
children: [
|
|
6541
7679
|
boundCopyButton,
|
|
6542
|
-
(onThumbsUp || thumbsUpButton) && boundThumbsUpButton,
|
|
6543
|
-
(onThumbsDown || thumbsDownButton) && boundThumbsDownButton,
|
|
7680
|
+
(onThumbsUp || thumbsUpButton || feedback) && boundThumbsUpButton,
|
|
7681
|
+
(onThumbsDown || thumbsDownButton || feedback) && boundThumbsDownButton,
|
|
6544
7682
|
(onReadAloud || readAloudButton) && boundReadAloudButton,
|
|
6545
7683
|
(onRegenerate || regenerateButton) && boundRegenerateButton,
|
|
6546
7684
|
additionalToolbarItems,
|
|
@@ -6554,11 +7692,31 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
6554
7692
|
const hasContent = !!(message.content && message.content.trim().length > 0);
|
|
6555
7693
|
const isLatestAssistantMessage = message.role === "assistant" && (isLatest ?? messages?.[messages.length - 1]?.id === message.id);
|
|
6556
7694
|
const shouldShowToolbar = toolbarVisible && (hasContent || showInspectorShortcut) && !(isRunning && isLatestAssistantMessage);
|
|
6557
|
-
|
|
7695
|
+
const { open: commentOpen, close: closeComment } = comment;
|
|
7696
|
+
(0, react.useEffect)(() => {
|
|
7697
|
+
if (!commentOpen) return;
|
|
7698
|
+
if (rating !== commentRating.current) closeComment({ save: false });
|
|
7699
|
+
else if (!shouldShowToolbar) closeComment();
|
|
7700
|
+
}, [
|
|
7701
|
+
commentOpen,
|
|
7702
|
+
shouldShowToolbar,
|
|
7703
|
+
rating,
|
|
7704
|
+
closeComment
|
|
7705
|
+
]);
|
|
7706
|
+
const feedbackComment = feedback?.feedback && shouldShowToolbar && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FeedbackCommentPopover, {
|
|
7707
|
+
feedbackComment: feedbackCommentSlot,
|
|
7708
|
+
comment,
|
|
7709
|
+
savedComment: feedback.feedback.comment ?? "",
|
|
7710
|
+
rating: feedback.feedback.rating,
|
|
7711
|
+
anchor: commentAnchor,
|
|
7712
|
+
messageId: message.id
|
|
7713
|
+
});
|
|
7714
|
+
if (children) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7715
|
+
ref: root,
|
|
6558
7716
|
"data-copilotkit": true,
|
|
6559
7717
|
"data-message-id": message.id,
|
|
6560
7718
|
style: { display: "contents" },
|
|
6561
|
-
children: children({
|
|
7719
|
+
children: [children({
|
|
6562
7720
|
markdownRenderer: boundMarkdownRenderer,
|
|
6563
7721
|
toolbar: boundToolbar,
|
|
6564
7722
|
toolCallsView: boundToolCallsView,
|
|
@@ -6577,21 +7735,26 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
6577
7735
|
onRegenerate,
|
|
6578
7736
|
additionalToolbarItems,
|
|
6579
7737
|
toolbarVisible: shouldShowToolbar
|
|
6580
|
-
})
|
|
7738
|
+
}), feedbackComment]
|
|
6581
7739
|
});
|
|
6582
7740
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7741
|
+
ref: root,
|
|
6583
7742
|
"data-copilotkit": true,
|
|
6584
7743
|
"data-testid": "copilot-assistant-message",
|
|
6585
7744
|
className: (0, tailwind_merge.twMerge)("copilotKitMessage copilotKitAssistantMessage", className),
|
|
6586
7745
|
...props,
|
|
6587
7746
|
"data-message-id": message.id,
|
|
6588
7747
|
children: [
|
|
6589
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
6590
|
-
|
|
6591
|
-
children:
|
|
7748
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(WorkText, {
|
|
7749
|
+
messageId: message.id,
|
|
7750
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
7751
|
+
className: "cpk:prose cpk:max-w-full cpk:break-words cpk:dark:prose-invert",
|
|
7752
|
+
children: boundMarkdownRenderer
|
|
7753
|
+
})
|
|
6592
7754
|
}),
|
|
6593
7755
|
boundToolCallsView,
|
|
6594
|
-
shouldShowToolbar && boundToolbar
|
|
7756
|
+
shouldShowToolbar && boundToolbar,
|
|
7757
|
+
feedbackComment
|
|
6595
7758
|
]
|
|
6596
7759
|
});
|
|
6597
7760
|
}
|
|
@@ -6607,20 +7770,27 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
6607
7770
|
...props
|
|
6608
7771
|
});
|
|
6609
7772
|
const ToolbarButton = _CopilotChatAssistantMessage.ToolbarButton = ({ title, tooltip, tooltipClassName, children, ...props }) => {
|
|
6610
|
-
|
|
6611
|
-
|
|
6612
|
-
|
|
6613
|
-
|
|
6614
|
-
|
|
6615
|
-
|
|
6616
|
-
|
|
6617
|
-
|
|
6618
|
-
|
|
6619
|
-
|
|
6620
|
-
|
|
6621
|
-
|
|
6622
|
-
|
|
6623
|
-
|
|
7773
|
+
const [tooltipOpen, setTooltipOpen] = (0, react.useState)(false);
|
|
7774
|
+
const popupOpen = props["aria-expanded"] === true;
|
|
7775
|
+
if (popupOpen && tooltipOpen) setTooltipOpen(false);
|
|
7776
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(Tooltip, {
|
|
7777
|
+
open: tooltipOpen && !popupOpen,
|
|
7778
|
+
onOpenChange: (open) => setTooltipOpen(open && !popupOpen),
|
|
7779
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(TooltipTrigger, {
|
|
7780
|
+
asChild: true,
|
|
7781
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
|
|
7782
|
+
type: "button",
|
|
7783
|
+
variant: "assistantMessageToolbarButton",
|
|
7784
|
+
"aria-label": title,
|
|
7785
|
+
...props,
|
|
7786
|
+
children
|
|
7787
|
+
})
|
|
7788
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(TooltipContent, {
|
|
7789
|
+
side: "bottom",
|
|
7790
|
+
className: tooltipClassName,
|
|
7791
|
+
children: tooltip ?? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: title })
|
|
7792
|
+
})]
|
|
7793
|
+
});
|
|
6624
7794
|
};
|
|
6625
7795
|
_CopilotChatAssistantMessage.CopyButton = ({ className, title, onClick, ...props }) => {
|
|
6626
7796
|
const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
|
|
@@ -6659,7 +7829,10 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
6659
7829
|
"data-testid": "copilot-thumbs-up-button",
|
|
6660
7830
|
title: title || labels.assistantMessageToolbarThumbsUpLabel,
|
|
6661
7831
|
...props,
|
|
6662
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ThumbsUp, {
|
|
7832
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ThumbsUp, {
|
|
7833
|
+
className: "cpk:size-[18px]",
|
|
7834
|
+
fill: props["aria-pressed"] === true ? "currentColor" : "none"
|
|
7835
|
+
})
|
|
6663
7836
|
});
|
|
6664
7837
|
};
|
|
6665
7838
|
_CopilotChatAssistantMessage.ThumbsDownButton = ({ title, ...props }) => {
|
|
@@ -6668,7 +7841,45 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
6668
7841
|
"data-testid": "copilot-thumbs-down-button",
|
|
6669
7842
|
title: title || labels.assistantMessageToolbarThumbsDownLabel,
|
|
6670
7843
|
...props,
|
|
6671
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ThumbsDown, {
|
|
7844
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ThumbsDown, {
|
|
7845
|
+
className: "cpk:size-[18px]",
|
|
7846
|
+
fill: props["aria-pressed"] === true ? "currentColor" : "none"
|
|
7847
|
+
})
|
|
7848
|
+
});
|
|
7849
|
+
};
|
|
7850
|
+
_CopilotChatAssistantMessage.FeedbackComment = ({ value, savedComment, inputRef, onChange, onSubmit, onEditingChange, onLeave, className }) => {
|
|
7851
|
+
const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
|
|
7852
|
+
const changed = value.trim() !== savedComment;
|
|
7853
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
|
|
7854
|
+
"data-testid": "copilot-feedback-comment",
|
|
7855
|
+
className: (0, tailwind_merge.twMerge)("cpk:flex cpk:w-80 cpk:max-w-[calc(100vw-1rem)] cpk:items-center cpk:gap-1 cpk:rounded-full cpk:border cpk:border-border cpk:bg-background cpk:py-0.5 cpk:pl-3 cpk:pr-0.5 cpk:text-sm cpk:shadow-md", className),
|
|
7856
|
+
onSubmit: (event) => {
|
|
7857
|
+
event.preventDefault();
|
|
7858
|
+
onSubmit();
|
|
7859
|
+
},
|
|
7860
|
+
onFocus: () => onEditingChange?.(true),
|
|
7861
|
+
onBlur: (event) => {
|
|
7862
|
+
const next = event.relatedTarget instanceof Element ? event.relatedTarget : null;
|
|
7863
|
+
if (event.currentTarget.contains(next)) return;
|
|
7864
|
+
if (typeof document !== "undefined" && !document.hasFocus()) return;
|
|
7865
|
+
onEditingChange?.(false);
|
|
7866
|
+
onLeave?.(next);
|
|
7867
|
+
},
|
|
7868
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
7869
|
+
ref: inputRef,
|
|
7870
|
+
value,
|
|
7871
|
+
maxLength: MESSAGE_FEEDBACK_MAX_COMMENT_LENGTH,
|
|
7872
|
+
onChange: (event) => onChange(event.target.value),
|
|
7873
|
+
placeholder: labels.assistantMessageFeedbackCommentPlaceholder,
|
|
7874
|
+
"aria-label": labels.assistantMessageFeedbackCommentPlaceholder,
|
|
7875
|
+
className: "cpk:min-w-0 cpk:flex-1 cpk:bg-transparent cpk:py-1 cpk:text-foreground cpk:outline-none cpk:placeholder:text-muted-foreground"
|
|
7876
|
+
}), changed && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
|
|
7877
|
+
type: "submit",
|
|
7878
|
+
variant: "assistantMessageToolbarButton",
|
|
7879
|
+
"aria-label": labels.assistantMessageFeedbackCommentSubmitLabel,
|
|
7880
|
+
title: labels.assistantMessageFeedbackCommentSubmitLabel,
|
|
7881
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ArrowUp, { className: "cpk:size-[16px]" })
|
|
7882
|
+
})]
|
|
6672
7883
|
});
|
|
6673
7884
|
};
|
|
6674
7885
|
_CopilotChatAssistantMessage.ReadAloudButton = ({ title, ...props }) => {
|
|
@@ -6696,6 +7907,7 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
6696
7907
|
CopilotChatAssistantMessage.InspectorButton.displayName = "CopilotChatAssistantMessage.InspectorButton";
|
|
6697
7908
|
CopilotChatAssistantMessage.ThumbsUpButton.displayName = "CopilotChatAssistantMessage.ThumbsUpButton";
|
|
6698
7909
|
CopilotChatAssistantMessage.ThumbsDownButton.displayName = "CopilotChatAssistantMessage.ThumbsDownButton";
|
|
7910
|
+
CopilotChatAssistantMessage.FeedbackComment.displayName = "CopilotChatAssistantMessage.FeedbackComment";
|
|
6699
7911
|
CopilotChatAssistantMessage.ReadAloudButton.displayName = "CopilotChatAssistantMessage.ReadAloudButton";
|
|
6700
7912
|
CopilotChatAssistantMessage.RegenerateButton.displayName = "CopilotChatAssistantMessage.RegenerateButton";
|
|
6701
7913
|
var CopilotChatAssistantMessage_default = CopilotChatAssistantMessage;
|
|
@@ -7001,6 +8213,7 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
7001
8213
|
});
|
|
7002
8214
|
};
|
|
7003
8215
|
_CopilotChatUserMessage.BranchNavigation = ({ className, currentBranch = 0, numberOfBranches = 1, onSwitchToBranch, message, ...props }) => {
|
|
8216
|
+
const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
|
|
7004
8217
|
if (!numberOfBranches || numberOfBranches <= 1 || !onSwitchToBranch) return null;
|
|
7005
8218
|
const canGoPrev = currentBranch > 0;
|
|
7006
8219
|
const canGoNext = currentBranch < numberOfBranches - 1;
|
|
@@ -7019,6 +8232,7 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
7019
8232
|
}),
|
|
7020
8233
|
disabled: !canGoPrev,
|
|
7021
8234
|
className: "cpk:h-6 cpk:w-6 cpk:p-0",
|
|
8235
|
+
"aria-label": labels.userMessageToolbarPreviousBranchLabel,
|
|
7022
8236
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronLeft, { className: "cpk:size-[20px]" })
|
|
7023
8237
|
}),
|
|
7024
8238
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
@@ -7039,6 +8253,7 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
7039
8253
|
}),
|
|
7040
8254
|
disabled: !canGoNext,
|
|
7041
8255
|
className: "cpk:h-6 cpk:w-6 cpk:p-0",
|
|
8256
|
+
"aria-label": labels.userMessageToolbarNextBranchLabel,
|
|
7042
8257
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronRight, { className: "cpk:size-[20px]" })
|
|
7043
8258
|
})
|
|
7044
8259
|
]
|
|
@@ -7059,7 +8274,7 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
7059
8274
|
/**
|
|
7060
8275
|
* Formats an elapsed duration (in seconds) to a human-readable string.
|
|
7061
8276
|
*/
|
|
7062
|
-
function formatDuration(seconds) {
|
|
8277
|
+
function formatDuration$1(seconds) {
|
|
7063
8278
|
if (seconds < 1) return "a few seconds";
|
|
7064
8279
|
if (seconds < 60) return `${Math.round(seconds)} seconds`;
|
|
7065
8280
|
const mins = Math.floor(seconds / 60);
|
|
@@ -7097,7 +8312,7 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
7097
8312
|
userToggledRef.current = true;
|
|
7098
8313
|
setIsOpen((prev) => !prev);
|
|
7099
8314
|
} : void 0;
|
|
7100
|
-
const label = isStreaming ? "Thinking…" : `Thought for ${formatDuration(elapsed)}`;
|
|
8315
|
+
const label = isStreaming ? "Thinking…" : `Thought for ${formatDuration$1(elapsed)}`;
|
|
7101
8316
|
const boundHeader = renderSlot(header, CopilotChatReasoningMessage.Header, {
|
|
7102
8317
|
isOpen,
|
|
7103
8318
|
label,
|
|
@@ -7319,6 +8534,71 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
7319
8534
|
*/
|
|
7320
8535
|
const ScrollPinnedContext = react.default.createContext(false);
|
|
7321
8536
|
|
|
8537
|
+
//#endregion
|
|
8538
|
+
//#region src/v2/components/chat/CopilotChatWorkSummary.tsx
|
|
8539
|
+
/** "45s", "1m 5s", "2m". Used for the live timer and the final duration. */
|
|
8540
|
+
function formatDuration(ms) {
|
|
8541
|
+
const seconds = Math.max(0, Math.floor(ms / 1e3));
|
|
8542
|
+
if (seconds < 60) return `${seconds}s`;
|
|
8543
|
+
const minutes = Math.floor(seconds / 60);
|
|
8544
|
+
const rest = seconds % 60;
|
|
8545
|
+
return rest ? `${minutes}m ${rest}s` : `${minutes}m`;
|
|
8546
|
+
}
|
|
8547
|
+
/** Re-renders every second while `active`, returning the current time. */
|
|
8548
|
+
function useNow(active) {
|
|
8549
|
+
const [now, setNow] = (0, react.useState)(() => Date.now());
|
|
8550
|
+
(0, react.useEffect)(() => {
|
|
8551
|
+
if (!active) return;
|
|
8552
|
+
setNow(Date.now());
|
|
8553
|
+
const timer = setInterval(() => setNow(Date.now()), 1e3);
|
|
8554
|
+
return () => clearInterval(timer);
|
|
8555
|
+
}, [active]);
|
|
8556
|
+
return now;
|
|
8557
|
+
}
|
|
8558
|
+
/**
|
|
8559
|
+
* The line at the top of a reply in the `"turn"` tool-call display. While the
|
|
8560
|
+
* agent works it reads "Working 4s"; once the reply is done it reads "Worked
|
|
8561
|
+
* for 9s · 7 tools" and toggles the work it folded away.
|
|
8562
|
+
*/
|
|
8563
|
+
function CopilotChatWorkSummary({ isWorking, isOpen, calls, elapsedMs, workingSince, className, ...props }) {
|
|
8564
|
+
const now = useNow(isWorking);
|
|
8565
|
+
const failed = calls.filter((call) => call.toolMessage?.error).length;
|
|
8566
|
+
const liveMs = elapsedMs !== void 0 && workingSince !== void 0 ? elapsedMs + Math.max(0, now - workingSince) : void 0;
|
|
8567
|
+
const duration = elapsedMs !== void 0 ? formatDuration(Math.max(1e3, elapsedMs)) : void 0;
|
|
8568
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
8569
|
+
type: "button",
|
|
8570
|
+
"data-copilotkit": true,
|
|
8571
|
+
"data-testid": "copilot-work-summary",
|
|
8572
|
+
"data-state": isWorking ? "working" : "done",
|
|
8573
|
+
"aria-expanded": isOpen,
|
|
8574
|
+
className: (0, tailwind_merge.twMerge)("cpk:m-0 cpk:inline-flex cpk:max-w-full cpk:cursor-pointer cpk:items-center cpk:gap-1.5 cpk:rounded-md cpk:border-none cpk:bg-transparent cpk:p-0 cpk:py-0.5 cpk:text-sm cpk:text-muted-foreground cpk:transition-colors cpk:hover:text-foreground cpk:focus-visible:outline-2 cpk:focus-visible:outline-ring", className),
|
|
8575
|
+
...props,
|
|
8576
|
+
children: [isWorking ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8577
|
+
className: "cpk:font-medium cpk-shimmer",
|
|
8578
|
+
children: "Working"
|
|
8579
|
+
}), liveMs !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8580
|
+
className: "cpk:text-xs cpk:tabular-nums cpk:opacity-70",
|
|
8581
|
+
children: formatDuration(liveMs)
|
|
8582
|
+
})] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
8583
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8584
|
+
className: "cpk:font-medium",
|
|
8585
|
+
children: duration ? `Worked for ${duration}` : `Used ${pluralize(calls.length, "tool")}`
|
|
8586
|
+
}),
|
|
8587
|
+
duration && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8588
|
+
className: "cpk:text-xs cpk:opacity-70",
|
|
8589
|
+
children: pluralize(calls.length, "tool")
|
|
8590
|
+
}),
|
|
8591
|
+
failed > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
8592
|
+
className: "cpk:text-destructive",
|
|
8593
|
+
children: [failed, " failed"]
|
|
8594
|
+
})
|
|
8595
|
+
] }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronRight, {
|
|
8596
|
+
"aria-hidden": "true",
|
|
8597
|
+
className: (0, tailwind_merge.twMerge)("cpk:size-3.5 cpk:shrink-0 cpk:transition-transform cpk:duration-200", isOpen && "cpk:rotate-90")
|
|
8598
|
+
})]
|
|
8599
|
+
});
|
|
8600
|
+
}
|
|
8601
|
+
|
|
7322
8602
|
//#endregion
|
|
7323
8603
|
//#region src/v2/components/intelligence-indicator/IntelligenceIndicatorView.tsx
|
|
7324
8604
|
/**
|
|
@@ -7805,7 +9085,7 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
7805
9085
|
}
|
|
7806
9086
|
const GROUP_ROW_KEY_PREFIX = "copilotkit-group:";
|
|
7807
9087
|
const VIRTUALIZE_THRESHOLD = 50;
|
|
7808
|
-
function CopilotChatMessageView({ messages = [], assistantMessage, userMessage, reasoningMessage, cursor, intelligenceIndicator, isRunning = false, transformMessages, groupMessages, children, className, ...props }) {
|
|
9088
|
+
function CopilotChatMessageView({ messages = [], assistantMessage, userMessage, reasoningMessage, cursor, intelligenceIndicator, workSummary, isRunning = false, transformMessages, groupMessages, messageFeedback = true, toolCallDisplay = "grouped", children, className, ...props }) {
|
|
7809
9089
|
const isPinnedToBottom = (0, react.useContext)(ScrollPinnedContext);
|
|
7810
9090
|
const renderCustomMessage = useRenderCustomMessages();
|
|
7811
9091
|
const { renderActivityMessage } = useRenderActivityMessage();
|
|
@@ -7846,6 +9126,100 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
7846
9126
|
transformedMessages
|
|
7847
9127
|
]);
|
|
7848
9128
|
const latestRenderedId = renderedMessages[renderedMessages.length - 1]?.id;
|
|
9129
|
+
const rendererNames = useToolCallRendererNames();
|
|
9130
|
+
const toolCallLayouts = (0, react.useMemo)(() => toolCallDisplay === "separate" ? /* @__PURE__ */ new Map() : getToolCallLayouts(renderedMessages, messages, rendererNames), [
|
|
9131
|
+
toolCallDisplay,
|
|
9132
|
+
renderedMessages,
|
|
9133
|
+
messages,
|
|
9134
|
+
rendererNames
|
|
9135
|
+
]);
|
|
9136
|
+
const turnWork = (0, react.useMemo)(() => toolCallDisplay === "turn" ? getTurnWork(renderedMessages, toolCallLayouts) : void 0, [
|
|
9137
|
+
toolCallDisplay,
|
|
9138
|
+
renderedMessages,
|
|
9139
|
+
toolCallLayouts
|
|
9140
|
+
]);
|
|
9141
|
+
const turnByFirstMessage = (0, react.useMemo)(() => {
|
|
9142
|
+
const byFirst = /* @__PURE__ */ new Map();
|
|
9143
|
+
for (const turn of turnWork?.values() ?? []) byFirst.set(turn.firstMessageId, turn);
|
|
9144
|
+
return byFirst;
|
|
9145
|
+
}, [turnWork]);
|
|
9146
|
+
let latestTurnKey = "start";
|
|
9147
|
+
for (let i = renderedMessages.length - 1; i >= 0; i--) if (renderedMessages[i].role === "user") {
|
|
9148
|
+
latestTurnKey = renderedMessages[i].id;
|
|
9149
|
+
break;
|
|
9150
|
+
}
|
|
9151
|
+
const isWorkingOn = (turnKey) => isRunning && turnKey === latestTurnKey;
|
|
9152
|
+
const [toggledTurns, setToggledTurns] = (0, react.useState)(() => /* @__PURE__ */ new Map());
|
|
9153
|
+
const isWorkOpen = (turnKey) => toggledTurns.get(turnKey) ?? isWorkingOn(turnKey);
|
|
9154
|
+
const workTimesRef = (0, react.useRef)(/* @__PURE__ */ new Map());
|
|
9155
|
+
if (toolCallDisplay === "turn") {
|
|
9156
|
+
const now = Date.now();
|
|
9157
|
+
const workTimes = workTimesRef.current;
|
|
9158
|
+
if (isRunning) {
|
|
9159
|
+
const times = workTimes.get(latestTurnKey);
|
|
9160
|
+
if (times) times.workingSince ?? (times.workingSince = now);
|
|
9161
|
+
else if (renderedMessages[renderedMessages.length - 1]?.role === "user") workTimes.set(latestTurnKey, {
|
|
9162
|
+
elapsedMs: 0,
|
|
9163
|
+
workingSince: now
|
|
9164
|
+
});
|
|
9165
|
+
} else for (const times of workTimes.values()) {
|
|
9166
|
+
if (times.workingSince === void 0) continue;
|
|
9167
|
+
times.elapsedMs += now - times.workingSince;
|
|
9168
|
+
times.workingSince = void 0;
|
|
9169
|
+
}
|
|
9170
|
+
}
|
|
9171
|
+
const { workOpen, workTextOpen } = (0, react.useMemo)(() => {
|
|
9172
|
+
const open = /* @__PURE__ */ new Map();
|
|
9173
|
+
const textOpen = /* @__PURE__ */ new Map();
|
|
9174
|
+
for (const turn of turnWork?.values() ?? []) {
|
|
9175
|
+
const turnOpen = toggledTurns.get(turn.key) ?? (isRunning && turn.key === latestTurnKey);
|
|
9176
|
+
for (const id of turn.workMessageIds) {
|
|
9177
|
+
open.set(id, turnOpen);
|
|
9178
|
+
if (id !== turn.replyTextMessageId) textOpen.set(id, turnOpen);
|
|
9179
|
+
}
|
|
9180
|
+
}
|
|
9181
|
+
return {
|
|
9182
|
+
workOpen: open,
|
|
9183
|
+
workTextOpen: textOpen
|
|
9184
|
+
};
|
|
9185
|
+
}, [
|
|
9186
|
+
turnWork,
|
|
9187
|
+
toggledTurns,
|
|
9188
|
+
isRunning,
|
|
9189
|
+
latestTurnKey
|
|
9190
|
+
]);
|
|
9191
|
+
const toolCallDisplayContext = (0, react.useMemo)(() => ({
|
|
9192
|
+
display: toolCallDisplay,
|
|
9193
|
+
isRunning,
|
|
9194
|
+
layouts: toolCallLayouts,
|
|
9195
|
+
workOpen,
|
|
9196
|
+
workTextOpen
|
|
9197
|
+
}), [
|
|
9198
|
+
toolCallDisplay,
|
|
9199
|
+
isRunning,
|
|
9200
|
+
toolCallLayouts,
|
|
9201
|
+
workOpen,
|
|
9202
|
+
workTextOpen
|
|
9203
|
+
]);
|
|
9204
|
+
const renderWorkSummary = (turnKey, calls) => {
|
|
9205
|
+
const working = isWorkingOn(turnKey);
|
|
9206
|
+
const open = isWorkOpen(turnKey);
|
|
9207
|
+
const times = workTimesRef.current.get(turnKey);
|
|
9208
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Collapsible, {
|
|
9209
|
+
open: working || calls.length > 0,
|
|
9210
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
9211
|
+
className: "cpk:pt-1 cpk:pb-2",
|
|
9212
|
+
children: renderSlot(workSummary, CopilotChatWorkSummary, {
|
|
9213
|
+
isWorking: working,
|
|
9214
|
+
isOpen: open,
|
|
9215
|
+
calls,
|
|
9216
|
+
elapsedMs: times?.elapsedMs,
|
|
9217
|
+
workingSince: times?.workingSince,
|
|
9218
|
+
onClick: () => setToggledTurns((toggled) => new Map(toggled).set(turnKey, !open))
|
|
9219
|
+
})
|
|
9220
|
+
})
|
|
9221
|
+
}, `work-summary-${turnKey}`);
|
|
9222
|
+
};
|
|
7849
9223
|
const transformDuplicateId = (0, react.useMemo)(() => {
|
|
7850
9224
|
if (process.env.NODE_ENV === "production" || !transformMessages && !groupMessages) return;
|
|
7851
9225
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -7883,8 +9257,6 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
7883
9257
|
(0, _copilotkit_shared.commitRowKeyStore)(rowKeyStore, renderedMessages);
|
|
7884
9258
|
}, [rowKeyStore, renderedMessages]);
|
|
7885
9259
|
const stableGroupKey = (key) => rowRenderKeys.get(key) ?? key;
|
|
7886
|
-
const rowKey = (row) => row.type === "group" ? `${GROUP_ROW_KEY_PREFIX}${stableGroupKey(row.key)}` : rowRenderKeys.get(row.message.id) ?? row.message.id;
|
|
7887
|
-
const rowKeys = (0, react.useMemo)(() => rows.map(rowKey), [rows, rowRenderKeys]);
|
|
7888
9260
|
const groupStateRef = (0, react.useRef)(/* @__PURE__ */ new Map());
|
|
7889
9261
|
const groupSettersRef = (0, react.useRef)(/* @__PURE__ */ new Map());
|
|
7890
9262
|
const groupStateThreadRef = (0, react.useRef)(config?.threadId);
|
|
@@ -7913,6 +9285,18 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
7913
9285
|
const { Component: AssistantComponent, slotProps: assistantSlotProps } = (0, react.useMemo)(() => resolveSlotComponent(assistantMessage, CopilotChatAssistantMessage_default), [assistantMessage]);
|
|
7914
9286
|
const agentId = config?.agentId;
|
|
7915
9287
|
const threadId = config?.threadId;
|
|
9288
|
+
const learningFeedbackEnabled = useLearningFeedbackEnabled(copilotkit);
|
|
9289
|
+
const feedbackScope = (0, react.useMemo)(() => messageFeedback && learningFeedbackEnabled && agentId !== void 0 && threadId !== void 0 ? {
|
|
9290
|
+
copilotkit,
|
|
9291
|
+
agentId,
|
|
9292
|
+
threadId
|
|
9293
|
+
} : null, [
|
|
9294
|
+
messageFeedback,
|
|
9295
|
+
learningFeedbackEnabled,
|
|
9296
|
+
copilotkit,
|
|
9297
|
+
agentId,
|
|
9298
|
+
threadId
|
|
9299
|
+
]);
|
|
7916
9300
|
const assistantSlotPropsWithFeedback = (0, react.useMemo)(() => {
|
|
7917
9301
|
const onThumbsUp = assistantSlotProps?.onThumbsUp;
|
|
7918
9302
|
const onThumbsDown = assistantSlotProps?.onThumbsDown;
|
|
@@ -7958,8 +9342,6 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
7958
9342
|
total: 0,
|
|
7959
9343
|
sizes: /* @__PURE__ */ new Map()
|
|
7960
9344
|
});
|
|
7961
|
-
const rowKeysRef = react.default.useRef(rowKeys);
|
|
7962
|
-
rowKeysRef.current = rowKeys;
|
|
7963
9345
|
const firstMessageId = deduplicatedMessages[0]?.id;
|
|
7964
9346
|
const measuredThreadRef = react.default.useRef(firstMessageId);
|
|
7965
9347
|
if (measuredThreadRef.current !== firstMessageId) {
|
|
@@ -7969,16 +9351,6 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
7969
9351
|
sizes: /* @__PURE__ */ new Map()
|
|
7970
9352
|
};
|
|
7971
9353
|
}
|
|
7972
|
-
const measuredKeysRef = react.default.useRef(rowKeys);
|
|
7973
|
-
if (measuredKeysRef.current !== rowKeys) {
|
|
7974
|
-
measuredKeysRef.current = rowKeys;
|
|
7975
|
-
const live = new Set(rowKeys);
|
|
7976
|
-
const measured = measuredRef.current;
|
|
7977
|
-
for (const [key, height] of measured.sizes) if (!live.has(key)) {
|
|
7978
|
-
measured.sizes.delete(key);
|
|
7979
|
-
measured.total -= height;
|
|
7980
|
-
}
|
|
7981
|
-
}
|
|
7982
9354
|
const estimateRowSize = react.default.useCallback(() => {
|
|
7983
9355
|
const { total, sizes } = measuredRef.current;
|
|
7984
9356
|
return sizes.size > 0 ? Math.max(1, Math.round(total / sizes.size)) : 100;
|
|
@@ -7986,15 +9358,13 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
7986
9358
|
const measureRowElement = react.default.useCallback((el) => {
|
|
7987
9359
|
const height = el?.getBoundingClientRect().height ?? 0;
|
|
7988
9360
|
const index = Number(el?.dataset?.index);
|
|
7989
|
-
|
|
7990
|
-
if (height > 0 && key !== void 0) {
|
|
9361
|
+
if (height > 0 && Number.isInteger(index)) {
|
|
7991
9362
|
const { total, sizes } = measuredRef.current;
|
|
7992
|
-
measuredRef.current.total = total - (sizes.get(
|
|
7993
|
-
sizes.set(
|
|
9363
|
+
measuredRef.current.total = total - (sizes.get(index) ?? 0) + height;
|
|
9364
|
+
sizes.set(index, height);
|
|
7994
9365
|
}
|
|
7995
|
-
return height;
|
|
9366
|
+
return height > 0 ? height : measuredRef.current.sizes.get(index) ?? 100;
|
|
7996
9367
|
}, []);
|
|
7997
|
-
const getRowKey = react.default.useCallback((index) => rowKeys[index] ?? index, [rowKeys]);
|
|
7998
9368
|
const isPinnedToBottomRef = react.default.useRef(isPinnedToBottom);
|
|
7999
9369
|
const shouldAdjustScrollOnResize = react.default.useCallback((item, _delta, instance) => {
|
|
8000
9370
|
if (isPinnedToBottomRef.current) return false;
|
|
@@ -8003,9 +9373,8 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
8003
9373
|
}, []);
|
|
8004
9374
|
const virtualizer = (0, _tanstack_react_virtual.useVirtualizer)({
|
|
8005
9375
|
count: shouldVirtualize ? rows.length : 0,
|
|
8006
|
-
getScrollElement: () => scrollElement,
|
|
9376
|
+
getScrollElement: () => shouldVirtualize ? scrollElement : null,
|
|
8007
9377
|
estimateSize: estimateRowSize,
|
|
8008
|
-
getItemKey: getRowKey,
|
|
8009
9378
|
overscan: 5,
|
|
8010
9379
|
measureElement: measureRowElement,
|
|
8011
9380
|
initialRect: {
|
|
@@ -8015,8 +9384,11 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
8015
9384
|
});
|
|
8016
9385
|
isPinnedToBottomRef.current = isPinnedToBottom;
|
|
8017
9386
|
virtualizer.shouldAdjustScrollPositionOnItemSizeChange = shouldAdjustScrollOnResize;
|
|
9387
|
+
const lastEndAlignedFirstMessageRef = react.default.useRef(void 0);
|
|
8018
9388
|
(0, react.useLayoutEffect)(() => {
|
|
8019
9389
|
if (!shouldVirtualize || !rows.length) return;
|
|
9390
|
+
if (lastEndAlignedFirstMessageRef.current === firstMessageId) return;
|
|
9391
|
+
lastEndAlignedFirstMessageRef.current = firstMessageId;
|
|
8020
9392
|
virtualizer.scrollToIndex(rows.length - 1, { align: "end" });
|
|
8021
9393
|
}, [shouldVirtualize, firstMessageId]);
|
|
8022
9394
|
const intelligenceTurnAnchors = (0, react.useMemo)(() => getIntelligenceTurnAnchors(deduplicatedMessages, renderedMessages), [deduplicatedMessages, renderedMessages]);
|
|
@@ -8024,6 +9396,8 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
8024
9396
|
const elements = [];
|
|
8025
9397
|
const stateSnapshot = renderCustomMessage ? getStateSnapshotForMessage(message.id) : void 0;
|
|
8026
9398
|
const rowKey = rowRenderKeys.get(message.id) ?? message.id;
|
|
9399
|
+
const turn = turnByFirstMessage.get(message.id);
|
|
9400
|
+
if (turn) elements.push(renderWorkSummary(turn.key, turn.calls));
|
|
8027
9401
|
if (renderCustomMessage) elements.push(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MemoizedCustomMessage, {
|
|
8028
9402
|
message,
|
|
8029
9403
|
position: "before",
|
|
@@ -8047,14 +9421,20 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
8047
9421
|
message,
|
|
8048
9422
|
renderActivityMessage
|
|
8049
9423
|
}, rowKey));
|
|
8050
|
-
else if (message.role === "reasoning")
|
|
8051
|
-
|
|
8052
|
-
|
|
8053
|
-
|
|
8054
|
-
|
|
8055
|
-
|
|
8056
|
-
|
|
8057
|
-
|
|
9424
|
+
else if (message.role === "reasoning") {
|
|
9425
|
+
const reasoning = /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MemoizedReasoningMessage, {
|
|
9426
|
+
message,
|
|
9427
|
+
messages,
|
|
9428
|
+
isRunning,
|
|
9429
|
+
isLatest: message.id === latestRenderedId,
|
|
9430
|
+
ReasoningMessageComponent: ReasoningComponent,
|
|
9431
|
+
slotProps: reasoningSlotProps
|
|
9432
|
+
}, rowKey);
|
|
9433
|
+
elements.push(toolCallDisplay === "turn" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Collapsible, {
|
|
9434
|
+
open: workOpen.get(message.id) ?? true,
|
|
9435
|
+
children: reasoning
|
|
9436
|
+
}, rowKey) : reasoning);
|
|
9437
|
+
}
|
|
8058
9438
|
if (renderCustomMessage) elements.push(/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MemoizedCustomMessage, {
|
|
8059
9439
|
message,
|
|
8060
9440
|
position: "after",
|
|
@@ -8069,6 +9449,7 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
8069
9449
|
}, `intelligence-${intelligenceTurnId}`));
|
|
8070
9450
|
return elements.filter(Boolean);
|
|
8071
9451
|
};
|
|
9452
|
+
const rowKey = (row) => row.type === "group" ? `${GROUP_ROW_KEY_PREFIX}${stableGroupKey(row.key)}` : rowRenderKeys.get(row.message.id) ?? row.message.id;
|
|
8072
9453
|
const renderRow = (row) => {
|
|
8073
9454
|
if (row.type === "message") return renderMessageBlock(row.message);
|
|
8074
9455
|
const Wrapper = row.wrapper;
|
|
@@ -8081,52 +9462,157 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
8081
9462
|
children: row.messages.flatMap(renderMessageBlock)
|
|
8082
9463
|
}, rowKey(row))];
|
|
8083
9464
|
};
|
|
9465
|
+
const rowKeysRef = (0, react.useRef)([]);
|
|
9466
|
+
rowKeysRef.current = rows.map(rowKey);
|
|
9467
|
+
const virtualModeRef = (0, react.useRef)(shouldVirtualize);
|
|
9468
|
+
virtualModeRef.current = shouldVirtualize;
|
|
9469
|
+
(0, react.useEffect)(() => {
|
|
9470
|
+
const element = scrollElementFromCtx;
|
|
9471
|
+
if (!element) return;
|
|
9472
|
+
let anchor = null;
|
|
9473
|
+
let suspended = false;
|
|
9474
|
+
let frame = 0;
|
|
9475
|
+
const visibleRows = () => Array.from(element.querySelectorAll("[data-scroll-anchor]"));
|
|
9476
|
+
const remember = () => {
|
|
9477
|
+
if (suspended || element.clientHeight === 0 || !virtualModeRef.current) return;
|
|
9478
|
+
if (isPinnedToBottomRef.current) {
|
|
9479
|
+
anchor = null;
|
|
9480
|
+
return;
|
|
9481
|
+
}
|
|
9482
|
+
const viewport = element.getBoundingClientRect();
|
|
9483
|
+
const row = visibleRows().find((row) => {
|
|
9484
|
+
const bounds = row.getBoundingClientRect();
|
|
9485
|
+
return bounds.bottom > viewport.top && bounds.top < viewport.bottom;
|
|
9486
|
+
});
|
|
9487
|
+
if (row) anchor = {
|
|
9488
|
+
key: row.dataset.scrollAnchor,
|
|
9489
|
+
offset: row.getBoundingClientRect().top - viewport.top
|
|
9490
|
+
};
|
|
9491
|
+
};
|
|
9492
|
+
const observer = new ResizeObserver(() => {
|
|
9493
|
+
if (element.clientHeight === 0) {
|
|
9494
|
+
suspended = true;
|
|
9495
|
+
cancelAnimationFrame(frame);
|
|
9496
|
+
return;
|
|
9497
|
+
}
|
|
9498
|
+
if (!suspended || !anchor) {
|
|
9499
|
+
suspended = false;
|
|
9500
|
+
remember();
|
|
9501
|
+
return;
|
|
9502
|
+
}
|
|
9503
|
+
let attempts = 0;
|
|
9504
|
+
let stableFrames = 0;
|
|
9505
|
+
const restore = () => {
|
|
9506
|
+
if (!anchor || element.clientHeight === 0) return;
|
|
9507
|
+
const index = rowKeysRef.current.indexOf(anchor.key);
|
|
9508
|
+
if (index < 0) {
|
|
9509
|
+
anchor = null;
|
|
9510
|
+
suspended = false;
|
|
9511
|
+
return;
|
|
9512
|
+
}
|
|
9513
|
+
const row = visibleRows().find((row) => row.dataset.scrollAnchor === anchor.key);
|
|
9514
|
+
if (row) {
|
|
9515
|
+
const delta = row.getBoundingClientRect().top - element.getBoundingClientRect().top - anchor.offset;
|
|
9516
|
+
element.scrollTop += delta;
|
|
9517
|
+
stableFrames = Math.abs(delta) < 1 ? stableFrames + 1 : 0;
|
|
9518
|
+
} else {
|
|
9519
|
+
const offset = virtualizer.getOffsetForIndex(index, "start")?.[0];
|
|
9520
|
+
if (offset !== void 0) virtualizer.scrollToOffset(offset - anchor.offset);
|
|
9521
|
+
stableFrames = 0;
|
|
9522
|
+
}
|
|
9523
|
+
if (++attempts < 60 && stableFrames < 3) frame = requestAnimationFrame(restore);
|
|
9524
|
+
else {
|
|
9525
|
+
suspended = false;
|
|
9526
|
+
remember();
|
|
9527
|
+
}
|
|
9528
|
+
};
|
|
9529
|
+
frame = requestAnimationFrame(restore);
|
|
9530
|
+
});
|
|
9531
|
+
const interrupt = () => {
|
|
9532
|
+
cancelAnimationFrame(frame);
|
|
9533
|
+
anchor = null;
|
|
9534
|
+
suspended = false;
|
|
9535
|
+
};
|
|
9536
|
+
element.addEventListener("scroll", remember, { passive: true });
|
|
9537
|
+
element.addEventListener("wheel", interrupt, { passive: true });
|
|
9538
|
+
element.addEventListener("touchstart", interrupt, { passive: true });
|
|
9539
|
+
element.addEventListener("keydown", interrupt);
|
|
9540
|
+
observer.observe(element);
|
|
9541
|
+
remember();
|
|
9542
|
+
return () => {
|
|
9543
|
+
cancelAnimationFrame(frame);
|
|
9544
|
+
observer.disconnect();
|
|
9545
|
+
element.removeEventListener("scroll", remember);
|
|
9546
|
+
element.removeEventListener("wheel", interrupt);
|
|
9547
|
+
element.removeEventListener("touchstart", interrupt);
|
|
9548
|
+
element.removeEventListener("keydown", interrupt);
|
|
9549
|
+
};
|
|
9550
|
+
}, [
|
|
9551
|
+
scrollElementFromCtx,
|
|
9552
|
+
virtualizer,
|
|
9553
|
+
firstMessageId
|
|
9554
|
+
]);
|
|
8084
9555
|
const messageElements = shouldVirtualize ? [] : rows.flatMap(renderRow);
|
|
8085
|
-
if (children) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
8086
|
-
|
|
8087
|
-
|
|
8088
|
-
|
|
8089
|
-
|
|
8090
|
-
|
|
8091
|
-
|
|
8092
|
-
|
|
9556
|
+
if (children) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MessageFeedbackScopeContext.Provider, {
|
|
9557
|
+
value: feedbackScope,
|
|
9558
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolCallDisplayContext.Provider, {
|
|
9559
|
+
value: toolCallDisplayContext,
|
|
9560
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
9561
|
+
"data-copilotkit": true,
|
|
9562
|
+
style: { display: "contents" },
|
|
9563
|
+
children: children({
|
|
9564
|
+
messageElements,
|
|
9565
|
+
messages,
|
|
9566
|
+
isRunning,
|
|
9567
|
+
interruptElement
|
|
9568
|
+
})
|
|
9569
|
+
})
|
|
8093
9570
|
})
|
|
8094
9571
|
});
|
|
8095
9572
|
const lastMessage = renderedMessages[renderedMessages.length - 1];
|
|
8096
|
-
const showCursor = isRunning && lastMessage?.role !== "reasoning";
|
|
8097
|
-
|
|
8098
|
-
|
|
8099
|
-
|
|
8100
|
-
|
|
8101
|
-
|
|
8102
|
-
|
|
8103
|
-
|
|
8104
|
-
|
|
8105
|
-
|
|
8106
|
-
|
|
8107
|
-
|
|
8108
|
-
|
|
8109
|
-
const row = rows[virtualItem.index];
|
|
8110
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8111
|
-
"data-index": virtualItem.index,
|
|
8112
|
-
ref: virtualizer.measureElement,
|
|
9573
|
+
const showCursor = isRunning && lastMessage?.role !== "reasoning" && toolCallDisplay !== "turn";
|
|
9574
|
+
const pendingWorkSummary = toolCallDisplay === "turn" && isRunning && lastMessage?.role === "user";
|
|
9575
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MessageFeedbackScopeContext.Provider, {
|
|
9576
|
+
value: feedbackScope,
|
|
9577
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ToolCallDisplayContext.Provider, {
|
|
9578
|
+
value: toolCallDisplayContext,
|
|
9579
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
9580
|
+
"data-copilotkit": true,
|
|
9581
|
+
"data-testid": "copilot-message-list",
|
|
9582
|
+
className: (0, tailwind_merge.twMerge)("copilotKitMessages cpk:flex cpk:flex-col", className),
|
|
9583
|
+
...props,
|
|
9584
|
+
children: [
|
|
9585
|
+
shouldVirtualize ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8113
9586
|
style: {
|
|
8114
|
-
|
|
8115
|
-
|
|
8116
|
-
left: 0,
|
|
8117
|
-
width: "100%",
|
|
8118
|
-
transform: `translateY(${virtualItem.start}px)`
|
|
9587
|
+
height: virtualizer.getTotalSize(),
|
|
9588
|
+
position: "relative"
|
|
8119
9589
|
},
|
|
8120
|
-
children:
|
|
8121
|
-
|
|
8122
|
-
|
|
8123
|
-
|
|
8124
|
-
|
|
8125
|
-
|
|
8126
|
-
|
|
8127
|
-
|
|
9590
|
+
children: virtualizer.getVirtualItems().map((virtualItem) => {
|
|
9591
|
+
const row = rows[virtualItem.index];
|
|
9592
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
9593
|
+
"data-index": virtualItem.index,
|
|
9594
|
+
"data-scroll-anchor": rowKey(row),
|
|
9595
|
+
ref: virtualizer.measureElement,
|
|
9596
|
+
style: {
|
|
9597
|
+
position: "absolute",
|
|
9598
|
+
top: 0,
|
|
9599
|
+
left: 0,
|
|
9600
|
+
width: "100%",
|
|
9601
|
+
transform: `translateY(${virtualItem.start}px)`
|
|
9602
|
+
},
|
|
9603
|
+
children: renderRow(row)
|
|
9604
|
+
}, rowKey(row));
|
|
9605
|
+
})
|
|
9606
|
+
}) : messageElements,
|
|
9607
|
+
interruptElement,
|
|
9608
|
+
pendingWorkSummary && renderWorkSummary(latestTurnKey, []),
|
|
9609
|
+
showCursor && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
9610
|
+
className: "cpk:mt-2",
|
|
9611
|
+
children: renderSlot(cursor, CopilotChatMessageView.Cursor, {})
|
|
9612
|
+
})
|
|
9613
|
+
]
|
|
8128
9614
|
})
|
|
8129
|
-
|
|
9615
|
+
})
|
|
8130
9616
|
});
|
|
8131
9617
|
}
|
|
8132
9618
|
CopilotChatMessageView.Cursor = function Cursor({ className, ...props }) {
|
|
@@ -8511,6 +9997,16 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
8511
9997
|
});
|
|
8512
9998
|
}
|
|
8513
9999
|
function CopilotChatView({ messageView, input, scrollView, suggestionView, welcomeScreen, messages = [], autoScroll = true, isRunning = false, suggestions, suggestionLoadingIndexes, onSelectSuggestion, onSubmitMessage, onStop, inputMode, inputValue, onInputChange, onStartTranscribe, onCancelTranscribe, onFinishTranscribe, onFinishTranscribeWithAudio, attachments, onRemoveAttachment, onAddFile, dragOver, onDragOver, onDragLeave, onDrop, isConnecting = false, hasExplicitThreadId = false, disclaimer, intelligenceIndicator, children, className, ...props }) {
|
|
10000
|
+
const configuredThreadId = useCopilotChatConfiguration()?.threadId;
|
|
10001
|
+
const [fallbackThreadId, setFallbackThreadId] = (0, react.useState)(messages[0]?.id);
|
|
10002
|
+
const previousMessageIds = (0, react.useRef)(/* @__PURE__ */ new Set());
|
|
10003
|
+
(0, react.useEffect)(() => {
|
|
10004
|
+
if (messages.length === 0) return;
|
|
10005
|
+
const overlaps = messages.some((message) => previousMessageIds.current.has(message.id));
|
|
10006
|
+
previousMessageIds.current = new Set(messages.map((message) => message.id));
|
|
10007
|
+
if (!overlaps) setFallbackThreadId(messages[0].id);
|
|
10008
|
+
}, [messages]);
|
|
10009
|
+
const scrollThreadId = configuredThreadId ?? fallbackThreadId;
|
|
8514
10010
|
const [inputContainerEl, setInputContainerEl] = (0, react.useState)(null);
|
|
8515
10011
|
const [inputContainerHeight, setInputContainerHeight] = (0, react.useState)(0);
|
|
8516
10012
|
const [isResizing, setIsResizing] = (0, react.useState)(false);
|
|
@@ -8577,6 +10073,7 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
8577
10073
|
}) : null;
|
|
8578
10074
|
const BoundScrollView = renderSlot(scrollView, CopilotChatView.ScrollView, {
|
|
8579
10075
|
autoScroll,
|
|
10076
|
+
scrollThreadId,
|
|
8580
10077
|
inputContainerHeight,
|
|
8581
10078
|
isResizing,
|
|
8582
10079
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -8672,12 +10169,102 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
8672
10169
|
});
|
|
8673
10170
|
}
|
|
8674
10171
|
(function(_CopilotChatView) {
|
|
8675
|
-
const ScrollContent = ({ children, scrollToBottomButton, feather, inputContainerHeight, isResizing }) => {
|
|
8676
|
-
const { isAtBottom, scrollToBottom, scrollRef, state } = (0, use_stick_to_bottom.useStickToBottomContext)();
|
|
10172
|
+
const ScrollContent = ({ children, scrollToBottomButton, feather, inputContainerHeight, isResizing, scrollThreadId }) => {
|
|
10173
|
+
const { isAtBottom, scrollToBottom, stopScroll, scrollRef, state } = (0, use_stick_to_bottom.useStickToBottomContext)();
|
|
8677
10174
|
const [scrollEl, setScrollEl] = (0, react.useState)(null);
|
|
10175
|
+
const readingOffsetRef = (0, react.useRef)(null);
|
|
10176
|
+
const pinIntentRef = (0, react.useRef)(false);
|
|
10177
|
+
const stateRef = (0, react.useRef)(state);
|
|
10178
|
+
stateRef.current = state;
|
|
8678
10179
|
(0, react.useLayoutEffect)(() => {
|
|
8679
10180
|
setScrollEl(scrollRef.current ?? null);
|
|
8680
10181
|
}, []);
|
|
10182
|
+
(0, react.useEffect)(() => {
|
|
10183
|
+
if (!scrollEl) return;
|
|
10184
|
+
let hidden = false;
|
|
10185
|
+
let resumeBottom = false;
|
|
10186
|
+
let pendingFrame = 0;
|
|
10187
|
+
let resumeFrame = 0;
|
|
10188
|
+
let settleFrame = 0;
|
|
10189
|
+
readingOffsetRef.current = null;
|
|
10190
|
+
const rememberScroll = () => {
|
|
10191
|
+
if (hidden || scrollEl.clientHeight === 0) return;
|
|
10192
|
+
if (resumeBottom) {
|
|
10193
|
+
readingOffsetRef.current = null;
|
|
10194
|
+
return;
|
|
10195
|
+
}
|
|
10196
|
+
if (pinIntentRef.current) if (stateRef.current.escapedFromLock) pinIntentRef.current = false;
|
|
10197
|
+
else {
|
|
10198
|
+
readingOffsetRef.current = null;
|
|
10199
|
+
if (!stateRef.current.isNearBottom) return;
|
|
10200
|
+
pinIntentRef.current = false;
|
|
10201
|
+
}
|
|
10202
|
+
readingOffsetRef.current = !stateRef.current.isAtBottom && (stateRef.current.escapedFromLock || !stateRef.current.isNearBottom) ? scrollEl.scrollTop : null;
|
|
10203
|
+
};
|
|
10204
|
+
const onScroll = () => {
|
|
10205
|
+
rememberScroll();
|
|
10206
|
+
cancelAnimationFrame(pendingFrame);
|
|
10207
|
+
pendingFrame = requestAnimationFrame(rememberScroll);
|
|
10208
|
+
};
|
|
10209
|
+
const onWheel = (event) => {
|
|
10210
|
+
if (event.deltaY < 0) {
|
|
10211
|
+
pinIntentRef.current = false;
|
|
10212
|
+
resumeBottom = false;
|
|
10213
|
+
}
|
|
10214
|
+
};
|
|
10215
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
10216
|
+
if (scrollEl.clientHeight === 0) {
|
|
10217
|
+
hidden = true;
|
|
10218
|
+
resumeBottom = pinIntentRef.current || readingOffsetRef.current === null;
|
|
10219
|
+
if (!resumeBottom) stopScroll();
|
|
10220
|
+
} else if (hidden) {
|
|
10221
|
+
hidden = false;
|
|
10222
|
+
if (resumeBottom) {
|
|
10223
|
+
stopScroll();
|
|
10224
|
+
resumeFrame = requestAnimationFrame(() => {
|
|
10225
|
+
settleFrame = requestAnimationFrame(() => {
|
|
10226
|
+
if (scrollEl.clientHeight > 0 && resumeBottom) {
|
|
10227
|
+
resumeBottom = false;
|
|
10228
|
+
pinIntentRef.current = true;
|
|
10229
|
+
scrollToBottom({ animation: "instant" });
|
|
10230
|
+
}
|
|
10231
|
+
});
|
|
10232
|
+
});
|
|
10233
|
+
} else if (readingOffsetRef.current !== null) {
|
|
10234
|
+
stopScroll();
|
|
10235
|
+
scrollEl.scrollTop = readingOffsetRef.current;
|
|
10236
|
+
}
|
|
10237
|
+
}
|
|
10238
|
+
});
|
|
10239
|
+
rememberScroll();
|
|
10240
|
+
scrollEl.addEventListener("scroll", onScroll);
|
|
10241
|
+
scrollEl.addEventListener("wheel", onWheel, { passive: true });
|
|
10242
|
+
resizeObserver.observe(scrollEl);
|
|
10243
|
+
return () => {
|
|
10244
|
+
scrollEl.removeEventListener("scroll", onScroll);
|
|
10245
|
+
scrollEl.removeEventListener("wheel", onWheel);
|
|
10246
|
+
cancelAnimationFrame(pendingFrame);
|
|
10247
|
+
cancelAnimationFrame(resumeFrame);
|
|
10248
|
+
cancelAnimationFrame(settleFrame);
|
|
10249
|
+
resizeObserver.disconnect();
|
|
10250
|
+
};
|
|
10251
|
+
}, [
|
|
10252
|
+
scrollEl,
|
|
10253
|
+
scrollToBottom,
|
|
10254
|
+
stopScroll,
|
|
10255
|
+
scrollThreadId
|
|
10256
|
+
]);
|
|
10257
|
+
const startBottomPin = (0, react.useCallback)((instant = false) => {
|
|
10258
|
+
readingOffsetRef.current = null;
|
|
10259
|
+
pinIntentRef.current = true;
|
|
10260
|
+
scrollToBottom(instant ? { animation: "instant" } : void 0);
|
|
10261
|
+
}, [scrollToBottom]);
|
|
10262
|
+
const previousScrollThreadId = (0, react.useRef)(scrollThreadId);
|
|
10263
|
+
(0, react.useEffect)(() => {
|
|
10264
|
+
if (previousScrollThreadId.current === scrollThreadId) return;
|
|
10265
|
+
previousScrollThreadId.current = scrollThreadId;
|
|
10266
|
+
startBottomPin(true);
|
|
10267
|
+
}, [scrollThreadId, startBottomPin]);
|
|
8681
10268
|
const BoundFeather = renderSlot(feather, CopilotChatView.Feather, {});
|
|
8682
10269
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ScrollElementContext.Provider, {
|
|
8683
10270
|
value: scrollEl,
|
|
@@ -8699,7 +10286,7 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
8699
10286
|
!isAtBottom && !isResizing && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8700
10287
|
className: "cpk:absolute cpk:inset-x-0 cpk:flex cpk:justify-center cpk:z-30 cpk:pointer-events-none",
|
|
8701
10288
|
style: { bottom: `${inputContainerHeight + SCROLL_BUTTON_OFFSET}px` },
|
|
8702
|
-
children: renderSlot(scrollToBottomButton, CopilotChatView.ScrollToBottomButton, { onClick: () =>
|
|
10289
|
+
children: renderSlot(scrollToBottomButton, CopilotChatView.ScrollToBottomButton, { onClick: () => startBottomPin() })
|
|
8703
10290
|
})
|
|
8704
10291
|
] })
|
|
8705
10292
|
})
|
|
@@ -8747,7 +10334,7 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
8747
10334
|
})
|
|
8748
10335
|
});
|
|
8749
10336
|
};
|
|
8750
|
-
_CopilotChatView.ScrollView = ({ children, autoScroll = "pin-to-bottom", scrollToBottomButton, feather, inputContainerHeight = 0, isResizing = false, className, ...props }) => {
|
|
10337
|
+
_CopilotChatView.ScrollView = ({ children, autoScroll = "pin-to-bottom", scrollThreadId, scrollToBottomButton, feather, inputContainerHeight = 0, isResizing = false, className, ...props }) => {
|
|
8751
10338
|
const mode = normalizeAutoScroll(autoScroll);
|
|
8752
10339
|
const [hasMounted, setHasMounted] = (0, react.useState)(false);
|
|
8753
10340
|
const scrollRef = (0, react.useRef)(null);
|
|
@@ -8836,6 +10423,7 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
8836
10423
|
initial: "smooth",
|
|
8837
10424
|
...props,
|
|
8838
10425
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ScrollContent, {
|
|
10426
|
+
scrollThreadId,
|
|
8839
10427
|
scrollToBottomButton,
|
|
8840
10428
|
feather,
|
|
8841
10429
|
inputContainerHeight,
|
|
@@ -8844,14 +10432,18 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
8844
10432
|
})
|
|
8845
10433
|
});
|
|
8846
10434
|
};
|
|
8847
|
-
_CopilotChatView.ScrollToBottomButton = ({ className, ...props }) =>
|
|
8848
|
-
|
|
8849
|
-
|
|
8850
|
-
|
|
8851
|
-
|
|
8852
|
-
|
|
8853
|
-
|
|
8854
|
-
|
|
10435
|
+
_CopilotChatView.ScrollToBottomButton = ({ className, ...props }) => {
|
|
10436
|
+
const labels = useCopilotChatConfiguration()?.labels ?? CopilotChatDefaultLabels;
|
|
10437
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Button, {
|
|
10438
|
+
"data-testid": "copilot-scroll-to-bottom",
|
|
10439
|
+
variant: "outline",
|
|
10440
|
+
size: "sm",
|
|
10441
|
+
className: (0, tailwind_merge.twMerge)("cpk:rounded-full cpk:w-10 cpk:h-10 cpk:p-0 cpk:pointer-events-auto", "cpk:bg-white cpk:dark:bg-gray-900", "cpk:shadow-lg cpk:border cpk:border-gray-200 cpk:dark:border-gray-700", "cpk:hover:bg-gray-50 cpk:dark:hover:bg-gray-800", "cpk:flex cpk:items-center cpk:justify-center cpk:cursor-pointer", className),
|
|
10442
|
+
"aria-label": labels.chatScrollToBottomLabel,
|
|
10443
|
+
...props,
|
|
10444
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronDown, { className: "cpk:w-4 cpk:h-4 cpk:text-gray-600 cpk:dark:text-white" })
|
|
10445
|
+
});
|
|
10446
|
+
};
|
|
8855
10447
|
_CopilotChatView.Feather = ({ className, ...props }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8856
10448
|
className,
|
|
8857
10449
|
...props
|
|
@@ -10234,6 +11826,7 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
10234
11826
|
if (containerRef.current?.contains(target)) return;
|
|
10235
11827
|
const toggleButton = document.querySelector("[data-slot='chat-toggle-button']");
|
|
10236
11828
|
if (toggleButton && toggleButton.contains(target)) return;
|
|
11829
|
+
if (target instanceof Element && target.closest("[data-copilotkit-popover]")) return;
|
|
10237
11830
|
setModalOpen?.(false);
|
|
10238
11831
|
};
|
|
10239
11832
|
document.addEventListener("pointerdown", handlePointerDown);
|
|
@@ -10744,62 +12337,14 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
10744
12337
|
|
|
10745
12338
|
//#endregion
|
|
10746
12339
|
//#region src/v2/components/WildcardToolCallRender.tsx
|
|
12340
|
+
/**
|
|
12341
|
+
* Catch-all (`"*"`) tool-call renderer that shows CopilotKit's default
|
|
12342
|
+
* tool-call card for any tool without a dedicated renderer.
|
|
12343
|
+
*/
|
|
10747
12344
|
const WildcardToolCallRender = defineToolCallRenderer({
|
|
10748
12345
|
name: "*",
|
|
10749
|
-
|
|
10750
|
-
|
|
10751
|
-
const statusString = String(status);
|
|
10752
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
10753
|
-
className: "cpk:mt-2 cpk:pb-2",
|
|
10754
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
10755
|
-
className: "cpk:rounded-xl cpk:border cpk:border-zinc-200/60 cpk:dark:border-zinc-800/60 cpk:bg-white/70 cpk:dark:bg-zinc-900/50 cpk:shadow-sm cpk:backdrop-blur cpk:p-4",
|
|
10756
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
10757
|
-
className: "cpk:flex cpk:items-center cpk:justify-between cpk:gap-3 cpk:cursor-pointer",
|
|
10758
|
-
onClick: () => setIsExpanded(!isExpanded),
|
|
10759
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
10760
|
-
className: "cpk:flex cpk:items-center cpk:gap-2 cpk:min-w-0",
|
|
10761
|
-
children: [
|
|
10762
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
10763
|
-
className: `cpk:h-4 cpk:w-4 cpk:text-zinc-500 cpk:dark:text-zinc-400 cpk:transition-transform ${isExpanded ? "cpk:rotate-90" : ""}`,
|
|
10764
|
-
fill: "none",
|
|
10765
|
-
viewBox: "0 0 24 24",
|
|
10766
|
-
strokeWidth: 2,
|
|
10767
|
-
stroke: "currentColor",
|
|
10768
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", {
|
|
10769
|
-
strokeLinecap: "round",
|
|
10770
|
-
strokeLinejoin: "round",
|
|
10771
|
-
d: "M8.25 4.5l7.5 7.5-7.5 7.5"
|
|
10772
|
-
})
|
|
10773
|
-
}),
|
|
10774
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: "cpk:inline-block cpk:h-2 cpk:w-2 cpk:rounded-full cpk:bg-blue-500" }),
|
|
10775
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
10776
|
-
className: "cpk:truncate cpk:text-sm cpk:font-medium cpk:text-zinc-900 cpk:dark:text-zinc-100",
|
|
10777
|
-
children: name
|
|
10778
|
-
})
|
|
10779
|
-
]
|
|
10780
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
10781
|
-
className: `cpk:inline-flex cpk:items-center cpk:rounded-full cpk:px-2 cpk:py-1 cpk:text-xs cpk:font-medium ${statusString === "inProgress" || statusString === "executing" ? "cpk:bg-amber-100 cpk:text-amber-800 cpk:dark:bg-amber-500/15 cpk:dark:text-amber-400" : statusString === "complete" ? "cpk:bg-emerald-100 cpk:text-emerald-800 cpk:dark:bg-emerald-500/15 cpk:dark:text-emerald-400" : "cpk:bg-zinc-100 cpk:text-zinc-800 cpk:dark:bg-zinc-700/40 cpk:dark:text-zinc-300"}`,
|
|
10782
|
-
children: String(status)
|
|
10783
|
-
})]
|
|
10784
|
-
}), isExpanded && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
10785
|
-
className: "cpk:mt-3 cpk:grid cpk:gap-4",
|
|
10786
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
10787
|
-
className: "cpk:text-xs cpk:uppercase cpk:tracking-wide cpk:text-zinc-500 cpk:dark:text-zinc-400",
|
|
10788
|
-
children: "Arguments"
|
|
10789
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
|
|
10790
|
-
className: "cpk:mt-2 cpk:max-h-64 cpk:overflow-auto cpk:rounded-md cpk:bg-zinc-50 cpk:dark:bg-zinc-800/60 cpk:p-3 cpk:text-xs cpk:leading-relaxed cpk:text-zinc-800 cpk:dark:text-zinc-200 cpk:whitespace-pre-wrap cpk:break-words",
|
|
10791
|
-
children: JSON.stringify(args ?? {}, null, 2)
|
|
10792
|
-
})] }), result !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
10793
|
-
className: "cpk:text-xs cpk:uppercase cpk:tracking-wide cpk:text-zinc-500 cpk:dark:text-zinc-400",
|
|
10794
|
-
children: "Result"
|
|
10795
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
|
|
10796
|
-
className: "cpk:mt-2 cpk:max-h-64 cpk:overflow-auto cpk:rounded-md cpk:bg-zinc-50 cpk:dark:bg-zinc-800/60 cpk:p-3 cpk:text-xs cpk:leading-relaxed cpk:text-zinc-800 cpk:dark:text-zinc-200 cpk:whitespace-pre-wrap cpk:break-words",
|
|
10797
|
-
children: typeof result === "string" ? result : JSON.stringify(result, null, 2)
|
|
10798
|
-
})] })]
|
|
10799
|
-
})]
|
|
10800
|
-
})
|
|
10801
|
-
});
|
|
10802
|
-
}
|
|
12346
|
+
group: true,
|
|
12347
|
+
render: (props) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DefaultToolCallRenderer, { ...adaptRendererProps(props) })
|
|
10803
12348
|
});
|
|
10804
12349
|
|
|
10805
12350
|
//#endregion
|
|
@@ -13044,9 +14589,11 @@ exports.CopilotChatSuggestionView = CopilotChatSuggestionView;
|
|
|
13044
14589
|
exports.CopilotChatToggleButton = CopilotChatToggleButton;
|
|
13045
14590
|
exports.CopilotChatToggleButtonCloseIcon = DefaultCloseIcon;
|
|
13046
14591
|
exports.CopilotChatToggleButtonOpenIcon = DefaultOpenIcon;
|
|
14592
|
+
exports.CopilotChatToolCallGroup = CopilotChatToolCallGroup;
|
|
13047
14593
|
exports.CopilotChatToolCallsView = CopilotChatToolCallsView;
|
|
13048
14594
|
exports.CopilotChatUserMessage = CopilotChatUserMessage_default;
|
|
13049
14595
|
exports.CopilotChatView = CopilotChatView_default;
|
|
14596
|
+
exports.CopilotChatWorkSummary = CopilotChatWorkSummary;
|
|
13050
14597
|
exports.CopilotKit = CopilotKit;
|
|
13051
14598
|
Object.defineProperty(exports, 'CopilotKitCore', {
|
|
13052
14599
|
enumerable: true,
|
|
@@ -13275,12 +14822,6 @@ Object.defineProperty(exports, 'IntelligenceAgent', {
|
|
|
13275
14822
|
});
|
|
13276
14823
|
exports.IntelligenceIndicator = IntelligenceIndicator;
|
|
13277
14824
|
exports.IntelligenceIndicatorView = IntelligenceIndicatorView;
|
|
13278
|
-
Object.defineProperty(exports, 'IntelligenceReplayFailedError', {
|
|
13279
|
-
enumerable: true,
|
|
13280
|
-
get: function () {
|
|
13281
|
-
return _copilotkit_core.IntelligenceReplayFailedError;
|
|
13282
|
-
}
|
|
13283
|
-
});
|
|
13284
14825
|
Object.defineProperty(exports, 'InterruptSchema', {
|
|
13285
14826
|
enumerable: true,
|
|
13286
14827
|
get: function () {
|