@athenaintel/react 0.22.2 → 0.22.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/dist/chat/AthenaChat.cjs +16 -6
- package/dist/chat/AthenaChat.cjs.map +1 -1
- package/dist/chat/AthenaChat.js +15 -5
- package/dist/chat/AthenaChat.js.map +1 -1
- package/dist/chat-ui/mentions/suggestions/data/sources/asset-type-icons.cjs +0 -1
- package/dist/chat-ui/mentions/suggestions/data/sources/asset-type-icons.cjs.map +1 -1
- package/dist/chat-ui/mentions/suggestions/data/sources/asset-type-icons.js +0 -1
- package/dist/chat-ui/mentions/suggestions/data/sources/asset-type-icons.js.map +1 -1
- package/dist/chat-ui/messages/message-components.cjs +1 -0
- package/dist/chat-ui/messages/message-components.cjs.map +1 -1
- package/dist/chat-ui/messages/message-components.d.ts +7 -0
- package/dist/chat-ui/messages/message-components.js +1 -0
- package/dist/chat-ui/messages/message-components.js.map +1 -1
- package/dist/packages/agent-runtime/src/tool-metadata.cjs +0 -14
- package/dist/packages/agent-runtime/src/tool-metadata.cjs.map +1 -1
- package/dist/packages/agent-runtime/src/tool-metadata.js +0 -14
- package/dist/packages/agent-runtime/src/tool-metadata.js.map +1 -1
- package/dist/packages/react/package.json.cjs +1 -1
- package/dist/packages/react/package.json.js +1 -1
- package/dist/styles.css +1 -1
- package/dist/toolkits/index.cjs +0 -7
- package/dist/toolkits/index.cjs.map +1 -1
- package/dist/toolkits/index.d.ts +0 -2
- package/dist/toolkits/index.js +0 -7
- package/dist/toolkits/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AthenaChat.js","sources":["../../src/chat/AthenaChat.tsx"],"sourcesContent":["import { TiptapText } from './tiptap-text';\nimport { AthenaChatErrorBoundary } from './AthenaChatErrorBoundary';\nimport { StatewireApprovalCard } from './StatewireApprovalCard';\nimport { StatewireQueuedMessages } from './StatewireQueuedMessages';\nimport { StatewireConnectionBanner, StatewireErrorBanner } from './statewire-banners';\nimport { ToolFallback } from '../tools/tool-fallback';\nimport { AppendDocumentToolUI } from '../tools/append-document-tool-ui';\nimport { ReadAssetToolUI } from '../tools/read-asset-tool-ui';\nimport { TOOL_UI_REGISTRY } from '../tools/tool-uis';\nimport { SuperGroupingCard, SuperGroupingFinalText } from './super-grouping/SuperGroupingCard';\nimport {\n NestedPtcComponentsProvider,\n NestedPtcMessages,\n useNestedPtcComponents,\n} from '../tools/NestedPtcMessages';\nimport { TooltipIconButton } from './tooltip-icon-button';\nimport { Button } from '../ui/button';\nimport { Collapsible, CollapsibleContent, CollapsibleTrigger } from '../ui/collapsible';\nimport { ChatComposerDock } from '../chat-ui/thread/chat-composer-dock';\nimport { ChatThreadShell } from '../chat-ui/thread/chat-thread-shell';\nimport { StatewireHistoryEdge } from '../chat-ui/thread/statewire-history-edge';\nimport { ComposerSendOrStop } from '../chat-ui/thread/composer-send-or-stop';\nimport {\n TiptapComposer,\n type ComposerFileIntake,\n type TiptapComposerHandle,\n} from '../chat-ui/composer/tiptap-composer';\nimport {\n MentionAuthCtx,\n type MentionAuthContext,\n} from '../chat-ui/mentions/suggestions/data/api-client';\nimport type { MentionRootCategory } from '../chat-ui/mentions/suggestions/data/use-mention-suggestions';\nimport type { MentionTool } from '../chat-ui/mentions/suggestions/data/types';\nimport type {\n ComposerSendButtonProps,\n ComposerStopButtonProps,\n} from '../chat-ui/messages/message-components';\nimport {\n ActionBarMorePrimitive,\n ActionBarPrimitive,\n AuiIf,\n ErrorPrimitive,\n MessagePrimitive,\n ThreadPrimitive,\n useAui,\n useAuiState,\n} from '@assistant-ui/react';\nimport type {\n EmptyMessagePartComponent,\n PartState,\n ReasoningMessagePartProps,\n ReasoningMessagePartComponent,\n TextMessagePartProps,\n TextMessagePartComponent,\n ToolCallMessagePartComponent,\n ToolCallMessagePartProps,\n} from '@assistant-ui/react';\nimport {\n AlertCircleIcon,\n ArrowDownIcon,\n ArrowUpIcon,\n ArrowRightIcon,\n BrainIcon,\n CheckIcon,\n ChevronDownIcon,\n ChevronRightIcon,\n CopyIcon,\n DownloadIcon,\n ExternalLinkIcon,\n LayersIcon,\n ListPlusIcon,\n MoreHorizontalIcon,\n RefreshCwIcon,\n SquareIcon,\n SearchIcon,\n FileTextIcon,\n PresentationIcon,\n} from 'lucide-react';\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type FC,\n} from 'react';\nimport { useAthenaStatewireThreadId, useAthenaThreadId } from '../threads/thread-id-context';\nimport { FileUploadButton } from '../composer/FileUploadButton';\nimport { ComposerQuotePreview } from '../composer/ComposerQuotePreview';\nimport { ComposerAttachmentPreview } from '../composer/ComposerAttachmentPreview';\nimport { ComposerDropZone } from '../composer/ComposerDropZone';\nimport { useQuote, QuoteProvider, useQuoteFromPostMessage } from '../composer/QuoteContext';\nimport { AttachmentProvider, useAttachments } from '../composer/AttachmentContext';\nimport { buildComposedMessage } from '../composer/build-composed-message';\nimport { useAttachFiles } from '../composer/useAttachFiles';\nimport { useAthenaConfig } from '../provider/AthenaContext';\nimport { createAthenaSpacesUrl } from '../lib/athena-urls';\nimport { cn, isRecord } from '../lib/utils';\nimport { useSendMessage } from '../composer/useSendMessage';\nimport { getToolkitDisplayInfo } from '../toolkits';\nimport {\n RUN_ACTIVITY_STALL_SECONDS,\n runActivityKey,\n runActivityLabel,\n} from './run-activity';\n\nfunction QuotePostMessageBridge() {\n useQuoteFromPostMessage();\n return null;\n}\n\nexport interface WelcomeSuggestion {\n icon: React.ElementType;\n title: string;\n prompt: string;\n}\n\nconst DEFAULT_SUGGESTIONS: WelcomeSuggestion[] = [\n {\n icon: SearchIcon,\n title: \"Research a topic and draft a report\",\n prompt: \"Search the web for the latest developments in enterprise AI adoption, then create a document summarizing the key trends, market data, and strategic implications.\",\n },\n {\n icon: SearchIcon,\n title: \"Compare recent AI model launches\",\n prompt: \"Search the web for the latest major AI model launches from OpenAI, Anthropic, and Google, then summarize the release dates, standout capabilities, and practical tradeoffs in a concise comparison table.\",\n },\n {\n icon: PresentationIcon,\n title: \"Build a presentation from scratch\",\n prompt: \"Create a 5-slide investor update presentation covering market opportunity, product traction, key metrics, competitive positioning, and next steps.\",\n },\n {\n icon: FileTextIcon,\n title: \"Set up a structured spreadsheet\",\n prompt: \"Create a project tracking spreadsheet with columns for task name, owner, priority, status, start date, due date, and completion percentage.\",\n },\n];\n\nexport interface AthenaChatProps {\n /** CSS class name for the root element. */\n className?: string;\n /** Welcome heading text. Defaults to \"Hello there!\" */\n welcomeMessage?: string;\n /** Welcome subheading text. */\n welcomeSubtext?: string;\n /** Maximum width for the thread content. Defaults to \"44rem\". */\n maxWidth?: string;\n /**\n * Scroll anchoring for new turns. \"bottom\" (default) keeps the viewport\n * pinned to the end while the assistant streams — classic chat follow.\n * \"top\" pins the just-sent user message to the top of the viewport and\n * intentionally does NOT follow the streaming response (assistant-ui\n * disables autoScroll in that mode), so readers scroll at their own pace.\n */\n turnAnchor?: \"top\" | \"bottom\";\n /** Additional tool UIs to register by name. */\n toolUIs?: Record<string, ToolCallMessagePartComponent>;\n /** Tools / Toolkits offered by the composer's `@` menu beside the asset\n * library. Defaults to the toolkits enabled on the provider. */\n mentionTools?: MentionTool[];\n /** Suggestion cards shown on the welcome screen. Pass `[]` to hide.\n * For workflow launchers outside AthenaChat, use `useSendMessage()`.\n */\n welcomeSuggestions?: WelcomeSuggestion[];\n /** Optional component overrides for message containers and key message parts. */\n components?: AthenaChatComponents;\n /** Collapse adjacent tool calls into a single expandable group. Defaults to `false`. */\n groupToolCalls?: boolean;\n}\n\nexport interface AthenaChatMessagePartComponents {\n Text?: TextMessagePartComponent;\n Reasoning?: ReasoningMessagePartComponent;\n Empty?: EmptyMessagePartComponent;\n}\n\nexport interface AthenaChatComponents {\n UserMessage?: FC;\n AssistantMessage?: FC;\n AssistantActionBar?: FC<AthenaAssistantActionBarProps>;\n messageParts?: AthenaChatMessagePartComponents;\n}\n\nexport interface AthenaUserMessageProps {\n TextComponent?: TextMessagePartComponent;\n}\n\nexport interface AthenaAssistantActionBarProps {\n className?: string;\n}\n\nexport interface AthenaAssistantMessageProps {\n toolUIs: Record<string, ToolCallMessagePartComponent>;\n TextComponent?: TextMessagePartComponent;\n ReasoningComponent?: ReasoningMessagePartComponent;\n EmptyComponent?: EmptyMessagePartComponent;\n ActionBarComponent?: FC<AthenaAssistantActionBarProps>;\n /** Collapse adjacent tool calls into a single expandable group. Defaults to `false`. */\n groupToolCalls?: boolean;\n}\n\nexport interface AthenaReasoningPartProps extends ReasoningMessagePartProps {\n TextComponent?: TextMessagePartComponent;\n}\n\ninterface AthenaChatDefaultComponentsContextValue {\n toolUIs: Record<string, ToolCallMessagePartComponent>;\n TextComponent: TextMessagePartComponent;\n ReasoningComponent?: ReasoningMessagePartComponent;\n EmptyComponent: EmptyMessagePartComponent;\n ActionBarComponent: FC<AthenaAssistantActionBarProps>;\n groupToolCalls: boolean;\n}\n\nconst AthenaChatDefaultComponentsContext =\n createContext<AthenaChatDefaultComponentsContextValue | null>(null);\n\nconst AthenaReasoningTextComponentContext = createContext<TextMessagePartComponent | null>(null);\n\nconst useAthenaChatDefaultComponents = (): AthenaChatDefaultComponentsContextValue => {\n const value = useContext(AthenaChatDefaultComponentsContext);\n\n if (!value) {\n throw new Error('Athena default chat components must be used within AthenaChat.');\n }\n\n return value;\n};\n\nconst AthenaDefaultAssistantMessage: FC = () => {\n const { toolUIs, TextComponent, ReasoningComponent, EmptyComponent, ActionBarComponent, groupToolCalls } =\n useAthenaChatDefaultComponents();\n\n return (\n <AthenaAssistantMessage\n toolUIs={toolUIs}\n TextComponent={TextComponent}\n ReasoningComponent={ReasoningComponent}\n EmptyComponent={EmptyComponent}\n ActionBarComponent={ActionBarComponent}\n groupToolCalls={groupToolCalls}\n />\n );\n};\n\nconst AthenaDefaultUserMessage: FC = () => {\n const { TextComponent } = useAthenaChatDefaultComponents();\n\n return <AthenaUserMessage TextComponent={TextComponent} />;\n};\n\nconst getReasoningTokensFromMetadata = (metadata: unknown): number | undefined => {\n if (!isRecord(metadata)) {\n return undefined;\n }\n\n const customMetadata = metadata.custom;\n if (!isRecord(customMetadata)) {\n return undefined;\n }\n\n const athenaMetadata = customMetadata._athena;\n if (!isRecord(athenaMetadata)) {\n return undefined;\n }\n\n const reasoningTokens = athenaMetadata.reasoningTokens;\n return typeof reasoningTokens === 'number' && Number.isFinite(reasoningTokens)\n ? reasoningTokens\n : undefined;\n};\n\nconst formatReasoningTokens = (reasoningTokens: number) =>\n `${reasoningTokens.toLocaleString('en-US')} ${reasoningTokens === 1 ? 'token' : 'tokens'}`;\n\nconst withNestedPtcMessages = (\n ToolUI: ToolCallMessagePartComponent\n): ToolCallMessagePartComponent => {\n const ToolUIWithNestedPtcMessages: ToolCallMessagePartComponent = (props) => {\n const nestedComponents = useNestedPtcComponents(ToolFallback);\n\n return (\n <>\n <ToolUI {...props} />\n <NestedPtcMessages components={nestedComponents} />\n </>\n );\n };\n\n return ToolUIWithNestedPtcMessages;\n};\n\nconst SuggestionCard: FC<{ suggestion: WelcomeSuggestion; index: number }> = ({\n suggestion,\n index,\n}) => {\n const Icon = suggestion.icon;\n const sendMessage = useSendMessage();\n\n const handleClick = useCallback(() => {\n void sendMessage(suggestion.prompt);\n }, [sendMessage, suggestion.prompt]);\n\n return (\n <button\n type=\"button\"\n onClick={handleClick}\n className={`fade-in slide-in-from-bottom-2 animate-in fill-mode-both group flex items-start gap-3 rounded-xl border border-border/60 bg-background p-3.5 text-left shadow-sm transition-all duration-150 hover:border-border hover:bg-muted/40 hover:shadow-md`}\n style={{ animationDelay: `${100 + index * 75}ms` }}\n >\n <div className=\"flex size-8 shrink-0 items-center justify-center rounded-lg bg-muted/60 text-muted-foreground transition-colors group-hover:bg-primary/10 group-hover:text-primary\">\n <Icon className=\"size-4\" />\n </div>\n <div className=\"min-w-0 flex-1\">\n <span className=\"text-[13px] font-medium leading-snug text-foreground\">\n {suggestion.title}\n </span>\n </div>\n <ArrowRightIcon className=\"mt-0.5 size-3.5 shrink-0 text-muted-foreground/0 transition-all group-hover:text-muted-foreground\" />\n </button>\n );\n};\n\nconst AthenaChatWelcome: FC<{\n welcomeMessage: string;\n welcomeSubtext?: string;\n welcomeSuggestions: WelcomeSuggestion[];\n}> = ({ welcomeMessage, welcomeSubtext, welcomeSuggestions }) => (\n <div className=\"aui-thread-welcome-root mx-auto my-auto flex w-full max-w-(--thread-max-width) grow flex-col\">\n <div className=\"aui-thread-welcome-center flex w-full grow flex-col items-center justify-center\">\n <div className=\"aui-thread-welcome-message flex size-full flex-col justify-center px-4\">\n <h1 className=\"aui-thread-welcome-message-inner fade-in slide-in-from-bottom-1 animate-in fill-mode-both font-semibold text-2xl duration-200\">\n {welcomeMessage}\n </h1>\n {welcomeSubtext && (\n <p className=\"aui-thread-welcome-message-inner fade-in slide-in-from-bottom-1 animate-in fill-mode-both text-muted-foreground text-lg delay-75 duration-200\">\n {welcomeSubtext}\n </p>\n )}\n {welcomeSuggestions.length > 0 && (\n <div className=\"mt-6 grid grid-cols-1 gap-2.5 sm:grid-cols-2\">\n {welcomeSuggestions.map((s, i) => (\n <SuggestionCard key={s.title} suggestion={s} index={i} />\n ))}\n </div>\n )}\n </div>\n </div>\n </div>\n);\n\nexport const AthenaChat: FC<AthenaChatProps> = ({\n className,\n welcomeMessage = \"Hello there!\",\n welcomeSubtext = \"What can I help you with?\",\n maxWidth = \"44rem\",\n turnAnchor = \"bottom\",\n toolUIs,\n mentionTools,\n welcomeSuggestions = DEFAULT_SUGGESTIONS,\n components,\n groupToolCalls = false,\n}) => {\n const athenaConfig = useAthenaConfig();\n // The mention menu's GraphQL credentials: the backend and credential the\n // provider resolved. `athenaConfig` keeps its identity across token\n // rotations (its `token` is a getter over a ref — see useAthenaConfigValue),\n // so this object is stable too. The mention store lists `accessToken` among\n // its memo dependencies, so it rebuilds (and refetches its lists) on the\n // composer's next render after a rotation; the getter is what hands the\n // rotated token to any fetch before that render. With neither token nor\n // API key the fetch rides the same-origin session cookie, as the SDK's\n // upload and thread REST calls do.\n const mentionAuth = useMemo<MentionAuthContext>(\n () => ({\n backendUrl: athenaConfig.backendUrl,\n appUrl: athenaConfig.appUrl,\n apiKey: athenaConfig.apiKey,\n credentials: 'include',\n get accessToken() {\n return athenaConfig.token ?? undefined;\n },\n }),\n [athenaConfig],\n );\n const providerMentionTools = useMemo<MentionTool[]>(() => {\n const uniqueToolkitIds = Array.from(new Set(athenaConfig.enabledToolkits));\n\n return uniqueToolkitIds.map((id) => {\n const toolkit = getToolkitDisplayInfo(id);\n\n return {\n id: toolkit.id,\n name: toolkit.name,\n description: toolkit.description,\n icon: toolkit.icon,\n type: 'toolkit',\n };\n });\n }, [athenaConfig.enabledToolkits]);\n const tools = mentionTools ?? providerMentionTools;\n const mergedToolUIs = useMemo(\n () => ({\n append_markdown_to_athena_document: AppendDocumentToolUI,\n read_full_asset: ReadAssetToolUI,\n read_asset: ReadAssetToolUI,\n ...TOOL_UI_REGISTRY,\n ...toolUIs,\n }),\n [toolUIs],\n );\n\n const textComponent = components?.messageParts?.Text ?? TiptapText;\n const reasoningComponent = components?.messageParts?.Reasoning;\n const emptyComponent = components?.messageParts?.Empty ?? AthenaAssistantMessageEmpty;\n const actionBarComponent = components?.AssistantActionBar ?? AthenaAssistantActionBar;\n\n const defaultComponentsContextValue = useMemo<AthenaChatDefaultComponentsContextValue>(\n () => ({\n toolUIs: mergedToolUIs,\n TextComponent: textComponent,\n ReasoningComponent: reasoningComponent,\n EmptyComponent: emptyComponent,\n ActionBarComponent: actionBarComponent,\n groupToolCalls,\n }),\n [actionBarComponent, emptyComponent, groupToolCalls, mergedToolUIs, reasoningComponent, textComponent],\n );\n const AssistantMessageComponent = components?.AssistantMessage ?? AthenaDefaultAssistantMessage;\n const UserMessageComponent = components?.UserMessage ?? AthenaDefaultUserMessage;\n const messageComponents = useMemo(\n () => ({\n UserMessage: UserMessageComponent,\n AssistantMessage: AssistantMessageComponent,\n }),\n [AssistantMessageComponent, UserMessageComponent],\n );\n\n return (\n <AthenaChatDefaultComponentsContext.Provider value={defaultComponentsContextValue}>\n {/* Contain render crashes to the chat pane (telemetry + retry) instead of\n unmounting the integrator's subtree. */}\n <AthenaChatErrorBoundary>\n <ChatThreadShell\n overlay={<ThreadLoadingOverlay />}\n panelClassName={cn(\n 'aui-root aui-thread-root @container relative flex h-full flex-col bg-background',\n className,\n )}\n maxWidth={maxWidth}\n turnAnchor={turnAnchor}\n viewportClassName=\"aui-thread-viewport relative flex flex-1 flex-col overflow-x-auto overflow-y-scroll scroll-smooth px-4 pt-4\"\n contentClassName=\"flex w-full flex-1 flex-col\"\n viewportOverlay={<ThreadScrollToTop />}\n welcome={\n <AthenaChatWelcome\n welcomeMessage={welcomeMessage}\n welcomeSubtext={welcomeSubtext}\n welcomeSuggestions={welcomeSuggestions}\n />\n }\n beforeMessages={<StatewireHistoryEdge className=\"aui-thread-history-edge\" />}\n components={messageComponents}\n runningIndicator={null}\n scrollToBottom={<ThreadScrollToBottom />}\n viewportFooterClassName=\"aui-thread-viewport-footer sticky bottom-0 mx-auto mt-auto flex w-full max-w-(--thread-max-width) flex-col gap-4 overflow-visible rounded-t-3xl bg-background pb-4 md:pb-6\"\n viewportFooter={\n <>\n <StatewireConnectionBanner />\n <StatewireErrorBanner />\n <StatewireApprovalCard />\n <StatewireQueuedMessages />\n <AttachmentProvider>\n <QuoteProvider>\n <QuotePostMessageBridge />\n <MentionAuthCtx.Provider value={mentionAuth}>\n <AthenaChatComposer tools={tools} />\n </MentionAuthCtx.Provider>\n </QuoteProvider>\n </AttachmentProvider>\n </>\n }\n />\n </AthenaChatErrorBoundary>\n </AthenaChatDefaultComponentsContext.Provider>\n );\n};\n\nconst ThreadLoadingOverlay: FC = () => {\n const remoteId = useAthenaThreadId();\n const [timedOut, setTimedOut] = useState(false);\n\n useEffect(() => {\n if (!remoteId) return;\n setTimedOut(false);\n const timer = setTimeout(() => setTimedOut(true), 15000);\n return () => clearTimeout(timer);\n }, [remoteId]);\n\n if (!remoteId || timedOut) return null;\n\n return (\n <AuiIf condition={(s) => s.thread.isEmpty}>\n <div className=\"absolute inset-0 z-10 flex items-center justify-center bg-background/80\">\n <div className=\"size-5 animate-spin rounded-full border-2 border-muted-foreground border-t-transparent\" />\n </div>\n </AuiIf>\n );\n};\n\nconst THREAD_VIEWPORT_ATTR = 'data-aui-thread-viewport';\n\nconst useScrollToTop = () => {\n const [isAtTop, setIsAtTop] = useState(true);\n const [buttonEl, setButtonEl] = useState<HTMLButtonElement | null>(null);\n\n const containerRef = useCallback((node: HTMLButtonElement | null) => {\n setButtonEl(node);\n }, []);\n\n const getViewport = useCallback((): HTMLElement | null => {\n if (!buttonEl) return null;\n return buttonEl.closest(`[${THREAD_VIEWPORT_ATTR}]`) as HTMLElement | null;\n }, [buttonEl]);\n\n useEffect(() => {\n const viewport: HTMLElement | null = getViewport();\n if (!viewport) return;\n\n const handleScroll = () => {\n setIsAtTop(viewport.scrollTop <= 50);\n };\n\n handleScroll();\n viewport.addEventListener('scroll', handleScroll, { passive: true });\n return () => viewport.removeEventListener('scroll', handleScroll);\n }, [getViewport]);\n\n const handleClick = useCallback(() => {\n const viewport: HTMLElement | null = getViewport();\n if (!viewport) return;\n viewport.scrollTo({ top: 0, behavior: 'smooth' });\n }, [getViewport]);\n\n return { isAtTop, containerRef, handleClick };\n};\n\nconst ThreadScrollToTop: FC = () => {\n const { isAtTop, containerRef, handleClick } = useScrollToTop();\n const isEmpty = useAuiState((s) => s.thread.isEmpty);\n\n if (isEmpty) return null;\n\n return (\n <div className=\"sticky top-0 z-10 mx-auto flex h-0 w-full max-w-(--thread-max-width) justify-center\">\n <TooltipIconButton\n ref={containerRef}\n tooltip=\"Scroll to top\"\n variant=\"outline\"\n className={cn('aui-thread-scroll-to-top absolute top-2 rounded-full p-4 dark:bg-background dark:hover:bg-accent', isAtTop && 'invisible')}\n onClick={handleClick}\n >\n <ArrowUpIcon />\n </TooltipIconButton>\n </div>\n );\n};\n\nconst ThreadScrollToBottom: FC = () => (\n <ThreadPrimitive.ScrollToBottom asChild>\n <TooltipIconButton\n tooltip=\"Scroll to bottom\"\n variant=\"outline\"\n className=\"aui-thread-scroll-to-bottom absolute -top-12 z-10 self-center rounded-full p-4 disabled:invisible dark:bg-background dark:hover:bg-accent\"\n >\n <ArrowDownIcon />\n </TooltipIconButton>\n </ThreadPrimitive.ScrollToBottom>\n);\n\nconst AthenaComposerSendButton: FC<ComposerSendButtonProps> = ({\n action,\n onSend,\n disabled,\n title,\n}) => {\n const label = action === 'queue' ? 'Queue message' : 'Send message';\n return (\n <TooltipIconButton\n tooltip={title ?? label}\n side=\"bottom\"\n type=\"button\"\n variant=\"default\"\n size=\"icon\"\n className=\"aui-composer-send size-8 rounded-full\"\n aria-label={label}\n onClick={onSend}\n disabled={disabled}\n >\n {action === 'queue' ? (\n <ListPlusIcon className=\"aui-composer-send-icon size-4\" />\n ) : (\n <ArrowUpIcon className=\"aui-composer-send-icon size-4\" />\n )}\n </TooltipIconButton>\n );\n};\n\nconst AthenaComposerStopButton: FC<ComposerStopButtonProps> = ({ onStop, disabled, title }) => (\n <Button\n type=\"button\"\n variant=\"default\"\n size=\"icon\"\n className=\"aui-composer-cancel size-8 rounded-full\"\n aria-label=\"Stop generating\"\n title={title}\n onClick={onStop}\n disabled={disabled}\n >\n <SquareIcon className=\"aui-composer-cancel-icon size-3 fill-current\" />\n </Button>\n);\n\nconst ATHENA_COMPOSER_COMPONENTS = {\n SendButton: AthenaComposerSendButton,\n StopButton: AthenaComposerStopButton,\n};\n\n/**\n * The asset-library categories of AthenaChat's `@` menu. Browse profiles,\n * team and drives are left out: they need browser-side scoping or a workspace\n * id that API-key auth does not carry. The Tools / Toolkits categories are\n * added when the host (or the provider's enabled toolkits) offers any.\n */\nconst ATHENA_CHAT_MENTION_CATEGORIES: readonly MentionRootCategory[] = [\n 'favorites',\n 'assets',\n 'projects',\n 'folders',\n];\n\n/**\n * AthenaChat's composer: the shared chat-ui Tiptap editor and `@` mention menu\n * with AthenaChat's quote and attachment pills composed into the send.\n *\n * A draft with a quote or attachment pills — text or not — is intercepted on\n * submit and dispatched as one composed message through the composer runtime,\n * the path the server-owned queue observes, so a mid-run submit queues like\n * any other send. Pasted images upload into the pills through the same intake\n * as the paperclip and the drop zone, and every submit path (Enter, the send\n * button) waits for an in-flight upload so a send never leaves without its\n * attachment. The send control resolves send / queue / stop through the\n * shared chat-ui logic.\n */\nconst AthenaChatComposer: FC<{ tools: MentionTool[] }> = ({ tools }) => {\n const aui = useAui();\n const threadId = useAthenaStatewireThreadId();\n const { appUrl } = useAthenaConfig();\n const { attachments, clearAttachments, isUploading } = useAttachments();\n const { quote, clearQuote } = useQuote();\n const { attachFiles } = useAttachFiles();\n const composerRef = useRef<TiptapComposerHandle>(null);\n const [hasText, setHasText] = useState(false);\n\n const rootCategories = useMemo<readonly MentionRootCategory[]>(() => {\n const categories = [...ATHENA_CHAT_MENTION_CATEGORIES];\n if (tools.some((tool) => tool.type === 'toolkit')) categories.push('toolkits');\n if (tools.some((tool) => tool.type === 'tool')) categories.push('tools');\n return categories;\n }, [tools]);\n\n // The submit paths are captured once by the editor's keybinding, so they\n // read the current draft extras through refs.\n const attachmentsRef = useRef(attachments);\n attachmentsRef.current = attachments;\n const quoteRef = useRef(quote);\n quoteRef.current = quote;\n const hasExtras = attachments.length > 0 || quote !== null;\n\n // A submit during an upload parks until the pills have the asset; the\n // waiters resolve on the render that turns `isUploading` off, by which\n // point `attachmentsRef` holds the uploaded asset.\n const isUploadingRef = useRef(isUploading);\n isUploadingRef.current = isUploading;\n const uploadWaitersRef = useRef<Array<() => void>>([]);\n useEffect(() => {\n if (isUploading) return;\n const waiters = uploadWaitersRef.current;\n uploadWaitersRef.current = [];\n for (const resolve of waiters) resolve();\n }, [isUploading]);\n const waitForHostUploads = useCallback(() => {\n if (!isUploadingRef.current) return;\n return new Promise<void>((resolve) => {\n uploadWaitersRef.current.push(resolve);\n });\n }, []);\n\n const sendComposed = useCallback(\n (userText: string): boolean => {\n const message = buildComposedMessage({\n attachments: attachmentsRef.current,\n quote: quoteRef.current,\n userText,\n appUrl,\n });\n if (!message) return false;\n // steer: false — a mid-run send queues behind the active run instead of\n // interrupting it; idle sends dispatch immediately.\n aui.composer.setText(message);\n aui.composer.send({ steer: false });\n clearAttachments();\n clearQuote();\n return true;\n },\n [appUrl, aui, clearAttachments, clearQuote],\n );\n\n // Consumes the editor's draft (possibly empty) only when there are extras\n // to compose with it.\n const interceptSubmit = useCallback(\n (text: string) =>\n attachmentsRef.current.length > 0 || quoteRef.current !== null\n ? sendComposed(text)\n : false,\n [sendComposed],\n );\n\n // Pasted images go through the pills' intake; drops are left to the\n // enclosing ComposerDropZone.\n const fileIntake = useMemo<ComposerFileIntake>(\n () => ({\n onPaste: (files) => {\n void attachFiles(files, 'paste');\n },\n }),\n [attachFiles],\n );\n\n return (\n <ComposerDropZone>\n <ChatComposerDock\n className=\"\"\n surfaceClassName=\"aui-composer-root relative flex w-full flex-col rounded-2xl border border-input bg-background px-1 pt-2 outline-none transition-shadow focus-within:border-ring focus-within:ring-2 focus-within:ring-ring/20\"\n editorRowClassName=\"px-2.5\"\n toolbarClassName=\"aui-composer-action-wrapper relative mx-2 mb-2 flex items-center\"\n beforeEditor={\n <>\n <ComposerQuotePreview />\n <ComposerAttachmentPreview />\n </>\n }\n editor={\n <TiptapComposer\n ref={composerRef}\n threadId={threadId}\n placeholder=\"Send a message...\"\n tools={tools}\n rootCategories={rootCategories}\n onDraftStateChange={setHasText}\n waitForHostUploads={waitForHostUploads}\n interceptSubmit={interceptSubmit}\n fileIntake={fileIntake}\n />\n }\n toolbarStart={\n <div className=\"flex items-center gap-1\">\n <FileUploadButton />\n </div>\n }\n toolbarEnd={\n <div className=\"flex items-center gap-1\">\n <ComposerSendOrStop\n composerRef={composerRef}\n hasDraft={hasText || hasExtras}\n sendBlockedReason={isUploading ? 'Upload in progress...' : null}\n components={ATHENA_COMPOSER_COMPONENTS}\n />\n </div>\n }\n />\n </ComposerDropZone>\n );\n};\n\nconst MessageError: FC = () => (\n <MessagePrimitive.Error>\n <ErrorPrimitive.Root className=\"aui-message-error-root mt-2 flex items-start gap-2 rounded-md border border-destructive bg-destructive/10 p-3 text-destructive text-sm dark:bg-destructive/5 dark:text-red-200\">\n <AlertCircleIcon className=\"mt-0.5 size-4 shrink-0\" />\n <ErrorPrimitive.Message className=\"aui-message-error-message grow\" />\n <ActionBarPrimitive.Reload asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-6 shrink-0 text-destructive hover:text-destructive dark:text-red-200 dark:hover:text-red-100\"\n >\n <RefreshCwIcon className=\"size-3.5\" />\n </Button>\n </ActionBarPrimitive.Reload>\n </ErrorPrimitive.Root>\n </MessagePrimitive.Error>\n);\n\nconst AthenaAssistantMessageEmpty: EmptyMessagePartComponent = ({ status }) => {\n if (status?.type !== 'running') return null;\n return (\n <span className=\"shimmer text-[13px] text-muted-foreground\">Thinking...</span>\n );\n};\n\n/**\n * Renders the empty/loading indicator while a message is running but has no\n * parts yet. `MessagePrimitive.GroupedParts` only renders existing parts, so\n * the indicator can't live inside its switch — it goes here as a sibling.\n */\nconst AthenaMessageEmptyIndicator: FC<{ EmptyComponent: EmptyMessagePartComponent }> = ({\n EmptyComponent,\n}) => {\n const hasParts = useAuiState((s) => s.message.parts.length > 0);\n const isRunning = useAuiState((s) => s.message.status?.type === 'running');\n if (hasParts || !isRunning) return null;\n return <EmptyComponent status={{ type: 'running' }} />;\n};\n\n/**\n * Run-liveness row under a running message whose tail is a tool call.\n *\n * Answers \"is anything still happening?\" once parts exist: pulsing dots plus\n * an elapsed counter that resets whenever the stream moves the tail part, and\n * a stall tone once nothing has streamed for a while — so a busy run and a\n * possibly-stuck one stop looking identical. Text/reasoning tails animate on\n * their own and render no row.\n */\nconst AthenaMessageActivityIndicator: FC = () => {\n const isRunning = useAuiState((s) => s.message.status?.type === 'running');\n const activityKey = useAuiState((s) => runActivityKey(s.message.parts));\n const [seconds, setSeconds] = useState(0);\n useEffect(() => {\n setSeconds(0);\n if (!isRunning || activityKey === null) return;\n const startedAt = Date.now();\n const timer = setInterval(() => {\n setSeconds(Math.floor((Date.now() - startedAt) / 1000));\n }, 1000);\n return () => clearInterval(timer);\n }, [isRunning, activityKey]);\n if (!isRunning || activityKey === null) return null;\n const stalled = seconds >= RUN_ACTIVITY_STALL_SECONDS;\n return (\n <div className=\"aui-run-activity mt-2 flex items-center gap-2 px-1 text-[12px] text-muted-foreground\">\n <span className=\"flex items-center gap-1\" aria-hidden>\n <span className=\"size-1.5 animate-bounce rounded-full bg-current [animation-delay:0ms]\" />\n <span className=\"size-1.5 animate-bounce rounded-full bg-current [animation-delay:150ms]\" />\n <span className=\"size-1.5 animate-bounce rounded-full bg-current [animation-delay:300ms]\" />\n </span>\n <span aria-hidden className={stalled ? 'text-amber-600 dark:text-amber-400' : undefined}>\n {runActivityLabel(seconds)}\n </span>\n {/* The visible counter ticks every second; announcing each tick would\n drown a screen reader, so the live region only speaks the two\n meaningful transitions: work started, and work looks stalled. */}\n <span aria-live=\"polite\" className=\"sr-only\">\n {stalled\n ? 'Assistant is still working; nothing new for over thirty seconds.'\n : 'Assistant is working.'}\n </span>\n </div>\n );\n};\n\nexport const AthenaReasoningPart: FC<AthenaReasoningPartProps> = ({\n text,\n status,\n TextComponent,\n}) => {\n const inheritedTextComponent = useContext(AthenaReasoningTextComponentContext);\n const EffectiveTextComponent = TextComponent ?? inheritedTextComponent ?? TiptapText;\n const isMessageRunning = useAuiState((state) => state.message.status?.type === 'running');\n const reasoningTokens = useAuiState((state) =>\n getReasoningTokensFromMetadata(state.message.metadata)\n );\n const isRunning = isMessageRunning || status?.type === 'running';\n const [isCollapsed, setIsCollapsed] = useState(!isRunning);\n const userOverrodeOpenStateRef = useRef(false);\n const hasText = text.trim().length > 0;\n\n const reasoningTextProps: TextMessagePartProps = {\n type: 'text',\n text,\n status: isRunning\n ? ({ type: 'running' } as TextMessagePartProps['status'])\n : (status as TextMessagePartProps['status']),\n };\n\n useEffect(() => {\n if (userOverrodeOpenStateRef.current) {\n return;\n }\n\n setIsCollapsed(!isRunning);\n }, [isRunning]);\n\n if (!hasText && !isRunning) {\n return null;\n }\n\n return (\n <Collapsible\n open={!isCollapsed}\n onOpenChange={(open) => {\n userOverrodeOpenStateRef.current = true;\n setIsCollapsed(!open);\n }}\n className=\"aui-assistant-reasoning-root mb-3 rounded-2xl border border-border/60 bg-muted/30 px-3 py-2\"\n >\n <CollapsibleTrigger asChild>\n <button\n type=\"button\"\n className=\"flex w-full items-center justify-between gap-3 text-left\"\n aria-label={isRunning ? 'Toggle reasoning while streaming' : 'Toggle reasoning'}\n >\n <span className=\"flex min-w-0 items-center gap-2 text-[13px] font-medium text-muted-foreground\">\n <BrainIcon className=\"size-4 shrink-0\" />\n <span>{isRunning ? 'Reasoning...' : 'Reasoning'}</span>\n </span>\n <span className=\"flex shrink-0 items-center gap-2\">\n {reasoningTokens !== undefined && (\n <span className=\"rounded-full border border-border/60 bg-background px-2 py-0.5 text-[11px] font-medium text-muted-foreground\">\n {formatReasoningTokens(reasoningTokens)}\n </span>\n )}\n <span\n className={cn(\n 'flex size-5 items-center justify-center text-muted-foreground transition-transform',\n isCollapsed ? 'rotate-0' : 'rotate-90'\n )}\n aria-hidden=\"true\"\n >\n <ChevronRightIcon className=\"size-4\" />\n </span>\n </span>\n </button>\n </CollapsibleTrigger>\n\n <CollapsibleContent className=\"pt-3\">\n {isRunning && !hasText ? (\n <span className=\"shimmer text-[13px] text-muted-foreground\">Analyzing...</span>\n ) : (\n <div className=\"aui-assistant-reasoning-body text-[13px] leading-relaxed\">\n <EffectiveTextComponent {...reasoningTextProps} />\n </div>\n )}\n </CollapsibleContent>\n </Collapsible>\n );\n};\n\nconst groupAdjacentToolCalls = (part: PartState) =>\n part.type === 'tool-call' ? (['group-tool'] as const) : null;\nconst noToolGrouping = () => null;\n\nexport const AthenaAssistantMessage: FC<AthenaAssistantMessageProps> = ({\n toolUIs,\n TextComponent = TiptapText,\n ReasoningComponent,\n EmptyComponent = AthenaAssistantMessageEmpty,\n ActionBarComponent = AthenaAssistantActionBar,\n groupToolCalls = false,\n}) => {\n const effectiveReasoningComponent = ReasoningComponent ?? AthenaReasoningPart;\n const toolUIsWithNestedMessages = useMemo(() => {\n const wrappedToolUIs: Record<string, ToolCallMessagePartComponent> = {};\n\n for (const [toolName, ToolUI] of Object.entries(toolUIs)) {\n wrappedToolUIs[toolName] = withNestedPtcMessages(ToolUI);\n }\n\n return wrappedToolUIs;\n }, [toolUIs]);\n\n // NestedPtcComponentsProvider still consumes the legacy parts-config shape\n // (Text / Reasoning / tools.by_name / Empty) to render PTC sub-tool messages\n // inside a tool card. The outer rendering uses GroupedParts, but the inner\n // PTC tree continues to mirror the parent registry.\n const nestedPtcComponents = useMemo(\n () => ({\n Text: TextComponent,\n Reasoning: effectiveReasoningComponent,\n tools: {\n Fallback: ToolFallback,\n by_name: toolUIsWithNestedMessages,\n },\n Empty: EmptyComponent,\n }),\n [EmptyComponent, TextComponent, effectiveReasoningComponent, toolUIsWithNestedMessages],\n );\n\n return (\n <MessagePrimitive.Root\n className=\"aui-assistant-message-root fade-in slide-in-from-bottom-1 relative mx-auto w-full max-w-(--thread-max-width) animate-in py-3 duration-150\"\n data-role=\"assistant\"\n >\n <AthenaReasoningTextComponentContext.Provider value={TextComponent}>\n <div className=\"aui-assistant-message-content wrap-break-word px-2 text-foreground leading-relaxed\">\n <NestedPtcComponentsProvider components={nestedPtcComponents}>\n {groupToolCalls ? (\n <div className=\"flex flex-col space-y-2\">\n <SuperGroupingCard\n toolUIs={toolUIsWithNestedMessages}\n TextComponent={TextComponent}\n ReasoningComponent={effectiveReasoningComponent}\n />\n <SuperGroupingFinalText TextComponent={TextComponent} />\n <AthenaMessageActivityIndicator />\n </div>\n ) : (\n <>\n <AthenaMessageEmptyIndicator EmptyComponent={EmptyComponent} />\n <MessagePrimitive.GroupedParts groupBy={noToolGrouping}>\n {({ part }) => {\n switch (part.type) {\n case 'tool-call': {\n const ToolUI = toolUIsWithNestedMessages[part.toolName];\n const toolProps = part as unknown as ToolCallMessagePartProps;\n return ToolUI ? <ToolUI {...toolProps} /> : <ToolFallback {...toolProps} />;\n }\n case 'reasoning': {\n const ReasoningRenderer = effectiveReasoningComponent;\n return <ReasoningRenderer {...(part as ReasoningMessagePartProps)} />;\n }\n case 'text': {\n const textPart = part as TextMessagePartProps;\n if (textPart.text === '' && textPart.status?.type === 'running') {\n return <EmptyComponent status={textPart.status} />;\n }\n return <TextComponent {...textPart} />;\n }\n default:\n return null;\n }\n }}\n </MessagePrimitive.GroupedParts>\n <AthenaMessageActivityIndicator />\n </>\n )}\n </NestedPtcComponentsProvider>\n <MessageError />\n </div>\n </AthenaReasoningTextComponentContext.Provider>\n <div className=\"aui-assistant-message-footer mt-1 ml-2 flex\">\n <ActionBarComponent />\n </div>\n </MessagePrimitive.Root>\n );\n};\n\nconst AthenaToolGroup: FC<{ children: React.ReactNode; count: number }> = ({ children, count }) => {\n const [expanded, setExpanded] = useState(false);\n\n return (\n <div className=\"my-3 w-full overflow-hidden rounded-xl border border-border/60 bg-background shadow-sm\">\n <button\n type=\"button\"\n onClick={() => setExpanded((v) => !v)}\n className=\"flex w-full items-center gap-3 px-4 py-3 text-left transition-colors hover:bg-muted/20\"\n aria-expanded={expanded}\n >\n <div className=\"flex size-8 shrink-0 items-center justify-center rounded-lg bg-muted/60 text-muted-foreground\">\n <LayersIcon className=\"size-4\" />\n </div>\n <div className=\"min-w-0 flex-1\">\n <span className=\"text-[13px] font-medium text-foreground\">\n {count} tool {count === 1 ? 'call' : 'calls'}\n </span>\n </div>\n <ChevronDownIcon\n className={cn(\n 'size-4 shrink-0 text-muted-foreground transition-transform duration-200',\n !expanded && '-rotate-90',\n )}\n />\n </button>\n {expanded && (\n <div className=\"border-t border-border/40 bg-muted/5 px-3 pt-1 pb-2 [&>*]:my-2\">\n {children}\n </div>\n )}\n </div>\n );\n};\n\nexport const AthenaAssistantActionBar: FC<AthenaAssistantActionBarProps> = ({ className }) => {\n const threadId = useAthenaThreadId();\n const { appUrl } = useAthenaConfig();\n\n return (\n <ActionBarPrimitive.Root\n hideWhenRunning\n autohide=\"not-last\"\n className={cn('aui-assistant-action-bar-root -ml-1 flex gap-1 text-muted-foreground', className)}\n >\n <ActionBarPrimitive.Copy asChild>\n <TooltipIconButton tooltip=\"Copy\">\n <AuiIf condition={(s) => s.message.isCopied}>\n <CheckIcon />\n </AuiIf>\n <AuiIf condition={(s) => !s.message.isCopied}>\n <CopyIcon />\n </AuiIf>\n </TooltipIconButton>\n </ActionBarPrimitive.Copy>\n <ActionBarMorePrimitive.Root>\n <ActionBarMorePrimitive.Trigger asChild>\n <TooltipIconButton tooltip=\"More\" className=\"data-[state=open]:bg-accent\">\n <MoreHorizontalIcon />\n </TooltipIconButton>\n </ActionBarMorePrimitive.Trigger>\n <ActionBarMorePrimitive.Content\n side=\"bottom\"\n align=\"start\"\n className=\"aui-action-bar-more-content z-50 min-w-32 overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md\"\n >\n <ActionBarPrimitive.ExportMarkdown asChild>\n <ActionBarMorePrimitive.Item className=\"aui-action-bar-more-item flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground\">\n <DownloadIcon className=\"size-4\" />\n Export as Markdown\n </ActionBarMorePrimitive.Item>\n </ActionBarPrimitive.ExportMarkdown>\n {threadId && (\n <ActionBarMorePrimitive.Item\n className=\"aui-action-bar-more-item flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground\"\n onClick={() => {\n window.open(createAthenaSpacesUrl({ appUrl, sessionId: threadId }), '_blank');\n }}\n >\n <ExternalLinkIcon className=\"size-4\" />\n Open in Athena\n </ActionBarMorePrimitive.Item>\n )}\n </ActionBarMorePrimitive.Content>\n </ActionBarMorePrimitive.Root>\n </ActionBarPrimitive.Root>\n );\n};\n\nexport const AthenaUserMessage: FC<AthenaUserMessageProps> = ({\n TextComponent = TiptapText,\n}) => (\n <MessagePrimitive.Root\n className=\"aui-user-message-root fade-in slide-in-from-bottom-1 mx-auto flex w-full max-w-(--thread-max-width) animate-in justify-end px-2 py-3 duration-150\"\n data-role=\"user\"\n >\n <div className=\"aui-user-message-content wrap-break-word rounded-2xl bg-muted px-4 py-2.5 text-foreground\">\n <MessagePrimitive.Parts components={{ Text: TextComponent }} />\n </div>\n </MessagePrimitive.Root>\n);\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"AthenaChat.js","sources":["../../src/chat/AthenaChat.tsx"],"sourcesContent":["import { TiptapText } from './tiptap-text';\nimport { AthenaChatErrorBoundary } from './AthenaChatErrorBoundary';\nimport { StatewireApprovalCard } from './StatewireApprovalCard';\nimport { StatewireQueuedMessages } from './StatewireQueuedMessages';\nimport { StatewireConnectionBanner, StatewireErrorBanner } from './statewire-banners';\nimport { ToolFallback } from '../tools/tool-fallback';\nimport { AppendDocumentToolUI } from '../tools/append-document-tool-ui';\nimport { ReadAssetToolUI } from '../tools/read-asset-tool-ui';\nimport { TOOL_UI_REGISTRY } from '../tools/tool-uis';\nimport { SuperGroupingCard, SuperGroupingFinalText } from './super-grouping/SuperGroupingCard';\nimport {\n NestedPtcComponentsProvider,\n NestedPtcMessages,\n useNestedPtcComponents,\n} from '../tools/NestedPtcMessages';\nimport { TooltipIconButton } from './tooltip-icon-button';\nimport { Button } from '../ui/button';\nimport { Collapsible, CollapsibleContent, CollapsibleTrigger } from '../ui/collapsible';\nimport { ChatComposerDock } from '../chat-ui/thread/chat-composer-dock';\nimport { ChatThreadShell } from '../chat-ui/thread/chat-thread-shell';\nimport { StatewireHistoryEdge } from '../chat-ui/thread/statewire-history-edge';\nimport { ComposerSendOrStop } from '../chat-ui/thread/composer-send-or-stop';\nimport {\n TiptapComposer,\n type ComposerFileIntake,\n type TiptapComposerHandle,\n} from '../chat-ui/composer/tiptap-composer';\nimport {\n MentionAuthCtx,\n type MentionAuthContext,\n} from '../chat-ui/mentions/suggestions/data/api-client';\nimport type { MentionRootCategory } from '../chat-ui/mentions/suggestions/data/use-mention-suggestions';\nimport type { MentionTool } from '../chat-ui/mentions/suggestions/data/types';\nimport {\n ACTION_BAR_REVEAL_CLASS,\n type ComposerSendButtonProps,\n type ComposerStopButtonProps,\n} from '../chat-ui/messages/message-components';\nimport {\n ActionBarMorePrimitive,\n ActionBarPrimitive,\n AuiIf,\n ErrorPrimitive,\n MessagePrimitive,\n ThreadPrimitive,\n useAui,\n useAuiState,\n} from '@assistant-ui/react';\nimport type {\n EmptyMessagePartComponent,\n PartState,\n ReasoningMessagePartProps,\n ReasoningMessagePartComponent,\n TextMessagePartProps,\n TextMessagePartComponent,\n ToolCallMessagePartComponent,\n ToolCallMessagePartProps,\n} from '@assistant-ui/react';\nimport {\n AlertCircleIcon,\n ArrowDownIcon,\n ArrowUpIcon,\n ArrowRightIcon,\n BrainIcon,\n CheckIcon,\n ChevronDownIcon,\n ChevronRightIcon,\n CopyIcon,\n DownloadIcon,\n ExternalLinkIcon,\n LayersIcon,\n ListPlusIcon,\n MoreHorizontalIcon,\n RefreshCwIcon,\n SquareIcon,\n SearchIcon,\n FileTextIcon,\n PresentationIcon,\n} from 'lucide-react';\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type FC,\n} from 'react';\nimport { useAthenaStatewireThreadId, useAthenaThreadId } from '../threads/thread-id-context';\nimport { FileUploadButton } from '../composer/FileUploadButton';\nimport { ComposerQuotePreview } from '../composer/ComposerQuotePreview';\nimport { ComposerAttachmentPreview } from '../composer/ComposerAttachmentPreview';\nimport { ComposerDropZone } from '../composer/ComposerDropZone';\nimport { useQuote, QuoteProvider, useQuoteFromPostMessage } from '../composer/QuoteContext';\nimport { AttachmentProvider, useAttachments } from '../composer/AttachmentContext';\nimport { buildComposedMessage } from '../composer/build-composed-message';\nimport { useAttachFiles } from '../composer/useAttachFiles';\nimport { useAthenaConfig } from '../provider/AthenaContext';\nimport { createAthenaSpacesUrl } from '../lib/athena-urls';\nimport { cn, isRecord } from '../lib/utils';\nimport { useSendMessage } from '../composer/useSendMessage';\nimport { getToolkitDisplayInfo } from '../toolkits';\nimport {\n RUN_ACTIVITY_STALL_SECONDS,\n runActivityKey,\n runActivityLabel,\n} from './run-activity';\n\nfunction QuotePostMessageBridge() {\n useQuoteFromPostMessage();\n return null;\n}\n\nexport interface WelcomeSuggestion {\n icon: React.ElementType;\n title: string;\n prompt: string;\n}\n\nconst DEFAULT_SUGGESTIONS: WelcomeSuggestion[] = [\n {\n icon: SearchIcon,\n title: \"Research a topic and draft a report\",\n prompt: \"Search the web for the latest developments in enterprise AI adoption, then create a document summarizing the key trends, market data, and strategic implications.\",\n },\n {\n icon: SearchIcon,\n title: \"Compare recent AI model launches\",\n prompt: \"Search the web for the latest major AI model launches from OpenAI, Anthropic, and Google, then summarize the release dates, standout capabilities, and practical tradeoffs in a concise comparison table.\",\n },\n {\n icon: PresentationIcon,\n title: \"Build a presentation from scratch\",\n prompt: \"Create a 5-slide investor update presentation covering market opportunity, product traction, key metrics, competitive positioning, and next steps.\",\n },\n {\n icon: FileTextIcon,\n title: \"Set up a structured spreadsheet\",\n prompt: \"Create a project tracking spreadsheet with columns for task name, owner, priority, status, start date, due date, and completion percentage.\",\n },\n];\n\nexport interface AthenaChatProps {\n /** CSS class name for the root element. */\n className?: string;\n /** Welcome heading text. Defaults to \"Hello there!\" */\n welcomeMessage?: string;\n /** Welcome subheading text. */\n welcomeSubtext?: string;\n /** Maximum width for the thread content. Defaults to \"44rem\". */\n maxWidth?: string;\n /**\n * Scroll anchoring for new turns. \"bottom\" (default) keeps the viewport\n * pinned to the end while the assistant streams — classic chat follow.\n * \"top\" pins the just-sent user message to the top of the viewport and\n * intentionally does NOT follow the streaming response (assistant-ui\n * disables autoScroll in that mode), so readers scroll at their own pace.\n */\n turnAnchor?: \"top\" | \"bottom\";\n /** Additional tool UIs to register by name. */\n toolUIs?: Record<string, ToolCallMessagePartComponent>;\n /** Tools / Toolkits offered by the composer's `@` menu beside the asset\n * library. Defaults to the toolkits enabled on the provider. */\n mentionTools?: MentionTool[];\n /** Suggestion cards shown on the welcome screen. Pass `[]` to hide.\n * For workflow launchers outside AthenaChat, use `useSendMessage()`.\n */\n welcomeSuggestions?: WelcomeSuggestion[];\n /** Optional component overrides for message containers and key message parts. */\n components?: AthenaChatComponents;\n /** Collapse adjacent tool calls into a single expandable group. Defaults to `false`. */\n groupToolCalls?: boolean;\n}\n\nexport interface AthenaChatMessagePartComponents {\n Text?: TextMessagePartComponent;\n Reasoning?: ReasoningMessagePartComponent;\n Empty?: EmptyMessagePartComponent;\n}\n\nexport interface AthenaChatComponents {\n UserMessage?: FC;\n AssistantMessage?: FC;\n AssistantActionBar?: FC<AthenaAssistantActionBarProps>;\n messageParts?: AthenaChatMessagePartComponents;\n}\n\nexport interface AthenaUserMessageProps {\n TextComponent?: TextMessagePartComponent;\n}\n\nexport interface AthenaAssistantActionBarProps {\n className?: string;\n}\n\nexport interface AthenaAssistantMessageProps {\n toolUIs: Record<string, ToolCallMessagePartComponent>;\n TextComponent?: TextMessagePartComponent;\n ReasoningComponent?: ReasoningMessagePartComponent;\n EmptyComponent?: EmptyMessagePartComponent;\n ActionBarComponent?: FC<AthenaAssistantActionBarProps>;\n /** Collapse adjacent tool calls into a single expandable group. Defaults to `false`. */\n groupToolCalls?: boolean;\n}\n\nexport interface AthenaReasoningPartProps extends ReasoningMessagePartProps {\n TextComponent?: TextMessagePartComponent;\n}\n\ninterface AthenaChatDefaultComponentsContextValue {\n toolUIs: Record<string, ToolCallMessagePartComponent>;\n TextComponent: TextMessagePartComponent;\n ReasoningComponent?: ReasoningMessagePartComponent;\n EmptyComponent: EmptyMessagePartComponent;\n ActionBarComponent: FC<AthenaAssistantActionBarProps>;\n groupToolCalls: boolean;\n}\n\nconst AthenaChatDefaultComponentsContext =\n createContext<AthenaChatDefaultComponentsContextValue | null>(null);\n\nconst AthenaReasoningTextComponentContext = createContext<TextMessagePartComponent | null>(null);\n\nconst useAthenaChatDefaultComponents = (): AthenaChatDefaultComponentsContextValue => {\n const value = useContext(AthenaChatDefaultComponentsContext);\n\n if (!value) {\n throw new Error('Athena default chat components must be used within AthenaChat.');\n }\n\n return value;\n};\n\nconst AthenaDefaultAssistantMessage: FC = () => {\n const { toolUIs, TextComponent, ReasoningComponent, EmptyComponent, ActionBarComponent, groupToolCalls } =\n useAthenaChatDefaultComponents();\n\n return (\n <AthenaAssistantMessage\n toolUIs={toolUIs}\n TextComponent={TextComponent}\n ReasoningComponent={ReasoningComponent}\n EmptyComponent={EmptyComponent}\n ActionBarComponent={ActionBarComponent}\n groupToolCalls={groupToolCalls}\n />\n );\n};\n\nconst AthenaDefaultUserMessage: FC = () => {\n const { TextComponent } = useAthenaChatDefaultComponents();\n\n return <AthenaUserMessage TextComponent={TextComponent} />;\n};\n\nconst getReasoningTokensFromMetadata = (metadata: unknown): number | undefined => {\n if (!isRecord(metadata)) {\n return undefined;\n }\n\n const customMetadata = metadata.custom;\n if (!isRecord(customMetadata)) {\n return undefined;\n }\n\n const athenaMetadata = customMetadata._athena;\n if (!isRecord(athenaMetadata)) {\n return undefined;\n }\n\n const reasoningTokens = athenaMetadata.reasoningTokens;\n return typeof reasoningTokens === 'number' && Number.isFinite(reasoningTokens)\n ? reasoningTokens\n : undefined;\n};\n\nconst formatReasoningTokens = (reasoningTokens: number) =>\n `${reasoningTokens.toLocaleString('en-US')} ${reasoningTokens === 1 ? 'token' : 'tokens'}`;\n\nconst withNestedPtcMessages = (\n ToolUI: ToolCallMessagePartComponent\n): ToolCallMessagePartComponent => {\n const ToolUIWithNestedPtcMessages: ToolCallMessagePartComponent = (props) => {\n const nestedComponents = useNestedPtcComponents(ToolFallback);\n\n return (\n <>\n <ToolUI {...props} />\n <NestedPtcMessages components={nestedComponents} />\n </>\n );\n };\n\n return ToolUIWithNestedPtcMessages;\n};\n\nconst SuggestionCard: FC<{ suggestion: WelcomeSuggestion; index: number }> = ({\n suggestion,\n index,\n}) => {\n const Icon = suggestion.icon;\n const sendMessage = useSendMessage();\n\n const handleClick = useCallback(() => {\n void sendMessage(suggestion.prompt);\n }, [sendMessage, suggestion.prompt]);\n\n return (\n <button\n type=\"button\"\n onClick={handleClick}\n className={`fade-in slide-in-from-bottom-2 animate-in fill-mode-both group flex items-start gap-3 rounded-xl border border-border/60 bg-background p-3.5 text-left shadow-sm transition-all duration-150 hover:border-border hover:bg-muted/40 hover:shadow-md`}\n style={{ animationDelay: `${100 + index * 75}ms` }}\n >\n <div className=\"flex size-8 shrink-0 items-center justify-center rounded-lg bg-muted/60 text-muted-foreground transition-colors group-hover:bg-primary/10 group-hover:text-primary\">\n <Icon className=\"size-4\" />\n </div>\n <div className=\"min-w-0 flex-1\">\n <span className=\"text-[13px] font-medium leading-snug text-foreground\">\n {suggestion.title}\n </span>\n </div>\n <ArrowRightIcon className=\"mt-0.5 size-3.5 shrink-0 text-muted-foreground/0 transition-all group-hover:text-muted-foreground\" />\n </button>\n );\n};\n\nconst AthenaChatWelcome: FC<{\n welcomeMessage: string;\n welcomeSubtext?: string;\n welcomeSuggestions: WelcomeSuggestion[];\n}> = ({ welcomeMessage, welcomeSubtext, welcomeSuggestions }) => (\n <div className=\"aui-thread-welcome-root mx-auto my-auto flex w-full max-w-(--thread-max-width) grow flex-col\">\n <div className=\"aui-thread-welcome-center flex w-full grow flex-col items-center justify-center\">\n <div className=\"aui-thread-welcome-message flex size-full flex-col justify-center px-4\">\n <h1 className=\"aui-thread-welcome-message-inner fade-in slide-in-from-bottom-1 animate-in fill-mode-both font-semibold text-2xl duration-200\">\n {welcomeMessage}\n </h1>\n {welcomeSubtext && (\n <p className=\"aui-thread-welcome-message-inner fade-in slide-in-from-bottom-1 animate-in fill-mode-both text-muted-foreground text-lg delay-75 duration-200\">\n {welcomeSubtext}\n </p>\n )}\n {welcomeSuggestions.length > 0 && (\n <div className=\"mt-6 grid grid-cols-1 gap-2.5 sm:grid-cols-2\">\n {welcomeSuggestions.map((s, i) => (\n <SuggestionCard key={s.title} suggestion={s} index={i} />\n ))}\n </div>\n )}\n </div>\n </div>\n </div>\n);\n\nexport const AthenaChat: FC<AthenaChatProps> = ({\n className,\n welcomeMessage = \"Hello there!\",\n welcomeSubtext = \"What can I help you with?\",\n maxWidth = \"44rem\",\n turnAnchor = \"bottom\",\n toolUIs,\n mentionTools,\n welcomeSuggestions = DEFAULT_SUGGESTIONS,\n components,\n groupToolCalls = false,\n}) => {\n const athenaConfig = useAthenaConfig();\n // The mention menu's GraphQL credentials: the backend and credential the\n // provider resolved. `athenaConfig` keeps its identity across token\n // rotations (its `token` is a getter over a ref — see useAthenaConfigValue),\n // so this object is stable too. The mention store lists `accessToken` among\n // its memo dependencies, so it rebuilds (and refetches its lists) on the\n // composer's next render after a rotation; the getter is what hands the\n // rotated token to any fetch before that render. With neither token nor\n // API key the fetch rides the same-origin session cookie, as the SDK's\n // upload and thread REST calls do.\n const mentionAuth = useMemo<MentionAuthContext>(\n () => ({\n backendUrl: athenaConfig.backendUrl,\n appUrl: athenaConfig.appUrl,\n apiKey: athenaConfig.apiKey,\n credentials: 'include',\n get accessToken() {\n return athenaConfig.token ?? undefined;\n },\n }),\n [athenaConfig],\n );\n const providerMentionTools = useMemo<MentionTool[]>(() => {\n const uniqueToolkitIds = Array.from(new Set(athenaConfig.enabledToolkits));\n\n return uniqueToolkitIds.map((id) => {\n const toolkit = getToolkitDisplayInfo(id);\n\n return {\n id: toolkit.id,\n name: toolkit.name,\n description: toolkit.description,\n icon: toolkit.icon,\n type: 'toolkit',\n };\n });\n }, [athenaConfig.enabledToolkits]);\n const tools = mentionTools ?? providerMentionTools;\n const mergedToolUIs = useMemo(\n () => ({\n append_markdown_to_athena_document: AppendDocumentToolUI,\n read_full_asset: ReadAssetToolUI,\n read_asset: ReadAssetToolUI,\n ...TOOL_UI_REGISTRY,\n ...toolUIs,\n }),\n [toolUIs],\n );\n\n const textComponent = components?.messageParts?.Text ?? TiptapText;\n const reasoningComponent = components?.messageParts?.Reasoning;\n const emptyComponent = components?.messageParts?.Empty ?? AthenaAssistantMessageEmpty;\n const actionBarComponent = components?.AssistantActionBar ?? AthenaAssistantActionBar;\n\n const defaultComponentsContextValue = useMemo<AthenaChatDefaultComponentsContextValue>(\n () => ({\n toolUIs: mergedToolUIs,\n TextComponent: textComponent,\n ReasoningComponent: reasoningComponent,\n EmptyComponent: emptyComponent,\n ActionBarComponent: actionBarComponent,\n groupToolCalls,\n }),\n [actionBarComponent, emptyComponent, groupToolCalls, mergedToolUIs, reasoningComponent, textComponent],\n );\n const AssistantMessageComponent = components?.AssistantMessage ?? AthenaDefaultAssistantMessage;\n const UserMessageComponent = components?.UserMessage ?? AthenaDefaultUserMessage;\n const messageComponents = useMemo(\n () => ({\n UserMessage: UserMessageComponent,\n AssistantMessage: AssistantMessageComponent,\n }),\n [AssistantMessageComponent, UserMessageComponent],\n );\n\n return (\n <AthenaChatDefaultComponentsContext.Provider value={defaultComponentsContextValue}>\n {/* Contain render crashes to the chat pane (telemetry + retry) instead of\n unmounting the integrator's subtree. */}\n <AthenaChatErrorBoundary>\n <ChatThreadShell\n overlay={<ThreadLoadingOverlay />}\n panelClassName={cn(\n 'aui-root aui-thread-root @container relative flex h-full flex-col bg-background',\n className,\n )}\n maxWidth={maxWidth}\n turnAnchor={turnAnchor}\n viewportClassName=\"aui-thread-viewport relative flex flex-1 flex-col overflow-x-auto overflow-y-scroll scroll-smooth px-4 pt-4\"\n contentClassName=\"flex w-full flex-1 flex-col\"\n viewportOverlay={<ThreadScrollToTop />}\n welcome={\n <AthenaChatWelcome\n welcomeMessage={welcomeMessage}\n welcomeSubtext={welcomeSubtext}\n welcomeSuggestions={welcomeSuggestions}\n />\n }\n beforeMessages={<StatewireHistoryEdge className=\"aui-thread-history-edge\" />}\n components={messageComponents}\n runningIndicator={null}\n scrollToBottom={<ThreadScrollToBottom />}\n viewportFooterClassName=\"aui-thread-viewport-footer sticky bottom-0 mx-auto mt-auto flex w-full max-w-(--thread-max-width) flex-col gap-4 overflow-visible rounded-t-3xl bg-background pb-4 md:pb-6\"\n viewportFooter={\n <>\n <StatewireConnectionBanner />\n <StatewireErrorBanner />\n <StatewireApprovalCard />\n <StatewireQueuedMessages />\n <AttachmentProvider>\n <QuoteProvider>\n <QuotePostMessageBridge />\n <MentionAuthCtx.Provider value={mentionAuth}>\n <AthenaChatComposer tools={tools} />\n </MentionAuthCtx.Provider>\n </QuoteProvider>\n </AttachmentProvider>\n </>\n }\n />\n </AthenaChatErrorBoundary>\n </AthenaChatDefaultComponentsContext.Provider>\n );\n};\n\nconst ThreadLoadingOverlay: FC = () => {\n const remoteId = useAthenaThreadId();\n const [timedOut, setTimedOut] = useState(false);\n\n useEffect(() => {\n if (!remoteId) return;\n setTimedOut(false);\n const timer = setTimeout(() => setTimedOut(true), 15000);\n return () => clearTimeout(timer);\n }, [remoteId]);\n\n if (!remoteId || timedOut) return null;\n\n return (\n <AuiIf condition={(s) => s.thread.isEmpty}>\n <div className=\"absolute inset-0 z-10 flex items-center justify-center bg-background/80\">\n <div className=\"size-5 animate-spin rounded-full border-2 border-muted-foreground border-t-transparent\" />\n </div>\n </AuiIf>\n );\n};\n\nconst THREAD_VIEWPORT_ATTR = 'data-aui-thread-viewport';\n\nconst useScrollToTop = () => {\n const [isAtTop, setIsAtTop] = useState(true);\n const [buttonEl, setButtonEl] = useState<HTMLButtonElement | null>(null);\n\n const containerRef = useCallback((node: HTMLButtonElement | null) => {\n setButtonEl(node);\n }, []);\n\n const getViewport = useCallback((): HTMLElement | null => {\n if (!buttonEl) return null;\n return buttonEl.closest(`[${THREAD_VIEWPORT_ATTR}]`) as HTMLElement | null;\n }, [buttonEl]);\n\n useEffect(() => {\n const viewport: HTMLElement | null = getViewport();\n if (!viewport) return;\n\n const handleScroll = () => {\n setIsAtTop(viewport.scrollTop <= 50);\n };\n\n handleScroll();\n viewport.addEventListener('scroll', handleScroll, { passive: true });\n return () => viewport.removeEventListener('scroll', handleScroll);\n }, [getViewport]);\n\n const handleClick = useCallback(() => {\n const viewport: HTMLElement | null = getViewport();\n if (!viewport) return;\n viewport.scrollTo({ top: 0, behavior: 'smooth' });\n }, [getViewport]);\n\n return { isAtTop, containerRef, handleClick };\n};\n\nconst ThreadScrollToTop: FC = () => {\n const { isAtTop, containerRef, handleClick } = useScrollToTop();\n const isEmpty = useAuiState((s) => s.thread.isEmpty);\n\n if (isEmpty) return null;\n\n return (\n <div className=\"sticky top-0 z-10 mx-auto flex h-0 w-full max-w-(--thread-max-width) justify-center\">\n <TooltipIconButton\n ref={containerRef}\n tooltip=\"Scroll to top\"\n variant=\"outline\"\n className={cn('aui-thread-scroll-to-top absolute top-2 rounded-full p-4 dark:bg-background dark:hover:bg-accent', isAtTop && 'invisible')}\n onClick={handleClick}\n >\n <ArrowUpIcon />\n </TooltipIconButton>\n </div>\n );\n};\n\nconst ThreadScrollToBottom: FC = () => (\n <ThreadPrimitive.ScrollToBottom asChild>\n <TooltipIconButton\n tooltip=\"Scroll to bottom\"\n variant=\"outline\"\n className=\"aui-thread-scroll-to-bottom absolute -top-12 z-10 self-center rounded-full p-4 disabled:invisible dark:bg-background dark:hover:bg-accent\"\n >\n <ArrowDownIcon />\n </TooltipIconButton>\n </ThreadPrimitive.ScrollToBottom>\n);\n\nconst AthenaComposerSendButton: FC<ComposerSendButtonProps> = ({\n action,\n onSend,\n disabled,\n title,\n}) => {\n const label = action === 'queue' ? 'Queue message' : 'Send message';\n return (\n <TooltipIconButton\n tooltip={title ?? label}\n side=\"bottom\"\n type=\"button\"\n variant=\"default\"\n size=\"icon\"\n className=\"aui-composer-send size-8 rounded-full\"\n aria-label={label}\n onClick={onSend}\n disabled={disabled}\n >\n {action === 'queue' ? (\n <ListPlusIcon className=\"aui-composer-send-icon size-4\" />\n ) : (\n <ArrowUpIcon className=\"aui-composer-send-icon size-4\" />\n )}\n </TooltipIconButton>\n );\n};\n\nconst AthenaComposerStopButton: FC<ComposerStopButtonProps> = ({ onStop, disabled, title }) => (\n <Button\n type=\"button\"\n variant=\"default\"\n size=\"icon\"\n className=\"aui-composer-cancel size-8 rounded-full\"\n aria-label=\"Stop generating\"\n title={title}\n onClick={onStop}\n disabled={disabled}\n >\n <SquareIcon className=\"aui-composer-cancel-icon size-3 fill-current\" />\n </Button>\n);\n\nconst ATHENA_COMPOSER_COMPONENTS = {\n SendButton: AthenaComposerSendButton,\n StopButton: AthenaComposerStopButton,\n};\n\n/**\n * The asset-library categories of AthenaChat's `@` menu. Browse profiles,\n * team and drives are left out: they need browser-side scoping or a workspace\n * id that API-key auth does not carry. The Tools / Toolkits categories are\n * added when the host (or the provider's enabled toolkits) offers any.\n */\nconst ATHENA_CHAT_MENTION_CATEGORIES: readonly MentionRootCategory[] = [\n 'favorites',\n 'assets',\n 'projects',\n 'folders',\n];\n\n/**\n * AthenaChat's composer: the shared chat-ui Tiptap editor and `@` mention menu\n * with AthenaChat's quote and attachment pills composed into the send.\n *\n * A draft with a quote or attachment pills — text or not — is intercepted on\n * submit and dispatched as one composed message through the composer runtime,\n * the path the server-owned queue observes, so a mid-run submit queues like\n * any other send. Pasted images upload into the pills through the same intake\n * as the paperclip and the drop zone, and every submit path (Enter, the send\n * button) waits for an in-flight upload so a send never leaves without its\n * attachment. The send control resolves send / queue / stop through the\n * shared chat-ui logic.\n */\nconst AthenaChatComposer: FC<{ tools: MentionTool[] }> = ({ tools }) => {\n const aui = useAui();\n const threadId = useAthenaStatewireThreadId();\n const { appUrl } = useAthenaConfig();\n const { attachments, clearAttachments, isUploading } = useAttachments();\n const { quote, clearQuote } = useQuote();\n const { attachFiles } = useAttachFiles();\n const composerRef = useRef<TiptapComposerHandle>(null);\n const [hasText, setHasText] = useState(false);\n\n const rootCategories = useMemo<readonly MentionRootCategory[]>(() => {\n const categories = [...ATHENA_CHAT_MENTION_CATEGORIES];\n if (tools.some((tool) => tool.type === 'toolkit')) categories.push('toolkits');\n if (tools.some((tool) => tool.type === 'tool')) categories.push('tools');\n return categories;\n }, [tools]);\n\n // The submit paths are captured once by the editor's keybinding, so they\n // read the current draft extras through refs.\n const attachmentsRef = useRef(attachments);\n attachmentsRef.current = attachments;\n const quoteRef = useRef(quote);\n quoteRef.current = quote;\n const hasExtras = attachments.length > 0 || quote !== null;\n\n // A submit during an upload parks until the pills have the asset; the\n // waiters resolve on the render that turns `isUploading` off, by which\n // point `attachmentsRef` holds the uploaded asset.\n const isUploadingRef = useRef(isUploading);\n isUploadingRef.current = isUploading;\n const uploadWaitersRef = useRef<Array<() => void>>([]);\n useEffect(() => {\n if (isUploading) return;\n const waiters = uploadWaitersRef.current;\n uploadWaitersRef.current = [];\n for (const resolve of waiters) resolve();\n }, [isUploading]);\n const waitForHostUploads = useCallback(() => {\n if (!isUploadingRef.current) return;\n return new Promise<void>((resolve) => {\n uploadWaitersRef.current.push(resolve);\n });\n }, []);\n\n const sendComposed = useCallback(\n (userText: string): boolean => {\n const message = buildComposedMessage({\n attachments: attachmentsRef.current,\n quote: quoteRef.current,\n userText,\n appUrl,\n });\n if (!message) return false;\n // steer: false — a mid-run send queues behind the active run instead of\n // interrupting it; idle sends dispatch immediately.\n aui.composer.setText(message);\n aui.composer.send({ steer: false });\n clearAttachments();\n clearQuote();\n return true;\n },\n [appUrl, aui, clearAttachments, clearQuote],\n );\n\n // Consumes the editor's draft (possibly empty) only when there are extras\n // to compose with it.\n const interceptSubmit = useCallback(\n (text: string) =>\n attachmentsRef.current.length > 0 || quoteRef.current !== null\n ? sendComposed(text)\n : false,\n [sendComposed],\n );\n\n // Pasted images go through the pills' intake; drops are left to the\n // enclosing ComposerDropZone.\n const fileIntake = useMemo<ComposerFileIntake>(\n () => ({\n onPaste: (files) => {\n void attachFiles(files, 'paste');\n },\n }),\n [attachFiles],\n );\n\n return (\n <ComposerDropZone>\n <ChatComposerDock\n className=\"\"\n surfaceClassName=\"aui-composer-root relative flex w-full flex-col rounded-2xl border border-input bg-background px-1 pt-2 outline-none transition-shadow focus-within:border-ring focus-within:ring-2 focus-within:ring-ring/20\"\n editorRowClassName=\"px-2.5\"\n toolbarClassName=\"aui-composer-action-wrapper relative mx-2 mb-2 flex items-center\"\n beforeEditor={\n <>\n <ComposerQuotePreview />\n <ComposerAttachmentPreview />\n </>\n }\n editor={\n <TiptapComposer\n ref={composerRef}\n threadId={threadId}\n placeholder=\"Send a message...\"\n tools={tools}\n rootCategories={rootCategories}\n onDraftStateChange={setHasText}\n waitForHostUploads={waitForHostUploads}\n interceptSubmit={interceptSubmit}\n fileIntake={fileIntake}\n />\n }\n toolbarStart={\n <div className=\"flex items-center gap-1\">\n <FileUploadButton />\n </div>\n }\n toolbarEnd={\n <div className=\"flex items-center gap-1\">\n <ComposerSendOrStop\n composerRef={composerRef}\n hasDraft={hasText || hasExtras}\n sendBlockedReason={isUploading ? 'Upload in progress...' : null}\n components={ATHENA_COMPOSER_COMPONENTS}\n />\n </div>\n }\n />\n </ComposerDropZone>\n );\n};\n\nconst MessageError: FC = () => (\n <MessagePrimitive.Error>\n <ErrorPrimitive.Root className=\"aui-message-error-root mt-2 flex items-start gap-2 rounded-md border border-destructive bg-destructive/10 p-3 text-destructive text-sm dark:bg-destructive/5 dark:text-red-200\">\n <AlertCircleIcon className=\"mt-0.5 size-4 shrink-0\" />\n <ErrorPrimitive.Message className=\"aui-message-error-message grow\" />\n <ActionBarPrimitive.Reload asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-6 shrink-0 text-destructive hover:text-destructive dark:text-red-200 dark:hover:text-red-100\"\n >\n <RefreshCwIcon className=\"size-3.5\" />\n </Button>\n </ActionBarPrimitive.Reload>\n </ErrorPrimitive.Root>\n </MessagePrimitive.Error>\n);\n\nconst AthenaAssistantMessageEmpty: EmptyMessagePartComponent = ({ status }) => {\n if (status?.type !== 'running') return null;\n return (\n <span className=\"shimmer text-[13px] text-muted-foreground\">Thinking...</span>\n );\n};\n\n/**\n * Renders the empty/loading indicator while a message is running but has no\n * parts yet. `MessagePrimitive.GroupedParts` only renders existing parts, so\n * the indicator can't live inside its switch — it goes here as a sibling.\n */\nconst AthenaMessageEmptyIndicator: FC<{ EmptyComponent: EmptyMessagePartComponent }> = ({\n EmptyComponent,\n}) => {\n const hasParts = useAuiState((s) => s.message.parts.length > 0);\n const isRunning = useAuiState((s) => s.message.status?.type === 'running');\n if (hasParts || !isRunning) return null;\n return <EmptyComponent status={{ type: 'running' }} />;\n};\n\n/**\n * Run-liveness row under a running message whose tail is a tool call.\n *\n * Answers \"is anything still happening?\" once parts exist: pulsing dots plus\n * an elapsed counter that resets whenever the stream moves the tail part, and\n * a stall tone once nothing has streamed for a while — so a busy run and a\n * possibly-stuck one stop looking identical. Text/reasoning tails animate on\n * their own and render no row.\n */\nconst AthenaMessageActivityIndicator: FC = () => {\n const isRunning = useAuiState((s) => s.message.status?.type === 'running');\n const activityKey = useAuiState((s) => runActivityKey(s.message.parts));\n const [seconds, setSeconds] = useState(0);\n useEffect(() => {\n setSeconds(0);\n if (!isRunning || activityKey === null) return;\n const startedAt = Date.now();\n const timer = setInterval(() => {\n setSeconds(Math.floor((Date.now() - startedAt) / 1000));\n }, 1000);\n return () => clearInterval(timer);\n }, [isRunning, activityKey]);\n if (!isRunning || activityKey === null) return null;\n const stalled = seconds >= RUN_ACTIVITY_STALL_SECONDS;\n return (\n <div className=\"aui-run-activity mt-2 flex items-center gap-2 px-1 text-[12px] text-muted-foreground\">\n <span className=\"flex items-center gap-1\" aria-hidden>\n <span className=\"size-1.5 animate-bounce rounded-full bg-current [animation-delay:0ms]\" />\n <span className=\"size-1.5 animate-bounce rounded-full bg-current [animation-delay:150ms]\" />\n <span className=\"size-1.5 animate-bounce rounded-full bg-current [animation-delay:300ms]\" />\n </span>\n <span aria-hidden className={stalled ? 'text-amber-600 dark:text-amber-400' : undefined}>\n {runActivityLabel(seconds)}\n </span>\n {/* The visible counter ticks every second; announcing each tick would\n drown a screen reader, so the live region only speaks the two\n meaningful transitions: work started, and work looks stalled. */}\n <span aria-live=\"polite\" className=\"sr-only\">\n {stalled\n ? 'Assistant is still working; nothing new for over thirty seconds.'\n : 'Assistant is working.'}\n </span>\n </div>\n );\n};\n\nexport const AthenaReasoningPart: FC<AthenaReasoningPartProps> = ({\n text,\n status,\n TextComponent,\n}) => {\n const inheritedTextComponent = useContext(AthenaReasoningTextComponentContext);\n const EffectiveTextComponent = TextComponent ?? inheritedTextComponent ?? TiptapText;\n const isMessageRunning = useAuiState((state) => state.message.status?.type === 'running');\n const reasoningTokens = useAuiState((state) =>\n getReasoningTokensFromMetadata(state.message.metadata)\n );\n const isRunning = isMessageRunning || status?.type === 'running';\n const [isCollapsed, setIsCollapsed] = useState(!isRunning);\n const userOverrodeOpenStateRef = useRef(false);\n const hasText = text.trim().length > 0;\n\n const reasoningTextProps: TextMessagePartProps = {\n type: 'text',\n text,\n status: isRunning\n ? ({ type: 'running' } as TextMessagePartProps['status'])\n : (status as TextMessagePartProps['status']),\n };\n\n useEffect(() => {\n if (userOverrodeOpenStateRef.current) {\n return;\n }\n\n setIsCollapsed(!isRunning);\n }, [isRunning]);\n\n if (!hasText && !isRunning) {\n return null;\n }\n\n return (\n <Collapsible\n open={!isCollapsed}\n onOpenChange={(open) => {\n userOverrodeOpenStateRef.current = true;\n setIsCollapsed(!open);\n }}\n className=\"aui-assistant-reasoning-root mb-3 rounded-2xl border border-border/60 bg-muted/30 px-3 py-2\"\n >\n <CollapsibleTrigger asChild>\n <button\n type=\"button\"\n className=\"flex w-full items-center justify-between gap-3 text-left\"\n aria-label={isRunning ? 'Toggle reasoning while streaming' : 'Toggle reasoning'}\n >\n <span className=\"flex min-w-0 items-center gap-2 text-[13px] font-medium text-muted-foreground\">\n <BrainIcon className=\"size-4 shrink-0\" />\n <span>{isRunning ? 'Reasoning...' : 'Reasoning'}</span>\n </span>\n <span className=\"flex shrink-0 items-center gap-2\">\n {reasoningTokens !== undefined && (\n <span className=\"rounded-full border border-border/60 bg-background px-2 py-0.5 text-[11px] font-medium text-muted-foreground\">\n {formatReasoningTokens(reasoningTokens)}\n </span>\n )}\n <span\n className={cn(\n 'flex size-5 items-center justify-center text-muted-foreground transition-transform',\n isCollapsed ? 'rotate-0' : 'rotate-90'\n )}\n aria-hidden=\"true\"\n >\n <ChevronRightIcon className=\"size-4\" />\n </span>\n </span>\n </button>\n </CollapsibleTrigger>\n\n <CollapsibleContent className=\"pt-3\">\n {isRunning && !hasText ? (\n <span className=\"shimmer text-[13px] text-muted-foreground\">Analyzing...</span>\n ) : (\n <div className=\"aui-assistant-reasoning-body text-[13px] leading-relaxed\">\n <EffectiveTextComponent {...reasoningTextProps} />\n </div>\n )}\n </CollapsibleContent>\n </Collapsible>\n );\n};\n\nconst groupAdjacentToolCalls = (part: PartState) =>\n part.type === 'tool-call' ? (['group-tool'] as const) : null;\nconst noToolGrouping = () => null;\n\nexport const AthenaAssistantMessage: FC<AthenaAssistantMessageProps> = ({\n toolUIs,\n TextComponent = TiptapText,\n ReasoningComponent,\n EmptyComponent = AthenaAssistantMessageEmpty,\n ActionBarComponent = AthenaAssistantActionBar,\n groupToolCalls = false,\n}) => {\n const effectiveReasoningComponent = ReasoningComponent ?? AthenaReasoningPart;\n const toolUIsWithNestedMessages = useMemo(() => {\n const wrappedToolUIs: Record<string, ToolCallMessagePartComponent> = {};\n\n for (const [toolName, ToolUI] of Object.entries(toolUIs)) {\n wrappedToolUIs[toolName] = withNestedPtcMessages(ToolUI);\n }\n\n return wrappedToolUIs;\n }, [toolUIs]);\n\n // NestedPtcComponentsProvider still consumes the legacy parts-config shape\n // (Text / Reasoning / tools.by_name / Empty) to render PTC sub-tool messages\n // inside a tool card. The outer rendering uses GroupedParts, but the inner\n // PTC tree continues to mirror the parent registry.\n const nestedPtcComponents = useMemo(\n () => ({\n Text: TextComponent,\n Reasoning: effectiveReasoningComponent,\n tools: {\n Fallback: ToolFallback,\n by_name: toolUIsWithNestedMessages,\n },\n Empty: EmptyComponent,\n }),\n [EmptyComponent, TextComponent, effectiveReasoningComponent, toolUIsWithNestedMessages],\n );\n\n return (\n <MessagePrimitive.Root\n className=\"aui-assistant-message-root group/aui-assistant-message fade-in slide-in-from-bottom-1 relative mx-auto w-full max-w-(--thread-max-width) animate-in py-3 duration-150\"\n data-role=\"assistant\"\n >\n <AthenaReasoningTextComponentContext.Provider value={TextComponent}>\n <div className=\"aui-assistant-message-content wrap-break-word px-2 text-foreground leading-relaxed\">\n <NestedPtcComponentsProvider components={nestedPtcComponents}>\n {groupToolCalls ? (\n <div className=\"flex flex-col space-y-2\">\n <SuperGroupingCard\n toolUIs={toolUIsWithNestedMessages}\n TextComponent={TextComponent}\n ReasoningComponent={effectiveReasoningComponent}\n />\n <SuperGroupingFinalText TextComponent={TextComponent} />\n <AthenaMessageActivityIndicator />\n </div>\n ) : (\n <>\n <AthenaMessageEmptyIndicator EmptyComponent={EmptyComponent} />\n <MessagePrimitive.GroupedParts groupBy={noToolGrouping}>\n {({ part }) => {\n switch (part.type) {\n case 'tool-call': {\n const ToolUI = toolUIsWithNestedMessages[part.toolName];\n const toolProps = part as unknown as ToolCallMessagePartProps;\n return ToolUI ? <ToolUI {...toolProps} /> : <ToolFallback {...toolProps} />;\n }\n case 'reasoning': {\n const ReasoningRenderer = effectiveReasoningComponent;\n return <ReasoningRenderer {...(part as ReasoningMessagePartProps)} />;\n }\n case 'text': {\n const textPart = part as TextMessagePartProps;\n if (textPart.text === '' && textPart.status?.type === 'running') {\n return <EmptyComponent status={textPart.status} />;\n }\n return <TextComponent {...textPart} />;\n }\n default:\n return null;\n }\n }}\n </MessagePrimitive.GroupedParts>\n <AthenaMessageActivityIndicator />\n </>\n )}\n </NestedPtcComponentsProvider>\n <MessageError />\n </div>\n </AthenaReasoningTextComponentContext.Provider>\n <div className=\"aui-assistant-message-footer mt-1 ml-2 flex\">\n <ActionBarComponent />\n </div>\n </MessagePrimitive.Root>\n );\n};\n\nconst AthenaToolGroup: FC<{ children: React.ReactNode; count: number }> = ({ children, count }) => {\n const [expanded, setExpanded] = useState(false);\n\n return (\n <div className=\"my-3 w-full overflow-hidden rounded-xl border border-border/60 bg-background shadow-sm\">\n <button\n type=\"button\"\n onClick={() => setExpanded((v) => !v)}\n className=\"flex w-full items-center gap-3 px-4 py-3 text-left transition-colors hover:bg-muted/20\"\n aria-expanded={expanded}\n >\n <div className=\"flex size-8 shrink-0 items-center justify-center rounded-lg bg-muted/60 text-muted-foreground\">\n <LayersIcon className=\"size-4\" />\n </div>\n <div className=\"min-w-0 flex-1\">\n <span className=\"text-[13px] font-medium text-foreground\">\n {count} tool {count === 1 ? 'call' : 'calls'}\n </span>\n </div>\n <ChevronDownIcon\n className={cn(\n 'size-4 shrink-0 text-muted-foreground transition-transform duration-200',\n !expanded && '-rotate-90',\n )}\n />\n </button>\n {expanded && (\n <div className=\"border-t border-border/40 bg-muted/5 px-3 pt-1 pb-2 [&>*]:my-2\">\n {children}\n </div>\n )}\n </div>\n );\n};\n\nexport const AthenaAssistantActionBar: FC<AthenaAssistantActionBarProps> = ({ className }) => {\n const threadId = useAthenaThreadId();\n const { appUrl } = useAthenaConfig();\n // The bar stays mounted so the footer keeps its height: assistant-ui's\n // `autohide` / `hideWhenRunning` unmount it, which shifts the whole message\n // up and down on every hover. Visibility is CSS instead — the latest reply\n // keeps its actions, older replies reveal on hover or keyboard focus, and\n // while the thread runs every bar is `invisible` (layout kept, controls\n // unfocusable — opacity alone would still let Tab reveal them).\n const isLast = useAuiState((s) => s.message.isLast);\n const isThreadRunning = useAuiState((s) => s.thread.isRunning);\n\n return (\n <ActionBarPrimitive.Root\n autohide=\"never\"\n className={cn(\n 'aui-assistant-action-bar-root -ml-1 flex min-h-6 gap-1 text-muted-foreground',\n isThreadRunning && 'invisible',\n !isThreadRunning &&\n !isLast && [\n ACTION_BAR_REVEAL_CLASS,\n 'group-hover/aui-assistant-message:pointer-events-auto group-hover/aui-assistant-message:opacity-100',\n ],\n className,\n )}\n >\n <ActionBarPrimitive.Copy asChild>\n <TooltipIconButton tooltip=\"Copy\">\n <AuiIf condition={(s) => s.message.isCopied}>\n <CheckIcon />\n </AuiIf>\n <AuiIf condition={(s) => !s.message.isCopied}>\n <CopyIcon />\n </AuiIf>\n </TooltipIconButton>\n </ActionBarPrimitive.Copy>\n <ActionBarMorePrimitive.Root>\n <ActionBarMorePrimitive.Trigger asChild>\n <TooltipIconButton tooltip=\"More\" className=\"data-[state=open]:bg-accent\">\n <MoreHorizontalIcon />\n </TooltipIconButton>\n </ActionBarMorePrimitive.Trigger>\n <ActionBarMorePrimitive.Content\n side=\"bottom\"\n align=\"start\"\n className=\"aui-action-bar-more-content z-50 min-w-32 overflow-hidden rounded-md border bg-popover p-1 text-popover-foreground shadow-md\"\n >\n <ActionBarPrimitive.ExportMarkdown asChild>\n <ActionBarMorePrimitive.Item className=\"aui-action-bar-more-item flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground\">\n <DownloadIcon className=\"size-4\" />\n Export as Markdown\n </ActionBarMorePrimitive.Item>\n </ActionBarPrimitive.ExportMarkdown>\n {threadId && (\n <ActionBarMorePrimitive.Item\n className=\"aui-action-bar-more-item flex cursor-pointer select-none items-center gap-2 rounded-sm px-2 py-1.5 text-sm outline-none hover:bg-accent hover:text-accent-foreground focus:bg-accent focus:text-accent-foreground\"\n onClick={() => {\n window.open(createAthenaSpacesUrl({ appUrl, sessionId: threadId }), '_blank');\n }}\n >\n <ExternalLinkIcon className=\"size-4\" />\n Open in Athena\n </ActionBarMorePrimitive.Item>\n )}\n </ActionBarMorePrimitive.Content>\n </ActionBarMorePrimitive.Root>\n </ActionBarPrimitive.Root>\n );\n};\n\nexport const AthenaUserMessage: FC<AthenaUserMessageProps> = ({\n TextComponent = TiptapText,\n}) => (\n <MessagePrimitive.Root\n className=\"aui-user-message-root fade-in slide-in-from-bottom-1 mx-auto flex w-full max-w-(--thread-max-width) animate-in justify-end px-2 py-3 duration-150\"\n data-role=\"user\"\n >\n <div className=\"aui-user-message-content wrap-break-word rounded-2xl bg-muted px-4 py-2.5 text-foreground\">\n <MessagePrimitive.Parts components={{ Text: TextComponent }} />\n </div>\n </MessagePrimitive.Root>\n);\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"asset-type-icons.cjs","sources":["../../../../../../src/chat-ui/mentions/suggestions/data/sources/asset-type-icons.ts"],"sourcesContent":["/**\n * Maps Athena asset types to SVG icon file names.\n *\n * The SVG files are bundled by the host app, which declares where they are\n * served from via `configureAssetIconBasePath`. Hosts that don't bundle them\n * fall back to the Lucide icons carried on every menu item.\n */\n\nlet iconBasePath: string | null = null;\n\n/**\n * Point the mention UI at the host's copy of the asset-type SVGs.\n * `basePath` is resolved against the host document; a trailing \"/\" is added\n * when the caller omits it.\n */\nexport function configureAssetIconBasePath({\n basePath,\n}: {\n basePath: string | null;\n}): void {\n iconBasePath = basePath ? basePath.replace(/\\/*$/, \"/\") : basePath;\n}\n\nconst ASSET_TYPE_ICON_FILE: Record<string, string> = {\n // Documents\n folder: \"ic-folder\",\n txt: \"ic-txt\",\n document: \"ic-word\",\n word_document: \"ic-word\",\n markdown: \"ic-md\",\n pdf: \"ic-pdf\",\n html: \"ic-html\",\n web_page: \"ic-html\",\n yaml: \"ic-yaml\",\n json: \"ic-json\",\n\n // Spreadsheets\n spreadsheet: \"ic-excel\",\n table: \"ic-table\",\n\n // Media\n image: \"ic-img\",\n audio: \"ic-audio\",\n video: \"ic-video\",\n voice_memo: \"ic-voice_memo\",\n\n // Presentations\n powerpoint_deck: \"ic-power_point\",\n presentation_pptx_studio: \"ic-power_point\",\n pptx: \"ic-power_point\",\n\n // Email & Calendar\n email: \"ic-mail\",\n email_message: \"ic-mail\",\n live_email_thread: \"ic-mail\",\n live_calendar_event: \"ic-mail\",\n\n // Code\n python: \"ic-py\",\n javascript: \"ic-js\",\n typescript: \"ic-code\",\n jsx: \"ic-code\",\n tsx: \"ic-code\",\n css: \"ic-code\",\n java: \"ic-code\",\n c: \"ic-code\",\n cpp: \"ic-code\",\n csharp: \"ic-code\",\n ruby: \"ic-code\",\n go: \"ic-code\",\n swift: \"ic-code\",\n php: \"ic-code\",\n rust: \"ic-code\",\n vue: \"ic-code\",\n wm_script: \"ic-code\",\n\n // Structured data\n database: \"ic-snippet\",\n schema: \"ic-schema\",\n catalog: \"ic-db\",\n drive: \"ic-db\",\n query_snippet: \"ic-snippet\",\n semantic_model: \"ic-db\",\n dataset: \"ic-db\",\n\n // Meetings & Calls\n meeting: \"ic-meeting\",\n video_session: \"ic-meeting\",\n phone_call: \"ic-phonecall\",\n\n // Sessions & Devices\n session: \"ic-session\",\n browse_session: \"ic-html\",\n
|
|
1
|
+
{"version":3,"file":"asset-type-icons.cjs","sources":["../../../../../../src/chat-ui/mentions/suggestions/data/sources/asset-type-icons.ts"],"sourcesContent":["/**\n * Maps Athena asset types to SVG icon file names.\n *\n * The SVG files are bundled by the host app, which declares where they are\n * served from via `configureAssetIconBasePath`. Hosts that don't bundle them\n * fall back to the Lucide icons carried on every menu item.\n */\n\nlet iconBasePath: string | null = null;\n\n/**\n * Point the mention UI at the host's copy of the asset-type SVGs.\n * `basePath` is resolved against the host document; a trailing \"/\" is added\n * when the caller omits it.\n */\nexport function configureAssetIconBasePath({\n basePath,\n}: {\n basePath: string | null;\n}): void {\n iconBasePath = basePath ? basePath.replace(/\\/*$/, \"/\") : basePath;\n}\n\nconst ASSET_TYPE_ICON_FILE: Record<string, string> = {\n // Documents\n folder: \"ic-folder\",\n txt: \"ic-txt\",\n document: \"ic-word\",\n word_document: \"ic-word\",\n markdown: \"ic-md\",\n pdf: \"ic-pdf\",\n html: \"ic-html\",\n web_page: \"ic-html\",\n yaml: \"ic-yaml\",\n json: \"ic-json\",\n\n // Spreadsheets\n spreadsheet: \"ic-excel\",\n table: \"ic-table\",\n\n // Media\n image: \"ic-img\",\n audio: \"ic-audio\",\n video: \"ic-video\",\n voice_memo: \"ic-voice_memo\",\n\n // Presentations\n powerpoint_deck: \"ic-power_point\",\n presentation_pptx_studio: \"ic-power_point\",\n pptx: \"ic-power_point\",\n\n // Email & Calendar\n email: \"ic-mail\",\n email_message: \"ic-mail\",\n live_email_thread: \"ic-mail\",\n live_calendar_event: \"ic-mail\",\n\n // Code\n python: \"ic-py\",\n javascript: \"ic-js\",\n typescript: \"ic-code\",\n jsx: \"ic-code\",\n tsx: \"ic-code\",\n css: \"ic-code\",\n java: \"ic-code\",\n c: \"ic-code\",\n cpp: \"ic-code\",\n csharp: \"ic-code\",\n ruby: \"ic-code\",\n go: \"ic-code\",\n swift: \"ic-code\",\n php: \"ic-code\",\n rust: \"ic-code\",\n vue: \"ic-code\",\n wm_script: \"ic-code\",\n\n // Structured data\n database: \"ic-snippet\",\n schema: \"ic-schema\",\n catalog: \"ic-db\",\n drive: \"ic-db\",\n query_snippet: \"ic-snippet\",\n semantic_model: \"ic-db\",\n dataset: \"ic-db\",\n\n // Meetings & Calls\n meeting: \"ic-meeting\",\n video_session: \"ic-meeting\",\n phone_call: \"ic-phonecall\",\n\n // Sessions & Devices\n session: \"ic-session\",\n browse_session: \"ic-html\",\n computer: \"ic-computer\",\n desktop_session: \"ic-desktop_session\",\n mobile_session: \"ic-mobile_session\",\n\n // Projects & Profiles\n project: \"ic-project\",\n browse_profile: \"ic-profile\",\n\n // Workflows & Automation\n aop: \"ic-flow\",\n playbook: \"ic-playbook\",\n policy: \"ic-policy\",\n flow: \"ic-flow\",\n transform_project: \"ic-transform_project\",\n\n // Collections & Notebooks\n collection: \"ic-collection\",\n notebook: \"ic-notebook\",\n\n // UI & Apps\n user_interface: \"ic-app\",\n application: \"ic-application\",\n canvas: \"ic-canvas\",\n dashboard: \"ic-dashboard\",\n figure: \"ic_figure\",\n\n // People & Companies\n person: \"ic-person\",\n company: \"ic-company\",\n\n // Misc\n prompt: \"ic-ai\",\n skill: \"ic-skill\",\n task_item: \"ic-task\",\n spaces: \"ic-spaces\",\n secret: \"ic-secret\",\n photoshop: \"ic-pts\",\n illustrator: \"ic-ai\",\n zip: \"ic-zip\",\n sevenzip: \"ic-zip\",\n\n // Google Drive / SharePoint / Salesforce\n gdrive_folder: \"ic-folder\",\n gdrive_file: \"ic-file\",\n salesforce_record: \"ic-db\",\n salesforce_file: \"ic-db\",\n};\n\nconst ASSET_TYPE_LUCIDE_FALLBACK: Record<string, string> = {\n folder: \"folder\",\n spreadsheet: \"sheet\",\n image: \"image\",\n video: \"video\",\n audio: \"headphones\",\n email: \"mail\",\n database: \"database\",\n project: \"folder-kanban\",\n meeting: \"video\",\n user_interface: \"layout\",\n};\n\n/**\n * Get the SVG thumbnail URL for an Athena asset type, or undefined when the\n * host app does not bundle the icon files.\n */\nexport function assetTypeToThumb(\n assetType: string | null | undefined,\n): string | undefined {\n if (!iconBasePath) return undefined;\n const name: string =\n (assetType ? ASSET_TYPE_ICON_FILE[assetType.toLowerCase()] : undefined) ??\n \"ic-file\";\n return `${iconBasePath}${name}.svg`;\n}\n\n/**\n * Get Lucide icon name fallback for an asset type.\n * Used when thumbnailUrl can't load.\n */\nexport function assetTypeToIcon(assetType: string | null | undefined): string {\n if (!assetType) return \"file\";\n return ASSET_TYPE_LUCIDE_FALLBACK[assetType.toLowerCase()] ?? \"file\";\n}\n"],"names":[],"mappings":";;AAQA,IAAI,eAA8B;AAO3B,SAAS,2BAA2B;AAAA,EACzC;AACF,GAES;AACP,iBAAe,WAAW,SAAS,QAAQ,QAAQ,GAAG,IAAI;AAC5D;AAEA,MAAM,uBAA+C;AAAA;AAAA,EAEnD,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,UAAU;AAAA,EACV,eAAe;AAAA,EACf,UAAU;AAAA,EACV,KAAK;AAAA,EACL,MAAM;AAAA,EACN,UAAU;AAAA,EACV,MAAM;AAAA,EACN,MAAM;AAAA;AAAA,EAGN,aAAa;AAAA,EACb,OAAO;AAAA;AAAA,EAGP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,YAAY;AAAA;AAAA,EAGZ,iBAAiB;AAAA,EACjB,0BAA0B;AAAA,EAC1B,MAAM;AAAA;AAAA,EAGN,OAAO;AAAA,EACP,eAAe;AAAA,EACf,mBAAmB;AAAA,EACnB,qBAAqB;AAAA;AAAA,EAGrB,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,MAAM;AAAA,EACN,GAAG;AAAA,EACH,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,KAAK;AAAA,EACL,MAAM;AAAA,EACN,KAAK;AAAA,EACL,WAAW;AAAA;AAAA,EAGX,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,OAAO;AAAA,EACP,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,SAAS;AAAA;AAAA,EAGT,SAAS;AAAA,EACT,eAAe;AAAA,EACf,YAAY;AAAA;AAAA,EAGZ,SAAS;AAAA,EACT,gBAAgB;AAAA,EAChB,UAAU;AAAA,EACV,iBAAiB;AAAA,EACjB,gBAAgB;AAAA;AAAA,EAGhB,SAAS;AAAA,EACT,gBAAgB;AAAA;AAAA,EAGhB,KAAK;AAAA,EACL,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,mBAAmB;AAAA;AAAA,EAGnB,YAAY;AAAA,EACZ,UAAU;AAAA;AAAA,EAGV,gBAAgB;AAAA,EAChB,aAAa;AAAA,EACb,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,QAAQ;AAAA;AAAA,EAGR,QAAQ;AAAA,EACR,SAAS;AAAA;AAAA,EAGT,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,aAAa;AAAA,EACb,KAAK;AAAA,EACL,UAAU;AAAA;AAAA,EAGV,eAAe;AAAA,EACf,aAAa;AAAA,EACb,mBAAmB;AAAA,EACnB,iBAAiB;AACnB;AAEA,MAAM,6BAAqD;AAAA,EACzD,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,UAAU;AAAA,EACV,SAAS;AAAA,EACT,SAAS;AAAA,EACT,gBAAgB;AAClB;AAMO,SAAS,iBACd,WACoB;AACpB,MAAI,CAAC,aAAc,QAAO;AAC1B,QAAM,QACH,YAAY,qBAAqB,UAAU,YAAA,CAAa,IAAI,WAC7D;AACF,SAAO,GAAG,YAAY,GAAG,IAAI;AAC/B;AAMO,SAAS,gBAAgB,WAA8C;AAC5E,MAAI,CAAC,UAAW,QAAO;AACvB,SAAO,2BAA2B,UAAU,YAAA,CAAa,KAAK;AAChE;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"asset-type-icons.js","sources":["../../../../../../src/chat-ui/mentions/suggestions/data/sources/asset-type-icons.ts"],"sourcesContent":["/**\n * Maps Athena asset types to SVG icon file names.\n *\n * The SVG files are bundled by the host app, which declares where they are\n * served from via `configureAssetIconBasePath`. Hosts that don't bundle them\n * fall back to the Lucide icons carried on every menu item.\n */\n\nlet iconBasePath: string | null = null;\n\n/**\n * Point the mention UI at the host's copy of the asset-type SVGs.\n * `basePath` is resolved against the host document; a trailing \"/\" is added\n * when the caller omits it.\n */\nexport function configureAssetIconBasePath({\n basePath,\n}: {\n basePath: string | null;\n}): void {\n iconBasePath = basePath ? basePath.replace(/\\/*$/, \"/\") : basePath;\n}\n\nconst ASSET_TYPE_ICON_FILE: Record<string, string> = {\n // Documents\n folder: \"ic-folder\",\n txt: \"ic-txt\",\n document: \"ic-word\",\n word_document: \"ic-word\",\n markdown: \"ic-md\",\n pdf: \"ic-pdf\",\n html: \"ic-html\",\n web_page: \"ic-html\",\n yaml: \"ic-yaml\",\n json: \"ic-json\",\n\n // Spreadsheets\n spreadsheet: \"ic-excel\",\n table: \"ic-table\",\n\n // Media\n image: \"ic-img\",\n audio: \"ic-audio\",\n video: \"ic-video\",\n voice_memo: \"ic-voice_memo\",\n\n // Presentations\n powerpoint_deck: \"ic-power_point\",\n presentation_pptx_studio: \"ic-power_point\",\n pptx: \"ic-power_point\",\n\n // Email & Calendar\n email: \"ic-mail\",\n email_message: \"ic-mail\",\n live_email_thread: \"ic-mail\",\n live_calendar_event: \"ic-mail\",\n\n // Code\n python: \"ic-py\",\n javascript: \"ic-js\",\n typescript: \"ic-code\",\n jsx: \"ic-code\",\n tsx: \"ic-code\",\n css: \"ic-code\",\n java: \"ic-code\",\n c: \"ic-code\",\n cpp: \"ic-code\",\n csharp: \"ic-code\",\n ruby: \"ic-code\",\n go: \"ic-code\",\n swift: \"ic-code\",\n php: \"ic-code\",\n rust: \"ic-code\",\n vue: \"ic-code\",\n wm_script: \"ic-code\",\n\n // Structured data\n database: \"ic-snippet\",\n schema: \"ic-schema\",\n catalog: \"ic-db\",\n drive: \"ic-db\",\n query_snippet: \"ic-snippet\",\n semantic_model: \"ic-db\",\n dataset: \"ic-db\",\n\n // Meetings & Calls\n meeting: \"ic-meeting\",\n video_session: \"ic-meeting\",\n phone_call: \"ic-phonecall\",\n\n // Sessions & Devices\n session: \"ic-session\",\n browse_session: \"ic-html\",\n
|
|
1
|
+
{"version":3,"file":"asset-type-icons.js","sources":["../../../../../../src/chat-ui/mentions/suggestions/data/sources/asset-type-icons.ts"],"sourcesContent":["/**\n * Maps Athena asset types to SVG icon file names.\n *\n * The SVG files are bundled by the host app, which declares where they are\n * served from via `configureAssetIconBasePath`. Hosts that don't bundle them\n * fall back to the Lucide icons carried on every menu item.\n */\n\nlet iconBasePath: string | null = null;\n\n/**\n * Point the mention UI at the host's copy of the asset-type SVGs.\n * `basePath` is resolved against the host document; a trailing \"/\" is added\n * when the caller omits it.\n */\nexport function configureAssetIconBasePath({\n basePath,\n}: {\n basePath: string | null;\n}): void {\n iconBasePath = basePath ? basePath.replace(/\\/*$/, \"/\") : basePath;\n}\n\nconst ASSET_TYPE_ICON_FILE: Record<string, string> = {\n // Documents\n folder: \"ic-folder\",\n txt: \"ic-txt\",\n document: \"ic-word\",\n word_document: \"ic-word\",\n markdown: \"ic-md\",\n pdf: \"ic-pdf\",\n html: \"ic-html\",\n web_page: \"ic-html\",\n yaml: \"ic-yaml\",\n json: \"ic-json\",\n\n // Spreadsheets\n spreadsheet: \"ic-excel\",\n table: \"ic-table\",\n\n // Media\n image: \"ic-img\",\n audio: \"ic-audio\",\n video: \"ic-video\",\n voice_memo: \"ic-voice_memo\",\n\n // Presentations\n powerpoint_deck: \"ic-power_point\",\n presentation_pptx_studio: \"ic-power_point\",\n pptx: \"ic-power_point\",\n\n // Email & Calendar\n email: \"ic-mail\",\n email_message: \"ic-mail\",\n live_email_thread: \"ic-mail\",\n live_calendar_event: \"ic-mail\",\n\n // Code\n python: \"ic-py\",\n javascript: \"ic-js\",\n typescript: \"ic-code\",\n jsx: \"ic-code\",\n tsx: \"ic-code\",\n css: \"ic-code\",\n java: \"ic-code\",\n c: \"ic-code\",\n cpp: \"ic-code\",\n csharp: \"ic-code\",\n ruby: \"ic-code\",\n go: \"ic-code\",\n swift: \"ic-code\",\n php: \"ic-code\",\n rust: \"ic-code\",\n vue: \"ic-code\",\n wm_script: \"ic-code\",\n\n // Structured data\n database: \"ic-snippet\",\n schema: \"ic-schema\",\n catalog: \"ic-db\",\n drive: \"ic-db\",\n query_snippet: \"ic-snippet\",\n semantic_model: \"ic-db\",\n dataset: \"ic-db\",\n\n // Meetings & Calls\n meeting: \"ic-meeting\",\n video_session: \"ic-meeting\",\n phone_call: \"ic-phonecall\",\n\n // Sessions & Devices\n session: \"ic-session\",\n browse_session: \"ic-html\",\n computer: \"ic-computer\",\n desktop_session: \"ic-desktop_session\",\n mobile_session: \"ic-mobile_session\",\n\n // Projects & Profiles\n project: \"ic-project\",\n browse_profile: \"ic-profile\",\n\n // Workflows & Automation\n aop: \"ic-flow\",\n playbook: \"ic-playbook\",\n policy: \"ic-policy\",\n flow: \"ic-flow\",\n transform_project: \"ic-transform_project\",\n\n // Collections & Notebooks\n collection: \"ic-collection\",\n notebook: \"ic-notebook\",\n\n // UI & Apps\n user_interface: \"ic-app\",\n application: \"ic-application\",\n canvas: \"ic-canvas\",\n dashboard: \"ic-dashboard\",\n figure: \"ic_figure\",\n\n // People & Companies\n person: \"ic-person\",\n company: \"ic-company\",\n\n // Misc\n prompt: \"ic-ai\",\n skill: \"ic-skill\",\n task_item: \"ic-task\",\n spaces: \"ic-spaces\",\n secret: \"ic-secret\",\n photoshop: \"ic-pts\",\n illustrator: \"ic-ai\",\n zip: \"ic-zip\",\n sevenzip: \"ic-zip\",\n\n // Google Drive / SharePoint / Salesforce\n gdrive_folder: \"ic-folder\",\n gdrive_file: \"ic-file\",\n salesforce_record: \"ic-db\",\n salesforce_file: \"ic-db\",\n};\n\nconst ASSET_TYPE_LUCIDE_FALLBACK: Record<string, string> = {\n folder: \"folder\",\n spreadsheet: \"sheet\",\n image: \"image\",\n video: \"video\",\n audio: \"headphones\",\n email: \"mail\",\n database: \"database\",\n project: \"folder-kanban\",\n meeting: \"video\",\n user_interface: \"layout\",\n};\n\n/**\n * Get the SVG thumbnail URL for an Athena asset type, or undefined when the\n * host app does not bundle the icon files.\n */\nexport function assetTypeToThumb(\n assetType: string | null | undefined,\n): string | undefined {\n if (!iconBasePath) return undefined;\n const name: string =\n (assetType ? ASSET_TYPE_ICON_FILE[assetType.toLowerCase()] : undefined) ??\n \"ic-file\";\n return `${iconBasePath}${name}.svg`;\n}\n\n/**\n * Get Lucide icon name fallback for an asset type.\n * Used when thumbnailUrl can't load.\n */\nexport function assetTypeToIcon(assetType: string | null | undefined): string {\n if (!assetType) return \"file\";\n return ASSET_TYPE_LUCIDE_FALLBACK[assetType.toLowerCase()] ?? \"file\";\n}\n"],"names":[],"mappings":"AAQA,IAAI,eAA8B;AAO3B,SAAS,2BAA2B;AAAA,EACzC;AACF,GAES;AACP,iBAAe,WAAW,SAAS,QAAQ,QAAQ,GAAG,IAAI;AAC5D;AAEA,MAAM,uBAA+C;AAAA;AAAA,EAEnD,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,UAAU;AAAA,EACV,eAAe;AAAA,EACf,UAAU;AAAA,EACV,KAAK;AAAA,EACL,MAAM;AAAA,EACN,UAAU;AAAA,EACV,MAAM;AAAA,EACN,MAAM;AAAA;AAAA,EAGN,aAAa;AAAA,EACb,OAAO;AAAA;AAAA,EAGP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,YAAY;AAAA;AAAA,EAGZ,iBAAiB;AAAA,EACjB,0BAA0B;AAAA,EAC1B,MAAM;AAAA;AAAA,EAGN,OAAO;AAAA,EACP,eAAe;AAAA,EACf,mBAAmB;AAAA,EACnB,qBAAqB;AAAA;AAAA,EAGrB,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,KAAK;AAAA,EACL,KAAK;AAAA,EACL,KAAK;AAAA,EACL,MAAM;AAAA,EACN,GAAG;AAAA,EACH,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,KAAK;AAAA,EACL,MAAM;AAAA,EACN,KAAK;AAAA,EACL,WAAW;AAAA;AAAA,EAGX,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,OAAO;AAAA,EACP,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,SAAS;AAAA;AAAA,EAGT,SAAS;AAAA,EACT,eAAe;AAAA,EACf,YAAY;AAAA;AAAA,EAGZ,SAAS;AAAA,EACT,gBAAgB;AAAA,EAChB,UAAU;AAAA,EACV,iBAAiB;AAAA,EACjB,gBAAgB;AAAA;AAAA,EAGhB,SAAS;AAAA,EACT,gBAAgB;AAAA;AAAA,EAGhB,KAAK;AAAA,EACL,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,mBAAmB;AAAA;AAAA,EAGnB,YAAY;AAAA,EACZ,UAAU;AAAA;AAAA,EAGV,gBAAgB;AAAA,EAChB,aAAa;AAAA,EACb,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,QAAQ;AAAA;AAAA,EAGR,QAAQ;AAAA,EACR,SAAS;AAAA;AAAA,EAGT,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,WAAW;AAAA,EACX,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,aAAa;AAAA,EACb,KAAK;AAAA,EACL,UAAU;AAAA;AAAA,EAGV,eAAe;AAAA,EACf,aAAa;AAAA,EACb,mBAAmB;AAAA,EACnB,iBAAiB;AACnB;AAEA,MAAM,6BAAqD;AAAA,EACzD,QAAQ;AAAA,EACR,aAAa;AAAA,EACb,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,OAAO;AAAA,EACP,UAAU;AAAA,EACV,SAAS;AAAA,EACT,SAAS;AAAA,EACT,gBAAgB;AAClB;AAMO,SAAS,iBACd,WACoB;AACpB,MAAI,CAAC,aAAc,QAAO;AAC1B,QAAM,QACH,YAAY,qBAAqB,UAAU,YAAA,CAAa,IAAI,WAC7D;AACF,SAAO,GAAG,YAAY,GAAG,IAAI;AAC/B;AAMO,SAAS,gBAAgB,WAA8C;AAC5E,MAAI,CAAC,UAAW,QAAO;AACvB,SAAO,2BAA2B,UAAU,YAAA,CAAa,KAAK;AAChE;"}
|
|
@@ -299,6 +299,7 @@ const ComposerSendButton = ({
|
|
|
299
299
|
children: action === "queue" ? /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ListPlusIcon, { className: "size-4" }) : /* @__PURE__ */ jsxRuntime.jsx(lucideReact.ArrowUpIcon, { className: "size-4" })
|
|
300
300
|
}
|
|
301
301
|
);
|
|
302
|
+
exports.ACTION_BAR_REVEAL_CLASS = ACTION_BAR_REVEAL_CLASS;
|
|
302
303
|
exports.BranchPicker = BranchPicker;
|
|
303
304
|
exports.COMPOSER_DOCK_CLASS = COMPOSER_DOCK_CLASS;
|
|
304
305
|
exports.COMPOSER_EDITOR_ROW_CLASS = COMPOSER_EDITOR_ROW_CLASS;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message-components.cjs","sources":["../../../src/chat-ui/messages/message-components.tsx"],"sourcesContent":["import {\n ActionBarPrimitive,\n AuiIf,\n BranchPickerPrimitive,\n MessagePrimitive,\n useAuiState,\n useMessagePartText,\n useSmooth,\n type ToolCallMessagePartComponent,\n} from \"@assistant-ui/react\";\nimport {\n hideUnterminatedMarkdownLink,\n isVoiceDelegationMessage,\n readRuntimeMessageFromSourceMessages,\n readSoleRuntimeMessageKind,\n} from \"@athenaintel/agent-runtime\";\nimport \"@assistant-ui/react-markdown/styles/dot.css\";\nimport {\n ArrowUpIcon,\n CheckIcon,\n ChevronLeftIcon,\n ChevronRightIcon,\n CopyIcon,\n ListPlusIcon,\n PencilIcon,\n RefreshCwIcon,\n} from \"lucide-react\";\nimport {\n type ButtonHTMLAttributes,\n type FC,\n type ReactNode,\n useMemo,\n} from \"react\";\nimport { useAthenaRunLive } from \"../../chat/use-athena-run-live\";\nimport type { ComposerAction } from \"../composer/composer-action\";\nimport { cn } from \"../../lib/utils\";\nimport { ChatMessageBody } from \"../rich-text/chat-message-body\";\nimport { useMessageActionsReadOnly } from \"./message-actions-config\";\nimport { RuntimeMessageCard } from \"./runtime-message\";\nimport { hasVisibleContent } from \"./running-indicator\";\nimport { VoiceDelegationMessage } from \"./voice-delegation-card\";\n\nexport function IconButton({\n children,\n tooltip,\n className,\n ...props\n}: ButtonHTMLAttributes<HTMLButtonElement> & { tooltip: string }) {\n return (\n <button\n type=\"button\"\n title={tooltip}\n aria-label={tooltip}\n className={cn(\n \"inline-flex size-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:bg-accent hover:text-foreground\",\n className,\n )}\n {...props}\n >\n {children}\n </button>\n );\n}\n\nexport function SmallIconButton({\n children,\n tooltip,\n className,\n ...props\n}: ButtonHTMLAttributes<HTMLButtonElement> & { tooltip: string }) {\n return (\n <button\n type=\"button\"\n title={tooltip}\n aria-label={tooltip}\n className={cn(\n \"inline-flex size-6 items-center justify-center rounded text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground\",\n className,\n )}\n {...props}\n >\n {children}\n </button>\n );\n}\n\nexport const BranchPicker: FC = () => (\n <BranchPickerPrimitive.Root\n hideWhenSingleBranch\n className=\"inline-flex items-center gap-0.5 text-xs text-muted-foreground\"\n data-testid=\"chat-branch-picker\"\n >\n <BranchPickerPrimitive.Previous asChild>\n <SmallIconButton\n tooltip=\"Previous branch\"\n data-testid=\"chat-branch-previous\"\n >\n <ChevronLeftIcon className=\"size-3\" />\n </SmallIconButton>\n </BranchPickerPrimitive.Previous>\n <span className=\"font-medium\" data-testid=\"chat-branch-count\">\n <BranchPickerPrimitive.Number /> / <BranchPickerPrimitive.Count />\n </span>\n <BranchPickerPrimitive.Next asChild>\n <SmallIconButton tooltip=\"Next branch\" data-testid=\"chat-branch-next\">\n <ChevronRightIcon className=\"size-3\" />\n </SmallIconButton>\n </BranchPickerPrimitive.Next>\n </BranchPickerPrimitive.Root>\n);\n\nconst CopyActionButton: FC = () => (\n <ActionBarPrimitive.Copy asChild>\n <SmallIconButton tooltip=\"Copy\">\n <AuiIf condition={(state) => state.message.isCopied}>\n <CheckIcon className=\"size-3\" />\n </AuiIf>\n <AuiIf condition={(state) => !state.message.isCopied}>\n <CopyIcon className=\"size-3\" />\n </AuiIf>\n </SmallIconButton>\n </ActionBarPrimitive.Copy>\n);\n\n/**\n * The edit primitive does not check the runtime's edit capability itself —\n * clicking it on a runtime without one throws inside onPress, where no error\n * boundary can catch it — so the button must gate on the capability and, to\n * match the rewind semantics of `run/edit`, stay hidden while a run is live.\n * The read-only context covers threads the capability flags cannot: a host's\n * static `edit: true` still applies to fenced legacy conversations.\n */\nconst EditActionButton: FC = () => {\n const allowEdit = useAuiState((s) => s.thread.capabilities.edit);\n const isRunning = useAthenaRunLive();\n const readOnly = useMessageActionsReadOnly();\n if (!allowEdit || isRunning || readOnly) return null;\n return (\n <ActionBarPrimitive.Edit asChild>\n <SmallIconButton tooltip=\"Edit\" data-testid=\"chat-message-edit\">\n <PencilIcon className=\"size-3\" />\n </SmallIconButton>\n </ActionBarPrimitive.Edit>\n );\n};\n\n/** Regenerate dispatches `run/reload`, so it hides on read-only threads too. */\nconst RegenerateActionButton: FC = () => {\n const readOnly = useMessageActionsReadOnly();\n if (readOnly) return null;\n return (\n <ActionBarPrimitive.Reload asChild>\n <SmallIconButton tooltip=\"Regenerate\">\n <RefreshCwIcon className=\"size-3\" />\n </SmallIconButton>\n </ActionBarPrimitive.Reload>\n );\n};\n\n/**\n * Reveal-on-demand treatment for action bars: invisible and click-through\n * until the surrounding named group is hovered or a control inside receives\n * keyboard focus. The `focus-within` escape hatch is what keeps the hidden\n * controls reachable for keyboard users.\n */\nconst ACTION_BAR_REVEAL_CLASS =\n \"pointer-events-none opacity-0 transition-opacity focus-within:pointer-events-auto focus-within:opacity-100\";\n\n/** Shared chat body; the reveal holds incomplete links until their URL is complete. */\nexport const MarkdownText: FC = () => {\n const revealed = useSmooth(useMessagePartText(), true);\n const isRunning = revealed.status.type === \"running\";\n const text = isRunning ? hideUnterminatedMarkdownLink(revealed.text) : revealed.text;\n return <ChatMessageBody text={text} isRunning={isRunning} />;\n};\n\nconst UserActionBar: FC = () => (\n <ActionBarPrimitive.Root\n autohide=\"never\"\n className={cn(\n \"flex min-h-6 items-center gap-0.5\",\n ACTION_BAR_REVEAL_CLASS,\n \"group-hover/user-message:pointer-events-auto group-hover/user-message:opacity-100\",\n )}\n >\n <CopyActionButton />\n <EditActionButton />\n </ActionBarPrimitive.Root>\n);\n\nexport const UserMessage: FC = () => {\n // A voice delegation's anchor is the ask the live voice model handed to the\n // thread, not words the user typed: it renders as the shared voice-task\n // card on every host instead of a second user bubble under the spoken turn.\n const isVoiceDelegation = useAuiState((s) =>\n isVoiceDelegationMessage({ messageId: s.message.id, custom: s.message.metadata?.custom }),\n );\n if (isVoiceDelegation) {\n return (\n <MessagePrimitive.Root data-message-role=\"user\" className=\"mb-3\">\n <VoiceDelegationMessage />\n </MessagePrimitive.Root>\n );\n }\n return (\n <MessagePrimitive.Root\n data-message-role=\"user\"\n className=\"group/user-message mb-3 flex justify-end\"\n >\n <div className=\"flex min-w-0 max-w-[85%] flex-col items-end gap-1\">\n <div className=\"min-w-0 max-w-full rounded-2xl rounded-br-md bg-muted px-3.5 py-2 text-sm text-foreground\">\n <MessagePrimitive.Content components={{ Text: MarkdownText }} />\n </div>\n <div className=\"flex min-h-6 items-center gap-1\">\n <BranchPicker />\n <UserActionBar />\n </div>\n </div>\n </MessagePrimitive.Root>\n );\n};\n\nexport interface CreateAssistantMessageOptions {\n /** Host-registered card for tools without a dedicated UI. */\n toolFallback: ToolCallMessagePartComponent;\n /** Extra action-bar controls appended after copy/regenerate. */\n extraActions?: ReactNode;\n /**\n * Renders the message body. Hosts that group content into activity\n * timelines supply their own; the default renders markdown and tool cards.\n */\n content?: FC;\n /**\n * Inline affordance rendered inside a runtime-ending card (e.g. a Continue\n * button). Hosts without one leave it unset.\n */\n runtimeMessageAction?: ReactNode;\n}\n\n/**\n * Builds the assistant bubble. Call this once per host (memoized on its\n * inputs) so the returned component identity stays stable across renders.\n */\nexport function createAssistantMessage({\n toolFallback,\n extraActions,\n content: Content,\n runtimeMessageAction,\n}: CreateAssistantMessageOptions): FC {\n const AssistantActionBar: FC = () => {\n // The latest reply keeps its actions visible; older replies reveal them\n // on hover so a long transcript is not a wall of icon rows.\n const isLast = useAuiState((s) => s.message.isLast);\n return (\n <ActionBarPrimitive.Root\n autohide=\"never\"\n className={cn(\n \"mt-1 flex min-h-6 items-center gap-0.5\",\n !isLast && [\n ACTION_BAR_REVEAL_CLASS,\n \"group-hover/assistant-message:pointer-events-auto group-hover/assistant-message:opacity-100\",\n ],\n )}\n >\n <CopyActionButton />\n <RegenerateActionButton />\n {extraActions}\n </ActionBarPrimitive.Root>\n );\n };\n\n // A run-lifecycle marker or handoff summary is a system event, not\n // assistant speech. When it owns the whole row, render the status card in\n // place of the bubble; when it is chunked in with the assistant's own work\n // (or is a handoff whose text IS the closing summary), keep the body and\n // frame it with the card above.\n const RuntimeEnding: FC<{ placement: \"row\" | \"banner\" }> = ({ placement }) => {\n // Select the message (a stable store reference) and derive from it: the\n // reader allocates a fresh object per call, and `useAuiState` compares\n // snapshots with `Object.is`, so selecting the reader's result directly\n // would re-render on every store update and trip React's update-depth\n // guard.\n const message = useAuiState((s) => s.message);\n const runtime = useMemo(() => readRuntimeMessageFromSourceMessages(message), [message]);\n if (!runtime || runtime.silent) return null;\n if (placement === \"row\" && !runtime.isSoleSourceMessage) return null;\n if (placement === \"banner\" && runtime.isSoleSourceMessage && runtime.kind !== \"handoff\") {\n return null;\n }\n return <RuntimeMessageCard message={runtime} action={runtimeMessageAction} />;\n };\n\n const AssistantMessage: FC = () => {\n // An assistant row exists before its first token streams; showing\n // copy/regenerate against nothing looks broken, so wait for content.\n const showActions = useAuiState((state) =>\n hasVisibleContent(state.message.content),\n );\n // Primitive selector: the reader builds a fresh object per call.\n const soleRuntimeKind = useAuiState((s) => readSoleRuntimeMessageKind(s.message));\n const soleRuntimeSilent = useAuiState(\n (s) => readRuntimeMessageFromSourceMessages(s.message)?.silent === true,\n );\n\n if (soleRuntimeKind && soleRuntimeKind !== \"handoff\") {\n if (soleRuntimeSilent) return null;\n return (\n <MessagePrimitive.Root\n data-message-role=\"assistant\"\n className=\"group group/assistant-message mb-3\"\n >\n <div className=\"max-w-[95%]\">\n <RuntimeEnding placement=\"row\" />\n </div>\n </MessagePrimitive.Root>\n );\n }\n\n return (\n <MessagePrimitive.Root\n data-message-role=\"assistant\"\n className=\"group group/assistant-message mb-3\"\n >\n <div className=\"max-w-[95%]\">\n <RuntimeEnding placement=\"banner\" />\n {Content ? (\n <Content />\n ) : (\n <MessagePrimitive.Content\n components={{\n Text: MarkdownText,\n tools: { Fallback: toolFallback },\n }}\n />\n )}\n {showActions ? (\n <div className=\"flex min-h-6 items-center gap-1\">\n <BranchPicker />\n <AssistantActionBar />\n </div>\n ) : null}\n </div>\n </MessagePrimitive.Root>\n );\n };\n\n return AssistantMessage;\n}\n\n/** Panel chrome: the thread card and the header row that sits inside it. */\nexport const THREAD_PANEL_CLASS =\n \"m-1 flex min-h-0 flex-1 flex-col overflow-hidden rounded-[18px] border border-dashed border-amber-500 bg-background shadow-[0_1px_10px_rgba(54,45,33,0.08)]\";\nexport const THREAD_HEADER_CLASS =\n \"flex items-center justify-between gap-2 px-3 py-2\";\nexport const THREAD_HEADER_ACTIONS_CLASS =\n \"flex min-w-0 items-center justify-end gap-1.5\";\n/** Pill used for the header's leading control (agent picker, host label). */\nexport const THREAD_HEADER_PILL_CLASS =\n \"inline-flex h-7 max-w-[170px] items-center gap-1.5 rounded-md border border-neutral-200 bg-white px-2 text-xs font-medium text-neutral-800 shadow-sm\";\nexport const THREAD_HEADER_ICON_CLASS = \"size-[18px]\";\n\n/** Composer chrome: the dock around the composer, its surface and its rows. */\nexport const COMPOSER_DOCK_CLASS = \"bg-background px-2.5 pb-2 pt-1.5\";\nexport const COMPOSER_SURFACE_CLASS =\n \"relative flex flex-col gap-1 rounded-xl border border-neutral-200 bg-white shadow-[0_2px_10px_rgba(54,45,33,0.08)]\";\nexport const COMPOSER_EDITOR_ROW_CLASS = \"px-2.5 pt-1\";\nexport const COMPOSER_TOOLBAR_CLASS =\n \"flex items-center gap-1 border-t border-neutral-100 px-2 py-1.5\";\nexport const THREAD_SCROLL_TO_BOTTOM_CLASS =\n \"inline-flex items-center justify-center rounded-full border bg-background/80 p-1 shadow-sm backdrop-blur transition-opacity hover:bg-accent disabled:invisible\";\n\nconst ComposerStopIcon: FC = () => (\n <svg\n aria-hidden=\"true\"\n className=\"size-4\"\n viewBox=\"0 0 16 16\"\n fill=\"currentColor\"\n >\n <rect width=\"10\" height=\"10\" x=\"3\" y=\"3\" rx=\"2\" />\n </svg>\n);\n\nexport interface ComposerStopButtonProps {\n onStop: () => void;\n disabled?: boolean;\n title?: string;\n}\n\nexport interface ComposerSendButtonProps {\n action: Extract<ComposerAction, \"send\" | \"queue\">;\n onSend: () => void;\n disabled?: boolean;\n title?: string;\n}\n\n/** Stop control shown while a run is in flight and there is nothing queued. */\nexport const ComposerStopButton: FC<ComposerStopButtonProps> = ({\n onStop,\n disabled = false,\n title = \"Stop generation\",\n}) => (\n <button\n type=\"button\"\n onClick={onStop}\n disabled={disabled}\n title={title}\n className={cn(\n \"inline-flex size-8 shrink-0 items-center justify-center rounded-lg bg-foreground text-background shadow-sm transition-colors hover:bg-foreground/80\",\n disabled && \"cursor-not-allowed opacity-60\",\n )}\n >\n <ComposerStopIcon />\n </button>\n);\n/** Send control, which becomes a queue control while a run is in flight. */\nexport const ComposerSendButton: FC<ComposerSendButtonProps> = ({\n action,\n onSend,\n disabled = false,\n title,\n}) => (\n <button\n type=\"button\"\n onClick={onSend}\n disabled={disabled}\n title={title ?? (action === \"queue\" ? \"Queue message\" : \"Send\")}\n className={cn(\n \"inline-flex size-8 shrink-0 items-center justify-center rounded-full shadow-sm transition-colors\",\n disabled\n ? \"cursor-not-allowed bg-muted text-muted-foreground opacity-60\"\n : \"bg-foreground text-background hover:bg-foreground/80\",\n )}\n >\n {action === \"queue\" ? (\n <ListPlusIcon className=\"size-4\" />\n ) : (\n <ArrowUpIcon className=\"size-4\" />\n )}\n </button>\n);\n"],"names":["jsx","cn","jsxs","BranchPickerPrimitive","ChevronLeftIcon","ChevronRightIcon","ActionBarPrimitive","AuiIf","CheckIcon","CopyIcon","useAuiState","useAthenaRunLive","useMessageActionsReadOnly","PencilIcon","RefreshCwIcon","useSmooth","useMessagePartText","hideUnterminatedMarkdownLink","ChatMessageBody","isVoiceDelegationMessage","MessagePrimitive","VoiceDelegationMessage","useMemo","readRuntimeMessageFromSourceMessages","RuntimeMessageCard","hasVisibleContent","readSoleRuntimeMessageKind","ListPlusIcon","ArrowUpIcon"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"message-components.cjs","sources":["../../../src/chat-ui/messages/message-components.tsx"],"sourcesContent":["import {\n ActionBarPrimitive,\n AuiIf,\n BranchPickerPrimitive,\n MessagePrimitive,\n useAuiState,\n useMessagePartText,\n useSmooth,\n type ToolCallMessagePartComponent,\n} from \"@assistant-ui/react\";\nimport {\n hideUnterminatedMarkdownLink,\n isVoiceDelegationMessage,\n readRuntimeMessageFromSourceMessages,\n readSoleRuntimeMessageKind,\n} from \"@athenaintel/agent-runtime\";\nimport \"@assistant-ui/react-markdown/styles/dot.css\";\nimport {\n ArrowUpIcon,\n CheckIcon,\n ChevronLeftIcon,\n ChevronRightIcon,\n CopyIcon,\n ListPlusIcon,\n PencilIcon,\n RefreshCwIcon,\n} from \"lucide-react\";\nimport {\n type ButtonHTMLAttributes,\n type FC,\n type ReactNode,\n useMemo,\n} from \"react\";\nimport { useAthenaRunLive } from \"../../chat/use-athena-run-live\";\nimport type { ComposerAction } from \"../composer/composer-action\";\nimport { cn } from \"../../lib/utils\";\nimport { ChatMessageBody } from \"../rich-text/chat-message-body\";\nimport { useMessageActionsReadOnly } from \"./message-actions-config\";\nimport { RuntimeMessageCard } from \"./runtime-message\";\nimport { hasVisibleContent } from \"./running-indicator\";\nimport { VoiceDelegationMessage } from \"./voice-delegation-card\";\n\nexport function IconButton({\n children,\n tooltip,\n className,\n ...props\n}: ButtonHTMLAttributes<HTMLButtonElement> & { tooltip: string }) {\n return (\n <button\n type=\"button\"\n title={tooltip}\n aria-label={tooltip}\n className={cn(\n \"inline-flex size-9 items-center justify-center rounded-lg text-muted-foreground transition-colors hover:bg-accent hover:text-foreground\",\n className,\n )}\n {...props}\n >\n {children}\n </button>\n );\n}\n\nexport function SmallIconButton({\n children,\n tooltip,\n className,\n ...props\n}: ButtonHTMLAttributes<HTMLButtonElement> & { tooltip: string }) {\n return (\n <button\n type=\"button\"\n title={tooltip}\n aria-label={tooltip}\n className={cn(\n \"inline-flex size-6 items-center justify-center rounded text-muted-foreground transition-colors hover:bg-accent hover:text-accent-foreground\",\n className,\n )}\n {...props}\n >\n {children}\n </button>\n );\n}\n\nexport const BranchPicker: FC = () => (\n <BranchPickerPrimitive.Root\n hideWhenSingleBranch\n className=\"inline-flex items-center gap-0.5 text-xs text-muted-foreground\"\n data-testid=\"chat-branch-picker\"\n >\n <BranchPickerPrimitive.Previous asChild>\n <SmallIconButton\n tooltip=\"Previous branch\"\n data-testid=\"chat-branch-previous\"\n >\n <ChevronLeftIcon className=\"size-3\" />\n </SmallIconButton>\n </BranchPickerPrimitive.Previous>\n <span className=\"font-medium\" data-testid=\"chat-branch-count\">\n <BranchPickerPrimitive.Number /> / <BranchPickerPrimitive.Count />\n </span>\n <BranchPickerPrimitive.Next asChild>\n <SmallIconButton tooltip=\"Next branch\" data-testid=\"chat-branch-next\">\n <ChevronRightIcon className=\"size-3\" />\n </SmallIconButton>\n </BranchPickerPrimitive.Next>\n </BranchPickerPrimitive.Root>\n);\n\nconst CopyActionButton: FC = () => (\n <ActionBarPrimitive.Copy asChild>\n <SmallIconButton tooltip=\"Copy\">\n <AuiIf condition={(state) => state.message.isCopied}>\n <CheckIcon className=\"size-3\" />\n </AuiIf>\n <AuiIf condition={(state) => !state.message.isCopied}>\n <CopyIcon className=\"size-3\" />\n </AuiIf>\n </SmallIconButton>\n </ActionBarPrimitive.Copy>\n);\n\n/**\n * The edit primitive does not check the runtime's edit capability itself —\n * clicking it on a runtime without one throws inside onPress, where no error\n * boundary can catch it — so the button must gate on the capability and, to\n * match the rewind semantics of `run/edit`, stay hidden while a run is live.\n * The read-only context covers threads the capability flags cannot: a host's\n * static `edit: true` still applies to fenced legacy conversations.\n */\nconst EditActionButton: FC = () => {\n const allowEdit = useAuiState((s) => s.thread.capabilities.edit);\n const isRunning = useAthenaRunLive();\n const readOnly = useMessageActionsReadOnly();\n if (!allowEdit || isRunning || readOnly) return null;\n return (\n <ActionBarPrimitive.Edit asChild>\n <SmallIconButton tooltip=\"Edit\" data-testid=\"chat-message-edit\">\n <PencilIcon className=\"size-3\" />\n </SmallIconButton>\n </ActionBarPrimitive.Edit>\n );\n};\n\n/** Regenerate dispatches `run/reload`, so it hides on read-only threads too. */\nconst RegenerateActionButton: FC = () => {\n const readOnly = useMessageActionsReadOnly();\n if (readOnly) return null;\n return (\n <ActionBarPrimitive.Reload asChild>\n <SmallIconButton tooltip=\"Regenerate\">\n <RefreshCwIcon className=\"size-3\" />\n </SmallIconButton>\n </ActionBarPrimitive.Reload>\n );\n};\n\n/**\n * Reveal-on-demand treatment for action bars: invisible and click-through\n * until the surrounding named group is hovered or a control inside receives\n * keyboard focus. The `focus-within` escape hatch is what keeps the hidden\n * controls reachable for keyboard users.\n */\nexport const ACTION_BAR_REVEAL_CLASS =\n \"pointer-events-none opacity-0 transition-opacity focus-within:pointer-events-auto focus-within:opacity-100\";\n\n/** Shared chat body; the reveal holds incomplete links until their URL is complete. */\nexport const MarkdownText: FC = () => {\n const revealed = useSmooth(useMessagePartText(), true);\n const isRunning = revealed.status.type === \"running\";\n const text = isRunning ? hideUnterminatedMarkdownLink(revealed.text) : revealed.text;\n return <ChatMessageBody text={text} isRunning={isRunning} />;\n};\n\nconst UserActionBar: FC = () => (\n <ActionBarPrimitive.Root\n autohide=\"never\"\n className={cn(\n \"flex min-h-6 items-center gap-0.5\",\n ACTION_BAR_REVEAL_CLASS,\n \"group-hover/user-message:pointer-events-auto group-hover/user-message:opacity-100\",\n )}\n >\n <CopyActionButton />\n <EditActionButton />\n </ActionBarPrimitive.Root>\n);\n\nexport const UserMessage: FC = () => {\n // A voice delegation's anchor is the ask the live voice model handed to the\n // thread, not words the user typed: it renders as the shared voice-task\n // card on every host instead of a second user bubble under the spoken turn.\n const isVoiceDelegation = useAuiState((s) =>\n isVoiceDelegationMessage({ messageId: s.message.id, custom: s.message.metadata?.custom }),\n );\n if (isVoiceDelegation) {\n return (\n <MessagePrimitive.Root data-message-role=\"user\" className=\"mb-3\">\n <VoiceDelegationMessage />\n </MessagePrimitive.Root>\n );\n }\n return (\n <MessagePrimitive.Root\n data-message-role=\"user\"\n className=\"group/user-message mb-3 flex justify-end\"\n >\n <div className=\"flex min-w-0 max-w-[85%] flex-col items-end gap-1\">\n <div className=\"min-w-0 max-w-full rounded-2xl rounded-br-md bg-muted px-3.5 py-2 text-sm text-foreground\">\n <MessagePrimitive.Content components={{ Text: MarkdownText }} />\n </div>\n <div className=\"flex min-h-6 items-center gap-1\">\n <BranchPicker />\n <UserActionBar />\n </div>\n </div>\n </MessagePrimitive.Root>\n );\n};\n\nexport interface CreateAssistantMessageOptions {\n /** Host-registered card for tools without a dedicated UI. */\n toolFallback: ToolCallMessagePartComponent;\n /** Extra action-bar controls appended after copy/regenerate. */\n extraActions?: ReactNode;\n /**\n * Renders the message body. Hosts that group content into activity\n * timelines supply their own; the default renders markdown and tool cards.\n */\n content?: FC;\n /**\n * Inline affordance rendered inside a runtime-ending card (e.g. a Continue\n * button). Hosts without one leave it unset.\n */\n runtimeMessageAction?: ReactNode;\n}\n\n/**\n * Builds the assistant bubble. Call this once per host (memoized on its\n * inputs) so the returned component identity stays stable across renders.\n */\nexport function createAssistantMessage({\n toolFallback,\n extraActions,\n content: Content,\n runtimeMessageAction,\n}: CreateAssistantMessageOptions): FC {\n const AssistantActionBar: FC = () => {\n // The latest reply keeps its actions visible; older replies reveal them\n // on hover so a long transcript is not a wall of icon rows.\n const isLast = useAuiState((s) => s.message.isLast);\n return (\n <ActionBarPrimitive.Root\n autohide=\"never\"\n className={cn(\n \"mt-1 flex min-h-6 items-center gap-0.5\",\n !isLast && [\n ACTION_BAR_REVEAL_CLASS,\n \"group-hover/assistant-message:pointer-events-auto group-hover/assistant-message:opacity-100\",\n ],\n )}\n >\n <CopyActionButton />\n <RegenerateActionButton />\n {extraActions}\n </ActionBarPrimitive.Root>\n );\n };\n\n // A run-lifecycle marker or handoff summary is a system event, not\n // assistant speech. When it owns the whole row, render the status card in\n // place of the bubble; when it is chunked in with the assistant's own work\n // (or is a handoff whose text IS the closing summary), keep the body and\n // frame it with the card above.\n const RuntimeEnding: FC<{ placement: \"row\" | \"banner\" }> = ({ placement }) => {\n // Select the message (a stable store reference) and derive from it: the\n // reader allocates a fresh object per call, and `useAuiState` compares\n // snapshots with `Object.is`, so selecting the reader's result directly\n // would re-render on every store update and trip React's update-depth\n // guard.\n const message = useAuiState((s) => s.message);\n const runtime = useMemo(() => readRuntimeMessageFromSourceMessages(message), [message]);\n if (!runtime || runtime.silent) return null;\n if (placement === \"row\" && !runtime.isSoleSourceMessage) return null;\n if (placement === \"banner\" && runtime.isSoleSourceMessage && runtime.kind !== \"handoff\") {\n return null;\n }\n return <RuntimeMessageCard message={runtime} action={runtimeMessageAction} />;\n };\n\n const AssistantMessage: FC = () => {\n // An assistant row exists before its first token streams; showing\n // copy/regenerate against nothing looks broken, so wait for content.\n const showActions = useAuiState((state) =>\n hasVisibleContent(state.message.content),\n );\n // Primitive selector: the reader builds a fresh object per call.\n const soleRuntimeKind = useAuiState((s) => readSoleRuntimeMessageKind(s.message));\n const soleRuntimeSilent = useAuiState(\n (s) => readRuntimeMessageFromSourceMessages(s.message)?.silent === true,\n );\n\n if (soleRuntimeKind && soleRuntimeKind !== \"handoff\") {\n if (soleRuntimeSilent) return null;\n return (\n <MessagePrimitive.Root\n data-message-role=\"assistant\"\n className=\"group group/assistant-message mb-3\"\n >\n <div className=\"max-w-[95%]\">\n <RuntimeEnding placement=\"row\" />\n </div>\n </MessagePrimitive.Root>\n );\n }\n\n return (\n <MessagePrimitive.Root\n data-message-role=\"assistant\"\n className=\"group group/assistant-message mb-3\"\n >\n <div className=\"max-w-[95%]\">\n <RuntimeEnding placement=\"banner\" />\n {Content ? (\n <Content />\n ) : (\n <MessagePrimitive.Content\n components={{\n Text: MarkdownText,\n tools: { Fallback: toolFallback },\n }}\n />\n )}\n {showActions ? (\n <div className=\"flex min-h-6 items-center gap-1\">\n <BranchPicker />\n <AssistantActionBar />\n </div>\n ) : null}\n </div>\n </MessagePrimitive.Root>\n );\n };\n\n return AssistantMessage;\n}\n\n/** Panel chrome: the thread card and the header row that sits inside it. */\nexport const THREAD_PANEL_CLASS =\n \"m-1 flex min-h-0 flex-1 flex-col overflow-hidden rounded-[18px] border border-dashed border-amber-500 bg-background shadow-[0_1px_10px_rgba(54,45,33,0.08)]\";\nexport const THREAD_HEADER_CLASS =\n \"flex items-center justify-between gap-2 px-3 py-2\";\nexport const THREAD_HEADER_ACTIONS_CLASS =\n \"flex min-w-0 items-center justify-end gap-1.5\";\n/** Pill used for the header's leading control (agent picker, host label). */\nexport const THREAD_HEADER_PILL_CLASS =\n \"inline-flex h-7 max-w-[170px] items-center gap-1.5 rounded-md border border-neutral-200 bg-white px-2 text-xs font-medium text-neutral-800 shadow-sm\";\nexport const THREAD_HEADER_ICON_CLASS = \"size-[18px]\";\n\n/** Composer chrome: the dock around the composer, its surface and its rows. */\nexport const COMPOSER_DOCK_CLASS = \"bg-background px-2.5 pb-2 pt-1.5\";\nexport const COMPOSER_SURFACE_CLASS =\n \"relative flex flex-col gap-1 rounded-xl border border-neutral-200 bg-white shadow-[0_2px_10px_rgba(54,45,33,0.08)]\";\nexport const COMPOSER_EDITOR_ROW_CLASS = \"px-2.5 pt-1\";\nexport const COMPOSER_TOOLBAR_CLASS =\n \"flex items-center gap-1 border-t border-neutral-100 px-2 py-1.5\";\nexport const THREAD_SCROLL_TO_BOTTOM_CLASS =\n \"inline-flex items-center justify-center rounded-full border bg-background/80 p-1 shadow-sm backdrop-blur transition-opacity hover:bg-accent disabled:invisible\";\n\nconst ComposerStopIcon: FC = () => (\n <svg\n aria-hidden=\"true\"\n className=\"size-4\"\n viewBox=\"0 0 16 16\"\n fill=\"currentColor\"\n >\n <rect width=\"10\" height=\"10\" x=\"3\" y=\"3\" rx=\"2\" />\n </svg>\n);\n\nexport interface ComposerStopButtonProps {\n onStop: () => void;\n disabled?: boolean;\n title?: string;\n}\n\nexport interface ComposerSendButtonProps {\n action: Extract<ComposerAction, \"send\" | \"queue\">;\n onSend: () => void;\n disabled?: boolean;\n title?: string;\n}\n\n/** Stop control shown while a run is in flight and there is nothing queued. */\nexport const ComposerStopButton: FC<ComposerStopButtonProps> = ({\n onStop,\n disabled = false,\n title = \"Stop generation\",\n}) => (\n <button\n type=\"button\"\n onClick={onStop}\n disabled={disabled}\n title={title}\n className={cn(\n \"inline-flex size-8 shrink-0 items-center justify-center rounded-lg bg-foreground text-background shadow-sm transition-colors hover:bg-foreground/80\",\n disabled && \"cursor-not-allowed opacity-60\",\n )}\n >\n <ComposerStopIcon />\n </button>\n);\n/** Send control, which becomes a queue control while a run is in flight. */\nexport const ComposerSendButton: FC<ComposerSendButtonProps> = ({\n action,\n onSend,\n disabled = false,\n title,\n}) => (\n <button\n type=\"button\"\n onClick={onSend}\n disabled={disabled}\n title={title ?? (action === \"queue\" ? \"Queue message\" : \"Send\")}\n className={cn(\n \"inline-flex size-8 shrink-0 items-center justify-center rounded-full shadow-sm transition-colors\",\n disabled\n ? \"cursor-not-allowed bg-muted text-muted-foreground opacity-60\"\n : \"bg-foreground text-background hover:bg-foreground/80\",\n )}\n >\n {action === \"queue\" ? (\n <ListPlusIcon className=\"size-4\" />\n ) : (\n <ArrowUpIcon className=\"size-4\" />\n )}\n </button>\n);\n"],"names":["jsx","cn","jsxs","BranchPickerPrimitive","ChevronLeftIcon","ChevronRightIcon","ActionBarPrimitive","AuiIf","CheckIcon","CopyIcon","useAuiState","useAthenaRunLive","useMessageActionsReadOnly","PencilIcon","RefreshCwIcon","useSmooth","useMessagePartText","hideUnterminatedMarkdownLink","ChatMessageBody","isVoiceDelegationMessage","MessagePrimitive","VoiceDelegationMessage","useMemo","readRuntimeMessageFromSourceMessages","RuntimeMessageCard","hasVisibleContent","readSoleRuntimeMessageKind","ListPlusIcon","ArrowUpIcon"],"mappings":"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"}
|
|
@@ -9,6 +9,13 @@ export declare function SmallIconButton({ children, tooltip, className, ...props
|
|
|
9
9
|
tooltip: string;
|
|
10
10
|
}): import("react/jsx-runtime").JSX.Element;
|
|
11
11
|
export declare const BranchPicker: FC;
|
|
12
|
+
/**
|
|
13
|
+
* Reveal-on-demand treatment for action bars: invisible and click-through
|
|
14
|
+
* until the surrounding named group is hovered or a control inside receives
|
|
15
|
+
* keyboard focus. The `focus-within` escape hatch is what keeps the hidden
|
|
16
|
+
* controls reachable for keyboard users.
|
|
17
|
+
*/
|
|
18
|
+
export declare const ACTION_BAR_REVEAL_CLASS = "pointer-events-none opacity-0 transition-opacity focus-within:pointer-events-auto focus-within:opacity-100";
|
|
12
19
|
/** Shared chat body; the reveal holds incomplete links until their URL is complete. */
|
|
13
20
|
export declare const MarkdownText: FC;
|
|
14
21
|
export declare const UserMessage: FC;
|