@copilotkitnext/react 1.52.2-next.2 → 1.52.2-next.3

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 (75) hide show
  1. package/dist/components/chat/CopilotChat.cjs +13 -6
  2. package/dist/components/chat/CopilotChat.cjs.map +1 -1
  3. package/dist/components/chat/CopilotChat.d.cts.map +1 -1
  4. package/dist/components/chat/CopilotChat.d.mts.map +1 -1
  5. package/dist/components/chat/CopilotChat.mjs +14 -7
  6. package/dist/components/chat/CopilotChat.mjs.map +1 -1
  7. package/dist/components/chat/CopilotChatAssistantMessage.cjs +1 -1
  8. package/dist/components/chat/CopilotChatAssistantMessage.cjs.map +1 -1
  9. package/dist/components/chat/CopilotChatAssistantMessage.d.cts.map +1 -1
  10. package/dist/components/chat/CopilotChatAssistantMessage.d.mts.map +1 -1
  11. package/dist/components/chat/CopilotChatAssistantMessage.mjs +1 -1
  12. package/dist/components/chat/CopilotChatAssistantMessage.mjs.map +1 -1
  13. package/dist/components/chat/CopilotChatInput.cjs +1 -1
  14. package/dist/components/chat/CopilotChatInput.cjs.map +1 -1
  15. package/dist/components/chat/CopilotChatInput.d.cts.map +1 -1
  16. package/dist/components/chat/CopilotChatInput.d.mts.map +1 -1
  17. package/dist/components/chat/CopilotChatInput.mjs +1 -1
  18. package/dist/components/chat/CopilotChatInput.mjs.map +1 -1
  19. package/dist/components/chat/CopilotChatMessageView.cjs +1 -1
  20. package/dist/components/chat/CopilotChatMessageView.cjs.map +1 -1
  21. package/dist/components/chat/CopilotChatMessageView.mjs +1 -1
  22. package/dist/components/chat/CopilotChatMessageView.mjs.map +1 -1
  23. package/dist/components/chat/CopilotChatToggleButton.cjs +1 -1
  24. package/dist/components/chat/CopilotChatToggleButton.cjs.map +1 -1
  25. package/dist/components/chat/CopilotChatToggleButton.d.cts.map +1 -1
  26. package/dist/components/chat/CopilotChatToggleButton.d.mts.map +1 -1
  27. package/dist/components/chat/CopilotChatToggleButton.mjs +1 -1
  28. package/dist/components/chat/CopilotChatToggleButton.mjs.map +1 -1
  29. package/dist/components/chat/CopilotChatUserMessage.cjs +1 -1
  30. package/dist/components/chat/CopilotChatUserMessage.cjs.map +1 -1
  31. package/dist/components/chat/CopilotChatUserMessage.mjs +1 -1
  32. package/dist/components/chat/CopilotChatUserMessage.mjs.map +1 -1
  33. package/dist/components/chat/CopilotChatView.cjs +2 -2
  34. package/dist/components/chat/CopilotChatView.cjs.map +1 -1
  35. package/dist/components/chat/CopilotChatView.mjs +2 -2
  36. package/dist/components/chat/CopilotChatView.mjs.map +1 -1
  37. package/dist/components/chat/CopilotModalHeader.cjs +1 -1
  38. package/dist/components/chat/CopilotModalHeader.cjs.map +1 -1
  39. package/dist/components/chat/CopilotModalHeader.d.cts.map +1 -1
  40. package/dist/components/chat/CopilotModalHeader.d.mts.map +1 -1
  41. package/dist/components/chat/CopilotModalHeader.mjs +1 -1
  42. package/dist/components/chat/CopilotModalHeader.mjs.map +1 -1
  43. package/dist/components/chat/CopilotPopupView.cjs +1 -1
  44. package/dist/components/chat/CopilotPopupView.cjs.map +1 -1
  45. package/dist/components/chat/CopilotPopupView.d.cts.map +1 -1
  46. package/dist/components/chat/CopilotPopupView.d.mts.map +1 -1
  47. package/dist/components/chat/CopilotPopupView.mjs +1 -1
  48. package/dist/components/chat/CopilotPopupView.mjs.map +1 -1
  49. package/dist/components/chat/CopilotSidebarView.cjs +1 -1
  50. package/dist/components/chat/CopilotSidebarView.cjs.map +1 -1
  51. package/dist/components/chat/CopilotSidebarView.d.cts.map +1 -1
  52. package/dist/components/chat/CopilotSidebarView.d.mts.map +1 -1
  53. package/dist/components/chat/CopilotSidebarView.mjs +1 -1
  54. package/dist/components/chat/CopilotSidebarView.mjs.map +1 -1
  55. package/dist/hooks/use-agent.cjs +12 -3
  56. package/dist/hooks/use-agent.cjs.map +1 -1
  57. package/dist/hooks/use-agent.mjs +13 -4
  58. package/dist/hooks/use-agent.mjs.map +1 -1
  59. package/dist/index.umd.js +81 -43
  60. package/dist/index.umd.js.map +1 -1
  61. package/dist/lib/react-core.cjs +6 -0
  62. package/dist/lib/react-core.cjs.map +1 -1
  63. package/dist/lib/react-core.d.cts +2 -0
  64. package/dist/lib/react-core.d.cts.map +1 -1
  65. package/dist/lib/react-core.d.mts +2 -0
  66. package/dist/lib/react-core.d.mts.map +1 -1
  67. package/dist/lib/react-core.mjs +6 -0
  68. package/dist/lib/react-core.mjs.map +1 -1
  69. package/dist/providers/CopilotKitProvider.cjs +40 -24
  70. package/dist/providers/CopilotKitProvider.cjs.map +1 -1
  71. package/dist/providers/CopilotKitProvider.d.cts.map +1 -1
  72. package/dist/providers/CopilotKitProvider.d.mts.map +1 -1
  73. package/dist/providers/CopilotKitProvider.mjs +40 -24
  74. package/dist/providers/CopilotKitProvider.mjs.map +1 -1
  75. package/package.json +8 -8
@@ -28,20 +28,27 @@ function CopilotChat({ agentId, threadId, labels, chatView, ...props }) {
28
28
  const isMediaRecorderSupported = typeof window !== "undefined" && typeof MediaRecorder !== "undefined";
29
29
  const { messageView: providedMessageView, suggestionView: providedSuggestionView, onStop: providedStopHandler, ...restProps } = props;
30
30
  (0, react.useEffect)(() => {
31
+ let detached = false;
32
+ const connectAbortController = new AbortController();
33
+ if (agent instanceof _ag_ui_client.HttpAgent) agent.abortController = connectAbortController;
31
34
  const connect = async (agent) => {
32
35
  try {
33
36
  await copilotkit.connectAgent({ agent });
34
37
  } catch (error) {
38
+ if (detached) return;
35
39
  if (error instanceof _ag_ui_client.AGUIConnectNotImplementedError) {} else throw error;
36
40
  }
37
41
  };
38
42
  agent.threadId = resolvedThreadId;
39
43
  connect(agent);
40
- return () => {};
44
+ return () => {
45
+ detached = true;
46
+ connectAbortController.abort();
47
+ agent.detachActiveRun();
48
+ };
41
49
  }, [
42
50
  resolvedThreadId,
43
51
  agent,
44
- copilotkit,
45
52
  resolvedAgentId
46
53
  ]);
47
54
  const onSubmitInput = (0, react.useCallback)(async (value) => {
@@ -56,7 +63,7 @@ function CopilotChat({ agentId, threadId, labels, chatView, ...props }) {
56
63
  } catch (error) {
57
64
  console.error("CopilotChat: runAgent failed", error);
58
65
  }
59
- }, [agent, copilotkit]);
66
+ }, [agent]);
60
67
  const handleSelectSuggestion = (0, react.useCallback)(async (suggestion) => {
61
68
  agent.addMessage({
62
69
  id: (0, _copilotkitnext_shared.randomUUID)(),
@@ -68,7 +75,7 @@ function CopilotChat({ agentId, threadId, labels, chatView, ...props }) {
68
75
  } catch (error) {
69
76
  console.error("CopilotChat: runAgent failed after selecting suggestion", error);
70
77
  }
71
- }, [agent, copilotkit]);
78
+ }, [agent]);
72
79
  const stopCurrentRun = (0, react.useCallback)(() => {
73
80
  try {
74
81
  copilotkit.stopAgent({ agent });
@@ -80,7 +87,7 @@ function CopilotChat({ agentId, threadId, labels, chatView, ...props }) {
80
87
  console.error("CopilotChat: abortRun fallback failed", abortError);
81
88
  }
82
89
  }
83
- }, [agent, copilotkit]);
90
+ }, [agent]);
84
91
  const handleStartTranscribe = (0, react.useCallback)(() => {
85
92
  setTranscriptionError(null);
86
93
  setTranscribeMode("transcribe");
@@ -134,7 +141,7 @@ function CopilotChat({ agentId, threadId, labels, chatView, ...props }) {
134
141
  } finally {
135
142
  setIsTranscribing(false);
136
143
  }
137
- }, [copilotkit]);
144
+ }, []);
138
145
  (0, react.useEffect)(() => {
139
146
  if (transcriptionError) {
140
147
  const timer = setTimeout(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"CopilotChat.cjs","names":["useCopilotChatConfiguration","DEFAULT_AGENT_ID","useAgent","useCopilotKit","useSuggestions","AGUIConnectNotImplementedError","transcribeAudio","TranscriptionError","TranscriptionErrorCode","renderSlot","CopilotChatView","CopilotChatConfigurationProvider"],"sources":["../../../src/components/chat/CopilotChat.tsx"],"sourcesContent":["import { useAgent } from \"@/hooks/use-agent\";\nimport { useSuggestions } from \"@/hooks/use-suggestions\";\nimport { CopilotChatView, CopilotChatViewProps } from \"./CopilotChatView\";\nimport { CopilotChatInputMode } from \"./CopilotChatInput\";\nimport {\n CopilotChatConfigurationProvider,\n CopilotChatLabels,\n useCopilotChatConfiguration,\n} from \"@/providers/CopilotChatConfigurationProvider\";\nimport {\n DEFAULT_AGENT_ID,\n randomUUID,\n TranscriptionErrorCode,\n} from \"@copilotkitnext/shared\";\nimport { Suggestion, CopilotKitCoreErrorCode } from \"@copilotkitnext/core\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { merge } from \"ts-deepmerge\";\nimport { useCopilotKit } from \"@/providers/CopilotKitProvider\";\nimport { AbstractAgent, AGUIConnectNotImplementedError } from \"@ag-ui/client\";\nimport { renderSlot, SlotValue } from \"@/lib/slots\";\nimport {\n transcribeAudio,\n TranscriptionError,\n} from \"@/lib/transcription-client\";\n\nexport type CopilotChatProps = Omit<\n CopilotChatViewProps,\n | \"messages\"\n | \"isRunning\"\n | \"suggestions\"\n | \"suggestionLoadingIndexes\"\n | \"onSelectSuggestion\"\n> & {\n agentId?: string;\n threadId?: string;\n labels?: Partial<CopilotChatLabels>;\n chatView?: SlotValue<typeof CopilotChatView>;\n};\nexport function CopilotChat({\n agentId,\n threadId,\n labels,\n chatView,\n ...props\n}: CopilotChatProps) {\n // Check for existing configuration provider\n const existingConfig = useCopilotChatConfiguration();\n\n // Apply priority: props > existing config > defaults\n const resolvedAgentId =\n agentId ?? existingConfig?.agentId ?? DEFAULT_AGENT_ID;\n const resolvedThreadId = useMemo(\n () => threadId ?? existingConfig?.threadId ?? randomUUID(),\n [threadId, existingConfig?.threadId],\n );\n\n const { agent } = useAgent({ agentId: resolvedAgentId });\n const { copilotkit } = useCopilotKit();\n const { suggestions: autoSuggestions } = useSuggestions({\n agentId: resolvedAgentId,\n });\n\n // Transcription state\n const [transcribeMode, setTranscribeMode] =\n useState<CopilotChatInputMode>(\"input\");\n const [inputValue, setInputValue] = useState(\"\");\n const [transcriptionError, setTranscriptionError] = useState<string | null>(\n null,\n );\n const [isTranscribing, setIsTranscribing] = useState(false);\n\n // Check if transcription is enabled\n const isTranscriptionEnabled = copilotkit.audioFileTranscriptionEnabled;\n\n // Check if browser supports MediaRecorder\n const isMediaRecorderSupported =\n typeof window !== \"undefined\" && typeof MediaRecorder !== \"undefined\";\n\n const {\n messageView: providedMessageView,\n suggestionView: providedSuggestionView,\n onStop: providedStopHandler,\n ...restProps\n } = props;\n\n useEffect(() => {\n const connect = async (agent: AbstractAgent) => {\n try {\n await copilotkit.connectAgent({ agent });\n } catch (error) {\n if (error instanceof AGUIConnectNotImplementedError) {\n // connect not implemented, ignore\n } else {\n throw error;\n }\n }\n };\n agent.threadId = resolvedThreadId;\n connect(agent);\n return () => {};\n }, [resolvedThreadId, agent, copilotkit, resolvedAgentId]);\n\n const onSubmitInput = useCallback(\n async (value: string) => {\n agent.addMessage({\n id: randomUUID(),\n role: \"user\",\n content: value,\n });\n // Clear input after submitting\n setInputValue(\"\");\n try {\n await copilotkit.runAgent({ agent });\n } catch (error) {\n console.error(\"CopilotChat: runAgent failed\", error);\n }\n },\n [agent, copilotkit],\n );\n\n const handleSelectSuggestion = useCallback(\n async (suggestion: Suggestion) => {\n agent.addMessage({\n id: randomUUID(),\n role: \"user\",\n content: suggestion.message,\n });\n\n try {\n await copilotkit.runAgent({ agent });\n } catch (error) {\n console.error(\n \"CopilotChat: runAgent failed after selecting suggestion\",\n error,\n );\n }\n },\n [agent, copilotkit],\n );\n\n const stopCurrentRun = useCallback(() => {\n try {\n copilotkit.stopAgent({ agent });\n } catch (error) {\n console.error(\"CopilotChat: stopAgent failed\", error);\n try {\n agent.abortRun();\n } catch (abortError) {\n console.error(\"CopilotChat: abortRun fallback failed\", abortError);\n }\n }\n }, [agent, copilotkit]);\n\n // Transcription handlers\n const handleStartTranscribe = useCallback(() => {\n setTranscriptionError(null);\n setTranscribeMode(\"transcribe\");\n }, []);\n\n const handleCancelTranscribe = useCallback(() => {\n setTranscriptionError(null);\n setTranscribeMode(\"input\");\n }, []);\n\n const handleFinishTranscribe = useCallback(() => {\n setTranscribeMode(\"input\");\n }, []);\n\n // Handle audio blob from CopilotChatInput and transcribe it\n const handleFinishTranscribeWithAudio = useCallback(\n async (audioBlob: Blob) => {\n setIsTranscribing(true);\n try {\n setTranscriptionError(null);\n\n // Send to transcription endpoint\n const result = await transcribeAudio(copilotkit, audioBlob);\n\n // Insert transcribed text into input\n setInputValue((prev) => {\n const trimmedPrev = prev.trim();\n if (trimmedPrev) {\n return `${trimmedPrev} ${result.text}`;\n }\n return result.text;\n });\n } catch (error) {\n console.error(\"CopilotChat: Transcription failed\", error);\n\n // Show contextual error message based on error type\n if (error instanceof TranscriptionError) {\n const { code, retryable, message } = error.info;\n switch (code) {\n case TranscriptionErrorCode.RATE_LIMITED:\n setTranscriptionError(\"Too many requests. Please wait a moment.\");\n break;\n case TranscriptionErrorCode.AUTH_FAILED:\n setTranscriptionError(\n \"Authentication error. Please check your configuration.\",\n );\n break;\n case TranscriptionErrorCode.AUDIO_TOO_LONG:\n setTranscriptionError(\n \"Recording is too long. Please try a shorter recording.\",\n );\n break;\n case TranscriptionErrorCode.AUDIO_TOO_SHORT:\n setTranscriptionError(\n \"Recording is too short. Please try again.\",\n );\n break;\n case TranscriptionErrorCode.INVALID_AUDIO_FORMAT:\n setTranscriptionError(\"Audio format not supported.\");\n break;\n case TranscriptionErrorCode.SERVICE_NOT_CONFIGURED:\n setTranscriptionError(\"Transcription service is not available.\");\n break;\n case TranscriptionErrorCode.NETWORK_ERROR:\n setTranscriptionError(\n \"Network error. Please check your connection.\",\n );\n break;\n default:\n // For retryable errors, show more helpful message\n setTranscriptionError(\n retryable ? \"Transcription failed. Please try again.\" : message,\n );\n }\n } else {\n // Fallback for unexpected errors\n setTranscriptionError(\"Transcription failed. Please try again.\");\n }\n } finally {\n setIsTranscribing(false);\n }\n },\n [copilotkit],\n );\n\n // Clear transcription error after a delay\n useEffect(() => {\n if (transcriptionError) {\n const timer = setTimeout(() => {\n setTranscriptionError(null);\n }, 5000);\n return () => clearTimeout(timer);\n }\n }, [transcriptionError]);\n\n const mergedProps = merge(\n {\n isRunning: agent.isRunning,\n suggestions: autoSuggestions,\n onSelectSuggestion: handleSelectSuggestion,\n suggestionView: providedSuggestionView,\n },\n {\n ...restProps,\n ...(typeof providedMessageView === \"string\"\n ? { messageView: { className: providedMessageView } }\n : providedMessageView !== undefined\n ? { messageView: providedMessageView }\n : {}),\n },\n );\n\n const hasMessages = agent.messages.length > 0;\n const shouldAllowStop = agent.isRunning && hasMessages;\n const effectiveStopHandler = shouldAllowStop\n ? (providedStopHandler ?? stopCurrentRun)\n : providedStopHandler;\n\n // Determine if transcription feature should be available\n const showTranscription = isTranscriptionEnabled && isMediaRecorderSupported;\n\n // Determine mode: transcribing takes priority, then transcribe mode, then default to input\n const effectiveMode: CopilotChatInputMode = isTranscribing\n ? \"processing\"\n : transcribeMode;\n\n // Memoize messages array - only create new reference when content actually changes\n // (agent.messages is mutated in place, so we need a new reference for React to detect changes)\n\n const messages = useMemo(\n () => [...agent.messages],\n [JSON.stringify(agent.messages)],\n );\n\n const finalProps = merge(mergedProps, {\n messages,\n // Input behavior props\n onSubmitMessage: onSubmitInput,\n onStop: effectiveStopHandler,\n inputMode: effectiveMode,\n inputValue,\n onInputChange: setInputValue,\n // Only provide transcription handlers if feature is available\n onStartTranscribe: showTranscription ? handleStartTranscribe : undefined,\n onCancelTranscribe: showTranscription ? handleCancelTranscribe : undefined,\n onFinishTranscribe: showTranscription ? handleFinishTranscribe : undefined,\n onFinishTranscribeWithAudio: showTranscription\n ? handleFinishTranscribeWithAudio\n : undefined,\n }) as CopilotChatViewProps;\n\n // Always create a provider with merged values\n // This ensures priority: props > existing config > defaults\n const RenderedChatView = renderSlot(chatView, CopilotChatView, finalProps);\n\n return (\n <CopilotChatConfigurationProvider\n agentId={resolvedAgentId}\n threadId={resolvedThreadId}\n labels={labels}\n >\n {transcriptionError && (\n <div\n style={{\n position: \"absolute\",\n bottom: \"100px\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n backgroundColor: \"#ef4444\",\n color: \"white\",\n padding: \"8px 16px\",\n borderRadius: \"8px\",\n fontSize: \"14px\",\n zIndex: 50,\n }}\n >\n {transcriptionError}\n </div>\n )}\n {RenderedChatView}\n </CopilotChatConfigurationProvider>\n );\n}\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace CopilotChat {\n export const View = CopilotChatView;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"CopilotChat.cjs","names":["useCopilotChatConfiguration","DEFAULT_AGENT_ID","useAgent","useCopilotKit","useSuggestions","HttpAgent","AGUIConnectNotImplementedError","transcribeAudio","TranscriptionError","TranscriptionErrorCode","renderSlot","CopilotChatView","CopilotChatConfigurationProvider"],"sources":["../../../src/components/chat/CopilotChat.tsx"],"sourcesContent":["import { useAgent } from \"@/hooks/use-agent\";\nimport { useSuggestions } from \"@/hooks/use-suggestions\";\nimport { CopilotChatView, CopilotChatViewProps } from \"./CopilotChatView\";\nimport { CopilotChatInputMode } from \"./CopilotChatInput\";\nimport {\n CopilotChatConfigurationProvider,\n CopilotChatLabels,\n useCopilotChatConfiguration,\n} from \"@/providers/CopilotChatConfigurationProvider\";\nimport {\n DEFAULT_AGENT_ID,\n randomUUID,\n TranscriptionErrorCode,\n} from \"@copilotkitnext/shared\";\nimport { Suggestion, CopilotKitCoreErrorCode } from \"@copilotkitnext/core\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { merge } from \"ts-deepmerge\";\nimport { useCopilotKit } from \"@/providers/CopilotKitProvider\";\nimport {\n AbstractAgent,\n AGUIConnectNotImplementedError,\n HttpAgent,\n} from \"@ag-ui/client\";\nimport { renderSlot, SlotValue } from \"@/lib/slots\";\nimport {\n transcribeAudio,\n TranscriptionError,\n} from \"@/lib/transcription-client\";\n\nexport type CopilotChatProps = Omit<\n CopilotChatViewProps,\n | \"messages\"\n | \"isRunning\"\n | \"suggestions\"\n | \"suggestionLoadingIndexes\"\n | \"onSelectSuggestion\"\n> & {\n agentId?: string;\n threadId?: string;\n labels?: Partial<CopilotChatLabels>;\n chatView?: SlotValue<typeof CopilotChatView>;\n};\nexport function CopilotChat({\n agentId,\n threadId,\n labels,\n chatView,\n ...props\n}: CopilotChatProps) {\n // Check for existing configuration provider\n const existingConfig = useCopilotChatConfiguration();\n\n // Apply priority: props > existing config > defaults\n const resolvedAgentId =\n agentId ?? existingConfig?.agentId ?? DEFAULT_AGENT_ID;\n const resolvedThreadId = useMemo(\n () => threadId ?? existingConfig?.threadId ?? randomUUID(),\n [threadId, existingConfig?.threadId],\n );\n\n const { agent } = useAgent({ agentId: resolvedAgentId });\n const { copilotkit } = useCopilotKit();\n const { suggestions: autoSuggestions } = useSuggestions({\n agentId: resolvedAgentId,\n });\n\n // Transcription state\n const [transcribeMode, setTranscribeMode] =\n useState<CopilotChatInputMode>(\"input\");\n const [inputValue, setInputValue] = useState(\"\");\n const [transcriptionError, setTranscriptionError] = useState<string | null>(\n null,\n );\n const [isTranscribing, setIsTranscribing] = useState(false);\n\n // Check if transcription is enabled\n const isTranscriptionEnabled = copilotkit.audioFileTranscriptionEnabled;\n\n // Check if browser supports MediaRecorder\n const isMediaRecorderSupported =\n typeof window !== \"undefined\" && typeof MediaRecorder !== \"undefined\";\n\n const {\n messageView: providedMessageView,\n suggestionView: providedSuggestionView,\n onStop: providedStopHandler,\n ...restProps\n } = props;\n\n useEffect(() => {\n let detached = false;\n\n // Create a fresh AbortController so we can cancel the HTTP request on cleanup.\n // HttpAgent (parent of ProxiedCopilotRuntimeAgent) uses this.abortController.signal\n // in its fetch config. Unlike runAgent(), connectAgent() does NOT create a new\n // AbortController automatically, so we must set one before connecting.\n const connectAbortController = new AbortController();\n if (agent instanceof HttpAgent) {\n agent.abortController = connectAbortController;\n }\n\n const connect = async (agent: AbstractAgent) => {\n try {\n await copilotkit.connectAgent({ agent });\n } catch (error) {\n // Ignore errors from aborted connections (e.g., React StrictMode cleanup)\n if (detached) return;\n if (error instanceof AGUIConnectNotImplementedError) {\n // connect not implemented, ignore\n } else {\n throw error;\n }\n }\n };\n agent.threadId = resolvedThreadId;\n connect(agent);\n return () => {\n // Abort the HTTP request and detach the active run.\n // This is critical for React StrictMode which unmounts+remounts in dev,\n // preventing duplicate /connect requests from reaching the server.\n detached = true;\n connectAbortController.abort();\n agent.detachActiveRun();\n };\n // copilotkit is intentionally excluded — it is a stable ref that never changes.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [resolvedThreadId, agent, resolvedAgentId]);\n\n const onSubmitInput = useCallback(\n async (value: string) => {\n agent.addMessage({\n id: randomUUID(),\n role: \"user\",\n content: value,\n });\n // Clear input after submitting\n setInputValue(\"\");\n try {\n await copilotkit.runAgent({ agent });\n } catch (error) {\n console.error(\"CopilotChat: runAgent failed\", error);\n }\n },\n // copilotkit is intentionally excluded — it is a stable ref that never changes.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [agent],\n );\n\n const handleSelectSuggestion = useCallback(\n async (suggestion: Suggestion) => {\n agent.addMessage({\n id: randomUUID(),\n role: \"user\",\n content: suggestion.message,\n });\n\n try {\n await copilotkit.runAgent({ agent });\n } catch (error) {\n console.error(\n \"CopilotChat: runAgent failed after selecting suggestion\",\n error,\n );\n }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [agent],\n );\n\n const stopCurrentRun = useCallback(() => {\n try {\n copilotkit.stopAgent({ agent });\n } catch (error) {\n console.error(\"CopilotChat: stopAgent failed\", error);\n try {\n agent.abortRun();\n } catch (abortError) {\n console.error(\"CopilotChat: abortRun fallback failed\", abortError);\n }\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [agent]);\n\n // Transcription handlers\n const handleStartTranscribe = useCallback(() => {\n setTranscriptionError(null);\n setTranscribeMode(\"transcribe\");\n }, []);\n\n const handleCancelTranscribe = useCallback(() => {\n setTranscriptionError(null);\n setTranscribeMode(\"input\");\n }, []);\n\n const handleFinishTranscribe = useCallback(() => {\n setTranscribeMode(\"input\");\n }, []);\n\n // Handle audio blob from CopilotChatInput and transcribe it\n const handleFinishTranscribeWithAudio = useCallback(\n async (audioBlob: Blob) => {\n setIsTranscribing(true);\n try {\n setTranscriptionError(null);\n\n // Send to transcription endpoint\n const result = await transcribeAudio(copilotkit, audioBlob);\n\n // Insert transcribed text into input\n setInputValue((prev) => {\n const trimmedPrev = prev.trim();\n if (trimmedPrev) {\n return `${trimmedPrev} ${result.text}`;\n }\n return result.text;\n });\n } catch (error) {\n console.error(\"CopilotChat: Transcription failed\", error);\n\n // Show contextual error message based on error type\n if (error instanceof TranscriptionError) {\n const { code, retryable, message } = error.info;\n switch (code) {\n case TranscriptionErrorCode.RATE_LIMITED:\n setTranscriptionError(\"Too many requests. Please wait a moment.\");\n break;\n case TranscriptionErrorCode.AUTH_FAILED:\n setTranscriptionError(\n \"Authentication error. Please check your configuration.\",\n );\n break;\n case TranscriptionErrorCode.AUDIO_TOO_LONG:\n setTranscriptionError(\n \"Recording is too long. Please try a shorter recording.\",\n );\n break;\n case TranscriptionErrorCode.AUDIO_TOO_SHORT:\n setTranscriptionError(\n \"Recording is too short. Please try again.\",\n );\n break;\n case TranscriptionErrorCode.INVALID_AUDIO_FORMAT:\n setTranscriptionError(\"Audio format not supported.\");\n break;\n case TranscriptionErrorCode.SERVICE_NOT_CONFIGURED:\n setTranscriptionError(\"Transcription service is not available.\");\n break;\n case TranscriptionErrorCode.NETWORK_ERROR:\n setTranscriptionError(\n \"Network error. Please check your connection.\",\n );\n break;\n default:\n // For retryable errors, show more helpful message\n setTranscriptionError(\n retryable ? \"Transcription failed. Please try again.\" : message,\n );\n }\n } else {\n // Fallback for unexpected errors\n setTranscriptionError(\"Transcription failed. Please try again.\");\n }\n } finally {\n setIsTranscribing(false);\n }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [],\n );\n\n // Clear transcription error after a delay\n useEffect(() => {\n if (transcriptionError) {\n const timer = setTimeout(() => {\n setTranscriptionError(null);\n }, 5000);\n return () => clearTimeout(timer);\n }\n }, [transcriptionError]);\n\n const mergedProps = merge(\n {\n isRunning: agent.isRunning,\n suggestions: autoSuggestions,\n onSelectSuggestion: handleSelectSuggestion,\n suggestionView: providedSuggestionView,\n },\n {\n ...restProps,\n ...(typeof providedMessageView === \"string\"\n ? { messageView: { className: providedMessageView } }\n : providedMessageView !== undefined\n ? { messageView: providedMessageView }\n : {}),\n },\n );\n\n const hasMessages = agent.messages.length > 0;\n const shouldAllowStop = agent.isRunning && hasMessages;\n const effectiveStopHandler = shouldAllowStop\n ? (providedStopHandler ?? stopCurrentRun)\n : providedStopHandler;\n\n // Determine if transcription feature should be available\n const showTranscription = isTranscriptionEnabled && isMediaRecorderSupported;\n\n // Determine mode: transcribing takes priority, then transcribe mode, then default to input\n const effectiveMode: CopilotChatInputMode = isTranscribing\n ? \"processing\"\n : transcribeMode;\n\n // Memoize messages array - only create new reference when content actually changes\n // (agent.messages is mutated in place, so we need a new reference for React to detect changes)\n\n const messages = useMemo(\n () => [...agent.messages],\n [JSON.stringify(agent.messages)],\n );\n\n const finalProps = merge(mergedProps, {\n messages,\n // Input behavior props\n onSubmitMessage: onSubmitInput,\n onStop: effectiveStopHandler,\n inputMode: effectiveMode,\n inputValue,\n onInputChange: setInputValue,\n // Only provide transcription handlers if feature is available\n onStartTranscribe: showTranscription ? handleStartTranscribe : undefined,\n onCancelTranscribe: showTranscription ? handleCancelTranscribe : undefined,\n onFinishTranscribe: showTranscription ? handleFinishTranscribe : undefined,\n onFinishTranscribeWithAudio: showTranscription\n ? handleFinishTranscribeWithAudio\n : undefined,\n }) as CopilotChatViewProps;\n\n // Always create a provider with merged values\n // This ensures priority: props > existing config > defaults\n const RenderedChatView = renderSlot(chatView, CopilotChatView, finalProps);\n\n return (\n <CopilotChatConfigurationProvider\n agentId={resolvedAgentId}\n threadId={resolvedThreadId}\n labels={labels}\n >\n {transcriptionError && (\n <div\n style={{\n position: \"absolute\",\n bottom: \"100px\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n backgroundColor: \"#ef4444\",\n color: \"white\",\n padding: \"8px 16px\",\n borderRadius: \"8px\",\n fontSize: \"14px\",\n zIndex: 50,\n }}\n >\n {transcriptionError}\n </div>\n )}\n {RenderedChatView}\n </CopilotChatConfigurationProvider>\n );\n}\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace CopilotChat {\n export const View = CopilotChatView;\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"CopilotChat.d.cts","names":[],"sources":["../../../src/components/chat/CopilotChat.tsx"],"mappings":";;;;;;KAyBY,gBAAA,GAAmB,IAAA,CAC7B,oBAAA;EAOA,OAAA;EACA,QAAA;EACA,MAAA,GAAS,OAAA,CAAQ,iBAAA;EACjB,QAAA,GAAW,SAAA,QAAiB,eAAA;AAAA;AAAA,iBAEd,WAAA,CAAA;EACd,OAAA;EACA,QAAA;EACA,MAAA;EACA,QAAA;EAAA,GACG;AAAA,GACF,gBAAA,GAAgB,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,kBAuSF,WAAA;EAAA,MACF,IAAA,SAAI,eAAA;AAAA"}
1
+ {"version":3,"file":"CopilotChat.d.cts","names":[],"sources":["../../../src/components/chat/CopilotChat.tsx"],"mappings":";;;;;;KA6BY,gBAAA,GAAmB,IAAA,CAC7B,oBAAA;EAOA,OAAA;EACA,QAAA;EACA,MAAA,GAAS,OAAA,CAAQ,iBAAA;EACjB,QAAA,GAAW,SAAA,QAAiB,eAAA;AAAA;AAAA,iBAEd,WAAA,CAAA;EACd,OAAA;EACA,QAAA;EACA,MAAA;EACA,QAAA;EAAA,GACG;AAAA,GACF,gBAAA,GAAgB,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,kBAkUF,WAAA;EAAA,MACF,IAAA,SAAI,eAAA;AAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"CopilotChat.d.mts","names":[],"sources":["../../../src/components/chat/CopilotChat.tsx"],"mappings":";;;;;;KAyBY,gBAAA,GAAmB,IAAA,CAC7B,oBAAA;EAOA,OAAA;EACA,QAAA;EACA,MAAA,GAAS,OAAA,CAAQ,iBAAA;EACjB,QAAA,GAAW,SAAA,QAAiB,eAAA;AAAA;AAAA,iBAEd,WAAA,CAAA;EACd,OAAA;EACA,QAAA;EACA,MAAA;EACA,QAAA;EAAA,GACG;AAAA,GACF,gBAAA,GAAgB,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,kBAuSF,WAAA;EAAA,MACF,IAAA,SAAI,eAAA;AAAA"}
1
+ {"version":3,"file":"CopilotChat.d.mts","names":[],"sources":["../../../src/components/chat/CopilotChat.tsx"],"mappings":";;;;;;KA6BY,gBAAA,GAAmB,IAAA,CAC7B,oBAAA;EAOA,OAAA;EACA,QAAA;EACA,MAAA,GAAS,OAAA,CAAQ,iBAAA;EACjB,QAAA,GAAW,SAAA,QAAiB,eAAA;AAAA;AAAA,iBAEd,WAAA,CAAA;EACd,OAAA;EACA,QAAA;EACA,MAAA;EACA,QAAA;EAAA,GACG;AAAA,GACF,gBAAA,GAAgB,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,kBAkUF,WAAA;EAAA,MACF,IAAA,SAAI,eAAA;AAAA"}
@@ -5,7 +5,7 @@ import { useAgent } from "../../hooks/use-agent.mjs";
5
5
  import { useSuggestions } from "../../hooks/use-suggestions.mjs";
6
6
  import { CopilotChatView } from "./CopilotChatView.mjs";
7
7
  import { TranscriptionError, transcribeAudio } from "../../lib/transcription-client.mjs";
8
- import { AGUIConnectNotImplementedError } from "@ag-ui/client";
8
+ import { AGUIConnectNotImplementedError, HttpAgent } from "@ag-ui/client";
9
9
  import { useCallback, useEffect, useMemo, useState } from "react";
10
10
  import { DEFAULT_AGENT_ID, TranscriptionErrorCode, randomUUID } from "@copilotkitnext/shared";
11
11
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -27,20 +27,27 @@ function CopilotChat({ agentId, threadId, labels, chatView, ...props }) {
27
27
  const isMediaRecorderSupported = typeof window !== "undefined" && typeof MediaRecorder !== "undefined";
28
28
  const { messageView: providedMessageView, suggestionView: providedSuggestionView, onStop: providedStopHandler, ...restProps } = props;
29
29
  useEffect(() => {
30
+ let detached = false;
31
+ const connectAbortController = new AbortController();
32
+ if (agent instanceof HttpAgent) agent.abortController = connectAbortController;
30
33
  const connect = async (agent) => {
31
34
  try {
32
35
  await copilotkit.connectAgent({ agent });
33
36
  } catch (error) {
37
+ if (detached) return;
34
38
  if (error instanceof AGUIConnectNotImplementedError) {} else throw error;
35
39
  }
36
40
  };
37
41
  agent.threadId = resolvedThreadId;
38
42
  connect(agent);
39
- return () => {};
43
+ return () => {
44
+ detached = true;
45
+ connectAbortController.abort();
46
+ agent.detachActiveRun();
47
+ };
40
48
  }, [
41
49
  resolvedThreadId,
42
50
  agent,
43
- copilotkit,
44
51
  resolvedAgentId
45
52
  ]);
46
53
  const onSubmitInput = useCallback(async (value) => {
@@ -55,7 +62,7 @@ function CopilotChat({ agentId, threadId, labels, chatView, ...props }) {
55
62
  } catch (error) {
56
63
  console.error("CopilotChat: runAgent failed", error);
57
64
  }
58
- }, [agent, copilotkit]);
65
+ }, [agent]);
59
66
  const handleSelectSuggestion = useCallback(async (suggestion) => {
60
67
  agent.addMessage({
61
68
  id: randomUUID(),
@@ -67,7 +74,7 @@ function CopilotChat({ agentId, threadId, labels, chatView, ...props }) {
67
74
  } catch (error) {
68
75
  console.error("CopilotChat: runAgent failed after selecting suggestion", error);
69
76
  }
70
- }, [agent, copilotkit]);
77
+ }, [agent]);
71
78
  const stopCurrentRun = useCallback(() => {
72
79
  try {
73
80
  copilotkit.stopAgent({ agent });
@@ -79,7 +86,7 @@ function CopilotChat({ agentId, threadId, labels, chatView, ...props }) {
79
86
  console.error("CopilotChat: abortRun fallback failed", abortError);
80
87
  }
81
88
  }
82
- }, [agent, copilotkit]);
89
+ }, [agent]);
83
90
  const handleStartTranscribe = useCallback(() => {
84
91
  setTranscriptionError(null);
85
92
  setTranscribeMode("transcribe");
@@ -133,7 +140,7 @@ function CopilotChat({ agentId, threadId, labels, chatView, ...props }) {
133
140
  } finally {
134
141
  setIsTranscribing(false);
135
142
  }
136
- }, [copilotkit]);
143
+ }, []);
137
144
  useEffect(() => {
138
145
  if (transcriptionError) {
139
146
  const timer = setTimeout(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"CopilotChat.mjs","names":[],"sources":["../../../src/components/chat/CopilotChat.tsx"],"sourcesContent":["import { useAgent } from \"@/hooks/use-agent\";\nimport { useSuggestions } from \"@/hooks/use-suggestions\";\nimport { CopilotChatView, CopilotChatViewProps } from \"./CopilotChatView\";\nimport { CopilotChatInputMode } from \"./CopilotChatInput\";\nimport {\n CopilotChatConfigurationProvider,\n CopilotChatLabels,\n useCopilotChatConfiguration,\n} from \"@/providers/CopilotChatConfigurationProvider\";\nimport {\n DEFAULT_AGENT_ID,\n randomUUID,\n TranscriptionErrorCode,\n} from \"@copilotkitnext/shared\";\nimport { Suggestion, CopilotKitCoreErrorCode } from \"@copilotkitnext/core\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { merge } from \"ts-deepmerge\";\nimport { useCopilotKit } from \"@/providers/CopilotKitProvider\";\nimport { AbstractAgent, AGUIConnectNotImplementedError } from \"@ag-ui/client\";\nimport { renderSlot, SlotValue } from \"@/lib/slots\";\nimport {\n transcribeAudio,\n TranscriptionError,\n} from \"@/lib/transcription-client\";\n\nexport type CopilotChatProps = Omit<\n CopilotChatViewProps,\n | \"messages\"\n | \"isRunning\"\n | \"suggestions\"\n | \"suggestionLoadingIndexes\"\n | \"onSelectSuggestion\"\n> & {\n agentId?: string;\n threadId?: string;\n labels?: Partial<CopilotChatLabels>;\n chatView?: SlotValue<typeof CopilotChatView>;\n};\nexport function CopilotChat({\n agentId,\n threadId,\n labels,\n chatView,\n ...props\n}: CopilotChatProps) {\n // Check for existing configuration provider\n const existingConfig = useCopilotChatConfiguration();\n\n // Apply priority: props > existing config > defaults\n const resolvedAgentId =\n agentId ?? existingConfig?.agentId ?? DEFAULT_AGENT_ID;\n const resolvedThreadId = useMemo(\n () => threadId ?? existingConfig?.threadId ?? randomUUID(),\n [threadId, existingConfig?.threadId],\n );\n\n const { agent } = useAgent({ agentId: resolvedAgentId });\n const { copilotkit } = useCopilotKit();\n const { suggestions: autoSuggestions } = useSuggestions({\n agentId: resolvedAgentId,\n });\n\n // Transcription state\n const [transcribeMode, setTranscribeMode] =\n useState<CopilotChatInputMode>(\"input\");\n const [inputValue, setInputValue] = useState(\"\");\n const [transcriptionError, setTranscriptionError] = useState<string | null>(\n null,\n );\n const [isTranscribing, setIsTranscribing] = useState(false);\n\n // Check if transcription is enabled\n const isTranscriptionEnabled = copilotkit.audioFileTranscriptionEnabled;\n\n // Check if browser supports MediaRecorder\n const isMediaRecorderSupported =\n typeof window !== \"undefined\" && typeof MediaRecorder !== \"undefined\";\n\n const {\n messageView: providedMessageView,\n suggestionView: providedSuggestionView,\n onStop: providedStopHandler,\n ...restProps\n } = props;\n\n useEffect(() => {\n const connect = async (agent: AbstractAgent) => {\n try {\n await copilotkit.connectAgent({ agent });\n } catch (error) {\n if (error instanceof AGUIConnectNotImplementedError) {\n // connect not implemented, ignore\n } else {\n throw error;\n }\n }\n };\n agent.threadId = resolvedThreadId;\n connect(agent);\n return () => {};\n }, [resolvedThreadId, agent, copilotkit, resolvedAgentId]);\n\n const onSubmitInput = useCallback(\n async (value: string) => {\n agent.addMessage({\n id: randomUUID(),\n role: \"user\",\n content: value,\n });\n // Clear input after submitting\n setInputValue(\"\");\n try {\n await copilotkit.runAgent({ agent });\n } catch (error) {\n console.error(\"CopilotChat: runAgent failed\", error);\n }\n },\n [agent, copilotkit],\n );\n\n const handleSelectSuggestion = useCallback(\n async (suggestion: Suggestion) => {\n agent.addMessage({\n id: randomUUID(),\n role: \"user\",\n content: suggestion.message,\n });\n\n try {\n await copilotkit.runAgent({ agent });\n } catch (error) {\n console.error(\n \"CopilotChat: runAgent failed after selecting suggestion\",\n error,\n );\n }\n },\n [agent, copilotkit],\n );\n\n const stopCurrentRun = useCallback(() => {\n try {\n copilotkit.stopAgent({ agent });\n } catch (error) {\n console.error(\"CopilotChat: stopAgent failed\", error);\n try {\n agent.abortRun();\n } catch (abortError) {\n console.error(\"CopilotChat: abortRun fallback failed\", abortError);\n }\n }\n }, [agent, copilotkit]);\n\n // Transcription handlers\n const handleStartTranscribe = useCallback(() => {\n setTranscriptionError(null);\n setTranscribeMode(\"transcribe\");\n }, []);\n\n const handleCancelTranscribe = useCallback(() => {\n setTranscriptionError(null);\n setTranscribeMode(\"input\");\n }, []);\n\n const handleFinishTranscribe = useCallback(() => {\n setTranscribeMode(\"input\");\n }, []);\n\n // Handle audio blob from CopilotChatInput and transcribe it\n const handleFinishTranscribeWithAudio = useCallback(\n async (audioBlob: Blob) => {\n setIsTranscribing(true);\n try {\n setTranscriptionError(null);\n\n // Send to transcription endpoint\n const result = await transcribeAudio(copilotkit, audioBlob);\n\n // Insert transcribed text into input\n setInputValue((prev) => {\n const trimmedPrev = prev.trim();\n if (trimmedPrev) {\n return `${trimmedPrev} ${result.text}`;\n }\n return result.text;\n });\n } catch (error) {\n console.error(\"CopilotChat: Transcription failed\", error);\n\n // Show contextual error message based on error type\n if (error instanceof TranscriptionError) {\n const { code, retryable, message } = error.info;\n switch (code) {\n case TranscriptionErrorCode.RATE_LIMITED:\n setTranscriptionError(\"Too many requests. Please wait a moment.\");\n break;\n case TranscriptionErrorCode.AUTH_FAILED:\n setTranscriptionError(\n \"Authentication error. Please check your configuration.\",\n );\n break;\n case TranscriptionErrorCode.AUDIO_TOO_LONG:\n setTranscriptionError(\n \"Recording is too long. Please try a shorter recording.\",\n );\n break;\n case TranscriptionErrorCode.AUDIO_TOO_SHORT:\n setTranscriptionError(\n \"Recording is too short. Please try again.\",\n );\n break;\n case TranscriptionErrorCode.INVALID_AUDIO_FORMAT:\n setTranscriptionError(\"Audio format not supported.\");\n break;\n case TranscriptionErrorCode.SERVICE_NOT_CONFIGURED:\n setTranscriptionError(\"Transcription service is not available.\");\n break;\n case TranscriptionErrorCode.NETWORK_ERROR:\n setTranscriptionError(\n \"Network error. Please check your connection.\",\n );\n break;\n default:\n // For retryable errors, show more helpful message\n setTranscriptionError(\n retryable ? \"Transcription failed. Please try again.\" : message,\n );\n }\n } else {\n // Fallback for unexpected errors\n setTranscriptionError(\"Transcription failed. Please try again.\");\n }\n } finally {\n setIsTranscribing(false);\n }\n },\n [copilotkit],\n );\n\n // Clear transcription error after a delay\n useEffect(() => {\n if (transcriptionError) {\n const timer = setTimeout(() => {\n setTranscriptionError(null);\n }, 5000);\n return () => clearTimeout(timer);\n }\n }, [transcriptionError]);\n\n const mergedProps = merge(\n {\n isRunning: agent.isRunning,\n suggestions: autoSuggestions,\n onSelectSuggestion: handleSelectSuggestion,\n suggestionView: providedSuggestionView,\n },\n {\n ...restProps,\n ...(typeof providedMessageView === \"string\"\n ? { messageView: { className: providedMessageView } }\n : providedMessageView !== undefined\n ? { messageView: providedMessageView }\n : {}),\n },\n );\n\n const hasMessages = agent.messages.length > 0;\n const shouldAllowStop = agent.isRunning && hasMessages;\n const effectiveStopHandler = shouldAllowStop\n ? (providedStopHandler ?? stopCurrentRun)\n : providedStopHandler;\n\n // Determine if transcription feature should be available\n const showTranscription = isTranscriptionEnabled && isMediaRecorderSupported;\n\n // Determine mode: transcribing takes priority, then transcribe mode, then default to input\n const effectiveMode: CopilotChatInputMode = isTranscribing\n ? \"processing\"\n : transcribeMode;\n\n // Memoize messages array - only create new reference when content actually changes\n // (agent.messages is mutated in place, so we need a new reference for React to detect changes)\n\n const messages = useMemo(\n () => [...agent.messages],\n [JSON.stringify(agent.messages)],\n );\n\n const finalProps = merge(mergedProps, {\n messages,\n // Input behavior props\n onSubmitMessage: onSubmitInput,\n onStop: effectiveStopHandler,\n inputMode: effectiveMode,\n inputValue,\n onInputChange: setInputValue,\n // Only provide transcription handlers if feature is available\n onStartTranscribe: showTranscription ? handleStartTranscribe : undefined,\n onCancelTranscribe: showTranscription ? handleCancelTranscribe : undefined,\n onFinishTranscribe: showTranscription ? handleFinishTranscribe : undefined,\n onFinishTranscribeWithAudio: showTranscription\n ? handleFinishTranscribeWithAudio\n : undefined,\n }) as CopilotChatViewProps;\n\n // Always create a provider with merged values\n // This ensures priority: props > existing config > defaults\n const RenderedChatView = renderSlot(chatView, CopilotChatView, finalProps);\n\n return (\n <CopilotChatConfigurationProvider\n agentId={resolvedAgentId}\n threadId={resolvedThreadId}\n labels={labels}\n >\n {transcriptionError && (\n <div\n style={{\n position: \"absolute\",\n bottom: \"100px\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n backgroundColor: \"#ef4444\",\n color: \"white\",\n padding: \"8px 16px\",\n borderRadius: \"8px\",\n fontSize: \"14px\",\n zIndex: 50,\n }}\n >\n {transcriptionError}\n </div>\n )}\n {RenderedChatView}\n </CopilotChatConfigurationProvider>\n );\n}\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace CopilotChat {\n export const View = CopilotChatView;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"CopilotChat.mjs","names":[],"sources":["../../../src/components/chat/CopilotChat.tsx"],"sourcesContent":["import { useAgent } from \"@/hooks/use-agent\";\nimport { useSuggestions } from \"@/hooks/use-suggestions\";\nimport { CopilotChatView, CopilotChatViewProps } from \"./CopilotChatView\";\nimport { CopilotChatInputMode } from \"./CopilotChatInput\";\nimport {\n CopilotChatConfigurationProvider,\n CopilotChatLabels,\n useCopilotChatConfiguration,\n} from \"@/providers/CopilotChatConfigurationProvider\";\nimport {\n DEFAULT_AGENT_ID,\n randomUUID,\n TranscriptionErrorCode,\n} from \"@copilotkitnext/shared\";\nimport { Suggestion, CopilotKitCoreErrorCode } from \"@copilotkitnext/core\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { merge } from \"ts-deepmerge\";\nimport { useCopilotKit } from \"@/providers/CopilotKitProvider\";\nimport {\n AbstractAgent,\n AGUIConnectNotImplementedError,\n HttpAgent,\n} from \"@ag-ui/client\";\nimport { renderSlot, SlotValue } from \"@/lib/slots\";\nimport {\n transcribeAudio,\n TranscriptionError,\n} from \"@/lib/transcription-client\";\n\nexport type CopilotChatProps = Omit<\n CopilotChatViewProps,\n | \"messages\"\n | \"isRunning\"\n | \"suggestions\"\n | \"suggestionLoadingIndexes\"\n | \"onSelectSuggestion\"\n> & {\n agentId?: string;\n threadId?: string;\n labels?: Partial<CopilotChatLabels>;\n chatView?: SlotValue<typeof CopilotChatView>;\n};\nexport function CopilotChat({\n agentId,\n threadId,\n labels,\n chatView,\n ...props\n}: CopilotChatProps) {\n // Check for existing configuration provider\n const existingConfig = useCopilotChatConfiguration();\n\n // Apply priority: props > existing config > defaults\n const resolvedAgentId =\n agentId ?? existingConfig?.agentId ?? DEFAULT_AGENT_ID;\n const resolvedThreadId = useMemo(\n () => threadId ?? existingConfig?.threadId ?? randomUUID(),\n [threadId, existingConfig?.threadId],\n );\n\n const { agent } = useAgent({ agentId: resolvedAgentId });\n const { copilotkit } = useCopilotKit();\n const { suggestions: autoSuggestions } = useSuggestions({\n agentId: resolvedAgentId,\n });\n\n // Transcription state\n const [transcribeMode, setTranscribeMode] =\n useState<CopilotChatInputMode>(\"input\");\n const [inputValue, setInputValue] = useState(\"\");\n const [transcriptionError, setTranscriptionError] = useState<string | null>(\n null,\n );\n const [isTranscribing, setIsTranscribing] = useState(false);\n\n // Check if transcription is enabled\n const isTranscriptionEnabled = copilotkit.audioFileTranscriptionEnabled;\n\n // Check if browser supports MediaRecorder\n const isMediaRecorderSupported =\n typeof window !== \"undefined\" && typeof MediaRecorder !== \"undefined\";\n\n const {\n messageView: providedMessageView,\n suggestionView: providedSuggestionView,\n onStop: providedStopHandler,\n ...restProps\n } = props;\n\n useEffect(() => {\n let detached = false;\n\n // Create a fresh AbortController so we can cancel the HTTP request on cleanup.\n // HttpAgent (parent of ProxiedCopilotRuntimeAgent) uses this.abortController.signal\n // in its fetch config. Unlike runAgent(), connectAgent() does NOT create a new\n // AbortController automatically, so we must set one before connecting.\n const connectAbortController = new AbortController();\n if (agent instanceof HttpAgent) {\n agent.abortController = connectAbortController;\n }\n\n const connect = async (agent: AbstractAgent) => {\n try {\n await copilotkit.connectAgent({ agent });\n } catch (error) {\n // Ignore errors from aborted connections (e.g., React StrictMode cleanup)\n if (detached) return;\n if (error instanceof AGUIConnectNotImplementedError) {\n // connect not implemented, ignore\n } else {\n throw error;\n }\n }\n };\n agent.threadId = resolvedThreadId;\n connect(agent);\n return () => {\n // Abort the HTTP request and detach the active run.\n // This is critical for React StrictMode which unmounts+remounts in dev,\n // preventing duplicate /connect requests from reaching the server.\n detached = true;\n connectAbortController.abort();\n agent.detachActiveRun();\n };\n // copilotkit is intentionally excluded — it is a stable ref that never changes.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [resolvedThreadId, agent, resolvedAgentId]);\n\n const onSubmitInput = useCallback(\n async (value: string) => {\n agent.addMessage({\n id: randomUUID(),\n role: \"user\",\n content: value,\n });\n // Clear input after submitting\n setInputValue(\"\");\n try {\n await copilotkit.runAgent({ agent });\n } catch (error) {\n console.error(\"CopilotChat: runAgent failed\", error);\n }\n },\n // copilotkit is intentionally excluded — it is a stable ref that never changes.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [agent],\n );\n\n const handleSelectSuggestion = useCallback(\n async (suggestion: Suggestion) => {\n agent.addMessage({\n id: randomUUID(),\n role: \"user\",\n content: suggestion.message,\n });\n\n try {\n await copilotkit.runAgent({ agent });\n } catch (error) {\n console.error(\n \"CopilotChat: runAgent failed after selecting suggestion\",\n error,\n );\n }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [agent],\n );\n\n const stopCurrentRun = useCallback(() => {\n try {\n copilotkit.stopAgent({ agent });\n } catch (error) {\n console.error(\"CopilotChat: stopAgent failed\", error);\n try {\n agent.abortRun();\n } catch (abortError) {\n console.error(\"CopilotChat: abortRun fallback failed\", abortError);\n }\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [agent]);\n\n // Transcription handlers\n const handleStartTranscribe = useCallback(() => {\n setTranscriptionError(null);\n setTranscribeMode(\"transcribe\");\n }, []);\n\n const handleCancelTranscribe = useCallback(() => {\n setTranscriptionError(null);\n setTranscribeMode(\"input\");\n }, []);\n\n const handleFinishTranscribe = useCallback(() => {\n setTranscribeMode(\"input\");\n }, []);\n\n // Handle audio blob from CopilotChatInput and transcribe it\n const handleFinishTranscribeWithAudio = useCallback(\n async (audioBlob: Blob) => {\n setIsTranscribing(true);\n try {\n setTranscriptionError(null);\n\n // Send to transcription endpoint\n const result = await transcribeAudio(copilotkit, audioBlob);\n\n // Insert transcribed text into input\n setInputValue((prev) => {\n const trimmedPrev = prev.trim();\n if (trimmedPrev) {\n return `${trimmedPrev} ${result.text}`;\n }\n return result.text;\n });\n } catch (error) {\n console.error(\"CopilotChat: Transcription failed\", error);\n\n // Show contextual error message based on error type\n if (error instanceof TranscriptionError) {\n const { code, retryable, message } = error.info;\n switch (code) {\n case TranscriptionErrorCode.RATE_LIMITED:\n setTranscriptionError(\"Too many requests. Please wait a moment.\");\n break;\n case TranscriptionErrorCode.AUTH_FAILED:\n setTranscriptionError(\n \"Authentication error. Please check your configuration.\",\n );\n break;\n case TranscriptionErrorCode.AUDIO_TOO_LONG:\n setTranscriptionError(\n \"Recording is too long. Please try a shorter recording.\",\n );\n break;\n case TranscriptionErrorCode.AUDIO_TOO_SHORT:\n setTranscriptionError(\n \"Recording is too short. Please try again.\",\n );\n break;\n case TranscriptionErrorCode.INVALID_AUDIO_FORMAT:\n setTranscriptionError(\"Audio format not supported.\");\n break;\n case TranscriptionErrorCode.SERVICE_NOT_CONFIGURED:\n setTranscriptionError(\"Transcription service is not available.\");\n break;\n case TranscriptionErrorCode.NETWORK_ERROR:\n setTranscriptionError(\n \"Network error. Please check your connection.\",\n );\n break;\n default:\n // For retryable errors, show more helpful message\n setTranscriptionError(\n retryable ? \"Transcription failed. Please try again.\" : message,\n );\n }\n } else {\n // Fallback for unexpected errors\n setTranscriptionError(\"Transcription failed. Please try again.\");\n }\n } finally {\n setIsTranscribing(false);\n }\n },\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [],\n );\n\n // Clear transcription error after a delay\n useEffect(() => {\n if (transcriptionError) {\n const timer = setTimeout(() => {\n setTranscriptionError(null);\n }, 5000);\n return () => clearTimeout(timer);\n }\n }, [transcriptionError]);\n\n const mergedProps = merge(\n {\n isRunning: agent.isRunning,\n suggestions: autoSuggestions,\n onSelectSuggestion: handleSelectSuggestion,\n suggestionView: providedSuggestionView,\n },\n {\n ...restProps,\n ...(typeof providedMessageView === \"string\"\n ? { messageView: { className: providedMessageView } }\n : providedMessageView !== undefined\n ? { messageView: providedMessageView }\n : {}),\n },\n );\n\n const hasMessages = agent.messages.length > 0;\n const shouldAllowStop = agent.isRunning && hasMessages;\n const effectiveStopHandler = shouldAllowStop\n ? (providedStopHandler ?? stopCurrentRun)\n : providedStopHandler;\n\n // Determine if transcription feature should be available\n const showTranscription = isTranscriptionEnabled && isMediaRecorderSupported;\n\n // Determine mode: transcribing takes priority, then transcribe mode, then default to input\n const effectiveMode: CopilotChatInputMode = isTranscribing\n ? \"processing\"\n : transcribeMode;\n\n // Memoize messages array - only create new reference when content actually changes\n // (agent.messages is mutated in place, so we need a new reference for React to detect changes)\n\n const messages = useMemo(\n () => [...agent.messages],\n [JSON.stringify(agent.messages)],\n );\n\n const finalProps = merge(mergedProps, {\n messages,\n // Input behavior props\n onSubmitMessage: onSubmitInput,\n onStop: effectiveStopHandler,\n inputMode: effectiveMode,\n inputValue,\n onInputChange: setInputValue,\n // Only provide transcription handlers if feature is available\n onStartTranscribe: showTranscription ? handleStartTranscribe : undefined,\n onCancelTranscribe: showTranscription ? handleCancelTranscribe : undefined,\n onFinishTranscribe: showTranscription ? handleFinishTranscribe : undefined,\n onFinishTranscribeWithAudio: showTranscription\n ? handleFinishTranscribeWithAudio\n : undefined,\n }) as CopilotChatViewProps;\n\n // Always create a provider with merged values\n // This ensures priority: props > existing config > defaults\n const RenderedChatView = renderSlot(chatView, CopilotChatView, finalProps);\n\n return (\n <CopilotChatConfigurationProvider\n agentId={resolvedAgentId}\n threadId={resolvedThreadId}\n labels={labels}\n >\n {transcriptionError && (\n <div\n style={{\n position: \"absolute\",\n bottom: \"100px\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n backgroundColor: \"#ef4444\",\n color: \"white\",\n padding: \"8px 16px\",\n borderRadius: \"8px\",\n fontSize: \"14px\",\n zIndex: 50,\n }}\n >\n {transcriptionError}\n </div>\n )}\n {RenderedChatView}\n </CopilotChatConfigurationProvider>\n );\n}\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace CopilotChat {\n export const View = CopilotChatView;\n}\n"],"mappings":"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"}
@@ -69,7 +69,7 @@ function CopilotChatAssistantMessage({ message, messages, isRunning, onThumbsUp,
69
69
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
70
70
  "data-copilotkit": true,
71
71
  "data-testid": "copilot-assistant-message",
72
- className: (0, tailwind_merge.twMerge)(className),
72
+ className: (0, tailwind_merge.twMerge)("copilotKitMessage copilotKitAssistantMessage", className),
73
73
  ...props,
74
74
  "data-message-id": message.id,
75
75
  children: [
@@ -1 +1 @@
1
- {"version":3,"file":"CopilotChatAssistantMessage.cjs","names":["renderSlot","CopilotChatToolCallsView","Streamdown","Tooltip","TooltipTrigger","Button","TooltipContent","useCopilotChatConfiguration","CopilotChatDefaultLabels","Check","Copy","ThumbsUp","ThumbsDown","Volume2","RefreshCw"],"sources":["../../../src/components/chat/CopilotChatAssistantMessage.tsx"],"sourcesContent":["import { AssistantMessage, Message } from \"@ag-ui/core\";\nimport { useState } from \"react\";\nimport {\n Copy,\n Check,\n ThumbsUp,\n ThumbsDown,\n Volume2,\n RefreshCw,\n} from \"lucide-react\";\nimport {\n useCopilotChatConfiguration,\n CopilotChatDefaultLabels,\n} from \"@/providers/CopilotChatConfigurationProvider\";\nimport { twMerge } from \"tailwind-merge\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport \"katex/dist/katex.min.css\";\nimport { WithSlots, renderSlot } from \"@/lib/slots\";\nimport { Streamdown } from \"streamdown\";\nimport CopilotChatToolCallsView from \"./CopilotChatToolCallsView\";\n\nexport type CopilotChatAssistantMessageProps = WithSlots<\n {\n markdownRenderer: typeof CopilotChatAssistantMessage.MarkdownRenderer;\n toolbar: typeof CopilotChatAssistantMessage.Toolbar;\n copyButton: typeof CopilotChatAssistantMessage.CopyButton;\n thumbsUpButton: typeof CopilotChatAssistantMessage.ThumbsUpButton;\n thumbsDownButton: typeof CopilotChatAssistantMessage.ThumbsDownButton;\n readAloudButton: typeof CopilotChatAssistantMessage.ReadAloudButton;\n regenerateButton: typeof CopilotChatAssistantMessage.RegenerateButton;\n toolCallsView: typeof CopilotChatToolCallsView;\n },\n {\n onThumbsUp?: (message: AssistantMessage) => void;\n onThumbsDown?: (message: AssistantMessage) => void;\n onReadAloud?: (message: AssistantMessage) => void;\n onRegenerate?: (message: AssistantMessage) => void;\n message: AssistantMessage;\n messages?: Message[];\n isRunning?: boolean;\n additionalToolbarItems?: React.ReactNode;\n toolbarVisible?: boolean;\n } & React.HTMLAttributes<HTMLDivElement>\n>;\n\nexport function CopilotChatAssistantMessage({\n message,\n messages,\n isRunning,\n onThumbsUp,\n onThumbsDown,\n onReadAloud,\n onRegenerate,\n additionalToolbarItems,\n toolbarVisible = true,\n markdownRenderer,\n toolbar,\n copyButton,\n thumbsUpButton,\n thumbsDownButton,\n readAloudButton,\n regenerateButton,\n toolCallsView,\n children,\n className,\n ...props\n}: CopilotChatAssistantMessageProps) {\n const boundMarkdownRenderer = renderSlot(\n markdownRenderer,\n CopilotChatAssistantMessage.MarkdownRenderer,\n {\n content: message.content || \"\",\n },\n );\n\n const boundCopyButton = renderSlot(\n copyButton,\n CopilotChatAssistantMessage.CopyButton,\n {\n onClick: async () => {\n if (message.content) {\n try {\n await navigator.clipboard.writeText(message.content);\n } catch (err) {\n console.error(\"Failed to copy message:\", err);\n }\n }\n },\n },\n );\n\n const boundThumbsUpButton = renderSlot(\n thumbsUpButton,\n CopilotChatAssistantMessage.ThumbsUpButton,\n {\n onClick: onThumbsUp,\n },\n );\n\n const boundThumbsDownButton = renderSlot(\n thumbsDownButton,\n CopilotChatAssistantMessage.ThumbsDownButton,\n {\n onClick: onThumbsDown,\n },\n );\n\n const boundReadAloudButton = renderSlot(\n readAloudButton,\n CopilotChatAssistantMessage.ReadAloudButton,\n {\n onClick: onReadAloud,\n },\n );\n\n const boundRegenerateButton = renderSlot(\n regenerateButton,\n CopilotChatAssistantMessage.RegenerateButton,\n {\n onClick: onRegenerate,\n },\n );\n\n const boundToolbar = renderSlot(\n toolbar,\n CopilotChatAssistantMessage.Toolbar,\n {\n children: (\n <div className=\"cpk:flex cpk:items-center cpk:gap-1\">\n {boundCopyButton}\n {(onThumbsUp || thumbsUpButton) && boundThumbsUpButton}\n {(onThumbsDown || thumbsDownButton) && boundThumbsDownButton}\n {(onReadAloud || readAloudButton) && boundReadAloudButton}\n {(onRegenerate || regenerateButton) && boundRegenerateButton}\n {additionalToolbarItems}\n </div>\n ),\n },\n );\n\n const boundToolCallsView = renderSlot(\n toolCallsView,\n CopilotChatToolCallsView,\n {\n message,\n messages,\n },\n );\n\n // Don't show toolbar if message has no content (only tool calls)\n const hasContent = !!(message.content && message.content.trim().length > 0);\n const isLatestAssistantMessage =\n message.role === \"assistant\" &&\n messages?.[messages.length - 1]?.id === message.id;\n const shouldShowToolbar =\n toolbarVisible && hasContent && !(isRunning && isLatestAssistantMessage);\n\n if (children) {\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {children({\n markdownRenderer: boundMarkdownRenderer,\n toolbar: boundToolbar,\n toolCallsView: boundToolCallsView,\n copyButton: boundCopyButton,\n thumbsUpButton: boundThumbsUpButton,\n thumbsDownButton: boundThumbsDownButton,\n readAloudButton: boundReadAloudButton,\n regenerateButton: boundRegenerateButton,\n message,\n messages,\n isRunning,\n onThumbsUp,\n onThumbsDown,\n onReadAloud,\n onRegenerate,\n additionalToolbarItems,\n toolbarVisible: shouldShowToolbar,\n })}\n </div>\n );\n }\n\n return (\n <div\n data-copilotkit\n data-testid=\"copilot-assistant-message\"\n className={twMerge(className)}\n {...props}\n data-message-id={message.id}\n >\n <div className=\"cpk:prose cpk:max-w-full cpk:break-words cpk:dark:prose-invert\">\n {boundMarkdownRenderer}\n </div>\n {boundToolCallsView}\n {shouldShowToolbar && boundToolbar}\n </div>\n );\n}\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace CopilotChatAssistantMessage {\n export const MarkdownRenderer: React.FC<\n Omit<React.ComponentProps<typeof Streamdown>, \"children\"> & {\n content: string;\n }\n > = ({ content, className, ...props }) => (\n <Streamdown className={className} {...props}>\n {content ?? \"\"}\n </Streamdown>\n );\n\n export const Toolbar: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({\n className,\n ...props\n }) => (\n <div\n data-testid=\"copilot-assistant-toolbar\"\n className={twMerge(\n \"cpk:w-full cpk:bg-transparent cpk:flex cpk:items-center cpk:-ml-[5px] cpk:-mt-[0px]\",\n className,\n )}\n {...props}\n />\n );\n\n export const ToolbarButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement> & {\n title: string;\n children: React.ReactNode;\n }\n > = ({ title, children, ...props }) => {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n type=\"button\"\n variant=\"assistantMessageToolbarButton\"\n aria-label={title}\n {...props}\n >\n {children}\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\">\n <p>{title}</p>\n </TooltipContent>\n </Tooltip>\n );\n };\n\n export const CopyButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ className, title, onClick, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n const [copied, setCopied] = useState(false);\n\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n\n if (onClick) {\n onClick(event);\n }\n };\n\n return (\n <ToolbarButton\n data-testid=\"copilot-copy-button\"\n title={title || labels.assistantMessageToolbarCopyMessageLabel}\n onClick={handleClick}\n className={className}\n {...props}\n >\n {copied ? (\n <Check className=\"cpk:size-[18px]\" />\n ) : (\n <Copy className=\"cpk:size-[18px]\" />\n )}\n </ToolbarButton>\n );\n };\n\n export const ThumbsUpButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ title, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <ToolbarButton\n data-testid=\"copilot-thumbs-up-button\"\n title={title || labels.assistantMessageToolbarThumbsUpLabel}\n {...props}\n >\n <ThumbsUp className=\"cpk:size-[18px]\" />\n </ToolbarButton>\n );\n };\n\n export const ThumbsDownButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ title, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <ToolbarButton\n data-testid=\"copilot-thumbs-down-button\"\n title={title || labels.assistantMessageToolbarThumbsDownLabel}\n {...props}\n >\n <ThumbsDown className=\"cpk:size-[18px]\" />\n </ToolbarButton>\n );\n };\n\n export const ReadAloudButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ title, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <ToolbarButton\n data-testid=\"copilot-read-aloud-button\"\n title={title || labels.assistantMessageToolbarReadAloudLabel}\n {...props}\n >\n <Volume2 className=\"cpk:size-[20px]\" />\n </ToolbarButton>\n );\n };\n\n export const RegenerateButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ title, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <ToolbarButton\n data-testid=\"copilot-regenerate-button\"\n title={title || labels.assistantMessageToolbarRegenerateLabel}\n {...props}\n >\n <RefreshCw className=\"cpk:size-[18px]\" />\n </ToolbarButton>\n );\n };\n}\n\nCopilotChatAssistantMessage.MarkdownRenderer.displayName =\n \"CopilotChatAssistantMessage.MarkdownRenderer\";\nCopilotChatAssistantMessage.Toolbar.displayName =\n \"CopilotChatAssistantMessage.Toolbar\";\nCopilotChatAssistantMessage.CopyButton.displayName =\n \"CopilotChatAssistantMessage.CopyButton\";\nCopilotChatAssistantMessage.ThumbsUpButton.displayName =\n \"CopilotChatAssistantMessage.ThumbsUpButton\";\nCopilotChatAssistantMessage.ThumbsDownButton.displayName =\n \"CopilotChatAssistantMessage.ThumbsDownButton\";\nCopilotChatAssistantMessage.ReadAloudButton.displayName =\n \"CopilotChatAssistantMessage.ReadAloudButton\";\nCopilotChatAssistantMessage.RegenerateButton.displayName =\n \"CopilotChatAssistantMessage.RegenerateButton\";\n\nexport default CopilotChatAssistantMessage;\n"],"mappings":"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"}
1
+ {"version":3,"file":"CopilotChatAssistantMessage.cjs","names":["renderSlot","CopilotChatToolCallsView","Streamdown","Tooltip","TooltipTrigger","Button","TooltipContent","useCopilotChatConfiguration","CopilotChatDefaultLabels","Check","Copy","ThumbsUp","ThumbsDown","Volume2","RefreshCw"],"sources":["../../../src/components/chat/CopilotChatAssistantMessage.tsx"],"sourcesContent":["import { AssistantMessage, Message } from \"@ag-ui/core\";\nimport { useState } from \"react\";\nimport {\n Copy,\n Check,\n ThumbsUp,\n ThumbsDown,\n Volume2,\n RefreshCw,\n} from \"lucide-react\";\nimport {\n useCopilotChatConfiguration,\n CopilotChatDefaultLabels,\n} from \"@/providers/CopilotChatConfigurationProvider\";\nimport { twMerge } from \"tailwind-merge\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport \"katex/dist/katex.min.css\";\nimport { WithSlots, renderSlot } from \"@/lib/slots\";\nimport { Streamdown } from \"streamdown\";\nimport CopilotChatToolCallsView from \"./CopilotChatToolCallsView\";\n\nexport type CopilotChatAssistantMessageProps = WithSlots<\n {\n markdownRenderer: typeof CopilotChatAssistantMessage.MarkdownRenderer;\n toolbar: typeof CopilotChatAssistantMessage.Toolbar;\n copyButton: typeof CopilotChatAssistantMessage.CopyButton;\n thumbsUpButton: typeof CopilotChatAssistantMessage.ThumbsUpButton;\n thumbsDownButton: typeof CopilotChatAssistantMessage.ThumbsDownButton;\n readAloudButton: typeof CopilotChatAssistantMessage.ReadAloudButton;\n regenerateButton: typeof CopilotChatAssistantMessage.RegenerateButton;\n toolCallsView: typeof CopilotChatToolCallsView;\n },\n {\n onThumbsUp?: (message: AssistantMessage) => void;\n onThumbsDown?: (message: AssistantMessage) => void;\n onReadAloud?: (message: AssistantMessage) => void;\n onRegenerate?: (message: AssistantMessage) => void;\n message: AssistantMessage;\n messages?: Message[];\n isRunning?: boolean;\n additionalToolbarItems?: React.ReactNode;\n toolbarVisible?: boolean;\n } & React.HTMLAttributes<HTMLDivElement>\n>;\n\nexport function CopilotChatAssistantMessage({\n message,\n messages,\n isRunning,\n onThumbsUp,\n onThumbsDown,\n onReadAloud,\n onRegenerate,\n additionalToolbarItems,\n toolbarVisible = true,\n markdownRenderer,\n toolbar,\n copyButton,\n thumbsUpButton,\n thumbsDownButton,\n readAloudButton,\n regenerateButton,\n toolCallsView,\n children,\n className,\n ...props\n}: CopilotChatAssistantMessageProps) {\n const boundMarkdownRenderer = renderSlot(\n markdownRenderer,\n CopilotChatAssistantMessage.MarkdownRenderer,\n {\n content: message.content || \"\",\n },\n );\n\n const boundCopyButton = renderSlot(\n copyButton,\n CopilotChatAssistantMessage.CopyButton,\n {\n onClick: async () => {\n if (message.content) {\n try {\n await navigator.clipboard.writeText(message.content);\n } catch (err) {\n console.error(\"Failed to copy message:\", err);\n }\n }\n },\n },\n );\n\n const boundThumbsUpButton = renderSlot(\n thumbsUpButton,\n CopilotChatAssistantMessage.ThumbsUpButton,\n {\n onClick: onThumbsUp,\n },\n );\n\n const boundThumbsDownButton = renderSlot(\n thumbsDownButton,\n CopilotChatAssistantMessage.ThumbsDownButton,\n {\n onClick: onThumbsDown,\n },\n );\n\n const boundReadAloudButton = renderSlot(\n readAloudButton,\n CopilotChatAssistantMessage.ReadAloudButton,\n {\n onClick: onReadAloud,\n },\n );\n\n const boundRegenerateButton = renderSlot(\n regenerateButton,\n CopilotChatAssistantMessage.RegenerateButton,\n {\n onClick: onRegenerate,\n },\n );\n\n const boundToolbar = renderSlot(\n toolbar,\n CopilotChatAssistantMessage.Toolbar,\n {\n children: (\n <div className=\"cpk:flex cpk:items-center cpk:gap-1\">\n {boundCopyButton}\n {(onThumbsUp || thumbsUpButton) && boundThumbsUpButton}\n {(onThumbsDown || thumbsDownButton) && boundThumbsDownButton}\n {(onReadAloud || readAloudButton) && boundReadAloudButton}\n {(onRegenerate || regenerateButton) && boundRegenerateButton}\n {additionalToolbarItems}\n </div>\n ),\n },\n );\n\n const boundToolCallsView = renderSlot(\n toolCallsView,\n CopilotChatToolCallsView,\n {\n message,\n messages,\n },\n );\n\n // Don't show toolbar if message has no content (only tool calls)\n const hasContent = !!(message.content && message.content.trim().length > 0);\n const isLatestAssistantMessage =\n message.role === \"assistant\" &&\n messages?.[messages.length - 1]?.id === message.id;\n const shouldShowToolbar =\n toolbarVisible && hasContent && !(isRunning && isLatestAssistantMessage);\n\n if (children) {\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {children({\n markdownRenderer: boundMarkdownRenderer,\n toolbar: boundToolbar,\n toolCallsView: boundToolCallsView,\n copyButton: boundCopyButton,\n thumbsUpButton: boundThumbsUpButton,\n thumbsDownButton: boundThumbsDownButton,\n readAloudButton: boundReadAloudButton,\n regenerateButton: boundRegenerateButton,\n message,\n messages,\n isRunning,\n onThumbsUp,\n onThumbsDown,\n onReadAloud,\n onRegenerate,\n additionalToolbarItems,\n toolbarVisible: shouldShowToolbar,\n })}\n </div>\n );\n }\n\n return (\n <div\n data-copilotkit\n data-testid=\"copilot-assistant-message\"\n className={twMerge(\n \"copilotKitMessage copilotKitAssistantMessage\",\n className,\n )}\n {...props}\n data-message-id={message.id}\n >\n <div className=\"cpk:prose cpk:max-w-full cpk:break-words cpk:dark:prose-invert\">\n {boundMarkdownRenderer}\n </div>\n {boundToolCallsView}\n {shouldShowToolbar && boundToolbar}\n </div>\n );\n}\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace CopilotChatAssistantMessage {\n export const MarkdownRenderer: React.FC<\n Omit<React.ComponentProps<typeof Streamdown>, \"children\"> & {\n content: string;\n }\n > = ({ content, className, ...props }) => (\n <Streamdown className={className} {...props}>\n {content ?? \"\"}\n </Streamdown>\n );\n\n export const Toolbar: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({\n className,\n ...props\n }) => (\n <div\n data-testid=\"copilot-assistant-toolbar\"\n className={twMerge(\n \"cpk:w-full cpk:bg-transparent cpk:flex cpk:items-center cpk:-ml-[5px] cpk:-mt-[0px]\",\n className,\n )}\n {...props}\n />\n );\n\n export const ToolbarButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement> & {\n title: string;\n children: React.ReactNode;\n }\n > = ({ title, children, ...props }) => {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n type=\"button\"\n variant=\"assistantMessageToolbarButton\"\n aria-label={title}\n {...props}\n >\n {children}\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\">\n <p>{title}</p>\n </TooltipContent>\n </Tooltip>\n );\n };\n\n export const CopyButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ className, title, onClick, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n const [copied, setCopied] = useState(false);\n\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n\n if (onClick) {\n onClick(event);\n }\n };\n\n return (\n <ToolbarButton\n data-testid=\"copilot-copy-button\"\n title={title || labels.assistantMessageToolbarCopyMessageLabel}\n onClick={handleClick}\n className={className}\n {...props}\n >\n {copied ? (\n <Check className=\"cpk:size-[18px]\" />\n ) : (\n <Copy className=\"cpk:size-[18px]\" />\n )}\n </ToolbarButton>\n );\n };\n\n export const ThumbsUpButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ title, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <ToolbarButton\n data-testid=\"copilot-thumbs-up-button\"\n title={title || labels.assistantMessageToolbarThumbsUpLabel}\n {...props}\n >\n <ThumbsUp className=\"cpk:size-[18px]\" />\n </ToolbarButton>\n );\n };\n\n export const ThumbsDownButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ title, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <ToolbarButton\n data-testid=\"copilot-thumbs-down-button\"\n title={title || labels.assistantMessageToolbarThumbsDownLabel}\n {...props}\n >\n <ThumbsDown className=\"cpk:size-[18px]\" />\n </ToolbarButton>\n );\n };\n\n export const ReadAloudButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ title, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <ToolbarButton\n data-testid=\"copilot-read-aloud-button\"\n title={title || labels.assistantMessageToolbarReadAloudLabel}\n {...props}\n >\n <Volume2 className=\"cpk:size-[20px]\" />\n </ToolbarButton>\n );\n };\n\n export const RegenerateButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ title, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <ToolbarButton\n data-testid=\"copilot-regenerate-button\"\n title={title || labels.assistantMessageToolbarRegenerateLabel}\n {...props}\n >\n <RefreshCw className=\"cpk:size-[18px]\" />\n </ToolbarButton>\n );\n };\n}\n\nCopilotChatAssistantMessage.MarkdownRenderer.displayName =\n \"CopilotChatAssistantMessage.MarkdownRenderer\";\nCopilotChatAssistantMessage.Toolbar.displayName =\n \"CopilotChatAssistantMessage.Toolbar\";\nCopilotChatAssistantMessage.CopyButton.displayName =\n \"CopilotChatAssistantMessage.CopyButton\";\nCopilotChatAssistantMessage.ThumbsUpButton.displayName =\n \"CopilotChatAssistantMessage.ThumbsUpButton\";\nCopilotChatAssistantMessage.ThumbsDownButton.displayName =\n \"CopilotChatAssistantMessage.ThumbsDownButton\";\nCopilotChatAssistantMessage.ReadAloudButton.displayName =\n \"CopilotChatAssistantMessage.ReadAloudButton\";\nCopilotChatAssistantMessage.RegenerateButton.displayName =\n \"CopilotChatAssistantMessage.RegenerateButton\";\n\nexport default CopilotChatAssistantMessage;\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"CopilotChatAssistantMessage.d.cts","names":[],"sources":["../../../src/components/chat/CopilotChatAssistantMessage.tsx"],"mappings":";;;;;;;KA0BY,gCAAA,GAAmC,SAAA;EAE3C,gBAAA,SAAyB,2BAAA,CAA4B,gBAAA;EACrD,OAAA,SAAgB,2BAAA,CAA4B,OAAA;EAC5C,UAAA,SAAmB,2BAAA,CAA4B,UAAA;EAC/C,cAAA,SAAuB,2BAAA,CAA4B,cAAA;EACnD,gBAAA,SAAyB,2BAAA,CAA4B,gBAAA;EACrD,eAAA,SAAwB,2BAAA,CAA4B,eAAA;EACpD,gBAAA,SAAyB,2BAAA,CAA4B,gBAAA;EACrD,aAAA,SAAsB,wBAAA;AAAA;EAGtB,UAAA,IAAc,OAAA,EAAS,gBAAA;EACvB,YAAA,IAAgB,OAAA,EAAS,gBAAA;EACzB,WAAA,IAAe,OAAA,EAAS,gBAAA;EACxB,YAAA,IAAgB,OAAA,EAAS,gBAAA;EACzB,OAAA,EAAS,gBAAA;EACT,QAAA,GAAW,OAAA;EACX,SAAA;EACA,sBAAA,GAAyB,KAAA,CAAM,SAAA;EAC/B,cAAA;AAAA,IACE,KAAA,CAAM,cAAA,CAAe,cAAA;AAAA,iBAGX,2BAAA,CAAA;EACd,OAAA;EACA,QAAA;EACA,SAAA;EACA,UAAA;EACA,YAAA;EACA,WAAA;EACA,YAAA;EACA,sBAAA;EACA,cAAA;EACA,gBAAA;EACA,OAAA;EACA,UAAA;EACA,cAAA;EACA,gBAAA;EACA,eAAA;EACA,gBAAA;EACA,aAAA;EACA,QAAA;EACA,SAAA;EAAA,GACG;AAAA,GACF,gCAAA,GAAgC,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,kBAuIlB,2BAAA;EAAA,MACF,gBAAA,EAAkB,KAAA,CAAM,EAAA,CACnC,IAAA,CAAK,KAAA,CAAM,cAAA,QAAsB,UAAA;IAC/B,OAAA;EAAA;EAAA,MAQS,OAAA,EAAS,KAAA,CAAM,EAAA,CAAG,KAAA,CAAM,cAAA,CAAe,cAAA;EAAA,MAcvC,aAAA,EAAe,KAAA,CAAM,EAAA,CAChC,KAAA,CAAM,oBAAA,CAAqB,iBAAA;IACzB,KAAA;IACA,QAAA,EAAU,KAAA,CAAM,SAAA;EAAA;EAAA,MAsBP,UAAA,EAAY,KAAA,CAAM,EAAA,CAC7B,KAAA,CAAM,oBAAA,CAAqB,iBAAA;EAAA,MAgChB,cAAA,EAAgB,KAAA,CAAM,EAAA,CACjC,KAAA,CAAM,oBAAA,CAAqB,iBAAA;EAAA,MAehB,gBAAA,EAAkB,KAAA,CAAM,EAAA,CACnC,KAAA,CAAM,oBAAA,CAAqB,iBAAA;EAAA,MAehB,eAAA,EAAiB,KAAA,CAAM,EAAA,CAClC,KAAA,CAAM,oBAAA,CAAqB,iBAAA;EAAA,MAehB,gBAAA,EAAkB,KAAA,CAAM,EAAA,CACnC,KAAA,CAAM,oBAAA,CAAqB,iBAAA;AAAA"}
1
+ {"version":3,"file":"CopilotChatAssistantMessage.d.cts","names":[],"sources":["../../../src/components/chat/CopilotChatAssistantMessage.tsx"],"mappings":";;;;;;;KA0BY,gCAAA,GAAmC,SAAA;EAE3C,gBAAA,SAAyB,2BAAA,CAA4B,gBAAA;EACrD,OAAA,SAAgB,2BAAA,CAA4B,OAAA;EAC5C,UAAA,SAAmB,2BAAA,CAA4B,UAAA;EAC/C,cAAA,SAAuB,2BAAA,CAA4B,cAAA;EACnD,gBAAA,SAAyB,2BAAA,CAA4B,gBAAA;EACrD,eAAA,SAAwB,2BAAA,CAA4B,eAAA;EACpD,gBAAA,SAAyB,2BAAA,CAA4B,gBAAA;EACrD,aAAA,SAAsB,wBAAA;AAAA;EAGtB,UAAA,IAAc,OAAA,EAAS,gBAAA;EACvB,YAAA,IAAgB,OAAA,EAAS,gBAAA;EACzB,WAAA,IAAe,OAAA,EAAS,gBAAA;EACxB,YAAA,IAAgB,OAAA,EAAS,gBAAA;EACzB,OAAA,EAAS,gBAAA;EACT,QAAA,GAAW,OAAA;EACX,SAAA;EACA,sBAAA,GAAyB,KAAA,CAAM,SAAA;EAC/B,cAAA;AAAA,IACE,KAAA,CAAM,cAAA,CAAe,cAAA;AAAA,iBAGX,2BAAA,CAAA;EACd,OAAA;EACA,QAAA;EACA,SAAA;EACA,UAAA;EACA,YAAA;EACA,WAAA;EACA,YAAA;EACA,sBAAA;EACA,cAAA;EACA,gBAAA;EACA,OAAA;EACA,UAAA;EACA,cAAA;EACA,gBAAA;EACA,eAAA;EACA,gBAAA;EACA,aAAA;EACA,QAAA;EACA,SAAA;EAAA,GACG;AAAA,GACF,gCAAA,GAAgC,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,kBA0IlB,2BAAA;EAAA,MACF,gBAAA,EAAkB,KAAA,CAAM,EAAA,CACnC,IAAA,CAAK,KAAA,CAAM,cAAA,QAAsB,UAAA;IAC/B,OAAA;EAAA;EAAA,MAQS,OAAA,EAAS,KAAA,CAAM,EAAA,CAAG,KAAA,CAAM,cAAA,CAAe,cAAA;EAAA,MAcvC,aAAA,EAAe,KAAA,CAAM,EAAA,CAChC,KAAA,CAAM,oBAAA,CAAqB,iBAAA;IACzB,KAAA;IACA,QAAA,EAAU,KAAA,CAAM,SAAA;EAAA;EAAA,MAsBP,UAAA,EAAY,KAAA,CAAM,EAAA,CAC7B,KAAA,CAAM,oBAAA,CAAqB,iBAAA;EAAA,MAgChB,cAAA,EAAgB,KAAA,CAAM,EAAA,CACjC,KAAA,CAAM,oBAAA,CAAqB,iBAAA;EAAA,MAehB,gBAAA,EAAkB,KAAA,CAAM,EAAA,CACnC,KAAA,CAAM,oBAAA,CAAqB,iBAAA;EAAA,MAehB,eAAA,EAAiB,KAAA,CAAM,EAAA,CAClC,KAAA,CAAM,oBAAA,CAAqB,iBAAA;EAAA,MAehB,gBAAA,EAAkB,KAAA,CAAM,EAAA,CACnC,KAAA,CAAM,oBAAA,CAAqB,iBAAA;AAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"CopilotChatAssistantMessage.d.mts","names":[],"sources":["../../../src/components/chat/CopilotChatAssistantMessage.tsx"],"mappings":";;;;;;;;KA0BY,gCAAA,GAAmC,SAAA;EAE3C,gBAAA,SAAyB,2BAAA,CAA4B,gBAAA;EACrD,OAAA,SAAgB,2BAAA,CAA4B,OAAA;EAC5C,UAAA,SAAmB,2BAAA,CAA4B,UAAA;EAC/C,cAAA,SAAuB,2BAAA,CAA4B,cAAA;EACnD,gBAAA,SAAyB,2BAAA,CAA4B,gBAAA;EACrD,eAAA,SAAwB,2BAAA,CAA4B,eAAA;EACpD,gBAAA,SAAyB,2BAAA,CAA4B,gBAAA;EACrD,aAAA,SAAsB,wBAAA;AAAA;EAGtB,UAAA,IAAc,OAAA,EAAS,gBAAA;EACvB,YAAA,IAAgB,OAAA,EAAS,gBAAA;EACzB,WAAA,IAAe,OAAA,EAAS,gBAAA;EACxB,YAAA,IAAgB,OAAA,EAAS,gBAAA;EACzB,OAAA,EAAS,gBAAA;EACT,QAAA,GAAW,OAAA;EACX,SAAA;EACA,sBAAA,GAAyB,KAAA,CAAM,SAAA;EAC/B,cAAA;AAAA,IACE,KAAA,CAAM,cAAA,CAAe,cAAA;AAAA,iBAGX,2BAAA,CAAA;EACd,OAAA;EACA,QAAA;EACA,SAAA;EACA,UAAA;EACA,YAAA;EACA,WAAA;EACA,YAAA;EACA,sBAAA;EACA,cAAA;EACA,gBAAA;EACA,OAAA;EACA,UAAA;EACA,cAAA;EACA,gBAAA;EACA,eAAA;EACA,gBAAA;EACA,aAAA;EACA,QAAA;EACA,SAAA;EAAA,GACG;AAAA,GACF,gCAAA,GAAgC,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,kBAuIlB,2BAAA;EAAA,MACF,gBAAA,EAAkB,KAAA,CAAM,EAAA,CACnC,IAAA,CAAK,KAAA,CAAM,cAAA,QAAsB,UAAA;IAC/B,OAAA;EAAA;EAAA,MAQS,OAAA,EAAS,KAAA,CAAM,EAAA,CAAG,KAAA,CAAM,cAAA,CAAe,cAAA;EAAA,MAcvC,aAAA,EAAe,KAAA,CAAM,EAAA,CAChC,KAAA,CAAM,oBAAA,CAAqB,iBAAA;IACzB,KAAA;IACA,QAAA,EAAU,KAAA,CAAM,SAAA;EAAA;EAAA,MAsBP,UAAA,EAAY,KAAA,CAAM,EAAA,CAC7B,KAAA,CAAM,oBAAA,CAAqB,iBAAA;EAAA,MAgChB,cAAA,EAAgB,KAAA,CAAM,EAAA,CACjC,KAAA,CAAM,oBAAA,CAAqB,iBAAA;EAAA,MAehB,gBAAA,EAAkB,KAAA,CAAM,EAAA,CACnC,KAAA,CAAM,oBAAA,CAAqB,iBAAA;EAAA,MAehB,eAAA,EAAiB,KAAA,CAAM,EAAA,CAClC,KAAA,CAAM,oBAAA,CAAqB,iBAAA;EAAA,MAehB,gBAAA,EAAkB,KAAA,CAAM,EAAA,CACnC,KAAA,CAAM,oBAAA,CAAqB,iBAAA;AAAA"}
1
+ {"version":3,"file":"CopilotChatAssistantMessage.d.mts","names":[],"sources":["../../../src/components/chat/CopilotChatAssistantMessage.tsx"],"mappings":";;;;;;;;KA0BY,gCAAA,GAAmC,SAAA;EAE3C,gBAAA,SAAyB,2BAAA,CAA4B,gBAAA;EACrD,OAAA,SAAgB,2BAAA,CAA4B,OAAA;EAC5C,UAAA,SAAmB,2BAAA,CAA4B,UAAA;EAC/C,cAAA,SAAuB,2BAAA,CAA4B,cAAA;EACnD,gBAAA,SAAyB,2BAAA,CAA4B,gBAAA;EACrD,eAAA,SAAwB,2BAAA,CAA4B,eAAA;EACpD,gBAAA,SAAyB,2BAAA,CAA4B,gBAAA;EACrD,aAAA,SAAsB,wBAAA;AAAA;EAGtB,UAAA,IAAc,OAAA,EAAS,gBAAA;EACvB,YAAA,IAAgB,OAAA,EAAS,gBAAA;EACzB,WAAA,IAAe,OAAA,EAAS,gBAAA;EACxB,YAAA,IAAgB,OAAA,EAAS,gBAAA;EACzB,OAAA,EAAS,gBAAA;EACT,QAAA,GAAW,OAAA;EACX,SAAA;EACA,sBAAA,GAAyB,KAAA,CAAM,SAAA;EAC/B,cAAA;AAAA,IACE,KAAA,CAAM,cAAA,CAAe,cAAA;AAAA,iBAGX,2BAAA,CAAA;EACd,OAAA;EACA,QAAA;EACA,SAAA;EACA,UAAA;EACA,YAAA;EACA,WAAA;EACA,YAAA;EACA,sBAAA;EACA,cAAA;EACA,gBAAA;EACA,OAAA;EACA,UAAA;EACA,cAAA;EACA,gBAAA;EACA,eAAA;EACA,gBAAA;EACA,aAAA;EACA,QAAA;EACA,SAAA;EAAA,GACG;AAAA,GACF,gCAAA,GAAgC,kBAAA,CAAA,GAAA,CAAA,OAAA;AAAA,kBA0IlB,2BAAA;EAAA,MACF,gBAAA,EAAkB,KAAA,CAAM,EAAA,CACnC,IAAA,CAAK,KAAA,CAAM,cAAA,QAAsB,UAAA;IAC/B,OAAA;EAAA;EAAA,MAQS,OAAA,EAAS,KAAA,CAAM,EAAA,CAAG,KAAA,CAAM,cAAA,CAAe,cAAA;EAAA,MAcvC,aAAA,EAAe,KAAA,CAAM,EAAA,CAChC,KAAA,CAAM,oBAAA,CAAqB,iBAAA;IACzB,KAAA;IACA,QAAA,EAAU,KAAA,CAAM,SAAA;EAAA;EAAA,MAsBP,UAAA,EAAY,KAAA,CAAM,EAAA,CAC7B,KAAA,CAAM,oBAAA,CAAqB,iBAAA;EAAA,MAgChB,cAAA,EAAgB,KAAA,CAAM,EAAA,CACjC,KAAA,CAAM,oBAAA,CAAqB,iBAAA;EAAA,MAehB,gBAAA,EAAkB,KAAA,CAAM,EAAA,CACnC,KAAA,CAAM,oBAAA,CAAqB,iBAAA;EAAA,MAehB,eAAA,EAAiB,KAAA,CAAM,EAAA,CAClC,KAAA,CAAM,oBAAA,CAAqB,iBAAA;EAAA,MAehB,gBAAA,EAAkB,KAAA,CAAM,EAAA,CACnC,KAAA,CAAM,oBAAA,CAAqB,iBAAA;AAAA"}
@@ -68,7 +68,7 @@ function CopilotChatAssistantMessage({ message, messages, isRunning, onThumbsUp,
68
68
  return /* @__PURE__ */ jsxs("div", {
69
69
  "data-copilotkit": true,
70
70
  "data-testid": "copilot-assistant-message",
71
- className: twMerge(className),
71
+ className: twMerge("copilotKitMessage copilotKitAssistantMessage", className),
72
72
  ...props,
73
73
  "data-message-id": message.id,
74
74
  children: [
@@ -1 +1 @@
1
- {"version":3,"file":"CopilotChatAssistantMessage.mjs","names":[],"sources":["../../../src/components/chat/CopilotChatAssistantMessage.tsx"],"sourcesContent":["import { AssistantMessage, Message } from \"@ag-ui/core\";\nimport { useState } from \"react\";\nimport {\n Copy,\n Check,\n ThumbsUp,\n ThumbsDown,\n Volume2,\n RefreshCw,\n} from \"lucide-react\";\nimport {\n useCopilotChatConfiguration,\n CopilotChatDefaultLabels,\n} from \"@/providers/CopilotChatConfigurationProvider\";\nimport { twMerge } from \"tailwind-merge\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport \"katex/dist/katex.min.css\";\nimport { WithSlots, renderSlot } from \"@/lib/slots\";\nimport { Streamdown } from \"streamdown\";\nimport CopilotChatToolCallsView from \"./CopilotChatToolCallsView\";\n\nexport type CopilotChatAssistantMessageProps = WithSlots<\n {\n markdownRenderer: typeof CopilotChatAssistantMessage.MarkdownRenderer;\n toolbar: typeof CopilotChatAssistantMessage.Toolbar;\n copyButton: typeof CopilotChatAssistantMessage.CopyButton;\n thumbsUpButton: typeof CopilotChatAssistantMessage.ThumbsUpButton;\n thumbsDownButton: typeof CopilotChatAssistantMessage.ThumbsDownButton;\n readAloudButton: typeof CopilotChatAssistantMessage.ReadAloudButton;\n regenerateButton: typeof CopilotChatAssistantMessage.RegenerateButton;\n toolCallsView: typeof CopilotChatToolCallsView;\n },\n {\n onThumbsUp?: (message: AssistantMessage) => void;\n onThumbsDown?: (message: AssistantMessage) => void;\n onReadAloud?: (message: AssistantMessage) => void;\n onRegenerate?: (message: AssistantMessage) => void;\n message: AssistantMessage;\n messages?: Message[];\n isRunning?: boolean;\n additionalToolbarItems?: React.ReactNode;\n toolbarVisible?: boolean;\n } & React.HTMLAttributes<HTMLDivElement>\n>;\n\nexport function CopilotChatAssistantMessage({\n message,\n messages,\n isRunning,\n onThumbsUp,\n onThumbsDown,\n onReadAloud,\n onRegenerate,\n additionalToolbarItems,\n toolbarVisible = true,\n markdownRenderer,\n toolbar,\n copyButton,\n thumbsUpButton,\n thumbsDownButton,\n readAloudButton,\n regenerateButton,\n toolCallsView,\n children,\n className,\n ...props\n}: CopilotChatAssistantMessageProps) {\n const boundMarkdownRenderer = renderSlot(\n markdownRenderer,\n CopilotChatAssistantMessage.MarkdownRenderer,\n {\n content: message.content || \"\",\n },\n );\n\n const boundCopyButton = renderSlot(\n copyButton,\n CopilotChatAssistantMessage.CopyButton,\n {\n onClick: async () => {\n if (message.content) {\n try {\n await navigator.clipboard.writeText(message.content);\n } catch (err) {\n console.error(\"Failed to copy message:\", err);\n }\n }\n },\n },\n );\n\n const boundThumbsUpButton = renderSlot(\n thumbsUpButton,\n CopilotChatAssistantMessage.ThumbsUpButton,\n {\n onClick: onThumbsUp,\n },\n );\n\n const boundThumbsDownButton = renderSlot(\n thumbsDownButton,\n CopilotChatAssistantMessage.ThumbsDownButton,\n {\n onClick: onThumbsDown,\n },\n );\n\n const boundReadAloudButton = renderSlot(\n readAloudButton,\n CopilotChatAssistantMessage.ReadAloudButton,\n {\n onClick: onReadAloud,\n },\n );\n\n const boundRegenerateButton = renderSlot(\n regenerateButton,\n CopilotChatAssistantMessage.RegenerateButton,\n {\n onClick: onRegenerate,\n },\n );\n\n const boundToolbar = renderSlot(\n toolbar,\n CopilotChatAssistantMessage.Toolbar,\n {\n children: (\n <div className=\"cpk:flex cpk:items-center cpk:gap-1\">\n {boundCopyButton}\n {(onThumbsUp || thumbsUpButton) && boundThumbsUpButton}\n {(onThumbsDown || thumbsDownButton) && boundThumbsDownButton}\n {(onReadAloud || readAloudButton) && boundReadAloudButton}\n {(onRegenerate || regenerateButton) && boundRegenerateButton}\n {additionalToolbarItems}\n </div>\n ),\n },\n );\n\n const boundToolCallsView = renderSlot(\n toolCallsView,\n CopilotChatToolCallsView,\n {\n message,\n messages,\n },\n );\n\n // Don't show toolbar if message has no content (only tool calls)\n const hasContent = !!(message.content && message.content.trim().length > 0);\n const isLatestAssistantMessage =\n message.role === \"assistant\" &&\n messages?.[messages.length - 1]?.id === message.id;\n const shouldShowToolbar =\n toolbarVisible && hasContent && !(isRunning && isLatestAssistantMessage);\n\n if (children) {\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {children({\n markdownRenderer: boundMarkdownRenderer,\n toolbar: boundToolbar,\n toolCallsView: boundToolCallsView,\n copyButton: boundCopyButton,\n thumbsUpButton: boundThumbsUpButton,\n thumbsDownButton: boundThumbsDownButton,\n readAloudButton: boundReadAloudButton,\n regenerateButton: boundRegenerateButton,\n message,\n messages,\n isRunning,\n onThumbsUp,\n onThumbsDown,\n onReadAloud,\n onRegenerate,\n additionalToolbarItems,\n toolbarVisible: shouldShowToolbar,\n })}\n </div>\n );\n }\n\n return (\n <div\n data-copilotkit\n data-testid=\"copilot-assistant-message\"\n className={twMerge(className)}\n {...props}\n data-message-id={message.id}\n >\n <div className=\"cpk:prose cpk:max-w-full cpk:break-words cpk:dark:prose-invert\">\n {boundMarkdownRenderer}\n </div>\n {boundToolCallsView}\n {shouldShowToolbar && boundToolbar}\n </div>\n );\n}\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace CopilotChatAssistantMessage {\n export const MarkdownRenderer: React.FC<\n Omit<React.ComponentProps<typeof Streamdown>, \"children\"> & {\n content: string;\n }\n > = ({ content, className, ...props }) => (\n <Streamdown className={className} {...props}>\n {content ?? \"\"}\n </Streamdown>\n );\n\n export const Toolbar: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({\n className,\n ...props\n }) => (\n <div\n data-testid=\"copilot-assistant-toolbar\"\n className={twMerge(\n \"cpk:w-full cpk:bg-transparent cpk:flex cpk:items-center cpk:-ml-[5px] cpk:-mt-[0px]\",\n className,\n )}\n {...props}\n />\n );\n\n export const ToolbarButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement> & {\n title: string;\n children: React.ReactNode;\n }\n > = ({ title, children, ...props }) => {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n type=\"button\"\n variant=\"assistantMessageToolbarButton\"\n aria-label={title}\n {...props}\n >\n {children}\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\">\n <p>{title}</p>\n </TooltipContent>\n </Tooltip>\n );\n };\n\n export const CopyButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ className, title, onClick, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n const [copied, setCopied] = useState(false);\n\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n\n if (onClick) {\n onClick(event);\n }\n };\n\n return (\n <ToolbarButton\n data-testid=\"copilot-copy-button\"\n title={title || labels.assistantMessageToolbarCopyMessageLabel}\n onClick={handleClick}\n className={className}\n {...props}\n >\n {copied ? (\n <Check className=\"cpk:size-[18px]\" />\n ) : (\n <Copy className=\"cpk:size-[18px]\" />\n )}\n </ToolbarButton>\n );\n };\n\n export const ThumbsUpButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ title, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <ToolbarButton\n data-testid=\"copilot-thumbs-up-button\"\n title={title || labels.assistantMessageToolbarThumbsUpLabel}\n {...props}\n >\n <ThumbsUp className=\"cpk:size-[18px]\" />\n </ToolbarButton>\n );\n };\n\n export const ThumbsDownButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ title, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <ToolbarButton\n data-testid=\"copilot-thumbs-down-button\"\n title={title || labels.assistantMessageToolbarThumbsDownLabel}\n {...props}\n >\n <ThumbsDown className=\"cpk:size-[18px]\" />\n </ToolbarButton>\n );\n };\n\n export const ReadAloudButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ title, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <ToolbarButton\n data-testid=\"copilot-read-aloud-button\"\n title={title || labels.assistantMessageToolbarReadAloudLabel}\n {...props}\n >\n <Volume2 className=\"cpk:size-[20px]\" />\n </ToolbarButton>\n );\n };\n\n export const RegenerateButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ title, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <ToolbarButton\n data-testid=\"copilot-regenerate-button\"\n title={title || labels.assistantMessageToolbarRegenerateLabel}\n {...props}\n >\n <RefreshCw className=\"cpk:size-[18px]\" />\n </ToolbarButton>\n );\n };\n}\n\nCopilotChatAssistantMessage.MarkdownRenderer.displayName =\n \"CopilotChatAssistantMessage.MarkdownRenderer\";\nCopilotChatAssistantMessage.Toolbar.displayName =\n \"CopilotChatAssistantMessage.Toolbar\";\nCopilotChatAssistantMessage.CopyButton.displayName =\n \"CopilotChatAssistantMessage.CopyButton\";\nCopilotChatAssistantMessage.ThumbsUpButton.displayName =\n \"CopilotChatAssistantMessage.ThumbsUpButton\";\nCopilotChatAssistantMessage.ThumbsDownButton.displayName =\n \"CopilotChatAssistantMessage.ThumbsDownButton\";\nCopilotChatAssistantMessage.ReadAloudButton.displayName =\n \"CopilotChatAssistantMessage.ReadAloudButton\";\nCopilotChatAssistantMessage.RegenerateButton.displayName =\n \"CopilotChatAssistantMessage.RegenerateButton\";\n\nexport default CopilotChatAssistantMessage;\n"],"mappings":"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"}
1
+ {"version":3,"file":"CopilotChatAssistantMessage.mjs","names":[],"sources":["../../../src/components/chat/CopilotChatAssistantMessage.tsx"],"sourcesContent":["import { AssistantMessage, Message } from \"@ag-ui/core\";\nimport { useState } from \"react\";\nimport {\n Copy,\n Check,\n ThumbsUp,\n ThumbsDown,\n Volume2,\n RefreshCw,\n} from \"lucide-react\";\nimport {\n useCopilotChatConfiguration,\n CopilotChatDefaultLabels,\n} from \"@/providers/CopilotChatConfigurationProvider\";\nimport { twMerge } from \"tailwind-merge\";\nimport { Button } from \"@/components/ui/button\";\nimport {\n Tooltip,\n TooltipContent,\n TooltipTrigger,\n} from \"@/components/ui/tooltip\";\nimport \"katex/dist/katex.min.css\";\nimport { WithSlots, renderSlot } from \"@/lib/slots\";\nimport { Streamdown } from \"streamdown\";\nimport CopilotChatToolCallsView from \"./CopilotChatToolCallsView\";\n\nexport type CopilotChatAssistantMessageProps = WithSlots<\n {\n markdownRenderer: typeof CopilotChatAssistantMessage.MarkdownRenderer;\n toolbar: typeof CopilotChatAssistantMessage.Toolbar;\n copyButton: typeof CopilotChatAssistantMessage.CopyButton;\n thumbsUpButton: typeof CopilotChatAssistantMessage.ThumbsUpButton;\n thumbsDownButton: typeof CopilotChatAssistantMessage.ThumbsDownButton;\n readAloudButton: typeof CopilotChatAssistantMessage.ReadAloudButton;\n regenerateButton: typeof CopilotChatAssistantMessage.RegenerateButton;\n toolCallsView: typeof CopilotChatToolCallsView;\n },\n {\n onThumbsUp?: (message: AssistantMessage) => void;\n onThumbsDown?: (message: AssistantMessage) => void;\n onReadAloud?: (message: AssistantMessage) => void;\n onRegenerate?: (message: AssistantMessage) => void;\n message: AssistantMessage;\n messages?: Message[];\n isRunning?: boolean;\n additionalToolbarItems?: React.ReactNode;\n toolbarVisible?: boolean;\n } & React.HTMLAttributes<HTMLDivElement>\n>;\n\nexport function CopilotChatAssistantMessage({\n message,\n messages,\n isRunning,\n onThumbsUp,\n onThumbsDown,\n onReadAloud,\n onRegenerate,\n additionalToolbarItems,\n toolbarVisible = true,\n markdownRenderer,\n toolbar,\n copyButton,\n thumbsUpButton,\n thumbsDownButton,\n readAloudButton,\n regenerateButton,\n toolCallsView,\n children,\n className,\n ...props\n}: CopilotChatAssistantMessageProps) {\n const boundMarkdownRenderer = renderSlot(\n markdownRenderer,\n CopilotChatAssistantMessage.MarkdownRenderer,\n {\n content: message.content || \"\",\n },\n );\n\n const boundCopyButton = renderSlot(\n copyButton,\n CopilotChatAssistantMessage.CopyButton,\n {\n onClick: async () => {\n if (message.content) {\n try {\n await navigator.clipboard.writeText(message.content);\n } catch (err) {\n console.error(\"Failed to copy message:\", err);\n }\n }\n },\n },\n );\n\n const boundThumbsUpButton = renderSlot(\n thumbsUpButton,\n CopilotChatAssistantMessage.ThumbsUpButton,\n {\n onClick: onThumbsUp,\n },\n );\n\n const boundThumbsDownButton = renderSlot(\n thumbsDownButton,\n CopilotChatAssistantMessage.ThumbsDownButton,\n {\n onClick: onThumbsDown,\n },\n );\n\n const boundReadAloudButton = renderSlot(\n readAloudButton,\n CopilotChatAssistantMessage.ReadAloudButton,\n {\n onClick: onReadAloud,\n },\n );\n\n const boundRegenerateButton = renderSlot(\n regenerateButton,\n CopilotChatAssistantMessage.RegenerateButton,\n {\n onClick: onRegenerate,\n },\n );\n\n const boundToolbar = renderSlot(\n toolbar,\n CopilotChatAssistantMessage.Toolbar,\n {\n children: (\n <div className=\"cpk:flex cpk:items-center cpk:gap-1\">\n {boundCopyButton}\n {(onThumbsUp || thumbsUpButton) && boundThumbsUpButton}\n {(onThumbsDown || thumbsDownButton) && boundThumbsDownButton}\n {(onReadAloud || readAloudButton) && boundReadAloudButton}\n {(onRegenerate || regenerateButton) && boundRegenerateButton}\n {additionalToolbarItems}\n </div>\n ),\n },\n );\n\n const boundToolCallsView = renderSlot(\n toolCallsView,\n CopilotChatToolCallsView,\n {\n message,\n messages,\n },\n );\n\n // Don't show toolbar if message has no content (only tool calls)\n const hasContent = !!(message.content && message.content.trim().length > 0);\n const isLatestAssistantMessage =\n message.role === \"assistant\" &&\n messages?.[messages.length - 1]?.id === message.id;\n const shouldShowToolbar =\n toolbarVisible && hasContent && !(isRunning && isLatestAssistantMessage);\n\n if (children) {\n return (\n <div data-copilotkit style={{ display: \"contents\" }}>\n {children({\n markdownRenderer: boundMarkdownRenderer,\n toolbar: boundToolbar,\n toolCallsView: boundToolCallsView,\n copyButton: boundCopyButton,\n thumbsUpButton: boundThumbsUpButton,\n thumbsDownButton: boundThumbsDownButton,\n readAloudButton: boundReadAloudButton,\n regenerateButton: boundRegenerateButton,\n message,\n messages,\n isRunning,\n onThumbsUp,\n onThumbsDown,\n onReadAloud,\n onRegenerate,\n additionalToolbarItems,\n toolbarVisible: shouldShowToolbar,\n })}\n </div>\n );\n }\n\n return (\n <div\n data-copilotkit\n data-testid=\"copilot-assistant-message\"\n className={twMerge(\n \"copilotKitMessage copilotKitAssistantMessage\",\n className,\n )}\n {...props}\n data-message-id={message.id}\n >\n <div className=\"cpk:prose cpk:max-w-full cpk:break-words cpk:dark:prose-invert\">\n {boundMarkdownRenderer}\n </div>\n {boundToolCallsView}\n {shouldShowToolbar && boundToolbar}\n </div>\n );\n}\n\n// eslint-disable-next-line @typescript-eslint/no-namespace\nexport namespace CopilotChatAssistantMessage {\n export const MarkdownRenderer: React.FC<\n Omit<React.ComponentProps<typeof Streamdown>, \"children\"> & {\n content: string;\n }\n > = ({ content, className, ...props }) => (\n <Streamdown className={className} {...props}>\n {content ?? \"\"}\n </Streamdown>\n );\n\n export const Toolbar: React.FC<React.HTMLAttributes<HTMLDivElement>> = ({\n className,\n ...props\n }) => (\n <div\n data-testid=\"copilot-assistant-toolbar\"\n className={twMerge(\n \"cpk:w-full cpk:bg-transparent cpk:flex cpk:items-center cpk:-ml-[5px] cpk:-mt-[0px]\",\n className,\n )}\n {...props}\n />\n );\n\n export const ToolbarButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement> & {\n title: string;\n children: React.ReactNode;\n }\n > = ({ title, children, ...props }) => {\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n type=\"button\"\n variant=\"assistantMessageToolbarButton\"\n aria-label={title}\n {...props}\n >\n {children}\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\">\n <p>{title}</p>\n </TooltipContent>\n </Tooltip>\n );\n };\n\n export const CopyButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ className, title, onClick, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n const [copied, setCopied] = useState(false);\n\n const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n\n if (onClick) {\n onClick(event);\n }\n };\n\n return (\n <ToolbarButton\n data-testid=\"copilot-copy-button\"\n title={title || labels.assistantMessageToolbarCopyMessageLabel}\n onClick={handleClick}\n className={className}\n {...props}\n >\n {copied ? (\n <Check className=\"cpk:size-[18px]\" />\n ) : (\n <Copy className=\"cpk:size-[18px]\" />\n )}\n </ToolbarButton>\n );\n };\n\n export const ThumbsUpButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ title, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <ToolbarButton\n data-testid=\"copilot-thumbs-up-button\"\n title={title || labels.assistantMessageToolbarThumbsUpLabel}\n {...props}\n >\n <ThumbsUp className=\"cpk:size-[18px]\" />\n </ToolbarButton>\n );\n };\n\n export const ThumbsDownButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ title, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <ToolbarButton\n data-testid=\"copilot-thumbs-down-button\"\n title={title || labels.assistantMessageToolbarThumbsDownLabel}\n {...props}\n >\n <ThumbsDown className=\"cpk:size-[18px]\" />\n </ToolbarButton>\n );\n };\n\n export const ReadAloudButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ title, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <ToolbarButton\n data-testid=\"copilot-read-aloud-button\"\n title={title || labels.assistantMessageToolbarReadAloudLabel}\n {...props}\n >\n <Volume2 className=\"cpk:size-[20px]\" />\n </ToolbarButton>\n );\n };\n\n export const RegenerateButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n > = ({ title, ...props }) => {\n const config = useCopilotChatConfiguration();\n const labels = config?.labels ?? CopilotChatDefaultLabels;\n return (\n <ToolbarButton\n data-testid=\"copilot-regenerate-button\"\n title={title || labels.assistantMessageToolbarRegenerateLabel}\n {...props}\n >\n <RefreshCw className=\"cpk:size-[18px]\" />\n </ToolbarButton>\n );\n };\n}\n\nCopilotChatAssistantMessage.MarkdownRenderer.displayName =\n \"CopilotChatAssistantMessage.MarkdownRenderer\";\nCopilotChatAssistantMessage.Toolbar.displayName =\n \"CopilotChatAssistantMessage.Toolbar\";\nCopilotChatAssistantMessage.CopyButton.displayName =\n \"CopilotChatAssistantMessage.CopyButton\";\nCopilotChatAssistantMessage.ThumbsUpButton.displayName =\n \"CopilotChatAssistantMessage.ThumbsUpButton\";\nCopilotChatAssistantMessage.ThumbsDownButton.displayName =\n \"CopilotChatAssistantMessage.ThumbsDownButton\";\nCopilotChatAssistantMessage.ReadAloudButton.displayName =\n \"CopilotChatAssistantMessage.ReadAloudButton\";\nCopilotChatAssistantMessage.RegenerateButton.displayName =\n \"CopilotChatAssistantMessage.RegenerateButton\";\n\nexport default CopilotChatAssistantMessage;\n"],"mappings":";;;;;;;;;;;;;AAkDA,SAAgB,4BAA4B,EAC1C,SACA,UACA,WACA,YACA,cACA,aACA,cACA,wBACA,iBAAiB,MACjB,kBACA,SACA,YACA,gBACA,kBACA,iBACA,kBACA,eACA,UACA,WACA,GAAG,SACgC;CACnC,MAAM,wBAAwB,WAC5B,kBACA,4BAA4B,kBAC5B,EACE,SAAS,QAAQ,WAAW,IAC7B,CACF;CAED,MAAM,kBAAkB,WACtB,YACA,4BAA4B,YAC5B,EACE,SAAS,YAAY;AACnB,MAAI,QAAQ,QACV,KAAI;AACF,SAAM,UAAU,UAAU,UAAU,QAAQ,QAAQ;WAC7C,KAAK;AACZ,WAAQ,MAAM,2BAA2B,IAAI;;IAIpD,CACF;CAED,MAAM,sBAAsB,WAC1B,gBACA,4BAA4B,gBAC5B,EACE,SAAS,YACV,CACF;CAED,MAAM,wBAAwB,WAC5B,kBACA,4BAA4B,kBAC5B,EACE,SAAS,cACV,CACF;CAED,MAAM,uBAAuB,WAC3B,iBACA,4BAA4B,iBAC5B,EACE,SAAS,aACV,CACF;CAED,MAAM,wBAAwB,WAC5B,kBACA,4BAA4B,kBAC5B,EACE,SAAS,cACV,CACF;CAED,MAAM,eAAe,WACnB,SACA,4BAA4B,SAC5B,EACE,UACE,qBAAC;EAAI,WAAU;;GACZ;IACC,cAAc,mBAAmB;IACjC,gBAAgB,qBAAqB;IACrC,eAAe,oBAAoB;IACnC,gBAAgB,qBAAqB;GACtC;;GACG,EAET,CACF;CAED,MAAM,qBAAqB,WACzB,eACA,0BACA;EACE;EACA;EACD,CACF;CAGD,MAAM,aAAa,CAAC,EAAE,QAAQ,WAAW,QAAQ,QAAQ,MAAM,CAAC,SAAS;CACzE,MAAM,2BACJ,QAAQ,SAAS,eACjB,WAAW,SAAS,SAAS,IAAI,OAAO,QAAQ;CAClD,MAAM,oBACJ,kBAAkB,cAAc,EAAE,aAAa;AAEjD,KAAI,SACF,QACE,oBAAC;EAAI;EAAgB,OAAO,EAAE,SAAS,YAAY;YAChD,SAAS;GACR,kBAAkB;GAClB,SAAS;GACT,eAAe;GACf,YAAY;GACZ,gBAAgB;GAChB,kBAAkB;GAClB,iBAAiB;GACjB,kBAAkB;GAClB;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA,gBAAgB;GACjB,CAAC;GACE;AAIV,QACE,qBAAC;EACC;EACA,eAAY;EACZ,WAAW,QACT,gDACA,UACD;EACD,GAAI;EACJ,mBAAiB,QAAQ;;GAEzB,oBAAC;IAAI,WAAU;cACZ;KACG;GACL;GACA,qBAAqB;;GAClB;;;kDAUH,EAAE,SAAS,WAAW,GAAG,YAC5B,oBAAC;EAAsB;EAAW,GAAI;YACnC,WAAW;GACD;yCAGyD,EACtE,WACA,GAAG,YAEH,oBAAC;EACC,eAAY;EACZ,WAAW,QACT,uFACA,UACD;EACD,GAAI;GACJ;CAGG,MAAM,8DAKR,EAAE,OAAO,UAAU,GAAG,YAAY;AACrC,SACE,qBAAC,sBACC,oBAAC;GAAe;aACd,oBAAC;IACC,MAAK;IACL,SAAQ;IACR,cAAY;IACZ,GAAI;IAEH;KACM;IACM,EACjB,oBAAC;GAAe,MAAK;aACnB,oBAAC,iBAAG,QAAU;IACC,IACT;;4CAMT,EAAE,WAAW,OAAO,SAAS,GAAG,YAAY;EAE/C,MAAM,SADS,6BAA6B,EACrB,UAAU;EACjC,MAAM,CAAC,QAAQ,aAAa,SAAS,MAAM;EAE3C,MAAM,eAAe,UAA+C;AAClE,aAAU,KAAK;AACf,oBAAiB,UAAU,MAAM,EAAE,IAAK;AAExC,OAAI,QACF,SAAQ,MAAM;;AAIlB,SACE,oBAAC;GACC,eAAY;GACZ,OAAO,SAAS,OAAO;GACvB,SAAS;GACE;GACX,GAAI;aAEH,SACC,oBAAC,SAAM,WAAU,oBAAoB,GAErC,oBAAC,QAAK,WAAU,oBAAoB;IAExB;;gDAMf,EAAE,OAAO,GAAG,YAAY;EAE3B,MAAM,SADS,6BAA6B,EACrB,UAAU;AACjC,SACE,oBAAC;GACC,eAAY;GACZ,OAAO,SAAS,OAAO;GACvB,GAAI;aAEJ,oBAAC,YAAS,WAAU,oBAAoB;IAC1B;;kDAMf,EAAE,OAAO,GAAG,YAAY;EAE3B,MAAM,SADS,6BAA6B,EACrB,UAAU;AACjC,SACE,oBAAC;GACC,eAAY;GACZ,OAAO,SAAS,OAAO;GACvB,GAAI;aAEJ,oBAAC,cAAW,WAAU,oBAAoB;IAC5B;;iDAMf,EAAE,OAAO,GAAG,YAAY;EAE3B,MAAM,SADS,6BAA6B,EACrB,UAAU;AACjC,SACE,oBAAC;GACC,eAAY;GACZ,OAAO,SAAS,OAAO;GACvB,GAAI;aAEJ,oBAAC,WAAQ,WAAU,oBAAoB;IACzB;;kDAMf,EAAE,OAAO,GAAG,YAAY;EAE3B,MAAM,SADS,6BAA6B,EACrB,UAAU;AACjC,SACE,oBAAC;GACC,eAAY;GACZ,OAAO,SAAS,OAAO;GACvB,GAAI;aAEJ,oBAAC,aAAU,WAAU,oBAAoB;IAC3B;;;AAKtB,4BAA4B,iBAAiB,cAC3C;AACF,4BAA4B,QAAQ,cAClC;AACF,4BAA4B,WAAW,cACrC;AACF,4BAA4B,eAAe,cACzC;AACF,4BAA4B,iBAAiB,cAC3C;AACF,4BAA4B,gBAAgB,cAC1C;AACF,4BAA4B,iBAAiB,cAC3C;AAEF,0CAAe"}
@@ -466,7 +466,7 @@ function CopilotChatInput({ mode = "input", onSubmitMessage, onStop, isRunning =
466
466
  }) : null;
467
467
  const inputPill = /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
468
468
  "data-testid": "copilot-chat-input",
469
- className: (0, tailwind_merge.twMerge)("cpk:flex cpk:w-full cpk:flex-col cpk:items-center cpk:justify-center", "cpk:cursor-text", "cpk:overflow-visible cpk:bg-clip-padding cpk:contain-inline-size", "cpk:bg-white cpk:dark:bg-[#303030]", "cpk:shadow-[0_4px_4px_0_#0000000a,0_0_1px_0_#0000009e] cpk:rounded-[28px]"),
469
+ className: (0, tailwind_merge.twMerge)("copilotKitInput", "cpk:flex cpk:w-full cpk:flex-col cpk:items-center cpk:justify-center", "cpk:cursor-text", "cpk:overflow-visible cpk:bg-clip-padding cpk:contain-inline-size", "cpk:bg-white cpk:dark:bg-[#303030]", "cpk:shadow-[0_4px_4px_0_#0000000a,0_0_1px_0_#0000009e] cpk:rounded-[28px]"),
470
470
  onClick: handleContainerClick,
471
471
  "data-layout": isExpanded ? "expanded" : "compact",
472
472
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {