@copilotkit/react-core 1.56.2 → 1.56.4
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-Cj2ZIxVr.mjs → copilotkit-Bd0m5HFp.mjs} +266 -81
- package/dist/copilotkit-Bd0m5HFp.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/{copilotkit-CSJw5BG8.cjs → copilotkit-tb4zqaMK.cjs} +265 -80
- package/dist/copilotkit-tb4zqaMK.cjs.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 +264 -83
- package/dist/v2/index.umd.js.map +1 -1
- package/package.json +6 -6
- 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 +4 -1
- package/src/v2/components/chat/CopilotChatInput.tsx +22 -0
- package/src/v2/components/chat/CopilotChatView.tsx +207 -44
- package/src/v2/components/chat/__tests__/CopilotChat.absentThreadConnect.test.tsx +66 -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 +172 -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
|
@@ -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,
|
|
@@ -5966,6 +5957,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
5966
5957
|
const CopilotChatAttachmentQueue = ({ attachments, onRemoveAttachment, className }) => {
|
|
5967
5958
|
if (attachments.length === 0) return null;
|
|
5968
5959
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5960
|
+
"data-testid": "copilot-attachment-queue",
|
|
5969
5961
|
className: cn("cpk:flex cpk:flex-wrap cpk:gap-2 cpk:p-2", className),
|
|
5970
5962
|
children: attachments.map((attachment) => {
|
|
5971
5963
|
const isMedia = attachment.type === "image" || attachment.type === "video";
|
|
@@ -6308,9 +6300,91 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6308
6300
|
return keyboardState;
|
|
6309
6301
|
}
|
|
6310
6302
|
|
|
6303
|
+
//#endregion
|
|
6304
|
+
//#region src/v2/components/chat/normalize-auto-scroll.ts
|
|
6305
|
+
const VALID = [
|
|
6306
|
+
"pin-to-bottom",
|
|
6307
|
+
"pin-to-send",
|
|
6308
|
+
"none"
|
|
6309
|
+
];
|
|
6310
|
+
function normalizeAutoScroll(value) {
|
|
6311
|
+
if (value === void 0) return "pin-to-bottom";
|
|
6312
|
+
if (value === true) return "pin-to-bottom";
|
|
6313
|
+
if (value === false) return "none";
|
|
6314
|
+
if (VALID.includes(value)) return value;
|
|
6315
|
+
return "pin-to-bottom";
|
|
6316
|
+
}
|
|
6317
|
+
|
|
6318
|
+
//#endregion
|
|
6319
|
+
//#region src/v2/components/chat/last-user-message-context.ts
|
|
6320
|
+
const LastUserMessageContext = react.default.createContext({
|
|
6321
|
+
id: null,
|
|
6322
|
+
sendNonce: 0
|
|
6323
|
+
});
|
|
6324
|
+
|
|
6325
|
+
//#endregion
|
|
6326
|
+
//#region src/v2/hooks/use-pin-to-send.ts
|
|
6327
|
+
function usePinToSend({ scrollRef, contentRef, spacerRef, topOffset = 16 }) {
|
|
6328
|
+
const { id, sendNonce } = (0, react.useContext)(LastUserMessageContext);
|
|
6329
|
+
const lastNonceRef = (0, react.useRef)(-1);
|
|
6330
|
+
const currentSpacerHeightRef = (0, react.useRef)(0);
|
|
6331
|
+
(0, react.useEffect)(() => {
|
|
6332
|
+
if (sendNonce === lastNonceRef.current) return;
|
|
6333
|
+
lastNonceRef.current = sendNonce;
|
|
6334
|
+
if (!id) return;
|
|
6335
|
+
const scrollEl = scrollRef.current;
|
|
6336
|
+
const contentEl = contentRef.current;
|
|
6337
|
+
const spacerEl = spacerRef.current;
|
|
6338
|
+
if (!scrollEl || !contentEl || !spacerEl) return;
|
|
6339
|
+
const escaped = typeof CSS !== "undefined" && CSS.escape ? CSS.escape(id) : id.replace(/[!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~]/g, "\\$&");
|
|
6340
|
+
const targetEl = contentEl.querySelector(`[data-message-id="${escaped}"]`);
|
|
6341
|
+
if (!targetEl) return;
|
|
6342
|
+
const viewportHeight = scrollEl.clientHeight;
|
|
6343
|
+
const userMessageHeight = targetEl.getBoundingClientRect().height;
|
|
6344
|
+
const paddingTop = parseFloat(getComputedStyle(targetEl).paddingTop) || 0;
|
|
6345
|
+
const bubbleHeight = Math.max(0, userMessageHeight - paddingTop);
|
|
6346
|
+
const spacerHeight = Math.max(0, viewportHeight - bubbleHeight - topOffset);
|
|
6347
|
+
spacerEl.style.height = `${spacerHeight}px`;
|
|
6348
|
+
currentSpacerHeightRef.current = spacerHeight;
|
|
6349
|
+
const raf = requestAnimationFrame(() => {
|
|
6350
|
+
const targetTop = computeOffsetTop(targetEl, scrollEl) + paddingTop - topOffset;
|
|
6351
|
+
scrollEl.scrollTo({
|
|
6352
|
+
top: Math.max(0, targetTop),
|
|
6353
|
+
behavior: "smooth"
|
|
6354
|
+
});
|
|
6355
|
+
});
|
|
6356
|
+
const ro = new ResizeObserver(() => {
|
|
6357
|
+
if (!contentEl || !spacerEl || !scrollEl) return;
|
|
6358
|
+
const consumedBelow = contentEl.getBoundingClientRect().height - computeOffsetTop(targetEl, contentEl) - userMessageHeight;
|
|
6359
|
+
const remaining = Math.max(0, spacerHeight - consumedBelow);
|
|
6360
|
+
if (remaining < currentSpacerHeightRef.current) {
|
|
6361
|
+
spacerEl.style.height = `${remaining}px`;
|
|
6362
|
+
currentSpacerHeightRef.current = remaining;
|
|
6363
|
+
}
|
|
6364
|
+
});
|
|
6365
|
+
ro.observe(contentEl);
|
|
6366
|
+
return () => {
|
|
6367
|
+
cancelAnimationFrame(raf);
|
|
6368
|
+
ro.disconnect();
|
|
6369
|
+
};
|
|
6370
|
+
}, [
|
|
6371
|
+
id,
|
|
6372
|
+
sendNonce,
|
|
6373
|
+
scrollRef,
|
|
6374
|
+
contentRef,
|
|
6375
|
+
spacerRef,
|
|
6376
|
+
topOffset
|
|
6377
|
+
]);
|
|
6378
|
+
}
|
|
6379
|
+
function computeOffsetTop(el, stopAt) {
|
|
6380
|
+
const elRect = el.getBoundingClientRect();
|
|
6381
|
+
const stopRect = stopAt.getBoundingClientRect();
|
|
6382
|
+
return elRect.top - stopRect.top + stopAt.scrollTop;
|
|
6383
|
+
}
|
|
6384
|
+
|
|
6311
6385
|
//#endregion
|
|
6312
6386
|
//#region src/v2/components/chat/CopilotChatView.tsx
|
|
6313
|
-
const
|
|
6387
|
+
const SCROLL_BUTTON_OFFSET = 16;
|
|
6314
6388
|
function DropOverlay() {
|
|
6315
6389
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6316
6390
|
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,7 +6397,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6323
6397
|
})
|
|
6324
6398
|
});
|
|
6325
6399
|
}
|
|
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 }) {
|
|
6400
|
+
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 }) {
|
|
6327
6401
|
const inputContainerRef = (0, react.useRef)(null);
|
|
6328
6402
|
const [inputContainerHeight, setInputContainerHeight] = (0, react.useState)(0);
|
|
6329
6403
|
const [isResizing, setIsResizing] = (0, react.useState)(false);
|
|
@@ -6373,11 +6447,11 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6373
6447
|
onAddFile,
|
|
6374
6448
|
positioning: "static",
|
|
6375
6449
|
keyboardHeight: isKeyboardOpen ? keyboardHeight : 0,
|
|
6376
|
-
containerRef: inputContainerRef,
|
|
6377
6450
|
showDisclaimer: true,
|
|
6451
|
+
bottomAnchored: true,
|
|
6378
6452
|
...disclaimer !== void 0 ? { disclaimer } : {}
|
|
6379
6453
|
});
|
|
6380
|
-
const hasSuggestions = Array.isArray(suggestions) && suggestions.length > 0;
|
|
6454
|
+
const hasSuggestions = !isConnecting && !isRunning && Array.isArray(suggestions) && suggestions.length > 0;
|
|
6381
6455
|
const BoundSuggestionView = hasSuggestions ? renderSlot(suggestionView, CopilotChatSuggestionView, {
|
|
6382
6456
|
suggestions,
|
|
6383
6457
|
loadingIndexes: suggestionLoadingIndexes,
|
|
@@ -6389,7 +6463,8 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6389
6463
|
inputContainerHeight,
|
|
6390
6464
|
isResizing,
|
|
6391
6465
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6392
|
-
|
|
6466
|
+
"data-testid": "copilot-scroll-content",
|
|
6467
|
+
style: { paddingBottom: `${inputContainerHeight + (hasSuggestions ? 4 : 32)}px` },
|
|
6393
6468
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6394
6469
|
className: "cpk:max-w-3xl cpk:mx-auto",
|
|
6395
6470
|
children: [BoundMessageView, hasSuggestions ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -6399,7 +6474,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6399
6474
|
})
|
|
6400
6475
|
})
|
|
6401
6476
|
});
|
|
6402
|
-
if (messages.length === 0 && !(welcomeScreen === false)) {
|
|
6477
|
+
if (messages.length === 0 && !(welcomeScreen === false) && !isConnecting && !hasExplicitThreadId) {
|
|
6403
6478
|
const BoundInputForWelcome = renderSlot(input, CopilotChatInput_default, {
|
|
6404
6479
|
onSubmitMessage,
|
|
6405
6480
|
onStop,
|
|
@@ -6463,15 +6538,19 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6463
6538
|
children: [
|
|
6464
6539
|
dragOver && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DropOverlay, {}),
|
|
6465
6540
|
BoundScrollView,
|
|
6466
|
-
/* @__PURE__ */ (0, react_jsx_runtime.
|
|
6467
|
-
|
|
6468
|
-
|
|
6469
|
-
|
|
6470
|
-
|
|
6471
|
-
className: "cpk:
|
|
6472
|
-
|
|
6473
|
-
|
|
6474
|
-
|
|
6541
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6542
|
+
ref: inputContainerRef,
|
|
6543
|
+
"data-testid": "copilot-input-overlay",
|
|
6544
|
+
className: "cpk:absolute cpk:bottom-0 cpk:left-0 cpk:right-0 cpk:z-20 cpk:pointer-events-none",
|
|
6545
|
+
children: [attachments && attachments.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6546
|
+
className: "cpk:max-w-3xl cpk:mx-auto cpk:w-full cpk:pointer-events-auto",
|
|
6547
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotChatAttachmentQueue, {
|
|
6548
|
+
attachments,
|
|
6549
|
+
onRemoveAttachment: (id) => onRemoveAttachment === null || onRemoveAttachment === void 0 ? void 0 : onRemoveAttachment(id),
|
|
6550
|
+
className: "cpk:px-4"
|
|
6551
|
+
})
|
|
6552
|
+
}), BoundInput]
|
|
6553
|
+
})
|
|
6475
6554
|
]
|
|
6476
6555
|
});
|
|
6477
6556
|
}
|
|
@@ -6501,15 +6580,66 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6501
6580
|
BoundFeather,
|
|
6502
6581
|
!isAtBottom && !isResizing && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6503
6582
|
className: "cpk:absolute cpk:inset-x-0 cpk:flex cpk:justify-center cpk:z-30 cpk:pointer-events-none",
|
|
6504
|
-
style: { bottom: `${inputContainerHeight +
|
|
6583
|
+
style: { bottom: `${inputContainerHeight + SCROLL_BUTTON_OFFSET}px` },
|
|
6505
6584
|
children: renderSlot(scrollToBottomButton, CopilotChatView.ScrollToBottomButton, { onClick: () => scrollToBottom() })
|
|
6506
6585
|
})
|
|
6507
6586
|
] })
|
|
6508
6587
|
});
|
|
6509
6588
|
};
|
|
6510
|
-
|
|
6589
|
+
const PinToSendScrollContainer = ({ children, scrollRef, contentRef, scrollToBottom, scrollToBottomButton, feather, inputContainerHeight, isResizing, nonAutoScrollEl, nonAutoScrollRefCallback, showScrollButton, className, ...props }) => {
|
|
6590
|
+
const spacerRef = (0, react.useRef)(null);
|
|
6591
|
+
usePinToSend({
|
|
6592
|
+
scrollRef,
|
|
6593
|
+
contentRef,
|
|
6594
|
+
spacerRef,
|
|
6595
|
+
topOffset: 16
|
|
6596
|
+
});
|
|
6597
|
+
const BoundFeather = renderSlot(feather, CopilotChatView.Feather, {});
|
|
6598
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ScrollElementContext.Provider, {
|
|
6599
|
+
value: nonAutoScrollEl,
|
|
6600
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6601
|
+
className: cn("cpk:h-full cpk:max-h-full cpk:flex cpk:flex-col cpk:min-h-0 cpk:relative", className),
|
|
6602
|
+
children: [
|
|
6603
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
6604
|
+
ref: nonAutoScrollRefCallback,
|
|
6605
|
+
className: "cpk:flex-1 cpk:min-h-0 cpk:overflow-y-auto cpk:overflow-x-hidden",
|
|
6606
|
+
...props,
|
|
6607
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6608
|
+
ref: contentRef,
|
|
6609
|
+
className: "cpk:px-4 cpk:sm:px-0 cpk:[div[data-sidebar-chat]_&]:px-8 cpk:[div[data-popup-chat]_&]:px-6",
|
|
6610
|
+
children
|
|
6611
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6612
|
+
ref: spacerRef,
|
|
6613
|
+
"data-pin-to-send-spacer": true,
|
|
6614
|
+
"aria-hidden": "true",
|
|
6615
|
+
style: {
|
|
6616
|
+
height: 0,
|
|
6617
|
+
flex: "0 0 auto"
|
|
6618
|
+
}
|
|
6619
|
+
})]
|
|
6620
|
+
}),
|
|
6621
|
+
BoundFeather,
|
|
6622
|
+
showScrollButton && !isResizing && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6623
|
+
className: "cpk:absolute cpk:inset-x-0 cpk:flex cpk:justify-center cpk:z-30 cpk:pointer-events-none",
|
|
6624
|
+
style: { bottom: `${inputContainerHeight + SCROLL_BUTTON_OFFSET}px` },
|
|
6625
|
+
children: renderSlot(scrollToBottomButton, CopilotChatView.ScrollToBottomButton, { onClick: () => scrollToBottom() })
|
|
6626
|
+
})
|
|
6627
|
+
]
|
|
6628
|
+
})
|
|
6629
|
+
});
|
|
6630
|
+
};
|
|
6631
|
+
_CopilotChatView.ScrollView = ({ children, autoScroll = "pin-to-bottom", scrollToBottomButton, feather, inputContainerHeight = 0, isResizing = false, className, ...props }) => {
|
|
6632
|
+
const mode = normalizeAutoScroll(autoScroll);
|
|
6511
6633
|
const [hasMounted, setHasMounted] = (0, react.useState)(false);
|
|
6512
|
-
const
|
|
6634
|
+
const scrollRef = (0, react.useRef)(null);
|
|
6635
|
+
const contentRef = (0, react.useRef)(null);
|
|
6636
|
+
const scrollToBottom = (0, react.useCallback)(() => {
|
|
6637
|
+
const el = scrollRef.current;
|
|
6638
|
+
if (el) el.scrollTo({
|
|
6639
|
+
top: el.scrollHeight,
|
|
6640
|
+
behavior: "smooth"
|
|
6641
|
+
});
|
|
6642
|
+
}, []);
|
|
6513
6643
|
const [showScrollButton, setShowScrollButton] = (0, react.useState)(false);
|
|
6514
6644
|
const [nonAutoScrollEl, setNonAutoScrollEl] = (0, react.useState)(null);
|
|
6515
6645
|
const nonAutoScrollRefCallback = (0, react.useCallback)((el) => {
|
|
@@ -6520,7 +6650,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6520
6650
|
setHasMounted(true);
|
|
6521
6651
|
}, []);
|
|
6522
6652
|
(0, react.useEffect)(() => {
|
|
6523
|
-
if (
|
|
6653
|
+
if (mode === "pin-to-bottom") return;
|
|
6524
6654
|
const scrollElement = scrollRef.current;
|
|
6525
6655
|
if (!scrollElement) return;
|
|
6526
6656
|
const checkScroll = () => {
|
|
@@ -6534,7 +6664,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6534
6664
|
scrollElement.removeEventListener("scroll", checkScroll);
|
|
6535
6665
|
resizeObserver.disconnect();
|
|
6536
6666
|
};
|
|
6537
|
-
}, [scrollRef,
|
|
6667
|
+
}, [scrollRef, mode]);
|
|
6538
6668
|
if (!hasMounted) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6539
6669
|
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
6670
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -6542,7 +6672,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6542
6672
|
children
|
|
6543
6673
|
})
|
|
6544
6674
|
});
|
|
6545
|
-
if (
|
|
6675
|
+
if (mode === "none") {
|
|
6546
6676
|
const BoundFeather = renderSlot(feather, CopilotChatView.Feather, {});
|
|
6547
6677
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ScrollElementContext.Provider, {
|
|
6548
6678
|
value: nonAutoScrollEl,
|
|
@@ -6559,13 +6689,28 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6559
6689
|
BoundFeather,
|
|
6560
6690
|
showScrollButton && !isResizing && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6561
6691
|
className: "cpk:absolute cpk:inset-x-0 cpk:flex cpk:justify-center cpk:z-30 cpk:pointer-events-none",
|
|
6562
|
-
style: { bottom: `${inputContainerHeight +
|
|
6692
|
+
style: { bottom: `${inputContainerHeight + SCROLL_BUTTON_OFFSET}px` },
|
|
6563
6693
|
children: renderSlot(scrollToBottomButton, CopilotChatView.ScrollToBottomButton, { onClick: () => scrollToBottom() })
|
|
6564
6694
|
})
|
|
6565
6695
|
]
|
|
6566
6696
|
})
|
|
6567
6697
|
});
|
|
6568
6698
|
}
|
|
6699
|
+
if (mode === "pin-to-send") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(PinToSendScrollContainer, {
|
|
6700
|
+
scrollRef,
|
|
6701
|
+
contentRef,
|
|
6702
|
+
scrollToBottom,
|
|
6703
|
+
scrollToBottomButton,
|
|
6704
|
+
feather,
|
|
6705
|
+
inputContainerHeight,
|
|
6706
|
+
isResizing,
|
|
6707
|
+
nonAutoScrollEl,
|
|
6708
|
+
nonAutoScrollRefCallback,
|
|
6709
|
+
showScrollButton,
|
|
6710
|
+
className,
|
|
6711
|
+
...props,
|
|
6712
|
+
children
|
|
6713
|
+
});
|
|
6569
6714
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(use_stick_to_bottom.StickToBottom, {
|
|
6570
6715
|
className: cn("cpk:flex-1 cpk:max-h-full cpk:flex cpk:flex-col cpk:min-h-0", className),
|
|
6571
6716
|
resize: "smooth",
|
|
@@ -6588,9 +6733,8 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6588
6733
|
...props,
|
|
6589
6734
|
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
6735
|
});
|
|
6591
|
-
_CopilotChatView.Feather = ({ className,
|
|
6592
|
-
className
|
|
6593
|
-
style,
|
|
6736
|
+
_CopilotChatView.Feather = ({ className, ...props }) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6737
|
+
className,
|
|
6594
6738
|
...props
|
|
6595
6739
|
});
|
|
6596
6740
|
_CopilotChatView.WelcomeMessage = ({ className, ...props }) => {
|
|
@@ -6762,10 +6906,9 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6762
6906
|
var _ref, _attachmentsConfig$ac;
|
|
6763
6907
|
const existingConfig = useCopilotChatConfiguration();
|
|
6764
6908
|
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]);
|
|
6909
|
+
const providedThreadId = threadId !== null && threadId !== void 0 ? threadId : existingConfig === null || existingConfig === void 0 ? void 0 : existingConfig.threadId;
|
|
6910
|
+
const resolvedThreadId = (0, react.useMemo)(() => providedThreadId !== null && providedThreadId !== void 0 ? providedThreadId : (0, _copilotkit_shared.randomUUID)(), [providedThreadId]);
|
|
6911
|
+
const hasExplicitThreadId = !!threadId || !!(existingConfig === null || existingConfig === void 0 ? void 0 : existingConfig.hasExplicitThreadId);
|
|
6769
6912
|
const { agent } = useAgent({
|
|
6770
6913
|
agentId: resolvedAgentId,
|
|
6771
6914
|
threadId: resolvedThreadId,
|
|
@@ -6807,7 +6950,10 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6807
6950
|
const isTranscriptionEnabled = copilotkit.audioFileTranscriptionEnabled;
|
|
6808
6951
|
const isMediaRecorderSupported = typeof window !== "undefined" && typeof MediaRecorder !== "undefined";
|
|
6809
6952
|
const { messageView: providedMessageView, suggestionView: providedSuggestionView, onStop: providedStopHandler, ...restProps } = props;
|
|
6953
|
+
const [lastConnectedThreadId, setLastConnectedThreadId] = (0, react.useState)(null);
|
|
6954
|
+
const isConnecting = hasExplicitThreadId && lastConnectedThreadId !== resolvedThreadId;
|
|
6810
6955
|
(0, react.useEffect)(() => {
|
|
6956
|
+
if (!hasExplicitThreadId) return;
|
|
6811
6957
|
let detached = false;
|
|
6812
6958
|
const connectAbortController = new AbortController();
|
|
6813
6959
|
if (agent instanceof _ag_ui_client.HttpAgent) agent.abortController = connectAbortController;
|
|
@@ -6817,6 +6963,10 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6817
6963
|
} catch (error) {
|
|
6818
6964
|
if (detached) return;
|
|
6819
6965
|
console.error("CopilotChat: connectAgent failed", error);
|
|
6966
|
+
} finally {
|
|
6967
|
+
if (!detached) (typeof requestAnimationFrame === "function" ? requestAnimationFrame : (cb) => setTimeout(cb, 16))(() => {
|
|
6968
|
+
if (!detached) setLastConnectedThreadId(resolvedThreadId);
|
|
6969
|
+
});
|
|
6820
6970
|
}
|
|
6821
6971
|
};
|
|
6822
6972
|
connect(agent);
|
|
@@ -6828,7 +6978,8 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6828
6978
|
}, [
|
|
6829
6979
|
resolvedThreadId,
|
|
6830
6980
|
agent,
|
|
6831
|
-
resolvedAgentId
|
|
6981
|
+
resolvedAgentId,
|
|
6982
|
+
hasExplicitThreadId
|
|
6832
6983
|
]);
|
|
6833
6984
|
const onSubmitInput = (0, react.useCallback)(async (value) => {
|
|
6834
6985
|
if (selectedAttachments.some((a) => a.status === "uploading")) {
|
|
@@ -6985,6 +7136,22 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
6985
7136
|
}).join(";") : "";
|
|
6986
7137
|
return `${m.id}:${m.role}:${contentKey}:${toolCallsKey}`;
|
|
6987
7138
|
}).join(",")]);
|
|
7139
|
+
const lastUserMessageId = (0, react.useMemo)(() => {
|
|
7140
|
+
for (let i = messages.length - 1; i >= 0; i--) if (messages[i].role === "user") return messages[i].id;
|
|
7141
|
+
return null;
|
|
7142
|
+
}, [messages]);
|
|
7143
|
+
const [sendNonce, setSendNonce] = (0, react.useState)(0);
|
|
7144
|
+
const prevLastUserMessageIdRef = (0, react.useRef)(lastUserMessageId);
|
|
7145
|
+
(0, react.useEffect)(() => {
|
|
7146
|
+
if (lastUserMessageId && lastUserMessageId !== prevLastUserMessageIdRef.current) {
|
|
7147
|
+
setSendNonce((n) => n + 1);
|
|
7148
|
+
prevLastUserMessageIdRef.current = lastUserMessageId;
|
|
7149
|
+
}
|
|
7150
|
+
}, [lastUserMessageId]);
|
|
7151
|
+
const lastUserMessageState = (0, react.useMemo)(() => ({
|
|
7152
|
+
id: lastUserMessageId,
|
|
7153
|
+
sendNonce
|
|
7154
|
+
}), [lastUserMessageId, sendNonce]);
|
|
6988
7155
|
const RenderedChatView = renderSlot(chatView, CopilotChatView, {
|
|
6989
7156
|
...mergedProps,
|
|
6990
7157
|
messages,
|
|
@@ -7003,11 +7170,14 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
7003
7170
|
dragOver,
|
|
7004
7171
|
onDragOver: handleDragOver,
|
|
7005
7172
|
onDragLeave: handleDragLeave,
|
|
7006
|
-
onDrop: handleDrop
|
|
7173
|
+
onDrop: handleDrop,
|
|
7174
|
+
isConnecting,
|
|
7175
|
+
hasExplicitThreadId
|
|
7007
7176
|
});
|
|
7008
7177
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotChatConfigurationProvider, {
|
|
7009
7178
|
agentId: resolvedAgentId,
|
|
7010
7179
|
threadId: resolvedThreadId,
|
|
7180
|
+
hasExplicitThreadId,
|
|
7011
7181
|
labels,
|
|
7012
7182
|
isModalDefaultOpen,
|
|
7013
7183
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -7038,7 +7208,10 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
7038
7208
|
},
|
|
7039
7209
|
children: transcriptionError
|
|
7040
7210
|
}),
|
|
7041
|
-
|
|
7211
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(LastUserMessageContext.Provider, {
|
|
7212
|
+
value: lastUserMessageState,
|
|
7213
|
+
children: RenderedChatView
|
|
7214
|
+
})
|
|
7042
7215
|
]
|
|
7043
7216
|
})
|
|
7044
7217
|
});
|
|
@@ -8663,12 +8836,19 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
8663
8836
|
//#region src/context/threads-context.tsx
|
|
8664
8837
|
const ThreadsContext = (0, react.createContext)(void 0);
|
|
8665
8838
|
function ThreadsProvider({ children, threadId: explicitThreadId }) {
|
|
8666
|
-
const [internalThreadId,
|
|
8839
|
+
const [internalThreadId, setInternalThreadId] = (0, react.useState)(() => (0, _copilotkit_shared.randomUUID)());
|
|
8840
|
+
const [internalIsExplicit, setInternalIsExplicit] = (0, react.useState)(false);
|
|
8667
8841
|
const threadId = explicitThreadId !== null && explicitThreadId !== void 0 ? explicitThreadId : internalThreadId;
|
|
8842
|
+
const isThreadIdExplicit = explicitThreadId != null || internalIsExplicit;
|
|
8843
|
+
const setThreadId = (0, react.useCallback)((value) => {
|
|
8844
|
+
setInternalThreadId(value);
|
|
8845
|
+
setInternalIsExplicit(true);
|
|
8846
|
+
}, []);
|
|
8668
8847
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ThreadsContext.Provider, {
|
|
8669
8848
|
value: {
|
|
8670
8849
|
threadId,
|
|
8671
|
-
setThreadId
|
|
8850
|
+
setThreadId,
|
|
8851
|
+
isThreadIdExplicit
|
|
8672
8852
|
},
|
|
8673
8853
|
children
|
|
8674
8854
|
});
|
|
@@ -9388,7 +9568,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
9388
9568
|
if (props.agent) setAgentSession({ agentName: props.agent });
|
|
9389
9569
|
else setAgentSession(null);
|
|
9390
9570
|
}, [props.agent]);
|
|
9391
|
-
const { threadId, setThreadId: setInternalThreadId } = useThreads$1();
|
|
9571
|
+
const { threadId, setThreadId: setInternalThreadId, isThreadIdExplicit } = useThreads$1();
|
|
9392
9572
|
const setThreadId = (0, react.useCallback)((value) => {
|
|
9393
9573
|
if (props.threadId) throw new Error("Cannot call setThreadId() when threadId is provided via props.");
|
|
9394
9574
|
setInternalThreadId(value);
|
|
@@ -9594,6 +9774,7 @@ window.parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-
|
|
|
9594
9774
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopilotChatConfigurationProvider, {
|
|
9595
9775
|
agentId: (_props$agent2 = props.agent) !== null && _props$agent2 !== void 0 ? _props$agent2 : "default",
|
|
9596
9776
|
threadId,
|
|
9777
|
+
hasExplicitThreadId: isThreadIdExplicit,
|
|
9597
9778
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(CopilotContext.Provider, {
|
|
9598
9779
|
value: copilotContextValue,
|
|
9599
9780
|
children: [
|