@copilotkitnext/react 0.0.17 → 0.0.19-threads-and-attachements.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +196 -19
- package/dist/index.d.ts +196 -19
- package/dist/index.js +868 -220
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +874 -228
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -54,6 +54,7 @@ __export(index_exports, {
|
|
|
54
54
|
CopilotPopupView: () => CopilotPopupView,
|
|
55
55
|
CopilotSidebar: () => CopilotSidebar,
|
|
56
56
|
CopilotSidebarView: () => CopilotSidebarView,
|
|
57
|
+
CopilotThreadList: () => CopilotThreadList,
|
|
57
58
|
WildcardToolCallRender: () => WildcardToolCallRender,
|
|
58
59
|
defineToolCallRenderer: () => defineToolCallRenderer,
|
|
59
60
|
useAgent: () => useAgent,
|
|
@@ -65,7 +66,9 @@ __export(index_exports, {
|
|
|
65
66
|
useHumanInTheLoop: () => useHumanInTheLoop,
|
|
66
67
|
useRenderCustomMessages: () => useRenderCustomMessages,
|
|
67
68
|
useRenderToolCall: () => useRenderToolCall,
|
|
68
|
-
useSuggestions: () => useSuggestions
|
|
69
|
+
useSuggestions: () => useSuggestions,
|
|
70
|
+
useThreadSwitch: () => useThreadSwitch,
|
|
71
|
+
useThreads: () => useThreads
|
|
69
72
|
});
|
|
70
73
|
module.exports = __toCommonJS(index_exports);
|
|
71
74
|
|
|
@@ -111,15 +114,21 @@ var CopilotChatConfigurationProvider = ({ children, labels, agentId, threadId, i
|
|
|
111
114
|
[labels, parentConfig?.labels]
|
|
112
115
|
);
|
|
113
116
|
const resolvedAgentId = agentId ?? parentConfig?.agentId ?? import_shared.DEFAULT_AGENT_ID;
|
|
114
|
-
const
|
|
115
|
-
if (threadId)
|
|
116
|
-
|
|
117
|
-
}
|
|
118
|
-
if (parentConfig?.threadId) {
|
|
119
|
-
return parentConfig.threadId;
|
|
120
|
-
}
|
|
117
|
+
const [internalThreadId, setInternalThreadId] = (0, import_react.useState)(() => {
|
|
118
|
+
if (threadId) return threadId;
|
|
119
|
+
if (parentConfig?.threadId) return parentConfig.threadId;
|
|
121
120
|
return (0, import_shared.randomUUID)();
|
|
122
|
-
}
|
|
121
|
+
});
|
|
122
|
+
const resolvedThreadId = threadId ?? internalThreadId;
|
|
123
|
+
const handleSetThreadId = (0, import_react.useCallback)(
|
|
124
|
+
(newThreadId) => {
|
|
125
|
+
if (threadId === void 0) {
|
|
126
|
+
setInternalThreadId(newThreadId);
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
[threadId]
|
|
130
|
+
);
|
|
131
|
+
const resolvedSetThreadId = parentConfig?.setThreadId ?? handleSetThreadId;
|
|
123
132
|
const resolvedDefaultOpen = isModalDefaultOpen ?? parentConfig?.isModalDefaultOpen ?? true;
|
|
124
133
|
const [internalModalOpen, setInternalModalOpen] = (0, import_react.useState)(
|
|
125
134
|
parentConfig?.isModalOpen ?? resolvedDefaultOpen
|
|
@@ -131,6 +140,7 @@ var CopilotChatConfigurationProvider = ({ children, labels, agentId, threadId, i
|
|
|
131
140
|
labels: mergedLabels,
|
|
132
141
|
agentId: resolvedAgentId,
|
|
133
142
|
threadId: resolvedThreadId,
|
|
143
|
+
setThreadId: resolvedSetThreadId,
|
|
134
144
|
isModalOpen: resolvedIsModalOpen,
|
|
135
145
|
setModalOpen: resolvedSetModalOpen,
|
|
136
146
|
isModalDefaultOpen: resolvedDefaultOpen
|
|
@@ -139,6 +149,7 @@ var CopilotChatConfigurationProvider = ({ children, labels, agentId, threadId, i
|
|
|
139
149
|
mergedLabels,
|
|
140
150
|
resolvedAgentId,
|
|
141
151
|
resolvedThreadId,
|
|
152
|
+
resolvedSetThreadId,
|
|
142
153
|
resolvedIsModalOpen,
|
|
143
154
|
resolvedSetModalOpen,
|
|
144
155
|
resolvedDefaultOpen
|
|
@@ -847,10 +858,7 @@ function CopilotChatInput({
|
|
|
847
858
|
onChange: handleChange,
|
|
848
859
|
onKeyDown: handleKeyDown,
|
|
849
860
|
autoFocus,
|
|
850
|
-
className: (0, import_tailwind_merge3.twMerge)(
|
|
851
|
-
"w-full py-3",
|
|
852
|
-
isExpanded ? "px-5" : "pr-5"
|
|
853
|
-
)
|
|
861
|
+
className: (0, import_tailwind_merge3.twMerge)("w-full py-3", isExpanded ? "px-5" : "pr-5")
|
|
854
862
|
});
|
|
855
863
|
const isProcessing = mode !== "transcribe" && isRunning;
|
|
856
864
|
const canSend = resolvedValue.trim().length > 0 && !!onSubmitMessage;
|
|
@@ -1091,10 +1099,10 @@ function CopilotChatInput({
|
|
|
1091
1099
|
if (!slashMenuVisible || slashHighlightIndex < 0) {
|
|
1092
1100
|
return;
|
|
1093
1101
|
}
|
|
1094
|
-
const active = slashMenuRef.current?.querySelector(
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1102
|
+
const active = slashMenuRef.current?.querySelector(`[data-slash-index="${slashHighlightIndex}"]`);
|
|
1103
|
+
if (active && typeof active.scrollIntoView === "function") {
|
|
1104
|
+
active.scrollIntoView({ block: "nearest" });
|
|
1105
|
+
}
|
|
1098
1106
|
}, [slashMenuVisible, slashHighlightIndex]);
|
|
1099
1107
|
const slashMenu = slashMenuVisible ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
1100
1108
|
"div",
|
|
@@ -1165,11 +1173,7 @@ function CopilotChatInput({
|
|
|
1165
1173
|
"div",
|
|
1166
1174
|
{
|
|
1167
1175
|
ref: addButtonContainerRef,
|
|
1168
|
-
className: (0, import_tailwind_merge3.twMerge)(
|
|
1169
|
-
"flex items-center",
|
|
1170
|
-
isExpanded ? "row-start-2" : "row-start-1",
|
|
1171
|
-
"col-start-1"
|
|
1172
|
-
),
|
|
1176
|
+
className: (0, import_tailwind_merge3.twMerge)("flex items-center", isExpanded ? "row-start-2" : "row-start-1", "col-start-1"),
|
|
1173
1177
|
children: BoundAddMenuButton
|
|
1174
1178
|
}
|
|
1175
1179
|
),
|
|
@@ -1346,7 +1350,9 @@ function CopilotChatInput({
|
|
|
1346
1350
|
if (!textarea) return;
|
|
1347
1351
|
const handleFocus = () => {
|
|
1348
1352
|
setTimeout(() => {
|
|
1349
|
-
textarea.scrollIntoView
|
|
1353
|
+
if (typeof textarea.scrollIntoView === "function") {
|
|
1354
|
+
textarea.scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
1355
|
+
}
|
|
1350
1356
|
}, 300);
|
|
1351
1357
|
};
|
|
1352
1358
|
textarea.addEventListener("focus", handleFocus);
|
|
@@ -1388,7 +1394,7 @@ CopilotChatInput.AddMenuButton.displayName = "CopilotChatInput.AddMenuButton";
|
|
|
1388
1394
|
var CopilotChatInput_default = CopilotChatInput;
|
|
1389
1395
|
|
|
1390
1396
|
// src/components/chat/CopilotChatAssistantMessage.tsx
|
|
1391
|
-
var
|
|
1397
|
+
var import_react18 = require("react");
|
|
1392
1398
|
var import_lucide_react3 = require("lucide-react");
|
|
1393
1399
|
var import_tailwind_merge4 = require("tailwind-merge");
|
|
1394
1400
|
var import_katex_min = require("katex/dist/katex.min.css");
|
|
@@ -1445,12 +1451,15 @@ var CopilotKitCoreReact = class extends import_core.CopilotKitCore {
|
|
|
1445
1451
|
// src/components/CopilotKitInspector.tsx
|
|
1446
1452
|
var React4 = __toESM(require("react"));
|
|
1447
1453
|
var import_react5 = require("@lit-labs/react");
|
|
1448
|
-
var
|
|
1454
|
+
var WebInspectorModule = __toESM(require("@copilotkitnext/web-inspector"));
|
|
1449
1455
|
var import_jsx_runtime7 = require("react/jsx-runtime");
|
|
1450
|
-
|
|
1456
|
+
var WEB_INSPECTOR_TAG2 = WebInspectorModule.WEB_INSPECTOR_TAG;
|
|
1457
|
+
var defineWebInspector2 = WebInspectorModule.defineWebInspector;
|
|
1458
|
+
var WebInspectorElementClass = WebInspectorModule.WebInspectorElement;
|
|
1459
|
+
defineWebInspector2();
|
|
1451
1460
|
var CopilotKitInspectorBase = (0, import_react5.createComponent)({
|
|
1452
|
-
tagName:
|
|
1453
|
-
elementClass:
|
|
1461
|
+
tagName: WEB_INSPECTOR_TAG2,
|
|
1462
|
+
elementClass: WebInspectorElementClass,
|
|
1454
1463
|
react: React4
|
|
1455
1464
|
});
|
|
1456
1465
|
var CopilotKitInspector = React4.forwardRef(
|
|
@@ -1476,7 +1485,10 @@ CopilotKitInspector.displayName = "CopilotKitInspector";
|
|
|
1476
1485
|
// src/providers/CopilotKitProvider.tsx
|
|
1477
1486
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
1478
1487
|
var CopilotKitContext = (0, import_react6.createContext)({
|
|
1479
|
-
copilotkit: null
|
|
1488
|
+
copilotkit: null,
|
|
1489
|
+
setResourceId: () => {
|
|
1490
|
+
throw new Error("useCopilotKit must be used within CopilotKitProvider");
|
|
1491
|
+
}
|
|
1480
1492
|
});
|
|
1481
1493
|
function useStableArrayProp(prop, warningMessage, isMeaningfulChange) {
|
|
1482
1494
|
const empty = (0, import_react6.useMemo)(() => [], []);
|
|
@@ -1494,6 +1506,7 @@ var CopilotKitProvider = ({
|
|
|
1494
1506
|
runtimeUrl,
|
|
1495
1507
|
headers = {},
|
|
1496
1508
|
properties = {},
|
|
1509
|
+
resourceId,
|
|
1497
1510
|
agents__unsafe_dev_only: agents = {},
|
|
1498
1511
|
renderToolCalls,
|
|
1499
1512
|
renderCustomMessages,
|
|
@@ -1601,6 +1614,7 @@ var CopilotKitProvider = ({
|
|
|
1601
1614
|
runtimeUrl,
|
|
1602
1615
|
headers,
|
|
1603
1616
|
properties,
|
|
1617
|
+
resourceId,
|
|
1604
1618
|
agents__unsafe_dev_only: agents,
|
|
1605
1619
|
tools: allTools,
|
|
1606
1620
|
renderToolCalls: allRenderToolCalls,
|
|
@@ -1623,13 +1637,36 @@ var CopilotKitProvider = ({
|
|
|
1623
1637
|
copilotkit.setRuntimeUrl(runtimeUrl);
|
|
1624
1638
|
copilotkit.setHeaders(headers);
|
|
1625
1639
|
copilotkit.setProperties(properties);
|
|
1640
|
+
copilotkit.setResourceId(resourceId);
|
|
1626
1641
|
copilotkit.setAgents__unsafe_dev_only(agents);
|
|
1627
|
-
}, [runtimeUrl, headers, properties, agents]);
|
|
1642
|
+
}, [runtimeUrl, headers, properties, resourceId, agents]);
|
|
1643
|
+
(0, import_react6.useEffect)(() => {
|
|
1644
|
+
if (typeof window === "undefined") {
|
|
1645
|
+
return;
|
|
1646
|
+
}
|
|
1647
|
+
const isProduction = process.env.NODE_ENV === "production";
|
|
1648
|
+
if (isProduction && !resourceId) {
|
|
1649
|
+
console.error(
|
|
1650
|
+
"CopilotKit Security Warning: No resourceId set in production.\nAll threads will be globally accessible. Set the resourceId prop:\n<CopilotKitProvider resourceId={userId}>\nLearn more: https://docs.copilotkit.ai/security/resource-scoping"
|
|
1651
|
+
);
|
|
1652
|
+
} else if (!isProduction && !resourceId) {
|
|
1653
|
+
console.warn(
|
|
1654
|
+
"CopilotKit: No resourceId set. All threads are globally accessible.\nThis is fine for development, but add resourceId for production:\n<CopilotKitProvider resourceId={userId}>"
|
|
1655
|
+
);
|
|
1656
|
+
}
|
|
1657
|
+
}, [resourceId]);
|
|
1658
|
+
const setResourceId = (0, import_react6.useCallback)(
|
|
1659
|
+
(newResourceId) => {
|
|
1660
|
+
copilotkit.setResourceId(newResourceId);
|
|
1661
|
+
},
|
|
1662
|
+
[copilotkit]
|
|
1663
|
+
);
|
|
1628
1664
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
1629
1665
|
CopilotKitContext.Provider,
|
|
1630
1666
|
{
|
|
1631
1667
|
value: {
|
|
1632
|
-
copilotkit
|
|
1668
|
+
copilotkit,
|
|
1669
|
+
setResourceId
|
|
1633
1670
|
},
|
|
1634
1671
|
children: [
|
|
1635
1672
|
children,
|
|
@@ -1648,6 +1685,9 @@ var useCopilotKit = () => {
|
|
|
1648
1685
|
const unsubscribe = context.copilotkit.subscribe({
|
|
1649
1686
|
onRuntimeConnectionStatusChanged: () => {
|
|
1650
1687
|
forceUpdate();
|
|
1688
|
+
},
|
|
1689
|
+
onResourceIdChanged: () => {
|
|
1690
|
+
forceUpdate();
|
|
1651
1691
|
}
|
|
1652
1692
|
});
|
|
1653
1693
|
return () => {
|
|
@@ -1776,33 +1816,38 @@ function useRenderCustomMessages() {
|
|
|
1776
1816
|
if (!agent) {
|
|
1777
1817
|
throw new Error("Agent not found");
|
|
1778
1818
|
}
|
|
1779
|
-
const messagesIdsInRun = agent.messages.filter((msg) => copilotkit.getRunIdForMessage(agentId, threadId, msg.id) === runId).map((msg) => msg.id);
|
|
1819
|
+
const messagesIdsInRun = runId ? agent.messages.filter((msg) => copilotkit.getRunIdForMessage(agentId, threadId, msg.id) === runId).map((msg) => msg.id) : [];
|
|
1780
1820
|
const messageIndex = agent.messages.findIndex((msg) => msg.id === message.id) ?? 0;
|
|
1781
|
-
const messageIndexInRun = Math.
|
|
1821
|
+
const messageIndexInRun = Math.max(messagesIdsInRun.indexOf(message.id), 0);
|
|
1782
1822
|
const numberOfMessagesInRun = messagesIdsInRun.length;
|
|
1783
|
-
const stateSnapshot = copilotkit.getStateByRun(agentId, threadId, runId);
|
|
1823
|
+
const stateSnapshot = runId ? copilotkit.getStateByRun(agentId, threadId, runId) : void 0;
|
|
1784
1824
|
let result = null;
|
|
1785
1825
|
for (const renderer of customMessageRenderers) {
|
|
1786
1826
|
if (!renderer.render) {
|
|
1787
1827
|
continue;
|
|
1788
1828
|
}
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1805
|
-
|
|
1829
|
+
try {
|
|
1830
|
+
const Component = renderer.render;
|
|
1831
|
+
result = /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
|
|
1832
|
+
Component,
|
|
1833
|
+
{
|
|
1834
|
+
message,
|
|
1835
|
+
position,
|
|
1836
|
+
runId: runId ?? "",
|
|
1837
|
+
messageIndex,
|
|
1838
|
+
messageIndexInRun,
|
|
1839
|
+
numberOfMessagesInRun,
|
|
1840
|
+
agentId,
|
|
1841
|
+
stateSnapshot
|
|
1842
|
+
},
|
|
1843
|
+
`${runId ?? "no-run"}-${message.id}-${position}`
|
|
1844
|
+
);
|
|
1845
|
+
if (result) {
|
|
1846
|
+
break;
|
|
1847
|
+
}
|
|
1848
|
+
} catch (error) {
|
|
1849
|
+
console.error("Error rendering custom message:", error);
|
|
1850
|
+
continue;
|
|
1806
1851
|
}
|
|
1807
1852
|
}
|
|
1808
1853
|
return result;
|
|
@@ -1931,18 +1976,10 @@ function useAgent({ agentId, updates } = {}) {
|
|
|
1931
1976
|
agentId ??= import_shared4.DEFAULT_AGENT_ID;
|
|
1932
1977
|
const { copilotkit } = useCopilotKit();
|
|
1933
1978
|
const [, forceUpdate] = (0, import_react11.useReducer)((x) => x + 1, 0);
|
|
1934
|
-
const updateFlags = (0, import_react11.useMemo)(
|
|
1935
|
-
() => updates ?? ALL_UPDATES,
|
|
1936
|
-
[JSON.stringify(updates)]
|
|
1937
|
-
);
|
|
1979
|
+
const updateFlags = (0, import_react11.useMemo)(() => updates ?? ALL_UPDATES, [JSON.stringify(updates)]);
|
|
1938
1980
|
const agent = (0, import_react11.useMemo)(() => {
|
|
1939
1981
|
return copilotkit.getAgent(agentId);
|
|
1940
|
-
}, [
|
|
1941
|
-
agentId,
|
|
1942
|
-
copilotkit.agents,
|
|
1943
|
-
copilotkit.runtimeConnectionStatus,
|
|
1944
|
-
copilotkit
|
|
1945
|
-
]);
|
|
1982
|
+
}, [agentId, copilotkit.agents, copilotkit.runtimeConnectionStatus, copilotkit]);
|
|
1946
1983
|
(0, import_react11.useEffect)(() => {
|
|
1947
1984
|
if (!agent) {
|
|
1948
1985
|
return;
|
|
@@ -2178,8 +2215,137 @@ function normalizeStaticSuggestions(suggestions) {
|
|
|
2178
2215
|
}));
|
|
2179
2216
|
}
|
|
2180
2217
|
|
|
2218
|
+
// src/hooks/use-threads.tsx
|
|
2219
|
+
var import_react15 = require("react");
|
|
2220
|
+
function useThreads(options = {}) {
|
|
2221
|
+
const { limit = 50, autoFetch = true } = options;
|
|
2222
|
+
const { copilotkit: core } = useCopilotKit();
|
|
2223
|
+
const chatConfig = useCopilotChatConfiguration();
|
|
2224
|
+
const [threads, setThreads] = (0, import_react15.useState)([]);
|
|
2225
|
+
const [total, setTotal] = (0, import_react15.useState)(0);
|
|
2226
|
+
const [isLoading, setIsLoading] = (0, import_react15.useState)(false);
|
|
2227
|
+
const [error, setError] = (0, import_react15.useState)(null);
|
|
2228
|
+
const fetchThreads = (0, import_react15.useCallback)(
|
|
2229
|
+
async (offset = 0) => {
|
|
2230
|
+
if (!core) {
|
|
2231
|
+
return;
|
|
2232
|
+
}
|
|
2233
|
+
setIsLoading(true);
|
|
2234
|
+
setError(null);
|
|
2235
|
+
try {
|
|
2236
|
+
const result = await core.listThreads({ limit, offset });
|
|
2237
|
+
setThreads(result.threads);
|
|
2238
|
+
setTotal(result.total);
|
|
2239
|
+
} catch (err) {
|
|
2240
|
+
const error2 = err instanceof Error ? err : new Error("Failed to fetch threads");
|
|
2241
|
+
setError(error2);
|
|
2242
|
+
console.error("Error fetching threads:", error2);
|
|
2243
|
+
} finally {
|
|
2244
|
+
setIsLoading(false);
|
|
2245
|
+
}
|
|
2246
|
+
},
|
|
2247
|
+
[core, limit]
|
|
2248
|
+
);
|
|
2249
|
+
const getThreadMetadata = (0, import_react15.useCallback)(
|
|
2250
|
+
async (threadId) => {
|
|
2251
|
+
if (!core) {
|
|
2252
|
+
throw new Error("CopilotKit core not initialized");
|
|
2253
|
+
}
|
|
2254
|
+
try {
|
|
2255
|
+
return await core.getThreadMetadata(threadId);
|
|
2256
|
+
} catch (err) {
|
|
2257
|
+
const error2 = err instanceof Error ? err : new Error("Failed to get thread metadata");
|
|
2258
|
+
console.error("Error getting thread metadata:", error2);
|
|
2259
|
+
throw error2;
|
|
2260
|
+
}
|
|
2261
|
+
},
|
|
2262
|
+
[core]
|
|
2263
|
+
);
|
|
2264
|
+
const refresh = (0, import_react15.useCallback)(() => fetchThreads(0), [fetchThreads]);
|
|
2265
|
+
const addOptimisticThread = (0, import_react15.useCallback)((threadId) => {
|
|
2266
|
+
const newThread = {
|
|
2267
|
+
threadId,
|
|
2268
|
+
createdAt: Date.now(),
|
|
2269
|
+
lastActivityAt: Date.now(),
|
|
2270
|
+
isRunning: false,
|
|
2271
|
+
messageCount: 0,
|
|
2272
|
+
firstMessage: void 0
|
|
2273
|
+
};
|
|
2274
|
+
setThreads((prev) => [newThread, ...prev]);
|
|
2275
|
+
setTotal((prev) => prev + 1);
|
|
2276
|
+
}, []);
|
|
2277
|
+
const deleteThread = (0, import_react15.useCallback)(
|
|
2278
|
+
async (threadId) => {
|
|
2279
|
+
if (!core) {
|
|
2280
|
+
throw new Error("CopilotKit core not initialized");
|
|
2281
|
+
}
|
|
2282
|
+
const originalThreads = threads;
|
|
2283
|
+
const originalTotal = total;
|
|
2284
|
+
const threadIndex = threads.findIndex((t) => t.threadId === threadId);
|
|
2285
|
+
const deletedThread = threadIndex >= 0 ? threads[threadIndex] : null;
|
|
2286
|
+
if (threadIndex >= 0) {
|
|
2287
|
+
setThreads((prev) => prev.filter((t) => t.threadId !== threadId));
|
|
2288
|
+
setTotal((prev) => prev - 1);
|
|
2289
|
+
}
|
|
2290
|
+
try {
|
|
2291
|
+
await core.deleteThread(threadId);
|
|
2292
|
+
await fetchThreads();
|
|
2293
|
+
} catch (err) {
|
|
2294
|
+
if (deletedThread && threadIndex >= 0) {
|
|
2295
|
+
setThreads((prev) => {
|
|
2296
|
+
const newThreads = [...prev];
|
|
2297
|
+
newThreads.splice(threadIndex, 0, deletedThread);
|
|
2298
|
+
return newThreads;
|
|
2299
|
+
});
|
|
2300
|
+
setTotal(originalTotal);
|
|
2301
|
+
} else {
|
|
2302
|
+
setThreads(originalThreads);
|
|
2303
|
+
setTotal(originalTotal);
|
|
2304
|
+
}
|
|
2305
|
+
const error2 = err instanceof Error ? err : new Error("Failed to delete thread");
|
|
2306
|
+
console.error("Error deleting thread:", error2);
|
|
2307
|
+
throw error2;
|
|
2308
|
+
}
|
|
2309
|
+
},
|
|
2310
|
+
[core, fetchThreads, threads, total]
|
|
2311
|
+
);
|
|
2312
|
+
(0, import_react15.useEffect)(() => {
|
|
2313
|
+
if (autoFetch && core) {
|
|
2314
|
+
void fetchThreads();
|
|
2315
|
+
}
|
|
2316
|
+
}, [autoFetch, core, fetchThreads]);
|
|
2317
|
+
return {
|
|
2318
|
+
threads,
|
|
2319
|
+
total,
|
|
2320
|
+
isLoading,
|
|
2321
|
+
error,
|
|
2322
|
+
fetchThreads,
|
|
2323
|
+
getThreadMetadata,
|
|
2324
|
+
refresh,
|
|
2325
|
+
addOptimisticThread,
|
|
2326
|
+
deleteThread,
|
|
2327
|
+
currentThreadId: chatConfig?.threadId
|
|
2328
|
+
};
|
|
2329
|
+
}
|
|
2330
|
+
|
|
2331
|
+
// src/hooks/use-thread-switcher.tsx
|
|
2332
|
+
var import_react16 = require("react");
|
|
2333
|
+
function useThreadSwitch() {
|
|
2334
|
+
const config = useCopilotChatConfiguration();
|
|
2335
|
+
const switchThread = (0, import_react16.useCallback)(
|
|
2336
|
+
(threadId) => {
|
|
2337
|
+
config?.setThreadId?.(threadId);
|
|
2338
|
+
},
|
|
2339
|
+
[config]
|
|
2340
|
+
);
|
|
2341
|
+
return {
|
|
2342
|
+
switchThread,
|
|
2343
|
+
currentThreadId: config?.threadId
|
|
2344
|
+
};
|
|
2345
|
+
}
|
|
2346
|
+
|
|
2181
2347
|
// src/components/chat/CopilotChatToolCallsView.tsx
|
|
2182
|
-
var
|
|
2348
|
+
var import_react17 = __toESM(require("react"));
|
|
2183
2349
|
var import_jsx_runtime11 = require("react/jsx-runtime");
|
|
2184
2350
|
function CopilotChatToolCallsView({
|
|
2185
2351
|
message,
|
|
@@ -2189,14 +2355,14 @@ function CopilotChatToolCallsView({
|
|
|
2189
2355
|
if (!message.toolCalls || message.toolCalls.length === 0) {
|
|
2190
2356
|
return null;
|
|
2191
2357
|
}
|
|
2192
|
-
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_jsx_runtime11.Fragment, { children: message.toolCalls.map((toolCall) => {
|
|
2358
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_jsx_runtime11.Fragment, { children: message.toolCalls.map((toolCall, index) => {
|
|
2193
2359
|
const toolMessage = messages.find(
|
|
2194
2360
|
(m) => m.role === "tool" && m.toolCallId === toolCall.id
|
|
2195
2361
|
);
|
|
2196
|
-
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
|
|
2362
|
+
return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react17.default.Fragment, { children: renderToolCall({
|
|
2197
2363
|
toolCall,
|
|
2198
2364
|
toolMessage
|
|
2199
|
-
}) }, toolCall.id);
|
|
2365
|
+
}) }, `${message.id}-${toolCall.id ?? index}-${index}`);
|
|
2200
2366
|
}) });
|
|
2201
2367
|
}
|
|
2202
2368
|
var CopilotChatToolCallsView_default = CopilotChatToolCallsView;
|
|
@@ -2371,7 +2537,7 @@ function CopilotChatAssistantMessage({
|
|
|
2371
2537
|
CopilotChatAssistantMessage2.CopyButton = ({ className, title, onClick, ...props }) => {
|
|
2372
2538
|
const config = useCopilotChatConfiguration();
|
|
2373
2539
|
const labels = config?.labels ?? CopilotChatDefaultLabels;
|
|
2374
|
-
const [copied, setCopied] = (0,
|
|
2540
|
+
const [copied, setCopied] = (0, import_react18.useState)(false);
|
|
2375
2541
|
const handleClick = (event) => {
|
|
2376
2542
|
setCopied(true);
|
|
2377
2543
|
setTimeout(() => setCopied(false), 2e3);
|
|
@@ -2449,9 +2615,10 @@ CopilotChatAssistantMessage.RegenerateButton.displayName = "CopilotChatAssistant
|
|
|
2449
2615
|
var CopilotChatAssistantMessage_default = CopilotChatAssistantMessage;
|
|
2450
2616
|
|
|
2451
2617
|
// src/components/chat/CopilotChatUserMessage.tsx
|
|
2452
|
-
var
|
|
2618
|
+
var import_react19 = require("react");
|
|
2453
2619
|
var import_lucide_react4 = require("lucide-react");
|
|
2454
2620
|
var import_tailwind_merge5 = require("tailwind-merge");
|
|
2621
|
+
var import_shared7 = require("@copilotkitnext/shared");
|
|
2455
2622
|
var import_jsx_runtime13 = require("react/jsx-runtime");
|
|
2456
2623
|
function CopilotChatUserMessage({
|
|
2457
2624
|
message,
|
|
@@ -2473,7 +2640,8 @@ function CopilotChatUserMessage({
|
|
|
2473
2640
|
messageRenderer,
|
|
2474
2641
|
CopilotChatUserMessage.MessageRenderer,
|
|
2475
2642
|
{
|
|
2476
|
-
content: message.content
|
|
2643
|
+
content: (0, import_shared7.getUserMessageTextContent)(message.content),
|
|
2644
|
+
contents: (0, import_shared7.normalizeUserMessageContents)(message.content)
|
|
2477
2645
|
}
|
|
2478
2646
|
);
|
|
2479
2647
|
const BoundCopyButton = renderSlot(
|
|
@@ -2481,9 +2649,10 @@ function CopilotChatUserMessage({
|
|
|
2481
2649
|
CopilotChatUserMessage.CopyButton,
|
|
2482
2650
|
{
|
|
2483
2651
|
onClick: async () => {
|
|
2484
|
-
|
|
2652
|
+
const textContent = (0, import_shared7.getUserMessageTextContent)(message.content);
|
|
2653
|
+
if (textContent.trim().length > 0) {
|
|
2485
2654
|
try {
|
|
2486
|
-
await navigator.clipboard.writeText(
|
|
2655
|
+
await navigator.clipboard.writeText(textContent);
|
|
2487
2656
|
} catch (err) {
|
|
2488
2657
|
console.error("Failed to copy message:", err);
|
|
2489
2658
|
}
|
|
@@ -2552,16 +2721,33 @@ function CopilotChatUserMessage({
|
|
|
2552
2721
|
children
|
|
2553
2722
|
}
|
|
2554
2723
|
);
|
|
2555
|
-
CopilotChatUserMessage2.MessageRenderer = ({
|
|
2556
|
-
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
|
|
2560
|
-
|
|
2561
|
-
|
|
2562
|
-
|
|
2563
|
-
|
|
2564
|
-
|
|
2724
|
+
CopilotChatUserMessage2.MessageRenderer = ({
|
|
2725
|
+
content,
|
|
2726
|
+
contents = [],
|
|
2727
|
+
className
|
|
2728
|
+
}) => {
|
|
2729
|
+
const attachments = (0, import_shared7.getUserMessageBinaryContents)(contents);
|
|
2730
|
+
const hasText = content.trim().length > 0;
|
|
2731
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
2732
|
+
"div",
|
|
2733
|
+
{
|
|
2734
|
+
className: (0, import_tailwind_merge5.twMerge)(
|
|
2735
|
+
"prose dark:prose-invert bg-muted relative max-w-[80%] rounded-[18px] px-4 py-1.5 data-[multiline]:py-3 inline-block whitespace-pre-wrap",
|
|
2736
|
+
className
|
|
2737
|
+
),
|
|
2738
|
+
children: [
|
|
2739
|
+
hasText && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { children: content }),
|
|
2740
|
+
attachments.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: (0, import_tailwind_merge5.twMerge)(hasText ? "mt-3 flex flex-col gap-2" : "flex flex-col gap-2"), children: attachments.map((attachment, index) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2741
|
+
AttachmentPreview,
|
|
2742
|
+
{
|
|
2743
|
+
attachment
|
|
2744
|
+
},
|
|
2745
|
+
attachment.id ?? attachment.url ?? attachment.filename ?? index
|
|
2746
|
+
)) })
|
|
2747
|
+
]
|
|
2748
|
+
}
|
|
2749
|
+
);
|
|
2750
|
+
};
|
|
2565
2751
|
CopilotChatUserMessage2.Toolbar = ({
|
|
2566
2752
|
className,
|
|
2567
2753
|
...props
|
|
@@ -2594,7 +2780,7 @@ function CopilotChatUserMessage({
|
|
|
2594
2780
|
CopilotChatUserMessage2.CopyButton = ({ className, title, onClick, ...props }) => {
|
|
2595
2781
|
const config = useCopilotChatConfiguration();
|
|
2596
2782
|
const labels = config?.labels ?? CopilotChatDefaultLabels;
|
|
2597
|
-
const [copied, setCopied] = (0,
|
|
2783
|
+
const [copied, setCopied] = (0, import_react19.useState)(false);
|
|
2598
2784
|
const handleClick = (event) => {
|
|
2599
2785
|
setCopied(true);
|
|
2600
2786
|
setTimeout(() => setCopied(false), 2e3);
|
|
@@ -2678,6 +2864,47 @@ function CopilotChatUserMessage({
|
|
|
2678
2864
|
] });
|
|
2679
2865
|
};
|
|
2680
2866
|
})(CopilotChatUserMessage || (CopilotChatUserMessage = {}));
|
|
2867
|
+
var AttachmentPreview = ({ attachment }) => {
|
|
2868
|
+
const source = resolveAttachmentSource(attachment);
|
|
2869
|
+
const isImage = attachment.mimeType.startsWith("image/");
|
|
2870
|
+
const label = attachment.filename ?? attachment.id ?? attachment.mimeType;
|
|
2871
|
+
if (isImage && source) {
|
|
2872
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("figure", { className: "flex flex-col gap-1", children: [
|
|
2873
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2874
|
+
"img",
|
|
2875
|
+
{
|
|
2876
|
+
src: source,
|
|
2877
|
+
alt: label ?? "User provided image",
|
|
2878
|
+
className: "max-h-64 rounded-lg border border-border object-contain"
|
|
2879
|
+
}
|
|
2880
|
+
),
|
|
2881
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("figcaption", { className: "text-xs text-muted-foreground", children: label ?? "Image attachment" })
|
|
2882
|
+
] });
|
|
2883
|
+
}
|
|
2884
|
+
return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "rounded-md border border-dashed border-border bg-muted/70 px-3 py-2 text-xs text-muted-foreground", children: [
|
|
2885
|
+
label ?? "Attachment",
|
|
2886
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "block text-[10px] uppercase tracking-wide text-muted-foreground/70", children: attachment.mimeType }),
|
|
2887
|
+
source && !isImage ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
2888
|
+
"a",
|
|
2889
|
+
{
|
|
2890
|
+
href: source,
|
|
2891
|
+
target: "_blank",
|
|
2892
|
+
rel: "noreferrer",
|
|
2893
|
+
className: "mt-1 block text-xs text-primary underline",
|
|
2894
|
+
children: "Open"
|
|
2895
|
+
}
|
|
2896
|
+
) : null
|
|
2897
|
+
] });
|
|
2898
|
+
};
|
|
2899
|
+
function resolveAttachmentSource(attachment) {
|
|
2900
|
+
if (attachment.url) {
|
|
2901
|
+
return attachment.url;
|
|
2902
|
+
}
|
|
2903
|
+
if (attachment.data) {
|
|
2904
|
+
return `data:${attachment.mimeType};base64,${attachment.data}`;
|
|
2905
|
+
}
|
|
2906
|
+
return null;
|
|
2907
|
+
}
|
|
2681
2908
|
CopilotChatUserMessage.Container.displayName = "CopilotChatUserMessage.Container";
|
|
2682
2909
|
CopilotChatUserMessage.MessageRenderer.displayName = "CopilotChatUserMessage.MessageRenderer";
|
|
2683
2910
|
CopilotChatUserMessage.Toolbar.displayName = "CopilotChatUserMessage.Toolbar";
|
|
@@ -2688,12 +2915,12 @@ CopilotChatUserMessage.BranchNavigation.displayName = "CopilotChatUserMessage.Br
|
|
|
2688
2915
|
var CopilotChatUserMessage_default = CopilotChatUserMessage;
|
|
2689
2916
|
|
|
2690
2917
|
// src/components/chat/CopilotChatSuggestionPill.tsx
|
|
2691
|
-
var
|
|
2918
|
+
var import_react20 = __toESM(require("react"));
|
|
2692
2919
|
var import_lucide_react5 = require("lucide-react");
|
|
2693
2920
|
var import_jsx_runtime14 = require("react/jsx-runtime");
|
|
2694
2921
|
var baseClasses = "group inline-flex h-7 sm:h-8 items-center gap-1 sm:gap-1.5 rounded-full border border-border/60 bg-background px-2.5 sm:px-3 text-[11px] sm:text-xs leading-none text-foreground transition-colors cursor-pointer hover:bg-accent/60 hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:text-muted-foreground disabled:hover:bg-background disabled:hover:text-muted-foreground pointer-events-auto";
|
|
2695
2922
|
var labelClasses = "whitespace-nowrap font-medium leading-none";
|
|
2696
|
-
var CopilotChatSuggestionPill =
|
|
2923
|
+
var CopilotChatSuggestionPill = import_react20.default.forwardRef(function CopilotChatSuggestionPill2({ className, children, icon, isLoading, type, ...props }, ref) {
|
|
2697
2924
|
const showIcon = !isLoading && icon;
|
|
2698
2925
|
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
|
|
2699
2926
|
"button",
|
|
@@ -2716,9 +2943,9 @@ CopilotChatSuggestionPill.displayName = "CopilotChatSuggestionPill";
|
|
|
2716
2943
|
var CopilotChatSuggestionPill_default = CopilotChatSuggestionPill;
|
|
2717
2944
|
|
|
2718
2945
|
// src/components/chat/CopilotChatSuggestionView.tsx
|
|
2719
|
-
var
|
|
2946
|
+
var import_react21 = __toESM(require("react"));
|
|
2720
2947
|
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
2721
|
-
var DefaultContainer =
|
|
2948
|
+
var DefaultContainer = import_react21.default.forwardRef(function DefaultContainer2({ className, ...props }, ref) {
|
|
2722
2949
|
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
|
|
2723
2950
|
"div",
|
|
2724
2951
|
{
|
|
@@ -2731,7 +2958,7 @@ var DefaultContainer = import_react19.default.forwardRef(function DefaultContain
|
|
|
2731
2958
|
}
|
|
2732
2959
|
);
|
|
2733
2960
|
});
|
|
2734
|
-
var CopilotChatSuggestionView =
|
|
2961
|
+
var CopilotChatSuggestionView = import_react21.default.forwardRef(function CopilotChatSuggestionView2({
|
|
2735
2962
|
suggestions,
|
|
2736
2963
|
onSelectSuggestion,
|
|
2737
2964
|
loadingIndexes,
|
|
@@ -2741,7 +2968,7 @@ var CopilotChatSuggestionView = import_react19.default.forwardRef(function Copil
|
|
|
2741
2968
|
children,
|
|
2742
2969
|
...restProps
|
|
2743
2970
|
}, ref) {
|
|
2744
|
-
const loadingSet =
|
|
2971
|
+
const loadingSet = import_react21.default.useMemo(() => {
|
|
2745
2972
|
if (!loadingIndexes || loadingIndexes.length === 0) {
|
|
2746
2973
|
return /* @__PURE__ */ new Set();
|
|
2747
2974
|
}
|
|
@@ -2760,11 +2987,11 @@ var CopilotChatSuggestionView = import_react19.default.forwardRef(function Copil
|
|
|
2760
2987
|
type: "button",
|
|
2761
2988
|
onClick: () => onSelectSuggestion?.(suggestion, index)
|
|
2762
2989
|
});
|
|
2763
|
-
return
|
|
2990
|
+
return import_react21.default.cloneElement(pill, {
|
|
2764
2991
|
key: `${suggestion.title}-${index}`
|
|
2765
2992
|
});
|
|
2766
2993
|
});
|
|
2767
|
-
const boundContainer =
|
|
2994
|
+
const boundContainer = import_react21.default.cloneElement(
|
|
2768
2995
|
ContainerElement,
|
|
2769
2996
|
void 0,
|
|
2770
2997
|
suggestionElements
|
|
@@ -2867,21 +3094,21 @@ CopilotChatMessageView.Cursor = function Cursor({ className, ...props }) {
|
|
|
2867
3094
|
var CopilotChatMessageView_default = CopilotChatMessageView;
|
|
2868
3095
|
|
|
2869
3096
|
// src/components/chat/CopilotChatView.tsx
|
|
2870
|
-
var
|
|
3097
|
+
var import_react23 = __toESM(require("react"));
|
|
2871
3098
|
var import_tailwind_merge7 = require("tailwind-merge");
|
|
2872
3099
|
var import_use_stick_to_bottom = require("use-stick-to-bottom");
|
|
2873
3100
|
var import_lucide_react6 = require("lucide-react");
|
|
2874
3101
|
|
|
2875
3102
|
// src/hooks/use-keyboard-height.tsx
|
|
2876
|
-
var
|
|
3103
|
+
var import_react22 = require("react");
|
|
2877
3104
|
function useKeyboardHeight() {
|
|
2878
|
-
const [keyboardState, setKeyboardState] = (0,
|
|
3105
|
+
const [keyboardState, setKeyboardState] = (0, import_react22.useState)({
|
|
2879
3106
|
isKeyboardOpen: false,
|
|
2880
3107
|
keyboardHeight: 0,
|
|
2881
3108
|
availableHeight: typeof window !== "undefined" ? window.innerHeight : 0,
|
|
2882
3109
|
viewportHeight: typeof window !== "undefined" ? window.innerHeight : 0
|
|
2883
3110
|
});
|
|
2884
|
-
(0,
|
|
3111
|
+
(0, import_react22.useEffect)(() => {
|
|
2885
3112
|
if (typeof window === "undefined") {
|
|
2886
3113
|
return;
|
|
2887
3114
|
}
|
|
@@ -2925,8 +3152,10 @@ function CopilotChatView({
|
|
|
2925
3152
|
suggestionView,
|
|
2926
3153
|
messages = [],
|
|
2927
3154
|
autoScroll = true,
|
|
3155
|
+
scrollBehavior = "auto",
|
|
2928
3156
|
inputProps,
|
|
2929
3157
|
isRunning = false,
|
|
3158
|
+
isSwitchingThread = false,
|
|
2930
3159
|
suggestions,
|
|
2931
3160
|
suggestionLoadingIndexes,
|
|
2932
3161
|
onSelectSuggestion,
|
|
@@ -2934,12 +3163,12 @@ function CopilotChatView({
|
|
|
2934
3163
|
className,
|
|
2935
3164
|
...props
|
|
2936
3165
|
}) {
|
|
2937
|
-
const inputContainerRef = (0,
|
|
2938
|
-
const [inputContainerHeight, setInputContainerHeight] = (0,
|
|
2939
|
-
const [isResizing, setIsResizing] = (0,
|
|
2940
|
-
const resizeTimeoutRef = (0,
|
|
3166
|
+
const inputContainerRef = (0, import_react23.useRef)(null);
|
|
3167
|
+
const [inputContainerHeight, setInputContainerHeight] = (0, import_react23.useState)(0);
|
|
3168
|
+
const [isResizing, setIsResizing] = (0, import_react23.useState)(false);
|
|
3169
|
+
const resizeTimeoutRef = (0, import_react23.useRef)(null);
|
|
2941
3170
|
const { isKeyboardOpen, keyboardHeight, availableHeight } = useKeyboardHeight();
|
|
2942
|
-
(0,
|
|
3171
|
+
(0, import_react23.useEffect)(() => {
|
|
2943
3172
|
const element = inputContainerRef.current;
|
|
2944
3173
|
if (!element) return;
|
|
2945
3174
|
const resizeObserver = new ResizeObserver((entries) => {
|
|
@@ -2988,6 +3217,8 @@ function CopilotChatView({
|
|
|
2988
3217
|
const BoundFeather = renderSlot(feather, CopilotChatView.Feather, {});
|
|
2989
3218
|
const BoundScrollView = renderSlot(scrollView, CopilotChatView.ScrollView, {
|
|
2990
3219
|
autoScroll,
|
|
3220
|
+
scrollBehavior,
|
|
3221
|
+
isSwitchingThread,
|
|
2991
3222
|
scrollToBottomButton,
|
|
2992
3223
|
inputContainerHeight,
|
|
2993
3224
|
isResizing,
|
|
@@ -3046,19 +3277,21 @@ function CopilotChatView({
|
|
|
3046
3277
|
CopilotChatView2.ScrollView = ({
|
|
3047
3278
|
children,
|
|
3048
3279
|
autoScroll = true,
|
|
3280
|
+
scrollBehavior = "auto",
|
|
3281
|
+
isSwitchingThread = false,
|
|
3049
3282
|
scrollToBottomButton,
|
|
3050
3283
|
inputContainerHeight = 0,
|
|
3051
3284
|
isResizing = false,
|
|
3052
3285
|
className,
|
|
3053
3286
|
...props
|
|
3054
3287
|
}) => {
|
|
3055
|
-
const [hasMounted, setHasMounted] = (0,
|
|
3288
|
+
const [hasMounted, setHasMounted] = (0, import_react23.useState)(false);
|
|
3056
3289
|
const { scrollRef, contentRef, scrollToBottom } = (0, import_use_stick_to_bottom.useStickToBottom)();
|
|
3057
|
-
const [showScrollButton, setShowScrollButton] = (0,
|
|
3058
|
-
(0,
|
|
3290
|
+
const [showScrollButton, setShowScrollButton] = (0, import_react23.useState)(false);
|
|
3291
|
+
(0, import_react23.useEffect)(() => {
|
|
3059
3292
|
setHasMounted(true);
|
|
3060
3293
|
}, []);
|
|
3061
|
-
(0,
|
|
3294
|
+
(0, import_react23.useEffect)(() => {
|
|
3062
3295
|
if (autoScroll) return;
|
|
3063
3296
|
const scrollElement = scrollRef.current;
|
|
3064
3297
|
if (!scrollElement) return;
|
|
@@ -3106,12 +3339,14 @@ function CopilotChatView({
|
|
|
3106
3339
|
}
|
|
3107
3340
|
);
|
|
3108
3341
|
}
|
|
3342
|
+
const initial = scrollBehavior === "auto" ? "instant" : scrollBehavior;
|
|
3343
|
+
const resize = scrollBehavior === "instant" ? "instant" : scrollBehavior === "auto" && isSwitchingThread ? "instant" : "smooth";
|
|
3109
3344
|
return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3110
3345
|
import_use_stick_to_bottom.StickToBottom,
|
|
3111
3346
|
{
|
|
3112
3347
|
className: cn("h-full max-h-full flex flex-col min-h-0 relative", className),
|
|
3113
|
-
resize
|
|
3114
|
-
initial
|
|
3348
|
+
resize,
|
|
3349
|
+
initial,
|
|
3115
3350
|
...props,
|
|
3116
3351
|
children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3117
3352
|
ScrollContent,
|
|
@@ -3158,7 +3393,7 @@ function CopilotChatView({
|
|
|
3158
3393
|
...props
|
|
3159
3394
|
}
|
|
3160
3395
|
);
|
|
3161
|
-
CopilotChatView2.InputContainer =
|
|
3396
|
+
CopilotChatView2.InputContainer = import_react23.default.forwardRef(({ children, className, keyboardHeight = 0, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
|
|
3162
3397
|
"div",
|
|
3163
3398
|
{
|
|
3164
3399
|
ref,
|
|
@@ -3189,20 +3424,95 @@ function CopilotChatView({
|
|
|
3189
3424
|
var CopilotChatView_default = CopilotChatView;
|
|
3190
3425
|
|
|
3191
3426
|
// src/components/chat/CopilotChat.tsx
|
|
3192
|
-
var
|
|
3193
|
-
var
|
|
3427
|
+
var import_shared8 = require("@copilotkitnext/shared");
|
|
3428
|
+
var import_react24 = require("react");
|
|
3194
3429
|
var import_ts_deepmerge = require("ts-deepmerge");
|
|
3195
|
-
var import_client = require("@ag-ui/client");
|
|
3196
3430
|
var import_jsx_runtime18 = require("react/jsx-runtime");
|
|
3197
3431
|
function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen, ...props }) {
|
|
3198
3432
|
const existingConfig = useCopilotChatConfiguration();
|
|
3199
|
-
const
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3433
|
+
const hasOverrideProps = agentId !== void 0 || threadId !== void 0 || labels !== void 0 || isModalDefaultOpen !== void 0;
|
|
3434
|
+
if (!existingConfig || hasOverrideProps) {
|
|
3435
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
3436
|
+
CopilotChatConfigurationProvider,
|
|
3437
|
+
{
|
|
3438
|
+
agentId,
|
|
3439
|
+
threadId,
|
|
3440
|
+
labels,
|
|
3441
|
+
isModalDefaultOpen,
|
|
3442
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(CopilotChat, { chatView, ...props })
|
|
3443
|
+
}
|
|
3444
|
+
);
|
|
3445
|
+
}
|
|
3446
|
+
const resolvedAgentId = agentId ?? existingConfig?.agentId ?? import_shared8.DEFAULT_AGENT_ID;
|
|
3447
|
+
const resolvedThreadId = threadId ?? existingConfig?.threadId;
|
|
3204
3448
|
const { agent } = useAgent({ agentId: resolvedAgentId });
|
|
3205
3449
|
const { copilotkit } = useCopilotKit();
|
|
3450
|
+
const [isSwitchingThread, setIsSwitchingThread] = (0, import_react24.useState)(false);
|
|
3451
|
+
const [threadSwitchError, setThreadSwitchError] = (0, import_react24.useState)(null);
|
|
3452
|
+
const previousThreadIdRef = (0, import_react24.useRef)(void 0);
|
|
3453
|
+
const abortControllerRef = (0, import_react24.useRef)(null);
|
|
3454
|
+
(0, import_react24.useEffect)(() => {
|
|
3455
|
+
if (!agent || !resolvedThreadId) return;
|
|
3456
|
+
if (previousThreadIdRef.current === resolvedThreadId) return;
|
|
3457
|
+
if (abortControllerRef.current) {
|
|
3458
|
+
abortControllerRef.current.abort();
|
|
3459
|
+
}
|
|
3460
|
+
const abortController = new AbortController();
|
|
3461
|
+
abortControllerRef.current = abortController;
|
|
3462
|
+
const switchThread = async () => {
|
|
3463
|
+
setIsSwitchingThread(true);
|
|
3464
|
+
setThreadSwitchError(null);
|
|
3465
|
+
try {
|
|
3466
|
+
if (abortController.signal.aborted) return;
|
|
3467
|
+
if (previousThreadIdRef.current) {
|
|
3468
|
+
try {
|
|
3469
|
+
await copilotkit.disconnectAgent({ agent });
|
|
3470
|
+
} catch (disconnectErr) {
|
|
3471
|
+
console.warn("Error during disconnect, continuing with thread switch:", disconnectErr);
|
|
3472
|
+
}
|
|
3473
|
+
}
|
|
3474
|
+
if (abortController.signal.aborted) {
|
|
3475
|
+
previousThreadIdRef.current = void 0;
|
|
3476
|
+
return;
|
|
3477
|
+
}
|
|
3478
|
+
agent.messages = [];
|
|
3479
|
+
const subscribers = agent.subscribers || [];
|
|
3480
|
+
subscribers.forEach((subscriber) => {
|
|
3481
|
+
if (subscriber.onMessagesChanged) {
|
|
3482
|
+
subscriber.onMessagesChanged({
|
|
3483
|
+
messages: agent.messages,
|
|
3484
|
+
state: agent.state,
|
|
3485
|
+
agent
|
|
3486
|
+
});
|
|
3487
|
+
}
|
|
3488
|
+
});
|
|
3489
|
+
if (abortController.signal.aborted) {
|
|
3490
|
+
previousThreadIdRef.current = void 0;
|
|
3491
|
+
return;
|
|
3492
|
+
}
|
|
3493
|
+
await copilotkit.connectAgent({ agent, threadId: resolvedThreadId });
|
|
3494
|
+
if (!abortController.signal.aborted) {
|
|
3495
|
+
previousThreadIdRef.current = resolvedThreadId;
|
|
3496
|
+
}
|
|
3497
|
+
} catch (err) {
|
|
3498
|
+
if (abortController.signal.aborted) {
|
|
3499
|
+
previousThreadIdRef.current = void 0;
|
|
3500
|
+
return;
|
|
3501
|
+
}
|
|
3502
|
+
const error = err instanceof Error ? err : new Error(String(err));
|
|
3503
|
+
setThreadSwitchError(error);
|
|
3504
|
+
console.error("Failed to switch thread:", error);
|
|
3505
|
+
} finally {
|
|
3506
|
+
if (!abortController.signal.aborted) {
|
|
3507
|
+
setIsSwitchingThread(false);
|
|
3508
|
+
}
|
|
3509
|
+
}
|
|
3510
|
+
};
|
|
3511
|
+
void switchThread();
|
|
3512
|
+
return () => {
|
|
3513
|
+
abortController.abort();
|
|
3514
|
+
};
|
|
3515
|
+
}, [agent, resolvedThreadId, copilotkit]);
|
|
3206
3516
|
const { suggestions: autoSuggestions } = useSuggestions({ agentId: resolvedAgentId });
|
|
3207
3517
|
const {
|
|
3208
3518
|
inputProps: providedInputProps,
|
|
@@ -3210,28 +3520,10 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
|
|
|
3210
3520
|
suggestionView: providedSuggestionView,
|
|
3211
3521
|
...restProps
|
|
3212
3522
|
} = props;
|
|
3213
|
-
(0,
|
|
3214
|
-
const connect = async (agent2) => {
|
|
3215
|
-
try {
|
|
3216
|
-
await copilotkit.connectAgent({ agent: agent2 });
|
|
3217
|
-
} catch (error) {
|
|
3218
|
-
if (error instanceof import_client.AGUIConnectNotImplementedError) {
|
|
3219
|
-
} else {
|
|
3220
|
-
throw error;
|
|
3221
|
-
}
|
|
3222
|
-
}
|
|
3223
|
-
};
|
|
3224
|
-
if (agent) {
|
|
3225
|
-
agent.threadId = resolvedThreadId;
|
|
3226
|
-
connect(agent);
|
|
3227
|
-
}
|
|
3228
|
-
return () => {
|
|
3229
|
-
};
|
|
3230
|
-
}, [resolvedThreadId, agent, copilotkit, resolvedAgentId]);
|
|
3231
|
-
const onSubmitInput = (0, import_react22.useCallback)(
|
|
3523
|
+
const onSubmitInput = (0, import_react24.useCallback)(
|
|
3232
3524
|
async (value) => {
|
|
3233
3525
|
agent?.addMessage({
|
|
3234
|
-
id: (0,
|
|
3526
|
+
id: (0, import_shared8.randomUUID)(),
|
|
3235
3527
|
role: "user",
|
|
3236
3528
|
content: value
|
|
3237
3529
|
});
|
|
@@ -3245,13 +3537,13 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
|
|
|
3245
3537
|
},
|
|
3246
3538
|
[agent, copilotkit]
|
|
3247
3539
|
);
|
|
3248
|
-
const handleSelectSuggestion = (0,
|
|
3540
|
+
const handleSelectSuggestion = (0, import_react24.useCallback)(
|
|
3249
3541
|
async (suggestion) => {
|
|
3250
3542
|
if (!agent) {
|
|
3251
3543
|
return;
|
|
3252
3544
|
}
|
|
3253
3545
|
agent.addMessage({
|
|
3254
|
-
id: (0,
|
|
3546
|
+
id: (0, import_shared8.randomUUID)(),
|
|
3255
3547
|
role: "user",
|
|
3256
3548
|
content: suggestion.message
|
|
3257
3549
|
});
|
|
@@ -3263,7 +3555,7 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
|
|
|
3263
3555
|
},
|
|
3264
3556
|
[agent, copilotkit]
|
|
3265
3557
|
);
|
|
3266
|
-
const stopCurrentRun = (0,
|
|
3558
|
+
const stopCurrentRun = (0, import_react24.useCallback)(() => {
|
|
3267
3559
|
if (!agent) {
|
|
3268
3560
|
return;
|
|
3269
3561
|
}
|
|
@@ -3305,24 +3597,27 @@ function CopilotChat({ agentId, threadId, labels, chatView, isModalDefaultOpen,
|
|
|
3305
3597
|
messages: agent?.messages ?? [],
|
|
3306
3598
|
inputProps: finalInputProps
|
|
3307
3599
|
});
|
|
3308
|
-
const
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3600
|
+
const inputPropsWithThreadState = {
|
|
3601
|
+
...finalProps.inputProps ?? {},
|
|
3602
|
+
mode: isSwitchingThread ? "processing" : finalProps.inputProps?.mode
|
|
3603
|
+
};
|
|
3604
|
+
const finalPropsWithThreadState = {
|
|
3605
|
+
...finalProps,
|
|
3606
|
+
isRunning: (finalProps.isRunning ?? false) || isSwitchingThread,
|
|
3607
|
+
inputProps: inputPropsWithThreadState,
|
|
3608
|
+
// Pass thread switching state to control scroll behavior
|
|
3609
|
+
isSwitchingThread,
|
|
3610
|
+
"data-thread-switching": isSwitchingThread ? "true" : void 0,
|
|
3611
|
+
"data-thread-switch-error": threadSwitchError ? threadSwitchError.message : void 0
|
|
3612
|
+
};
|
|
3613
|
+
return renderSlot(chatView, CopilotChatView, finalPropsWithThreadState);
|
|
3319
3614
|
}
|
|
3320
3615
|
((CopilotChat2) => {
|
|
3321
3616
|
CopilotChat2.View = CopilotChatView;
|
|
3322
3617
|
})(CopilotChat || (CopilotChat = {}));
|
|
3323
3618
|
|
|
3324
3619
|
// src/components/chat/CopilotChatToggleButton.tsx
|
|
3325
|
-
var
|
|
3620
|
+
var import_react25 = __toESM(require("react"));
|
|
3326
3621
|
var import_lucide_react7 = require("lucide-react");
|
|
3327
3622
|
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
3328
3623
|
var DefaultOpenIcon = ({
|
|
@@ -3349,11 +3644,11 @@ var BUTTON_BASE_CLASSES = cn(
|
|
|
3349
3644
|
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/50 focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
3350
3645
|
"disabled:pointer-events-none disabled:opacity-60"
|
|
3351
3646
|
);
|
|
3352
|
-
var CopilotChatToggleButton =
|
|
3647
|
+
var CopilotChatToggleButton = import_react25.default.forwardRef(function CopilotChatToggleButton2({ openIcon, closeIcon, className, ...buttonProps }, ref) {
|
|
3353
3648
|
const { onClick, type, disabled, ...restProps } = buttonProps;
|
|
3354
3649
|
const configuration = useCopilotChatConfiguration();
|
|
3355
3650
|
const labels = configuration?.labels ?? CopilotChatDefaultLabels;
|
|
3356
|
-
const [fallbackOpen, setFallbackOpen] = (0,
|
|
3651
|
+
const [fallbackOpen, setFallbackOpen] = (0, import_react25.useState)(false);
|
|
3357
3652
|
const isOpen = configuration?.isModalOpen ?? fallbackOpen;
|
|
3358
3653
|
const setModalOpen = configuration?.setModalOpen ?? setFallbackOpen;
|
|
3359
3654
|
const handleClick = (event) => {
|
|
@@ -3439,16 +3734,21 @@ CopilotChatToggleButton.displayName = "CopilotChatToggleButton";
|
|
|
3439
3734
|
var CopilotChatToggleButton_default = CopilotChatToggleButton;
|
|
3440
3735
|
|
|
3441
3736
|
// src/components/chat/CopilotSidebarView.tsx
|
|
3442
|
-
var
|
|
3737
|
+
var import_react28 = require("react");
|
|
3443
3738
|
|
|
3444
3739
|
// src/components/chat/CopilotModalHeader.tsx
|
|
3445
|
-
var
|
|
3740
|
+
var import_react26 = require("react");
|
|
3446
3741
|
var import_lucide_react8 = require("lucide-react");
|
|
3447
3742
|
var import_jsx_runtime20 = require("react/jsx-runtime");
|
|
3448
3743
|
function CopilotModalHeader({
|
|
3449
3744
|
title,
|
|
3450
3745
|
titleContent,
|
|
3451
3746
|
closeButton,
|
|
3747
|
+
leftContent,
|
|
3748
|
+
onThreadListClick,
|
|
3749
|
+
showThreadListButton = false,
|
|
3750
|
+
onNewThreadClick,
|
|
3751
|
+
showNewThreadButton = false,
|
|
3452
3752
|
children,
|
|
3453
3753
|
className,
|
|
3454
3754
|
...rest
|
|
@@ -3456,7 +3756,7 @@ function CopilotModalHeader({
|
|
|
3456
3756
|
const configuration = useCopilotChatConfiguration();
|
|
3457
3757
|
const fallbackTitle = configuration?.labels.modalHeaderTitle ?? CopilotChatDefaultLabels.modalHeaderTitle;
|
|
3458
3758
|
const resolvedTitle = title ?? fallbackTitle;
|
|
3459
|
-
const handleClose = (0,
|
|
3759
|
+
const handleClose = (0, import_react26.useCallback)(() => {
|
|
3460
3760
|
configuration?.setModalOpen(false);
|
|
3461
3761
|
}, [configuration]);
|
|
3462
3762
|
const BoundTitle = renderSlot(titleContent, CopilotModalHeader.Title, {
|
|
@@ -3465,10 +3765,17 @@ function CopilotModalHeader({
|
|
|
3465
3765
|
const BoundCloseButton = renderSlot(closeButton, CopilotModalHeader.CloseButton, {
|
|
3466
3766
|
onClick: handleClose
|
|
3467
3767
|
});
|
|
3768
|
+
const BoundLeftContent = renderSlot(leftContent, CopilotModalHeader.LeftContent, {
|
|
3769
|
+
onThreadListClick,
|
|
3770
|
+
showThreadListButton,
|
|
3771
|
+
onNewThreadClick,
|
|
3772
|
+
showNewThreadButton
|
|
3773
|
+
});
|
|
3468
3774
|
if (children) {
|
|
3469
3775
|
return children({
|
|
3470
3776
|
titleContent: BoundTitle,
|
|
3471
3777
|
closeButton: BoundCloseButton,
|
|
3778
|
+
leftContent: BoundLeftContent,
|
|
3472
3779
|
title: resolvedTitle,
|
|
3473
3780
|
...rest
|
|
3474
3781
|
});
|
|
@@ -3484,7 +3791,7 @@ function CopilotModalHeader({
|
|
|
3484
3791
|
),
|
|
3485
3792
|
...rest,
|
|
3486
3793
|
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex w-full items-center gap-2", children: [
|
|
3487
|
-
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex-1",
|
|
3794
|
+
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex flex-1 justify-start", children: BoundLeftContent }),
|
|
3488
3795
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex flex-1 justify-center text-center", children: BoundTitle }),
|
|
3489
3796
|
/* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex flex-1 justify-end", children: BoundCloseButton })
|
|
3490
3797
|
] })
|
|
@@ -3521,19 +3828,281 @@ CopilotModalHeader.displayName = "CopilotModalHeader";
|
|
|
3521
3828
|
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.X, { className: "h-4 w-4", "aria-hidden": "true" })
|
|
3522
3829
|
}
|
|
3523
3830
|
);
|
|
3831
|
+
CopilotModalHeader2.LeftContent = ({
|
|
3832
|
+
onThreadListClick,
|
|
3833
|
+
showThreadListButton,
|
|
3834
|
+
onNewThreadClick,
|
|
3835
|
+
showNewThreadButton,
|
|
3836
|
+
className,
|
|
3837
|
+
children
|
|
3838
|
+
}) => {
|
|
3839
|
+
if (children) {
|
|
3840
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className, children });
|
|
3841
|
+
}
|
|
3842
|
+
const hasAnyButton = showNewThreadButton && onNewThreadClick || showThreadListButton && onThreadListClick;
|
|
3843
|
+
if (!hasAnyButton) {
|
|
3844
|
+
return null;
|
|
3845
|
+
}
|
|
3846
|
+
return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: cn("flex items-center gap-1", className), children: [
|
|
3847
|
+
showNewThreadButton && onNewThreadClick && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3848
|
+
"button",
|
|
3849
|
+
{
|
|
3850
|
+
type: "button",
|
|
3851
|
+
onClick: onNewThreadClick,
|
|
3852
|
+
className: cn(
|
|
3853
|
+
"inline-flex size-8 items-center justify-center rounded-full text-muted-foreground transition cursor-pointer",
|
|
3854
|
+
"hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
3855
|
+
),
|
|
3856
|
+
"aria-label": "New thread",
|
|
3857
|
+
title: "New thread",
|
|
3858
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.SquarePen, { className: "h-4 w-4", "aria-hidden": "true" })
|
|
3859
|
+
}
|
|
3860
|
+
),
|
|
3861
|
+
showThreadListButton && onThreadListClick && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
|
|
3862
|
+
"button",
|
|
3863
|
+
{
|
|
3864
|
+
type: "button",
|
|
3865
|
+
onClick: onThreadListClick,
|
|
3866
|
+
className: cn(
|
|
3867
|
+
"inline-flex size-8 items-center justify-center rounded-full text-muted-foreground transition cursor-pointer",
|
|
3868
|
+
"hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
|
3869
|
+
),
|
|
3870
|
+
"aria-label": "Show threads",
|
|
3871
|
+
title: "Show threads",
|
|
3872
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_lucide_react8.List, { className: "h-4 w-4", "aria-hidden": "true" })
|
|
3873
|
+
}
|
|
3874
|
+
)
|
|
3875
|
+
] });
|
|
3876
|
+
};
|
|
3524
3877
|
})(CopilotModalHeader || (CopilotModalHeader = {}));
|
|
3525
3878
|
CopilotModalHeader.Title.displayName = "CopilotModalHeader.Title";
|
|
3526
3879
|
CopilotModalHeader.CloseButton.displayName = "CopilotModalHeader.CloseButton";
|
|
3880
|
+
CopilotModalHeader.LeftContent.displayName = "CopilotModalHeader.LeftContent";
|
|
3527
3881
|
|
|
3528
|
-
// src/components/
|
|
3882
|
+
// src/components/threads/CopilotThreadList.tsx
|
|
3883
|
+
var import_react27 = require("react");
|
|
3884
|
+
var import_lucide_react9 = require("lucide-react");
|
|
3885
|
+
var import_shared9 = require("@copilotkitnext/shared");
|
|
3529
3886
|
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
3887
|
+
function CopilotThreadListInner({
|
|
3888
|
+
limit = 50,
|
|
3889
|
+
onThreadSelect,
|
|
3890
|
+
className,
|
|
3891
|
+
threadItem,
|
|
3892
|
+
newThreadButton,
|
|
3893
|
+
container,
|
|
3894
|
+
refreshInterval = 2e3,
|
|
3895
|
+
disableAutoRefresh = false
|
|
3896
|
+
}) {
|
|
3897
|
+
const config = useCopilotChatConfiguration();
|
|
3898
|
+
const { threads, isLoading, error, fetchThreads, addOptimisticThread, refresh, currentThreadId, deleteThread } = useThreads({
|
|
3899
|
+
limit
|
|
3900
|
+
});
|
|
3901
|
+
const attemptedFetchRef = (0, import_react27.useRef)(/* @__PURE__ */ new Set());
|
|
3902
|
+
const handleNewThread = (0, import_react27.useCallback)(() => {
|
|
3903
|
+
const newThreadId = (0, import_shared9.randomUUID)();
|
|
3904
|
+
addOptimisticThread(newThreadId);
|
|
3905
|
+
config?.setThreadId?.(newThreadId);
|
|
3906
|
+
onThreadSelect?.(newThreadId);
|
|
3907
|
+
}, [addOptimisticThread, config, onThreadSelect]);
|
|
3908
|
+
const handleThreadSelect = (0, import_react27.useCallback)(
|
|
3909
|
+
(threadId) => {
|
|
3910
|
+
config?.setThreadId?.(threadId);
|
|
3911
|
+
onThreadSelect?.(threadId);
|
|
3912
|
+
},
|
|
3913
|
+
[config, onThreadSelect]
|
|
3914
|
+
);
|
|
3915
|
+
const handleDeleteThread = (0, import_react27.useCallback)(
|
|
3916
|
+
async (threadId) => {
|
|
3917
|
+
try {
|
|
3918
|
+
await deleteThread(threadId);
|
|
3919
|
+
if (threadId === (currentThreadId ?? config?.threadId)) {
|
|
3920
|
+
const newThreadId = (0, import_shared9.randomUUID)();
|
|
3921
|
+
addOptimisticThread(newThreadId);
|
|
3922
|
+
config?.setThreadId?.(newThreadId);
|
|
3923
|
+
}
|
|
3924
|
+
} catch (err) {
|
|
3925
|
+
console.error("Failed to delete thread:", err);
|
|
3926
|
+
}
|
|
3927
|
+
},
|
|
3928
|
+
[deleteThread, currentThreadId, config, addOptimisticThread]
|
|
3929
|
+
);
|
|
3930
|
+
(0, import_react27.useEffect)(() => {
|
|
3931
|
+
const activeId = currentThreadId ?? config?.threadId;
|
|
3932
|
+
if (!activeId) return;
|
|
3933
|
+
const isCurrentThreadInList = threads.some((t) => t.threadId === activeId);
|
|
3934
|
+
if (isCurrentThreadInList) {
|
|
3935
|
+
attemptedFetchRef.current.delete(activeId);
|
|
3936
|
+
return;
|
|
3937
|
+
}
|
|
3938
|
+
if (!isLoading && !attemptedFetchRef.current.has(activeId)) {
|
|
3939
|
+
attemptedFetchRef.current.add(activeId);
|
|
3940
|
+
refresh();
|
|
3941
|
+
}
|
|
3942
|
+
}, [currentThreadId, config?.threadId, threads, refresh, isLoading]);
|
|
3943
|
+
(0, import_react27.useEffect)(() => {
|
|
3944
|
+
if (disableAutoRefresh) return;
|
|
3945
|
+
const hasRunningThread = threads.some((t) => t.isRunning);
|
|
3946
|
+
const hasUnnamedThread = threads.some((t) => !t.firstMessage);
|
|
3947
|
+
if (!hasRunningThread && !hasUnnamedThread) return;
|
|
3948
|
+
const interval = setInterval(() => {
|
|
3949
|
+
refresh();
|
|
3950
|
+
}, refreshInterval);
|
|
3951
|
+
return () => clearInterval(interval);
|
|
3952
|
+
}, [threads, refresh, refreshInterval, disableAutoRefresh]);
|
|
3953
|
+
const BoundNewThreadButton = renderSlot(newThreadButton, NewThreadButton, {
|
|
3954
|
+
onClick: handleNewThread
|
|
3955
|
+
});
|
|
3956
|
+
const activeThreadId = currentThreadId ?? config?.threadId;
|
|
3957
|
+
const threadItems = threads.map((thread) => {
|
|
3958
|
+
const isActive = thread.threadId === activeThreadId;
|
|
3959
|
+
return renderSlot(threadItem, ThreadListItem, {
|
|
3960
|
+
key: thread.threadId,
|
|
3961
|
+
thread,
|
|
3962
|
+
isActive,
|
|
3963
|
+
onClick: () => handleThreadSelect(thread.threadId),
|
|
3964
|
+
onDelete: () => handleDeleteThread(thread.threadId)
|
|
3965
|
+
});
|
|
3966
|
+
});
|
|
3967
|
+
const content = /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
|
|
3968
|
+
BoundNewThreadButton,
|
|
3969
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "space-y-1", children: error ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "copilotkit-thread-list-error mx-4 my-3 rounded-md border border-destructive/30 bg-destructive/5 p-4 text-sm text-destructive", children: [
|
|
3970
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("p", { className: "mb-3 font-medium", children: [
|
|
3971
|
+
"Failed to load threads: ",
|
|
3972
|
+
error.message
|
|
3973
|
+
] }),
|
|
3974
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
3975
|
+
"button",
|
|
3976
|
+
{
|
|
3977
|
+
type: "button",
|
|
3978
|
+
className: "rounded bg-destructive px-3 py-1.5 text-xs font-medium text-destructive-foreground transition hover:bg-destructive/90",
|
|
3979
|
+
onClick: () => fetchThreads(),
|
|
3980
|
+
children: "Retry"
|
|
3981
|
+
}
|
|
3982
|
+
)
|
|
3983
|
+
] }) : isLoading && threads.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "p-4 text-center text-sm text-muted-foreground", children: "Loading threads..." }) : threads.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "p-4 text-center text-sm text-muted-foreground", children: "No threads yet" }) : threadItems })
|
|
3984
|
+
] });
|
|
3985
|
+
return renderSlot(container, Container, {
|
|
3986
|
+
className,
|
|
3987
|
+
children: content
|
|
3988
|
+
});
|
|
3989
|
+
}
|
|
3990
|
+
var Container = ({ className, children, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: cn("flex flex-col h-full", className), ...props, children });
|
|
3991
|
+
var NewThreadButton = ({ className, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
3992
|
+
"button",
|
|
3993
|
+
{
|
|
3994
|
+
className: cn(
|
|
3995
|
+
"w-full flex items-center gap-3 px-4 py-3 text-sm font-medium",
|
|
3996
|
+
"border-b border-border",
|
|
3997
|
+
"hover:bg-accent/50 transition-colors",
|
|
3998
|
+
"text-foreground",
|
|
3999
|
+
className
|
|
4000
|
+
),
|
|
4001
|
+
...props,
|
|
4002
|
+
children: [
|
|
4003
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Plus, { className: "w-4 h-4" }),
|
|
4004
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { children: "New Conversation" })
|
|
4005
|
+
]
|
|
4006
|
+
}
|
|
4007
|
+
);
|
|
4008
|
+
var ThreadListItem = ({ thread, isActive, onClick, onDelete }) => {
|
|
4009
|
+
const displayText = thread.firstMessage?.substring(0, 60) || "New conversation";
|
|
4010
|
+
const hasEllipsis = thread.firstMessage && thread.firstMessage.length > 60;
|
|
4011
|
+
const messageCount = thread.messageCount || 0;
|
|
4012
|
+
const [isDeleting, setIsDeleting] = (0, import_react27.useState)(false);
|
|
4013
|
+
const handleDelete = (0, import_react27.useCallback)(
|
|
4014
|
+
async (e) => {
|
|
4015
|
+
e.stopPropagation();
|
|
4016
|
+
if (!onDelete) return;
|
|
4017
|
+
setIsDeleting(true);
|
|
4018
|
+
try {
|
|
4019
|
+
await onDelete();
|
|
4020
|
+
} catch (err) {
|
|
4021
|
+
console.error("Delete failed:", err);
|
|
4022
|
+
setIsDeleting(false);
|
|
4023
|
+
}
|
|
4024
|
+
},
|
|
4025
|
+
[onDelete]
|
|
4026
|
+
);
|
|
4027
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
|
|
4028
|
+
"div",
|
|
4029
|
+
{
|
|
4030
|
+
className: cn(
|
|
4031
|
+
"w-full flex items-start gap-3 px-4 py-3 group relative",
|
|
4032
|
+
"hover:bg-accent/50 transition-colors",
|
|
4033
|
+
"border-b border-border",
|
|
4034
|
+
isActive && "bg-accent border-l-2 border-l-primary",
|
|
4035
|
+
isDeleting && "opacity-50 pointer-events-none"
|
|
4036
|
+
),
|
|
4037
|
+
children: [
|
|
4038
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("button", { onClick, className: "flex items-start gap-3 flex-1 min-w-0 text-left", children: [
|
|
4039
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.MessageSquare, { className: "w-4 h-4 mt-0.5 flex-shrink-0 text-muted-foreground" }),
|
|
4040
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex-1 min-w-0", children: [
|
|
4041
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("p", { className: "text-sm text-foreground truncate", children: [
|
|
4042
|
+
displayText,
|
|
4043
|
+
hasEllipsis && "..."
|
|
4044
|
+
] }),
|
|
4045
|
+
messageCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("p", { className: "text-xs text-muted-foreground mt-1", children: [
|
|
4046
|
+
messageCount,
|
|
4047
|
+
" messages"
|
|
4048
|
+
] })
|
|
4049
|
+
] })
|
|
4050
|
+
] }),
|
|
4051
|
+
onDelete && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
|
|
4052
|
+
"button",
|
|
4053
|
+
{
|
|
4054
|
+
type: "button",
|
|
4055
|
+
onClick: handleDelete,
|
|
4056
|
+
disabled: isDeleting,
|
|
4057
|
+
className: cn(
|
|
4058
|
+
"p-1.5 rounded transition-all",
|
|
4059
|
+
"text-muted-foreground hover:text-destructive hover:bg-destructive/10",
|
|
4060
|
+
"opacity-0 group-hover:opacity-100",
|
|
4061
|
+
"focus:opacity-100 focus:outline-none focus:ring-2 focus:ring-destructive/20",
|
|
4062
|
+
isDeleting && "animate-pulse"
|
|
4063
|
+
),
|
|
4064
|
+
"aria-label": "Delete thread",
|
|
4065
|
+
title: "Delete thread",
|
|
4066
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_lucide_react9.Trash2, { className: "w-4 h-4" })
|
|
4067
|
+
}
|
|
4068
|
+
)
|
|
4069
|
+
]
|
|
4070
|
+
}
|
|
4071
|
+
);
|
|
4072
|
+
};
|
|
4073
|
+
function CopilotThreadList(props) {
|
|
4074
|
+
const existingConfig = useCopilotChatConfiguration();
|
|
4075
|
+
if (!existingConfig) {
|
|
4076
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CopilotChatConfigurationProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CopilotThreadListInner, { ...props }) });
|
|
4077
|
+
}
|
|
4078
|
+
return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CopilotThreadListInner, { ...props });
|
|
4079
|
+
}
|
|
4080
|
+
CopilotThreadList.displayName = "CopilotThreadList";
|
|
4081
|
+
CopilotThreadList.ThreadItem = ThreadListItem;
|
|
4082
|
+
CopilotThreadList.NewThreadButton = NewThreadButton;
|
|
4083
|
+
CopilotThreadList.Container = Container;
|
|
4084
|
+
|
|
4085
|
+
// src/components/chat/CopilotSidebarView.tsx
|
|
4086
|
+
var import_shared10 = require("@copilotkitnext/shared");
|
|
4087
|
+
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
3530
4088
|
var DEFAULT_SIDEBAR_WIDTH = 480;
|
|
3531
4089
|
var SIDEBAR_TRANSITION_MS = 260;
|
|
3532
|
-
function CopilotSidebarView({ header, width, ...props }) {
|
|
4090
|
+
function CopilotSidebarView({ header, width, showThreadListButton = false, showNewThreadButton = false, ...props }) {
|
|
3533
4091
|
const configuration = useCopilotChatConfiguration();
|
|
3534
4092
|
const isSidebarOpen = configuration?.isModalOpen ?? false;
|
|
3535
|
-
const
|
|
3536
|
-
const
|
|
4093
|
+
const [isThreadListOpen, setIsThreadListOpen] = (0, import_react28.useState)(false);
|
|
4094
|
+
const sidebarRef = (0, import_react28.useRef)(null);
|
|
4095
|
+
const [sidebarWidth, setSidebarWidth] = (0, import_react28.useState)(width ?? DEFAULT_SIDEBAR_WIDTH);
|
|
4096
|
+
const handleThreadListToggle = (0, import_react28.useCallback)(() => {
|
|
4097
|
+
setIsThreadListOpen((prev) => !prev);
|
|
4098
|
+
}, []);
|
|
4099
|
+
const handleThreadSelect = (0, import_react28.useCallback)(() => {
|
|
4100
|
+
setIsThreadListOpen(false);
|
|
4101
|
+
}, []);
|
|
4102
|
+
const handleNewThread = (0, import_react28.useCallback)(() => {
|
|
4103
|
+
const newThreadId = (0, import_shared10.randomUUID)();
|
|
4104
|
+
configuration?.setThreadId?.(newThreadId);
|
|
4105
|
+
}, [configuration]);
|
|
3537
4106
|
const widthToCss = (w) => {
|
|
3538
4107
|
return typeof w === "number" ? `${w}px` : w;
|
|
3539
4108
|
};
|
|
@@ -3543,7 +4112,7 @@ function CopilotSidebarView({ header, width, ...props }) {
|
|
|
3543
4112
|
}
|
|
3544
4113
|
return w;
|
|
3545
4114
|
};
|
|
3546
|
-
(0,
|
|
4115
|
+
(0, import_react28.useEffect)(() => {
|
|
3547
4116
|
if (width !== void 0) {
|
|
3548
4117
|
return;
|
|
3549
4118
|
}
|
|
@@ -3569,9 +4138,14 @@ function CopilotSidebarView({ header, width, ...props }) {
|
|
|
3569
4138
|
window.addEventListener("resize", updateWidth);
|
|
3570
4139
|
return () => window.removeEventListener("resize", updateWidth);
|
|
3571
4140
|
}, [width]);
|
|
3572
|
-
const headerElement = renderSlot(header, CopilotModalHeader, {
|
|
3573
|
-
|
|
3574
|
-
|
|
4141
|
+
const headerElement = renderSlot(header, CopilotModalHeader, {
|
|
4142
|
+
onThreadListClick: handleThreadListToggle,
|
|
4143
|
+
showThreadListButton,
|
|
4144
|
+
onNewThreadClick: handleNewThread,
|
|
4145
|
+
showNewThreadButton
|
|
4146
|
+
});
|
|
4147
|
+
return /* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
|
|
4148
|
+
isSidebarOpen && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
3575
4149
|
"style",
|
|
3576
4150
|
{
|
|
3577
4151
|
dangerouslySetInnerHTML: {
|
|
@@ -3585,8 +4159,8 @@ function CopilotSidebarView({ header, width, ...props }) {
|
|
|
3585
4159
|
}
|
|
3586
4160
|
}
|
|
3587
4161
|
),
|
|
3588
|
-
/* @__PURE__ */ (0,
|
|
3589
|
-
/* @__PURE__ */ (0,
|
|
4162
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CopilotChatToggleButton_default, {}),
|
|
4163
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)(
|
|
3590
4164
|
"aside",
|
|
3591
4165
|
{
|
|
3592
4166
|
ref: sidebarRef,
|
|
@@ -3599,6 +4173,8 @@ function CopilotSidebarView({ header, width, ...props }) {
|
|
|
3599
4173
|
"w-full",
|
|
3600
4174
|
"border-l border-border bg-background text-foreground shadow-xl",
|
|
3601
4175
|
"transition-transform duration-300 ease-out",
|
|
4176
|
+
"overflow-hidden",
|
|
4177
|
+
// Clip the sliding panel
|
|
3602
4178
|
isSidebarOpen ? "translate-x-0" : "translate-x-full pointer-events-none"
|
|
3603
4179
|
),
|
|
3604
4180
|
style: {
|
|
@@ -3611,10 +4187,31 @@ function CopilotSidebarView({ header, width, ...props }) {
|
|
|
3611
4187
|
"aria-hidden": !isSidebarOpen,
|
|
3612
4188
|
"aria-label": "Copilot chat sidebar",
|
|
3613
4189
|
role: "complementary",
|
|
3614
|
-
children:
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
4190
|
+
children: [
|
|
4191
|
+
isThreadListOpen && /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4192
|
+
"div",
|
|
4193
|
+
{
|
|
4194
|
+
className: "absolute inset-0 z-50",
|
|
4195
|
+
onClick: handleThreadListToggle,
|
|
4196
|
+
"aria-hidden": "true"
|
|
4197
|
+
}
|
|
4198
|
+
),
|
|
4199
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
|
|
4200
|
+
"div",
|
|
4201
|
+
{
|
|
4202
|
+
className: cn(
|
|
4203
|
+
"absolute left-0 top-0 h-full w-80 bg-background border-r border-border z-[60]",
|
|
4204
|
+
"transition-transform duration-300 ease-out",
|
|
4205
|
+
isThreadListOpen ? "translate-x-0" : "-translate-x-full"
|
|
4206
|
+
),
|
|
4207
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CopilotThreadList, { onThreadSelect: handleThreadSelect })
|
|
4208
|
+
}
|
|
4209
|
+
),
|
|
4210
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsxs)("div", { className: "flex h-full w-full flex-col overflow-hidden", children: [
|
|
4211
|
+
headerElement,
|
|
4212
|
+
/* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { className: "flex-1 overflow-hidden", "data-sidebar-chat": true, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CopilotChatView_default, { ...props }) })
|
|
4213
|
+
] })
|
|
4214
|
+
]
|
|
3618
4215
|
}
|
|
3619
4216
|
)
|
|
3620
4217
|
] });
|
|
@@ -3622,8 +4219,9 @@ function CopilotSidebarView({ header, width, ...props }) {
|
|
|
3622
4219
|
CopilotSidebarView.displayName = "CopilotSidebarView";
|
|
3623
4220
|
|
|
3624
4221
|
// src/components/chat/CopilotPopupView.tsx
|
|
3625
|
-
var
|
|
3626
|
-
var
|
|
4222
|
+
var import_react29 = require("react");
|
|
4223
|
+
var import_shared11 = require("@copilotkitnext/shared");
|
|
4224
|
+
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
3627
4225
|
var DEFAULT_POPUP_WIDTH = 420;
|
|
3628
4226
|
var DEFAULT_POPUP_HEIGHT = 560;
|
|
3629
4227
|
var dimensionToCss = (value, fallback) => {
|
|
@@ -3640,6 +4238,8 @@ function CopilotPopupView({
|
|
|
3640
4238
|
width,
|
|
3641
4239
|
height,
|
|
3642
4240
|
clickOutsideToClose,
|
|
4241
|
+
showThreadListButton = false,
|
|
4242
|
+
showNewThreadButton = false,
|
|
3643
4243
|
className,
|
|
3644
4244
|
...restProps
|
|
3645
4245
|
}) {
|
|
@@ -3647,10 +4247,21 @@ function CopilotPopupView({
|
|
|
3647
4247
|
const isPopupOpen = configuration?.isModalOpen ?? false;
|
|
3648
4248
|
const setModalOpen = configuration?.setModalOpen;
|
|
3649
4249
|
const labels = configuration?.labels ?? CopilotChatDefaultLabels;
|
|
3650
|
-
const containerRef = (0,
|
|
3651
|
-
const [isRendered, setIsRendered] = (0,
|
|
3652
|
-
const [isAnimatingOut, setIsAnimatingOut] = (0,
|
|
3653
|
-
(0,
|
|
4250
|
+
const containerRef = (0, import_react29.useRef)(null);
|
|
4251
|
+
const [isRendered, setIsRendered] = (0, import_react29.useState)(isPopupOpen);
|
|
4252
|
+
const [isAnimatingOut, setIsAnimatingOut] = (0, import_react29.useState)(false);
|
|
4253
|
+
const [isThreadListOpen, setIsThreadListOpen] = (0, import_react29.useState)(false);
|
|
4254
|
+
const handleThreadListToggle = (0, import_react29.useCallback)(() => {
|
|
4255
|
+
setIsThreadListOpen((prev) => !prev);
|
|
4256
|
+
}, []);
|
|
4257
|
+
const handleThreadSelect = (0, import_react29.useCallback)(() => {
|
|
4258
|
+
setIsThreadListOpen(false);
|
|
4259
|
+
}, []);
|
|
4260
|
+
const handleNewThread = (0, import_react29.useCallback)(() => {
|
|
4261
|
+
const newThreadId = (0, import_shared11.randomUUID)();
|
|
4262
|
+
configuration?.setThreadId?.(newThreadId);
|
|
4263
|
+
}, [configuration]);
|
|
4264
|
+
(0, import_react29.useEffect)(() => {
|
|
3654
4265
|
if (isPopupOpen) {
|
|
3655
4266
|
setIsRendered(true);
|
|
3656
4267
|
setIsAnimatingOut(false);
|
|
@@ -3666,7 +4277,7 @@ function CopilotPopupView({
|
|
|
3666
4277
|
}, 200);
|
|
3667
4278
|
return () => clearTimeout(timeout);
|
|
3668
4279
|
}, [isPopupOpen, isRendered]);
|
|
3669
|
-
(0,
|
|
4280
|
+
(0, import_react29.useEffect)(() => {
|
|
3670
4281
|
if (!isPopupOpen) {
|
|
3671
4282
|
return;
|
|
3672
4283
|
}
|
|
@@ -3682,7 +4293,7 @@ function CopilotPopupView({
|
|
|
3682
4293
|
window.addEventListener("keydown", handleKeyDown);
|
|
3683
4294
|
return () => window.removeEventListener("keydown", handleKeyDown);
|
|
3684
4295
|
}, [isPopupOpen, setModalOpen]);
|
|
3685
|
-
(0,
|
|
4296
|
+
(0, import_react29.useEffect)(() => {
|
|
3686
4297
|
if (!isPopupOpen) {
|
|
3687
4298
|
return;
|
|
3688
4299
|
}
|
|
@@ -3691,7 +4302,7 @@ function CopilotPopupView({
|
|
|
3691
4302
|
}, 200);
|
|
3692
4303
|
return () => clearTimeout(focusTimer);
|
|
3693
4304
|
}, [isPopupOpen]);
|
|
3694
|
-
(0,
|
|
4305
|
+
(0, import_react29.useEffect)(() => {
|
|
3695
4306
|
if (!isPopupOpen || !clickOutsideToClose) {
|
|
3696
4307
|
return;
|
|
3697
4308
|
}
|
|
@@ -3716,10 +4327,15 @@ function CopilotPopupView({
|
|
|
3716
4327
|
document.addEventListener("pointerdown", handlePointerDown);
|
|
3717
4328
|
return () => document.removeEventListener("pointerdown", handlePointerDown);
|
|
3718
4329
|
}, [isPopupOpen, clickOutsideToClose, setModalOpen]);
|
|
3719
|
-
const headerElement = (0,
|
|
4330
|
+
const headerElement = (0, import_react29.useMemo)(() => renderSlot(header, CopilotModalHeader, {
|
|
4331
|
+
onThreadListClick: handleThreadListToggle,
|
|
4332
|
+
showThreadListButton,
|
|
4333
|
+
onNewThreadClick: handleNewThread,
|
|
4334
|
+
showNewThreadButton
|
|
4335
|
+
}), [header, handleThreadListToggle, showThreadListButton, handleNewThread, showNewThreadButton]);
|
|
3720
4336
|
const resolvedWidth = dimensionToCss(width, DEFAULT_POPUP_WIDTH);
|
|
3721
4337
|
const resolvedHeight = dimensionToCss(height, DEFAULT_POPUP_HEIGHT);
|
|
3722
|
-
const popupStyle = (0,
|
|
4338
|
+
const popupStyle = (0, import_react29.useMemo)(
|
|
3723
4339
|
() => ({
|
|
3724
4340
|
"--copilot-popup-width": resolvedWidth,
|
|
3725
4341
|
"--copilot-popup-height": resolvedHeight,
|
|
@@ -3733,14 +4349,14 @@ function CopilotPopupView({
|
|
|
3733
4349
|
[resolvedHeight, resolvedWidth]
|
|
3734
4350
|
);
|
|
3735
4351
|
const popupAnimationClass = isPopupOpen && !isAnimatingOut ? "pointer-events-auto translate-y-0 opacity-100 md:scale-100" : "pointer-events-none translate-y-4 opacity-0 md:translate-y-5 md:scale-[0.95]";
|
|
3736
|
-
const popupContent = isRendered ? /* @__PURE__ */ (0,
|
|
4352
|
+
const popupContent = isRendered ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3737
4353
|
"div",
|
|
3738
4354
|
{
|
|
3739
4355
|
className: cn(
|
|
3740
4356
|
"fixed inset-0 z-[1200] flex max-w-full flex-col items-stretch",
|
|
3741
4357
|
"md:inset-auto md:bottom-24 md:right-6 md:items-end md:gap-4"
|
|
3742
4358
|
),
|
|
3743
|
-
children: /* @__PURE__ */ (0,
|
|
4359
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
|
|
3744
4360
|
"div",
|
|
3745
4361
|
{
|
|
3746
4362
|
ref: containerRef,
|
|
@@ -3749,19 +4365,40 @@ function CopilotPopupView({
|
|
|
3749
4365
|
"aria-label": labels.modalHeaderTitle,
|
|
3750
4366
|
"data-copilot-popup": true,
|
|
3751
4367
|
className: cn(
|
|
3752
|
-
"relative flex h-full w-full flex-col
|
|
4368
|
+
"relative flex h-full w-full flex-col bg-background text-foreground",
|
|
3753
4369
|
"origin-bottom focus:outline-none transform-gpu transition-transform transition-opacity duration-200 ease-out",
|
|
3754
4370
|
"md:transition-transform md:transition-opacity",
|
|
3755
4371
|
"rounded-none border border-border/0 shadow-none ring-0",
|
|
3756
4372
|
"md:h-[var(--copilot-popup-height)] md:w-[var(--copilot-popup-width)]",
|
|
3757
4373
|
"md:max-h-[var(--copilot-popup-max-height)] md:max-w-[var(--copilot-popup-max-width)]",
|
|
3758
4374
|
"md:origin-bottom-right md:rounded-2xl md:border-border md:shadow-xl md:ring-1 md:ring-border/40",
|
|
4375
|
+
"overflow-hidden",
|
|
4376
|
+
// Clip the sliding panel
|
|
3759
4377
|
popupAnimationClass
|
|
3760
4378
|
),
|
|
3761
4379
|
style: popupStyle,
|
|
3762
4380
|
children: [
|
|
4381
|
+
isThreadListOpen && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4382
|
+
"div",
|
|
4383
|
+
{
|
|
4384
|
+
className: "absolute inset-0 z-50",
|
|
4385
|
+
onClick: handleThreadListToggle,
|
|
4386
|
+
"aria-hidden": "true"
|
|
4387
|
+
}
|
|
4388
|
+
),
|
|
4389
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4390
|
+
"div",
|
|
4391
|
+
{
|
|
4392
|
+
className: cn(
|
|
4393
|
+
"absolute left-0 top-0 h-full w-80 bg-background border-r border-border z-[60]",
|
|
4394
|
+
"transition-transform duration-300 ease-out",
|
|
4395
|
+
isThreadListOpen ? "translate-x-0" : "-translate-x-full"
|
|
4396
|
+
),
|
|
4397
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CopilotThreadList, { onThreadSelect: handleThreadSelect })
|
|
4398
|
+
}
|
|
4399
|
+
),
|
|
3763
4400
|
headerElement,
|
|
3764
|
-
/* @__PURE__ */ (0,
|
|
4401
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "flex-1 overflow-hidden", "data-popup-chat": true, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
3765
4402
|
CopilotChatView_default,
|
|
3766
4403
|
{
|
|
3767
4404
|
...restProps,
|
|
@@ -3773,32 +4410,34 @@ function CopilotPopupView({
|
|
|
3773
4410
|
)
|
|
3774
4411
|
}
|
|
3775
4412
|
) : null;
|
|
3776
|
-
return /* @__PURE__ */ (0,
|
|
3777
|
-
/* @__PURE__ */ (0,
|
|
4413
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
|
|
4414
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)(CopilotChatToggleButton_default, {}),
|
|
3778
4415
|
popupContent
|
|
3779
4416
|
] });
|
|
3780
4417
|
}
|
|
3781
4418
|
CopilotPopupView.displayName = "CopilotPopupView";
|
|
3782
4419
|
|
|
3783
4420
|
// src/components/chat/CopilotSidebar.tsx
|
|
3784
|
-
var
|
|
3785
|
-
var
|
|
3786
|
-
function CopilotSidebar({ header, defaultOpen, width, ...chatProps }) {
|
|
3787
|
-
const SidebarViewOverride = (0,
|
|
4421
|
+
var import_react30 = require("react");
|
|
4422
|
+
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
4423
|
+
function CopilotSidebar({ header, defaultOpen, width, showThreadListButton, showNewThreadButton, ...chatProps }) {
|
|
4424
|
+
const SidebarViewOverride = (0, import_react30.useMemo)(() => {
|
|
3788
4425
|
const Component = (viewProps) => {
|
|
3789
|
-
const { header: viewHeader, width: viewWidth, ...restProps } = viewProps;
|
|
3790
|
-
return /* @__PURE__ */ (0,
|
|
4426
|
+
const { header: viewHeader, width: viewWidth, showThreadListButton: viewShowThreadList, showNewThreadButton: viewShowNewThread, ...restProps } = viewProps;
|
|
4427
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
3791
4428
|
CopilotSidebarView,
|
|
3792
4429
|
{
|
|
3793
4430
|
...restProps,
|
|
3794
4431
|
header: header ?? viewHeader,
|
|
3795
|
-
width: width ?? viewWidth
|
|
4432
|
+
width: width ?? viewWidth,
|
|
4433
|
+
showThreadListButton: showThreadListButton ?? viewShowThreadList,
|
|
4434
|
+
showNewThreadButton: showNewThreadButton ?? viewShowNewThread
|
|
3796
4435
|
}
|
|
3797
4436
|
);
|
|
3798
4437
|
};
|
|
3799
4438
|
return Object.assign(Component, CopilotChatView_default);
|
|
3800
|
-
}, [header, width]);
|
|
3801
|
-
return /* @__PURE__ */ (0,
|
|
4439
|
+
}, [header, width, showThreadListButton, showNewThreadButton]);
|
|
4440
|
+
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
3802
4441
|
CopilotChat,
|
|
3803
4442
|
{
|
|
3804
4443
|
...chatProps,
|
|
@@ -3810,39 +4449,45 @@ function CopilotSidebar({ header, defaultOpen, width, ...chatProps }) {
|
|
|
3810
4449
|
CopilotSidebar.displayName = "CopilotSidebar";
|
|
3811
4450
|
|
|
3812
4451
|
// src/components/chat/CopilotPopup.tsx
|
|
3813
|
-
var
|
|
3814
|
-
var
|
|
4452
|
+
var import_react31 = require("react");
|
|
4453
|
+
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
3815
4454
|
function CopilotPopup({
|
|
3816
4455
|
header,
|
|
3817
4456
|
defaultOpen,
|
|
3818
4457
|
width,
|
|
3819
4458
|
height,
|
|
3820
4459
|
clickOutsideToClose,
|
|
4460
|
+
showThreadListButton,
|
|
4461
|
+
showNewThreadButton,
|
|
3821
4462
|
...chatProps
|
|
3822
4463
|
}) {
|
|
3823
|
-
const PopupViewOverride = (0,
|
|
4464
|
+
const PopupViewOverride = (0, import_react31.useMemo)(() => {
|
|
3824
4465
|
const Component = (viewProps) => {
|
|
3825
4466
|
const {
|
|
3826
4467
|
header: viewHeader,
|
|
3827
4468
|
width: viewWidth,
|
|
3828
4469
|
height: viewHeight,
|
|
3829
4470
|
clickOutsideToClose: viewClickOutsideToClose,
|
|
4471
|
+
showThreadListButton: viewShowThreadList,
|
|
4472
|
+
showNewThreadButton: viewShowNewThread,
|
|
3830
4473
|
...restProps
|
|
3831
4474
|
} = viewProps;
|
|
3832
|
-
return /* @__PURE__ */ (0,
|
|
4475
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
3833
4476
|
CopilotPopupView,
|
|
3834
4477
|
{
|
|
3835
4478
|
...restProps,
|
|
3836
4479
|
header: header ?? viewHeader,
|
|
3837
4480
|
width: width ?? viewWidth,
|
|
3838
4481
|
height: height ?? viewHeight,
|
|
3839
|
-
clickOutsideToClose: clickOutsideToClose ?? viewClickOutsideToClose
|
|
4482
|
+
clickOutsideToClose: clickOutsideToClose ?? viewClickOutsideToClose,
|
|
4483
|
+
showThreadListButton: showThreadListButton ?? viewShowThreadList,
|
|
4484
|
+
showNewThreadButton: showNewThreadButton ?? viewShowNewThread
|
|
3840
4485
|
}
|
|
3841
4486
|
);
|
|
3842
4487
|
};
|
|
3843
4488
|
return Object.assign(Component, CopilotChatView_default);
|
|
3844
|
-
}, [clickOutsideToClose, header, height, width]);
|
|
3845
|
-
return /* @__PURE__ */ (0,
|
|
4489
|
+
}, [clickOutsideToClose, header, height, width, showThreadListButton, showNewThreadButton]);
|
|
4490
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
3846
4491
|
CopilotChat,
|
|
3847
4492
|
{
|
|
3848
4493
|
...chatProps,
|
|
@@ -3866,25 +4511,25 @@ function defineToolCallRenderer(def) {
|
|
|
3866
4511
|
}
|
|
3867
4512
|
|
|
3868
4513
|
// src/components/WildcardToolCallRender.tsx
|
|
3869
|
-
var
|
|
3870
|
-
var
|
|
4514
|
+
var import_react32 = require("react");
|
|
4515
|
+
var import_jsx_runtime26 = require("react/jsx-runtime");
|
|
3871
4516
|
var WildcardToolCallRender = defineToolCallRenderer({
|
|
3872
4517
|
name: "*",
|
|
3873
4518
|
render: ({ args, result, name, status }) => {
|
|
3874
|
-
const [isExpanded, setIsExpanded] = (0,
|
|
4519
|
+
const [isExpanded, setIsExpanded] = (0, import_react32.useState)(false);
|
|
3875
4520
|
const statusString = String(status);
|
|
3876
4521
|
const isActive = statusString === "inProgress" || statusString === "executing";
|
|
3877
4522
|
const isComplete = statusString === "complete";
|
|
3878
4523
|
const statusStyles = isActive ? "bg-amber-100 text-amber-800 dark:bg-amber-500/15 dark:text-amber-400" : isComplete ? "bg-emerald-100 text-emerald-800 dark:bg-emerald-500/15 dark:text-emerald-400" : "bg-zinc-100 text-zinc-800 dark:bg-zinc-700/40 dark:text-zinc-300";
|
|
3879
|
-
return /* @__PURE__ */ (0,
|
|
3880
|
-
/* @__PURE__ */ (0,
|
|
4524
|
+
return /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "mt-2 pb-2", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "rounded-xl border border-zinc-200/60 dark:border-zinc-800/60 bg-white/70 dark:bg-zinc-900/50 shadow-sm backdrop-blur p-4", children: [
|
|
4525
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
3881
4526
|
"div",
|
|
3882
4527
|
{
|
|
3883
4528
|
className: "flex items-center justify-between gap-3 cursor-pointer",
|
|
3884
4529
|
onClick: () => setIsExpanded(!isExpanded),
|
|
3885
4530
|
children: [
|
|
3886
|
-
/* @__PURE__ */ (0,
|
|
3887
|
-
/* @__PURE__ */ (0,
|
|
4531
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "flex items-center gap-2 min-w-0", children: [
|
|
4532
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3888
4533
|
"svg",
|
|
3889
4534
|
{
|
|
3890
4535
|
className: `h-4 w-4 text-zinc-500 dark:text-zinc-400 transition-transform ${isExpanded ? "rotate-90" : ""}`,
|
|
@@ -3892,7 +4537,7 @@ var WildcardToolCallRender = defineToolCallRenderer({
|
|
|
3892
4537
|
viewBox: "0 0 24 24",
|
|
3893
4538
|
strokeWidth: 2,
|
|
3894
4539
|
stroke: "currentColor",
|
|
3895
|
-
children: /* @__PURE__ */ (0,
|
|
4540
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3896
4541
|
"path",
|
|
3897
4542
|
{
|
|
3898
4543
|
strokeLinecap: "round",
|
|
@@ -3902,10 +4547,10 @@ var WildcardToolCallRender = defineToolCallRenderer({
|
|
|
3902
4547
|
)
|
|
3903
4548
|
}
|
|
3904
4549
|
),
|
|
3905
|
-
/* @__PURE__ */ (0,
|
|
3906
|
-
/* @__PURE__ */ (0,
|
|
4550
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "inline-block h-2 w-2 rounded-full bg-blue-500" }),
|
|
4551
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "truncate text-sm font-medium text-zinc-900 dark:text-zinc-100", children: name })
|
|
3907
4552
|
] }),
|
|
3908
|
-
/* @__PURE__ */ (0,
|
|
4553
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
3909
4554
|
"span",
|
|
3910
4555
|
{
|
|
3911
4556
|
className: `inline-flex items-center rounded-full px-2 py-1 text-xs font-medium ${statusStyles}`,
|
|
@@ -3915,14 +4560,14 @@ var WildcardToolCallRender = defineToolCallRenderer({
|
|
|
3915
4560
|
]
|
|
3916
4561
|
}
|
|
3917
4562
|
),
|
|
3918
|
-
isExpanded && /* @__PURE__ */ (0,
|
|
3919
|
-
/* @__PURE__ */ (0,
|
|
3920
|
-
/* @__PURE__ */ (0,
|
|
3921
|
-
/* @__PURE__ */ (0,
|
|
4563
|
+
isExpanded && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { className: "mt-3 grid gap-4", children: [
|
|
4564
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { children: [
|
|
4565
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "text-xs uppercase tracking-wide text-zinc-500 dark:text-zinc-400", children: "Arguments" }),
|
|
4566
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("pre", { className: "mt-2 max-h-64 overflow-auto rounded-md bg-zinc-50 dark:bg-zinc-800/60 p-3 text-xs leading-relaxed text-zinc-800 dark:text-zinc-200 whitespace-pre-wrap break-words", children: JSON.stringify(args ?? {}, null, 2) })
|
|
3922
4567
|
] }),
|
|
3923
|
-
result !== void 0 && /* @__PURE__ */ (0,
|
|
3924
|
-
/* @__PURE__ */ (0,
|
|
3925
|
-
/* @__PURE__ */ (0,
|
|
4568
|
+
result !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("div", { children: [
|
|
4569
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "text-xs uppercase tracking-wide text-zinc-500 dark:text-zinc-400", children: "Result" }),
|
|
4570
|
+
/* @__PURE__ */ (0, import_jsx_runtime26.jsx)("pre", { className: "mt-2 max-h-64 overflow-auto rounded-md bg-zinc-50 dark:bg-zinc-800/60 p-3 text-xs leading-relaxed text-zinc-800 dark:text-zinc-200 whitespace-pre-wrap break-words", children: typeof result === "string" ? result : JSON.stringify(result, null, 2) })
|
|
3926
4571
|
] })
|
|
3927
4572
|
] })
|
|
3928
4573
|
] }) });
|
|
@@ -3953,6 +4598,7 @@ var WildcardToolCallRender = defineToolCallRenderer({
|
|
|
3953
4598
|
CopilotPopupView,
|
|
3954
4599
|
CopilotSidebar,
|
|
3955
4600
|
CopilotSidebarView,
|
|
4601
|
+
CopilotThreadList,
|
|
3956
4602
|
WildcardToolCallRender,
|
|
3957
4603
|
defineToolCallRenderer,
|
|
3958
4604
|
useAgent,
|
|
@@ -3964,6 +4610,8 @@ var WildcardToolCallRender = defineToolCallRenderer({
|
|
|
3964
4610
|
useHumanInTheLoop,
|
|
3965
4611
|
useRenderCustomMessages,
|
|
3966
4612
|
useRenderToolCall,
|
|
3967
|
-
useSuggestions
|
|
4613
|
+
useSuggestions,
|
|
4614
|
+
useThreadSwitch,
|
|
4615
|
+
useThreads
|
|
3968
4616
|
});
|
|
3969
4617
|
//# sourceMappingURL=index.js.map
|