@copilotkitnext/react 0.0.18 → 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.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 resolvedThreadId = (0, import_react.useMemo)(() => {
115
- if (threadId) {
116
- return threadId;
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
- }, [threadId, parentConfig?.threadId]);
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
- `[data-slash-index="${slashHighlightIndex}"]`
1096
- );
1097
- active?.scrollIntoView({ block: "nearest" });
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({ behavior: "smooth", block: "nearest" });
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 import_react16 = require("react");
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 import_web_inspector = require("@copilotkitnext/web-inspector");
1454
+ var WebInspectorModule = __toESM(require("@copilotkitnext/web-inspector"));
1449
1455
  var import_jsx_runtime7 = require("react/jsx-runtime");
1450
- (0, import_web_inspector.defineWebInspector)();
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: import_web_inspector.WEB_INSPECTOR_TAG,
1453
- elementClass: import_web_inspector.WebInspectorElement,
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.min(messagesIdsInRun.indexOf(message.id), 0);
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
- const Component = renderer.render;
1790
- result = /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1791
- Component,
1792
- {
1793
- message,
1794
- position,
1795
- runId,
1796
- messageIndex,
1797
- messageIndexInRun,
1798
- numberOfMessagesInRun,
1799
- agentId,
1800
- stateSnapshot
1801
- },
1802
- `${runId}-${message.id}-${position}`
1803
- );
1804
- if (result) {
1805
- break;
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 import_react15 = __toESM(require("react"));
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)(import_react15.default.Fragment, { children: renderToolCall({
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, import_react16.useState)(false);
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 import_react17 = require("react");
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
- if (message.content) {
2652
+ const textContent = (0, import_shared7.getUserMessageTextContent)(message.content);
2653
+ if (textContent.trim().length > 0) {
2485
2654
  try {
2486
- await navigator.clipboard.writeText(message.content);
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 = ({ content, className }) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2556
- "div",
2557
- {
2558
- className: (0, import_tailwind_merge5.twMerge)(
2559
- "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",
2560
- className
2561
- ),
2562
- children: content
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, import_react17.useState)(false);
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 import_react18 = __toESM(require("react"));
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 = import_react18.default.forwardRef(function CopilotChatSuggestionPill2({ className, children, icon, isLoading, type, ...props }, ref) {
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 import_react19 = __toESM(require("react"));
2946
+ var import_react21 = __toESM(require("react"));
2720
2947
  var import_jsx_runtime15 = require("react/jsx-runtime");
2721
- var DefaultContainer = import_react19.default.forwardRef(function DefaultContainer2({ className, ...props }, ref) {
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 = import_react19.default.forwardRef(function CopilotChatSuggestionView2({
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 = import_react19.default.useMemo(() => {
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 import_react19.default.cloneElement(pill, {
2990
+ return import_react21.default.cloneElement(pill, {
2764
2991
  key: `${suggestion.title}-${index}`
2765
2992
  });
2766
2993
  });
2767
- const boundContainer = import_react19.default.cloneElement(
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 import_react21 = __toESM(require("react"));
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 import_react20 = require("react");
3103
+ var import_react22 = require("react");
2877
3104
  function useKeyboardHeight() {
2878
- const [keyboardState, setKeyboardState] = (0, import_react20.useState)({
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, import_react20.useEffect)(() => {
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, import_react21.useRef)(null);
2938
- const [inputContainerHeight, setInputContainerHeight] = (0, import_react21.useState)(0);
2939
- const [isResizing, setIsResizing] = (0, import_react21.useState)(false);
2940
- const resizeTimeoutRef = (0, import_react21.useRef)(null);
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, import_react21.useEffect)(() => {
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, import_react21.useState)(false);
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, import_react21.useState)(false);
3058
- (0, import_react21.useEffect)(() => {
3290
+ const [showScrollButton, setShowScrollButton] = (0, import_react23.useState)(false);
3291
+ (0, import_react23.useEffect)(() => {
3059
3292
  setHasMounted(true);
3060
3293
  }, []);
3061
- (0, import_react21.useEffect)(() => {
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: "smooth",
3114
- initial: "smooth",
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 = import_react21.default.forwardRef(({ children, className, keyboardHeight = 0, ...props }, ref) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
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 import_shared7 = require("@copilotkitnext/shared");
3193
- var import_react22 = require("react");
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 resolvedAgentId = agentId ?? existingConfig?.agentId ?? import_shared7.DEFAULT_AGENT_ID;
3200
- const resolvedThreadId = (0, import_react22.useMemo)(
3201
- () => threadId ?? existingConfig?.threadId ?? (0, import_shared7.randomUUID)(),
3202
- [threadId, existingConfig?.threadId]
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, import_react22.useEffect)(() => {
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, import_shared7.randomUUID)(),
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, import_react22.useCallback)(
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, import_shared7.randomUUID)(),
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, import_react22.useCallback)(() => {
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 RenderedChatView = renderSlot(chatView, CopilotChatView, finalProps);
3309
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3310
- CopilotChatConfigurationProvider,
3311
- {
3312
- agentId: resolvedAgentId,
3313
- threadId: resolvedThreadId,
3314
- labels,
3315
- isModalDefaultOpen,
3316
- children: RenderedChatView
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 import_react23 = __toESM(require("react"));
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 = import_react23.default.forwardRef(function CopilotChatToggleButton2({ openIcon, closeIcon, className, ...buttonProps }, ref) {
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, import_react23.useState)(false);
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 import_react25 = require("react");
3737
+ var import_react28 = require("react");
3443
3738
 
3444
3739
  // src/components/chat/CopilotModalHeader.tsx
3445
- var import_react24 = require("react");
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, import_react24.useCallback)(() => {
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", "aria-hidden": "true" }),
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/chat/CopilotSidebarView.tsx
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 sidebarRef = (0, import_react25.useRef)(null);
3536
- const [sidebarWidth, setSidebarWidth] = (0, import_react25.useState)(width ?? DEFAULT_SIDEBAR_WIDTH);
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, import_react25.useEffect)(() => {
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
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
3574
- isSidebarOpen && /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
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, import_jsx_runtime21.jsx)(CopilotChatToggleButton_default, {}),
3589
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
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: /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("div", { className: "flex h-full w-full flex-col overflow-hidden", children: [
3615
- headerElement,
3616
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("div", { className: "flex-1 overflow-hidden", "data-sidebar-chat": true, children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CopilotChatView_default, { ...props }) })
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 import_react26 = require("react");
3626
- var import_jsx_runtime22 = require("react/jsx-runtime");
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, import_react26.useRef)(null);
3651
- const [isRendered, setIsRendered] = (0, import_react26.useState)(isPopupOpen);
3652
- const [isAnimatingOut, setIsAnimatingOut] = (0, import_react26.useState)(false);
3653
- (0, import_react26.useEffect)(() => {
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, import_react26.useEffect)(() => {
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, import_react26.useEffect)(() => {
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, import_react26.useEffect)(() => {
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, import_react26.useMemo)(() => renderSlot(header, CopilotModalHeader, {}), [header]);
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, import_react26.useMemo)(
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, import_jsx_runtime22.jsx)(
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, import_jsx_runtime22.jsxs)(
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 overflow-hidden bg-background text-foreground",
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, import_jsx_runtime22.jsx)("div", { className: "flex-1 overflow-hidden", "data-popup-chat": true, children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(
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, import_jsx_runtime22.jsxs)(import_jsx_runtime22.Fragment, { children: [
3777
- /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(CopilotChatToggleButton_default, {}),
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 import_react27 = require("react");
3785
- var import_jsx_runtime23 = require("react/jsx-runtime");
3786
- function CopilotSidebar({ header, defaultOpen, width, ...chatProps }) {
3787
- const SidebarViewOverride = (0, import_react27.useMemo)(() => {
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, import_jsx_runtime23.jsx)(
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, import_jsx_runtime23.jsx)(
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 import_react28 = require("react");
3814
- var import_jsx_runtime24 = require("react/jsx-runtime");
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, import_react28.useMemo)(() => {
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, import_jsx_runtime24.jsx)(
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, import_jsx_runtime24.jsx)(
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 import_react29 = require("react");
3870
- var import_jsx_runtime25 = require("react/jsx-runtime");
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, import_react29.useState)(false);
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, import_jsx_runtime25.jsx)("div", { className: "mt-2 pb-2", children: /* @__PURE__ */ (0, import_jsx_runtime25.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: [
3880
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
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, import_jsx_runtime25.jsxs)("div", { className: "flex items-center gap-2 min-w-0", children: [
3887
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
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, import_jsx_runtime25.jsx)(
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, import_jsx_runtime25.jsx)("span", { className: "inline-block h-2 w-2 rounded-full bg-blue-500" }),
3906
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "truncate text-sm font-medium text-zinc-900 dark:text-zinc-100", children: name })
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, import_jsx_runtime25.jsx)(
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, import_jsx_runtime25.jsxs)("div", { className: "mt-3 grid gap-4", children: [
3919
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { children: [
3920
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "text-xs uppercase tracking-wide text-zinc-500 dark:text-zinc-400", children: "Arguments" }),
3921
- /* @__PURE__ */ (0, import_jsx_runtime25.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) })
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, import_jsx_runtime25.jsxs)("div", { children: [
3924
- /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "text-xs uppercase tracking-wide text-zinc-500 dark:text-zinc-400", children: "Result" }),
3925
- /* @__PURE__ */ (0, import_jsx_runtime25.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) })
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