@copilotkit/react-core 1.56.2 → 1.56.4-canary.1777529757
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-CSJw5BG8.cjs → copilotkit-BAkj3zUc.cjs} +359 -157
- package/dist/copilotkit-BAkj3zUc.cjs.map +1 -0
- package/dist/{copilotkit-Cj2ZIxVr.mjs → copilotkit-DAatqMh2.mjs} +360 -158
- package/dist/copilotkit-DAatqMh2.mjs.map +1 -0
- package/dist/{copilotkit-CCbxm6JM.d.mts → copilotkit-DFaI4j2r.d.mts} +64 -18
- package/dist/copilotkit-DFaI4j2r.d.mts.map +1 -0
- package/dist/{copilotkit-BtP7w7cT.d.cts → copilotkit-Dg4r4Gi_.d.cts} +64 -18
- package/dist/copilotkit-Dg4r4Gi_.d.cts.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +2 -1
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +2 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.umd.js +31 -44
- package/dist/index.umd.js.map +1 -1
- package/dist/v2/index.cjs +1 -1
- 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 +1 -1
- package/dist/v2/index.umd.js +361 -163
- package/dist/v2/index.umd.js.map +1 -1
- package/package.json +8 -8
- package/src/components/copilot-provider/__tests__/v1-explicit-threadid-bridge.test.tsx +107 -0
- package/src/components/copilot-provider/copilotkit.tsx +6 -1
- package/src/context/__tests__/threads-context.test.tsx +116 -3
- package/src/context/threads-context.tsx +18 -1
- package/src/v2/components/chat/CopilotChat.tsx +91 -4
- package/src/v2/components/chat/CopilotChatAttachmentQueue.tsx +7 -114
- package/src/v2/components/chat/CopilotChatAttachmentRenderer.tsx +26 -6
- package/src/v2/components/chat/CopilotChatInput.tsx +22 -0
- package/src/v2/components/chat/CopilotChatUserMessage.tsx +2 -2
- package/src/v2/components/chat/CopilotChatView.tsx +226 -48
- package/src/v2/components/chat/Lightbox.tsx +103 -0
- package/src/v2/components/chat/__tests__/CopilotChat.absentThreadConnect.test.tsx +66 -0
- package/src/v2/components/chat/__tests__/CopilotChat.suggestionsAlways.test.tsx +189 -0
- package/src/v2/components/chat/__tests__/CopilotChat.welcomeGate.test.tsx +186 -0
- package/src/v2/components/chat/__tests__/CopilotChatActivityRendering.e2e.test.tsx +438 -4
- package/src/v2/components/chat/__tests__/CopilotChatView.connectingGate.test.tsx +56 -0
- package/src/v2/components/chat/__tests__/CopilotChatView.inputOverlay.test.tsx +264 -0
- package/src/v2/components/chat/__tests__/CopilotChatView.pinToSend.test.tsx +94 -0
- package/src/v2/components/chat/__tests__/copilot-chat-throttle.test.tsx +0 -1
- package/src/v2/components/chat/__tests__/normalize-auto-scroll.test.ts +37 -0
- package/src/v2/components/chat/index.ts +2 -0
- package/src/v2/components/chat/last-user-message-context.ts +21 -0
- package/src/v2/components/chat/normalize-auto-scroll.ts +17 -0
- package/src/v2/components/license-warning-banner.tsx +20 -1
- package/src/v2/hooks/__tests__/use-agent-stability.test.tsx +6 -0
- package/src/v2/hooks/__tests__/use-agent-thread-isolation.test.tsx +6 -0
- package/src/v2/hooks/__tests__/use-agent-throttle.test.tsx +76 -50
- package/src/v2/hooks/__tests__/use-pin-to-send.test.tsx +219 -0
- package/src/v2/hooks/__tests__/use-threads.test.tsx +68 -0
- package/src/v2/hooks/use-agent.tsx +34 -77
- package/src/v2/hooks/use-pin-to-send.ts +94 -0
- package/src/v2/hooks/use-threads.tsx +55 -12
- package/src/v2/providers/CopilotChatConfigurationProvider.tsx +29 -1
- package/src/v2/providers/CopilotKitProvider.tsx +2 -11
- package/src/v2/providers/__tests__/CopilotChatConfigurationProvider.test.tsx +106 -0
- package/dist/copilotkit-BtP7w7cT.d.cts.map +0 -1
- package/dist/copilotkit-CCbxm6JM.d.mts.map +0 -1
- package/dist/copilotkit-CSJw5BG8.cjs.map +0 -1
- package/dist/copilotkit-Cj2ZIxVr.mjs.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('zod'), require('@lit-labs/react'), require('@copilotkit/a2ui-renderer'), require('zod-to-json-schema'), require('
|
|
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', 'zod', '@lit-labs/react', '@copilotkit/a2ui-renderer', 'zod-to-json-schema', '
|
|
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.Zod,global.LitLabsReact,global.CopilotKitA2UIRenderer,global.zod_to_json_schema,global.
|
|
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, zod, _lit_labs_react, _copilotkit_a2ui_renderer, zod_to_json_schema,
|
|
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('zod'), require('@lit-labs/react'), require('@copilotkit/a2ui-renderer'), require('zod-to-json-schema'), require('react-dom'), require('@tanstack/react-virtual'), require('use-stick-to-bottom')) :
|
|
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', 'zod', '@lit-labs/react', '@copilotkit/a2ui-renderer', 'zod-to-json-schema', 'react-dom', '@tanstack/react-virtual', 'use-stick-to-bottom'], 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.Zod,global.LitLabsReact,global.CopilotKitA2UIRenderer,global.zod_to_json_schema,global.ReactDOM,global._tanstack_react_virtual,global.useStickToBottom));
|
|
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, zod, _lit_labs_react, _copilotkit_a2ui_renderer, zod_to_json_schema, react_dom, _tanstack_react_virtual, use_stick_to_bottom) {
|
|
8
8
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
9
9
|
//#region \0rolldown/runtime.js
|
|
10
10
|
var __create = Object.create;
|
|
@@ -161,7 +161,7 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
161
161
|
welcomeMessageText: "How can I help you today?"
|
|
162
162
|
};
|
|
163
163
|
const CopilotChatConfiguration = (0, react.createContext)(null);
|
|
164
|
-
const CopilotChatConfigurationProvider = ({ children, labels, agentId, threadId, isModalDefaultOpen }) => {
|
|
164
|
+
const CopilotChatConfigurationProvider = ({ children, labels, agentId, threadId, hasExplicitThreadId, isModalDefaultOpen }) => {
|
|
165
165
|
var _ref, _parentConfig$isModal, _parentConfig$setModa;
|
|
166
166
|
const parentConfig = (0, react.useContext)(CopilotChatConfiguration);
|
|
167
167
|
const stableLabels = useShallowStableRef(labels);
|
|
@@ -176,6 +176,7 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
176
176
|
if (parentConfig === null || parentConfig === void 0 ? void 0 : parentConfig.threadId) return parentConfig.threadId;
|
|
177
177
|
return (0, _copilotkit_shared.randomUUID)();
|
|
178
178
|
}, [threadId, parentConfig === null || parentConfig === void 0 ? void 0 : parentConfig.threadId]);
|
|
179
|
+
const resolvedHasExplicitThreadId = (hasExplicitThreadId !== void 0 ? hasExplicitThreadId : !!threadId) || !!(parentConfig === null || parentConfig === void 0 ? void 0 : parentConfig.hasExplicitThreadId);
|
|
179
180
|
const [internalModalOpen, setInternalModalOpen] = (0, react.useState)(isModalDefaultOpen !== null && isModalDefaultOpen !== void 0 ? isModalDefaultOpen : true);
|
|
180
181
|
const hasExplicitDefault = isModalDefaultOpen !== void 0;
|
|
181
182
|
const setAndSync = (0, react.useCallback)((open) => {
|
|
@@ -198,12 +199,14 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
198
199
|
labels: mergedLabels,
|
|
199
200
|
agentId: resolvedAgentId,
|
|
200
201
|
threadId: resolvedThreadId,
|
|
202
|
+
hasExplicitThreadId: resolvedHasExplicitThreadId,
|
|
201
203
|
isModalOpen: resolvedIsModalOpen,
|
|
202
204
|
setModalOpen: resolvedSetModalOpen
|
|
203
205
|
}), [
|
|
204
206
|
mergedLabels,
|
|
205
207
|
resolvedAgentId,
|
|
206
208
|
resolvedThreadId,
|
|
209
|
+
resolvedHasExplicitThreadId,
|
|
207
210
|
resolvedIsModalOpen,
|
|
208
211
|
resolvedSetModalOpen
|
|
209
212
|
]);
|
|
@@ -599,7 +602,7 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
599
602
|
//#region src/v2/components/chat/CopilotChatInput.tsx
|
|
600
603
|
const SLASH_MENU_MAX_VISIBLE_ITEMS = 5;
|
|
601
604
|
const SLASH_MENU_ITEM_HEIGHT_PX = 40;
|
|
602
|
-
function CopilotChatInput({ mode = "input", onSubmitMessage, onStop, isRunning = false, onStartTranscribe, onCancelTranscribe, onFinishTranscribe, onFinishTranscribeWithAudio, onAddFile, onChange, value, toolsMenu, autoFocus = false, positioning = "static", keyboardHeight = 0, containerRef, showDisclaimer, textArea, sendButton, startTranscribeButton, cancelTranscribeButton, finishTranscribeButton, addMenuButton, audioRecorder, disclaimer, children, className, ...props }) {
|
|
605
|
+
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 }) {
|
|
603
606
|
var _config$labels;
|
|
604
607
|
const isControlled = value !== void 0;
|
|
605
608
|
const [internalValue, setInternalValue] = (0, react.useState)(() => value !== null && value !== void 0 ? value : "");
|
|
@@ -1134,7 +1137,8 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
1134
1137
|
className: cn("cpk:pointer-events-none cpk:relative cpk:z-20", positioning === "absolute" && "cpk:absolute cpk:bottom-0 cpk:left-0 cpk:right-0", className),
|
|
1135
1138
|
style: {
|
|
1136
1139
|
transform: keyboardHeight > 0 ? `translateY(-${keyboardHeight}px)` : void 0,
|
|
1137
|
-
transition: "transform 0.2s ease-out"
|
|
1140
|
+
transition: "transform 0.2s ease-out",
|
|
1141
|
+
...positioning === "absolute" || bottomAnchored ? { paddingBottom: "var(--copilotkit-license-banner-offset, 0px)" } : {}
|
|
1138
1142
|
},
|
|
1139
1143
|
...props,
|
|
1140
1144
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -1361,6 +1365,8 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
1361
1365
|
|
|
1362
1366
|
//#endregion
|
|
1363
1367
|
//#region src/v2/components/license-warning-banner.tsx
|
|
1368
|
+
const LICENSE_BANNER_OFFSET_PX = 52;
|
|
1369
|
+
const LICENSE_BANNER_OFFSET_VAR = "--copilotkit-license-banner-offset";
|
|
1364
1370
|
const BANNER_STYLES = {
|
|
1365
1371
|
base: {
|
|
1366
1372
|
position: "fixed",
|
|
@@ -1402,6 +1408,14 @@ _radix_ui_react_dropdown_menu = __toESM(_radix_ui_react_dropdown_menu);
|
|
|
1402
1408
|
}
|
|
1403
1409
|
}
|
|
1404
1410
|
function BannerShell({ severity, message, actionLabel, actionUrl, onDismiss }) {
|
|
1411
|
+
(0, react.useEffect)(() => {
|
|
1412
|
+
if (typeof document === "undefined") return;
|
|
1413
|
+
const root = document.documentElement;
|
|
1414
|
+
root.style.setProperty(LICENSE_BANNER_OFFSET_VAR, `${LICENSE_BANNER_OFFSET_PX}px`);
|
|
1415
|
+
return () => {
|
|
1416
|
+
root.style.removeProperty(LICENSE_BANNER_OFFSET_VAR);
|
|
1417
|
+
};
|
|
1418
|
+
}, []);
|
|
1405
1419
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1406
1420
|
style: {
|
|
1407
1421
|
...BANNER_STYLES.base,
|
|
@@ -3386,7 +3400,6 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
3386
3400
|
didMountRef.current = true;
|
|
3387
3401
|
}, []);
|
|
3388
3402
|
(0, react.useEffect)(() => {
|
|
3389
|
-
if (defaultThrottleMs !== void 0 && (!Number.isFinite(defaultThrottleMs) || defaultThrottleMs < 0)) console.error(`CopilotKitProvider: defaultThrottleMs must be a non-negative finite number, got ${defaultThrottleMs}. useAgent hooks without an explicit throttleMs will fall back to unthrottled.`);
|
|
3390
3403
|
copilotkit.setDefaultThrottleMs(defaultThrottleMs);
|
|
3391
3404
|
}, [copilotkit, defaultThrottleMs]);
|
|
3392
3405
|
const designSkill = (_openGenerativeUI$des = openGenerativeUI === null || openGenerativeUI === void 0 ? void 0 : openGenerativeUI.designSkill) !== null && _openGenerativeUI$des !== void 0 ? _openGenerativeUI$des : DEFAULT_DESIGN_SKILL;
|
|
@@ -3608,16 +3621,6 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
3608
3621
|
const providerThrottleMs = copilotkit.defaultThrottleMs;
|
|
3609
3622
|
const chatConfig = useCopilotChatConfiguration();
|
|
3610
3623
|
(_threadId = threadId) !== null && _threadId !== void 0 || (threadId = chatConfig === null || chatConfig === void 0 ? void 0 : chatConfig.threadId);
|
|
3611
|
-
const effectiveThrottleMs = (0, react.useMemo)(() => {
|
|
3612
|
-
var _ref;
|
|
3613
|
-
const resolved = (_ref = throttleMs !== null && throttleMs !== void 0 ? throttleMs : providerThrottleMs) !== null && _ref !== void 0 ? _ref : 0;
|
|
3614
|
-
if (!Number.isFinite(resolved) || resolved < 0) {
|
|
3615
|
-
const source = throttleMs !== void 0 ? "hook-level throttleMs" : "provider-level defaultThrottleMs";
|
|
3616
|
-
console.error(`useAgent: ${source} must be a non-negative finite number, got ${resolved}. Falling back to unthrottled.`);
|
|
3617
|
-
return 0;
|
|
3618
|
-
}
|
|
3619
|
-
return resolved;
|
|
3620
|
-
}, [throttleMs, providerThrottleMs]);
|
|
3621
3624
|
const [, forceUpdate] = (0, react.useReducer)((x) => x + 1, 0);
|
|
3622
3625
|
const updateFlags = (0, react.useMemo)(() => updates !== null && updates !== void 0 ? updates : ALL_UPDATES, [JSON.stringify(updates)]);
|
|
3623
3626
|
const provisionalAgentCache = (0, react.useRef)(/* @__PURE__ */ new Map());
|
|
@@ -3681,9 +3684,8 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
3681
3684
|
]);
|
|
3682
3685
|
(0, react.useEffect)(() => {
|
|
3683
3686
|
if (updateFlags.length === 0) return;
|
|
3684
|
-
const handlers = {};
|
|
3685
|
-
let timerId = null;
|
|
3686
3687
|
let active = true;
|
|
3688
|
+
const handlers = {};
|
|
3687
3689
|
let batchScheduled = false;
|
|
3688
3690
|
const batchedForceUpdate = () => {
|
|
3689
3691
|
if (!active) return;
|
|
@@ -3695,46 +3697,24 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
3695
3697
|
});
|
|
3696
3698
|
}
|
|
3697
3699
|
};
|
|
3698
|
-
if (updateFlags.includes(UseAgentUpdate.OnMessagesChanged))
|
|
3699
|
-
const ms = effectiveThrottleMs;
|
|
3700
|
-
if (ms > 0) {
|
|
3701
|
-
let throttleActive = false;
|
|
3702
|
-
let pending = false;
|
|
3703
|
-
const throttledNotify = () => {
|
|
3704
|
-
if (!active) return;
|
|
3705
|
-
if (!throttleActive) {
|
|
3706
|
-
throttleActive = true;
|
|
3707
|
-
pending = false;
|
|
3708
|
-
forceUpdate();
|
|
3709
|
-
timerId = setTimeout(function trailingEdge() {
|
|
3710
|
-
timerId = null;
|
|
3711
|
-
if (active && pending) {
|
|
3712
|
-
pending = false;
|
|
3713
|
-
forceUpdate();
|
|
3714
|
-
timerId = setTimeout(trailingEdge, ms);
|
|
3715
|
-
} else throttleActive = false;
|
|
3716
|
-
}, ms);
|
|
3717
|
-
} else pending = true;
|
|
3718
|
-
};
|
|
3719
|
-
handlers.onMessagesChanged = throttledNotify;
|
|
3720
|
-
} else handlers.onMessagesChanged = forceUpdate;
|
|
3721
|
-
}
|
|
3700
|
+
if (updateFlags.includes(UseAgentUpdate.OnMessagesChanged)) handlers.onMessagesChanged = forceUpdate;
|
|
3722
3701
|
if (updateFlags.includes(UseAgentUpdate.OnStateChanged)) handlers.onStateChanged = batchedForceUpdate;
|
|
3723
3702
|
if (updateFlags.includes(UseAgentUpdate.OnRunStatusChanged)) {
|
|
3724
3703
|
handlers.onRunInitialized = batchedForceUpdate;
|
|
3725
3704
|
handlers.onRunFinalized = batchedForceUpdate;
|
|
3726
3705
|
handlers.onRunFailed = batchedForceUpdate;
|
|
3706
|
+
handlers.onRunErrorEvent = batchedForceUpdate;
|
|
3727
3707
|
}
|
|
3728
|
-
const subscription =
|
|
3708
|
+
const subscription = copilotkit.subscribeToAgentWithOptions(agent, handlers, { throttleMs });
|
|
3729
3709
|
return () => {
|
|
3730
3710
|
active = false;
|
|
3731
|
-
if (timerId !== null) clearTimeout(timerId);
|
|
3732
3711
|
subscription.unsubscribe();
|
|
3733
3712
|
};
|
|
3734
3713
|
}, [
|
|
3735
3714
|
agent,
|
|
3736
3715
|
forceUpdate,
|
|
3737
|
-
|
|
3716
|
+
throttleMs,
|
|
3717
|
+
providerThrottleMs,
|
|
3738
3718
|
updateFlags
|
|
3739
3719
|
]);
|
|
3740
3720
|
(0, react.useEffect)(() => {
|
|
@@ -4705,13 +4685,14 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
4705
4685
|
const { copilotkit } = useCopilotKit();
|
|
4706
4686
|
const [store] = (0, react.useState)(() => (0, _copilotkit_core.ɵcreateThreadStore)({ fetch: globalThis.fetch }));
|
|
4707
4687
|
const coreThreads = useThreadStoreSelector(store, _copilotkit_core.ɵselectThreads);
|
|
4708
|
-
const threads = (0, react.useMemo)(() => coreThreads.map(({ id, agentId, name, archived, createdAt, updatedAt }) => ({
|
|
4688
|
+
const threads = (0, react.useMemo)(() => coreThreads.map(({ id, agentId, name, archived, createdAt, updatedAt, lastRunAt }) => ({
|
|
4709
4689
|
id,
|
|
4710
4690
|
agentId,
|
|
4711
4691
|
name,
|
|
4712
4692
|
archived,
|
|
4713
4693
|
createdAt,
|
|
4714
|
-
updatedAt
|
|
4694
|
+
updatedAt,
|
|
4695
|
+
...lastRunAt !== void 0 ? { lastRunAt } : {}
|
|
4715
4696
|
})), [coreThreads]);
|
|
4716
4697
|
const storeIsLoading = useThreadStoreSelector(store, _copilotkit_core.ɵselectThreadsIsLoading);
|
|
4717
4698
|
const storeError = useThreadStoreSelector(store, _copilotkit_core.ɵselectThreadsError);
|
|
@@ -4725,7 +4706,9 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
4725
4706
|
if (copilotkit.runtimeUrl) return null;
|
|
4726
4707
|
return /* @__PURE__ */ new Error("Runtime URL is not configured");
|
|
4727
4708
|
}, [copilotkit.runtimeUrl]);
|
|
4728
|
-
const
|
|
4709
|
+
const [hasDispatchedContext, setHasDispatchedContext] = (0, react.useState)(false);
|
|
4710
|
+
const preConnectLoading = !!copilotkit.runtimeUrl && !hasDispatchedContext;
|
|
4711
|
+
const isLoading = runtimeError ? false : preConnectLoading || storeIsLoading;
|
|
4729
4712
|
const error = runtimeError !== null && runtimeError !== void 0 ? runtimeError : storeError;
|
|
4730
4713
|
(0, react.useEffect)(() => {
|
|
4731
4714
|
store.start();
|
|
@@ -4733,20 +4716,28 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
4733
4716
|
store.stop();
|
|
4734
4717
|
};
|
|
4735
4718
|
}, [store]);
|
|
4719
|
+
const runtimeStatus = copilotkit.runtimeConnectionStatus;
|
|
4736
4720
|
(0, react.useEffect)(() => {
|
|
4737
4721
|
var _copilotkit$intellige;
|
|
4738
|
-
|
|
4722
|
+
if (!copilotkit.runtimeUrl) {
|
|
4723
|
+
store.setContext(null);
|
|
4724
|
+
return;
|
|
4725
|
+
}
|
|
4726
|
+
if (runtimeStatus !== _copilotkit_core.CopilotKitCoreRuntimeConnectionStatus.Connected) return;
|
|
4727
|
+
const context = {
|
|
4739
4728
|
runtimeUrl: copilotkit.runtimeUrl,
|
|
4740
4729
|
headers: { ...copilotkit.headers },
|
|
4741
4730
|
wsUrl: (_copilotkit$intellige = copilotkit.intelligence) === null || _copilotkit$intellige === void 0 ? void 0 : _copilotkit$intellige.wsUrl,
|
|
4742
4731
|
agentId,
|
|
4743
4732
|
includeArchived,
|
|
4744
4733
|
limit
|
|
4745
|
-
}
|
|
4734
|
+
};
|
|
4746
4735
|
store.setContext(context);
|
|
4736
|
+
setHasDispatchedContext(true);
|
|
4747
4737
|
}, [
|
|
4748
4738
|
store,
|
|
4749
4739
|
copilotkit.runtimeUrl,
|
|
4740
|
+
runtimeStatus,
|
|
4750
4741
|
headersKey,
|
|
4751
4742
|
(_copilotkit$intellige2 = copilotkit.intelligence) === null || _copilotkit$intellige2 === void 0 ? void 0 : _copilotkit$intellige2.wsUrl,
|
|
4752
4743
|
agentId,
|
|
@@ -5136,20 +5127,101 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
5136
5127
|
CopilotChatAssistantMessage.RegenerateButton.displayName = "CopilotChatAssistantMessage.RegenerateButton";
|
|
5137
5128
|
var CopilotChatAssistantMessage_default = CopilotChatAssistantMessage;
|
|
5138
5129
|
|
|
5130
|
+
//#endregion
|
|
5131
|
+
//#region src/v2/components/chat/Lightbox.tsx
|
|
5132
|
+
function Lightbox({ onClose, children }) {
|
|
5133
|
+
(0, react.useEffect)(() => {
|
|
5134
|
+
const handleKey = (e) => {
|
|
5135
|
+
if (e.key === "Escape") onClose();
|
|
5136
|
+
};
|
|
5137
|
+
document.addEventListener("keydown", handleKey);
|
|
5138
|
+
return () => document.removeEventListener("keydown", handleKey);
|
|
5139
|
+
}, [onClose]);
|
|
5140
|
+
if (typeof document === "undefined") return null;
|
|
5141
|
+
return (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
5142
|
+
className: "cpk:fixed cpk:inset-0 cpk:z-[9999] cpk:flex cpk:items-center cpk:justify-center cpk:bg-black/80 cpk:animate-fade-in",
|
|
5143
|
+
onClick: onClose,
|
|
5144
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
5145
|
+
onClick: onClose,
|
|
5146
|
+
className: "cpk:absolute cpk:top-4 cpk:right-4 cpk:text-white cpk:bg-white/10 cpk:hover:bg-white/20 cpk:rounded-full cpk:w-10 cpk:h-10 cpk:flex cpk:items-center cpk:justify-center cpk:cursor-pointer cpk:border-none cpk:z-10",
|
|
5147
|
+
"aria-label": "Close preview",
|
|
5148
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.X, { className: "cpk:w-5 cpk:h-5" })
|
|
5149
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5150
|
+
onClick: (e) => e.stopPropagation(),
|
|
5151
|
+
children
|
|
5152
|
+
})]
|
|
5153
|
+
}), document.body);
|
|
5154
|
+
}
|
|
5155
|
+
/**
|
|
5156
|
+
* Hook that manages lightbox open/close and uses the View Transition API to
|
|
5157
|
+
* morph the thumbnail into fullscreen content.
|
|
5158
|
+
*
|
|
5159
|
+
* The trick: `view-transition-name` must live on exactly ONE element at a time.
|
|
5160
|
+
* - Old state (thumbnail visible): name is on the thumbnail.
|
|
5161
|
+
* - New state (lightbox visible): name moves to the lightbox content.
|
|
5162
|
+
* `flushSync` ensures React commits the DOM change synchronously inside the
|
|
5163
|
+
* `startViewTransition` callback so the API can snapshot old → new correctly.
|
|
5164
|
+
*/
|
|
5165
|
+
function useLightbox() {
|
|
5166
|
+
const thumbnailRef = (0, react.useRef)(null);
|
|
5167
|
+
const [open, setOpen] = (0, react.useState)(false);
|
|
5168
|
+
const vtName = (0, react.useId)();
|
|
5169
|
+
return {
|
|
5170
|
+
thumbnailRef,
|
|
5171
|
+
vtName,
|
|
5172
|
+
open,
|
|
5173
|
+
openLightbox: (0, react.useCallback)(() => {
|
|
5174
|
+
const thumb = thumbnailRef.current;
|
|
5175
|
+
const doc = document;
|
|
5176
|
+
if (doc.startViewTransition && thumb) {
|
|
5177
|
+
thumb.style.viewTransitionName = vtName;
|
|
5178
|
+
doc.startViewTransition(() => {
|
|
5179
|
+
thumb.style.viewTransitionName = "";
|
|
5180
|
+
(0, react_dom.flushSync)(() => setOpen(true));
|
|
5181
|
+
});
|
|
5182
|
+
} else setOpen(true);
|
|
5183
|
+
}, [vtName]),
|
|
5184
|
+
closeLightbox: (0, react.useCallback)(() => {
|
|
5185
|
+
const thumb = thumbnailRef.current;
|
|
5186
|
+
const doc = document;
|
|
5187
|
+
if (doc.startViewTransition && thumb) doc.startViewTransition(() => {
|
|
5188
|
+
(0, react_dom.flushSync)(() => setOpen(false));
|
|
5189
|
+
thumb.style.viewTransitionName = vtName;
|
|
5190
|
+
}).finished.then(() => {
|
|
5191
|
+
thumb.style.viewTransitionName = "";
|
|
5192
|
+
}).catch(() => {
|
|
5193
|
+
thumb.style.viewTransitionName = "";
|
|
5194
|
+
});
|
|
5195
|
+
else setOpen(false);
|
|
5196
|
+
}, [vtName])
|
|
5197
|
+
};
|
|
5198
|
+
}
|
|
5199
|
+
|
|
5139
5200
|
//#endregion
|
|
5140
5201
|
//#region src/v2/components/chat/CopilotChatAttachmentRenderer.tsx
|
|
5141
5202
|
const ImageAttachment = (0, react.memo)(function ImageAttachment({ src, className }) {
|
|
5142
5203
|
const [error, setError] = (0, react.useState)(false);
|
|
5204
|
+
const { thumbnailRef, vtName, open, openLightbox, closeLightbox } = useLightbox();
|
|
5143
5205
|
if (error) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5144
5206
|
className: cn("cpk:flex cpk:flex-col cpk:items-center cpk:justify-center cpk:rounded-lg cpk:bg-muted cpk:p-4 cpk:text-sm cpk:text-muted-foreground", className),
|
|
5145
5207
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: "Failed to load image" })
|
|
5146
5208
|
});
|
|
5147
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
5209
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
5210
|
+
ref: thumbnailRef,
|
|
5148
5211
|
src,
|
|
5149
5212
|
alt: "Image attachment",
|
|
5150
|
-
className: cn("cpk:max-w-
|
|
5213
|
+
className: cn("cpk:max-w-[80px] cpk:max-h-[80px] cpk:w-auto cpk:h-auto cpk:rounded-xl cpk:object-cover cpk:cursor-pointer cpk:bg-muted", className),
|
|
5214
|
+
onClick: openLightbox,
|
|
5151
5215
|
onError: () => setError(true)
|
|
5152
|
-
})
|
|
5216
|
+
}), open && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Lightbox, {
|
|
5217
|
+
onClose: closeLightbox,
|
|
5218
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("img", {
|
|
5219
|
+
style: { viewTransitionName: vtName },
|
|
5220
|
+
src,
|
|
5221
|
+
alt: "Image attachment",
|
|
5222
|
+
className: "cpk:max-w-[90vw] cpk:max-h-[90vh] cpk:object-contain cpk:rounded-lg"
|
|
5223
|
+
})
|
|
5224
|
+
})] });
|
|
5153
5225
|
});
|
|
5154
5226
|
const AudioAttachment = (0, react.memo)(function AudioAttachment({ src, filename, className }) {
|
|
5155
5227
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -5275,15 +5347,15 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
5275
5347
|
"data-message-id": message.id,
|
|
5276
5348
|
...props,
|
|
5277
5349
|
children: [
|
|
5278
|
-
BoundMessageRenderer,
|
|
5279
5350
|
mediaParts.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5280
|
-
className: "cpk:flex cpk:flex-
|
|
5351
|
+
className: "cpk:flex cpk:flex-row cpk:flex-wrap cpk:justify-end cpk:gap-2 cpk:mb-2",
|
|
5281
5352
|
children: mediaParts.map((part, index) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotChatAttachmentRenderer, {
|
|
5282
5353
|
type: part.type,
|
|
5283
5354
|
source: part.source,
|
|
5284
5355
|
filename: getFilename(part)
|
|
5285
5356
|
}, index))
|
|
5286
5357
|
}),
|
|
5358
|
+
BoundMessageRenderer,
|
|
5287
5359
|
BoundToolbar
|
|
5288
5360
|
]
|
|
5289
5361
|
});
|
|
@@ -5966,6 +6038,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
5966
6038
|
const CopilotChatAttachmentQueue = ({ attachments, onRemoveAttachment, className }) => {
|
|
5967
6039
|
if (attachments.length === 0) return null;
|
|
5968
6040
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6041
|
+
"data-testid": "copilot-attachment-queue",
|
|
5969
6042
|
className: cn("cpk:flex cpk:flex-wrap cpk:gap-2 cpk:p-2", className),
|
|
5970
6043
|
children: attachments.map((attachment) => {
|
|
5971
6044
|
const isMedia = attachment.type === "image" || attachment.type === "video";
|
|
@@ -6000,73 +6073,6 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6000
6073
|
case "document": return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DocumentPreview, { attachment });
|
|
6001
6074
|
}
|
|
6002
6075
|
}
|
|
6003
|
-
function Lightbox({ onClose, children }) {
|
|
6004
|
-
(0, react.useEffect)(() => {
|
|
6005
|
-
const handleKey = (e) => {
|
|
6006
|
-
if (e.key === "Escape") onClose();
|
|
6007
|
-
};
|
|
6008
|
-
document.addEventListener("keydown", handleKey);
|
|
6009
|
-
return () => document.removeEventListener("keydown", handleKey);
|
|
6010
|
-
}, [onClose]);
|
|
6011
|
-
if (typeof document === "undefined") return null;
|
|
6012
|
-
return (0, react_dom.createPortal)(/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6013
|
-
className: "cpk:fixed cpk:inset-0 cpk:z-[9999] cpk:flex cpk:items-center cpk:justify-center cpk:bg-black/80 cpk:animate-fade-in",
|
|
6014
|
-
onClick: onClose,
|
|
6015
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
6016
|
-
onClick: onClose,
|
|
6017
|
-
className: "cpk:absolute cpk:top-4 cpk:right-4 cpk:text-white cpk:bg-white/10 cpk:hover:bg-white/20 cpk:rounded-full cpk:w-10 cpk:h-10 cpk:flex cpk:items-center cpk:justify-center cpk:cursor-pointer cpk:border-none cpk:z-10",
|
|
6018
|
-
"aria-label": "Close preview",
|
|
6019
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.X, { className: "cpk:w-5 cpk:h-5" })
|
|
6020
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6021
|
-
onClick: (e) => e.stopPropagation(),
|
|
6022
|
-
children
|
|
6023
|
-
})]
|
|
6024
|
-
}), document.body);
|
|
6025
|
-
}
|
|
6026
|
-
/**
|
|
6027
|
-
* Hook that manages lightbox open/close and uses the View Transition API to
|
|
6028
|
-
* morph the thumbnail into fullscreen content.
|
|
6029
|
-
*
|
|
6030
|
-
* The trick: `view-transition-name` must live on exactly ONE element at a time.
|
|
6031
|
-
* - Old state (thumbnail visible): name is on the thumbnail.
|
|
6032
|
-
* - New state (lightbox visible): name moves to the lightbox content.
|
|
6033
|
-
* `flushSync` ensures React commits the DOM change synchronously inside the
|
|
6034
|
-
* `startViewTransition` callback so the API can snapshot old → new correctly.
|
|
6035
|
-
*/
|
|
6036
|
-
function useLightbox() {
|
|
6037
|
-
const thumbnailRef = (0, react.useRef)(null);
|
|
6038
|
-
const [open, setOpen] = (0, react.useState)(false);
|
|
6039
|
-
const vtName = (0, react.useId)();
|
|
6040
|
-
return {
|
|
6041
|
-
thumbnailRef,
|
|
6042
|
-
vtName,
|
|
6043
|
-
open,
|
|
6044
|
-
openLightbox: (0, react.useCallback)(() => {
|
|
6045
|
-
const thumb = thumbnailRef.current;
|
|
6046
|
-
const doc = document;
|
|
6047
|
-
if (doc.startViewTransition && thumb) {
|
|
6048
|
-
thumb.style.viewTransitionName = vtName;
|
|
6049
|
-
doc.startViewTransition(() => {
|
|
6050
|
-
thumb.style.viewTransitionName = "";
|
|
6051
|
-
(0, react_dom.flushSync)(() => setOpen(true));
|
|
6052
|
-
});
|
|
6053
|
-
} else setOpen(true);
|
|
6054
|
-
}, []),
|
|
6055
|
-
closeLightbox: (0, react.useCallback)(() => {
|
|
6056
|
-
const thumb = thumbnailRef.current;
|
|
6057
|
-
const doc = document;
|
|
6058
|
-
if (doc.startViewTransition && thumb) doc.startViewTransition(() => {
|
|
6059
|
-
(0, react_dom.flushSync)(() => setOpen(false));
|
|
6060
|
-
thumb.style.viewTransitionName = vtName;
|
|
6061
|
-
}).finished.then(() => {
|
|
6062
|
-
thumb.style.viewTransitionName = "";
|
|
6063
|
-
}).catch(() => {
|
|
6064
|
-
thumb.style.viewTransitionName = "";
|
|
6065
|
-
});
|
|
6066
|
-
else setOpen(false);
|
|
6067
|
-
}, [])
|
|
6068
|
-
};
|
|
6069
|
-
}
|
|
6070
6076
|
function ImagePreview({ attachment }) {
|
|
6071
6077
|
const src = (0, _copilotkit_shared.getSourceUrl)(attachment.source);
|
|
6072
6078
|
const { thumbnailRef, vtName, open, openLightbox, closeLightbox } = useLightbox();
|
|
@@ -6308,9 +6314,91 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6308
6314
|
return keyboardState;
|
|
6309
6315
|
}
|
|
6310
6316
|
|
|
6317
|
+
//#endregion
|
|
6318
|
+
//#region src/v2/components/chat/normalize-auto-scroll.ts
|
|
6319
|
+
const VALID = [
|
|
6320
|
+
"pin-to-bottom",
|
|
6321
|
+
"pin-to-send",
|
|
6322
|
+
"none"
|
|
6323
|
+
];
|
|
6324
|
+
function normalizeAutoScroll(value) {
|
|
6325
|
+
if (value === void 0) return "pin-to-bottom";
|
|
6326
|
+
if (value === true) return "pin-to-bottom";
|
|
6327
|
+
if (value === false) return "none";
|
|
6328
|
+
if (VALID.includes(value)) return value;
|
|
6329
|
+
return "pin-to-bottom";
|
|
6330
|
+
}
|
|
6331
|
+
|
|
6332
|
+
//#endregion
|
|
6333
|
+
//#region src/v2/components/chat/last-user-message-context.ts
|
|
6334
|
+
const LastUserMessageContext = react.default.createContext({
|
|
6335
|
+
id: null,
|
|
6336
|
+
sendNonce: 0
|
|
6337
|
+
});
|
|
6338
|
+
|
|
6339
|
+
//#endregion
|
|
6340
|
+
//#region src/v2/hooks/use-pin-to-send.ts
|
|
6341
|
+
function usePinToSend({ scrollRef, contentRef, spacerRef, topOffset = 16 }) {
|
|
6342
|
+
const { id, sendNonce } = (0, react.useContext)(LastUserMessageContext);
|
|
6343
|
+
const lastNonceRef = (0, react.useRef)(-1);
|
|
6344
|
+
const currentSpacerHeightRef = (0, react.useRef)(0);
|
|
6345
|
+
(0, react.useEffect)(() => {
|
|
6346
|
+
if (sendNonce === lastNonceRef.current) return;
|
|
6347
|
+
lastNonceRef.current = sendNonce;
|
|
6348
|
+
if (!id) return;
|
|
6349
|
+
const scrollEl = scrollRef.current;
|
|
6350
|
+
const contentEl = contentRef.current;
|
|
6351
|
+
const spacerEl = spacerRef.current;
|
|
6352
|
+
if (!scrollEl || !contentEl || !spacerEl) return;
|
|
6353
|
+
const escaped = typeof CSS !== "undefined" && CSS.escape ? CSS.escape(id) : id.replace(/[!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~]/g, "\\$&");
|
|
6354
|
+
const targetEl = contentEl.querySelector(`[data-message-id="${escaped}"]`);
|
|
6355
|
+
if (!targetEl) return;
|
|
6356
|
+
const viewportHeight = scrollEl.clientHeight;
|
|
6357
|
+
const userMessageHeight = targetEl.getBoundingClientRect().height;
|
|
6358
|
+
const paddingTop = parseFloat(getComputedStyle(targetEl).paddingTop) || 0;
|
|
6359
|
+
const bubbleHeight = Math.max(0, userMessageHeight - paddingTop);
|
|
6360
|
+
const spacerHeight = Math.max(0, viewportHeight - bubbleHeight - topOffset);
|
|
6361
|
+
spacerEl.style.height = `${spacerHeight}px`;
|
|
6362
|
+
currentSpacerHeightRef.current = spacerHeight;
|
|
6363
|
+
const raf = requestAnimationFrame(() => {
|
|
6364
|
+
const targetTop = computeOffsetTop(targetEl, scrollEl) + paddingTop - topOffset;
|
|
6365
|
+
scrollEl.scrollTo({
|
|
6366
|
+
top: Math.max(0, targetTop),
|
|
6367
|
+
behavior: "smooth"
|
|
6368
|
+
});
|
|
6369
|
+
});
|
|
6370
|
+
const ro = new ResizeObserver(() => {
|
|
6371
|
+
if (!contentEl || !spacerEl || !scrollEl) return;
|
|
6372
|
+
const consumedBelow = contentEl.getBoundingClientRect().height - computeOffsetTop(targetEl, contentEl) - userMessageHeight;
|
|
6373
|
+
const remaining = Math.max(0, spacerHeight - consumedBelow);
|
|
6374
|
+
if (remaining < currentSpacerHeightRef.current) {
|
|
6375
|
+
spacerEl.style.height = `${remaining}px`;
|
|
6376
|
+
currentSpacerHeightRef.current = remaining;
|
|
6377
|
+
}
|
|
6378
|
+
});
|
|
6379
|
+
ro.observe(contentEl);
|
|
6380
|
+
return () => {
|
|
6381
|
+
cancelAnimationFrame(raf);
|
|
6382
|
+
ro.disconnect();
|
|
6383
|
+
};
|
|
6384
|
+
}, [
|
|
6385
|
+
id,
|
|
6386
|
+
sendNonce,
|
|
6387
|
+
scrollRef,
|
|
6388
|
+
contentRef,
|
|
6389
|
+
spacerRef,
|
|
6390
|
+
topOffset
|
|
6391
|
+
]);
|
|
6392
|
+
}
|
|
6393
|
+
function computeOffsetTop(el, stopAt) {
|
|
6394
|
+
const elRect = el.getBoundingClientRect();
|
|
6395
|
+
const stopRect = stopAt.getBoundingClientRect();
|
|
6396
|
+
return elRect.top - stopRect.top + stopAt.scrollTop;
|
|
6397
|
+
}
|
|
6398
|
+
|
|
6311
6399
|
//#endregion
|
|
6312
6400
|
//#region src/v2/components/chat/CopilotChatView.tsx
|
|
6313
|
-
const
|
|
6401
|
+
const SCROLL_BUTTON_OFFSET = 16;
|
|
6314
6402
|
function DropOverlay() {
|
|
6315
6403
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6316
6404
|
className: cn("cpk:absolute cpk:inset-0 cpk:z-50 cpk:pointer-events-none", "cpk:flex cpk:items-center cpk:justify-center", "cpk:bg-primary/5 cpk:backdrop-blur-[2px]", "cpk:border-2 cpk:border-dashed cpk:border-primary/40 cpk:rounded-lg cpk:m-2"),
|
|
@@ -6323,15 +6411,18 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6323
6411
|
})
|
|
6324
6412
|
});
|
|
6325
6413
|
}
|
|
6326
|
-
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, disclaimer, children, className, ...props }) {
|
|
6327
|
-
const
|
|
6414
|
+
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, children, className, ...props }) {
|
|
6415
|
+
const [inputContainerEl, setInputContainerEl] = (0, react.useState)(null);
|
|
6328
6416
|
const [inputContainerHeight, setInputContainerHeight] = (0, react.useState)(0);
|
|
6329
6417
|
const [isResizing, setIsResizing] = (0, react.useState)(false);
|
|
6330
6418
|
const resizeTimeoutRef = (0, react.useRef)(null);
|
|
6331
6419
|
const { isKeyboardOpen, keyboardHeight, availableHeight } = useKeyboardHeight();
|
|
6332
6420
|
(0, react.useEffect)(() => {
|
|
6333
|
-
const element =
|
|
6334
|
-
if (!element)
|
|
6421
|
+
const element = inputContainerEl;
|
|
6422
|
+
if (!element) {
|
|
6423
|
+
setInputContainerHeight(0);
|
|
6424
|
+
return;
|
|
6425
|
+
}
|
|
6335
6426
|
const resizeObserver = new ResizeObserver((entries) => {
|
|
6336
6427
|
for (const entry of entries) {
|
|
6337
6428
|
const newHeight = entry.contentRect.height;
|
|
@@ -6354,7 +6445,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6354
6445
|
resizeObserver.disconnect();
|
|
6355
6446
|
if (resizeTimeoutRef.current) clearTimeout(resizeTimeoutRef.current);
|
|
6356
6447
|
};
|
|
6357
|
-
}, []);
|
|
6448
|
+
}, [inputContainerEl]);
|
|
6358
6449
|
const BoundMessageView = renderSlot(messageView, CopilotChatMessageView, {
|
|
6359
6450
|
messages,
|
|
6360
6451
|
isRunning
|
|
@@ -6373,11 +6464,11 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6373
6464
|
onAddFile,
|
|
6374
6465
|
positioning: "static",
|
|
6375
6466
|
keyboardHeight: isKeyboardOpen ? keyboardHeight : 0,
|
|
6376
|
-
containerRef: inputContainerRef,
|
|
6377
6467
|
showDisclaimer: true,
|
|
6468
|
+
bottomAnchored: true,
|
|
6378
6469
|
...disclaimer !== void 0 ? { disclaimer } : {}
|
|
6379
6470
|
});
|
|
6380
|
-
const hasSuggestions = Array.isArray(suggestions) && suggestions.length > 0;
|
|
6471
|
+
const hasSuggestions = !isConnecting && Array.isArray(suggestions) && suggestions.length > 0;
|
|
6381
6472
|
const BoundSuggestionView = hasSuggestions ? renderSlot(suggestionView, CopilotChatSuggestionView, {
|
|
6382
6473
|
suggestions,
|
|
6383
6474
|
loadingIndexes: suggestionLoadingIndexes,
|
|
@@ -6389,7 +6480,8 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6389
6480
|
inputContainerHeight,
|
|
6390
6481
|
isResizing,
|
|
6391
6482
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6392
|
-
|
|
6483
|
+
"data-testid": "copilot-scroll-content",
|
|
6484
|
+
style: { paddingBottom: `${inputContainerHeight + (hasSuggestions ? 4 : 32)}px` },
|
|
6393
6485
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6394
6486
|
className: "cpk:max-w-3xl cpk:mx-auto",
|
|
6395
6487
|
children: [BoundMessageView, hasSuggestions ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -6399,7 +6491,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6399
6491
|
})
|
|
6400
6492
|
})
|
|
6401
6493
|
});
|
|
6402
|
-
if (messages.length === 0 && !(welcomeScreen === false)) {
|
|
6494
|
+
if (messages.length === 0 && !(welcomeScreen === false) && !isConnecting && !hasExplicitThreadId) {
|
|
6403
6495
|
const BoundInputForWelcome = renderSlot(input, CopilotChatInput_default, {
|
|
6404
6496
|
onSubmitMessage,
|
|
6405
6497
|
onStop,
|
|
@@ -6463,15 +6555,19 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6463
6555
|
children: [
|
|
6464
6556
|
dragOver && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DropOverlay, {}),
|
|
6465
6557
|
BoundScrollView,
|
|
6466
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
6467
|
-
|
|
6468
|
-
|
|
6469
|
-
|
|
6470
|
-
|
|
6471
|
-
className: "cpk:
|
|
6472
|
-
|
|
6473
|
-
|
|
6474
|
-
|
|
6558
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6559
|
+
ref: setInputContainerEl,
|
|
6560
|
+
"data-testid": "copilot-input-overlay",
|
|
6561
|
+
className: "cpk:absolute cpk:bottom-0 cpk:left-0 cpk:right-0 cpk:z-20 cpk:pointer-events-none",
|
|
6562
|
+
children: [attachments && attachments.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6563
|
+
className: "cpk:max-w-3xl cpk:mx-auto cpk:w-full cpk:pointer-events-auto",
|
|
6564
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotChatAttachmentQueue, {
|
|
6565
|
+
attachments,
|
|
6566
|
+
onRemoveAttachment: (id) => onRemoveAttachment === null || onRemoveAttachment === void 0 ? void 0 : onRemoveAttachment(id),
|
|
6567
|
+
className: "cpk:px-4"
|
|
6568
|
+
})
|
|
6569
|
+
}), BoundInput]
|
|
6570
|
+
})
|
|
6475
6571
|
]
|
|
6476
6572
|
});
|
|
6477
6573
|
}
|
|
@@ -6501,15 +6597,66 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6501
6597
|
BoundFeather,
|
|
6502
6598
|
!isAtBottom && !isResizing && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6503
6599
|
className: "cpk:absolute cpk:inset-x-0 cpk:flex cpk:justify-center cpk:z-30 cpk:pointer-events-none",
|
|
6504
|
-
style: { bottom: `${inputContainerHeight +
|
|
6600
|
+
style: { bottom: `${inputContainerHeight + SCROLL_BUTTON_OFFSET}px` },
|
|
6505
6601
|
children: renderSlot(scrollToBottomButton, CopilotChatView.ScrollToBottomButton, { onClick: () => scrollToBottom() })
|
|
6506
6602
|
})
|
|
6507
6603
|
] })
|
|
6508
6604
|
});
|
|
6509
6605
|
};
|
|
6510
|
-
|
|
6606
|
+
const PinToSendScrollContainer = ({ children, scrollRef, contentRef, scrollToBottom, scrollToBottomButton, feather, inputContainerHeight, isResizing, nonAutoScrollEl, nonAutoScrollRefCallback, showScrollButton, className, ...props }) => {
|
|
6607
|
+
const spacerRef = (0, react.useRef)(null);
|
|
6608
|
+
usePinToSend({
|
|
6609
|
+
scrollRef,
|
|
6610
|
+
contentRef,
|
|
6611
|
+
spacerRef,
|
|
6612
|
+
topOffset: 16
|
|
6613
|
+
});
|
|
6614
|
+
const BoundFeather = renderSlot(feather, CopilotChatView.Feather, {});
|
|
6615
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ScrollElementContext.Provider, {
|
|
6616
|
+
value: nonAutoScrollEl,
|
|
6617
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6618
|
+
className: cn("cpk:h-full cpk:max-h-full cpk:flex cpk:flex-col cpk:min-h-0 cpk:relative", className),
|
|
6619
|
+
children: [
|
|
6620
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6621
|
+
ref: nonAutoScrollRefCallback,
|
|
6622
|
+
className: "cpk:flex-1 cpk:min-h-0 cpk:overflow-y-auto cpk:overflow-x-hidden",
|
|
6623
|
+
...props,
|
|
6624
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6625
|
+
ref: contentRef,
|
|
6626
|
+
className: "cpk:px-4 cpk:sm:px-0 cpk:[div[data-sidebar-chat]_&]:px-8 cpk:[div[data-popup-chat]_&]:px-6",
|
|
6627
|
+
children
|
|
6628
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6629
|
+
ref: spacerRef,
|
|
6630
|
+
"data-pin-to-send-spacer": true,
|
|
6631
|
+
"aria-hidden": "true",
|
|
6632
|
+
style: {
|
|
6633
|
+
height: 0,
|
|
6634
|
+
flex: "0 0 auto"
|
|
6635
|
+
}
|
|
6636
|
+
})]
|
|
6637
|
+
}),
|
|
6638
|
+
BoundFeather,
|
|
6639
|
+
showScrollButton && !isResizing && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6640
|
+
className: "cpk:absolute cpk:inset-x-0 cpk:flex cpk:justify-center cpk:z-30 cpk:pointer-events-none",
|
|
6641
|
+
style: { bottom: `${inputContainerHeight + SCROLL_BUTTON_OFFSET}px` },
|
|
6642
|
+
children: renderSlot(scrollToBottomButton, CopilotChatView.ScrollToBottomButton, { onClick: () => scrollToBottom() })
|
|
6643
|
+
})
|
|
6644
|
+
]
|
|
6645
|
+
})
|
|
6646
|
+
});
|
|
6647
|
+
};
|
|
6648
|
+
_CopilotChatView.ScrollView = ({ children, autoScroll = "pin-to-bottom", scrollToBottomButton, feather, inputContainerHeight = 0, isResizing = false, className, ...props }) => {
|
|
6649
|
+
const mode = normalizeAutoScroll(autoScroll);
|
|
6511
6650
|
const [hasMounted, setHasMounted] = (0, react.useState)(false);
|
|
6512
|
-
const
|
|
6651
|
+
const scrollRef = (0, react.useRef)(null);
|
|
6652
|
+
const contentRef = (0, react.useRef)(null);
|
|
6653
|
+
const scrollToBottom = (0, react.useCallback)(() => {
|
|
6654
|
+
const el = scrollRef.current;
|
|
6655
|
+
if (el) el.scrollTo({
|
|
6656
|
+
top: el.scrollHeight,
|
|
6657
|
+
behavior: "smooth"
|
|
6658
|
+
});
|
|
6659
|
+
}, []);
|
|
6513
6660
|
const [showScrollButton, setShowScrollButton] = (0, react.useState)(false);
|
|
6514
6661
|
const [nonAutoScrollEl, setNonAutoScrollEl] = (0, react.useState)(null);
|
|
6515
6662
|
const nonAutoScrollRefCallback = (0, react.useCallback)((el) => {
|
|
@@ -6520,7 +6667,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6520
6667
|
setHasMounted(true);
|
|
6521
6668
|
}, []);
|
|
6522
6669
|
(0, react.useEffect)(() => {
|
|
6523
|
-
if (
|
|
6670
|
+
if (mode === "pin-to-bottom") return;
|
|
6524
6671
|
const scrollElement = scrollRef.current;
|
|
6525
6672
|
if (!scrollElement) return;
|
|
6526
6673
|
const checkScroll = () => {
|
|
@@ -6534,7 +6681,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6534
6681
|
scrollElement.removeEventListener("scroll", checkScroll);
|
|
6535
6682
|
resizeObserver.disconnect();
|
|
6536
6683
|
};
|
|
6537
|
-
}, [scrollRef,
|
|
6684
|
+
}, [scrollRef, mode]);
|
|
6538
6685
|
if (!hasMounted) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6539
6686
|
className: "cpk:h-full cpk:max-h-full cpk:flex cpk:flex-col cpk:min-h-0 cpk:overflow-y-auto cpk:overflow-x-hidden",
|
|
6540
6687
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -6542,7 +6689,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6542
6689
|
children
|
|
6543
6690
|
})
|
|
6544
6691
|
});
|
|
6545
|
-
if (
|
|
6692
|
+
if (mode === "none") {
|
|
6546
6693
|
const BoundFeather = renderSlot(feather, CopilotChatView.Feather, {});
|
|
6547
6694
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ScrollElementContext.Provider, {
|
|
6548
6695
|
value: nonAutoScrollEl,
|
|
@@ -6559,13 +6706,28 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6559
6706
|
BoundFeather,
|
|
6560
6707
|
showScrollButton && !isResizing && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6561
6708
|
className: "cpk:absolute cpk:inset-x-0 cpk:flex cpk:justify-center cpk:z-30 cpk:pointer-events-none",
|
|
6562
|
-
style: { bottom: `${inputContainerHeight +
|
|
6709
|
+
style: { bottom: `${inputContainerHeight + SCROLL_BUTTON_OFFSET}px` },
|
|
6563
6710
|
children: renderSlot(scrollToBottomButton, CopilotChatView.ScrollToBottomButton, { onClick: () => scrollToBottom() })
|
|
6564
6711
|
})
|
|
6565
6712
|
]
|
|
6566
6713
|
})
|
|
6567
6714
|
});
|
|
6568
6715
|
}
|
|
6716
|
+
if (mode === "pin-to-send") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PinToSendScrollContainer, {
|
|
6717
|
+
scrollRef,
|
|
6718
|
+
contentRef,
|
|
6719
|
+
scrollToBottom,
|
|
6720
|
+
scrollToBottomButton,
|
|
6721
|
+
feather,
|
|
6722
|
+
inputContainerHeight,
|
|
6723
|
+
isResizing,
|
|
6724
|
+
nonAutoScrollEl,
|
|
6725
|
+
nonAutoScrollRefCallback,
|
|
6726
|
+
showScrollButton,
|
|
6727
|
+
className,
|
|
6728
|
+
...props,
|
|
6729
|
+
children
|
|
6730
|
+
});
|
|
6569
6731
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(use_stick_to_bottom.StickToBottom, {
|
|
6570
6732
|
className: cn("cpk:flex-1 cpk:max-h-full cpk:flex cpk:flex-col cpk:min-h-0", className),
|
|
6571
6733
|
resize: "smooth",
|
|
@@ -6588,9 +6750,8 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6588
6750
|
...props,
|
|
6589
6751
|
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" })
|
|
6590
6752
|
});
|
|
6591
|
-
_CopilotChatView.Feather = ({ className,
|
|
6592
|
-
className
|
|
6593
|
-
style,
|
|
6753
|
+
_CopilotChatView.Feather = ({ className, ...props }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6754
|
+
className,
|
|
6594
6755
|
...props
|
|
6595
6756
|
});
|
|
6596
6757
|
_CopilotChatView.WelcomeMessage = ({ className, ...props }) => {
|
|
@@ -6762,10 +6923,9 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6762
6923
|
var _ref, _attachmentsConfig$ac;
|
|
6763
6924
|
const existingConfig = useCopilotChatConfiguration();
|
|
6764
6925
|
const resolvedAgentId = (_ref = agentId !== null && agentId !== void 0 ? agentId : existingConfig === null || existingConfig === void 0 ? void 0 : existingConfig.agentId) !== null && _ref !== void 0 ? _ref : _copilotkit_shared.DEFAULT_AGENT_ID;
|
|
6765
|
-
const
|
|
6766
|
-
|
|
6767
|
-
|
|
6768
|
-
}, [threadId, existingConfig === null || existingConfig === void 0 ? void 0 : existingConfig.threadId]);
|
|
6926
|
+
const providedThreadId = threadId !== null && threadId !== void 0 ? threadId : existingConfig === null || existingConfig === void 0 ? void 0 : existingConfig.threadId;
|
|
6927
|
+
const resolvedThreadId = (0, react.useMemo)(() => providedThreadId !== null && providedThreadId !== void 0 ? providedThreadId : (0, _copilotkit_shared.randomUUID)(), [providedThreadId]);
|
|
6928
|
+
const hasExplicitThreadId = !!threadId || !!(existingConfig === null || existingConfig === void 0 ? void 0 : existingConfig.hasExplicitThreadId);
|
|
6769
6929
|
const { agent } = useAgent({
|
|
6770
6930
|
agentId: resolvedAgentId,
|
|
6771
6931
|
threadId: resolvedThreadId,
|
|
@@ -6807,7 +6967,10 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6807
6967
|
const isTranscriptionEnabled = copilotkit.audioFileTranscriptionEnabled;
|
|
6808
6968
|
const isMediaRecorderSupported = typeof window !== "undefined" && typeof MediaRecorder !== "undefined";
|
|
6809
6969
|
const { messageView: providedMessageView, suggestionView: providedSuggestionView, onStop: providedStopHandler, ...restProps } = props;
|
|
6970
|
+
const [lastConnectedThreadId, setLastConnectedThreadId] = (0, react.useState)(null);
|
|
6971
|
+
const isConnecting = hasExplicitThreadId && lastConnectedThreadId !== resolvedThreadId;
|
|
6810
6972
|
(0, react.useEffect)(() => {
|
|
6973
|
+
if (!hasExplicitThreadId) return;
|
|
6811
6974
|
let detached = false;
|
|
6812
6975
|
const connectAbortController = new AbortController();
|
|
6813
6976
|
if (agent instanceof _ag_ui_client.HttpAgent) agent.abortController = connectAbortController;
|
|
@@ -6817,6 +6980,10 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6817
6980
|
} catch (error) {
|
|
6818
6981
|
if (detached) return;
|
|
6819
6982
|
console.error("CopilotChat: connectAgent failed", error);
|
|
6983
|
+
} finally {
|
|
6984
|
+
if (!detached) (typeof requestAnimationFrame === "function" ? requestAnimationFrame : (cb) => setTimeout(cb, 16))(() => {
|
|
6985
|
+
if (!detached) setLastConnectedThreadId(resolvedThreadId);
|
|
6986
|
+
});
|
|
6820
6987
|
}
|
|
6821
6988
|
};
|
|
6822
6989
|
connect(agent);
|
|
@@ -6828,7 +6995,8 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6828
6995
|
}, [
|
|
6829
6996
|
resolvedThreadId,
|
|
6830
6997
|
agent,
|
|
6831
|
-
resolvedAgentId
|
|
6998
|
+
resolvedAgentId,
|
|
6999
|
+
hasExplicitThreadId
|
|
6832
7000
|
]);
|
|
6833
7001
|
const onSubmitInput = (0, react.useCallback)(async (value) => {
|
|
6834
7002
|
if (selectedAttachments.some((a) => a.status === "uploading")) {
|
|
@@ -6985,6 +7153,22 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6985
7153
|
}).join(";") : "";
|
|
6986
7154
|
return `${m.id}:${m.role}:${contentKey}:${toolCallsKey}`;
|
|
6987
7155
|
}).join(",")]);
|
|
7156
|
+
const lastUserMessageId = (0, react.useMemo)(() => {
|
|
7157
|
+
for (let i = messages.length - 1; i >= 0; i--) if (messages[i].role === "user") return messages[i].id;
|
|
7158
|
+
return null;
|
|
7159
|
+
}, [messages]);
|
|
7160
|
+
const [sendNonce, setSendNonce] = (0, react.useState)(0);
|
|
7161
|
+
const prevLastUserMessageIdRef = (0, react.useRef)(lastUserMessageId);
|
|
7162
|
+
(0, react.useEffect)(() => {
|
|
7163
|
+
if (lastUserMessageId && lastUserMessageId !== prevLastUserMessageIdRef.current) {
|
|
7164
|
+
setSendNonce((n) => n + 1);
|
|
7165
|
+
prevLastUserMessageIdRef.current = lastUserMessageId;
|
|
7166
|
+
}
|
|
7167
|
+
}, [lastUserMessageId]);
|
|
7168
|
+
const lastUserMessageState = (0, react.useMemo)(() => ({
|
|
7169
|
+
id: lastUserMessageId,
|
|
7170
|
+
sendNonce
|
|
7171
|
+
}), [lastUserMessageId, sendNonce]);
|
|
6988
7172
|
const RenderedChatView = renderSlot(chatView, CopilotChatView, {
|
|
6989
7173
|
...mergedProps,
|
|
6990
7174
|
messages,
|
|
@@ -7003,11 +7187,14 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
7003
7187
|
dragOver,
|
|
7004
7188
|
onDragOver: handleDragOver,
|
|
7005
7189
|
onDragLeave: handleDragLeave,
|
|
7006
|
-
onDrop: handleDrop
|
|
7190
|
+
onDrop: handleDrop,
|
|
7191
|
+
isConnecting,
|
|
7192
|
+
hasExplicitThreadId
|
|
7007
7193
|
});
|
|
7008
7194
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotChatConfigurationProvider, {
|
|
7009
7195
|
agentId: resolvedAgentId,
|
|
7010
7196
|
threadId: resolvedThreadId,
|
|
7197
|
+
hasExplicitThreadId,
|
|
7011
7198
|
labels,
|
|
7012
7199
|
isModalDefaultOpen,
|
|
7013
7200
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -7038,7 +7225,10 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
7038
7225
|
},
|
|
7039
7226
|
children: transcriptionError
|
|
7040
7227
|
}),
|
|
7041
|
-
|
|
7228
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(LastUserMessageContext.Provider, {
|
|
7229
|
+
value: lastUserMessageState,
|
|
7230
|
+
children: RenderedChatView
|
|
7231
|
+
})
|
|
7042
7232
|
]
|
|
7043
7233
|
})
|
|
7044
7234
|
});
|
|
@@ -8663,12 +8853,19 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
8663
8853
|
//#region src/context/threads-context.tsx
|
|
8664
8854
|
const ThreadsContext = (0, react.createContext)(void 0);
|
|
8665
8855
|
function ThreadsProvider({ children, threadId: explicitThreadId }) {
|
|
8666
|
-
const [internalThreadId,
|
|
8856
|
+
const [internalThreadId, setInternalThreadId] = (0, react.useState)(() => (0, _copilotkit_shared.randomUUID)());
|
|
8857
|
+
const [internalIsExplicit, setInternalIsExplicit] = (0, react.useState)(false);
|
|
8667
8858
|
const threadId = explicitThreadId !== null && explicitThreadId !== void 0 ? explicitThreadId : internalThreadId;
|
|
8859
|
+
const isThreadIdExplicit = explicitThreadId != null || internalIsExplicit;
|
|
8860
|
+
const setThreadId = (0, react.useCallback)((value) => {
|
|
8861
|
+
setInternalThreadId(value);
|
|
8862
|
+
setInternalIsExplicit(true);
|
|
8863
|
+
}, []);
|
|
8668
8864
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ThreadsContext.Provider, {
|
|
8669
8865
|
value: {
|
|
8670
8866
|
threadId,
|
|
8671
|
-
setThreadId
|
|
8867
|
+
setThreadId,
|
|
8868
|
+
isThreadIdExplicit
|
|
8672
8869
|
},
|
|
8673
8870
|
children
|
|
8674
8871
|
});
|
|
@@ -9388,7 +9585,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
9388
9585
|
if (props.agent) setAgentSession({ agentName: props.agent });
|
|
9389
9586
|
else setAgentSession(null);
|
|
9390
9587
|
}, [props.agent]);
|
|
9391
|
-
const { threadId, setThreadId: setInternalThreadId } = useThreads$1();
|
|
9588
|
+
const { threadId, setThreadId: setInternalThreadId, isThreadIdExplicit } = useThreads$1();
|
|
9392
9589
|
const setThreadId = (0, react.useCallback)((value) => {
|
|
9393
9590
|
if (props.threadId) throw new Error("Cannot call setThreadId() when threadId is provided via props.");
|
|
9394
9591
|
setInternalThreadId(value);
|
|
@@ -9594,6 +9791,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
9594
9791
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotChatConfigurationProvider, {
|
|
9595
9792
|
agentId: (_props$agent2 = props.agent) !== null && _props$agent2 !== void 0 ? _props$agent2 : "default",
|
|
9596
9793
|
threadId,
|
|
9794
|
+
hasExplicitThreadId: isThreadIdExplicit,
|
|
9597
9795
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(CopilotContext.Provider, {
|
|
9598
9796
|
value: copilotContextValue,
|
|
9599
9797
|
children: [
|