@coral-ai/chat 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +28 -0
- package/dist/index.d.ts +252 -0
- package/dist/index.js +1537 -0
- package/dist/index.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/Chat.tsx","../src/Chat.Canvas.tsx","../src/Chat.Context.tsx","../src/Chat.Messages.tsx","../src/Chat.ThinkingIndicator.tsx","../src/Chat.Callout.tsx","../src/Chat.Error.tsx","../src/Chat.ReasoningBlock.tsx","../src/Chat.Input.tsx","../src/createHandler.ts","../src/index.ts"],"sourcesContent":["import React from \"react\";\nimport {\n InteractionTag,\n InteractionTagPrimary,\n makeStyles,\n motionTokens,\n} from \"@fluentui/react-components\";\nimport type { ChatFontSize, ChatFontFamily } from \"@coral-ai/markdown\";\nimport ChatCanvas, { type AgentConfig } from \"./Chat.Canvas\";\nimport ChatMessages from \"./Chat.Messages\";\nimport ChatInput from \"./Chat.Input\";\nimport { useChatContext } from \"./Chat.Context\";\n\n// ---- Types (re-exported for consumers) ----\n\nexport type ChatMessage = {\n /** Stable identifier — generated automatically by Chat.Canvas. Used as React key. */\n id?: string;\n role: \"user\" | \"assistant\" | \"system\";\n content: string;\n /** Identifies the message type for custom renderer lookup via the `components` prop. */\n type?: string;\n /** Arbitrary data passed to the custom renderer for this message. */\n metadata?: Record<string, unknown>;\n};\n\n/** A single chunk yielded by a streaming onSendMessage. */\nexport type ChatChunk =\n | string\n | { type: \"reasoning\"; content: string }\n | { type: \"agent\"; name: string };\n\nexport type ChatResponse =\n | string\n | AsyncIterable<ChatChunk>\n | { content: string; type?: string; metadata?: Record<string, unknown> };\n\n/** The typed handler signature engineers implement. */\nexport type ChatAttachment = {\n id: string;\n file: File;\n /** Data URL — populated for image/* files only. */\n preview?: string;\n};\n\nexport type AgentHandler = (\n input: string,\n history: ChatMessage[],\n attachments: File[],\n) => ChatResponse | Promise<ChatResponse>;\n\n/** Props passed to a custom message renderer. */\nexport type ChatMessageRendererProps = {\n message: ChatMessage;\n /** Sends a message back into the chat as the user. */\n onReply: (content: string) => void;\n};\n\nexport type ChatComponents = Record<string, React.FC<ChatMessageRendererProps>>;\n\n// ---- Props ----\n\ninterface ChatProps {\n agent?: string;\n /** Named agent handlers keyed by agent name. Use `\"default\"` for the catch-all. */\n agents?: Record<string, AgentConfig>;\n conversationId?: string;\n initialMessages?: ChatMessage[];\n systemPrompt?: string;\n onSendMessage?: AgentHandler;\n onMessageComplete?: (messages: ChatMessage[], conversationId?: string) => void;\n /** Fires on every message-state update (user append, streaming chunk, final). Use for live persistence. */\n onMessagesChange?: (messages: ChatMessage[], conversationId?: string) => void;\n onError?: (err: unknown) => void;\n autoSendMessage?: string;\n onFeedback?: (messageIndex: number, rating: \"up\" | \"down\") => void;\n onCopy?: (content: string) => void;\n onNavigate?: (path: string) => void;\n components?: ChatComponents;\n thinkingStatus?: string;\n onStop?: () => void;\n /** Placeholder text for the chat input. @default \"Type a message...\" */\n placeholder?: string;\n /** Disables the entire input. */\n disabled?: boolean;\n /** Slot rendered at the left of the input toolbar. */\n actionsStart?: React.ReactNode;\n /** Slot rendered at the right of the input toolbar, just before Send/Stop. */\n actionsEnd?: React.ReactNode;\n /** Shown 24px above the input while messages is empty. */\n emptyState?: React.ReactNode;\n /**\n * Clickable suggestion chips rendered below the input while the chat is empty.\n * Clicking a chip sends that string as the user's message. Chips fade out once\n * any message has been sent.\n */\n promptStarters?: string[];\n /**\n * Pass `null` to disable the chat's built-in surface motion (input slide to\n * bottom + prompt-starter fade). Omit / leave undefined for default motion.\n */\n surfaceMotion?: null;\n /** Font size for assistant message markdown. */\n fontSize?: ChatFontSize;\n /** Font family for assistant message markdown. */\n fontFamily?: ChatFontFamily;\n}\n\n// ---- Styles ----\n\nconst useStyles = makeStyles({\n emptySlot: {\n width: \"100%\",\n maxWidth: \"768px\",\n margin: \"0 auto\",\n padding: \"0 16px\",\n boxSizing: \"border-box\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n },\n contentArea: {\n width: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n minHeight: \"0\",\n },\n inputRow: {\n display: \"flex\",\n width: \"100%\",\n alignItems: \"center\",\n justifyContent: \"center\",\n },\n inputInner: {\n display: \"flex\",\n width: \"100%\",\n maxWidth: \"768px\",\n padding: \"0 16px 16px 16px\",\n boxSizing: \"border-box\",\n },\n starterRow: {\n display: \"flex\",\n flexWrap: \"wrap\",\n justifyContent: \"center\",\n gap: \"6px\",\n width: \"100%\",\n maxWidth: \"768px\",\n margin: \"0 auto\",\n padding: \"0 16px\",\n boxSizing: \"border-box\",\n overflow: \"hidden\",\n },\n});\n\n// ---- Inner layout (reads context, positions via CSS without remounting Input) ----\n\ninterface ChatLayoutProps {\n emptyState?: React.ReactNode;\n promptStarters?: string[];\n surfaceMotion?: null;\n placeholder?: string;\n disabled?: boolean;\n actionsStart?: React.ReactNode;\n actionsEnd?: React.ReactNode;\n components?: ChatComponents;\n onFeedback?: (messageIndex: number, rating: \"up\" | \"down\") => void;\n onCopy?: (content: string) => void;\n onNavigate?: (path: string) => void;\n fontSize?: ChatFontSize;\n fontFamily?: ChatFontFamily;\n}\n\nconst ChatLayout: React.FC<ChatLayoutProps> = ({\n emptyState,\n promptStarters,\n surfaceMotion,\n placeholder,\n disabled,\n actionsStart,\n actionsEnd,\n components,\n onFeedback,\n onCopy,\n onNavigate,\n fontSize,\n fontFamily,\n}) => {\n const styles = useStyles();\n const { messages, isTyping, sendMessage } = useChatContext();\n const empty =\n messages.every((m) => m.role === \"system\") && !isTyping;\n\n const motionEnabled = surfaceMotion !== null;\n const curve = motionTokens.curveDecelerateMax;\n const spacerTransition = motionEnabled ? `flex-grow 300ms ${curve}` : \"none\";\n const gapTransition = motionEnabled ? `height 300ms ${curve}` : \"none\";\n const starterTransition = motionEnabled\n ? `opacity 300ms ${curve}, max-height 300ms ${curve}, padding-bottom 300ms ${curve}`\n : \"none\";\n const hasStarters = !!promptStarters && promptStarters.length > 0;\n\n return (\n <>\n <div\n style={{\n flexGrow: empty ? 1 : 0,\n flexShrink: 1,\n flexBasis: 0,\n minHeight: 0,\n transition: spacerTransition,\n }}\n />\n <div\n className={styles.contentArea}\n style={{\n flex: empty ? \"none\" : 1,\n overflow: empty ? \"visible\" : \"hidden\",\n }}\n >\n {empty ? (\n <div className={styles.emptySlot}>{emptyState}</div>\n ) : (\n <ChatMessages\n components={components}\n onFeedback={onFeedback}\n onCopy={onCopy}\n onNavigate={onNavigate}\n fontSize={fontSize}\n fontFamily={fontFamily}\n />\n )}\n </div>\n <div style={{ height: empty ? 24 : 0, transition: gapTransition }} />\n <div className={styles.inputRow}>\n <div className={styles.inputInner}>\n <ChatInput\n placeholder={placeholder}\n disabled={disabled}\n actionsStart={actionsStart}\n actionsEnd={actionsEnd}\n />\n </div>\n </div>\n {hasStarters && (\n <div\n className={styles.starterRow}\n style={{\n opacity: empty ? 1 : 0,\n maxHeight: empty ? 160 : 0,\n paddingBottom: empty ? 16 : 0,\n pointerEvents: empty ? \"auto\" : \"none\",\n transition: starterTransition,\n gap: '8px'\n }}\n aria-hidden={!empty}\n >\n {promptStarters!.map((p) => (\n <InteractionTag\n key={p}\n appearance=\"outline\"\n onClick={() => sendMessage(p)}\n tabIndex={empty ? 0 : -1}\n >\n <InteractionTagPrimary>{p}</InteractionTagPrimary>\n </InteractionTag>\n ))}\n </div>\n )}\n <div\n style={{\n flexGrow: empty ? 1 : 0,\n flexShrink: 1,\n flexBasis: 0,\n minHeight: 0,\n transition: spacerTransition,\n }}\n />\n </>\n );\n};\n\n// ---- Component ----\n\nconst Chat: React.FC<ChatProps> = ({\n agent,\n agents,\n conversationId,\n initialMessages,\n systemPrompt,\n onSendMessage,\n onMessageComplete,\n onMessagesChange,\n onError,\n autoSendMessage,\n thinkingStatus,\n onStop,\n emptyState,\n promptStarters,\n surfaceMotion,\n components,\n onFeedback,\n onCopy,\n onNavigate,\n placeholder,\n disabled,\n actionsStart,\n actionsEnd,\n fontSize,\n fontFamily,\n}) => {\n return (\n <ChatCanvas\n agent={agent}\n agents={agents}\n conversationId={conversationId}\n initialMessages={initialMessages}\n systemPrompt={systemPrompt}\n onSendMessage={onSendMessage}\n onMessageComplete={onMessageComplete}\n onMessagesChange={onMessagesChange}\n onError={onError}\n autoSendMessage={autoSendMessage}\n thinkingStatus={thinkingStatus}\n onStop={onStop}\n >\n <ChatLayout\n emptyState={emptyState}\n promptStarters={promptStarters}\n surfaceMotion={surfaceMotion}\n placeholder={placeholder}\n disabled={disabled}\n actionsStart={actionsStart}\n actionsEnd={actionsEnd}\n components={components}\n onFeedback={onFeedback}\n onCopy={onCopy}\n onNavigate={onNavigate}\n fontSize={fontSize}\n fontFamily={fontFamily}\n />\n </ChatCanvas>\n );\n};\n\nexport default Chat;\n","import React, { useState, useEffect, useLayoutEffect, useRef, useCallback, ReactNode } from \"react\";\nimport { Button, makeStyles, tokens } from \"@fluentui/react-components\";\nimport { ArrowDown } from \"@coral-ai/bundleicons\";\nimport { ChatContext } from \"./Chat.Context\";\nimport type { ChatMessage, ChatChunk, AgentHandler, ChatAttachment } from \"./Chat\";\n\n/** Agent registration — keyed by agent name; `\"default\"` is the catch-all. */\nexport type AgentConfig = {\n handler: AgentHandler;\n};\n\n// ---- Props ----\n\nexport interface ChatCanvasProps {\n /** Name of the agent from the `agents` map. Falls back to `\"default\"`. */\n agent?: string;\n /** Named agent handlers keyed by agent name. Use `\"default\"` for the catch-all. */\n agents?: Record<string, AgentConfig>;\n /** Stable conversation identifier, passed back in onMessageComplete. */\n conversationId?: string;\n /** Pre-load conversation history. */\n initialMessages?: ChatMessage[];\n /** System prompt prepended to every request (not shown in UI). */\n systemPrompt?: string;\n /** Called when the user sends a message. Return a string, async iterable, or ChatResponse. */\n onSendMessage?: (input: string, history: ChatMessage[], attachments: File[]) => ReturnType<AgentHandler>;\n /** Called after every completed assistant response. Use to persist messages. */\n onMessageComplete?: (messages: ChatMessage[], conversationId?: string) => void;\n /** Called on every message-state update (user append, streaming chunk, final). Use for live persistence. */\n onMessagesChange?: (messages: ChatMessage[], conversationId?: string) => void;\n /** Called when an error occurs during send. */\n onError?: (err: unknown) => void;\n /** Automatically sends this message once on mount. */\n autoSendMessage?: string;\n /** Override the thinking indicator text during generation. */\n thinkingStatus?: string;\n /** Called when the user clicks Stop. Use to abort your fetch/API call. */\n onStop?: () => void;\n children?: ReactNode;\n}\n\n// ---- Styles ----\n\nconst useStyles = makeStyles({\n root: {\n width: \"100%\",\n display: \"flex\",\n flexDirection: \"column\",\n flex: \"1\",\n minHeight: \"0\",\n position: \"relative\",\n },\n scrollToBottom: {\n position: \"absolute\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n zIndex: 1000,\n cursor: \"pointer\",\n boxShadow: tokens.shadow8,\n marginBottom: \"16px\",\n },\n});\n\n// ---- Helpers ----\n\nfunction isAsyncIterable(value: unknown): value is AsyncIterable<ChatChunk> {\n return (\n value !== null &&\n typeof value === \"object\" &&\n Symbol.asyncIterator in (value as object)\n );\n}\n\nfunction isRateLimitError(err: unknown): boolean {\n const e = err as Record<string, unknown>;\n const status = Number(e?.status ?? e?.statusCode ?? 0);\n const msg = String(e?.message ?? \"\").toLowerCase();\n return (\n status === 429 ||\n msg.includes(\"rate limit\") ||\n msg.includes(\"too many requests\")\n );\n}\n\n// ---- Component ----\n\nconst ChatCanvas: React.FC<ChatCanvasProps> = ({\n agent,\n agents,\n conversationId,\n initialMessages,\n systemPrompt,\n onSendMessage,\n onMessageComplete,\n onMessagesChange,\n onError,\n autoSendMessage,\n thinkingStatus,\n onStop,\n children,\n}) => {\n const styles = useStyles();\n const agentKey = agent ?? \"default\";\n const resolvedHandler: AgentHandler | undefined =\n onSendMessage ??\n agents?.[agentKey]?.handler ??\n agents?.[\"default\"]?.handler;\n\n const [messages, setMessages] = useState<ChatMessage[]>(initialMessages ?? []);\n const [input, setInput] = useState(\"\");\n const [isTyping, setIsTyping] = useState(false);\n const [isRetrying, setIsRetrying] = useState(false);\n const [chatError, setChatError] = useState<unknown>(null);\n const [showScrollButton, setShowScrollButton] = useState(false);\n const [inputHeight, setInputHeightState] = useState(0);\n const [isInterrupted, setIsInterrupted] = useState(false);\n const [streamingReasoning, setStreamingReasoning] = useState(\"\");\n const [streamingAgentName, setStreamingAgentName] = useState<string | undefined>();\n const [attachments, setAttachments] = useState<ChatAttachment[]>([]);\n\n const reasoningRef = useRef(\"\");\n const lastUserInputRef = useRef(\"\");\n const hasEverSentRef = useRef(false);\n const currentConversationIdRef = useRef(conversationId);\n const messagesContainerRef = useRef<HTMLDivElement>(null);\n const [messagesEl, setMessagesEl] = useState<HTMLDivElement | null>(null);\n const bottomRef = useRef<HTMLDivElement>(null);\n const shouldStopRef = useRef(false);\n const userScrolledUpRef = useRef(false);\n\n // Sync initialMessages (e.g. conversation switched externally).\n useEffect(() => {\n setMessages((current) => {\n if ((initialMessages?.length ?? 0) > 0 || current.length === 0) {\n return initialMessages ?? [];\n }\n return current;\n });\n }, [initialMessages]);\n\n // Track current conversationId so in-flight streams can detect a session switch.\n useEffect(() => {\n currentConversationIdRef.current = conversationId;\n }, [conversationId]);\n\n // Auto-send on mount; ref guard prevents Strict Mode double-fire.\n const autoSentRef = useRef(false);\n useEffect(() => {\n if (autoSendMessage?.trim() && !autoSentRef.current) {\n autoSentRef.current = true;\n sendMessage(autoSendMessage);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const registerMessagesContainer = useCallback((el: HTMLDivElement | null) => {\n messagesContainerRef.current = el;\n setMessagesEl(el);\n }, []);\n\n // Auto-scroll to bottom when messages update (unless user scrolled up).\n useLayoutEffect(() => {\n if (!userScrolledUpRef.current) {\n if (messagesEl) {\n messagesEl.scrollTop = messagesEl.scrollHeight;\n }\n setShowScrollButton(false);\n }\n }, [messages, messagesEl]);\n\n // Scroll detection — attaches lazily when Chat.Messages mounts.\n useEffect(() => {\n const container = messagesEl;\n if (!container) return;\n const handleScroll = () => {\n const { scrollTop, scrollHeight, clientHeight } = container;\n const atBottom = scrollTop + clientHeight >= scrollHeight - 80;\n userScrolledUpRef.current = !atBottom;\n setShowScrollButton(!atBottom);\n };\n container.addEventListener(\"scroll\", handleScroll, { passive: true });\n return () => container.removeEventListener(\"scroll\", handleScroll);\n }, [messagesEl]);\n\n const scrollToBottom = () => {\n userScrolledUpRef.current = false;\n bottomRef.current?.scrollIntoView({ behavior: \"smooth\" });\n setShowScrollButton(false);\n };\n\n const handleCopy = (content: string) => {\n navigator.clipboard.writeText(content).catch(console.error);\n };\n\n const addAttachments = (files: File[]) => {\n const newItems: ChatAttachment[] = files.map((file) => {\n const attachment: ChatAttachment = { id: crypto.randomUUID(), file };\n if (file.type.startsWith(\"image/\")) {\n const reader = new FileReader();\n reader.onload = (e) => {\n const preview = e.target?.result as string;\n setAttachments((prev) =>\n prev.map((a) => (a.id === attachment.id ? { ...a, preview } : a))\n );\n };\n reader.readAsDataURL(file);\n }\n return attachment;\n });\n setAttachments((prev) => [...prev, ...newItems]);\n };\n\n const removeAttachment = (id: string) => {\n setAttachments((prev) => prev.filter((a) => a.id !== id));\n };\n\n const sendMessage = async (overrideInput?: string) => {\n const textToSend = overrideInput ?? input;\n if (!textToSend.trim()) return;\n hasEverSentRef.current = true;\n\n const sessionAtSend = conversationId;\n\n const baseMessages = overrideInput\n ? messages.filter((_, i) => i < messages.length - 2)\n : messages;\n\n const snapshotAttachments = attachments;\n const attachmentMeta = snapshotAttachments.map((a) => ({\n name: a.file.name,\n type: a.file.type,\n preview: a.preview,\n }));\n\n const updatedMessages: ChatMessage[] = [\n ...baseMessages,\n {\n id: crypto.randomUUID(),\n role: \"user\",\n content: textToSend.replace(/^[\\n\\r]+|[\\n\\r]+$/g, \"\"),\n ...(attachmentMeta.length > 0 ? { metadata: { attachments: attachmentMeta } } : {}),\n },\n ];\n\n lastUserInputRef.current = textToSend;\n userScrolledUpRef.current = false;\n setMessages(updatedMessages);\n onMessagesChange?.(updatedMessages, sessionAtSend);\n if (!overrideInput) setInput(\"\");\n setAttachments([]);\n setIsTyping(true);\n setIsInterrupted(false);\n setChatError(null);\n shouldStopRef.current = false;\n reasoningRef.current = \"\";\n setStreamingReasoning(\"\");\n setStreamingAgentName(undefined);\n\n const historyForAI: ChatMessage[] = systemPrompt\n ? [{ role: \"system\", content: systemPrompt }, ...updatedMessages]\n : updatedMessages;\n\n const MAX_RETRIES = 3;\n\n try {\n if (resolvedHandler) {\n for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {\n try {\n const assistantId = crypto.randomUUID();\n const placeholder: ChatMessage[] = [...updatedMessages, { id: assistantId, role: \"assistant\", content: \"\" }];\n setMessages(placeholder);\n onMessagesChange?.(placeholder, sessionAtSend);\n const response = await resolvedHandler(textToSend, historyForAI, snapshotAttachments.map((a) => a.file));\n\n if (isAsyncIterable(response)) {\n let assistantContent = \"\";\n let rafId: number | null = null;\n let pendingContent = \"\";\n\n for await (const chunk of response) {\n if (shouldStopRef.current) break;\n // Only bail on an actual conversation switch — not when a new\n // session is created mid-send (undefined → defined), which\n // happens when the app assigns an id on first message.\n if (\n sessionAtSend !== undefined &&\n currentConversationIdRef.current !== sessionAtSend\n ) break;\n if (typeof chunk === \"string\") {\n assistantContent += chunk;\n pendingContent = assistantContent;\n if (rafId === null) {\n rafId = requestAnimationFrame(() => {\n const content = pendingContent;\n const nextMsg: ChatMessage = { id: assistantId, role: \"assistant\", content };\n setMessages((prev) => {\n const updated = [...prev];\n updated[updated.length - 1] = nextMsg;\n return updated;\n });\n onMessagesChange?.([...updatedMessages, nextMsg], sessionAtSend);\n rafId = null;\n });\n }\n } else if (chunk.type === \"reasoning\") {\n reasoningRef.current += chunk.content;\n setStreamingReasoning(reasoningRef.current);\n } else if (chunk.type === \"agent\") {\n setStreamingAgentName(chunk.name);\n }\n }\n\n if (rafId !== null) cancelAnimationFrame(rafId);\n if (shouldStopRef.current) setIsInterrupted(true);\n\n if (\n sessionAtSend !== undefined &&\n currentConversationIdRef.current !== sessionAtSend\n ) {\n break;\n }\n\n const finalMsg: ChatMessage = {\n id: assistantId,\n role: \"assistant\",\n content: assistantContent,\n ...(reasoningRef.current ? { metadata: { reasoning: reasoningRef.current } } : {}),\n };\n const finalMessages = [...updatedMessages, finalMsg];\n setMessages(finalMessages);\n onMessagesChange?.(finalMessages, sessionAtSend);\n onMessageComplete?.(finalMessages, sessionAtSend);\n } else if (typeof response === \"string\") {\n if (currentConversationIdRef.current !== sessionAtSend) break;\n const finalMessages: ChatMessage[] = [...updatedMessages, { id: assistantId, role: \"assistant\" as const, content: response }];\n setMessages(finalMessages);\n onMessagesChange?.(finalMessages, sessionAtSend);\n onMessageComplete?.(finalMessages, sessionAtSend);\n } else {\n if (currentConversationIdRef.current !== sessionAtSend) break;\n const assistantMsg: ChatMessage = {\n id: assistantId,\n role: \"assistant\",\n content: response.content,\n type: response.type,\n metadata: response.metadata,\n };\n const finalMessages = [...updatedMessages, assistantMsg];\n setMessages(finalMessages);\n onMessagesChange?.(finalMessages, sessionAtSend);\n onMessageComplete?.(finalMessages, sessionAtSend);\n }\n\n break;\n } catch (err) {\n if (isRateLimitError(err) && attempt < MAX_RETRIES - 1) {\n setIsRetrying(true);\n await new Promise<void>((r) => setTimeout(r, (attempt + 1) * 3000));\n continue;\n }\n throw err;\n }\n }\n }\n } catch (err) {\n onError?.(err);\n setChatError(err);\n } finally {\n setIsRetrying(false);\n setIsTyping(false);\n }\n };\n\n return (\n <ChatContext.Provider\n value={{\n sendMessage,\n scrollToBottom,\n handleCopy,\n messages,\n setMessages,\n input,\n setInput,\n isTyping,\n isRetrying,\n isInterrupted,\n streamingReasoning,\n streamingAgentName,\n thinkingStatus,\n chatError,\n showScrollButton,\n setInputHeight: setInputHeightState,\n messagesContainerRef,\n registerMessagesContainer,\n bottomRef,\n lastUserInputRef,\n hasEverSentRef,\n shouldStopRef,\n onStop,\n attachments,\n addAttachments,\n removeAttachment,\n }}\n >\n <div className={styles.root}>\n {children}\n {showScrollButton && (\n <Button\n onClick={scrollToBottom}\n className={styles.scrollToBottom}\n shape=\"circular\"\n style={{\n bottom: inputHeight + 16,\n backgroundColor: \"transparent\",\n border: `1px solid ${tokens.colorNeutralStroke3}`,\n backdropFilter: \"saturate(180%) blur(16px)\",\n }}\n icon={<ArrowDown style={{ fontSize: \"16px\" }} />}\n />\n )}\n </div>\n </ChatContext.Provider>\n );\n};\n\nexport default ChatCanvas;\n","import { createContext, useContext } from \"react\";\nimport type React from \"react\";\nimport type { ChatMessage, ChatAttachment } from \"./Chat\";\n\nexport interface ChatContextValue {\n // ── Actions ───────────────────────────────────────────────────────────────\n sendMessage: (overrideInput?: string) => Promise<void>;\n scrollToBottom: () => void;\n /** Pre-binds navigator.clipboard.writeText + the onCopy prop callback. */\n handleCopy: (content: string) => void;\n\n // ── Message state ─────────────────────────────────────────────────────────\n messages: ChatMessage[];\n setMessages: React.Dispatch<React.SetStateAction<ChatMessage[]>>;\n\n // ── Input state ───────────────────────────────────────────────────────────\n input: string;\n setInput: React.Dispatch<React.SetStateAction<string>>;\n\n // ── Generation state ──────────────────────────────────────────────────────\n isTyping: boolean;\n isRetrying: boolean;\n isInterrupted: boolean;\n streamingReasoning: string;\n streamingAgentName?: string;\n /** Forwarded from Chat.Canvas thinkingStatus prop so Chat.Messages can read it. */\n thinkingStatus?: string;\n\n // ── Error state ───────────────────────────────────────────────────────────\n chatError: unknown | null;\n\n // ── Scroll / layout ───────────────────────────────────────────────────────\n showScrollButton: boolean;\n /** Called by Chat.Input to report its measured height so Canvas positions the scroll button. */\n setInputHeight: (height: number) => void;\n\n // ── Refs exposed to children ──────────────────────────────────────────────\n messagesContainerRef: React.RefObject<HTMLDivElement | null>;\n /** Called by Chat.Messages on mount/unmount so Canvas can attach scroll listener lazily. */\n registerMessagesContainer: (el: HTMLDivElement | null) => void;\n bottomRef: React.RefObject<HTMLDivElement | null>;\n lastUserInputRef: React.MutableRefObject<string>;\n hasEverSentRef: React.MutableRefObject<boolean>;\n shouldStopRef: React.MutableRefObject<boolean>;\n\n // ── Attachments ───────────────────────────────────────────────────────────\n attachments: ChatAttachment[];\n addAttachments: (files: File[]) => void;\n removeAttachment: (id: string) => void;\n\n // ── Callbacks forwarded from Canvas props ─────────────────────────────────\n onStop?: () => void;\n}\n\nexport const ChatContext = createContext<ChatContextValue>({} as ChatContextValue);\n\nexport function useChatContext(): ChatContextValue {\n return useContext(ChatContext);\n}\n","import React, { useEffect, useRef, useState } from \"react\";\nimport { Body1, Button, makeStyles, tokens } from \"@fluentui/react-components\";\nimport { Copy, Heart, CheckmarkCircle } from \"@coral-ai/bundleicons\";\nimport { CoralMarkdown, type ChatFontSize, type ChatFontFamily } from \"@coral-ai/markdown\";\nimport { useChatContext } from \"./Chat.Context\";\nimport ThinkingIndicator from \"./Chat.ThinkingIndicator\";\nimport ChatCallout from \"./Chat.Callout\";\nimport ChatError from \"./Chat.Error\";\nimport ReasoningBlock from \"./Chat.ReasoningBlock\";\nimport type { ChatMessage, ChatComponents } from \"./Chat\";\nimport { Checkmark20Filled, CheckmarkCircle20Filled } from \"@fluentui/react-icons\";\n\n// ---- Props ----\n\nexport interface ChatMessagesProps {\n /**\n * Custom renderers keyed by message type.\n * Falls back to default markdown rendering if no match.\n */\n components?: ChatComponents;\n /** Called when the user clicks thumbs-up on an assistant message. */\n onFeedback?: (messageIndex: number, rating: \"up\" | \"down\") => void;\n /** Called when the user copies an assistant message. */\n onCopy?: (content: string) => void;\n /** Called when the user clicks an internal link (href starts with \"/\"). */\n onNavigate?: (path: string) => void;\n /** Font size for assistant message markdown. */\n fontSize?: ChatFontSize;\n /** Font family for assistant message markdown. */\n fontFamily?: ChatFontFamily;\n}\n\n// ---- Styles ----\n\nconst useStyles = makeStyles({\n messages: {\n flex: \"1\",\n overflowY: \"auto\",\n overflowX: \"hidden\",\n display: \"flex\",\n flexDirection: \"column\",\n alignItems: \"center\",\n padding: \"40px 0\",\n boxSizing: \"border-box\",\n scrollbarGutter: \"stable both-edges\",\n },\n messageWrapper: {\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"24px\",\n width: \"100%\",\n maxWidth: \"768px\",\n padding: \"0 16px\",\n boxSizing: \"border-box\",\n },\n messageUser: {\n alignSelf: \"flex-end\",\n maxWidth: \"80%\",\n backgroundColor: tokens.colorNeutralBackground2,\n color: tokens.colorNeutralForeground2,\n border: `1px solid ${tokens.colorNeutralStroke2}`,\n padding: \"8px 12px\",\n borderRadius: tokens.borderRadiusXLarge,\n wordBreak: \"break-word\",\n boxSizing: \"border-box\",\n },\n messageAssistant: {\n alignSelf: \"flex-start\",\n width: \"100%\",\n color: tokens.colorNeutralForeground2,\n wordBreak: \"break-word\",\n boxSizing: \"border-box\",\n },\n assistantFooter: {\n display: \"flex\",\n justifyContent: \"space-between\",\n marginTop: \"6px\",\n marginLeft: \"-10px\",\n },\n assistantActions: {\n display: \"flex\",\n },\n});\n\n// ---- Component ----\n\nconst ChatMessages: React.FC<ChatMessagesProps> = ({\n components,\n onFeedback,\n onCopy,\n onNavigate,\n fontSize,\n fontFamily,\n}) => {\n const styles = useStyles();\n const ctx = useChatContext();\n const {\n messages,\n setMessages,\n isTyping,\n isRetrying,\n isInterrupted,\n streamingReasoning,\n streamingAgentName,\n thinkingStatus,\n chatError,\n sendMessage,\n handleCopy,\n lastUserInputRef,\n registerMessagesContainer,\n bottomRef,\n } = ctx;\n\n const containerRef = useRef<HTMLDivElement>(null);\n const [copiedIndex, setCopiedIndex] = useState<number | null>(null);\n const copiedTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n\n useEffect(() => {\n registerMessagesContainer(containerRef.current);\n return () => registerMessagesContainer(null);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n const onCopyMerged = (content: string, index: number) => {\n handleCopy(content);\n onCopy?.(content);\n if (copiedTimerRef.current) clearTimeout(copiedTimerRef.current);\n setCopiedIndex(index);\n copiedTimerRef.current = setTimeout(() => setCopiedIndex(null), 1500);\n };\n\n const renderAssistantMessage = (msg: ChatMessage, index: number) => {\n const isLatest = index === messages.length - 1;\n const reasoning =\n isLatest && isTyping\n ? streamingReasoning\n : (msg.metadata?.reasoning as string | undefined);\n\n if (msg.type && components?.[msg.type]) {\n const CustomRenderer = components[msg.type];\n return (\n <CustomRenderer\n message={msg}\n onReply={(content) => {\n const updatedMessages: ChatMessage[] = [\n ...messages.slice(0, index + 1),\n { role: \"user\", content },\n ];\n setMessages(updatedMessages);\n sendMessage(content);\n }}\n />\n );\n }\n\n return (\n <div>\n {reasoning && (\n <ReasoningBlock\n content={reasoning}\n isStreaming={isLatest && isTyping && !msg.content}\n />\n )}\n <CoralMarkdown onNavigate={onNavigate} fontSize={fontSize} fontFamily={fontFamily}>{msg.content}</CoralMarkdown>\n {isInterrupted && !isTyping && index === messages.length - 1 && (\n <ChatCallout\n message=\"Response was interrupted\"\n onRetry={() => sendMessage(lastUserInputRef.current)}\n />\n )}\n {!(isTyping && isLatest) && (\n <div className={`${styles.assistantFooter} coral-assistant-footer`}>\n <div className={styles.assistantActions}>\n {copiedIndex === index ? (\n <span\n style={{\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"32px\",\n height: \"32px\",\n color: tokens.colorPaletteSeafoamForeground2,\n }}\n >\n <CheckmarkCircle20Filled />\n </span>\n ) : (\n <Button\n onClick={() => onCopyMerged(msg.content, index)}\n title=\"Copy Response\"\n appearance=\"subtle\"\n style={{ color: tokens.colorNeutralForeground3 }}\n icon={<Copy />}\n />\n )}\n <Button\n onClick={() => onFeedback?.(index, \"up\")}\n title=\"Like\"\n appearance=\"subtle\"\n style={{ color: tokens.colorNeutralForeground3 }}\n icon={<Heart />}\n />\n </div>\n </div>\n )}\n </div>\n );\n };\n\n return (\n <div className={styles.messages} ref={containerRef}>\n <div className={styles.messageWrapper}>\n {messages.map((msg, index) => (\n <div\n key={msg.id ?? index}\n className={\n msg.role === \"user\"\n ? styles.messageUser\n : `${styles.messageAssistant} coral-message-assistant${index === messages.length - 1 ? \" is-latest\" : \"\"}`\n }\n >\n {msg.role === \"user\" && Array.isArray(msg.metadata?.attachments) && (\n <div style={{ display: \"flex\", gap: \"6px\", flexWrap: \"wrap\", marginBottom: \"6px\" }}>\n {(msg.metadata!.attachments as Array<{ name: string; type: string; preview?: string }>).map((a, i) =>\n a.type.startsWith(\"image/\") && a.preview ? (\n <img\n key={i}\n src={a.preview}\n alt={a.name}\n style={{ width: 64, height: 64, borderRadius: \"var(--borderRadiusMedium)\", objectFit: \"cover\" }}\n />\n ) : (\n <span\n key={i}\n style={{\n fontSize: 12,\n padding: \"2px 8px\",\n borderRadius: \"var(--borderRadiusSmall)\",\n backgroundColor: tokens.colorNeutralBackground3,\n color: tokens.colorNeutralForeground2,\n }}\n >\n 📄 {a.name}\n </span>\n )\n )}\n </div>\n )}\n <Body1>\n {msg.role === \"user\"\n ? msg.content.split(\"\\n\").map((line, i, arr) => (\n <React.Fragment key={i}>\n {line}\n {i < arr.length - 1 && <br />}\n </React.Fragment>\n ))\n : renderAssistantMessage(msg, index)}\n </Body1>\n </div>\n ))}\n\n {chatError !== null && !isTyping && (\n <ChatError\n error={chatError}\n onRetry={() => sendMessage(lastUserInputRef.current)}\n />\n )}\n {isTyping && (\n <ThinkingIndicator\n isRetrying={isRetrying}\n status={streamingAgentName ? `${streamingAgentName}...` : thinkingStatus}\n />\n )}\n <div ref={bottomRef} />\n </div>\n </div>\n );\n};\n\nexport default ChatMessages;\n","import React, { useState, useEffect, useRef } from \"react\";\nimport { makeStyles, tokens } from \"@fluentui/react-components\";\n\nconst thinkingMessages = [\n \"Generating\",\n \"Thinking\",\n \"Optimizing\",\n \"Processing\",\n \"Analyzing\",\n \"Reasoning\",\n \"Drafting\",\n \"Evaluating\",\n \"Computing\",\n \"Synthesizing\",\n \"Reviewing\",\n \"Refining\",\n];\n\nconst retryingMessages = [\n \"Still working\",\n \"Awaiting\",\n \"Hang tight\",\n \"One moment\",\n \"Almost there\",\n \"Just a moment\",\n \"Reconnecting\",\n];\n\nconst TYPING_SPEED = 80; // ms per character\nconst HOLD_DURATION = 1300; // ms to hold the full word before moving on\n\nconst SPINNER_BG = '#000000';\n\nconst useStyles = makeStyles({\n root: {\n display: \"flex\",\n alignItems: \"center\",\n gap: \"8px\",\n width: \"100%\",\n color: tokens.colorNeutralForeground3,\n // fontSize: \"14px\",\n },\n icon: {\n width: \"28px\",\n height: \"28px\",\n flexShrink: 0,\n border: `3px solid ${SPINNER_BG}`,\n boxSizing: \"border-box\",\n backgroundColor: '${SPINNER_BG}',\n opacity: 0.8,\n backgroundImage: [\n `radial-gradient(farthest-side, ${tokens.colorNeutralForeground1} 98%, ${SPINNER_BG})`,\n `radial-gradient(farthest-side, ${tokens.colorNeutralForeground1} 98%, ${SPINNER_BG})`,\n `radial-gradient(farthest-side, ${tokens.colorNeutralForeground1} 98%, ${SPINNER_BG})`,\n `radial-gradient(farthest-side, ${tokens.colorNeutralForeground1} 98%, ${SPINNER_BG})`,\n `radial-gradient(farthest-side, ${tokens.colorNeutralForeground1} 98%, ${SPINNER_BG})`,\n `linear-gradient(${tokens.colorNeutralForeground1} 0 0)`,\n `linear-gradient(${tokens.colorNeutralForeground1} 0 0)`,\n ].join(\", \"),\n backgroundSize: \"7px 7px, 7px 7px, 7px 7px, 7px 7px, 7px 7px, 100% 3px, 3px 100%\",\n backgroundPosition: \"50%, 50%, 50%, 50%, 50%, 50%, 50%\",\n backgroundRepeat: \"no-repeat\",\n filter: \"blur(2px) contrast(10)\",\n animationName: {\n \"100%\": {\n backgroundPosition: \"50% -7px, -7px 50%, 22px 50%, 50% 22px, 50%, 50%, 50%\",\n },\n },\n animationDuration: \"0.8s\",\n animationIterationCount: \"infinite\",\n animationTimingFunction: \"ease\",\n },\n text: {\n // fontFamily: tokens.fontFamilyBase,\n // fontSize: tokens.fontSizeBase200,\n // color: tokens.colorNeutralForeground3,\n fontFamily: \"var(--fontFamilyMonospace)\",\n minWidth: \"0\",\n },\n cursor: {\n display: \"inline-block\",\n width: \"6px\",\n height: \"1em\",\n backgroundColor: tokens.colorNeutralForeground3,\n marginLeft: \"1px\",\n verticalAlign: \"text-bottom\",\n animationName: {\n \"0%, 100%\": { opacity: \"1\" },\n \"50%\": { opacity: \"0\" },\n },\n animationDuration: \"0.9s\",\n animationTimingFunction: \"step-end\",\n animationIterationCount: \"infinite\",\n },\n});\n\ninterface ThinkingIndicatorProps {\n isRetrying?: boolean;\n /** Override the cycling animation with a static status string. The animated icon is retained. */\n status?: string;\n}\n\nconst ThinkingIndicator: React.FC<ThinkingIndicatorProps> = ({ isRetrying = false, status }) => {\n const styles = useStyles();\n const [displayText, setDisplayText] = useState(\"\");\n const timerRef = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);\n const msgIdxRef = useRef(0);\n const charIdxRef = useRef(0);\n\n useEffect(() => {\n const pool = isRetrying ? retryingMessages : thinkingMessages;\n // Reset animation when mode switches\n msgIdxRef.current = 0;\n charIdxRef.current = 0;\n\n const tick = () => {\n const word = pool[msgIdxRef.current];\n\n if (charIdxRef.current < word.length) {\n charIdxRef.current += 1;\n setDisplayText(word.slice(0, charIdxRef.current));\n timerRef.current = setTimeout(tick, TYPING_SPEED);\n } else {\n // Finished typing the word — hold, then advance\n timerRef.current = setTimeout(() => {\n msgIdxRef.current = (msgIdxRef.current + 1) % pool.length;\n charIdxRef.current = 0;\n tick();\n }, HOLD_DURATION);\n }\n };\n\n tick();\n return () => clearTimeout(timerRef.current);\n }, [isRetrying]);\n\n return (\n <div className={styles.root}>\n <div className={styles.icon} />\n <span className={styles.text}>\n {status ?? displayText}\n <span className={styles.cursor} />\n </span>\n </div>\n );\n};\n\nexport default ThinkingIndicator;\n","import React from \"react\";\nimport { Body1, Button, makeStyles, mergeClasses, tokens } from \"@fluentui/react-components\";\nimport { ChatWarning20Regular } from \"@fluentui/react-icons\";\n\ninterface ChatCalloutProps {\n message: string;\n onRetry?: () => void;\n className?: string;\n}\n\nconst useStyles = makeStyles({\n root: {\n display: \"inline-flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: \"8px\",\n padding: \"12px 12px\",\n borderRadius: tokens.borderRadiusXLarge,\n backgroundColor: tokens.colorNeutralBackground3,\n border: `1px solid ${tokens.colorNeutralStroke2}`,\n color: tokens.colorNeutralForeground3,\n width: \"100%\",\n boxSizing: \"border-box\",\n margin: \"24px 0\",\n },\n left: {\n display: \"flex\",\n alignItems: \"center\",\n gap: \"8px\",\n },\n label: {\n fontFamily: \"var(--fontFamilyMonospace)\",\n },\n retryButton: {\n minWidth: 0,\n },\n});\n\nconst ChatCallout: React.FC<ChatCalloutProps> = ({ message, onRetry, className }) => {\n const styles = useStyles();\n\n return (\n <div className={mergeClasses(styles.root, className)}>\n <span className={styles.left}>\n <ChatWarning20Regular />\n <Body1 className={styles.label}>{message}</Body1>\n </span>\n {onRetry && (\n <Button\n onClick={onRetry}\n className={styles.retryButton}\n size=\"small\"\n appearance=\"primary\"\n >\n Retry\n </Button>\n )}\n </div>\n );\n};\n\nexport default ChatCallout;\n","import React from \"react\";\nimport { Body1, Button, makeStyles, tokens } from \"@fluentui/react-components\";\nimport {\n ErrorCircle20Regular,\n Clock20Regular,\n LockClosed20Regular,\n PlugDisconnected20Regular,\n Warning20Regular,\n ArrowCounterclockwise16Regular,\n} from \"@fluentui/react-icons\";\n\n// ---- Error normalization ----\n\ntype ErrorCategory =\n | \"auth_billing\"\n | \"rate_limit\"\n | \"overloaded\"\n | \"bad_input\"\n | \"not_found\"\n | \"server_error\"\n | \"unknown\";\n\ninterface NormalizedError {\n category: ErrorCategory;\n message: string;\n}\n\n/**\n * Normalizes raw errors from Anthropic, OpenAI, and Google Gemini into a\n * common category + user-friendly message. Safe to call with any unknown value.\n */\nexport function normalizeChatError(err: unknown): NormalizedError {\n const anyErr = err as Record<string, unknown>;\n const rawMessage = String(\n anyErr?.message ?? (anyErr?.error as Record<string, unknown>)?.message ?? err ?? \"\"\n ).toLowerCase();\n\n const status = Number(anyErr?.status ?? anyErr?.statusCode ?? 0);\n const errorType = String(\n (anyErr?.error as Record<string, unknown>)?.type ?? anyErr?.type ?? anyErr?.code ?? \"\"\n );\n const errorCode = String(\n (anyErr?.error as Record<string, unknown>)?.code ?? anyErr?.code ?? \"\"\n );\n\n // Auth / billing — Anthropic \"credit\", OpenAI \"insufficient_quota\", Gemini PERMISSION_DENIED\n if (\n rawMessage.includes(\"credit\") ||\n rawMessage.includes(\"billing\") ||\n rawMessage.includes(\"insufficient_quota\") ||\n errorCode === \"insufficient_quota\" ||\n errorType === \"PERMISSION_DENIED\"\n ) {\n return {\n category: \"auth_billing\",\n message: \"API credits exhausted. Add credits in your provider's billing dashboard.\",\n };\n }\n\n // Rate limit — Anthropic rate_limit_error, OpenAI 429, Gemini RESOURCE_EXHAUSTED\n if (\n errorType === \"rate_limit_error\" ||\n rawMessage.includes(\"rate limit\") ||\n rawMessage.includes(\"too many requests\")\n ) {\n return {\n category: \"rate_limit\",\n message: \"You're being rate limited. Wait a moment and try again.\",\n };\n }\n\n // Overloaded — Anthropic overloaded_error (529), OpenAI 503\n if (\n status === 529 ||\n status === 503 ||\n errorType === \"overloaded_error\" ||\n errorType === \"RESOURCE_EXHAUSTED\" ||\n rawMessage.includes(\"overload\") ||\n rawMessage.includes(\"capacity\")\n ) {\n return {\n category: \"overloaded\",\n message: \"The AI service is overloaded right now. Try again in a few seconds.\",\n };\n }\n\n // Not found — OpenAI 404 / model_not_found, Gemini NOT_FOUND\n if (\n status === 404 ||\n errorType === \"NOT_FOUND\" ||\n rawMessage.includes(\"model_not_found\") ||\n rawMessage.includes(\"not found\")\n ) {\n return {\n category: \"not_found\",\n message: \"Model not found. Check the model name in your configuration.\",\n };\n }\n\n // Bad input — Anthropic/OpenAI invalid_request_error (400), Gemini INVALID_ARGUMENT\n if (\n status === 400 ||\n errorType === \"invalid_request_error\" ||\n errorType === \"INVALID_ARGUMENT\"\n ) {\n return {\n category: \"bad_input\",\n message: \"The request was invalid. Check your message or API configuration.\",\n };\n }\n\n // Server error — 5xx, Anthropic api_error, Gemini INTERNAL\n if (status >= 500 || errorType === \"api_error\" || errorType === \"INTERNAL\") {\n return {\n category: \"server_error\",\n message: \"The AI service hit an internal error. Try again shortly.\",\n };\n }\n\n return {\n category: \"unknown\",\n message: \"Something went wrong. Check your connection and try again.\",\n };\n}\n\n// ---- Styles ----\n\nconst useStyles = makeStyles({\n root: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n gap: \"8px\",\n padding: \"12px\",\n borderRadius: tokens.borderRadiusXLarge,\n backgroundColor: tokens.colorNeutralBackground3,\n border: `1px solid ${tokens.colorNeutralStroke2}`,\n color: tokens.colorNeutralForeground3,\n width: \"100%\",\n boxSizing: \"border-box\",\n margin: \"8px 0\",\n },\n left: {\n display: \"flex\",\n alignItems: \"center\",\n gap: \"8px\",\n minWidth: 0,\n },\n message: {\n fontFamily: \"var(--fontFamilyMonospace)\",\n },\n});\n\nconst categoryIcon: Record<ErrorCategory, React.ReactElement> = {\n auth_billing: <LockClosed20Regular />,\n rate_limit: <Clock20Regular />,\n overloaded: <PlugDisconnected20Regular />,\n bad_input: <Warning20Regular />,\n not_found: <ErrorCircle20Regular />,\n server_error: <ErrorCircle20Regular />,\n unknown: <Warning20Regular />,\n};\n\n// ---- Component ----\n\nexport interface ChatErrorProps {\n /** Raw error thrown by your onSendMessage handler — any provider shape works. */\n error: unknown;\n /** Optional retry callback shown as a button. */\n onRetry?: () => void;\n}\n\nconst ChatError: React.FC<ChatErrorProps> = ({ error, onRetry }) => {\n const styles = useStyles();\n const { category, message } = normalizeChatError(error);\n\n return (\n <div className={styles.root}>\n <span className={styles.left}>\n {categoryIcon[category]}\n <Body1 className={styles.message}>{message}</Body1>\n </span>\n {onRetry && (\n <Button\n size=\"small\"\n appearance=\"primary\"\n onClick={onRetry}\n >\n Retry\n </Button>\n )}\n </div>\n );\n};\n\nexport default ChatError;\n","import React, { useState, useEffect, useRef } from \"react\";\nimport { Body1, makeStyles, tokens } from \"@fluentui/react-components\";\nimport { ChevronDown16Regular, ChevronRight16Regular } from \"@fluentui/react-icons\";\n\nexport interface ReasoningBlockProps {\n /** Full accumulated reasoning content. */\n content: string;\n /** True while the model is still streaming reasoning tokens. */\n isStreaming?: boolean;\n}\n\nconst useStyles = makeStyles({\n root: {\n display: \"flex\",\n flexDirection: \"column\",\n overflow: \"hidden\",\n margin: \"12px 0 40px 0\",\n },\n header: {\n display: \"flex\",\n alignItems: \"center\",\n padding: \"0\",\n cursor: \"pointer\",\n background: \"none\",\n border: \"none\",\n width: \"100%\",\n textAlign: \"left\",\n gap: \"8px\",\n },\n labelRow: {\n display: \"flex\",\n alignItems: \"center\",\n gap: \"6px\",\n minWidth: 0,\n },\n pulseContainer: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n width: \"16px\",\n height: \"16px\",\n },\n pulse: {\n flexShrink: 0,\n width: \"8px\",\n height: \"8px\",\n borderRadius: \"50%\",\n backgroundColor: tokens.colorNeutralForeground3,\n animationName: {\n \"0%, 100%\": { opacity: \"1\" },\n \"50%\": { opacity: \"0.2\" },\n },\n animationDuration: \"1.2s\",\n animationTimingFunction: \"ease-in-out\",\n animationIterationCount: \"infinite\",\n },\n pulseDone: {\n flexShrink: 0,\n width: \"8px\",\n height: \"8px\",\n borderRadius: \"50%\",\n backgroundColor: tokens.colorBrandForeground1,\n },\n label: {\n color: tokens.colorNeutralForeground3,\n flexShrink: 0,\n marginBottom: \"2px\",\n },\n chevron: {\n color: tokens.colorNeutralForeground3,\n flexShrink: 0,\n transition: \"transform 0.2s ease\",\n },\n chevronExpanded: {\n color: tokens.colorNeutralForeground3,\n flexShrink: 0,\n transition: \"transform 0.2s ease\",\n transform: \"rotate(90deg)\",\n },\n expanded: {\n padding: \"16px 0 0 0\",\n marginLeft: \"22px\",\n fontSize: tokens.fontSizeBase300,\n color: tokens.colorNeutralForeground3,\n fontFamily: \"var(--fontFamilyMonospace)\",\n whiteSpace: \"pre-wrap\",\n wordBreak: \"break-word\",\n // maxHeight: \"320px\",\n // overflowY: \"auto\",\n },\n});\n\nconst ReasoningBlock: React.FC<ReasoningBlockProps> = ({\n content,\n isStreaming = false,\n}) => {\n const styles = useStyles();\n const [expanded, setExpanded] = useState(false);\n const [duration, setDuration] = useState<number | null>(null);\n const startTimeRef = useRef<number | null>(null);\n\n useEffect(() => {\n if (isStreaming) {\n startTimeRef.current = Date.now();\n setDuration(null);\n } else if (startTimeRef.current !== null) {\n setDuration(Math.round((Date.now() - startTimeRef.current) / 1000));\n startTimeRef.current = null;\n }\n }, [isStreaming]);\n\n const label = isStreaming\n ? \"Thinking\"\n : duration !== null\n ? `Thought for ${duration}s`\n : \"Thought\";\n\n return (\n <div className={styles.root}>\n <button className={styles.header} onClick={() => setExpanded((e) => !e)}>\n <div className={styles.labelRow}>\n <div className={styles.pulseContainer}>\n <span className={isStreaming ? styles.pulse : styles.pulseDone} />\n </div>\n <Body1 className={styles.label}>{label}</Body1>\n <ChevronRight16Regular\n className={expanded ? styles.chevronExpanded : styles.chevron}\n />\n </div>\n </button>\n\n {expanded && (\n <div className={styles.expanded}>{content}</div>\n )}\n </div>\n );\n};\n\nexport default ReasoningBlock;\n","import React, {\n useRef,\n useState,\n useEffect,\n forwardRef,\n useImperativeHandle,\n} from \"react\";\nimport { Body1, Button, Tag, makeStyles, tokens } from \"@fluentui/react-components\";\nimport { Dismiss, Send, Stop } from \"@coral-ai/bundleicons\";\nimport { useChatContext } from \"./Chat.Context\";\nimport type { ChatAttachment } from \"./Chat\";\n\n// ---- Props ----\n\nexport interface ChatInputProps {\n /** Current input value. Optional inside Chat.Canvas — auto-wired from context. */\n value?: string;\n /** Change handler. Optional inside Chat.Canvas — auto-wired from context. */\n onChange?: (val: string) => void;\n /** Called on Enter. Optional inside Chat.Canvas — auto-wired to sendMessage. */\n onEnter?: () => void;\n placeholder?: string;\n /** Disabled state. */\n disabled?: boolean;\n style?: React.CSSProperties;\n /** Slot rendered at the left of the bottom toolbar. */\n actionsStart?: React.ReactNode;\n /** Slot rendered at the right of the bottom toolbar, just before Send/Stop. */\n actionsEnd?: React.ReactNode;\n /** Override attachments when used outside a Chat.Canvas. */\n attachments?: ChatAttachment[];\n /** Override remove handler when used outside a Chat.Canvas. */\n removeAttachment?: (id: string) => void;\n}\n\n// ---- Styles ----\n\nconst useStyles = makeStyles({\n wrapper: {\n width: \"100%\",\n margin: \"0 auto\",\n },\n card: {\n display: \"inline-flex\",\n flexDirection: \"column\",\n gap: \"8px\",\n alignItems: \"stretch\",\n width: \"100%\",\n padding: \"8px\",\n borderRadius: \"var(--borderRadiusXLarge)\",\n backgroundColor: \"var(--colorNeutralBackgroundAlpha2)\",\n transition: \"border-color 0.2s ease-in-out\",\n position: \"relative\",\n boxSizing: \"border-box\",\n overflow: \"hidden\",\n },\n cardFocused: {\n boxShadow: tokens.shadow28,\n },\n cardDisabled: {\n opacity: \"0.3\",\n pointerEvents: \"none\",\n },\n attachmentsRow: {\n display: \"flex\",\n gap: \"8px\",\n overflowX: \"auto\",\n padding: \"0 4px\",\n },\n attachmentItem: {\n position: \"relative\",\n flexShrink: 0,\n width: \"128px\",\n height: \"128px\",\n borderRadius: \"var(--borderRadiusMedium)\",\n overflow: \"hidden\",\n border: `1px solid ${tokens.colorNeutralStroke2}`,\n backgroundColor: \"var(--colorNeutralBackground3)\",\n display: \"flex\",\n flexDirection: \"column\",\n },\n attachmentImage: {\n width: \"100%\",\n height: \"100%\",\n objectFit: \"cover\",\n },\n attachmentFile: {\n padding: \"12px\",\n boxSizing: \"border-box\",\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"4px\",\n justifyContent: \"space-between\",\n },\n attachmentFileName: {\n wordBreak: \"break-all\",\n color: \"var(--colorNeutralForeground2)\",\n overflow: \"hidden\",\n maxHeight: \"36px\",\n lineHeight: \"1.2\",\n },\n attachmentDismiss: {\n position: \"absolute\",\n top: \"6px\",\n right: \"6px\",\n },\n textarea: {\n resize: \"none\",\n overflowY: \"auto\",\n height: \"auto\",\n minHeight: \"24px\",\n maxHeight: \"150px\",\n padding: \"8px\",\n backgroundColor: \"transparent\",\n border: \"none\",\n outline: \"none\",\n fontFamily: \"var(--fontFamilyBase)\",\n fontSize: \"var(--fontSizeBase300)\",\n fontWeight: \"var(--fontWeightRegular)\",\n color: \"var(--colorNeutralForeground1)\",\n lineHeight: \"1.5\",\n boxSizing: \"border-box\",\n width: \"100%\",\n },\n toolbar: {\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n maxHeight: \"32px\",\n },\n toolbarSide: {\n display: \"flex\",\n alignItems: \"center\",\n },\n focusBar: {\n position: \"absolute\",\n bottom: \"0\",\n left: \"0\",\n width: \"100%\",\n height: \"2px\",\n backgroundColor: \"var(--colorCompoundBrandStroke)\",\n transition: \"transform 0.2s ease-in-out\",\n textAlign: \"center\",\n },\n focusBarVisible: {\n transform: \"scaleX(1)\",\n },\n focusBarHidden: {\n transform: \"scaleX(0)\",\n },\n});\n\n// ---- Component ----\n\nconst ChatInput = forwardRef<HTMLTextAreaElement, ChatInputProps>(\n (\n {\n value: valueProp,\n onChange: onChangeProp,\n onEnter: onEnterProp,\n placeholder = \"Type a message...\",\n disabled: disabledProp,\n style,\n actionsStart,\n actionsEnd,\n attachments: attachmentsProp,\n removeAttachment: removeAttachmentProp,\n },\n ref,\n ) => {\n const styles = useStyles();\n const [isFocused, setIsFocused] = useState(false);\n const textareaRef = useRef<HTMLTextAreaElement>(null);\n const containerRef = useRef<HTMLDivElement>(null);\n\n useImperativeHandle(ref, () => textareaRef.current as HTMLTextAreaElement);\n\n // ── Context wiring ────────────────────────────────────────────────────────\n const ctx = useChatContext();\n const isInsideCanvas = ctx.setInput !== undefined;\n const attachments = isInsideCanvas ? ctx.attachments : (attachmentsProp ?? []);\n const removeAttachment = isInsideCanvas ? ctx.removeAttachment : (removeAttachmentProp ?? (() => {}));\n\n const value = valueProp ?? (isInsideCanvas ? ctx.input : \"\");\n const onChange = onChangeProp ?? (isInsideCanvas ? ctx.setInput : () => {});\n const disabled = disabledProp ?? false;\n const onEnter =\n onEnterProp ??\n (isInsideCanvas\n ? () => {\n if (!ctx.isTyping) ctx.sendMessage();\n }\n : undefined);\n\n // ── Height reporting to Canvas (for scroll-button positioning) ────────────\n useEffect(() => {\n if (!isInsideCanvas) return;\n const el = containerRef.current;\n if (!el) return;\n const ro = new ResizeObserver(() => {\n ctx.setInputHeight(el.offsetHeight);\n });\n ro.observe(el);\n ctx.setInputHeight(el.offsetHeight);\n return () => ro.disconnect();\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [isInsideCanvas]);\n\n // ── Auto-grow textarea ────────────────────────────────────────────────────\n useEffect(() => {\n if (textareaRef.current) {\n textareaRef.current.style.height = \"auto\";\n textareaRef.current.style.height = `${textareaRef.current.scrollHeight}px`;\n }\n }, [value]);\n\n useEffect(() => {\n const el = textareaRef.current;\n if (!el) return;\n const observer = new ResizeObserver(() => {\n el.style.height = \"auto\";\n el.style.height = `${el.scrollHeight}px`;\n });\n observer.observe(el);\n return () => observer.disconnect();\n }, []);\n\n // ── Send / Stop (always present in Canvas mode) ───────────────────────────\n const sendStopButton = isInsideCanvas ? (\n ctx.isTyping ? (\n <Button\n appearance=\"transparent\"\n onClick={() => {\n ctx.shouldStopRef.current = true;\n ctx.onStop?.();\n }}\n icon={<Stop />}\n style={{ cursor: \"default\" }}\n />\n ) : (\n <Button\n appearance=\"transparent\"\n onClick={() => ctx.sendMessage()}\n icon={<Send />}\n disabled={!value.trim()}\n style={{ cursor: \"default\" }}\n />\n )\n ) : null;\n\n return (\n <div ref={containerRef} className={styles.wrapper} style={style}>\n <div\n className={`${styles.card}${isFocused ? ` ${styles.cardFocused}` : \"\"}${disabled ? ` ${styles.cardDisabled}` : \"\"}`}\n style={{\n border: isFocused\n ? `1px solid ${tokens.colorNeutralStroke1}`\n : `1px solid ${tokens.colorNeutralStroke2}`,\n }}\n >\n {attachments.length > 0 && (\n <div className={styles.attachmentsRow}>\n {attachments.map((a) => {\n const ext = a.file.name.split(\".\").pop()?.toUpperCase() ?? \"FILE\";\n return (\n <div key={a.id} className={styles.attachmentItem}>\n {a.preview ? (\n <img\n src={a.preview}\n alt={a.file.name}\n className={styles.attachmentImage}\n />\n ) : (\n <div className={styles.attachmentFile}>\n <Body1 className={styles.attachmentFileName}>\n {a.file.name}\n </Body1>\n <Tag appearance=\"outline\" size=\"small\">\n {ext}\n </Tag>\n </div>\n )}\n <Button\n icon={<Dismiss />}\n size=\"small\"\n onClick={() => removeAttachment(a.id)}\n className={styles.attachmentDismiss}\n />\n </div>\n );\n })}\n </div>\n )}\n\n <textarea\n disabled={disabled}\n ref={textareaRef}\n value={value}\n onChange={(e) => onChange(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n onEnter?.();\n }\n }}\n onFocus={() => setIsFocused(true)}\n onBlur={() => setIsFocused(false)}\n placeholder={placeholder}\n rows={1}\n className={styles.textarea}\n />\n\n <div className={styles.toolbar}>\n <div className={styles.toolbarSide}>{actionsStart}</div>\n <div className={styles.toolbarSide}>\n {actionsEnd}\n {sendStopButton}\n </div>\n </div>\n\n <span\n className={`${styles.focusBar} ${isFocused ? styles.focusBarVisible : styles.focusBarHidden}`}\n />\n </div>\n </div>\n );\n },\n);\n\nexport default ChatInput;\n","import type { AgentHandler, ChatChunk } from \"./Chat\";\n\ntype CreateHandlerOptions = {\n /** Your backend endpoint. Receives POST { input, history, context }. */\n endpoint: string;\n /** Additional headers (e.g. Authorization). */\n headers?: HeadersInit;\n};\n\n/**\n * Wraps a fetch endpoint into an AgentHandler.\n * The endpoint should stream newline-delimited responses where each line is either:\n * - A plain text chunk (yielded as a string)\n * - A JSON-encoded ChatChunk object (e.g. `{\"type\":\"reasoning\",\"content\":\"...\"}`)\n * - An SSE `data: ...` line (the `data: ` prefix is stripped automatically)\n * - `[DONE]` to signal end-of-stream\n *\n * @example\n * // main.tsx\n * <CoralProvider agents={{ default: { handler: createHandler({ endpoint: '/api/chat' }) } }}>\n */\nexport function createHandler({ endpoint, headers }: CreateHandlerOptions): AgentHandler {\n return async function* (input, history, context) {\n const res = await fetch(endpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\", ...headers },\n body: JSON.stringify({ input, history, context }),\n });\n\n if (!res.ok || !res.body) {\n throw Object.assign(new Error(`${res.status} ${res.statusText}`), {\n status: res.status,\n statusText: res.statusText,\n });\n }\n\n const reader = res.body.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() ?? \"\"; // keep any incomplete final line\n\n for (const line of lines) {\n // Strip SSE prefix\n const text = line.startsWith(\"data: \") ? line.slice(6) : line;\n if (!text || text === \"[DONE]\") continue;\n\n try {\n const chunk = JSON.parse(text) as ChatChunk;\n yield chunk;\n } catch {\n // Plain text line\n yield text;\n }\n }\n }\n };\n}\n","import _ChatRoot from \"./Chat\";\nimport _ChatCanvas from \"./Chat.Canvas\";\nimport _ChatMessages from \"./Chat.Messages\";\nimport _ChatInput from \"./Chat.Input\";\nimport _ChatError, { normalizeChatError as _normalizeChatError } from \"./Chat.Error\";\nimport _ChatCallout from \"./Chat.Callout\";\nimport { createHandler as _createHandler } from \"./createHandler\";\n\nexport const Chat: typeof _ChatRoot & {\n Canvas: typeof _ChatCanvas;\n Messages: typeof _ChatMessages;\n Input: typeof _ChatInput;\n Error: typeof _ChatError;\n Callout: typeof _ChatCallout;\n} = Object.assign(_ChatRoot, {\n Canvas: _ChatCanvas,\n Messages: _ChatMessages,\n Input: _ChatInput,\n Error: _ChatError,\n Callout: _ChatCallout,\n});\n\nexport const normalizeChatError = _normalizeChatError;\nexport const createHandler = _createHandler;\n\nexport { useChatContext } from \"./Chat.Context\";\n\nexport type {\n ChatMessage,\n ChatChunk,\n ChatResponse,\n AgentHandler,\n ChatAttachment,\n ChatMessageRendererProps,\n ChatComponents,\n} from \"./Chat\";\nexport type { ChatCanvasProps, AgentConfig } from \"./Chat.Canvas\";\nexport type { ChatMessagesProps } from \"./Chat.Messages\";\nexport type { ChatInputProps } from \"./Chat.Input\";\nexport type { ChatErrorProps } from \"./Chat.Error\";\n"],"mappings":"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","names":["makeStyles","React","useEffect","useRef","useState","Body1","Button","makeStyles","tokens","useState","useEffect","useRef","makeStyles","tokens","jsx","jsxs","useStyles","Button","makeStyles","tokens","jsx","jsxs","useStyles","Body1","Button","makeStyles","tokens","jsx","jsxs","useStyles","useState","useEffect","useRef","Body1","makeStyles","tokens","jsx","jsxs","useStyles","jsx","jsxs","useStyles","makeStyles","tokens","useRef","useState","useEffect","Button","Body1","React","useRef","useState","useEffect","Body1","Button","makeStyles","tokens","jsx","jsxs","useStyles","makeStyles","tokens","useState","useRef","useEffect","Button","Body1","jsx","jsxs","useStyles","makeStyles","Chat","normalizeChatError","createHandler"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@coral-ai/chat",
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"description": "Chat surface for Coral UI: Chat, Chat.Canvas, Chat.Messages, Chat.Input, and agent helpers.",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "Eunsoo Lee",
|
|
8
|
+
"homepage": "https://github.com/mochimilk/coral-ai#readme",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/mochimilk/coral-ai.git",
|
|
12
|
+
"directory": "packages/chat"
|
|
13
|
+
},
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/mochimilk/coral-ai/issues"
|
|
16
|
+
},
|
|
17
|
+
"type": "module",
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"import": "./dist/index.js"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist",
|
|
26
|
+
"README.md",
|
|
27
|
+
"LICENSE"
|
|
28
|
+
],
|
|
29
|
+
"sideEffects": [
|
|
30
|
+
"**/*.css"
|
|
31
|
+
],
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"@fluentui/react-components": "^9.0.0",
|
|
34
|
+
"@fluentui/react-icons": "^2.0.322",
|
|
35
|
+
"react": "^19.0.0",
|
|
36
|
+
"react-dom": "^19.0.0",
|
|
37
|
+
"@coral-ai/markdown": "^0.3.0",
|
|
38
|
+
"@coral-ai/bundleicons": "^2.0.324"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@fluentui/react-components": "^9.0.0",
|
|
42
|
+
"@fluentui/react-icons": "^2.0.322",
|
|
43
|
+
"tsup": "^8.5.1",
|
|
44
|
+
"@coral-ai/markdown": "0.3.0",
|
|
45
|
+
"@coral-ai/bundleicons": "2.0.324"
|
|
46
|
+
},
|
|
47
|
+
"publishConfig": {
|
|
48
|
+
"access": "public"
|
|
49
|
+
},
|
|
50
|
+
"scripts": {
|
|
51
|
+
"build": "tsup",
|
|
52
|
+
"dev": "tsup --watch"
|
|
53
|
+
}
|
|
54
|
+
}
|