@copilotkit/react-core 1.56.4-canary.1777659843 → 1.56.5-canary.1777664617

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.
Files changed (31) hide show
  1. package/dist/{copilotkit-DHEUlli6.mjs → copilotkit-CPe2-340.mjs} +165 -91
  2. package/dist/copilotkit-CPe2-340.mjs.map +1 -0
  3. package/dist/copilotkit-DFaI4j2r.d.mts.map +1 -1
  4. package/dist/{copilotkit-Bn7CCpNA.cjs → copilotkit-DGbvw8n2.cjs} +165 -91
  5. package/dist/copilotkit-DGbvw8n2.cjs.map +1 -0
  6. package/dist/copilotkit-Dg4r4Gi_.d.cts.map +1 -1
  7. package/dist/index.cjs +1 -1
  8. package/dist/index.mjs +1 -1
  9. package/dist/index.umd.js +24 -0
  10. package/dist/index.umd.js.map +1 -1
  11. package/dist/v2/index.cjs +1 -1
  12. package/dist/v2/index.css +1 -1
  13. package/dist/v2/index.mjs +1 -1
  14. package/dist/v2/index.umd.js +167 -93
  15. package/dist/v2/index.umd.js.map +1 -1
  16. package/package.json +8 -8
  17. package/src/v2/components/chat/CopilotChatAttachmentQueue.tsx +3 -113
  18. package/src/v2/components/chat/CopilotChatAttachmentRenderer.tsx +26 -6
  19. package/src/v2/components/chat/CopilotChatUserMessage.tsx +2 -2
  20. package/src/v2/components/chat/CopilotChatView.tsx +30 -6
  21. package/src/v2/components/chat/Lightbox.tsx +103 -0
  22. package/src/v2/components/chat/__tests__/CopilotChat.suggestionsAlways.test.tsx +183 -0
  23. package/src/v2/components/chat/__tests__/CopilotChatView.inputOverlay.test.tsx +92 -0
  24. package/src/v2/components/chat/__tests__/CopilotChatView.pinToSend.test.tsx +13 -23
  25. package/src/v2/hooks/__tests__/use-pin-to-send.test.tsx +53 -48
  26. package/src/v2/hooks/__tests__/use-threads.test.tsx +229 -27
  27. package/src/v2/hooks/use-configure-suggestions.tsx +50 -1
  28. package/src/v2/hooks/use-pin-to-send.ts +32 -23
  29. package/src/v2/hooks/use-threads.tsx +7 -1
  30. package/dist/copilotkit-Bn7CCpNA.cjs.map +0 -1
  31. package/dist/copilotkit-DHEUlli6.mjs.map +0 -1
@@ -16,8 +16,8 @@ import { z } from "zod";
16
16
  import { createComponent } from "@lit-labs/react";
17
17
  import { A2UIProvider, A2UIRenderer, A2UI_SCHEMA_CONTEXT_DESCRIPTION, DEFAULT_SURFACE_ID, buildCatalogContextValue, extractCatalogComponentSchemas, initializeDefaultCatalog, injectStyles, useA2UIActions, useA2UIError, viewerTheme } from "@copilotkit/a2ui-renderer";
18
18
  import { zodToJsonSchema } from "zod-to-json-schema";
19
- import { useVirtualizer } from "@tanstack/react-virtual";
20
19
  import { createPortal, flushSync } from "react-dom";
20
+ import { useVirtualizer } from "@tanstack/react-virtual";
21
21
  import { StickToBottom, useStickToBottomContext } from "use-stick-to-bottom";
22
22
  import ReactMarkdown from "react-markdown";
23
23
 
@@ -4302,15 +4302,19 @@ function useConfigureSuggestions(config, deps) {
4302
4302
  return consumer;
4303
4303
  }, [normalizedConfig, resolvedConsumerAgentId]);
4304
4304
  const isGlobalConfig = rawConsumerAgentId === void 0 || rawConsumerAgentId === "*";
4305
+ const isDynamicConfigType = useMemo(() => !!normalizedConfig && "instructions" in normalizedConfig, [normalizedConfig]);
4305
4306
  const requestReload = useCallback(() => {
4306
4307
  if (!normalizedConfig) return;
4307
4308
  if (isGlobalConfig) {
4309
+ const seen = /* @__PURE__ */ new Set();
4308
4310
  const agents = Object.values(copilotkit.agents ?? {});
4309
4311
  for (const entry of agents) {
4310
4312
  const agentId = entry.agentId;
4311
4313
  if (!agentId) continue;
4314
+ seen.add(agentId);
4312
4315
  if (!entry.isRunning) copilotkit.reloadSuggestions(agentId);
4313
4316
  }
4317
+ if (targetAgentId && !seen.has(targetAgentId)) copilotkit.reloadSuggestions(targetAgentId);
4314
4318
  return;
4315
4319
  }
4316
4320
  if (!targetAgentId) return;
@@ -4355,6 +4359,26 @@ function useConfigureSuggestions(config, deps) {
4355
4359
  requestReload,
4356
4360
  ...extraDeps
4357
4361
  ]);
4362
+ useEffect(() => {
4363
+ if (!normalizedConfig || !isDynamicConfigType) return;
4364
+ if (!targetAgentId) return;
4365
+ if (!!copilotkit.getAgent(targetAgentId)) return;
4366
+ const subscription = copilotkit.subscribe({ onAgentsChanged: () => {
4367
+ if (copilotkit.getAgent(targetAgentId)) {
4368
+ requestReload();
4369
+ subscription.unsubscribe();
4370
+ }
4371
+ } });
4372
+ return () => {
4373
+ subscription.unsubscribe();
4374
+ };
4375
+ }, [
4376
+ copilotkit,
4377
+ normalizedConfig,
4378
+ isDynamicConfigType,
4379
+ targetAgentId,
4380
+ requestReload
4381
+ ]);
4358
4382
  }
4359
4383
  function isDynamicConfig(config) {
4360
4384
  return "instructions" in config;
@@ -4619,6 +4643,16 @@ function useThreads$1({ agentId, includeArchived, limit }) {
4619
4643
  };
4620
4644
  }, [store]);
4621
4645
  const runtimeStatus = copilotkit.runtimeConnectionStatus;
4646
+ useEffect(() => {
4647
+ copilotkit.registerThreadStore(agentId, store);
4648
+ return () => {
4649
+ copilotkit.unregisterThreadStore(agentId);
4650
+ };
4651
+ }, [
4652
+ copilotkit,
4653
+ agentId,
4654
+ store
4655
+ ]);
4622
4656
  useEffect(() => {
4623
4657
  if (!copilotkit.runtimeUrl) {
4624
4658
  store.setContext(null);
@@ -4642,7 +4676,6 @@ function useThreads$1({ agentId, includeArchived, limit }) {
4642
4676
  headersKey,
4643
4677
  copilotkit.intelligence?.wsUrl,
4644
4678
  agentId,
4645
- copilotkit.headers,
4646
4679
  includeArchived,
4647
4680
  limit
4648
4681
  ]);
@@ -5006,20 +5039,101 @@ CopilotChatAssistantMessage.ReadAloudButton.displayName = "CopilotChatAssistantM
5006
5039
  CopilotChatAssistantMessage.RegenerateButton.displayName = "CopilotChatAssistantMessage.RegenerateButton";
5007
5040
  var CopilotChatAssistantMessage_default = CopilotChatAssistantMessage;
5008
5041
 
5042
+ //#endregion
5043
+ //#region src/v2/components/chat/Lightbox.tsx
5044
+ function Lightbox({ onClose, children }) {
5045
+ useEffect(() => {
5046
+ const handleKey = (e) => {
5047
+ if (e.key === "Escape") onClose();
5048
+ };
5049
+ document.addEventListener("keydown", handleKey);
5050
+ return () => document.removeEventListener("keydown", handleKey);
5051
+ }, [onClose]);
5052
+ if (typeof document === "undefined") return null;
5053
+ return createPortal(/* @__PURE__ */ jsxs("div", {
5054
+ className: "cpk:fixed cpk:inset-0 cpk:z-[9999] cpk:flex cpk:items-center cpk:justify-center cpk:bg-black/80 cpk:animate-fade-in",
5055
+ onClick: onClose,
5056
+ children: [/* @__PURE__ */ jsx("button", {
5057
+ onClick: onClose,
5058
+ className: "cpk:absolute cpk:top-4 cpk:right-4 cpk:text-white cpk:bg-white/10 cpk:hover:bg-white/20 cpk:rounded-full cpk:w-10 cpk:h-10 cpk:flex cpk:items-center cpk:justify-center cpk:cursor-pointer cpk:border-none cpk:z-10",
5059
+ "aria-label": "Close preview",
5060
+ children: /* @__PURE__ */ jsx(X, { className: "cpk:w-5 cpk:h-5" })
5061
+ }), /* @__PURE__ */ jsx("div", {
5062
+ onClick: (e) => e.stopPropagation(),
5063
+ children
5064
+ })]
5065
+ }), document.body);
5066
+ }
5067
+ /**
5068
+ * Hook that manages lightbox open/close and uses the View Transition API to
5069
+ * morph the thumbnail into fullscreen content.
5070
+ *
5071
+ * The trick: `view-transition-name` must live on exactly ONE element at a time.
5072
+ * - Old state (thumbnail visible): name is on the thumbnail.
5073
+ * - New state (lightbox visible): name moves to the lightbox content.
5074
+ * `flushSync` ensures React commits the DOM change synchronously inside the
5075
+ * `startViewTransition` callback so the API can snapshot old → new correctly.
5076
+ */
5077
+ function useLightbox() {
5078
+ const thumbnailRef = useRef(null);
5079
+ const [open, setOpen] = useState(false);
5080
+ const vtName = useId();
5081
+ return {
5082
+ thumbnailRef,
5083
+ vtName,
5084
+ open,
5085
+ openLightbox: useCallback(() => {
5086
+ const thumb = thumbnailRef.current;
5087
+ const doc = document;
5088
+ if (doc.startViewTransition && thumb) {
5089
+ thumb.style.viewTransitionName = vtName;
5090
+ doc.startViewTransition(() => {
5091
+ thumb.style.viewTransitionName = "";
5092
+ flushSync(() => setOpen(true));
5093
+ });
5094
+ } else setOpen(true);
5095
+ }, [vtName]),
5096
+ closeLightbox: useCallback(() => {
5097
+ const thumb = thumbnailRef.current;
5098
+ const doc = document;
5099
+ if (doc.startViewTransition && thumb) doc.startViewTransition(() => {
5100
+ flushSync(() => setOpen(false));
5101
+ thumb.style.viewTransitionName = vtName;
5102
+ }).finished.then(() => {
5103
+ thumb.style.viewTransitionName = "";
5104
+ }).catch(() => {
5105
+ thumb.style.viewTransitionName = "";
5106
+ });
5107
+ else setOpen(false);
5108
+ }, [vtName])
5109
+ };
5110
+ }
5111
+
5009
5112
  //#endregion
5010
5113
  //#region src/v2/components/chat/CopilotChatAttachmentRenderer.tsx
5011
5114
  const ImageAttachment = memo(function ImageAttachment({ src, className }) {
5012
5115
  const [error, setError] = useState(false);
5116
+ const { thumbnailRef, vtName, open, openLightbox, closeLightbox } = useLightbox();
5013
5117
  if (error) return /* @__PURE__ */ jsx("div", {
5014
5118
  className: cn("cpk:flex cpk:flex-col cpk:items-center cpk:justify-center cpk:rounded-lg cpk:bg-muted cpk:p-4 cpk:text-sm cpk:text-muted-foreground", className),
5015
5119
  children: /* @__PURE__ */ jsx("span", { children: "Failed to load image" })
5016
5120
  });
5017
- return /* @__PURE__ */ jsx("img", {
5121
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("img", {
5122
+ ref: thumbnailRef,
5018
5123
  src,
5019
5124
  alt: "Image attachment",
5020
- className: cn("cpk:max-w-full cpk:h-auto cpk:rounded-lg", className),
5125
+ className: cn("cpk:max-w-[80px] cpk:max-h-[80px] cpk:w-auto cpk:h-auto cpk:rounded-xl cpk:object-cover cpk:cursor-pointer cpk:bg-muted", className),
5126
+ onClick: openLightbox,
5021
5127
  onError: () => setError(true)
5022
- });
5128
+ }), open && /* @__PURE__ */ jsx(Lightbox, {
5129
+ onClose: closeLightbox,
5130
+ children: /* @__PURE__ */ jsx("img", {
5131
+ style: { viewTransitionName: vtName },
5132
+ src,
5133
+ alt: "Image attachment",
5134
+ className: "cpk:max-w-[90vw] cpk:max-h-[90vh] cpk:object-contain cpk:rounded-lg"
5135
+ })
5136
+ })] });
5023
5137
  });
5024
5138
  const AudioAttachment = memo(function AudioAttachment({ src, filename, className }) {
5025
5139
  return /* @__PURE__ */ jsxs("div", {
@@ -5144,15 +5258,15 @@ function CopilotChatUserMessage({ message, onEditMessage, branchIndex, numberOfB
5144
5258
  "data-message-id": message.id,
5145
5259
  ...props,
5146
5260
  children: [
5147
- BoundMessageRenderer,
5148
5261
  mediaParts.length > 0 && /* @__PURE__ */ jsx("div", {
5149
- className: "cpk:flex cpk:flex-col cpk:items-end cpk:gap-2 cpk:mt-2",
5262
+ className: "cpk:flex cpk:flex-row cpk:flex-wrap cpk:justify-end cpk:gap-2 cpk:mb-2",
5150
5263
  children: mediaParts.map((part, index) => /* @__PURE__ */ jsx(CopilotChatAttachmentRenderer, {
5151
5264
  type: part.type,
5152
5265
  source: part.source,
5153
5266
  filename: getFilename(part)
5154
5267
  }, index))
5155
5268
  }),
5269
+ BoundMessageRenderer,
5156
5270
  BoundToolbar
5157
5271
  ]
5158
5272
  });
@@ -5856,73 +5970,6 @@ function AttachmentPreview({ attachment }) {
5856
5970
  case "document": return /* @__PURE__ */ jsx(DocumentPreview, { attachment });
5857
5971
  }
5858
5972
  }
5859
- function Lightbox({ onClose, children }) {
5860
- useEffect(() => {
5861
- const handleKey = (e) => {
5862
- if (e.key === "Escape") onClose();
5863
- };
5864
- document.addEventListener("keydown", handleKey);
5865
- return () => document.removeEventListener("keydown", handleKey);
5866
- }, [onClose]);
5867
- if (typeof document === "undefined") return null;
5868
- return createPortal(/* @__PURE__ */ jsxs("div", {
5869
- className: "cpk:fixed cpk:inset-0 cpk:z-[9999] cpk:flex cpk:items-center cpk:justify-center cpk:bg-black/80 cpk:animate-fade-in",
5870
- onClick: onClose,
5871
- children: [/* @__PURE__ */ jsx("button", {
5872
- onClick: onClose,
5873
- className: "cpk:absolute cpk:top-4 cpk:right-4 cpk:text-white cpk:bg-white/10 cpk:hover:bg-white/20 cpk:rounded-full cpk:w-10 cpk:h-10 cpk:flex cpk:items-center cpk:justify-center cpk:cursor-pointer cpk:border-none cpk:z-10",
5874
- "aria-label": "Close preview",
5875
- children: /* @__PURE__ */ jsx(X, { className: "cpk:w-5 cpk:h-5" })
5876
- }), /* @__PURE__ */ jsx("div", {
5877
- onClick: (e) => e.stopPropagation(),
5878
- children
5879
- })]
5880
- }), document.body);
5881
- }
5882
- /**
5883
- * Hook that manages lightbox open/close and uses the View Transition API to
5884
- * morph the thumbnail into fullscreen content.
5885
- *
5886
- * The trick: `view-transition-name` must live on exactly ONE element at a time.
5887
- * - Old state (thumbnail visible): name is on the thumbnail.
5888
- * - New state (lightbox visible): name moves to the lightbox content.
5889
- * `flushSync` ensures React commits the DOM change synchronously inside the
5890
- * `startViewTransition` callback so the API can snapshot old → new correctly.
5891
- */
5892
- function useLightbox() {
5893
- const thumbnailRef = useRef(null);
5894
- const [open, setOpen] = useState(false);
5895
- const vtName = useId();
5896
- return {
5897
- thumbnailRef,
5898
- vtName,
5899
- open,
5900
- openLightbox: useCallback(() => {
5901
- const thumb = thumbnailRef.current;
5902
- const doc = document;
5903
- if (doc.startViewTransition && thumb) {
5904
- thumb.style.viewTransitionName = vtName;
5905
- doc.startViewTransition(() => {
5906
- thumb.style.viewTransitionName = "";
5907
- flushSync(() => setOpen(true));
5908
- });
5909
- } else setOpen(true);
5910
- }, []),
5911
- closeLightbox: useCallback(() => {
5912
- const thumb = thumbnailRef.current;
5913
- const doc = document;
5914
- if (doc.startViewTransition && thumb) doc.startViewTransition(() => {
5915
- flushSync(() => setOpen(false));
5916
- thumb.style.viewTransitionName = vtName;
5917
- }).finished.then(() => {
5918
- thumb.style.viewTransitionName = "";
5919
- }).catch(() => {
5920
- thumb.style.viewTransitionName = "";
5921
- });
5922
- else setOpen(false);
5923
- }, [])
5924
- };
5925
- }
5926
5973
  function ImagePreview({ attachment }) {
5927
5974
  const src = getSourceUrl(attachment.source);
5928
5975
  const { thumbnailRef, vtName, open, openLightbox, closeLightbox } = useLightbox();
@@ -6188,40 +6235,55 @@ const LastUserMessageContext = React.createContext({
6188
6235
 
6189
6236
  //#endregion
6190
6237
  //#region src/v2/hooks/use-pin-to-send.ts
6191
- function usePinToSend({ scrollRef, contentRef, topOffset = 16 }) {
6238
+ function usePinToSend({ scrollRef, contentRef, spacerRef, topOffset = 16 }) {
6192
6239
  const { id, sendNonce } = useContext(LastUserMessageContext);
6193
6240
  const lastNonceRef = useRef(-1);
6241
+ const currentSpacerHeightRef = useRef(0);
6194
6242
  useEffect(() => {
6195
6243
  if (sendNonce === lastNonceRef.current) return;
6196
6244
  lastNonceRef.current = sendNonce;
6197
6245
  if (!id) return;
6198
6246
  const scrollEl = scrollRef.current;
6199
6247
  const contentEl = contentRef.current;
6200
- if (!scrollEl || !contentEl) return;
6248
+ const spacerEl = spacerRef.current;
6249
+ if (!scrollEl || !contentEl || !spacerEl) return;
6201
6250
  const escaped = typeof CSS !== "undefined" && CSS.escape ? CSS.escape(id) : id.replace(/[!"#$%&'()*+,./:;<=>?@[\\\]^`{|}~]/g, "\\$&");
6202
6251
  const targetEl = contentEl.querySelector(`[data-message-id="${escaped}"]`);
6203
6252
  if (!targetEl) return;
6204
6253
  const viewportHeight = scrollEl.clientHeight;
6254
+ const userMessageHeight = targetEl.getBoundingClientRect().height;
6205
6255
  const paddingTop = parseFloat(getComputedStyle(targetEl).paddingTop) || 0;
6206
- const userMsgOffsetInScroll = computeOffsetTop(targetEl, scrollEl);
6207
- const requiredScrollHeight = userMsgOffsetInScroll + paddingTop + viewportHeight - topOffset;
6208
- contentEl.style.minHeight = `${Math.max(0, requiredScrollHeight)}px`;
6256
+ const bubbleHeight = Math.max(0, userMessageHeight - paddingTop);
6257
+ const spacerHeight = Math.max(0, viewportHeight - bubbleHeight - topOffset);
6258
+ spacerEl.style.height = `${spacerHeight}px`;
6259
+ currentSpacerHeightRef.current = spacerHeight;
6209
6260
  const raf = requestAnimationFrame(() => {
6210
- const targetTop = userMsgOffsetInScroll + paddingTop - topOffset;
6261
+ const targetTop = computeOffsetTop(targetEl, scrollEl) + paddingTop - topOffset;
6211
6262
  scrollEl.scrollTo({
6212
6263
  top: Math.max(0, targetTop),
6213
6264
  behavior: "smooth"
6214
6265
  });
6215
6266
  });
6267
+ const ro = new ResizeObserver(() => {
6268
+ if (!contentEl || !spacerEl || !scrollEl) return;
6269
+ const consumedBelow = contentEl.getBoundingClientRect().height - computeOffsetTop(targetEl, contentEl) - userMessageHeight;
6270
+ const remaining = Math.max(0, spacerHeight - consumedBelow);
6271
+ if (remaining < currentSpacerHeightRef.current) {
6272
+ spacerEl.style.height = `${remaining}px`;
6273
+ currentSpacerHeightRef.current = remaining;
6274
+ }
6275
+ });
6276
+ ro.observe(contentEl);
6216
6277
  return () => {
6217
6278
  cancelAnimationFrame(raf);
6218
- contentEl.style.minHeight = "";
6279
+ ro.disconnect();
6219
6280
  };
6220
6281
  }, [
6221
6282
  id,
6222
6283
  sendNonce,
6223
6284
  scrollRef,
6224
6285
  contentRef,
6286
+ spacerRef,
6225
6287
  topOffset
6226
6288
  ]);
6227
6289
  }
@@ -6247,14 +6309,17 @@ function DropOverlay() {
6247
6309
  });
6248
6310
  }
6249
6311
  function CopilotChatView({ messageView, input, scrollView, suggestionView, welcomeScreen, messages = [], autoScroll = true, isRunning = false, suggestions, suggestionLoadingIndexes, onSelectSuggestion, onSubmitMessage, onStop, inputMode, inputValue, onInputChange, onStartTranscribe, onCancelTranscribe, onFinishTranscribe, onFinishTranscribeWithAudio, attachments, onRemoveAttachment, onAddFile, dragOver, onDragOver, onDragLeave, onDrop, isConnecting = false, hasExplicitThreadId = false, disclaimer, children, className, ...props }) {
6250
- const inputContainerRef = useRef(null);
6312
+ const [inputContainerEl, setInputContainerEl] = useState(null);
6251
6313
  const [inputContainerHeight, setInputContainerHeight] = useState(0);
6252
6314
  const [isResizing, setIsResizing] = useState(false);
6253
6315
  const resizeTimeoutRef = useRef(null);
6254
6316
  const { isKeyboardOpen, keyboardHeight, availableHeight } = useKeyboardHeight();
6255
6317
  useEffect(() => {
6256
- const element = inputContainerRef.current;
6257
- if (!element) return;
6318
+ const element = inputContainerEl;
6319
+ if (!element) {
6320
+ setInputContainerHeight(0);
6321
+ return;
6322
+ }
6258
6323
  const resizeObserver = new ResizeObserver((entries) => {
6259
6324
  for (const entry of entries) {
6260
6325
  const newHeight = entry.contentRect.height;
@@ -6277,7 +6342,7 @@ function CopilotChatView({ messageView, input, scrollView, suggestionView, welco
6277
6342
  resizeObserver.disconnect();
6278
6343
  if (resizeTimeoutRef.current) clearTimeout(resizeTimeoutRef.current);
6279
6344
  };
6280
- }, []);
6345
+ }, [inputContainerEl]);
6281
6346
  const BoundMessageView = renderSlot(messageView, CopilotChatMessageView, {
6282
6347
  messages,
6283
6348
  isRunning
@@ -6388,7 +6453,7 @@ function CopilotChatView({ messageView, input, scrollView, suggestionView, welco
6388
6453
  dragOver && /* @__PURE__ */ jsx(DropOverlay, {}),
6389
6454
  BoundScrollView,
6390
6455
  /* @__PURE__ */ jsxs("div", {
6391
- ref: inputContainerRef,
6456
+ ref: setInputContainerEl,
6392
6457
  "data-testid": "copilot-input-overlay",
6393
6458
  className: "cpk:absolute cpk:bottom-0 cpk:left-0 cpk:right-0 cpk:z-20 cpk:pointer-events-none",
6394
6459
  children: [attachments && attachments.length > 0 && /* @__PURE__ */ jsx("div", {
@@ -6435,9 +6500,11 @@ function CopilotChatView({ messageView, input, scrollView, suggestionView, welco
6435
6500
  });
6436
6501
  };
6437
6502
  const PinToSendScrollContainer = ({ children, scrollRef, contentRef, scrollToBottom, scrollToBottomButton, feather, inputContainerHeight, isResizing, nonAutoScrollEl, nonAutoScrollRefCallback, showScrollButton, className, ...props }) => {
6503
+ const spacerRef = useRef(null);
6438
6504
  usePinToSend({
6439
6505
  scrollRef,
6440
6506
  contentRef,
6507
+ spacerRef,
6441
6508
  topOffset: 16
6442
6509
  });
6443
6510
  const BoundFeather = renderSlot(feather, CopilotChatView.Feather, {});
@@ -6446,16 +6513,23 @@ function CopilotChatView({ messageView, input, scrollView, suggestionView, welco
6446
6513
  children: /* @__PURE__ */ jsxs("div", {
6447
6514
  className: cn("cpk:h-full cpk:max-h-full cpk:flex cpk:flex-col cpk:min-h-0 cpk:relative", className),
6448
6515
  children: [
6449
- /* @__PURE__ */ jsx("div", {
6516
+ /* @__PURE__ */ jsxs("div", {
6450
6517
  ref: nonAutoScrollRefCallback,
6451
6518
  className: "cpk:flex-1 cpk:min-h-0 cpk:overflow-y-auto cpk:overflow-x-hidden",
6452
6519
  ...props,
6453
- children: /* @__PURE__ */ jsx("div", {
6520
+ children: [/* @__PURE__ */ jsx("div", {
6454
6521
  ref: contentRef,
6455
- "data-pin-to-send-content": true,
6456
6522
  className: "cpk:px-4 cpk:sm:px-0 cpk:[div[data-sidebar-chat]_&]:px-8 cpk:[div[data-popup-chat]_&]:px-6",
6457
6523
  children
6458
- })
6524
+ }), /* @__PURE__ */ jsx("div", {
6525
+ ref: spacerRef,
6526
+ "data-pin-to-send-spacer": true,
6527
+ "aria-hidden": "true",
6528
+ style: {
6529
+ height: 0,
6530
+ flex: "0 0 auto"
6531
+ }
6532
+ })]
6459
6533
  }),
6460
6534
  BoundFeather,
6461
6535
  showScrollButton && !isResizing && /* @__PURE__ */ jsx("div", {
@@ -9729,4 +9803,4 @@ function validateProps(props) {
9729
9803
 
9730
9804
  //#endregion
9731
9805
  export { CopilotKitProvider as $, CopilotChatSuggestionView as A, useConfigureSuggestions as B, CopilotChatToggleButton as C, CopilotChatView_default as D, CopilotChat as E, CopilotChatAssistantMessage_default as F, useRenderTool as G, useCapabilities as H, CopilotChatToolCallsView as I, useRenderActivityMessage as J, useComponent as K, useAttachments as L, CopilotChatReasoningMessage_default as M, CopilotChatUserMessage_default as N, CopilotChatAttachmentQueue as O, CopilotChatAttachmentRenderer as P, useRenderToolCall as Q, useThreads$1 as R, CopilotModalHeader as S, DefaultOpenIcon as T, useHumanInTheLoop as U, useSuggestions as V, useDefaultRenderTool as W, UseAgentUpdate as X, useRenderCustomMessages as Y, useAgent as Z, WildcardToolCallRender as _, ThreadsProvider as a, SandboxFunctionsContext as at, CopilotPopupView as b, CoAgentStateRendersProvider as c, MCPAppsActivityRenderer as ct, shouldShowDevConsole as d, CopilotChatInput_default as dt, useCopilotKit as et, useToast as f, AudioRecorderError as ft, useCopilotContext as g, CopilotContext as h, useCopilotChatConfiguration as ht, ThreadsContext as i, createA2UIMessageRenderer as it, CopilotChatSuggestionPill as j, CopilotChatMessageView as k, useCoAgentStateRenders as l, MCPAppsActivityType as lt, useCopilotMessagesContext as m, CopilotChatConfigurationProvider as mt, defaultCopilotContextCategories as n, useAgentContext as nt, useThreads as o, useSandboxFunctions as ot, CopilotMessagesContext as p, CopilotChatAudioRecorder as pt, useFrontendTool as q, CoAgentStateRenderBridge as r, defineToolCallRenderer as rt, CoAgentStateRendersContext as s, MCPAppsActivityContentSchema as st, CopilotKit as t, CopilotKitCoreReact as tt, useAsyncCallback as u, CopilotKitInspector as ut, CopilotPopup as v, DefaultCloseIcon as w, CopilotSidebarView as x, CopilotSidebar as y, useInterrupt as z };
9732
- //# sourceMappingURL=copilotkit-DHEUlli6.mjs.map
9806
+ //# sourceMappingURL=copilotkit-CPe2-340.mjs.map