@slipstream-ui/ai 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +33 -1
- package/dist/index.d.ts +33 -1
- package/dist/index.js +236 -110
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +238 -112
- package/dist/index.mjs.map +1 -1
- package/dist/manifests/attachment.manifest.json +2 -0
- package/dist/manifests/branch.manifest.json +2 -0
- package/dist/manifests/code-block.manifest.json +2 -0
- package/dist/manifests/command-palette.manifest.json +37 -3
- package/dist/manifests/confirmation.manifest.json +2 -0
- package/dist/manifests/inline-citation.manifest.json +2 -0
- package/dist/manifests/message-actions.manifest.json +3 -0
- package/dist/manifests/reasoning.manifest.json +6 -0
- package/dist/manifests/response.manifest.json +2 -0
- package/dist/manifests/tool-call.manifest.json +6 -0
- package/package.json +3 -3
- package/src/components/code-block/CodeBlock.tsx +91 -5
- package/src/components/command-palette/CommandPalette.test.tsx +21 -0
- package/src/components/command-palette/CommandPalette.tsx +71 -6
- package/src/components/confirmation/Confirmation.tsx +1 -1
- package/src/components/conversation/Conversation.tsx +6 -1
- package/src/components/reasoning/Reasoning.tsx +13 -6
- package/src/components/tool-call/ToolCall.tsx +24 -8
- package/src/manifests/attachment.manifest.json +2 -0
- package/src/manifests/branch.manifest.json +2 -0
- package/src/manifests/code-block.manifest.json +2 -0
- package/src/manifests/command-palette.manifest.json +37 -3
- package/src/manifests/confirmation.manifest.json +2 -0
- package/src/manifests/inline-citation.manifest.json +2 -0
- package/src/manifests/message-actions.manifest.json +3 -0
- package/src/manifests/reasoning.manifest.json +6 -0
- package/src/manifests/response.manifest.json +2 -0
- package/src/manifests/tool-call.manifest.json +6 -0
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/components/message/Message.tsx","../src/components/message-actions/MessageActions.tsx","../src/components/attachment/Attachment.tsx","../src/components/attachment/AttachmentList.tsx","../src/components/response/Response.tsx","../src/components/code-block/CodeBlock.tsx","../src/components/response/close-incomplete-markdown.ts","../src/components/confirmation/Confirmation.tsx","../src/components/branch/Branch.tsx","../src/components/inline-citation/InlineCitation.tsx","../src/components/conversation/Conversation.tsx","../src/components/prompt-input/PromptInput.tsx","../src/components/reasoning/Reasoning.tsx","../src/components/tool-call/ToolCall.tsx","../src/components/source/Source.tsx","../src/components/source/Sources.tsx","../src/components/suggestion/Suggestion.tsx","../src/components/chainthought/ChainThought.tsx","../src/components/streaming/StreamingIndicator.tsx","../src/components/command-palette/CommandPalette.tsx","../src/adapter/messages.ts","../src/adapter/hooks.ts"],"sourcesContent":["export type {\n MessageRole,\n ReasoningStep,\n SourceItem,\n} from './types';\n// Data-model aliases: exporting these under their bare names would collide\n// with same-named components in the bundled .d.ts output.\nexport type {\n Message as MessageData,\n ToolCall as ToolCallData,\n} from './types';\nexport * from './components/message';\nexport * from './components/message-actions';\nexport * from './components/attachment';\nexport * from './components/response';\nexport * from './components/code-block';\nexport * from './components/confirmation';\nexport * from './components/branch';\nexport * from './components/inline-citation';\nexport * from './components/conversation';\nexport * from './components/prompt-input';\nexport * from './components/reasoning';\nexport * from './components/tool-call';\nexport * from './components/source';\nexport * from './components/suggestion';\nexport * from './components/chainthought';\nexport * from './components/streaming';\nexport * from './components/command-palette';\nexport * from './adapter';\n","'use client';\n\nimport * as React from 'react';\nimport { Avatar, AvatarImage, AvatarFallback, Button } from '@slipstream-ui/core';\nimport { cn } from '@slipstream-ui/core';\nimport type { Message as MessageType } from '../../types';\n\nexport type MessageProps = {\n message: MessageType;\n className?: string;\n showAvatar?: boolean;\n avatarSrc?: string;\n avatarFallback?: string;\n /** Display name for the user role; override for localization. */\n userLabel?: string;\n /** Display name for the assistant role; override for localization. */\n assistantLabel?: string;\n /**\n * Custom content renderer, e.g. for markdown/code blocks.\n * When provided, it fully replaces the default plain-text rendering.\n */\n renderContent?: (content: string) => React.ReactNode;\n /**\n * Marks the response as still being generated: shows a typing cursor\n * and sets aria-busy so assistive tech knows more content is coming.\n */\n isStreaming?: boolean;\n /** Generation failure text; renders an error card in place of content. */\n error?: string;\n /** Called when the user requests a retry after `error`; omit to hide the action. */\n onRetry?: () => void;\n labels?: {\n retry?: string;\n edit?: string;\n save?: string;\n cancel?: string;\n };\n /**\n * Edit-and-resubmit affordance for user messages: renders an Edit action\n * that swaps content into an inline textarea and calls `onEditContent`.\n */\n onEditContent?: (content: string) => void;\n};\n\nconst Message = React.forwardRef<HTMLDivElement, MessageProps>(\n (\n {\n message,\n className,\n showAvatar = true,\n avatarSrc,\n avatarFallback,\n userLabel = 'You',\n assistantLabel = 'Assistant',\n renderContent,\n isStreaming = false,\n error,\n onRetry,\n onEditContent,\n labels,\n ...props\n },\n ref\n ) => {\n const [isEditing, setIsEditing] = React.useState(false);\n const [draft, setDraft] = React.useState(message.content);\n\n const t = {\n retry: labels?.retry ?? 'Retry',\n edit: labels?.edit ?? 'Edit',\n save: labels?.save ?? 'Save & resend',\n cancel: labels?.cancel ?? 'Cancel',\n };\n\n const isUser = message.role === 'user';\n const isSystem = message.role === 'system';\n const displayLabel = isUser\n ? userLabel\n : message.role === 'assistant'\n ? assistantLabel\n : message.role;\n\n const startEdit = () => {\n setDraft(message.content);\n setIsEditing(true);\n };\n\n const commitEdit = () => {\n const trimmed = draft.trim();\n if (!trimmed) return;\n setIsEditing(false);\n onEditContent?.(trimmed);\n };\n\n return (\n <div\n ref={ref}\n aria-busy={isStreaming || undefined}\n className={cn(\n 'flex gap-3 p-4 rounded-lg',\n isUser ? 'bg-primary/10' : 'bg-muted',\n isSystem && 'border-l-4 border-muted-foreground',\n error && 'border border-destructive/40',\n className\n )}\n {...props}\n >\n {showAvatar && !isSystem && (\n <Avatar className=\"h-8 w-8 flex-shrink-0\">\n {avatarSrc && <AvatarImage src={avatarSrc} alt={displayLabel} />}\n <AvatarFallback className={cn(\n 'text-xs font-medium',\n isUser ? 'bg-primary text-primary-foreground' : 'bg-secondary text-secondary-foreground'\n )}>\n {avatarFallback || (isUser ? 'U' : 'A')}\n </AvatarFallback>\n </Avatar>\n )}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2 mb-1\">\n <span className=\"text-sm font-medium\">{displayLabel}</span>\n {message.timestamp && (\n <span className=\"text-xs text-muted-foreground\">\n {new Date(message.timestamp).toLocaleTimeString()}\n </span>\n )}\n </div>\n\n {error ? (\n <div role=\"alert\" className=\"text-sm\">\n <div className=\"text-destructive mb-2\">{error}</div>\n {onRetry && (\n <Button size=\"sm\" variant=\"outline\" onClick={onRetry}>\n ↻ {t.retry}\n </Button>\n )}\n </div>\n ) : isEditing ? (\n <div className=\"space-y-2\">\n <textarea\n value={draft}\n onChange={(event) => setDraft(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault();\n commitEdit();\n }\n if (event.key === 'Escape') setIsEditing(false);\n }}\n aria-label=\"Edit message\"\n autoFocus\n rows={Math.min(6, draft.split('\\n').length + 1)}\n className=\"w-full resize-none rounded-md border border-input bg-background px-3 py-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n />\n <div className=\"flex gap-2\">\n <Button size=\"sm\" onClick={commitEdit}>{t.save}</Button>\n <Button size=\"sm\" variant=\"ghost\" onClick={() => setIsEditing(false)}>{t.cancel}</Button>\n </div>\n </div>\n ) : (\n <div className=\"text-sm whitespace-pre-wrap break-words\">\n {renderContent ? (\n renderContent(message.content)\n ) : (\n <>\n {message.content}\n {isStreaming && (\n <span\n className=\"inline-block w-[2px] h-[1em] ml-0.5 align-text-bottom bg-current animate-pulse motion-reduce:animate-none\"\n data-testid=\"streaming-cursor\"\n />\n )}\n </>\n )}\n {onEditContent && !isStreaming && (\n <div>\n <button\n type=\"button\"\n onClick={startEdit}\n aria-label={t.edit}\n className=\"mt-1 rounded px-1 py-0.5 text-xs text-muted-foreground hover:bg-accent hover:text-accent-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n ✎ {t.edit}\n </button>\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n );\n }\n);\nMessage.displayName = 'Message';\n\n/**\n * Memoized: during token streaming the parent re-renders on every tick, but\n * only the streaming message's object identity changes. Memo skips re-render\n * (and timestamp re-formatting) for every other message in the transcript.\n * Callback props must be referentially stable for memo to help.\n */\nconst MemoizedMessage = React.memo(Message);\nMemoizedMessage.displayName = 'Message';\n\nexport { MemoizedMessage as Message };\n","'use client';\n\nimport * as React from 'react';\nimport { cn } from '@slipstream-ui/core';\n\n/** User sentiment for an AI response. */\nexport type FeedbackRating = 'up' | 'down';\n\nexport type MessageActionsProps = {\n /**\n * Visibility rule:\n * - 'always': always visible (default)\n * - 'on-hover': fades in when the parent message is hovered/focused\n * (add the `group` class to the parent element)\n * - 'not-last': like 'on-hover', intended for non-latest messages\n */\n autohide?: 'always' | 'on-hover' | 'not-last';\n /**\n * Content to copy. Omit to hide the copy action, or pass a getter when\n * the content lives outside this component.\n */\n content?: string;\n /** Called after the user copies the message; receives the copied text. */\n onCopy?: (content: string) => void;\n /** Called with the selected rating; selecting the same rating clears it (passes undefined). */\n onFeedback?: (rating: FeedbackRating | undefined) => void;\n /** Called when the user requests a regenerated response; omit to hide the action. */\n onRegenerate?: () => void;\n labels?: {\n copy?: string;\n copied?: string;\n thumbUp?: string;\n thumbDown?: string;\n regenerate?: string;\n };\n className?: string;\n};\n\nconst MessageActions = React.forwardRef<HTMLDivElement, MessageActionsProps>(\n (\n { content, onCopy, onFeedback, onRegenerate, autohide = 'always', labels, className, ...props },\n ref\n ) => {\n const [copied, setCopied] = React.useState(false);\n const [rating, setRating] = React.useState<FeedbackRating | undefined>();\n\n const t = {\n copy: labels?.copy ?? 'Copy',\n copied: labels?.copied ?? 'Copied',\n thumbUp: labels?.thumbUp ?? 'Good response',\n thumbDown: labels?.thumbDown ?? 'Bad response',\n regenerate: labels?.regenerate ?? 'Regenerate',\n };\n\n const handleCopy = async () => {\n if (!content) return;\n try {\n await navigator.clipboard.writeText(content);\n } catch {\n // Clipboard API may be unavailable (insecure context); still notify so consumers can react.\n }\n setCopied(true);\n window.setTimeout(() => setCopied(false), 2000);\n onCopy?.(content);\n };\n\n const handleRating = (next: FeedbackRating) => {\n const updated = rating === next ? undefined : next;\n setRating(updated);\n onFeedback?.(updated);\n };\n\n const actionButton =\n 'rounded px-1.5 py-0.5 text-xs transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring';\n const actionButtonIdle =\n 'text-muted-foreground hover:bg-accent hover:text-accent-foreground';\n\n return (\n <div\n ref={ref}\n role=\"toolbar\"\n aria-label=\"Message actions\"\n className={cn(\n 'flex items-center gap-1 mt-2',\n autohide !== 'always' &&\n 'opacity-0 transition-opacity focus-within:opacity-100 group-hover:opacity-100 motion-reduce:opacity-100',\n className\n )}\n {...props}\n >\n {content !== undefined && (\n <button type=\"button\" onClick={handleCopy} className={cn(actionButton, actionButtonIdle)}>\n {copied ? t.copied : t.copy}\n </button>\n )}\n\n <button\n type=\"button\"\n onClick={() => handleRating('up')}\n aria-label={t.thumbUp}\n aria-pressed={rating === 'up'}\n className={cn(\n actionButton,\n rating === 'up' ? 'text-primary' : actionButtonIdle\n )}\n >\n 👍\n </button>\n\n <button\n type=\"button\"\n onClick={() => handleRating('down')}\n aria-label={t.thumbDown}\n aria-pressed={rating === 'down'}\n className={cn(\n actionButton,\n rating === 'down' ? 'text-destructive' : actionButtonIdle\n )}\n >\n 👎\n </button>\n\n {onRegenerate && (\n <button type=\"button\" onClick={onRegenerate} className={cn(actionButton, actionButtonIdle)}>\n {t.regenerate}\n </button>\n )}\n </div>\n );\n }\n);\nMessageActions.displayName = 'MessageActions';\n\nexport { MessageActions };\n","import * as React from 'react';\nimport { Spinner } from '@slipstream-ui/core';\nimport { cn } from '@slipstream-ui/core';\n\n/** A single file attached to a message or prompt. Display-only; upload logic stays consumer-side. */\nexport type AttachmentItem = {\n id: string;\n /** File name, including extension. */\n name: string;\n /** Human-readable size, e.g. \"2.4 MB\". */\n size?: string;\n /** MIME type or simple kind used for the chip label. */\n type?: string;\n /** Optional image thumbnail URL. */\n previewUrl?: string;\n status?: 'uploading' | 'done' | 'error';\n};\n\nexport type AttachmentProps = {\n attachment: AttachmentItem;\n /** Called when the user removes the attachment; omit to hide the remove control. */\n onRemove?: (attachment: AttachmentItem) => void;\n className?: string;\n};\n\nconst Attachment = React.forwardRef<HTMLDivElement, AttachmentProps>(\n ({ attachment, onRemove, className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\n 'inline-flex items-center gap-2 rounded-md border border-border bg-muted/50 px-2 py-1.5 text-sm max-w-xs',\n className\n )}\n {...props}\n >\n {attachment.previewUrl ? (\n <img\n src={attachment.previewUrl}\n alt=\"\"\n aria-hidden=\"true\"\n className=\"h-8 w-8 rounded object-cover flex-shrink-0\"\n />\n ) : (\n <span\n aria-hidden=\"true\"\n className=\"flex h-8 w-8 items-center justify-center rounded bg-secondary text-[10px] font-semibold uppercase text-secondary-foreground flex-shrink-0\"\n >\n {(attachment.type ?? attachment.name.split('.').pop() ?? '?').slice(0, 4)}\n </span>\n )}\n\n <div className=\"min-w-0 flex-1\">\n <div className=\"truncate font-medium text-foreground\" title={attachment.name}>\n {attachment.name}\n </div>\n <div className=\"text-xs text-muted-foreground\">\n {attachment.status === 'uploading'\n ? 'Uploading...'\n : [attachment.size, attachment.type].filter(Boolean).join(' · ') || null}\n </div>\n </div>\n\n {attachment.status === 'uploading' && (\n <Spinner size=\"sm\" label=\"Uploading\" aria-label=\"Uploading\" className=\"flex-shrink-0\" />\n )}\n\n {onRemove && (\n <button\n type=\"button\"\n onClick={() => onRemove(attachment)}\n aria-label={`Remove ${attachment.name}`}\n className=\"flex-shrink-0 rounded p-0.5 text-muted-foreground hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n ✕\n </button>\n )}\n </div>\n );\n }\n);\nAttachment.displayName = 'Attachment';\n\nexport { Attachment };\n","import * as React from 'react';\nimport { cn } from '@slipstream-ui/core';\nimport { Attachment } from './Attachment';\nimport type { AttachmentItem } from './Attachment';\n\nexport type AttachmentListProps = {\n attachments: AttachmentItem[];\n /** Passed through to every Attachment; omit to hide remove controls. */\n onRemove?: (attachment: AttachmentItem) => void;\n className?: string;\n};\n\nconst AttachmentList = React.forwardRef<HTMLDivElement, AttachmentListProps>(\n ({ attachments, onRemove, className, ...props }, ref) => {\n if (attachments.length === 0) {\n return null;\n }\n\n return (\n <div ref={ref} className={cn('flex flex-wrap gap-2', className)} {...props}>\n {attachments.map((attachment) => (\n <Attachment key={attachment.id} attachment={attachment} onRemove={onRemove} />\n ))}\n </div>\n );\n }\n);\nAttachmentList.displayName = 'AttachmentList';\n\nexport { AttachmentList };\n","'use client';\n\nimport * as React from 'react';\nimport ReactMarkdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport { cn } from '@slipstream-ui/core';\nimport { CodeBlock } from '../code-block';\nimport { closeIncompleteMarkdown } from './close-incomplete-markdown';\n\nexport type ResponseProps = {\n /** Markdown content to render. */\n children: string;\n /**\n * Repair unclosed emphasis/inline-code/fences while streaming so partial\n * chunks render cleanly (default true).\n */\n parseIncompleteMarkdown?: boolean;\n className?: string;\n};\n\n/**\n * Streaming-optimized markdown renderer for AI responses.\n *\n * Wraps react-markdown with GFM support and routes fenced code blocks to\n * the CodeBlock component for highlighting + copy.\n */\nconst Response = React.forwardRef<HTMLDivElement, ResponseProps>(\n ({ children, parseIncompleteMarkdown = true, className, ...props }, ref) => {\n const content = React.useMemo(\n () => (parseIncompleteMarkdown ? closeIncompleteMarkdown(children) : children),\n [children, parseIncompleteMarkdown]\n );\n\n return (\n <div\n ref={ref}\n className={cn(\n 'text-sm space-y-3 [&_a]:text-primary [&_a]:underline underline-offset-2',\n '[&_ul]:list-disc [&_ul]:pl-5 [&_ol]:list-decimal [&_ol]:pl-5',\n '[&_h1]:text-lg [&_h1]:font-semibold [&_h2]:text-base [&_h2]:font-semibold',\n '[&_h3]:text-sm [&_h3]:font-semibold',\n '[&_blockquote]:border-l-2 [&_blockquote]:border-border [&_blockquote]:pl-3 [&_blockquote]:text-muted-foreground',\n '[&_table]:w-full [&_table]:text-xs [&_th]:border [&_th]:border-border [&_th]:p-1.5 [&_td]:border [&_td]:border-border [&_td]:p-1.5',\n className\n )}\n {...props}\n >\n <ReactMarkdown\n remarkPlugins={[remarkGfm]}\n components={{\n pre: ({ children }) => <>{children}</>,\n code: ({ className: codeClassName, children: codeChildren }) => {\n const raw = String(codeChildren).replace(/\\n$/, '');\n const match = /language-(\\w+)/.exec(codeClassName ?? '');\n const isInline = !match && !raw.includes('\\n');\n if (isInline) {\n return (\n <code className=\"bg-muted px-1 py-0.5 rounded text-xs font-mono before:content-none after:content-none\">\n {raw}\n </code>\n );\n }\n return <CodeBlock code={raw} language={match?.[1] ?? 'text'} />;\n },\n }}\n >\n {content}\n </ReactMarkdown>\n </div>\n );\n }\n);\nResponse.displayName = 'Response';\n\nexport { Response };\n","'use client';\n\nimport * as React from 'react';\nimport { Highlight, themes } from 'prism-react-renderer';\nimport { cn } from '@slipstream-ui/core';\n\nexport type CodeBlockProps = {\n /** Raw code to display (no trailing newline needed). */\n code: string;\n /** Language identifier used for Prism highlighting. */\n language?: string;\n /** Show a copy-to-clipboard button (default true). */\n showCopyButton?: boolean;\n className?: string;\n};\n\n/** Tracks whether the `.dark` class is present on `<html>`, staying in sync with toggles. */\nfunction useIsDark(): boolean {\n const [dark, setDark] = React.useState(false);\n\n React.useEffect(() => {\n const el = document.documentElement;\n setDark(el.classList.contains('dark'));\n const observer = new MutationObserver(() => setDark(el.classList.contains('dark')));\n observer.observe(el, { attributes: true, attributeFilter: ['class'] });\n return () => observer.disconnect();\n }, []);\n\n return dark;\n}\n\nconst CodeBlock = React.forwardRef<HTMLDivElement, CodeBlockProps>(\n ({ code, language = 'tsx', showCopyButton = true, className, ...props }, ref) => {\n const [copied, setCopied] = React.useState(false);\n const isDark = useIsDark();\n const trimmedCode = code.replace(/\\n$/, '');\n\n const handleCopy = async () => {\n try {\n await navigator.clipboard.writeText(trimmedCode);\n } catch {\n // Clipboard unavailable (insecure context); still show feedback so\n // consumers can hook onCopy-style behavior via DOM if needed.\n }\n setCopied(true);\n window.setTimeout(() => setCopied(false), 2000);\n };\n\n return (\n <div\n ref={ref}\n className={cn(\n // bg-background (not muted): Prism light themes assume a white\n // surface — on gray the comment/keyword tokens fall below AA.\n 'relative group rounded-md border border-border bg-background overflow-hidden',\n className\n )}\n {...props}\n >\n <div className=\"flex items-center justify-between px-3 py-1.5 border-b border-border bg-muted/60\">\n <span className=\"text-xs font-mono text-muted-foreground uppercase\">{language}</span>\n {showCopyButton && (\n <button\n type=\"button\"\n onClick={handleCopy}\n aria-label={copied ? 'Copied' : 'Copy code'}\n className=\"text-xs text-muted-foreground hover:text-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring rounded px-1\"\n >\n {copied ? 'Copied!' : 'Copy'}\n </button>\n )}\n </div>\n <Highlight theme={isDark ? themes.vsDark : themes.github} code={trimmedCode} language={language}>\n {({ style, tokens, getLineProps, getTokenProps }) => (\n <pre\n className=\"overflow-x-auto p-4 text-xs leading-relaxed m-0\"\n style={{ ...style, background: 'transparent' }}\n >\n {tokens.map((line, i) => (\n <div key={i} {...getLineProps({ line })}>\n {line.map((token, key) => (\n <span key={key} {...getTokenProps({ token })} />\n ))}\n </div>\n ))}\n </pre>\n )}\n </Highlight>\n </div>\n );\n }\n);\nCodeBlock.displayName = 'CodeBlock';\n\nexport { CodeBlock };\n","/**\n * Repairs markdown that is mid-stream: closes unclosed bold/italic/strikethrough\n * markers and unterminated inline code / code fences so partial chunks render\n * without flickering or broken syntax.\n *\n * Deliberately conservative — only appends closing characters, never rewrites content.\n */\nexport function closeIncompleteMarkdown(markdown: string): string {\n let text = markdown;\n\n // Close an unterminated fenced code block (odd number of ``` lines).\n const fenceMatches = text.match(/^`{3,}/gm);\n if (fenceMatches && fenceMatches.length % 2 === 1) {\n text = `${text}\\n\\`\\`\\``;\n }\n\n // Inline constructs are only repaired outside of code fences for simplicity:\n // if we just opened a fence, the remainder is code and should not be touched.\n const firstFence = text.indexOf('```');\n const hasUnclosedFence = fenceMatches !== null && fenceMatches.length % 2 === 1;\n const prose = hasUnclosedFence && firstFence !== -1 ? text.slice(0, firstFence) : text;\n const rest = hasUnclosedFence && firstFence !== -1 ? text.slice(firstFence) : '';\n\n let repaired = prose;\n // Count unescaped emphasis markers; close whichever are odd.\n for (const marker of ['**', '__', '~~']) {\n const occurrences = prose.split(marker).length - 1;\n if (occurrences % 2 === 1) {\n repaired += marker;\n }\n }\n // Single asterisk/underscore italics.\n for (const marker of ['*', '_']) {\n // Only count markers not part of **/__ pairs by stripping doubles first.\n const singles = repaired.replace(/\\*\\*/g, '').replace(/__/g, '').split(marker).length - 1;\n if (singles % 2 === 1) {\n repaired += marker;\n }\n }\n // Inline code.\n const backtickCount = repaired.replace(/```/g, '').split('`').length - 1;\n if (backtickCount % 2 === 1) {\n repaired += '`';\n }\n\n return repaired + rest;\n}\n","'use client';\n\nimport * as React from 'react';\nimport { Button } from '@slipstream-ui/core';\nimport { cn } from '@slipstream-ui/core';\n\nexport type ConfirmationStatus = 'pending' | 'approved' | 'rejected';\n\nexport type ConfirmationVariant = 'default' | 'warning' | 'destructive' | 'info' | 'success';\n\n/** Button variants accepted for the approve/reject actions (Button's variant union). */\nexport type ConfirmationActionVariant =\n | 'default'\n | 'destructive'\n | 'outline'\n | 'secondary'\n | 'ghost'\n | 'link';\n\nexport type ConfirmationProps = {\n /** Human-readable summary of the action requiring approval. */\n title: string;\n /** Optional detail: affected resource, arguments preview, risk note. */\n description?: string;\n /** Tool or action name shown as a mono chip. */\n toolName?: string;\n /** Controlled outcome; omit for fully interactive uncontrolled use. */\n status?: ConfirmationStatus;\n /** Accent color of the pending card (outcome chips always follow the result). */\n variant?: ConfirmationVariant;\n onApprove?: () => void;\n onReject?: () => void;\n /** Button styling for the approve/reject actions. */\n approveVariant?: ConfirmationActionVariant;\n rejectVariant?: ConfirmationActionVariant;\n /** Hide the action buttons (controlled-only gate; status drives the chip). */\n showActions?: boolean;\n labels?: {\n approve?: string;\n reject?: string;\n approved?: string;\n rejected?: string;\n };\n className?: string;\n};\n\nconst statusChipClasses: Record<ConfirmationStatus, string> = {\n pending: 'bg-warning/10 text-warning border-warning/20',\n approved: 'bg-success/10 text-success border-success/20',\n rejected: 'bg-destructive/10 text-destructive border-destructive/20',\n};\n\nconst pendingVariantClasses: Record<ConfirmationVariant, string> = {\n default: 'border-warning/40',\n warning: 'border-warning/40',\n destructive: 'border-destructive/40 bg-destructive/5',\n info: 'border-info/40',\n success: 'border-success/40',\n};\n\n/**\n * Human-in-the-loop approval gate for agent actions (tool execution,\n * destructive operations). The agent pauses until the user decides.\n */\nconst Confirmation = React.forwardRef<HTMLDivElement, ConfirmationProps>(\n (\n {\n title,\n description,\n toolName,\n status: controlledStatus,\n variant = 'default',\n onApprove,\n onReject,\n approveVariant = 'default',\n rejectVariant = 'outline',\n showActions = true,\n labels,\n className,\n ...props\n },\n ref\n ) => {\n const [internalStatus, setInternalStatus] = React.useState<ConfirmationStatus>('pending');\n const status = controlledStatus ?? internalStatus;\n\n const t = {\n approve: labels?.approve ?? 'Approve',\n reject: labels?.reject ?? 'Reject',\n approved: labels?.approved ?? 'Approved',\n rejected: labels?.rejected ?? 'Rejected',\n };\n\n const decide = (next: Exclude<ConfirmationStatus, 'pending'>) => {\n setInternalStatus(next);\n (next === 'approved' ? onApprove : onReject)?.();\n };\n\n return (\n <div\n ref={ref}\n role={status === 'pending' ? 'alertdialog' : undefined}\n aria-label={status === 'pending' ? title : undefined}\n className={cn(\n 'rounded-lg border p-4 bg-muted/30 max-w-md',\n status === 'pending' && pendingVariantClasses[variant],\n className\n )}\n {...props}\n >\n <div className=\"flex items-center justify-between gap-2 mb-2\">\n <div className=\"text-sm font-medium text-foreground\">{title}</div>\n <span\n className={cn(\n 'text-xs px-2 py-0.5 rounded-full border whitespace-nowrap',\n statusChipClasses[status]\n )}\n >\n {status === 'approved' ? t.approved : status === 'rejected' ? t.rejected : 'Pending'}\n </span>\n </div>\n\n {description && (\n <div className=\"text-sm text-muted-foreground mb-1\">{description}</div>\n )}\n {toolName && (\n <div className=\"text-xs font-mono text-muted-foreground mb-3\">{toolName}</div>\n )}\n\n {status === 'pending' && showActions && (\n <div className=\"flex gap-2 mt-2\">\n <Button size=\"sm\" variant={approveVariant} onClick={() => decide('approved')}>\n {t.approve}\n </Button>\n <Button size=\"sm\" variant={rejectVariant} onClick={() => decide('rejected')}>\n {t.reject}\n </Button>\n </div>\n )}\n </div>\n );\n }\n);\nConfirmation.displayName = 'Confirmation';\n\nexport { Confirmation };\n","'use client';\n\nimport * as React from 'react';\nimport { cn } from '@slipstream-ui/core';\n\nexport type BranchProps = {\n /** Total number of message variants. Renders nothing when count < 2. */\n count: number;\n /** Zero-based index of the currently displayed variant. */\n selected?: number;\n /** Uncontrolled initial variant when `selected` is omitted. */\n defaultSelected?: number;\n onSelect?: (index: number) => void;\n labels?: { previous?: string; next?: string };\n className?: string;\n};\n\n/**\n * Variant navigation for branched messages (`‹ 2 / 3 ›`).\n * Purely presentational + minimal internal state; the consumer swaps content.\n */\nconst Branch = React.forwardRef<HTMLDivElement, BranchProps>(\n (\n { count, selected, defaultSelected = 0, onSelect, labels, className, ...props },\n ref\n ) => {\n const [internalIndex, setInternalIndex] = React.useState(defaultSelected);\n const isControlled = selected !== undefined;\n const index = Math.min(Math.max(isControlled ? selected : internalIndex, 0), count - 1);\n\n const t = {\n previous: labels?.previous ?? 'Previous response',\n next: labels?.next ?? 'Next response',\n };\n\n if (count < 2) return null;\n\n const goTo = (next: number) => {\n const clamped = Math.min(Math.max(next, 0), count - 1);\n if (!isControlled) setInternalIndex(clamped);\n onSelect?.(clamped);\n };\n\n return (\n <div\n ref={ref}\n className={cn('flex items-center gap-1 text-xs text-muted-foreground', className)}\n {...props}\n >\n <button\n type=\"button\"\n onClick={() => goTo(index - 1)}\n disabled={index === 0}\n aria-label={t.previous}\n className=\"rounded px-1 hover:bg-accent hover:text-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-40\"\n >\n ‹\n </button>\n <span aria-live=\"polite\" className=\"tabular-nums\">\n {index + 1} / {count}\n </span>\n <button\n type=\"button\"\n onClick={() => goTo(index + 1)}\n disabled={index === count - 1}\n aria-label={t.next}\n className=\"rounded px-1 hover:bg-accent hover:text-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-40\"\n >\n ›\n </button>\n </div>\n );\n }\n);\nBranch.displayName = 'Branch';\n\nexport { Branch };\n","import * as React from 'react';\nimport { cn } from '@slipstream-ui/core';\nimport type { SourceItem } from '../../types';\n\nexport type InlineCitationProps = {\n /** The cited source; powers the hover/focus preview card. */\n source: SourceItem;\n /** Citation text to wrap (defaults to the source title). */\n children?: React.ReactNode;\n className?: string;\n};\n\n/**\n * Perplexity-style inline citation: a superscript chip that reveals the\n * source snippet on hover or keyboard focus.\n */\nconst InlineCitation = React.forwardRef<HTMLSpanElement, InlineCitationProps>(\n ({ source, children, className, ...props }, ref) => {\n return (\n <span\n ref={ref}\n className={cn('group relative inline focus-within:outline-none', className)}\n {...props}\n >\n <button\n type=\"button\"\n aria-describedby={`citation-${source.id}-card`}\n className=\"inline-flex items-baseline rounded-sm text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n {children ?? <span>{source.title}</span>}\n <span\n aria-hidden=\"true\"\n className=\"inline-flex items-center justify-center align-super ml-0.5 h-4 min-w-4 px-1 rounded-full border border-border bg-muted text-[10px] font-medium text-muted-foreground group-hover:text-foreground transition-colors\"\n >\n {source.title.charAt(0).toUpperCase()}\n </span>\n </button>\n <span\n id={`citation-${source.id}-card`}\n role=\"tooltip\"\n className=\"pointer-events-none absolute bottom-full left-1/2 z-10 mb-1 -translate-x-1/2 w-64 rounded-md border border-border bg-popover p-2.5 text-xs text-popover-foreground shadow-md opacity-0 group-hover:opacity-100 focus-within:opacity-100 transition-opacity\"\n >\n <span className=\"block font-medium text-foreground truncate\">{source.title}</span>\n {source.snippet && (\n <span className=\"mt-0.5 block text-muted-foreground line-clamp-3\">\n {source.snippet}\n </span>\n )}\n </span>\n </span>\n );\n }\n);\nInlineCitation.displayName = 'InlineCitation';\n\nexport { InlineCitation };\n","'use client';\n\nimport * as React from 'react';\nimport { cn } from '@slipstream-ui/core';\nimport { Message } from '../message';\nimport type { Message as MessageType } from '../../types';\n\nexport type ConversationProps = {\n messages: MessageType[];\n className?: string;\n showAvatars?: boolean;\n userAvatarSrc?: string;\n userAvatarFallback?: string;\n assistantAvatarSrc?: string;\n assistantAvatarFallback?: string;\n isLoading?: boolean;\n loadingMessage?: string;\n /** Custom content renderer applied to every message (e.g. markdown). */\n renderContent?: (content: string) => React.ReactNode;\n /** ID of the message still being generated; renders its streaming cursor. */\n streamingMessageId?: string;\n /**\n * Show a floating \"scroll to latest\" pill when the user has scrolled up.\n * Default true.\n */\n showScrollButton?: boolean;\n /** Show a download button that exports the transcript as Markdown. Default false. */\n showDownload?: boolean;\n /** Per-message generation failures keyed by message id; renders retry cards. */\n messageErrors?: Record<string, string>;\n /** Retry handler for failed messages in `messageErrors`. */\n onRetryMessage?: (message: MessageType) => void;\n\n // --- Empty state -------------------------------------------------------\n /** Heading for the empty-transcript welcome state. */\n welcomeTitle?: string;\n /** Supporting copy for the welcome state. */\n welcomeDescription?: string;\n /** Starter prompts rendered as buttons under the welcome copy. */\n welcomeSuggestions?: string[];\n /** Called with the chosen starter prompt text. */\n onWelcomeSelect?: (prompt: string) => void;\n\n // --- History pagination --------------------------------------------------\n /** Older history exists; renders a \"load earlier\" control at the top. */\n hasMoreHistory?: boolean;\n /** Older history request is in flight; shows a loading row. */\n isLoadingMore?: boolean;\n /** Called when the user requests older history. */\n onLoadMore?: () => void;\n};\n\n/** Distance (px) from the bottom within which the view counts as \"pinned\". */\nconst PINNED_THRESHOLD = 80;\n\nconst DEFAULT_WELCOME_TITLE = 'Start the conversation';\nconst DEFAULT_WELCOME_DESCRIPTION = 'Ask anything — responses stream in real time.';\nconst DEFAULT_WELCOME_SUGGESTIONS = [\n 'Explain what you can do',\n 'Summarize a topic for me',\n];\n\nfunction transcriptToMarkdown(messages: MessageType[]): string {\n return messages\n .map((message) => {\n const speaker =\n message.role === 'user' ? 'You' : message.role === 'assistant' ? 'Assistant' : message.role;\n const time = message.timestamp ? ` (${new Date(message.timestamp).toISOString()})` : '';\n return `**${speaker}${time}:**\\n\\n${message.content}`;\n })\n .join('\\n\\n---\\n\\n');\n}\n\nconst Conversation = React.forwardRef<HTMLDivElement, ConversationProps>(\n ({\n messages,\n className,\n showAvatars = true,\n userAvatarSrc,\n userAvatarFallback,\n assistantAvatarSrc,\n assistantAvatarFallback,\n isLoading = false,\n loadingMessage = 'Thinking...',\n renderContent,\n streamingMessageId,\n showScrollButton = true,\n showDownload = false,\n messageErrors,\n onRetryMessage,\n welcomeTitle = DEFAULT_WELCOME_TITLE,\n welcomeDescription = DEFAULT_WELCOME_DESCRIPTION,\n welcomeSuggestions = DEFAULT_WELCOME_SUGGESTIONS,\n onWelcomeSelect,\n hasMoreHistory = false,\n isLoadingMore = false,\n onLoadMore,\n ...props\n }, ref) => {\n const scrollRef = React.useRef<HTMLDivElement>(null);\n const messagesEndRef = React.useRef<HTMLDivElement>(null);\n const [isUnpinned, setIsUnpinned] = React.useState(false);\n const prevScrollMetrics = React.useRef<{ height: number; top: number } | null>(null);\n\n // Announce stream completion to assistive tech: when the streaming id\n // transitions from set to unset, a response just finished.\n const [announcement, setAnnouncement] = React.useState('');\n const prevStreamingRef = React.useRef<string | undefined>(undefined);\n React.useEffect(() => {\n if (prevStreamingRef.current && !streamingMessageId) {\n setAnnouncement('Response complete.');\n }\n prevStreamingRef.current = streamingMessageId;\n }, [streamingMessageId]);\n\n // Track pinned state on scroll so the jump-to-latest pill can appear.\n React.useEffect(() => {\n const container = scrollRef.current;\n if (!container) return;\n\n const updatePinned = () => {\n const distanceFromBottom =\n container.scrollHeight - container.scrollTop - container.clientHeight;\n setIsUnpinned(distanceFromBottom > PINNED_THRESHOLD);\n };\n\n updatePinned();\n container.addEventListener('scroll', updatePinned, { passive: true });\n return () => container.removeEventListener('scroll', updatePinned);\n }, []);\n\n // Scroll anchoring across history loads: capture metrics before new rows\n // render, then restore the same visual position after they land.\n React.useLayoutEffect(() => {\n const container = scrollRef.current;\n if (!container || prevScrollMetrics.current === null) return;\n\n const { height, top } = prevScrollMetrics.current;\n container.scrollTop = container.scrollHeight - height + top;\n prevScrollMetrics.current = null;\n }, [messages]);\n\n const captureAnchor = () => {\n const container = scrollRef.current;\n if (!container) return;\n prevScrollMetrics.current = { height: container.scrollHeight, top: container.scrollTop };\n };\n\n const handleLoadMore = () => {\n captureAnchor();\n onLoadMore?.();\n };\n\n // Auto-scroll only when the user is already near the bottom, so reading\n // history is never yanked. During streaming use instant scrolls; smooth\n // animations restarted per token cause jank.\n //\n // Scroll the container itself (never scrollIntoView): scrollIntoView\n // bubbles through every scrollable ancestor, including the document,\n // which yanked the whole page when the demo/preview frames were small.\n React.useEffect(() => {\n const container = scrollRef.current;\n if (!container) return;\n\n const distanceFromBottom =\n container.scrollHeight - container.scrollTop - container.clientHeight;\n if (distanceFromBottom > PINNED_THRESHOLD) return;\n\n container.scrollTo?.({\n top: container.scrollHeight,\n behavior: streamingMessageId ? 'auto' : 'smooth',\n });\n }, [messages, streamingMessageId]);\n\n const scrollToLatest = () => {\n const container = scrollRef.current;\n if (!container) return;\n container.scrollTo?.({ top: container.scrollHeight, behavior: 'smooth' });\n };\n\n const handleDownload = () => {\n const blob = new Blob([transcriptToMarkdown(messages)], { type: 'text/markdown' });\n const url = URL.createObjectURL(blob);\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.download = 'conversation.md';\n anchor.click();\n URL.revokeObjectURL(url);\n };\n\n const isEmpty = messages.length === 0 && !isLoading;\n\n return (\n <div ref={ref} className={cn('relative h-full w-full', className)} {...props}>\n <div ref={scrollRef} className=\"flex flex-col gap-4 p-4 overflow-y-auto h-full\">\n {(hasMoreHistory || isLoadingMore) && (\n <button\n type=\"button\"\n onClick={handleLoadMore}\n disabled={isLoadingMore}\n className=\"mx-auto rounded-full border border-border bg-background px-3 py-1 text-xs text-muted-foreground hover:text-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-50\"\n >\n {isLoadingMore ? 'Loading…' : 'Load earlier messages'}\n </button>\n )}\n\n {isEmpty ? (\n <div className=\"flex flex-1 flex-col items-center justify-center gap-3 text-center py-16\">\n <h3 className=\"text-lg font-semibold\">{welcomeTitle}</h3>\n <p className=\"text-sm text-muted-foreground max-w-sm\">{welcomeDescription}</p>\n {welcomeSuggestions.length > 0 && (\n <div className=\"mt-2 flex flex-col gap-2 w-full max-w-sm\">\n {welcomeSuggestions.map((suggestion) => (\n <button\n key={suggestion}\n type=\"button\"\n onClick={() => onWelcomeSelect?.(suggestion)}\n className=\"rounded-md border border-border bg-background px-4 py-2.5 text-sm text-left text-muted-foreground hover:bg-accent hover:text-accent-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n {suggestion}\n </button>\n ))}\n </div>\n )}\n </div>\n ) : (\n messages.map((message) => (\n <Message\n key={message.id}\n message={message}\n showAvatar={showAvatars}\n avatarSrc={\n message.role === 'user' ? userAvatarSrc : assistantAvatarSrc\n }\n avatarFallback={\n message.role === 'user' ? userAvatarFallback : assistantAvatarFallback\n }\n renderContent={renderContent}\n isStreaming={message.id === streamingMessageId}\n error={messageErrors?.[message.id]}\n onRetry={\n onRetryMessage && messageErrors?.[message.id]\n ? () => onRetryMessage(message)\n : undefined\n }\n />\n ))\n )}\n\n {isLoading && !isEmpty && (\n <Message\n message={{\n id: '__loading__',\n role: 'assistant',\n content: loadingMessage,\n }}\n showAvatar={showAvatars}\n avatarSrc={assistantAvatarSrc}\n avatarFallback={assistantAvatarFallback}\n className=\"bg-muted/50\"\n renderContent={(content) => (\n <span className=\"text-muted-foreground animate-pulse motion-reduce:animate-none\">{content}</span>\n )}\n />\n )}\n\n {/* Screen-reader announcement when a streamed response completes. */}\n <div aria-live=\"polite\" className=\"sr-only\">{announcement}</div>\n\n <div ref={messagesEndRef} />\n </div>\n\n {showDownload && messages.length > 0 && (\n <button\n type=\"button\"\n onClick={handleDownload}\n aria-label=\"Download transcript\"\n className=\"absolute top-2 right-2 z-10 rounded-md border border-border bg-background/90 px-2 py-1 text-xs text-muted-foreground hover:text-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n ↓ .md\n </button>\n )}\n\n {showScrollButton && isUnpinned && (\n <button\n type=\"button\"\n onClick={scrollToLatest}\n aria-label=\"Scroll to latest message\"\n className=\"absolute bottom-3 left-1/2 z-10 -translate-x-1/2 rounded-full border border-border bg-background/95 px-3 py-1.5 text-xs font-medium shadow-sm hover:bg-accent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n ↓ Latest\n </button>\n )}\n </div>\n );\n }\n);\n\nConversation.displayName = 'Conversation';\n\nexport { Conversation };\n","'use client';\n\nimport * as React from 'react';\nimport { Button } from '@slipstream-ui/core';\nimport { cn } from '@slipstream-ui/core';\nimport { AttachmentList } from '../attachment';\nimport type { AttachmentItem } from '../attachment';\n\n// ---------------------------------------------------------------------------\n// Attachments hook: validation + state, reusable outside the input.\n// ---------------------------------------------------------------------------\n\nexport type UseAttachmentsOptions = {\n /** File types to accept, e.g. \"image/*\" (HTML accept syntax). */\n accept?: string;\n /** Maximum number of queued files. */\n maxFiles?: number;\n /** Maximum size per file in bytes. */\n maxFileSize?: number;\n multiple?: boolean;\n onError?: (error: { code: 'max_files' | 'max_file_size' | 'accept'; message: string }) => void;\n};\n\nexport type UseAttachmentsResult = {\n files: AttachmentItem[];\n add: (fileList: FileList | File[]) => void;\n remove: (id: string) => void;\n clear: () => void;\n openFileDialog: () => void;\n /** Hidden file input element; render it once somewhere in your tree. */\n input: React.ReactElement;\n};\n\n/**\n * Headless attachment queue with constraint validation.\n * Used internally by PromptInput and exported for custom composers.\n */\nexport function usePromptInputAttachments(options: UseAttachmentsOptions = {}): UseAttachmentsResult {\n const { accept, maxFiles, maxFileSize, multiple = true, onError } = options;\n const [files, setFiles] = React.useState<AttachmentItem[]>([]);\n const inputRef = React.useRef<HTMLInputElement>(null);\n\n const add = React.useCallback(\n (fileList: FileList | File[]) => {\n const incoming = Array.from(fileList);\n setFiles((prev) => {\n const next = [...prev];\n for (const file of incoming) {\n if (accept && !file.type.match(accept.replace(/\\*/g, '.*'))) {\n onError?.({ code: 'accept', message: `\"${file.name}\" is not an accepted file type.` });\n continue;\n }\n if (maxFileSize && file.size > maxFileSize) {\n onError?.({\n code: 'max_file_size',\n message: `\"${file.name}\" exceeds the ${Math.round(maxFileSize / 1024)} KB limit.`,\n });\n continue;\n }\n if (maxFiles !== undefined && next.length >= maxFiles) {\n onError?.({ code: 'max_files', message: `At most ${maxFiles} files can be attached.` });\n break;\n }\n if (!multiple && next.length >= 1) {\n onError?.({ code: 'max_files', message: 'Only one file can be attached.' });\n break;\n }\n next.push({\n id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,\n name: file.name,\n size: `${Math.max(1, Math.round(file.size / 1024))} KB`,\n type: file.type.split('/')[1]?.toUpperCase() ?? file.name.split('.').pop()?.toUpperCase(),\n });\n }\n return next;\n });\n },\n [accept, maxFileSize, maxFiles, multiple, onError]\n );\n\n const remove = React.useCallback((id: string) => {\n setFiles((prev) => prev.filter((file) => file.id !== id));\n }, []);\n\n const clear = React.useCallback(() => setFiles([]), []);\n\n const openFileDialog = React.useCallback(() => inputRef.current?.click(), []);\n\n const input = (\n <input\n ref={inputRef}\n type=\"file\"\n hidden\n accept={accept}\n multiple={multiple}\n onChange={(event) => {\n if (event.target.files) add(event.target.files);\n event.target.value = '';\n }}\n />\n );\n\n return { files, add, remove, clear, openFileDialog, input };\n}\n\n// ---------------------------------------------------------------------------\n// Speech recognition (Web Speech API), no-op where unsupported.\n// ---------------------------------------------------------------------------\n\ntype SpeechRecognitionLike = {\n lang: string;\n continuous: boolean;\n interimResults: boolean;\n start: () => void;\n stop: () => void;\n onresult: ((event: { results: ArrayLike<ArrayLike<{ transcript: string }>> }) => void) | null;\n onend: (() => void) | null;\n};\n\ntype SpeechRecognitionCtor = new () => SpeechRecognitionLike;\n\n/** Web Speech API dictation; returns supported=false on unsupported browsers. */\nexport function useSpeechRecognition(onTranscript: (text: string) => void): {\n supported: boolean;\n isListening: boolean;\n toggle: () => void;\n} {\n const [isListening, setIsListening] = React.useState(false);\n // Cast through unknown: Safari prefixes webkitSpeechRecognition.\n const Ctor =\n typeof window !== 'undefined'\n ? ((window as unknown as Record<string, SpeechRecognitionCtor | undefined>).SpeechRecognition ??\n (window as unknown as Record<string, SpeechRecognitionCtor | undefined>).webkitSpeechRecognition)\n : undefined;\n\n const recognitionRef = React.useRef<SpeechRecognitionLike | null>(null);\n\n const toggle = React.useCallback(() => {\n if (!Ctor) return;\n if (isListening) {\n recognitionRef.current?.stop();\n setIsListening(false);\n return;\n }\n const recognition = new Ctor();\n recognition.lang = navigator.language || 'en-US';\n recognition.continuous = false;\n recognition.interimResults = false;\n recognition.onresult = (event) => {\n const transcript = Array.from({ length: event.results.length }, (_, i) => event.results[i][0].transcript).join(' ');\n onTranscript(transcript.trim());\n };\n recognition.onend = () => setIsListening(false);\n recognitionRef.current = recognition;\n recognition.start();\n setIsListening(true);\n }, [Ctor, isListening, onTranscript]);\n\n return { supported: Boolean(Ctor), isListening, toggle };\n}\n\n// ---------------------------------------------------------------------------\n// Context shared by the compound primitives.\n// ---------------------------------------------------------------------------\n\ntype PromptInputContextValue = {\n value: string;\n setValue: (value: string) => void;\n disabled: boolean;\n isLoading: boolean;\n canSubmit: boolean;\n submit: () => void;\n stop: () => void;\n hasStop: boolean;\n attachments: AttachmentItem[];\n removeAttachment: (id: string) => void;\n addFiles: (files: FileList | File[]) => void;\n openFilePicker: () => void;\n hiddenInput: React.ReactElement;\n dictate: { supported: boolean; isListening: boolean; toggle: () => void };\n};\n\nconst PromptInputContext = React.createContext<PromptInputContextValue | null>(null);\n\nfunction usePromptInputContext(): PromptInputContextValue {\n const context = React.useContext(PromptInputContext);\n if (!context) throw new Error('PromptInput primitives must be rendered inside <PromptInput>.');\n return context;\n}\n\n// ---------------------------------------------------------------------------\n// Root\n// ---------------------------------------------------------------------------\n\nexport type PromptInputProps = {\n onSubmit: (value: string) => void;\n /** Called when the user requests to stop an in-flight generation. */\n onStop?: () => void;\n /**\n * Externally owned attachment queue. When omitted, PromptInput manages its\n * own queue with drag-and-drop + clipboard-paste support.\n */\n attachments?: AttachmentItem[];\n onRemoveAttachment?: (attachment: AttachmentItem) => void;\n /** Called whenever the managed attachment queue changes. */\n onAttachmentsChange?: (attachments: AttachmentItem[]) => void;\n /** Marks submission as failed; the send control reflects the error state. */\n hasError?: boolean;\n accept?: string;\n multiple?: boolean;\n maxFiles?: number;\n maxFileSize?: number;\n onAttachmentError?: UseAttachmentsOptions['onError'];\n /** Accept file drops anywhere on the document (default false). */\n globalDrop?: boolean;\n placeholder?: string;\n disabled?: boolean;\n isLoading?: boolean;\n className?: string;\n autoFocus?: boolean;\n maxLength?: number;\n showSendButton?: boolean;\n sendButtonText?: string;\n stopButtonText?: string;\n children?: React.ReactNode;\n};\n\nconst PromptInputRoot = React.forwardRef<HTMLTextAreaElement, PromptInputProps>(\n ({\n onSubmit,\n onStop,\n attachments: controlledAttachments,\n onRemoveAttachment,\n onAttachmentsChange,\n hasError = false,\n accept,\n multiple = true,\n maxFiles,\n maxFileSize,\n onAttachmentError,\n globalDrop = false,\n placeholder = 'Type your message...',\n disabled = false,\n isLoading = false,\n className,\n autoFocus = false,\n maxLength,\n showSendButton = true,\n sendButtonText = 'Send',\n stopButtonText = 'Stop generating',\n children,\n ...props\n }, ref) => {\n const [value, setValue] = React.useState('');\n const textareaRef = React.useRef<HTMLTextAreaElement>(null);\n\n const managed = usePromptInputAttachments({ accept, maxFiles, maxFileSize, multiple, onError: onAttachmentError });\n\n // Notify consumers of managed-queue changes.\n const prevManagedCount = React.useRef(0);\n React.useEffect(() => {\n if (!controlledAttachments && managed.files.length !== prevManagedCount.current) {\n prevManagedCount.current = managed.files.length;\n onAttachmentsChange?.(managed.files);\n }\n }, [managed.files, controlledAttachments, onAttachmentsChange]);\n\n const activeAttachments = controlledAttachments ?? managed.files;\n\n // Auto-focus on mount if requested\n React.useEffect(() => {\n if (autoFocus && textareaRef.current) textareaRef.current.focus();\n }, [autoFocus]);\n\n // Merge forwarded ref with internal handle (auto-resize needs it).\n React.useImperativeHandle(ref, () => textareaRef.current!);\n\n // Auto-resize textarea\n React.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 // Global drop: opt-in document-level listener.\n React.useEffect(() => {\n if (!globalDrop || controlledAttachments) return;\n const prevent = (event: DragEvent) => event.preventDefault();\n const drop = (event: DragEvent) => {\n event.preventDefault();\n if (event.dataTransfer?.files.length) managed.add(event.dataTransfer.files);\n };\n document.addEventListener('dragover', prevent);\n document.addEventListener('drop', drop);\n return () => {\n document.removeEventListener('dragover', prevent);\n document.removeEventListener('drop', drop);\n };\n }, [globalDrop, controlledAttachments, managed]);\n\n const canSubmit = Boolean(value.trim()) && !disabled && !isLoading;\n\n const handleSubmit = () => {\n const trimmedValue = value.trim();\n if (!trimmedValue || disabled || isLoading) return;\n onSubmit(trimmedValue);\n setValue('');\n if (textareaRef.current) textareaRef.current.style.height = 'auto';\n if (!controlledAttachments) managed.clear();\n };\n\n const handleStop = () => onStop?.();\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault();\n handleSubmit();\n }\n };\n\n const dictate = useSpeechRecognition((transcript) =>\n setValue((current) => (current ? `${current} ${transcript}` : transcript))\n );\n\n const contextValue: PromptInputContextValue = {\n value,\n setValue,\n disabled,\n isLoading,\n canSubmit,\n submit: handleSubmit,\n stop: handleStop,\n hasStop: Boolean(onStop),\n attachments: activeAttachments,\n removeAttachment: (id) => (controlledAttachments ? onRemoveAttachment?.({ id } as AttachmentItem) : managed.remove(id)),\n addFiles: (files) => !controlledAttachments && managed.add(files),\n openFilePicker: managed.openFileDialog,\n hiddenInput: managed.input,\n dictate,\n };\n\n const showStop = isLoading && Boolean(onStop);\n const submitIcon = showStop ? '■' : hasError ? '⚠' : '→';\n const submitLabel = showStop ? stopButtonText : hasError ? 'Failed — check message' : sendButtonText;\n\n const textarea = (\n <textarea\n ref={textareaRef}\n value={value}\n onChange={(event) => setValue(event.target.value)}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n disabled={disabled || isLoading}\n maxLength={maxLength}\n rows={1}\n className={cn(\n 'flex-1 resize-none rounded-md border border-input bg-background px-3 py-2 text-sm',\n 'placeholder:text-muted-foreground',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n 'min-h-[40px] max-h-[200px] overflow-y-auto'\n )}\n />\n );\n\n const sendButton = showSendButton ? (\n <Button\n onClick={showStop ? handleStop : handleSubmit}\n disabled={showStop ? false : !canSubmit || disabled}\n variant={showStop ? 'outline' : 'default'}\n size=\"icon\"\n type=\"button\"\n aria-label={submitLabel}\n >\n <span aria-hidden=\"true\">{submitIcon}</span>\n </Button>\n ) : null;\n\n // Drop/paste surface wraps everything in both modes.\n const dropHandlers = controlledAttachments\n ? {}\n : {\n onDrop: (event: React.DragEvent) => {\n event.preventDefault();\n if (event.dataTransfer.files.length) managed.add(event.dataTransfer.files);\n },\n onPaste: (event: React.ClipboardEvent) => {\n const files = event.clipboardData?.files;\n if (files && files.length > 0) {\n event.preventDefault();\n managed.add(files);\n }\n },\n };\n\n return (\n <PromptInputContext.Provider value={contextValue}>\n <div className={cn('flex flex-col gap-2', className)} {...dropHandlers} {...props}>\n {activeAttachments.length > 0 && (\n <AttachmentList\n attachments={activeAttachments}\n onRemove={controlledAttachments ? onRemoveAttachment : (a) => managed.remove(a.id)}\n />\n )}\n\n {children ? (\n <>\n {children}\n {managed.input}\n </>\n ) : (\n <>\n <div className=\"flex gap-2 items-end\">\n {textarea}\n {sendButton}\n </div>\n {managed.input}\n </>\n )}\n </div>\n </PromptInputContext.Provider>\n );\n }\n);\nPromptInputRoot.displayName = 'PromptInput';\n\n// ---------------------------------------------------------------------------\n// Compound primitives\n// ---------------------------------------------------------------------------\n\n/** Auto-resizing textarea bound to the prompt state. Accepts standard textarea props. */\nconst PromptInputTextarea = React.forwardRef<\n HTMLTextAreaElement,\n Omit<React.TextareaHTMLAttributes<HTMLTextAreaElement>, 'value' | 'onChange'>\n>(({ className, onKeyDown, ...props }, ref) => {\n const { value, setValue, disabled, isLoading, submit } = usePromptInputContext();\n return (\n <textarea\n ref={ref}\n value={value}\n onChange={(event) => setValue(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault();\n submit();\n }\n onKeyDown?.(event);\n }}\n disabled={disabled || isLoading}\n rows={1}\n className={cn(\n 'flex-1 resize-none rounded-md border border-input bg-background px-3 py-2 text-sm',\n 'placeholder:text-muted-foreground',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n 'min-h-[40px]',\n className\n )}\n {...props}\n />\n );\n});\nPromptInputTextarea.displayName = 'PromptInputTextarea';\n\n/** Status-aware submit control: send / stop / error icons chosen automatically. */\nconst PromptInputSubmit = React.forwardRef<HTMLButtonElement, { className?: string }>(({ className }, ref) => {\n const { canSubmit, isLoading, hasStop, submit, stop, disabled } = usePromptInputContext();\n return (\n <Button\n ref={ref}\n onClick={isLoading && hasStop ? stop : submit}\n disabled={isLoading && hasStop ? false : !canSubmit || disabled}\n variant={isLoading && hasStop ? 'outline' : 'default'}\n size=\"icon\"\n type=\"button\"\n aria-label={isLoading && hasStop ? 'Stop generating' : 'Send'}\n className={className}\n >\n <span aria-hidden=\"true\">{isLoading && hasStop ? '■' : '→'}</span>\n </Button>\n );\n});\nPromptInputSubmit.displayName = 'PromptInputSubmit';\n\n/** Toolbar row under the textarea. */\nfunction PromptInputFooter({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n return <div className={cn('flex items-center justify-between gap-2 pt-1', className)} {...props} />;\n}\n\n/** Left-aligned group of tools inside a footer. */\nfunction PromptInputTools({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n return <div className={cn('flex items-center gap-1', className)} {...props} />;\n}\n\n/** Row above the textarea (attachments, hints). */\nfunction PromptInputHeader({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n return <div className={cn('mb-1', className)} {...props} />;\n}\n\n/** Wrapper around the textarea row. */\nfunction PromptInputBody({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n return <div className={cn('flex gap-2 items-end', className)} {...props} />;\n}\n\nexport type PromptInputButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {\n /** Tooltip content; optionally includes a keyboard shortcut hint. */\n tooltip?: string | { content: React.ReactNode; shortcut?: string };\n active?: boolean;\n};\n\n/** Small toolbar button with optional tooltip and shortcut hint. */\nconst PromptInputButton = React.forwardRef<HTMLButtonElement, PromptInputButtonProps>(\n ({ tooltip, active = false, className, ...props }, ref) => {\n const tip = typeof tooltip === 'string' ? { content: tooltip } : tooltip;\n return (\n <span className=\"relative inline-flex group/tip\">\n <button\n ref={ref}\n type=\"button\"\n aria-pressed={active || undefined}\n className={cn(\n 'inline-flex h-7 items-center gap-1 rounded-md border border-transparent px-2 text-xs text-muted-foreground transition-colors',\n 'hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n active && 'border-border bg-muted text-foreground',\n className\n )}\n {...props}\n />\n {tip && (\n <span\n role=\"tooltip\"\n className=\"pointer-events-none absolute bottom-full left-0 mb-1 z-10 flex items-center gap-1 whitespace-nowrap rounded border border-border bg-popover px-2 py-0.5 text-[11px] text-popover-foreground opacity-0 shadow-sm transition-opacity group-hover/tip:opacity-100\"\n >\n {tip.content}\n {tip.shortcut && <kbd className=\"rounded bg-muted px-1 font-mono\">{tip.shortcut}</kbd>}\n </span>\n )}\n </span>\n );\n }\n);\nPromptInputButton.displayName = 'PromptInputButton';\n\n/** Dictation toggle using the Web Speech API; hidden when unsupported. */\nfunction PromptInputActionDictate({ labels }: { labels?: { start?: string; stop?: string } }) {\n const { dictate } = usePromptInputContext();\n if (!dictate.supported) return null;\n return (\n <PromptInputButton\n onClick={dictate.toggle}\n active={dictate.isListening}\n tooltip={{ content: dictate.isListening ? labels?.stop ?? 'Stop dictating' : labels?.start ?? 'Dictate' }}\n aria-label={dictate.isListening ? labels?.stop ?? 'Stop dictation' : labels?.start ?? 'Start dictation'}\n >\n <span aria-hidden=\"true\">🎙</span>\n </PromptInputButton>\n );\n}\n\n/** Opens the managed file picker with configured constraints. */\n\n/** Opens the managed file picker with configured constraints. */\nfunction PromptInputActionAddAttachments({ label = 'Add photos or files' }: { label?: string }) {\n const { openFilePicker } = usePromptInputContext();\n return (\n <PromptInputButton onClick={openFilePicker}>\n <span aria-hidden=\"true\">+</span>\n <span>{label}</span>\n </PromptInputButton>\n );\n}\n\nexport {\n PromptInputRoot as PromptInput,\n PromptInputTextarea,\n PromptInputSubmit,\n PromptInputFooter,\n PromptInputTools,\n PromptInputHeader,\n PromptInputBody,\n PromptInputButton,\n PromptInputActionDictate,\n PromptInputActionAddAttachments,\n};\n","'use client';\n\nimport * as React from 'react';\nimport { cn } from '@slipstream-ui/core';\nimport type { ReasoningStep } from '../../types';\n\nexport type ReasoningProps = {\n steps: ReasoningStep[];\n className?: string;\n collapsible?: boolean;\n defaultExpanded?: boolean;\n /** Elapsed thinking time, e.g. 4 (seconds) or \"4s\"; rendered in the header. */\n duration?: number | string;\n /** Marks reasoning as still arriving: animated header state. */\n isStreaming?: boolean;\n};\n\nconst Reasoning = React.forwardRef<HTMLDivElement, ReasoningProps>(\n ({ steps, className, collapsible = true, defaultExpanded = false, duration, isStreaming = false, ...props }, ref) => {\n const [isExpanded, setIsExpanded] = React.useState(defaultExpanded);\n const contentId = React.useId();\n\n if (steps.length === 0) {\n return null;\n }\n\n const headerText = [\n 'Reasoning',\n `(${steps.length} ${steps.length === 1 ? 'step' : 'steps'})`,\n typeof duration === 'number' ? `· ${duration}s` : duration ? `· ${duration}` : '',\n isStreaming ? '· thinking…' : '',\n ]\n .filter(Boolean)\n .join(' ');\n\n return (\n <div ref={ref} className={cn('border-l-2 border-muted-foreground/30 pl-4', className)} {...props}>\n {collapsible ? (\n <button\n onClick={() => setIsExpanded(!isExpanded)}\n className=\"flex items-center gap-2 text-sm font-medium text-muted-foreground hover:text-foreground transition-colors\"\n aria-expanded={isExpanded}\n aria-controls={contentId}\n >\n <span className={cn('transition-transform', isExpanded ? 'rotate-90' : '')}>▶</span>\n <span>{headerText}</span>\n {isStreaming && (\n <span className=\"flex gap-0.5\" aria-hidden=\"true\">\n {[0, 150, 300].map((delay) => (\n <span\n key={delay}\n className=\"h-1 w-1 rounded-full bg-muted-foreground animate-pulse motion-reduce:animate-none\"\n style={{ animationDelay: `${delay}ms` }}\n />\n ))}\n </span>\n )}\n </button>\n ) : null}\n\n {(isExpanded || !collapsible) && (\n <div id={contentId} className=\"mt-3 space-y-3\">\n {steps.map((step, index) => (\n <div key={step.id} className=\"flex gap-3\">\n <div className=\"w-3 h-3 rounded-full bg-primary/20 border-2 border-primary flex-shrink-0 mt-1\" />\n <div className=\"text-sm flex-1\">\n <div className=\"font-medium text-foreground mb-1\">Step {index + 1}</div>\n <div className=\"text-muted-foreground\">{step.content}</div>\n {step.timestamp && (\n <div className=\"text-xs text-muted-foreground mt-1\">\n {new Date(step.timestamp).toLocaleTimeString()}\n </div>\n )}\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n );\n }\n);\nReasoning.displayName = 'Reasoning';\n\nexport { Reasoning };\n","'use client';\n\nimport * as React from 'react';\nimport { cn } from '@slipstream-ui/core';\nimport type { ToolCall as ToolCallType } from '../../types';\n\nexport type ToolCallProps = {\n toolCall: ToolCallType;\n className?: string;\n showResult?: boolean;\n};\n\nconst statusChipClasses: Record<ToolCallType['status'], string> = {\n pending: 'bg-warning/10 text-warning border-warning/20',\n running: 'bg-info/10 text-info border-info/20',\n completed: 'bg-success/10 text-success border-success/20',\n failed: 'bg-destructive/10 text-destructive border-destructive/20',\n};\n\nconst statusLabels: Record<ToolCallType['status'], string> = {\n pending: 'Pending',\n running: 'Running',\n completed: 'Completed',\n failed: 'Failed',\n};\n\n/**\n * Displays a single tool invocation: name, status chip, serialized\n * arguments, optional result, and an error block on failure.\n */\nconst ToolCall = React.forwardRef<HTMLDivElement, ToolCallProps>(\n ({ toolCall, className, showResult = true, ...props }, ref) => {\n // Serialize once per tool-call change instead of on every render.\n const serializedArguments = React.useMemo(\n () => JSON.stringify(toolCall.arguments, null, 2),\n [toolCall.arguments]\n );\n const serializedResult = React.useMemo(() => {\n if (toolCall.result === undefined) return undefined;\n return typeof toolCall.result === 'string'\n ? toolCall.result\n : JSON.stringify(toolCall.result, null, 2);\n }, [toolCall.result]);\n\n return (\n <div\n ref={ref}\n className={cn(\n 'border rounded-lg p-4 bg-muted/30',\n className\n )}\n {...props}\n >\n <div className=\"flex items-center justify-between mb-3\">\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium text-sm\">{toolCall.name}</span>\n <span\n className={cn(\n 'text-xs px-2 py-0.5 rounded-full border',\n statusChipClasses[toolCall.status]\n )}\n >\n {statusLabels[toolCall.status]}\n </span>\n </div>\n <span className=\"text-xs text-muted-foreground\">{toolCall.id}</span>\n </div>\n\n <div className=\"space-y-2\">\n <div>\n <div className=\"text-xs font-medium text-muted-foreground mb-1\">Arguments</div>\n <pre className=\"text-xs bg-muted p-2 rounded overflow-x-auto\">\n <code>{serializedArguments}</code>\n </pre>\n </div>\n\n {showResult && serializedResult !== undefined && (\n <div>\n <div className=\"text-xs font-medium text-muted-foreground mb-1\">Result</div>\n <pre className=\"text-xs bg-muted p-2 rounded overflow-x-auto\">\n <code>{serializedResult}</code>\n </pre>\n </div>\n )}\n\n {toolCall.status === 'failed' && toolCall.error && (\n <div role=\"alert\">\n <div className=\"text-xs font-medium text-destructive mb-1\">Error</div>\n <pre className=\"text-xs bg-destructive/10 text-destructive p-2 rounded overflow-x-auto whitespace-pre-wrap\">\n <code>{toolCall.error}</code>\n </pre>\n </div>\n )}\n </div>\n </div>\n );\n }\n);\nToolCall.displayName = 'ToolCall';\n\nexport { ToolCall };\n","import * as React from 'react';\nimport { cn } from '@slipstream-ui/core';\nimport type { SourceItem } from '../../types';\n\nexport type SourceProps = {\n source: SourceItem;\n /**\n * 1-based citation marker rendered as a `[n]` prefix.\n * Omit to render the citation without numbering.\n */\n index?: number;\n className?: string;\n};\n\nconst Source = React.forwardRef<HTMLDivElement, SourceProps>(\n ({ source, index, className, ...props }, ref) => {\n return (\n <div ref={ref} className={cn('flex gap-2 items-start text-sm', className)} {...props}>\n {index !== undefined && (\n <span className=\"text-muted-foreground select-none\" aria-hidden=\"true\">\n [{index}]\n </span>\n )}\n <div className=\"flex-1 min-w-0\">\n <div className=\"font-medium text-foreground\">\n {source.url ? (\n <a\n href={source.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"hover:text-primary transition-colors\"\n >\n {source.title}\n </a>\n ) : (\n <span>{source.title}</span>\n )}\n </div>\n {source.snippet && (\n <div className=\"text-xs text-muted-foreground mt-1 line-clamp-2\">\n {source.snippet}\n </div>\n )}\n </div>\n </div>\n );\n }\n);\nSource.displayName = 'Source';\n\nexport { Source };\n","import * as React from 'react';\nimport { cn } from '@slipstream-ui/core';\nimport type { SourceItem } from '../../types';\nimport { Source } from './Source';\n\nexport type SourcesProps = {\n sources: SourceItem[];\n className?: string;\n maxDisplay?: number;\n /** Heading label; override for localization. */\n label?: string;\n};\n\nconst Sources = React.forwardRef<HTMLDivElement, SourcesProps>(\n ({ sources, className, maxDisplay = 3, label = 'Sources', ...props }, ref) => {\n const displaySources = maxDisplay ? sources.slice(0, maxDisplay) : sources;\n const hasMore = maxDisplay && sources.length > maxDisplay;\n\n if (sources.length === 0) {\n return null;\n }\n\n return (\n <div ref={ref} className={cn('mt-4 pt-4 border-t border-border', className)} {...props}>\n <div className=\"text-xs font-medium text-muted-foreground mb-2\">{label}</div>\n <div className=\"space-y-2\">\n {displaySources.map((source, index) => (\n <Source key={source.id} source={source} index={index + 1} />\n ))}\n {hasMore && (\n <div className=\"text-xs text-muted-foreground\">\n +{sources.length - (maxDisplay ?? 0)} more sources\n </div>\n )}\n </div>\n </div>\n );\n }\n);\nSources.displayName = 'Sources';\n\nexport { Sources };\n","import * as React from 'react';\nimport { cn } from '@slipstream-ui/core';\n\nexport type Suggestion = {\n id: string;\n text: string;\n type?: 'action' | 'query' | 'follow-up';\n};\n\nexport type SuggestionsProps = {\n suggestions: Suggestion[];\n onSelect?: (suggestion: Suggestion) => void;\n className?: string;\n maxDisplay?: number;\n};\n\nconst Suggestions = React.forwardRef<HTMLDivElement, SuggestionsProps>(\n ({ suggestions, onSelect, className, maxDisplay = 4, ...props }, ref) => {\n const displaySuggestions = maxDisplay ? suggestions.slice(0, maxDisplay) : suggestions;\n\n if (suggestions.length === 0) {\n return null;\n }\n\n return (\n <div ref={ref} className={cn('mt-4 space-y-2', className)} {...props}>\n {displaySuggestions.map((suggestion) => (\n <button\n key={suggestion.id}\n className={cn(\n 'w-full text-left h-auto py-2 px-3 text-sm rounded-md',\n 'hover:bg-accent hover:text-accent-foreground',\n 'transition-colors',\n 'text-muted-foreground',\n 'focus:outline-none focus:ring-2 focus:ring-ring'\n )}\n onClick={() => onSelect?.(suggestion)}\n >\n {suggestion.text}\n </button>\n ))}\n </div>\n );\n});\nSuggestions.displayName = 'Suggestions';\n\nexport { Suggestions };\n","import * as React from 'react';\nimport { cn } from '@slipstream-ui/core';\n\nexport type ChainThoughtStep = {\n id: string;\n content: string;\n status?: 'pending' | 'completed' | 'failed';\n};\n\nexport type ChainThoughtProps = {\n steps: ChainThoughtStep[];\n className?: string;\n compact?: boolean;\n};\n\nconst ChainThought = React.forwardRef<HTMLDivElement, ChainThoughtProps>(\n ({ steps, className, compact = false, ...props }, ref) => {\n if (steps.length === 0) {\n return null;\n }\n\n return (\n <div ref={ref} className={cn('space-y-2', className)} {...props}>\n {steps.map((step, index) => (\n <div key={step.id} className=\"flex gap-3 items-start\">\n <div className={cn(\n 'w-2 h-2 rounded-full mt-1.5 flex-shrink-0',\n step.status === 'completed' ? 'bg-success' : \n step.status === 'failed' ? 'bg-destructive' : \n step.status === 'pending' ? 'bg-warning' : 'bg-primary'\n )} />\n <div className={cn('flex-1', compact && 'text-sm')}>\n <div className=\"text-sm text-muted-foreground\">\n Step {index + 1}\n </div>\n <div className=\"text-foreground\">{step.content}</div>\n </div>\n </div>\n ))}\n </div>\n );\n});\nChainThought.displayName = 'ChainThought';\n\nexport { ChainThought };\n","import * as React from 'react';\nimport { cn } from '@slipstream-ui/core';\n\nexport type StreamingIndicatorProps = {\n isStreaming: boolean;\n className?: string;\n text?: string;\n};\n\n/**\n * Animated three-dot streaming indicator. Announces the streaming state\n * to screen readers via role=\"status\" / aria-live so assistive tech\n * users know generation is in progress.\n */\nconst StreamingIndicator = React.forwardRef<HTMLDivElement, StreamingIndicatorProps>(\n ({ isStreaming, className, text = 'Generating...', ...props }, ref) => {\n if (!isStreaming) {\n return null;\n }\n\n return (\n <div\n ref={ref}\n role=\"status\"\n aria-live=\"polite\"\n aria-label={text}\n className={cn('flex items-center gap-2 text-sm text-muted-foreground', className)}\n {...props}\n >\n <div className=\"flex gap-1\" aria-hidden=\"true\">\n {[0, 150, 300].map((delay) => (\n <span\n key={delay}\n className=\"w-2 h-2 bg-primary rounded-full animate-pulse motion-reduce:animate-none\"\n style={{ animationDelay: `${delay}ms` }}\n />\n ))}\n </div>\n <span>{text}</span>\n </div>\n );\n }\n);\nStreamingIndicator.displayName = 'StreamingIndicator';\n\nexport { StreamingIndicator };\n","'use client';\n\nimport * as React from 'react';\nimport { cn } from '@slipstream-ui/core';\n\nexport type Command = {\n id: string;\n label: string;\n /** Optional grouping header, e.g. \"Navigation\". */\n section?: string;\n /** Extra lexical search terms. */\n keywords?: string[];\n shortcut?: string;\n};\n\nexport type CommandPaletteProps = {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n commands: Command[];\n onSelect: (command: Command) => void;\n placeholder?: string;\n};\n\n/**\n * Cmd+K command palette: combobox + listbox with aria-activedescendant\n * keyboard navigation, lexical filtering over label/keywords, and\n * Escape-to-close. No focus leaves the input while navigating.\n */\nexport function CommandPalette({\n open,\n onOpenChange,\n commands,\n onSelect,\n placeholder = 'Type a command…',\n}: CommandPaletteProps) {\n const [query, setQuery] = React.useState('');\n const [activeIndex, setActiveIndex] = React.useState(0);\n const inputRef = React.useRef<HTMLInputElement | null>(null);\n const listboxId = React.useId();\n const optionId = (index: number) => `${listboxId}-option-${index}`;\n\n const filtered = React.useMemo(() => {\n const terms = query.trim().toLowerCase().split(/\\s+/).filter(Boolean);\n if (terms.length === 0) return commands;\n return commands.filter((command) => {\n const haystack = `${command.label} ${command.section ?? ''} ${(command.keywords ?? []).join(' ')}`.toLowerCase();\n return terms.every((term) => haystack.includes(term));\n });\n }, [commands, query]);\n\n React.useEffect(() => {\n if (open) {\n setQuery('');\n setActiveIndex(0);\n // Focus after paint so the portal/DOM node exists.\n const timer = setTimeout(() => inputRef.current?.focus(), 0);\n return () => clearTimeout(timer);\n }\n return undefined;\n }, [open]);\n\n React.useEffect(() => {\n setActiveIndex((index) => Math.min(index, Math.max(0, filtered.length - 1)));\n }, [filtered.length]);\n\n if (!open) return null;\n\n const onKeyDown = (event: React.KeyboardEvent) => {\n if (event.key === 'Escape') {\n event.preventDefault();\n onOpenChange(false);\n } else if (event.key === 'ArrowDown') {\n event.preventDefault();\n setActiveIndex((index) => (filtered.length === 0 ? 0 : (index + 1) % filtered.length));\n } else if (event.key === 'ArrowUp') {\n event.preventDefault();\n setActiveIndex((index) => (filtered.length === 0 ? 0 : (index - 1 + filtered.length) % filtered.length));\n } else if (event.key === 'Enter') {\n event.preventDefault();\n const command = filtered[activeIndex];\n if (command) {\n onSelect(command);\n onOpenChange(false);\n }\n }\n };\n\n let lastSection: string | undefined;\n\n return (\n <div\n className=\"fixed inset-0 z-50 flex items-start justify-center bg-background/80 p-4 pt-[15vh]\"\n onMouseDown={(event) => {\n if (event.target === event.currentTarget) onOpenChange(false);\n }}\n >\n <div className=\"w-full max-w-lg overflow-hidden rounded-xl border border-border bg-card shadow-2xl\">\n <input\n ref={inputRef}\n type=\"text\"\n role=\"combobox\"\n aria-expanded=\"true\"\n aria-controls={listboxId}\n aria-activedescendant={filtered.length > 0 ? optionId(activeIndex) : undefined}\n aria-autocomplete=\"list\"\n aria-label=\"Command palette\"\n placeholder={placeholder}\n value={query}\n onChange={(event) => {\n setQuery(event.target.value);\n setActiveIndex(0);\n }}\n onKeyDown={onKeyDown}\n className=\"w-full border-b border-border bg-transparent px-4 py-3 text-sm outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring placeholder:text-muted-foreground\"\n />\n <ul id={listboxId} role=\"listbox\" aria-label=\"Commands\" className=\"max-h-72 overflow-y-auto py-1\">\n {filtered.length === 0 && (\n <li role=\"presentation\" className=\"px-4 py-3 text-sm text-muted-foreground\">\n No matching commands.\n </li>\n )}\n {filtered.map((command, index) => {\n const showSection = command.section && command.section !== lastSection;\n lastSection = command.section ?? lastSection;\n return (\n <React.Fragment key={command.id}>\n {showSection && (\n <li role=\"presentation\" className=\"px-4 pb-1 pt-3 text-xs font-medium uppercase text-muted-foreground\">\n {command.section}\n </li>\n )}\n <li\n id={optionId(index)}\n role=\"option\"\n aria-selected={index === activeIndex}\n onMouseEnter={() => setActiveIndex(index)}\n onClick={() => {\n onSelect(command);\n onOpenChange(false);\n }}\n className={cn(\n 'flex cursor-pointer items-center justify-between px-4 py-2 text-sm',\n index === activeIndex ? 'bg-primary/10 text-foreground' : 'text-muted-foreground'\n )}\n >\n <span>{command.label}</span>\n {command.shortcut && <span className=\"font-mono text-xs\">{command.shortcut}</span>}\n </li>\n </React.Fragment>\n );\n })}\n </ul>\n </div>\n </div>\n );\n}\n","import type { Message as MessageData, ToolCall as ToolCallData } from '../types';\nimport type { AiSdkMessage, AiSdkToolInvocation } from './types';\n\n/** Map one AI SDK tool invocation to a Slipstream ToolCall data object. */\nexport function toSlipstreamToolCall(invocation: AiSdkToolInvocation): ToolCallData {\n const status =\n invocation.state === 'result' ? 'completed'\n : invocation.state === 'error' ? 'failed'\n : invocation.state === 'call' ? 'pending'\n : 'pending';\n return {\n id: invocation.toolCallId,\n name: invocation.toolName,\n arguments: invocation.args ?? {},\n status,\n ...(status === 'completed' && invocation.result !== undefined\n ? { result: invocation.result as ToolCallData['result'] }\n : {}),\n ...(status === 'failed'\n ? { error: invocation.error instanceof Error ? invocation.error.message : String(invocation.error ?? 'Tool call failed') }\n : {}),\n };\n}\n\n/** Extract every tool call carried by an AI SDK message. */\nexport function toSlipstreamToolCalls(message: AiSdkMessage): ToolCallData[] {\n return (message.toolInvocations ?? []).map(toSlipstreamToolCall);\n}\n\n/**\n * Map one AI SDK message onto a Slipstream Message. Tool invocations are\n * preserved under `metadata.toolCalls` (and via toSlipstreamToolCalls) so\n * ToolCall components can render them.\n */\nexport function toSlipstreamMessage(message: AiSdkMessage): MessageData {\n return {\n id: message.id,\n role: message.role,\n content: message.content,\n ...(message.toolInvocations?.length\n ? { metadata: { toolCalls: toSlipstreamToolCalls(message) } }\n : {}),\n };\n}\n\n/** Map a useChat/useCompletion message list into Slipstream messages. */\nexport function toSlipstreamMessages(messages: AiSdkMessage[]): MessageData[] {\n return messages.map(toSlipstreamMessage);\n}\n","'use client';\n\nimport { useMemo } from 'react';\nimport type { Message as MessageData } from '../types';\nimport { toSlipstreamMessages } from './messages';\nimport type { AiSdkMessage, AiSdkStatus } from './types';\n\nexport type UseSlipstreamMessagesOptions = {\n /** `messages` from the AI SDK's useChat()/useCompletion() state. */\n messages: AiSdkMessage[];\n}\n\nexport type UseSlipstreamMessagesResult = {\n messages: MessageData[];\n};\n\n/**\n * Bridge AI SDK chat messages to Slipstream `<Conversation>`/`<Message>`\n * input. Pure derivation of the current state — safe to call from any\n * runtime that provides the structural message shape.\n */\nexport function useSlipstreamMessages({ messages }: UseSlipstreamMessagesOptions): UseSlipstreamMessagesResult {\n const mapped = useMemo(() => toSlipstreamMessages(messages), [messages]);\n return { messages: mapped };\n}\n\nexport type UseSlipstreamStreamOptions = {\n /** `status` from the AI SDK chat state. */\n status?: AiSdkStatus;\n /** `error` from the AI SDK chat state. */\n error?: unknown;\n /** Retry handler wired to the SDK's reload/retry (e.g. `reload`). */\n onRetry?: () => void;\n /** Messages from the SDK chat state; used to locate the streaming id. */\n messages?: AiSdkMessage[];\n};\n\nexport type UseSlipstreamStreamResult = {\n isLoading: boolean;\n streamingMessageId?: string;\n messageErrors?: Record<string, string>;\n onRetryMessage?: (messageId: string) => void;\n};\n\n/**\n * Bridge AI SDK stream status/error to Slipstream Conversation props:\n * `isLoading` gates the loading row, `streamingMessageId` drives the typing\n * cursor on the last assistant message, and errors map to retryable\n * per-message failures (streaming/tool states).\n */\nexport function useSlipstreamStream({\n status,\n error,\n onRetry,\n messages = [],\n}: UseSlipstreamStreamOptions): UseSlipstreamStreamResult {\n const isLoading = status === 'submitted' || status === 'streaming';\n const streamingMessageId = useMemo(() => {\n if (status !== 'streaming') return undefined;\n for (let index = messages.length - 1; index >= 0; index--) {\n const message = messages[index];\n if (message?.role === 'assistant') return message.id;\n }\n return messages.at(-1)?.id;\n }, [status, messages]);\n\n const messageErrors = useMemo(() => {\n if (status !== 'error' || !error) return undefined;\n const last = messages.at(-1);\n if (!last) return undefined;\n return {\n [last.id]: error instanceof Error ? error.message : String(error),\n };\n }, [status, error, messages]);\n\n return {\n isLoading,\n ...(streamingMessageId ? { streamingMessageId } : {}),\n ...(messageErrors ? { messageErrors } : {}),\n ...(onRetry ? { onRetryMessage: onRetry } : {}),\n };\n}\n"],"mappings":"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","names":["import_core","React","import_core","import_jsx_runtime","React","import_core","import_jsx_runtime","React","import_core","import_jsx_runtime","React","import_core","React","import_core","import_jsx_runtime","import_jsx_runtime","ReactMarkdown","remarkGfm","children","React","import_core","import_jsx_runtime","React","import_core","import_jsx_runtime","React","import_core","import_jsx_runtime","React","import_core","import_jsx_runtime","React","import_core","import_jsx_runtime","React","import_core","import_jsx_runtime","React","import_core","import_jsx_runtime","statusChipClasses","React","import_core","import_jsx_runtime","React","import_core","import_jsx_runtime","React","import_core","import_jsx_runtime","React","import_core","import_jsx_runtime","React","import_core","import_jsx_runtime","React","import_core","import_jsx_runtime"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/components/message/Message.tsx","../src/components/message-actions/MessageActions.tsx","../src/components/attachment/Attachment.tsx","../src/components/attachment/AttachmentList.tsx","../src/components/response/Response.tsx","../src/components/code-block/CodeBlock.tsx","../src/components/response/close-incomplete-markdown.ts","../src/components/confirmation/Confirmation.tsx","../src/components/branch/Branch.tsx","../src/components/inline-citation/InlineCitation.tsx","../src/components/conversation/Conversation.tsx","../src/components/prompt-input/PromptInput.tsx","../src/components/reasoning/Reasoning.tsx","../src/components/tool-call/ToolCall.tsx","../src/components/source/Source.tsx","../src/components/source/Sources.tsx","../src/components/suggestion/Suggestion.tsx","../src/components/chainthought/ChainThought.tsx","../src/components/streaming/StreamingIndicator.tsx","../src/components/command-palette/CommandPalette.tsx","../src/adapter/messages.ts","../src/adapter/hooks.ts"],"sourcesContent":["export type {\n MessageRole,\n ReasoningStep,\n SourceItem,\n} from './types';\n// Data-model aliases: exporting these under their bare names would collide\n// with same-named components in the bundled .d.ts output.\nexport type {\n Message as MessageData,\n ToolCall as ToolCallData,\n} from './types';\nexport * from './components/message';\nexport * from './components/message-actions';\nexport * from './components/attachment';\nexport * from './components/response';\nexport * from './components/code-block';\nexport * from './components/confirmation';\nexport * from './components/branch';\nexport * from './components/inline-citation';\nexport * from './components/conversation';\nexport * from './components/prompt-input';\nexport * from './components/reasoning';\nexport * from './components/tool-call';\nexport * from './components/source';\nexport * from './components/suggestion';\nexport * from './components/chainthought';\nexport * from './components/streaming';\nexport * from './components/command-palette';\nexport * from './adapter';\n","'use client';\n\nimport * as React from 'react';\nimport { Avatar, AvatarImage, AvatarFallback, Button } from '@slipstream-ui/core';\nimport { cn } from '@slipstream-ui/core';\nimport type { Message as MessageType } from '../../types';\n\nexport type MessageProps = {\n message: MessageType;\n className?: string;\n showAvatar?: boolean;\n avatarSrc?: string;\n avatarFallback?: string;\n /** Display name for the user role; override for localization. */\n userLabel?: string;\n /** Display name for the assistant role; override for localization. */\n assistantLabel?: string;\n /**\n * Custom content renderer, e.g. for markdown/code blocks.\n * When provided, it fully replaces the default plain-text rendering.\n */\n renderContent?: (content: string) => React.ReactNode;\n /**\n * Marks the response as still being generated: shows a typing cursor\n * and sets aria-busy so assistive tech knows more content is coming.\n */\n isStreaming?: boolean;\n /** Generation failure text; renders an error card in place of content. */\n error?: string;\n /** Called when the user requests a retry after `error`; omit to hide the action. */\n onRetry?: () => void;\n labels?: {\n retry?: string;\n edit?: string;\n save?: string;\n cancel?: string;\n };\n /**\n * Edit-and-resubmit affordance for user messages: renders an Edit action\n * that swaps content into an inline textarea and calls `onEditContent`.\n */\n onEditContent?: (content: string) => void;\n};\n\nconst Message = React.forwardRef<HTMLDivElement, MessageProps>(\n (\n {\n message,\n className,\n showAvatar = true,\n avatarSrc,\n avatarFallback,\n userLabel = 'You',\n assistantLabel = 'Assistant',\n renderContent,\n isStreaming = false,\n error,\n onRetry,\n onEditContent,\n labels,\n ...props\n },\n ref\n ) => {\n const [isEditing, setIsEditing] = React.useState(false);\n const [draft, setDraft] = React.useState(message.content);\n\n const t = {\n retry: labels?.retry ?? 'Retry',\n edit: labels?.edit ?? 'Edit',\n save: labels?.save ?? 'Save & resend',\n cancel: labels?.cancel ?? 'Cancel',\n };\n\n const isUser = message.role === 'user';\n const isSystem = message.role === 'system';\n const displayLabel = isUser\n ? userLabel\n : message.role === 'assistant'\n ? assistantLabel\n : message.role;\n\n const startEdit = () => {\n setDraft(message.content);\n setIsEditing(true);\n };\n\n const commitEdit = () => {\n const trimmed = draft.trim();\n if (!trimmed) return;\n setIsEditing(false);\n onEditContent?.(trimmed);\n };\n\n return (\n <div\n ref={ref}\n aria-busy={isStreaming || undefined}\n className={cn(\n 'flex gap-3 p-4 rounded-lg',\n isUser ? 'bg-primary/10' : 'bg-muted',\n isSystem && 'border-l-4 border-muted-foreground',\n error && 'border border-destructive/40',\n className\n )}\n {...props}\n >\n {showAvatar && !isSystem && (\n <Avatar className=\"h-8 w-8 flex-shrink-0\">\n {avatarSrc && <AvatarImage src={avatarSrc} alt={displayLabel} />}\n <AvatarFallback className={cn(\n 'text-xs font-medium',\n isUser ? 'bg-primary text-primary-foreground' : 'bg-secondary text-secondary-foreground'\n )}>\n {avatarFallback || (isUser ? 'U' : 'A')}\n </AvatarFallback>\n </Avatar>\n )}\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2 mb-1\">\n <span className=\"text-sm font-medium\">{displayLabel}</span>\n {message.timestamp && (\n <span className=\"text-xs text-muted-foreground\">\n {new Date(message.timestamp).toLocaleTimeString()}\n </span>\n )}\n </div>\n\n {error ? (\n <div role=\"alert\" className=\"text-sm\">\n <div className=\"text-destructive mb-2\">{error}</div>\n {onRetry && (\n <Button size=\"sm\" variant=\"outline\" onClick={onRetry}>\n ↻ {t.retry}\n </Button>\n )}\n </div>\n ) : isEditing ? (\n <div className=\"space-y-2\">\n <textarea\n value={draft}\n onChange={(event) => setDraft(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault();\n commitEdit();\n }\n if (event.key === 'Escape') setIsEditing(false);\n }}\n aria-label=\"Edit message\"\n autoFocus\n rows={Math.min(6, draft.split('\\n').length + 1)}\n className=\"w-full resize-none rounded-md border border-input bg-background px-3 py-2 text-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n />\n <div className=\"flex gap-2\">\n <Button size=\"sm\" onClick={commitEdit}>{t.save}</Button>\n <Button size=\"sm\" variant=\"ghost\" onClick={() => setIsEditing(false)}>{t.cancel}</Button>\n </div>\n </div>\n ) : (\n <div className=\"text-sm whitespace-pre-wrap break-words\">\n {renderContent ? (\n renderContent(message.content)\n ) : (\n <>\n {message.content}\n {isStreaming && (\n <span\n className=\"inline-block w-[2px] h-[1em] ml-0.5 align-text-bottom bg-current animate-pulse motion-reduce:animate-none\"\n data-testid=\"streaming-cursor\"\n />\n )}\n </>\n )}\n {onEditContent && !isStreaming && (\n <div>\n <button\n type=\"button\"\n onClick={startEdit}\n aria-label={t.edit}\n className=\"mt-1 rounded px-1 py-0.5 text-xs text-muted-foreground hover:bg-accent hover:text-accent-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n ✎ {t.edit}\n </button>\n </div>\n )}\n </div>\n )}\n </div>\n </div>\n );\n }\n);\nMessage.displayName = 'Message';\n\n/**\n * Memoized: during token streaming the parent re-renders on every tick, but\n * only the streaming message's object identity changes. Memo skips re-render\n * (and timestamp re-formatting) for every other message in the transcript.\n * Callback props must be referentially stable for memo to help.\n */\nconst MemoizedMessage = React.memo(Message);\nMemoizedMessage.displayName = 'Message';\n\nexport { MemoizedMessage as Message };\n","'use client';\n\nimport * as React from 'react';\nimport { cn } from '@slipstream-ui/core';\n\n/** User sentiment for an AI response. */\nexport type FeedbackRating = 'up' | 'down';\n\nexport type MessageActionsProps = {\n /**\n * Visibility rule:\n * - 'always': always visible (default)\n * - 'on-hover': fades in when the parent message is hovered/focused\n * (add the `group` class to the parent element)\n * - 'not-last': like 'on-hover', intended for non-latest messages\n */\n autohide?: 'always' | 'on-hover' | 'not-last';\n /**\n * Content to copy. Omit to hide the copy action, or pass a getter when\n * the content lives outside this component.\n */\n content?: string;\n /** Called after the user copies the message; receives the copied text. */\n onCopy?: (content: string) => void;\n /** Called with the selected rating; selecting the same rating clears it (passes undefined). */\n onFeedback?: (rating: FeedbackRating | undefined) => void;\n /** Called when the user requests a regenerated response; omit to hide the action. */\n onRegenerate?: () => void;\n labels?: {\n copy?: string;\n copied?: string;\n thumbUp?: string;\n thumbDown?: string;\n regenerate?: string;\n };\n className?: string;\n};\n\nconst MessageActions = React.forwardRef<HTMLDivElement, MessageActionsProps>(\n (\n { content, onCopy, onFeedback, onRegenerate, autohide = 'always', labels, className, ...props },\n ref\n ) => {\n const [copied, setCopied] = React.useState(false);\n const [rating, setRating] = React.useState<FeedbackRating | undefined>();\n\n const t = {\n copy: labels?.copy ?? 'Copy',\n copied: labels?.copied ?? 'Copied',\n thumbUp: labels?.thumbUp ?? 'Good response',\n thumbDown: labels?.thumbDown ?? 'Bad response',\n regenerate: labels?.regenerate ?? 'Regenerate',\n };\n\n const handleCopy = async () => {\n if (!content) return;\n try {\n await navigator.clipboard.writeText(content);\n } catch {\n // Clipboard API may be unavailable (insecure context); still notify so consumers can react.\n }\n setCopied(true);\n window.setTimeout(() => setCopied(false), 2000);\n onCopy?.(content);\n };\n\n const handleRating = (next: FeedbackRating) => {\n const updated = rating === next ? undefined : next;\n setRating(updated);\n onFeedback?.(updated);\n };\n\n const actionButton =\n 'rounded px-1.5 py-0.5 text-xs transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring';\n const actionButtonIdle =\n 'text-muted-foreground hover:bg-accent hover:text-accent-foreground';\n\n return (\n <div\n ref={ref}\n role=\"toolbar\"\n aria-label=\"Message actions\"\n className={cn(\n 'flex items-center gap-1 mt-2',\n autohide !== 'always' &&\n 'opacity-0 transition-opacity focus-within:opacity-100 group-hover:opacity-100 motion-reduce:opacity-100',\n className\n )}\n {...props}\n >\n {content !== undefined && (\n <button type=\"button\" onClick={handleCopy} className={cn(actionButton, actionButtonIdle)}>\n {copied ? t.copied : t.copy}\n </button>\n )}\n\n <button\n type=\"button\"\n onClick={() => handleRating('up')}\n aria-label={t.thumbUp}\n aria-pressed={rating === 'up'}\n className={cn(\n actionButton,\n rating === 'up' ? 'text-primary' : actionButtonIdle\n )}\n >\n 👍\n </button>\n\n <button\n type=\"button\"\n onClick={() => handleRating('down')}\n aria-label={t.thumbDown}\n aria-pressed={rating === 'down'}\n className={cn(\n actionButton,\n rating === 'down' ? 'text-destructive' : actionButtonIdle\n )}\n >\n 👎\n </button>\n\n {onRegenerate && (\n <button type=\"button\" onClick={onRegenerate} className={cn(actionButton, actionButtonIdle)}>\n {t.regenerate}\n </button>\n )}\n </div>\n );\n }\n);\nMessageActions.displayName = 'MessageActions';\n\nexport { MessageActions };\n","import * as React from 'react';\nimport { Spinner } from '@slipstream-ui/core';\nimport { cn } from '@slipstream-ui/core';\n\n/** A single file attached to a message or prompt. Display-only; upload logic stays consumer-side. */\nexport type AttachmentItem = {\n id: string;\n /** File name, including extension. */\n name: string;\n /** Human-readable size, e.g. \"2.4 MB\". */\n size?: string;\n /** MIME type or simple kind used for the chip label. */\n type?: string;\n /** Optional image thumbnail URL. */\n previewUrl?: string;\n status?: 'uploading' | 'done' | 'error';\n};\n\nexport type AttachmentProps = {\n attachment: AttachmentItem;\n /** Called when the user removes the attachment; omit to hide the remove control. */\n onRemove?: (attachment: AttachmentItem) => void;\n className?: string;\n};\n\nconst Attachment = React.forwardRef<HTMLDivElement, AttachmentProps>(\n ({ attachment, onRemove, className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n className={cn(\n 'inline-flex items-center gap-2 rounded-md border border-border bg-muted/50 px-2 py-1.5 text-sm max-w-xs',\n className\n )}\n {...props}\n >\n {attachment.previewUrl ? (\n <img\n src={attachment.previewUrl}\n alt=\"\"\n aria-hidden=\"true\"\n className=\"h-8 w-8 rounded object-cover flex-shrink-0\"\n />\n ) : (\n <span\n aria-hidden=\"true\"\n className=\"flex h-8 w-8 items-center justify-center rounded bg-secondary text-[10px] font-semibold uppercase text-secondary-foreground flex-shrink-0\"\n >\n {(attachment.type ?? attachment.name.split('.').pop() ?? '?').slice(0, 4)}\n </span>\n )}\n\n <div className=\"min-w-0 flex-1\">\n <div className=\"truncate font-medium text-foreground\" title={attachment.name}>\n {attachment.name}\n </div>\n <div className=\"text-xs text-muted-foreground\">\n {attachment.status === 'uploading'\n ? 'Uploading...'\n : [attachment.size, attachment.type].filter(Boolean).join(' · ') || null}\n </div>\n </div>\n\n {attachment.status === 'uploading' && (\n <Spinner size=\"sm\" label=\"Uploading\" aria-label=\"Uploading\" className=\"flex-shrink-0\" />\n )}\n\n {onRemove && (\n <button\n type=\"button\"\n onClick={() => onRemove(attachment)}\n aria-label={`Remove ${attachment.name}`}\n className=\"flex-shrink-0 rounded p-0.5 text-muted-foreground hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n ✕\n </button>\n )}\n </div>\n );\n }\n);\nAttachment.displayName = 'Attachment';\n\nexport { Attachment };\n","import * as React from 'react';\nimport { cn } from '@slipstream-ui/core';\nimport { Attachment } from './Attachment';\nimport type { AttachmentItem } from './Attachment';\n\nexport type AttachmentListProps = {\n attachments: AttachmentItem[];\n /** Passed through to every Attachment; omit to hide remove controls. */\n onRemove?: (attachment: AttachmentItem) => void;\n className?: string;\n};\n\nconst AttachmentList = React.forwardRef<HTMLDivElement, AttachmentListProps>(\n ({ attachments, onRemove, className, ...props }, ref) => {\n if (attachments.length === 0) {\n return null;\n }\n\n return (\n <div ref={ref} className={cn('flex flex-wrap gap-2', className)} {...props}>\n {attachments.map((attachment) => (\n <Attachment key={attachment.id} attachment={attachment} onRemove={onRemove} />\n ))}\n </div>\n );\n }\n);\nAttachmentList.displayName = 'AttachmentList';\n\nexport { AttachmentList };\n","'use client';\n\nimport * as React from 'react';\nimport ReactMarkdown from 'react-markdown';\nimport remarkGfm from 'remark-gfm';\nimport { cn } from '@slipstream-ui/core';\nimport { CodeBlock } from '../code-block';\nimport { closeIncompleteMarkdown } from './close-incomplete-markdown';\n\nexport type ResponseProps = {\n /** Markdown content to render. */\n children: string;\n /**\n * Repair unclosed emphasis/inline-code/fences while streaming so partial\n * chunks render cleanly (default true).\n */\n parseIncompleteMarkdown?: boolean;\n className?: string;\n};\n\n/**\n * Streaming-optimized markdown renderer for AI responses.\n *\n * Wraps react-markdown with GFM support and routes fenced code blocks to\n * the CodeBlock component for highlighting + copy.\n */\nconst Response = React.forwardRef<HTMLDivElement, ResponseProps>(\n ({ children, parseIncompleteMarkdown = true, className, ...props }, ref) => {\n const content = React.useMemo(\n () => (parseIncompleteMarkdown ? closeIncompleteMarkdown(children) : children),\n [children, parseIncompleteMarkdown]\n );\n\n return (\n <div\n ref={ref}\n className={cn(\n 'text-sm space-y-3 [&_a]:text-primary [&_a]:underline underline-offset-2',\n '[&_ul]:list-disc [&_ul]:pl-5 [&_ol]:list-decimal [&_ol]:pl-5',\n '[&_h1]:text-lg [&_h1]:font-semibold [&_h2]:text-base [&_h2]:font-semibold',\n '[&_h3]:text-sm [&_h3]:font-semibold',\n '[&_blockquote]:border-l-2 [&_blockquote]:border-border [&_blockquote]:pl-3 [&_blockquote]:text-muted-foreground',\n '[&_table]:w-full [&_table]:text-xs [&_th]:border [&_th]:border-border [&_th]:p-1.5 [&_td]:border [&_td]:border-border [&_td]:p-1.5',\n className\n )}\n {...props}\n >\n <ReactMarkdown\n remarkPlugins={[remarkGfm]}\n components={{\n pre: ({ children }) => <>{children}</>,\n code: ({ className: codeClassName, children: codeChildren }) => {\n const raw = String(codeChildren).replace(/\\n$/, '');\n const match = /language-(\\w+)/.exec(codeClassName ?? '');\n const isInline = !match && !raw.includes('\\n');\n if (isInline) {\n return (\n <code className=\"bg-muted px-1 py-0.5 rounded text-xs font-mono before:content-none after:content-none\">\n {raw}\n </code>\n );\n }\n return <CodeBlock code={raw} language={match?.[1] ?? 'text'} />;\n },\n }}\n >\n {content}\n </ReactMarkdown>\n </div>\n );\n }\n);\nResponse.displayName = 'Response';\n\nexport { Response };\n","'use client';\n\nimport * as React from 'react';\nimport { Highlight, type PrismTheme } from 'prism-react-renderer';\nimport { cn } from '@slipstream-ui/core';\n\nexport type CodeBlockProps = {\n /** Raw code to display (no trailing newline needed). */\n code: string;\n /** Language identifier used for Prism highlighting. */\n language?: string;\n /** Show a copy-to-clipboard button (default true). */\n showCopyButton?: boolean;\n className?: string;\n};\n\n/** Tracks whether the `.dark` class is present on `<html>`, staying in sync with toggles. */\nfunction useIsDark(): boolean {\n const [dark, setDark] = React.useState(false);\n\n React.useEffect(() => {\n const el = document.documentElement;\n setDark(el.classList.contains('dark'));\n const observer = new MutationObserver(() => setDark(el.classList.contains('dark')));\n observer.observe(el, { attributes: true, attributeFilter: ['class'] });\n return () => observer.disconnect();\n }, []);\n\n return dark;\n}\n\n/**\n * AA-safe syntax palettes.\n *\n * prism-react-renderer's stock themes put comments (#999988) and constants\n * (#36acaa) at ~2.7-2.9:1 on the code surface. Every colour below clears\n * 4.5:1 against its background (white light / near-black dark).\n */\nconst LIGHT_CODE_THEME: PrismTheme = {\n plain: { color: '#1f2328', backgroundColor: 'transparent' },\n styles: [\n { types: ['comment', 'prolog', 'doctype', 'cdata'], style: { color: '#57606a' } },\n { types: ['punctuation', 'operator'], style: { color: '#24292f' } },\n { types: ['namespace'], style: { color: '#6f42c1' } },\n { types: ['tag', 'deleted', 'keyword', 'atrule', 'important'], style: { color: '#b31d28' } },\n { types: ['attr-name', 'variable'], style: { color: '#953800' } },\n { types: ['string', 'char', 'attr-value', 'inserted', 'regex'], style: { color: '#0a5c2f' } },\n {\n types: [\n 'function',\n 'class-name',\n 'number',\n 'boolean',\n 'constant',\n 'symbol',\n 'property',\n 'selector',\n 'builtin',\n 'entity',\n 'url',\n ],\n style: { color: '#0550ae' },\n },\n ],\n};\n\nconst DARK_CODE_THEME: PrismTheme = {\n plain: { color: '#e6edf3', backgroundColor: 'transparent' },\n styles: [\n { types: ['comment', 'prolog', 'doctype', 'cdata'], style: { color: '#8b949e' } },\n { types: ['punctuation', 'operator'], style: { color: '#c9d1d9' } },\n { types: ['namespace'], style: { color: '#d2a8ff' } },\n { types: ['tag', 'deleted', 'keyword', 'atrule', 'important'], style: { color: '#ff7b72' } },\n { types: ['attr-name', 'variable'], style: { color: '#ffa657' } },\n { types: ['string', 'char', 'attr-value', 'inserted', 'regex'], style: { color: '#7ee787' } },\n {\n types: [\n 'function',\n 'class-name',\n 'number',\n 'boolean',\n 'constant',\n 'symbol',\n 'property',\n 'selector',\n 'builtin',\n 'entity',\n 'url',\n ],\n style: { color: '#79c0ff' },\n },\n ],\n};\n\nconst CodeBlock = React.forwardRef<HTMLDivElement, CodeBlockProps>(\n ({ code, language = 'tsx', showCopyButton = true, className, ...props }, ref) => {\n const [copied, setCopied] = React.useState(false);\n const isDark = useIsDark();\n const trimmedCode = code.replace(/\\n$/, '');\n\n // Horizontally scrollable code must be reachable by keyboard (WCAG 2.1.1).\n // Only make it a tab stop when it actually overflows, so short snippets\n // do not add noise to the tab order.\n const preRef = React.useRef<HTMLPreElement>(null);\n const [scrollable, setScrollable] = React.useState(false);\n React.useEffect(() => {\n const element = preRef.current;\n if (!element) return;\n const update = () => setScrollable(element.scrollWidth > element.clientWidth + 1);\n update();\n // jsdom (tests) has no ResizeObserver; window resize is the fallback.\n if (typeof ResizeObserver === 'undefined') {\n window.addEventListener('resize', update);\n return () => window.removeEventListener('resize', update);\n }\n const observer = new ResizeObserver(update);\n observer.observe(element);\n return () => observer.disconnect();\n }, [trimmedCode, language]);\n\n const handleCopy = async () => {\n try {\n await navigator.clipboard.writeText(trimmedCode);\n } catch {\n // Clipboard unavailable (insecure context); still show feedback so\n // consumers can hook onCopy-style behavior via DOM if needed.\n }\n setCopied(true);\n window.setTimeout(() => setCopied(false), 2000);\n };\n\n return (\n <div\n ref={ref}\n className={cn(\n // bg-background (not muted): the light syntax palette is tuned for\n // a white surface; on gray the token contrast drops below AA.\n 'relative group rounded-md border border-border bg-background overflow-hidden',\n className\n )}\n {...props}\n >\n <div className=\"flex items-center justify-between px-3 py-1.5 border-b border-border bg-muted/60\">\n <span className=\"text-xs font-mono text-muted-foreground uppercase\">{language}</span>\n {showCopyButton && (\n <button\n type=\"button\"\n onClick={handleCopy}\n aria-label={copied ? 'Copied' : 'Copy code'}\n className=\"text-xs text-muted-foreground hover:text-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring rounded px-1\"\n >\n {copied ? 'Copied!' : 'Copy'}\n </button>\n )}\n </div>\n <Highlight theme={isDark ? DARK_CODE_THEME : LIGHT_CODE_THEME} code={trimmedCode} language={language}>\n {({ style, tokens, getLineProps, getTokenProps }) => (\n <pre\n ref={preRef}\n tabIndex={scrollable ? 0 : undefined}\n aria-label={scrollable ? `${language} code, scrollable` : undefined}\n className=\"overflow-x-auto p-4 text-xs leading-relaxed m-0 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n style={{ ...style, background: 'transparent' }}\n >\n {tokens.map((line, i) => (\n <div key={i} {...getLineProps({ line })}>\n {line.map((token, key) => (\n <span key={key} {...getTokenProps({ token })} />\n ))}\n </div>\n ))}\n </pre>\n )}\n </Highlight>\n </div>\n );\n }\n);\nCodeBlock.displayName = 'CodeBlock';\n\nexport { CodeBlock };\n","/**\n * Repairs markdown that is mid-stream: closes unclosed bold/italic/strikethrough\n * markers and unterminated inline code / code fences so partial chunks render\n * without flickering or broken syntax.\n *\n * Deliberately conservative — only appends closing characters, never rewrites content.\n */\nexport function closeIncompleteMarkdown(markdown: string): string {\n let text = markdown;\n\n // Close an unterminated fenced code block (odd number of ``` lines).\n const fenceMatches = text.match(/^`{3,}/gm);\n if (fenceMatches && fenceMatches.length % 2 === 1) {\n text = `${text}\\n\\`\\`\\``;\n }\n\n // Inline constructs are only repaired outside of code fences for simplicity:\n // if we just opened a fence, the remainder is code and should not be touched.\n const firstFence = text.indexOf('```');\n const hasUnclosedFence = fenceMatches !== null && fenceMatches.length % 2 === 1;\n const prose = hasUnclosedFence && firstFence !== -1 ? text.slice(0, firstFence) : text;\n const rest = hasUnclosedFence && firstFence !== -1 ? text.slice(firstFence) : '';\n\n let repaired = prose;\n // Count unescaped emphasis markers; close whichever are odd.\n for (const marker of ['**', '__', '~~']) {\n const occurrences = prose.split(marker).length - 1;\n if (occurrences % 2 === 1) {\n repaired += marker;\n }\n }\n // Single asterisk/underscore italics.\n for (const marker of ['*', '_']) {\n // Only count markers not part of **/__ pairs by stripping doubles first.\n const singles = repaired.replace(/\\*\\*/g, '').replace(/__/g, '').split(marker).length - 1;\n if (singles % 2 === 1) {\n repaired += marker;\n }\n }\n // Inline code.\n const backtickCount = repaired.replace(/```/g, '').split('`').length - 1;\n if (backtickCount % 2 === 1) {\n repaired += '`';\n }\n\n return repaired + rest;\n}\n","'use client';\n\nimport * as React from 'react';\nimport { Button } from '@slipstream-ui/core';\nimport { cn } from '@slipstream-ui/core';\n\nexport type ConfirmationStatus = 'pending' | 'approved' | 'rejected';\n\nexport type ConfirmationVariant = 'default' | 'warning' | 'destructive' | 'info' | 'success';\n\n/** Button variants accepted for the approve/reject actions (Button's variant union). */\nexport type ConfirmationActionVariant =\n | 'default'\n | 'destructive'\n | 'outline'\n | 'secondary'\n | 'ghost'\n | 'link';\n\nexport type ConfirmationProps = {\n /** Human-readable summary of the action requiring approval. */\n title: string;\n /** Optional detail: affected resource, arguments preview, risk note. */\n description?: string;\n /** Tool or action name shown as a mono chip. */\n toolName?: string;\n /** Controlled outcome; omit for fully interactive uncontrolled use. */\n status?: ConfirmationStatus;\n /** Accent color of the pending card (outcome chips always follow the result). */\n variant?: ConfirmationVariant;\n onApprove?: () => void;\n onReject?: () => void;\n /** Button styling for the approve/reject actions. */\n approveVariant?: ConfirmationActionVariant;\n rejectVariant?: ConfirmationActionVariant;\n /** Hide the action buttons (controlled-only gate; status drives the chip). */\n showActions?: boolean;\n labels?: {\n approve?: string;\n reject?: string;\n approved?: string;\n rejected?: string;\n };\n className?: string;\n};\n\nconst statusChipClasses: Record<ConfirmationStatus, string> = {\n pending: 'bg-warning/10 text-warning-ink border-warning/20',\n approved: 'bg-success/10 text-success border-success/20',\n rejected: 'bg-destructive/10 text-destructive border-destructive/20',\n};\n\nconst pendingVariantClasses: Record<ConfirmationVariant, string> = {\n default: 'border-warning/40',\n warning: 'border-warning/40',\n destructive: 'border-destructive/40 bg-destructive/5',\n info: 'border-info/40',\n success: 'border-success/40',\n};\n\n/**\n * Human-in-the-loop approval gate for agent actions (tool execution,\n * destructive operations). The agent pauses until the user decides.\n */\nconst Confirmation = React.forwardRef<HTMLDivElement, ConfirmationProps>(\n (\n {\n title,\n description,\n toolName,\n status: controlledStatus,\n variant = 'default',\n onApprove,\n onReject,\n approveVariant = 'default',\n rejectVariant = 'outline',\n showActions = true,\n labels,\n className,\n ...props\n },\n ref\n ) => {\n const [internalStatus, setInternalStatus] = React.useState<ConfirmationStatus>('pending');\n const status = controlledStatus ?? internalStatus;\n\n const t = {\n approve: labels?.approve ?? 'Approve',\n reject: labels?.reject ?? 'Reject',\n approved: labels?.approved ?? 'Approved',\n rejected: labels?.rejected ?? 'Rejected',\n };\n\n const decide = (next: Exclude<ConfirmationStatus, 'pending'>) => {\n setInternalStatus(next);\n (next === 'approved' ? onApprove : onReject)?.();\n };\n\n return (\n <div\n ref={ref}\n role={status === 'pending' ? 'alertdialog' : undefined}\n aria-label={status === 'pending' ? title : undefined}\n className={cn(\n 'rounded-lg border p-4 bg-muted/30 max-w-md',\n status === 'pending' && pendingVariantClasses[variant],\n className\n )}\n {...props}\n >\n <div className=\"flex items-center justify-between gap-2 mb-2\">\n <div className=\"text-sm font-medium text-foreground\">{title}</div>\n <span\n className={cn(\n 'text-xs px-2 py-0.5 rounded-full border whitespace-nowrap',\n statusChipClasses[status]\n )}\n >\n {status === 'approved' ? t.approved : status === 'rejected' ? t.rejected : 'Pending'}\n </span>\n </div>\n\n {description && (\n <div className=\"text-sm text-muted-foreground mb-1\">{description}</div>\n )}\n {toolName && (\n <div className=\"text-xs font-mono text-muted-foreground mb-3\">{toolName}</div>\n )}\n\n {status === 'pending' && showActions && (\n <div className=\"flex gap-2 mt-2\">\n <Button size=\"sm\" variant={approveVariant} onClick={() => decide('approved')}>\n {t.approve}\n </Button>\n <Button size=\"sm\" variant={rejectVariant} onClick={() => decide('rejected')}>\n {t.reject}\n </Button>\n </div>\n )}\n </div>\n );\n }\n);\nConfirmation.displayName = 'Confirmation';\n\nexport { Confirmation };\n","'use client';\n\nimport * as React from 'react';\nimport { cn } from '@slipstream-ui/core';\n\nexport type BranchProps = {\n /** Total number of message variants. Renders nothing when count < 2. */\n count: number;\n /** Zero-based index of the currently displayed variant. */\n selected?: number;\n /** Uncontrolled initial variant when `selected` is omitted. */\n defaultSelected?: number;\n onSelect?: (index: number) => void;\n labels?: { previous?: string; next?: string };\n className?: string;\n};\n\n/**\n * Variant navigation for branched messages (`‹ 2 / 3 ›`).\n * Purely presentational + minimal internal state; the consumer swaps content.\n */\nconst Branch = React.forwardRef<HTMLDivElement, BranchProps>(\n (\n { count, selected, defaultSelected = 0, onSelect, labels, className, ...props },\n ref\n ) => {\n const [internalIndex, setInternalIndex] = React.useState(defaultSelected);\n const isControlled = selected !== undefined;\n const index = Math.min(Math.max(isControlled ? selected : internalIndex, 0), count - 1);\n\n const t = {\n previous: labels?.previous ?? 'Previous response',\n next: labels?.next ?? 'Next response',\n };\n\n if (count < 2) return null;\n\n const goTo = (next: number) => {\n const clamped = Math.min(Math.max(next, 0), count - 1);\n if (!isControlled) setInternalIndex(clamped);\n onSelect?.(clamped);\n };\n\n return (\n <div\n ref={ref}\n className={cn('flex items-center gap-1 text-xs text-muted-foreground', className)}\n {...props}\n >\n <button\n type=\"button\"\n onClick={() => goTo(index - 1)}\n disabled={index === 0}\n aria-label={t.previous}\n className=\"rounded px-1 hover:bg-accent hover:text-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-40\"\n >\n ‹\n </button>\n <span aria-live=\"polite\" className=\"tabular-nums\">\n {index + 1} / {count}\n </span>\n <button\n type=\"button\"\n onClick={() => goTo(index + 1)}\n disabled={index === count - 1}\n aria-label={t.next}\n className=\"rounded px-1 hover:bg-accent hover:text-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-40\"\n >\n ›\n </button>\n </div>\n );\n }\n);\nBranch.displayName = 'Branch';\n\nexport { Branch };\n","import * as React from 'react';\nimport { cn } from '@slipstream-ui/core';\nimport type { SourceItem } from '../../types';\n\nexport type InlineCitationProps = {\n /** The cited source; powers the hover/focus preview card. */\n source: SourceItem;\n /** Citation text to wrap (defaults to the source title). */\n children?: React.ReactNode;\n className?: string;\n};\n\n/**\n * Perplexity-style inline citation: a superscript chip that reveals the\n * source snippet on hover or keyboard focus.\n */\nconst InlineCitation = React.forwardRef<HTMLSpanElement, InlineCitationProps>(\n ({ source, children, className, ...props }, ref) => {\n return (\n <span\n ref={ref}\n className={cn('group relative inline focus-within:outline-none', className)}\n {...props}\n >\n <button\n type=\"button\"\n aria-describedby={`citation-${source.id}-card`}\n className=\"inline-flex items-baseline rounded-sm text-left focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n {children ?? <span>{source.title}</span>}\n <span\n aria-hidden=\"true\"\n className=\"inline-flex items-center justify-center align-super ml-0.5 h-4 min-w-4 px-1 rounded-full border border-border bg-muted text-[10px] font-medium text-muted-foreground group-hover:text-foreground transition-colors\"\n >\n {source.title.charAt(0).toUpperCase()}\n </span>\n </button>\n <span\n id={`citation-${source.id}-card`}\n role=\"tooltip\"\n className=\"pointer-events-none absolute bottom-full left-1/2 z-10 mb-1 -translate-x-1/2 w-64 rounded-md border border-border bg-popover p-2.5 text-xs text-popover-foreground shadow-md opacity-0 group-hover:opacity-100 focus-within:opacity-100 transition-opacity\"\n >\n <span className=\"block font-medium text-foreground truncate\">{source.title}</span>\n {source.snippet && (\n <span className=\"mt-0.5 block text-muted-foreground line-clamp-3\">\n {source.snippet}\n </span>\n )}\n </span>\n </span>\n );\n }\n);\nInlineCitation.displayName = 'InlineCitation';\n\nexport { InlineCitation };\n","'use client';\n\nimport * as React from 'react';\nimport { cn } from '@slipstream-ui/core';\nimport { Message } from '../message';\nimport type { Message as MessageType } from '../../types';\n\nexport type ConversationProps = {\n messages: MessageType[];\n className?: string;\n showAvatars?: boolean;\n userAvatarSrc?: string;\n userAvatarFallback?: string;\n assistantAvatarSrc?: string;\n assistantAvatarFallback?: string;\n isLoading?: boolean;\n loadingMessage?: string;\n /** Custom content renderer applied to every message (e.g. markdown). */\n renderContent?: (content: string) => React.ReactNode;\n /** ID of the message still being generated; renders its streaming cursor. */\n streamingMessageId?: string;\n /**\n * Show a floating \"scroll to latest\" pill when the user has scrolled up.\n * Default true.\n */\n showScrollButton?: boolean;\n /** Show a download button that exports the transcript as Markdown. Default false. */\n showDownload?: boolean;\n /** Per-message generation failures keyed by message id; renders retry cards. */\n messageErrors?: Record<string, string>;\n /** Retry handler for failed messages in `messageErrors`. */\n onRetryMessage?: (message: MessageType) => void;\n\n // --- Empty state -------------------------------------------------------\n /** Heading for the empty-transcript welcome state. */\n welcomeTitle?: string;\n /** Supporting copy for the welcome state. */\n welcomeDescription?: string;\n /** Starter prompts rendered as buttons under the welcome copy. */\n welcomeSuggestions?: string[];\n /** Called with the chosen starter prompt text. */\n onWelcomeSelect?: (prompt: string) => void;\n\n // --- History pagination --------------------------------------------------\n /** Older history exists; renders a \"load earlier\" control at the top. */\n hasMoreHistory?: boolean;\n /** Older history request is in flight; shows a loading row. */\n isLoadingMore?: boolean;\n /** Called when the user requests older history. */\n onLoadMore?: () => void;\n};\n\n/** Distance (px) from the bottom within which the view counts as \"pinned\". */\nconst PINNED_THRESHOLD = 80;\n\nconst DEFAULT_WELCOME_TITLE = 'Start the conversation';\nconst DEFAULT_WELCOME_DESCRIPTION = 'Ask anything — responses stream in real time.';\nconst DEFAULT_WELCOME_SUGGESTIONS = [\n 'Explain what you can do',\n 'Summarize a topic for me',\n];\n\nfunction transcriptToMarkdown(messages: MessageType[]): string {\n return messages\n .map((message) => {\n const speaker =\n message.role === 'user' ? 'You' : message.role === 'assistant' ? 'Assistant' : message.role;\n const time = message.timestamp ? ` (${new Date(message.timestamp).toISOString()})` : '';\n return `**${speaker}${time}:**\\n\\n${message.content}`;\n })\n .join('\\n\\n---\\n\\n');\n}\n\nconst Conversation = React.forwardRef<HTMLDivElement, ConversationProps>(\n ({\n messages,\n className,\n showAvatars = true,\n userAvatarSrc,\n userAvatarFallback,\n assistantAvatarSrc,\n assistantAvatarFallback,\n isLoading = false,\n loadingMessage = 'Thinking...',\n renderContent,\n streamingMessageId,\n showScrollButton = true,\n showDownload = false,\n messageErrors,\n onRetryMessage,\n welcomeTitle = DEFAULT_WELCOME_TITLE,\n welcomeDescription = DEFAULT_WELCOME_DESCRIPTION,\n welcomeSuggestions = DEFAULT_WELCOME_SUGGESTIONS,\n onWelcomeSelect,\n hasMoreHistory = false,\n isLoadingMore = false,\n onLoadMore,\n ...props\n }, ref) => {\n const scrollRef = React.useRef<HTMLDivElement>(null);\n const messagesEndRef = React.useRef<HTMLDivElement>(null);\n const [isUnpinned, setIsUnpinned] = React.useState(false);\n const prevScrollMetrics = React.useRef<{ height: number; top: number } | null>(null);\n\n // Announce stream completion to assistive tech: when the streaming id\n // transitions from set to unset, a response just finished.\n const [announcement, setAnnouncement] = React.useState('');\n const prevStreamingRef = React.useRef<string | undefined>(undefined);\n React.useEffect(() => {\n if (prevStreamingRef.current && !streamingMessageId) {\n setAnnouncement('Response complete.');\n }\n prevStreamingRef.current = streamingMessageId;\n }, [streamingMessageId]);\n\n // Track pinned state on scroll so the jump-to-latest pill can appear.\n React.useEffect(() => {\n const container = scrollRef.current;\n if (!container) return;\n\n const updatePinned = () => {\n const distanceFromBottom =\n container.scrollHeight - container.scrollTop - container.clientHeight;\n setIsUnpinned(distanceFromBottom > PINNED_THRESHOLD);\n };\n\n updatePinned();\n container.addEventListener('scroll', updatePinned, { passive: true });\n return () => container.removeEventListener('scroll', updatePinned);\n }, []);\n\n // Scroll anchoring across history loads: capture metrics before new rows\n // render, then restore the same visual position after they land.\n React.useLayoutEffect(() => {\n const container = scrollRef.current;\n if (!container || prevScrollMetrics.current === null) return;\n\n const { height, top } = prevScrollMetrics.current;\n container.scrollTop = container.scrollHeight - height + top;\n prevScrollMetrics.current = null;\n }, [messages]);\n\n const captureAnchor = () => {\n const container = scrollRef.current;\n if (!container) return;\n prevScrollMetrics.current = { height: container.scrollHeight, top: container.scrollTop };\n };\n\n const handleLoadMore = () => {\n captureAnchor();\n onLoadMore?.();\n };\n\n // Auto-scroll only when the user is already near the bottom, so reading\n // history is never yanked. During streaming use instant scrolls; smooth\n // animations restarted per token cause jank.\n //\n // Scroll the container itself (never scrollIntoView): scrollIntoView\n // bubbles through every scrollable ancestor, including the document,\n // which yanked the whole page when the demo/preview frames were small.\n React.useEffect(() => {\n const container = scrollRef.current;\n if (!container) return;\n\n const distanceFromBottom =\n container.scrollHeight - container.scrollTop - container.clientHeight;\n if (distanceFromBottom > PINNED_THRESHOLD) return;\n\n container.scrollTo?.({\n top: container.scrollHeight,\n behavior: streamingMessageId ? 'auto' : 'smooth',\n });\n }, [messages, streamingMessageId]);\n\n const scrollToLatest = () => {\n const container = scrollRef.current;\n if (!container) return;\n container.scrollTo?.({ top: container.scrollHeight, behavior: 'smooth' });\n };\n\n const handleDownload = () => {\n const blob = new Blob([transcriptToMarkdown(messages)], { type: 'text/markdown' });\n const url = URL.createObjectURL(blob);\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.download = 'conversation.md';\n anchor.click();\n URL.revokeObjectURL(url);\n };\n\n const isEmpty = messages.length === 0 && !isLoading;\n\n return (\n <div ref={ref} className={cn('relative h-full w-full', className)} {...props}>\n <div\n ref={scrollRef}\n tabIndex={0}\n aria-label=\"Conversation transcript\"\n className=\"flex flex-col gap-4 p-4 overflow-y-auto h-full focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n {(hasMoreHistory || isLoadingMore) && (\n <button\n type=\"button\"\n onClick={handleLoadMore}\n disabled={isLoadingMore}\n className=\"mx-auto rounded-full border border-border bg-background px-3 py-1 text-xs text-muted-foreground hover:text-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:opacity-50\"\n >\n {isLoadingMore ? 'Loading…' : 'Load earlier messages'}\n </button>\n )}\n\n {isEmpty ? (\n <div className=\"flex flex-1 flex-col items-center justify-center gap-3 text-center py-16\">\n <h3 className=\"text-lg font-semibold\">{welcomeTitle}</h3>\n <p className=\"text-sm text-muted-foreground max-w-sm\">{welcomeDescription}</p>\n {welcomeSuggestions.length > 0 && (\n <div className=\"mt-2 flex flex-col gap-2 w-full max-w-sm\">\n {welcomeSuggestions.map((suggestion) => (\n <button\n key={suggestion}\n type=\"button\"\n onClick={() => onWelcomeSelect?.(suggestion)}\n className=\"rounded-md border border-border bg-background px-4 py-2.5 text-sm text-left text-muted-foreground hover:bg-accent hover:text-accent-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n {suggestion}\n </button>\n ))}\n </div>\n )}\n </div>\n ) : (\n messages.map((message) => (\n <Message\n key={message.id}\n message={message}\n showAvatar={showAvatars}\n avatarSrc={\n message.role === 'user' ? userAvatarSrc : assistantAvatarSrc\n }\n avatarFallback={\n message.role === 'user' ? userAvatarFallback : assistantAvatarFallback\n }\n renderContent={renderContent}\n isStreaming={message.id === streamingMessageId}\n error={messageErrors?.[message.id]}\n onRetry={\n onRetryMessage && messageErrors?.[message.id]\n ? () => onRetryMessage(message)\n : undefined\n }\n />\n ))\n )}\n\n {isLoading && !isEmpty && (\n <Message\n message={{\n id: '__loading__',\n role: 'assistant',\n content: loadingMessage,\n }}\n showAvatar={showAvatars}\n avatarSrc={assistantAvatarSrc}\n avatarFallback={assistantAvatarFallback}\n className=\"bg-muted/50\"\n renderContent={(content) => (\n <span className=\"text-muted-foreground animate-pulse motion-reduce:animate-none\">{content}</span>\n )}\n />\n )}\n\n {/* Screen-reader announcement when a streamed response completes. */}\n <div aria-live=\"polite\" className=\"sr-only\">{announcement}</div>\n\n <div ref={messagesEndRef} />\n </div>\n\n {showDownload && messages.length > 0 && (\n <button\n type=\"button\"\n onClick={handleDownload}\n aria-label=\"Download transcript\"\n className=\"absolute top-2 right-2 z-10 rounded-md border border-border bg-background/90 px-2 py-1 text-xs text-muted-foreground hover:text-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n ↓ .md\n </button>\n )}\n\n {showScrollButton && isUnpinned && (\n <button\n type=\"button\"\n onClick={scrollToLatest}\n aria-label=\"Scroll to latest message\"\n className=\"absolute bottom-3 left-1/2 z-10 -translate-x-1/2 rounded-full border border-border bg-background/95 px-3 py-1.5 text-xs font-medium shadow-sm hover:bg-accent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n >\n ↓ Latest\n </button>\n )}\n </div>\n );\n }\n);\n\nConversation.displayName = 'Conversation';\n\nexport { Conversation };\n","'use client';\n\nimport * as React from 'react';\nimport { Button } from '@slipstream-ui/core';\nimport { cn } from '@slipstream-ui/core';\nimport { AttachmentList } from '../attachment';\nimport type { AttachmentItem } from '../attachment';\n\n// ---------------------------------------------------------------------------\n// Attachments hook: validation + state, reusable outside the input.\n// ---------------------------------------------------------------------------\n\nexport type UseAttachmentsOptions = {\n /** File types to accept, e.g. \"image/*\" (HTML accept syntax). */\n accept?: string;\n /** Maximum number of queued files. */\n maxFiles?: number;\n /** Maximum size per file in bytes. */\n maxFileSize?: number;\n multiple?: boolean;\n onError?: (error: { code: 'max_files' | 'max_file_size' | 'accept'; message: string }) => void;\n};\n\nexport type UseAttachmentsResult = {\n files: AttachmentItem[];\n add: (fileList: FileList | File[]) => void;\n remove: (id: string) => void;\n clear: () => void;\n openFileDialog: () => void;\n /** Hidden file input element; render it once somewhere in your tree. */\n input: React.ReactElement;\n};\n\n/**\n * Headless attachment queue with constraint validation.\n * Used internally by PromptInput and exported for custom composers.\n */\nexport function usePromptInputAttachments(options: UseAttachmentsOptions = {}): UseAttachmentsResult {\n const { accept, maxFiles, maxFileSize, multiple = true, onError } = options;\n const [files, setFiles] = React.useState<AttachmentItem[]>([]);\n const inputRef = React.useRef<HTMLInputElement>(null);\n\n const add = React.useCallback(\n (fileList: FileList | File[]) => {\n const incoming = Array.from(fileList);\n setFiles((prev) => {\n const next = [...prev];\n for (const file of incoming) {\n if (accept && !file.type.match(accept.replace(/\\*/g, '.*'))) {\n onError?.({ code: 'accept', message: `\"${file.name}\" is not an accepted file type.` });\n continue;\n }\n if (maxFileSize && file.size > maxFileSize) {\n onError?.({\n code: 'max_file_size',\n message: `\"${file.name}\" exceeds the ${Math.round(maxFileSize / 1024)} KB limit.`,\n });\n continue;\n }\n if (maxFiles !== undefined && next.length >= maxFiles) {\n onError?.({ code: 'max_files', message: `At most ${maxFiles} files can be attached.` });\n break;\n }\n if (!multiple && next.length >= 1) {\n onError?.({ code: 'max_files', message: 'Only one file can be attached.' });\n break;\n }\n next.push({\n id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`,\n name: file.name,\n size: `${Math.max(1, Math.round(file.size / 1024))} KB`,\n type: file.type.split('/')[1]?.toUpperCase() ?? file.name.split('.').pop()?.toUpperCase(),\n });\n }\n return next;\n });\n },\n [accept, maxFileSize, maxFiles, multiple, onError]\n );\n\n const remove = React.useCallback((id: string) => {\n setFiles((prev) => prev.filter((file) => file.id !== id));\n }, []);\n\n const clear = React.useCallback(() => setFiles([]), []);\n\n const openFileDialog = React.useCallback(() => inputRef.current?.click(), []);\n\n const input = (\n <input\n ref={inputRef}\n type=\"file\"\n hidden\n accept={accept}\n multiple={multiple}\n onChange={(event) => {\n if (event.target.files) add(event.target.files);\n event.target.value = '';\n }}\n />\n );\n\n return { files, add, remove, clear, openFileDialog, input };\n}\n\n// ---------------------------------------------------------------------------\n// Speech recognition (Web Speech API), no-op where unsupported.\n// ---------------------------------------------------------------------------\n\ntype SpeechRecognitionLike = {\n lang: string;\n continuous: boolean;\n interimResults: boolean;\n start: () => void;\n stop: () => void;\n onresult: ((event: { results: ArrayLike<ArrayLike<{ transcript: string }>> }) => void) | null;\n onend: (() => void) | null;\n};\n\ntype SpeechRecognitionCtor = new () => SpeechRecognitionLike;\n\n/** Web Speech API dictation; returns supported=false on unsupported browsers. */\nexport function useSpeechRecognition(onTranscript: (text: string) => void): {\n supported: boolean;\n isListening: boolean;\n toggle: () => void;\n} {\n const [isListening, setIsListening] = React.useState(false);\n // Cast through unknown: Safari prefixes webkitSpeechRecognition.\n const Ctor =\n typeof window !== 'undefined'\n ? ((window as unknown as Record<string, SpeechRecognitionCtor | undefined>).SpeechRecognition ??\n (window as unknown as Record<string, SpeechRecognitionCtor | undefined>).webkitSpeechRecognition)\n : undefined;\n\n const recognitionRef = React.useRef<SpeechRecognitionLike | null>(null);\n\n const toggle = React.useCallback(() => {\n if (!Ctor) return;\n if (isListening) {\n recognitionRef.current?.stop();\n setIsListening(false);\n return;\n }\n const recognition = new Ctor();\n recognition.lang = navigator.language || 'en-US';\n recognition.continuous = false;\n recognition.interimResults = false;\n recognition.onresult = (event) => {\n const transcript = Array.from({ length: event.results.length }, (_, i) => event.results[i][0].transcript).join(' ');\n onTranscript(transcript.trim());\n };\n recognition.onend = () => setIsListening(false);\n recognitionRef.current = recognition;\n recognition.start();\n setIsListening(true);\n }, [Ctor, isListening, onTranscript]);\n\n return { supported: Boolean(Ctor), isListening, toggle };\n}\n\n// ---------------------------------------------------------------------------\n// Context shared by the compound primitives.\n// ---------------------------------------------------------------------------\n\ntype PromptInputContextValue = {\n value: string;\n setValue: (value: string) => void;\n disabled: boolean;\n isLoading: boolean;\n canSubmit: boolean;\n submit: () => void;\n stop: () => void;\n hasStop: boolean;\n attachments: AttachmentItem[];\n removeAttachment: (id: string) => void;\n addFiles: (files: FileList | File[]) => void;\n openFilePicker: () => void;\n hiddenInput: React.ReactElement;\n dictate: { supported: boolean; isListening: boolean; toggle: () => void };\n};\n\nconst PromptInputContext = React.createContext<PromptInputContextValue | null>(null);\n\nfunction usePromptInputContext(): PromptInputContextValue {\n const context = React.useContext(PromptInputContext);\n if (!context) throw new Error('PromptInput primitives must be rendered inside <PromptInput>.');\n return context;\n}\n\n// ---------------------------------------------------------------------------\n// Root\n// ---------------------------------------------------------------------------\n\nexport type PromptInputProps = {\n onSubmit: (value: string) => void;\n /** Called when the user requests to stop an in-flight generation. */\n onStop?: () => void;\n /**\n * Externally owned attachment queue. When omitted, PromptInput manages its\n * own queue with drag-and-drop + clipboard-paste support.\n */\n attachments?: AttachmentItem[];\n onRemoveAttachment?: (attachment: AttachmentItem) => void;\n /** Called whenever the managed attachment queue changes. */\n onAttachmentsChange?: (attachments: AttachmentItem[]) => void;\n /** Marks submission as failed; the send control reflects the error state. */\n hasError?: boolean;\n accept?: string;\n multiple?: boolean;\n maxFiles?: number;\n maxFileSize?: number;\n onAttachmentError?: UseAttachmentsOptions['onError'];\n /** Accept file drops anywhere on the document (default false). */\n globalDrop?: boolean;\n placeholder?: string;\n disabled?: boolean;\n isLoading?: boolean;\n className?: string;\n autoFocus?: boolean;\n maxLength?: number;\n showSendButton?: boolean;\n sendButtonText?: string;\n stopButtonText?: string;\n children?: React.ReactNode;\n};\n\nconst PromptInputRoot = React.forwardRef<HTMLTextAreaElement, PromptInputProps>(\n ({\n onSubmit,\n onStop,\n attachments: controlledAttachments,\n onRemoveAttachment,\n onAttachmentsChange,\n hasError = false,\n accept,\n multiple = true,\n maxFiles,\n maxFileSize,\n onAttachmentError,\n globalDrop = false,\n placeholder = 'Type your message...',\n disabled = false,\n isLoading = false,\n className,\n autoFocus = false,\n maxLength,\n showSendButton = true,\n sendButtonText = 'Send',\n stopButtonText = 'Stop generating',\n children,\n ...props\n }, ref) => {\n const [value, setValue] = React.useState('');\n const textareaRef = React.useRef<HTMLTextAreaElement>(null);\n\n const managed = usePromptInputAttachments({ accept, maxFiles, maxFileSize, multiple, onError: onAttachmentError });\n\n // Notify consumers of managed-queue changes.\n const prevManagedCount = React.useRef(0);\n React.useEffect(() => {\n if (!controlledAttachments && managed.files.length !== prevManagedCount.current) {\n prevManagedCount.current = managed.files.length;\n onAttachmentsChange?.(managed.files);\n }\n }, [managed.files, controlledAttachments, onAttachmentsChange]);\n\n const activeAttachments = controlledAttachments ?? managed.files;\n\n // Auto-focus on mount if requested\n React.useEffect(() => {\n if (autoFocus && textareaRef.current) textareaRef.current.focus();\n }, [autoFocus]);\n\n // Merge forwarded ref with internal handle (auto-resize needs it).\n React.useImperativeHandle(ref, () => textareaRef.current!);\n\n // Auto-resize textarea\n React.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 // Global drop: opt-in document-level listener.\n React.useEffect(() => {\n if (!globalDrop || controlledAttachments) return;\n const prevent = (event: DragEvent) => event.preventDefault();\n const drop = (event: DragEvent) => {\n event.preventDefault();\n if (event.dataTransfer?.files.length) managed.add(event.dataTransfer.files);\n };\n document.addEventListener('dragover', prevent);\n document.addEventListener('drop', drop);\n return () => {\n document.removeEventListener('dragover', prevent);\n document.removeEventListener('drop', drop);\n };\n }, [globalDrop, controlledAttachments, managed]);\n\n const canSubmit = Boolean(value.trim()) && !disabled && !isLoading;\n\n const handleSubmit = () => {\n const trimmedValue = value.trim();\n if (!trimmedValue || disabled || isLoading) return;\n onSubmit(trimmedValue);\n setValue('');\n if (textareaRef.current) textareaRef.current.style.height = 'auto';\n if (!controlledAttachments) managed.clear();\n };\n\n const handleStop = () => onStop?.();\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLTextAreaElement>) => {\n if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault();\n handleSubmit();\n }\n };\n\n const dictate = useSpeechRecognition((transcript) =>\n setValue((current) => (current ? `${current} ${transcript}` : transcript))\n );\n\n const contextValue: PromptInputContextValue = {\n value,\n setValue,\n disabled,\n isLoading,\n canSubmit,\n submit: handleSubmit,\n stop: handleStop,\n hasStop: Boolean(onStop),\n attachments: activeAttachments,\n removeAttachment: (id) => (controlledAttachments ? onRemoveAttachment?.({ id } as AttachmentItem) : managed.remove(id)),\n addFiles: (files) => !controlledAttachments && managed.add(files),\n openFilePicker: managed.openFileDialog,\n hiddenInput: managed.input,\n dictate,\n };\n\n const showStop = isLoading && Boolean(onStop);\n const submitIcon = showStop ? '■' : hasError ? '⚠' : '→';\n const submitLabel = showStop ? stopButtonText : hasError ? 'Failed — check message' : sendButtonText;\n\n const textarea = (\n <textarea\n ref={textareaRef}\n value={value}\n onChange={(event) => setValue(event.target.value)}\n onKeyDown={handleKeyDown}\n placeholder={placeholder}\n disabled={disabled || isLoading}\n maxLength={maxLength}\n rows={1}\n className={cn(\n 'flex-1 resize-none rounded-md border border-input bg-background px-3 py-2 text-sm',\n 'placeholder:text-muted-foreground',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n 'min-h-[40px] max-h-[200px] overflow-y-auto'\n )}\n />\n );\n\n const sendButton = showSendButton ? (\n <Button\n onClick={showStop ? handleStop : handleSubmit}\n disabled={showStop ? false : !canSubmit || disabled}\n variant={showStop ? 'outline' : 'default'}\n size=\"icon\"\n type=\"button\"\n aria-label={submitLabel}\n >\n <span aria-hidden=\"true\">{submitIcon}</span>\n </Button>\n ) : null;\n\n // Drop/paste surface wraps everything in both modes.\n const dropHandlers = controlledAttachments\n ? {}\n : {\n onDrop: (event: React.DragEvent) => {\n event.preventDefault();\n if (event.dataTransfer.files.length) managed.add(event.dataTransfer.files);\n },\n onPaste: (event: React.ClipboardEvent) => {\n const files = event.clipboardData?.files;\n if (files && files.length > 0) {\n event.preventDefault();\n managed.add(files);\n }\n },\n };\n\n return (\n <PromptInputContext.Provider value={contextValue}>\n <div className={cn('flex flex-col gap-2', className)} {...dropHandlers} {...props}>\n {activeAttachments.length > 0 && (\n <AttachmentList\n attachments={activeAttachments}\n onRemove={controlledAttachments ? onRemoveAttachment : (a) => managed.remove(a.id)}\n />\n )}\n\n {children ? (\n <>\n {children}\n {managed.input}\n </>\n ) : (\n <>\n <div className=\"flex gap-2 items-end\">\n {textarea}\n {sendButton}\n </div>\n {managed.input}\n </>\n )}\n </div>\n </PromptInputContext.Provider>\n );\n }\n);\nPromptInputRoot.displayName = 'PromptInput';\n\n// ---------------------------------------------------------------------------\n// Compound primitives\n// ---------------------------------------------------------------------------\n\n/** Auto-resizing textarea bound to the prompt state. Accepts standard textarea props. */\nconst PromptInputTextarea = React.forwardRef<\n HTMLTextAreaElement,\n Omit<React.TextareaHTMLAttributes<HTMLTextAreaElement>, 'value' | 'onChange'>\n>(({ className, onKeyDown, ...props }, ref) => {\n const { value, setValue, disabled, isLoading, submit } = usePromptInputContext();\n return (\n <textarea\n ref={ref}\n value={value}\n onChange={(event) => setValue(event.target.value)}\n onKeyDown={(event) => {\n if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault();\n submit();\n }\n onKeyDown?.(event);\n }}\n disabled={disabled || isLoading}\n rows={1}\n className={cn(\n 'flex-1 resize-none rounded-md border border-input bg-background px-3 py-2 text-sm',\n 'placeholder:text-muted-foreground',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n 'min-h-[40px]',\n className\n )}\n {...props}\n />\n );\n});\nPromptInputTextarea.displayName = 'PromptInputTextarea';\n\n/** Status-aware submit control: send / stop / error icons chosen automatically. */\nconst PromptInputSubmit = React.forwardRef<HTMLButtonElement, { className?: string }>(({ className }, ref) => {\n const { canSubmit, isLoading, hasStop, submit, stop, disabled } = usePromptInputContext();\n return (\n <Button\n ref={ref}\n onClick={isLoading && hasStop ? stop : submit}\n disabled={isLoading && hasStop ? false : !canSubmit || disabled}\n variant={isLoading && hasStop ? 'outline' : 'default'}\n size=\"icon\"\n type=\"button\"\n aria-label={isLoading && hasStop ? 'Stop generating' : 'Send'}\n className={className}\n >\n <span aria-hidden=\"true\">{isLoading && hasStop ? '■' : '→'}</span>\n </Button>\n );\n});\nPromptInputSubmit.displayName = 'PromptInputSubmit';\n\n/** Toolbar row under the textarea. */\nfunction PromptInputFooter({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n return <div className={cn('flex items-center justify-between gap-2 pt-1', className)} {...props} />;\n}\n\n/** Left-aligned group of tools inside a footer. */\nfunction PromptInputTools({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n return <div className={cn('flex items-center gap-1', className)} {...props} />;\n}\n\n/** Row above the textarea (attachments, hints). */\nfunction PromptInputHeader({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n return <div className={cn('mb-1', className)} {...props} />;\n}\n\n/** Wrapper around the textarea row. */\nfunction PromptInputBody({ className, ...props }: React.HTMLAttributes<HTMLDivElement>) {\n return <div className={cn('flex gap-2 items-end', className)} {...props} />;\n}\n\nexport type PromptInputButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {\n /** Tooltip content; optionally includes a keyboard shortcut hint. */\n tooltip?: string | { content: React.ReactNode; shortcut?: string };\n active?: boolean;\n};\n\n/** Small toolbar button with optional tooltip and shortcut hint. */\nconst PromptInputButton = React.forwardRef<HTMLButtonElement, PromptInputButtonProps>(\n ({ tooltip, active = false, className, ...props }, ref) => {\n const tip = typeof tooltip === 'string' ? { content: tooltip } : tooltip;\n return (\n <span className=\"relative inline-flex group/tip\">\n <button\n ref={ref}\n type=\"button\"\n aria-pressed={active || undefined}\n className={cn(\n 'inline-flex h-7 items-center gap-1 rounded-md border border-transparent px-2 text-xs text-muted-foreground transition-colors',\n 'hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',\n active && 'border-border bg-muted text-foreground',\n className\n )}\n {...props}\n />\n {tip && (\n <span\n role=\"tooltip\"\n className=\"pointer-events-none absolute bottom-full left-0 mb-1 z-10 flex items-center gap-1 whitespace-nowrap rounded border border-border bg-popover px-2 py-0.5 text-[11px] text-popover-foreground opacity-0 shadow-sm transition-opacity group-hover/tip:opacity-100\"\n >\n {tip.content}\n {tip.shortcut && <kbd className=\"rounded bg-muted px-1 font-mono\">{tip.shortcut}</kbd>}\n </span>\n )}\n </span>\n );\n }\n);\nPromptInputButton.displayName = 'PromptInputButton';\n\n/** Dictation toggle using the Web Speech API; hidden when unsupported. */\nfunction PromptInputActionDictate({ labels }: { labels?: { start?: string; stop?: string } }) {\n const { dictate } = usePromptInputContext();\n if (!dictate.supported) return null;\n return (\n <PromptInputButton\n onClick={dictate.toggle}\n active={dictate.isListening}\n tooltip={{ content: dictate.isListening ? labels?.stop ?? 'Stop dictating' : labels?.start ?? 'Dictate' }}\n aria-label={dictate.isListening ? labels?.stop ?? 'Stop dictation' : labels?.start ?? 'Start dictation'}\n >\n <span aria-hidden=\"true\">🎙</span>\n </PromptInputButton>\n );\n}\n\n/** Opens the managed file picker with configured constraints. */\n\n/** Opens the managed file picker with configured constraints. */\nfunction PromptInputActionAddAttachments({ label = 'Add photos or files' }: { label?: string }) {\n const { openFilePicker } = usePromptInputContext();\n return (\n <PromptInputButton onClick={openFilePicker}>\n <span aria-hidden=\"true\">+</span>\n <span>{label}</span>\n </PromptInputButton>\n );\n}\n\nexport {\n PromptInputRoot as PromptInput,\n PromptInputTextarea,\n PromptInputSubmit,\n PromptInputFooter,\n PromptInputTools,\n PromptInputHeader,\n PromptInputBody,\n PromptInputButton,\n PromptInputActionDictate,\n PromptInputActionAddAttachments,\n};\n","'use client';\n\nimport * as React from 'react';\nimport { cn } from '@slipstream-ui/core';\nimport type { ReasoningStep } from '../../types';\n\nexport type ReasoningProps = {\n steps: ReasoningStep[];\n className?: string;\n collapsible?: boolean;\n defaultExpanded?: boolean;\n /** Elapsed thinking time, e.g. 4 (seconds) or \"4s\"; rendered in the header. */\n duration?: number | string;\n /** Marks reasoning as still arriving: animated header state. */\n isStreaming?: boolean;\n /** Localized header, count and step labels. */\n labels?: {\n title?: string;\n count?: (count: number) => string;\n thinking?: string;\n step?: (index: number) => string;\n };\n};\n\nconst Reasoning = React.forwardRef<HTMLDivElement, ReasoningProps>(\n ({ steps, className, collapsible = true, defaultExpanded = false, duration, isStreaming = false, labels, ...props }, ref) => {\n const [isExpanded, setIsExpanded] = React.useState(defaultExpanded);\n const contentId = React.useId();\n\n if (steps.length === 0) {\n return null;\n }\n\n const headerText = [\n labels?.title ?? 'Reasoning',\n labels?.count ? labels.count(steps.length) : `(${steps.length} ${steps.length === 1 ? 'step' : 'steps'})`,\n typeof duration === 'number' ? `· ${duration}s` : duration ? `· ${duration}` : '',\n isStreaming ? `· ${labels?.thinking ?? 'thinking…'}` : '',\n ]\n .filter(Boolean)\n .join(' ');\n\n return (\n <div ref={ref} className={cn('border-l-2 border-muted-foreground/30 pl-4', className)} {...props}>\n {collapsible ? (\n <button\n onClick={() => setIsExpanded(!isExpanded)}\n className=\"flex items-center gap-2 text-sm font-medium text-muted-foreground hover:text-foreground transition-colors\"\n aria-expanded={isExpanded}\n aria-controls={contentId}\n >\n <span className={cn('transition-transform', isExpanded ? 'rotate-90' : '')}>?</span>\n <span>{headerText}</span>\n {isStreaming && (\n <span className=\"flex gap-0.5\" aria-hidden=\"true\">\n {[0, 150, 300].map((delay) => (\n <span\n key={delay}\n className=\"h-1 w-1 rounded-full bg-muted-foreground animate-pulse motion-reduce:animate-none\"\n style={{ animationDelay: `${delay}ms` }}\n />\n ))}\n </span>\n )}\n </button>\n ) : null}\n\n {(isExpanded || !collapsible) && (\n <div id={contentId} className=\"mt-3 space-y-3\">\n {steps.map((step, index) => (\n <div key={step.id} className=\"flex gap-3\">\n <div className=\"w-3 h-3 rounded-full bg-primary/20 border-2 border-primary flex-shrink-0 mt-1\" />\n <div className=\"text-sm flex-1\">\n <div className=\"font-medium text-foreground mb-1\">{labels?.step?.(index + 1) ?? `Step ${index + 1}`}</div>\n <div className=\"text-muted-foreground\">{step.content}</div>\n {step.timestamp && (\n <div className=\"text-xs text-muted-foreground mt-1\">\n {new Date(step.timestamp).toLocaleTimeString()}\n </div>\n )}\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n );\n }\n);\nReasoning.displayName = 'Reasoning';\n\nexport { Reasoning };\n","'use client';\n\nimport * as React from 'react';\nimport { cn } from '@slipstream-ui/core';\nimport type { ToolCall as ToolCallType } from '../../types';\n\nexport type ToolCallProps = {\n toolCall: ToolCallType;\n className?: string;\n showResult?: boolean;\n /** Localized status and section labels. */\n labels?: {\n pending?: string;\n running?: string;\n completed?: string;\n failed?: string;\n arguments?: string;\n result?: string;\n error?: string;\n };\n};\n\nconst statusChipClasses: Record<ToolCallType['status'], string> = {\n pending: 'bg-warning/10 text-warning-ink border-warning/20',\n running: 'bg-info/10 text-info-ink border-info/20',\n completed: 'bg-success/10 text-success border-success/20',\n failed: 'bg-destructive/10 text-destructive border-destructive/20',\n};\n\nconst defaultStatusLabels: Record<ToolCallType['status'], string> = {\n pending: 'Pending',\n running: 'Running',\n completed: 'Completed',\n failed: 'Failed',\n};\n\n/**\n * Displays a single tool invocation: name, status chip, serialized\n * arguments, optional result, and an error block on failure.\n */\nconst ToolCall = React.forwardRef<HTMLDivElement, ToolCallProps>(\n ({ toolCall, className, showResult = true, labels, ...props }, ref) => {\n const serializedArguments = React.useMemo(\n () => JSON.stringify(toolCall.arguments, null, 2),\n [toolCall.arguments]\n );\n const serializedResult = React.useMemo(() => {\n if (toolCall.result === undefined) return undefined;\n return typeof toolCall.result === 'string'\n ? toolCall.result\n : JSON.stringify(toolCall.result, null, 2);\n }, [toolCall.result]);\n\n const statusLabels: Record<ToolCallType['status'], string> = {\n pending: labels?.pending ?? defaultStatusLabels.pending,\n running: labels?.running ?? defaultStatusLabels.running,\n completed: labels?.completed ?? defaultStatusLabels.completed,\n failed: labels?.failed ?? defaultStatusLabels.failed,\n };\n\n return (\n <div\n ref={ref}\n className={cn(\n 'border rounded-lg p-4 bg-muted/30',\n className\n )}\n {...props}\n >\n <div className=\"flex items-center justify-between mb-3\">\n <div className=\"flex items-center gap-2\">\n <span className=\"font-medium text-sm\">{toolCall.name}</span>\n <span\n className={cn(\n 'text-xs px-2 py-0.5 rounded-full border',\n statusChipClasses[toolCall.status]\n )}\n >\n {statusLabels[toolCall.status]}\n </span>\n </div>\n <span className=\"text-xs text-muted-foreground\">{toolCall.id}</span>\n </div>\n\n <div className=\"space-y-2\">\n <div>\n <div className=\"text-xs font-medium text-muted-foreground mb-1\">{labels?.arguments ?? 'Arguments'}</div>\n <pre className=\"text-xs bg-muted p-2 rounded overflow-x-auto\">\n <code>{serializedArguments}</code>\n </pre>\n </div>\n\n {showResult && serializedResult !== undefined && (\n <div>\n <div className=\"text-xs font-medium text-muted-foreground mb-1\">{labels?.result ?? 'Result'}</div>\n <pre className=\"text-xs bg-muted p-2 rounded overflow-x-auto\">\n <code>{serializedResult}</code>\n </pre>\n </div>\n )}\n\n {toolCall.status === 'failed' && toolCall.error && (\n <div role=\"alert\">\n <div className=\"text-xs font-medium text-destructive mb-1\">{labels?.error ?? 'Error'}</div>\n <pre className=\"text-xs bg-destructive/10 text-destructive p-2 rounded overflow-x-auto whitespace-pre-wrap\">\n <code>{toolCall.error}</code>\n </pre>\n </div>\n )}\n </div>\n </div>\n );\n }\n);\nToolCall.displayName = 'ToolCall';\n\nexport { ToolCall };\n","import * as React from 'react';\nimport { cn } from '@slipstream-ui/core';\nimport type { SourceItem } from '../../types';\n\nexport type SourceProps = {\n source: SourceItem;\n /**\n * 1-based citation marker rendered as a `[n]` prefix.\n * Omit to render the citation without numbering.\n */\n index?: number;\n className?: string;\n};\n\nconst Source = React.forwardRef<HTMLDivElement, SourceProps>(\n ({ source, index, className, ...props }, ref) => {\n return (\n <div ref={ref} className={cn('flex gap-2 items-start text-sm', className)} {...props}>\n {index !== undefined && (\n <span className=\"text-muted-foreground select-none\" aria-hidden=\"true\">\n [{index}]\n </span>\n )}\n <div className=\"flex-1 min-w-0\">\n <div className=\"font-medium text-foreground\">\n {source.url ? (\n <a\n href={source.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"hover:text-primary transition-colors\"\n >\n {source.title}\n </a>\n ) : (\n <span>{source.title}</span>\n )}\n </div>\n {source.snippet && (\n <div className=\"text-xs text-muted-foreground mt-1 line-clamp-2\">\n {source.snippet}\n </div>\n )}\n </div>\n </div>\n );\n }\n);\nSource.displayName = 'Source';\n\nexport { Source };\n","import * as React from 'react';\nimport { cn } from '@slipstream-ui/core';\nimport type { SourceItem } from '../../types';\nimport { Source } from './Source';\n\nexport type SourcesProps = {\n sources: SourceItem[];\n className?: string;\n maxDisplay?: number;\n /** Heading label; override for localization. */\n label?: string;\n};\n\nconst Sources = React.forwardRef<HTMLDivElement, SourcesProps>(\n ({ sources, className, maxDisplay = 3, label = 'Sources', ...props }, ref) => {\n const displaySources = maxDisplay ? sources.slice(0, maxDisplay) : sources;\n const hasMore = maxDisplay && sources.length > maxDisplay;\n\n if (sources.length === 0) {\n return null;\n }\n\n return (\n <div ref={ref} className={cn('mt-4 pt-4 border-t border-border', className)} {...props}>\n <div className=\"text-xs font-medium text-muted-foreground mb-2\">{label}</div>\n <div className=\"space-y-2\">\n {displaySources.map((source, index) => (\n <Source key={source.id} source={source} index={index + 1} />\n ))}\n {hasMore && (\n <div className=\"text-xs text-muted-foreground\">\n +{sources.length - (maxDisplay ?? 0)} more sources\n </div>\n )}\n </div>\n </div>\n );\n }\n);\nSources.displayName = 'Sources';\n\nexport { Sources };\n","import * as React from 'react';\nimport { cn } from '@slipstream-ui/core';\n\nexport type Suggestion = {\n id: string;\n text: string;\n type?: 'action' | 'query' | 'follow-up';\n};\n\nexport type SuggestionsProps = {\n suggestions: Suggestion[];\n onSelect?: (suggestion: Suggestion) => void;\n className?: string;\n maxDisplay?: number;\n};\n\nconst Suggestions = React.forwardRef<HTMLDivElement, SuggestionsProps>(\n ({ suggestions, onSelect, className, maxDisplay = 4, ...props }, ref) => {\n const displaySuggestions = maxDisplay ? suggestions.slice(0, maxDisplay) : suggestions;\n\n if (suggestions.length === 0) {\n return null;\n }\n\n return (\n <div ref={ref} className={cn('mt-4 space-y-2', className)} {...props}>\n {displaySuggestions.map((suggestion) => (\n <button\n key={suggestion.id}\n className={cn(\n 'w-full text-left h-auto py-2 px-3 text-sm rounded-md',\n 'hover:bg-accent hover:text-accent-foreground',\n 'transition-colors',\n 'text-muted-foreground',\n 'focus:outline-none focus:ring-2 focus:ring-ring'\n )}\n onClick={() => onSelect?.(suggestion)}\n >\n {suggestion.text}\n </button>\n ))}\n </div>\n );\n});\nSuggestions.displayName = 'Suggestions';\n\nexport { Suggestions };\n","import * as React from 'react';\nimport { cn } from '@slipstream-ui/core';\n\nexport type ChainThoughtStep = {\n id: string;\n content: string;\n status?: 'pending' | 'completed' | 'failed';\n};\n\nexport type ChainThoughtProps = {\n steps: ChainThoughtStep[];\n className?: string;\n compact?: boolean;\n};\n\nconst ChainThought = React.forwardRef<HTMLDivElement, ChainThoughtProps>(\n ({ steps, className, compact = false, ...props }, ref) => {\n if (steps.length === 0) {\n return null;\n }\n\n return (\n <div ref={ref} className={cn('space-y-2', className)} {...props}>\n {steps.map((step, index) => (\n <div key={step.id} className=\"flex gap-3 items-start\">\n <div className={cn(\n 'w-2 h-2 rounded-full mt-1.5 flex-shrink-0',\n step.status === 'completed' ? 'bg-success' : \n step.status === 'failed' ? 'bg-destructive' : \n step.status === 'pending' ? 'bg-warning' : 'bg-primary'\n )} />\n <div className={cn('flex-1', compact && 'text-sm')}>\n <div className=\"text-sm text-muted-foreground\">\n Step {index + 1}\n </div>\n <div className=\"text-foreground\">{step.content}</div>\n </div>\n </div>\n ))}\n </div>\n );\n});\nChainThought.displayName = 'ChainThought';\n\nexport { ChainThought };\n","import * as React from 'react';\nimport { cn } from '@slipstream-ui/core';\n\nexport type StreamingIndicatorProps = {\n isStreaming: boolean;\n className?: string;\n text?: string;\n};\n\n/**\n * Animated three-dot streaming indicator. Announces the streaming state\n * to screen readers via role=\"status\" / aria-live so assistive tech\n * users know generation is in progress.\n */\nconst StreamingIndicator = React.forwardRef<HTMLDivElement, StreamingIndicatorProps>(\n ({ isStreaming, className, text = 'Generating...', ...props }, ref) => {\n if (!isStreaming) {\n return null;\n }\n\n return (\n <div\n ref={ref}\n role=\"status\"\n aria-live=\"polite\"\n aria-label={text}\n className={cn('flex items-center gap-2 text-sm text-muted-foreground', className)}\n {...props}\n >\n <div className=\"flex gap-1\" aria-hidden=\"true\">\n {[0, 150, 300].map((delay) => (\n <span\n key={delay}\n className=\"w-2 h-2 bg-primary rounded-full animate-pulse motion-reduce:animate-none\"\n style={{ animationDelay: `${delay}ms` }}\n />\n ))}\n </div>\n <span>{text}</span>\n </div>\n );\n }\n);\nStreamingIndicator.displayName = 'StreamingIndicator';\n\nexport { StreamingIndicator };\n","'use client';\n\nimport * as React from 'react';\nimport { cn } from '@slipstream-ui/core';\n\nexport type Command = {\n id: string;\n label: string;\n /** Optional grouping header, e.g. \"Navigation\". */\n section?: string;\n /** Extra lexical search terms. */\n keywords?: string[];\n shortcut?: string;\n /** Optional leading icon (rendered by the default row or renderCommand). */\n icon?: React.ReactNode;\n /** Optional secondary line in the default row. */\n description?: string;\n};\n\nexport type CommandPaletteProps = {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n /** Static command set (ignored for filtering when loadCommands is set). */\n commands: Command[];\n onSelect: (command: Command) => void;\n /** Async source; called with the current query (debounced). */\n loadCommands?: (query: string) => Promise<Command[]>;\n /** Debounce for loadCommands, in ms. Default 200. */\n debounceMs?: number;\n /** Custom row renderer (icons, type badges, metadata). */\n renderCommand?: (command: Command, state: { active: boolean }) => React.ReactNode;\n /** Shown while async commands load. */\n loadingText?: string;\n placeholder?: string;\n};\n\n/**\n * Cmd+K command palette: combobox + listbox with aria-activedescendant\n * keyboard navigation, lexical filtering over label/keywords, and\n * Escape-to-close. No focus leaves the input while navigating.\n */\nexport function CommandPalette({\n open,\n onOpenChange,\n commands,\n onSelect,\n loadCommands,\n debounceMs = 200,\n renderCommand,\n loadingText = 'Searching…',\n placeholder = 'Type a command.',\n}: CommandPaletteProps) {\n const [query, setQuery] = React.useState('');\n const [activeIndex, setActiveIndex] = React.useState(0);\n const [asyncCommands, setAsyncCommands] = React.useState<Command[]>([]);\n const [loading, setLoading] = React.useState(false);\n const requestId = React.useRef(0);\n const asyncSignature = loadCommands ? String(loadCommands.length) : '';\n const inputRef = React.useRef<HTMLInputElement | null>(null);\n const listboxId = React.useId();\n const optionId = (index: number) => `${listboxId}-option-${index}`;\n\n React.useEffect(() => {\n if (!open || !loadCommands) return;\n const id = ++requestId.current;\n setLoading(true);\n const timer = setTimeout(async () => {\n try {\n const result = await loadCommands(query);\n if (requestId.current === id) setAsyncCommands(result);\n } catch {\n if (requestId.current === id) setAsyncCommands([]);\n } finally {\n if (requestId.current === id) setLoading(false);\n }\n }, debounceMs);\n return () => clearTimeout(timer);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open, query, debounceMs, asyncSignature]);\n\n const filtered = React.useMemo(() => {\n if (loadCommands) return asyncCommands;\n const terms = query.trim().toLowerCase().split(/\\s+/).filter(Boolean);\n if (terms.length === 0) return commands;\n return commands.filter((command) => {\n const haystack = `${command.label} ${command.section ?? ''} ${(command.keywords ?? []).join(' ')}`.toLowerCase();\n return terms.every((term) => haystack.includes(term));\n });\n }, [commands, query, asyncCommands, loadCommands]);\n\n React.useEffect(() => {\n if (open) {\n setQuery('');\n setActiveIndex(0);\n // Focus after paint so the portal/DOM node exists.\n const timer = setTimeout(() => inputRef.current?.focus(), 0);\n return () => clearTimeout(timer);\n }\n return undefined;\n }, [open]);\n\n React.useEffect(() => {\n setActiveIndex((index) => Math.min(index, Math.max(0, filtered.length - 1)));\n }, [filtered.length]);\n\n if (!open) return null;\n\n const onKeyDown = (event: React.KeyboardEvent) => {\n if (event.key === 'Escape') {\n event.preventDefault();\n onOpenChange(false);\n } else if (event.key === 'ArrowDown') {\n event.preventDefault();\n setActiveIndex((index) => (filtered.length === 0 ? 0 : (index + 1) % filtered.length));\n } else if (event.key === 'ArrowUp') {\n event.preventDefault();\n setActiveIndex((index) => (filtered.length === 0 ? 0 : (index - 1 + filtered.length) % filtered.length));\n } else if (event.key === 'Enter') {\n event.preventDefault();\n const command = filtered[activeIndex];\n if (command) {\n onSelect(command);\n onOpenChange(false);\n }\n }\n };\n\n let lastSection: string | undefined;\n\n return (\n <div\n className=\"fixed inset-0 z-50 flex items-start justify-center bg-background/80 p-4 pt-[15vh]\"\n onMouseDown={(event) => {\n if (event.target === event.currentTarget) onOpenChange(false);\n }}\n >\n <div className=\"w-full max-w-lg overflow-hidden rounded-xl border border-border bg-card shadow-2xl\">\n <input\n ref={inputRef}\n type=\"text\"\n role=\"combobox\"\n aria-expanded=\"true\"\n aria-controls={listboxId}\n aria-activedescendant={filtered.length > 0 ? optionId(activeIndex) : undefined}\n aria-autocomplete=\"list\"\n aria-label=\"Command palette\"\n placeholder={placeholder}\n value={query}\n onChange={(event) => {\n setQuery(event.target.value);\n setActiveIndex(0);\n }}\n onKeyDown={onKeyDown}\n className=\"w-full border-b border-border bg-transparent px-4 py-3 text-sm outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-ring placeholder:text-muted-foreground\"\n />\n <ul\n id={listboxId}\n role=\"listbox\"\n aria-label=\"Commands\"\n aria-busy={loading || undefined}\n className=\"max-h-72 overflow-y-auto py-1\"\n >\n {loading && filtered.length === 0 && (\n <li role=\"presentation\" className=\"px-4 py-3 text-sm text-muted-foreground\">\n {loadingText}\n </li>\n )}\n {!loading && filtered.length === 0 && (\n <li role=\"presentation\" className=\"px-4 py-3 text-sm text-muted-foreground\">\n No matching commands.\n </li>\n )}\n {filtered.map((command, index) => {\n const showSection = command.section && command.section !== lastSection;\n lastSection = command.section ?? lastSection;\n return (\n <React.Fragment key={command.id}>\n {showSection && (\n <li role=\"presentation\" className=\"px-4 pb-1 pt-3 text-xs font-medium uppercase text-muted-foreground\">\n {command.section}\n </li>\n )}\n <li\n id={optionId(index)}\n role=\"option\"\n aria-selected={index === activeIndex}\n onMouseEnter={() => setActiveIndex(index)}\n onClick={() => {\n onSelect(command);\n onOpenChange(false);\n }}\n className={cn(\n 'flex cursor-pointer items-center justify-between px-4 py-2 text-sm',\n index === activeIndex ? 'bg-primary/10 text-foreground' : 'text-muted-foreground'\n )}\n >\n {renderCommand ? (\n renderCommand(command, { active: index === activeIndex })\n ) : (\n <>\n <span className=\"flex min-w-0 items-center gap-2\">\n {command.icon && <span className=\"shrink-0 [&_svg]:size-4\">{command.icon}</span>}\n <span className=\"min-w-0\">\n <span className=\"block truncate\">{command.label}</span>\n {command.description && (\n <span className=\"block text-xs text-muted-foreground\">{command.description}</span>\n )}\n </span>\n </span>\n {command.shortcut && <span className=\"font-mono text-xs\">{command.shortcut}</span>}\n </>\n )}\n </li>\n </React.Fragment>\n );\n })}\n </ul>\n </div>\n </div>\n );\n}\n","import type { Message as MessageData, ToolCall as ToolCallData } from '../types';\nimport type { AiSdkMessage, AiSdkToolInvocation } from './types';\n\n/** Map one AI SDK tool invocation to a Slipstream ToolCall data object. */\nexport function toSlipstreamToolCall(invocation: AiSdkToolInvocation): ToolCallData {\n const status =\n invocation.state === 'result' ? 'completed'\n : invocation.state === 'error' ? 'failed'\n : invocation.state === 'call' ? 'pending'\n : 'pending';\n return {\n id: invocation.toolCallId,\n name: invocation.toolName,\n arguments: invocation.args ?? {},\n status,\n ...(status === 'completed' && invocation.result !== undefined\n ? { result: invocation.result as ToolCallData['result'] }\n : {}),\n ...(status === 'failed'\n ? { error: invocation.error instanceof Error ? invocation.error.message : String(invocation.error ?? 'Tool call failed') }\n : {}),\n };\n}\n\n/** Extract every tool call carried by an AI SDK message. */\nexport function toSlipstreamToolCalls(message: AiSdkMessage): ToolCallData[] {\n return (message.toolInvocations ?? []).map(toSlipstreamToolCall);\n}\n\n/**\n * Map one AI SDK message onto a Slipstream Message. Tool invocations are\n * preserved under `metadata.toolCalls` (and via toSlipstreamToolCalls) so\n * ToolCall components can render them.\n */\nexport function toSlipstreamMessage(message: AiSdkMessage): MessageData {\n return {\n id: message.id,\n role: message.role,\n content: message.content,\n ...(message.toolInvocations?.length\n ? { metadata: { toolCalls: toSlipstreamToolCalls(message) } }\n : {}),\n };\n}\n\n/** Map a useChat/useCompletion message list into Slipstream messages. */\nexport function toSlipstreamMessages(messages: AiSdkMessage[]): MessageData[] {\n return messages.map(toSlipstreamMessage);\n}\n","'use client';\n\nimport { useMemo } from 'react';\nimport type { Message as MessageData } from '../types';\nimport { toSlipstreamMessages } from './messages';\nimport type { AiSdkMessage, AiSdkStatus } from './types';\n\nexport type UseSlipstreamMessagesOptions = {\n /** `messages` from the AI SDK's useChat()/useCompletion() state. */\n messages: AiSdkMessage[];\n}\n\nexport type UseSlipstreamMessagesResult = {\n messages: MessageData[];\n};\n\n/**\n * Bridge AI SDK chat messages to Slipstream `<Conversation>`/`<Message>`\n * input. Pure derivation of the current state — safe to call from any\n * runtime that provides the structural message shape.\n */\nexport function useSlipstreamMessages({ messages }: UseSlipstreamMessagesOptions): UseSlipstreamMessagesResult {\n const mapped = useMemo(() => toSlipstreamMessages(messages), [messages]);\n return { messages: mapped };\n}\n\nexport type UseSlipstreamStreamOptions = {\n /** `status` from the AI SDK chat state. */\n status?: AiSdkStatus;\n /** `error` from the AI SDK chat state. */\n error?: unknown;\n /** Retry handler wired to the SDK's reload/retry (e.g. `reload`). */\n onRetry?: () => void;\n /** Messages from the SDK chat state; used to locate the streaming id. */\n messages?: AiSdkMessage[];\n};\n\nexport type UseSlipstreamStreamResult = {\n isLoading: boolean;\n streamingMessageId?: string;\n messageErrors?: Record<string, string>;\n onRetryMessage?: (messageId: string) => void;\n};\n\n/**\n * Bridge AI SDK stream status/error to Slipstream Conversation props:\n * `isLoading` gates the loading row, `streamingMessageId` drives the typing\n * cursor on the last assistant message, and errors map to retryable\n * per-message failures (streaming/tool states).\n */\nexport function useSlipstreamStream({\n status,\n error,\n onRetry,\n messages = [],\n}: UseSlipstreamStreamOptions): UseSlipstreamStreamResult {\n const isLoading = status === 'submitted' || status === 'streaming';\n const streamingMessageId = useMemo(() => {\n if (status !== 'streaming') return undefined;\n for (let index = messages.length - 1; index >= 0; index--) {\n const message = messages[index];\n if (message?.role === 'assistant') return message.id;\n }\n return messages.at(-1)?.id;\n }, [status, messages]);\n\n const messageErrors = useMemo(() => {\n if (status !== 'error' || !error) return undefined;\n const last = messages.at(-1);\n if (!last) return undefined;\n return {\n [last.id]: error instanceof Error ? error.message : String(error),\n };\n }, [status, error, messages]);\n\n return {\n isLoading,\n ...(streamingMessageId ? { streamingMessageId } : {}),\n ...(messageErrors ? { messageErrors } : {}),\n ...(onRetry ? { onRetryMessage: onRetry } : {}),\n };\n}\n"],"mappings":"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","names":["import_core","React","import_core","import_jsx_runtime","React","import_core","import_jsx_runtime","React","import_core","import_jsx_runtime","React","import_core","React","import_core","import_jsx_runtime","import_jsx_runtime","ReactMarkdown","remarkGfm","children","React","import_core","import_jsx_runtime","React","import_core","import_jsx_runtime","React","import_core","import_jsx_runtime","React","import_core","import_jsx_runtime","React","import_core","import_jsx_runtime","React","import_core","import_jsx_runtime","React","import_core","import_jsx_runtime","statusChipClasses","React","import_core","import_jsx_runtime","React","import_core","import_jsx_runtime","React","import_core","import_jsx_runtime","React","import_core","import_jsx_runtime","React","import_core","import_jsx_runtime","React","import_core","import_jsx_runtime"]}
|