@arbidocs/blocks 0.5.113 → 0.5.115
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{ConnectedCallDock-VCJ6Q7WE.cjs → ConnectedCallDock-WER7R222.cjs} +27 -27
- package/dist/{ConnectedCallDock-VCJ6Q7WE.cjs.map → ConnectedCallDock-WER7R222.cjs.map} +1 -1
- package/dist/{ConnectedCallRoom-BUI3ILJD.cjs → ConnectedCallRoom-T7OBQTYP.cjs} +19 -19
- package/dist/{ConnectedCallRoom-BUI3ILJD.cjs.map → ConnectedCallRoom-T7OBQTYP.cjs.map} +1 -1
- package/dist/{ConnectedMailInviteCard-P65MQM6J.cjs → ConnectedMailInviteCard-EINB3THA.cjs} +5 -5
- package/dist/{ConnectedMailInviteCard-P65MQM6J.cjs.map → ConnectedMailInviteCard-EINB3THA.cjs.map} +1 -1
- package/dist/{ConnectedNativeDocxComparison-JO2H4QIP.cjs → ConnectedNativeDocxComparison-YXMYJWXY.cjs} +24 -24
- package/dist/{ConnectedNativeDocxComparison-JO2H4QIP.cjs.map → ConnectedNativeDocxComparison-YXMYJWXY.cjs.map} +1 -1
- package/dist/{ConnectedProductionSetDialog-BSPM4NQC.cjs → ConnectedProductionSetDialog-LHB4VQWC.cjs} +9 -9
- package/dist/{ConnectedProductionSetDialog-BSPM4NQC.cjs.map → ConnectedProductionSetDialog-LHB4VQWC.cjs.map} +1 -1
- package/dist/{ConnectedStreamedWordArtifact-DMQEJFCA.cjs → ConnectedStreamedWordArtifact-2RTCHVPI.cjs} +24 -24
- package/dist/{ConnectedStreamedWordArtifact-DMQEJFCA.cjs.map → ConnectedStreamedWordArtifact-2RTCHVPI.cjs.map} +1 -1
- package/dist/{DocumentReviewCard-UBE2DVAC.cjs → DocumentReviewCard-ZSBZBGFK.cjs} +23 -23
- package/dist/{DocumentReviewCard-UBE2DVAC.cjs.map → DocumentReviewCard-ZSBZBGFK.cjs.map} +1 -1
- package/dist/{FilesViewerDialog-EBYRA3ZZ.cjs → FilesViewerDialog-I5QIHQZT.cjs} +55 -55
- package/dist/{FilesViewerDialog-EBYRA3ZZ.cjs.map → FilesViewerDialog-I5QIHQZT.cjs.map} +1 -1
- package/dist/{NativeDocxEditor-EJEIJDOC.cjs → NativeDocxEditor-H6TAEVGY.cjs} +6 -6
- package/dist/{NativeDocxEditor-EJEIJDOC.cjs.map → NativeDocxEditor-H6TAEVGY.cjs.map} +1 -1
- package/dist/{WorkspaceTableView-BO2OJO7A.cjs → WorkspaceTableView-J3C6VH4T.cjs} +9 -9
- package/dist/{WorkspaceTableView-BO2OJO7A.cjs.map → WorkspaceTableView-J3C6VH4T.cjs.map} +1 -1
- package/dist/agents/index.cjs +298 -298
- package/dist/{ai-EMNMGDAN.cjs → ai-IM4A23YT.cjs} +27 -27
- package/dist/ai-IM4A23YT.cjs.map +1 -0
- package/dist/calls/index.cjs +149 -149
- package/dist/chat/DraftingDocChip.d.ts +3 -1
- package/dist/chat/DraftingDocChip.js +7 -4
- package/dist/chat/DraftingDocChip.js.map +2 -2
- package/dist/chat/index.cjs +65 -65
- package/dist/{chunk-AJVZYRAJ.cjs → chunk-24EDG4PC.cjs} +68 -68
- package/dist/{chunk-AJVZYRAJ.cjs.map → chunk-24EDG4PC.cjs.map} +1 -1
- package/dist/{chunk-GTTDJMWX.cjs → chunk-325GVZE6.cjs} +6 -6
- package/dist/{chunk-GTTDJMWX.cjs.map → chunk-325GVZE6.cjs.map} +1 -1
- package/dist/{chunk-HM5L4SBC.cjs → chunk-3A7QWUAW.cjs} +3 -3
- package/dist/{chunk-HM5L4SBC.cjs.map → chunk-3A7QWUAW.cjs.map} +1 -1
- package/dist/{chunk-ET3NVY27.cjs → chunk-42TURFHF.cjs} +5 -5
- package/dist/{chunk-ET3NVY27.cjs.map → chunk-42TURFHF.cjs.map} +1 -1
- package/dist/{chunk-J2RXQVVF.cjs → chunk-4EK7TAP7.cjs} +5 -5
- package/dist/{chunk-J2RXQVVF.cjs.map → chunk-4EK7TAP7.cjs.map} +1 -1
- package/dist/{chunk-BHTEKYWJ.cjs → chunk-557MJ4IH.cjs} +23 -23
- package/dist/{chunk-BHTEKYWJ.cjs.map → chunk-557MJ4IH.cjs.map} +1 -1
- package/dist/{chunk-Y45VRNSZ.cjs → chunk-57NHXEU2.cjs} +4 -4
- package/dist/{chunk-Y45VRNSZ.cjs.map → chunk-57NHXEU2.cjs.map} +1 -1
- package/dist/{chunk-MUA5PJGX.cjs → chunk-5SKHK3BG.cjs} +4 -4
- package/dist/{chunk-MUA5PJGX.cjs.map → chunk-5SKHK3BG.cjs.map} +1 -1
- package/dist/{chunk-AFXDLDPU.cjs → chunk-5UYFLFNR.cjs} +4 -4
- package/dist/{chunk-AFXDLDPU.cjs.map → chunk-5UYFLFNR.cjs.map} +1 -1
- package/dist/{chunk-OTG5T5Z5.cjs → chunk-6UTKM5AB.cjs} +5 -5
- package/dist/{chunk-OTG5T5Z5.cjs.map → chunk-6UTKM5AB.cjs.map} +1 -1
- package/dist/{chunk-H5OLHP2U.cjs → chunk-7OPOPYV6.cjs} +3 -3
- package/dist/{chunk-H5OLHP2U.cjs.map → chunk-7OPOPYV6.cjs.map} +1 -1
- package/dist/{chunk-MQANCZOD.cjs → chunk-A3T3IC3K.cjs} +78 -78
- package/dist/{chunk-MQANCZOD.cjs.map → chunk-A3T3IC3K.cjs.map} +1 -1
- package/dist/{chunk-5VCID67B.cjs → chunk-B3LZITVF.cjs} +12 -12
- package/dist/{chunk-5VCID67B.cjs.map → chunk-B3LZITVF.cjs.map} +1 -1
- package/dist/{chunk-OZWYCRRK.cjs → chunk-BQ5RIWWT.cjs} +30 -30
- package/dist/{chunk-OZWYCRRK.cjs.map → chunk-BQ5RIWWT.cjs.map} +1 -1
- package/dist/chunk-CIHERNDO.cjs +18 -0
- package/dist/{chunk-L52N2LVE.cjs.map → chunk-CIHERNDO.cjs.map} +1 -1
- package/dist/{chunk-NP4EWPIP.cjs → chunk-CJYWHUZR.cjs} +6 -6
- package/dist/{chunk-NP4EWPIP.cjs.map → chunk-CJYWHUZR.cjs.map} +1 -1
- package/dist/{chunk-6W4X4EFI.cjs → chunk-CMGNRMPA.cjs} +5 -5
- package/dist/{chunk-6W4X4EFI.cjs.map → chunk-CMGNRMPA.cjs.map} +1 -1
- package/dist/{chunk-YONJRX6N.cjs → chunk-CPG7II4E.cjs} +28 -28
- package/dist/{chunk-YONJRX6N.cjs.map → chunk-CPG7II4E.cjs.map} +1 -1
- package/dist/{chunk-GGBNUDLK.cjs → chunk-CPR6EHG7.cjs} +70 -70
- package/dist/{chunk-GGBNUDLK.cjs.map → chunk-CPR6EHG7.cjs.map} +1 -1
- package/dist/{chunk-DZWIVRYP.cjs → chunk-DDIW4HLU.cjs} +36 -36
- package/dist/{chunk-DZWIVRYP.cjs.map → chunk-DDIW4HLU.cjs.map} +1 -1
- package/dist/{chunk-Z3VNKPPH.cjs → chunk-E3Y7RI3J.cjs} +4 -4
- package/dist/{chunk-Z3VNKPPH.cjs.map → chunk-E3Y7RI3J.cjs.map} +1 -1
- package/dist/{chunk-WT7CCCIN.cjs → chunk-GNX3FBBX.cjs} +4 -4
- package/dist/{chunk-WT7CCCIN.cjs.map → chunk-GNX3FBBX.cjs.map} +1 -1
- package/dist/{chunk-IIWJQEBC.cjs → chunk-H7PHOTX2.cjs} +10 -10
- package/dist/{chunk-IIWJQEBC.cjs.map → chunk-H7PHOTX2.cjs.map} +1 -1
- package/dist/{chunk-LQHXUSWZ.cjs → chunk-HQDR43JC.cjs} +6 -6
- package/dist/{chunk-LQHXUSWZ.cjs.map → chunk-HQDR43JC.cjs.map} +1 -1
- package/dist/{chunk-6LQN4BMX.cjs → chunk-IDCD5TEZ.cjs} +5 -5
- package/dist/{chunk-6LQN4BMX.cjs.map → chunk-IDCD5TEZ.cjs.map} +1 -1
- package/dist/{chunk-INEPPS4H.cjs → chunk-IW7CDJTA.cjs} +4 -4
- package/dist/{chunk-INEPPS4H.cjs.map → chunk-IW7CDJTA.cjs.map} +1 -1
- package/dist/{chunk-6YOZKXV6.cjs → chunk-JR2YSBD5.cjs} +4 -4
- package/dist/{chunk-6YOZKXV6.cjs.map → chunk-JR2YSBD5.cjs.map} +1 -1
- package/dist/{chunk-ZFKWCGA5.cjs → chunk-JV5TVUOU.cjs} +4 -4
- package/dist/{chunk-ZFKWCGA5.cjs.map → chunk-JV5TVUOU.cjs.map} +1 -1
- package/dist/{chunk-IFOGBMAE.cjs → chunk-KLMNCBLY.cjs} +9 -6
- package/dist/chunk-KLMNCBLY.cjs.map +1 -0
- package/dist/{chunk-JDI7E4RI.cjs → chunk-KTQOGT2L.cjs} +14 -14
- package/dist/{chunk-JDI7E4RI.cjs.map → chunk-KTQOGT2L.cjs.map} +1 -1
- package/dist/{chunk-OKHKJ5ML.cjs → chunk-KXIRVKCJ.cjs} +11 -11
- package/dist/{chunk-OKHKJ5ML.cjs.map → chunk-KXIRVKCJ.cjs.map} +1 -1
- package/dist/{chunk-4ED7CNOX.cjs → chunk-M6IKVKU5.cjs} +40 -3
- package/dist/chunk-M6IKVKU5.cjs.map +1 -0
- package/dist/{chunk-XKDUPU7B.cjs → chunk-NJCK6V6U.cjs} +4 -4
- package/dist/{chunk-XKDUPU7B.cjs.map → chunk-NJCK6V6U.cjs.map} +1 -1
- package/dist/{chunk-OVKJ7OVZ.cjs → chunk-NNUK5ZM7.cjs} +6 -6
- package/dist/{chunk-OVKJ7OVZ.cjs.map → chunk-NNUK5ZM7.cjs.map} +1 -1
- package/dist/{chunk-MJHIBCF7.cjs → chunk-NY3YUCOW.cjs} +4 -4
- package/dist/{chunk-MJHIBCF7.cjs.map → chunk-NY3YUCOW.cjs.map} +1 -1
- package/dist/{chunk-R4TP3VS3.cjs → chunk-OEREKAAP.cjs} +101 -101
- package/dist/{chunk-R4TP3VS3.cjs.map → chunk-OEREKAAP.cjs.map} +1 -1
- package/dist/{chunk-ENUZ35NR.cjs → chunk-P5AQYC4D.cjs} +4 -4
- package/dist/{chunk-ENUZ35NR.cjs.map → chunk-P5AQYC4D.cjs.map} +1 -1
- package/dist/{chunk-ZZZ6AZDR.cjs → chunk-P77YTTJ3.cjs} +4 -4
- package/dist/{chunk-ZZZ6AZDR.cjs.map → chunk-P77YTTJ3.cjs.map} +1 -1
- package/dist/{chunk-5I2VUNZR.cjs → chunk-PGJYD67F.cjs} +6 -6
- package/dist/{chunk-5I2VUNZR.cjs.map → chunk-PGJYD67F.cjs.map} +1 -1
- package/dist/{chunk-BYN7UMC5.cjs → chunk-PL7HUTM3.cjs} +8 -8
- package/dist/{chunk-BYN7UMC5.cjs.map → chunk-PL7HUTM3.cjs.map} +1 -1
- package/dist/{chunk-T7J352JD.cjs → chunk-QMIHLJMH.cjs} +6 -6
- package/dist/{chunk-T7J352JD.cjs.map → chunk-QMIHLJMH.cjs.map} +1 -1
- package/dist/{chunk-WJP6ICDM.cjs → chunk-R7CJEIA5.cjs} +4 -4
- package/dist/{chunk-WJP6ICDM.cjs.map → chunk-R7CJEIA5.cjs.map} +1 -1
- package/dist/{chunk-IE677C4I.cjs → chunk-SBWIA4PL.cjs} +21 -21
- package/dist/{chunk-IE677C4I.cjs.map → chunk-SBWIA4PL.cjs.map} +1 -1
- package/dist/{chunk-GVTKFVXH.cjs → chunk-SGYSDABK.cjs} +6 -6
- package/dist/{chunk-GVTKFVXH.cjs.map → chunk-SGYSDABK.cjs.map} +1 -1
- package/dist/{chunk-PIB7K7HI.cjs → chunk-T23UTIRI.cjs} +8 -8
- package/dist/{chunk-PIB7K7HI.cjs.map → chunk-T23UTIRI.cjs.map} +1 -1
- package/dist/{chunk-E4BLRF2L.cjs → chunk-TDO5UWXF.cjs} +5 -5
- package/dist/{chunk-E4BLRF2L.cjs.map → chunk-TDO5UWXF.cjs.map} +1 -1
- package/dist/{chunk-U5T46QCS.cjs → chunk-TKHCIHE2.cjs} +3 -3
- package/dist/chunk-TKHCIHE2.cjs.map +1 -0
- package/dist/{chunk-4IOYQLKG.cjs → chunk-TP5PGWIO.cjs} +3 -3
- package/dist/{chunk-4IOYQLKG.cjs.map → chunk-TP5PGWIO.cjs.map} +1 -1
- package/dist/{chunk-A4Z5CTLF.cjs → chunk-TT4IF52H.cjs} +39 -39
- package/dist/{chunk-A4Z5CTLF.cjs.map → chunk-TT4IF52H.cjs.map} +1 -1
- package/dist/{chunk-WIAWHETB.cjs → chunk-ULPTSXXO.cjs} +4 -4
- package/dist/{chunk-WIAWHETB.cjs.map → chunk-ULPTSXXO.cjs.map} +1 -1
- package/dist/{chunk-K5MYEWD5.cjs → chunk-UZHWXKS6.cjs} +7 -7
- package/dist/{chunk-K5MYEWD5.cjs.map → chunk-UZHWXKS6.cjs.map} +1 -1
- package/dist/{chunk-XW524KUX.cjs → chunk-VJCSEMXT.cjs} +4 -4
- package/dist/{chunk-XW524KUX.cjs.map → chunk-VJCSEMXT.cjs.map} +1 -1
- package/dist/{chunk-B5442TKX.cjs → chunk-VRK3IQAP.cjs} +4 -4
- package/dist/{chunk-B5442TKX.cjs.map → chunk-VRK3IQAP.cjs.map} +1 -1
- package/dist/{chunk-MYRKL3JO.cjs → chunk-VWTOIGX4.cjs} +4 -4
- package/dist/{chunk-MYRKL3JO.cjs.map → chunk-VWTOIGX4.cjs.map} +1 -1
- package/dist/{chunk-KZKGZ7IG.cjs → chunk-WAV762GP.cjs} +14 -14
- package/dist/{chunk-KZKGZ7IG.cjs.map → chunk-WAV762GP.cjs.map} +1 -1
- package/dist/{chunk-DMNX556N.cjs → chunk-WR2SF44W.cjs} +10 -10
- package/dist/{chunk-DMNX556N.cjs.map → chunk-WR2SF44W.cjs.map} +1 -1
- package/dist/{chunk-M2D4POJV.cjs → chunk-WXUU3COI.cjs} +9 -9
- package/dist/{chunk-M2D4POJV.cjs.map → chunk-WXUU3COI.cjs.map} +1 -1
- package/dist/{chunk-FGEBA3TL.cjs → chunk-X5LANJDZ.cjs} +26 -26
- package/dist/{chunk-FGEBA3TL.cjs.map → chunk-X5LANJDZ.cjs.map} +1 -1
- package/dist/{chunk-MY7Q3QE2.cjs → chunk-XKVPSOKP.cjs} +4 -4
- package/dist/{chunk-MY7Q3QE2.cjs.map → chunk-XKVPSOKP.cjs.map} +1 -1
- package/dist/{chunk-ONZOVO2B.cjs → chunk-Y24V6HPR.cjs} +24 -24
- package/dist/{chunk-ONZOVO2B.cjs.map → chunk-Y24V6HPR.cjs.map} +1 -1
- package/dist/{chunk-KGGSBJMU.cjs → chunk-YGXOKB5Z.cjs} +4 -4
- package/dist/{chunk-KGGSBJMU.cjs.map → chunk-YGXOKB5Z.cjs.map} +1 -1
- package/dist/{chunk-YAPXIANR.cjs → chunk-YVCOQHCE.cjs} +5 -5
- package/dist/{chunk-YAPXIANR.cjs.map → chunk-YVCOQHCE.cjs.map} +1 -1
- package/dist/{chunk-LCNKKSN3.cjs → chunk-ZTXQIIFV.cjs} +6 -6
- package/dist/{chunk-LCNKKSN3.cjs.map → chunk-ZTXQIIFV.cjs.map} +1 -1
- package/dist/citations/index.cjs +8 -8
- package/dist/connect/docx.cjs +28 -28
- package/dist/connect/index.cjs +1683 -1497
- package/dist/connect/index.cjs.map +1 -1
- package/dist/connect/viewer.cjs +41 -41
- package/dist/connection/ConnectedWorkflowBuilder.d.ts +11 -0
- package/dist/connection/ConnectedWorkflowBuilder.js +42 -3
- package/dist/connection/ConnectedWorkflowBuilder.js.map +2 -2
- package/dist/connection/conversation/ConnectedConversation.js +143 -55
- package/dist/connection/conversation/ConnectedConversation.js.map +2 -2
- package/dist/connection/conversation/ConnectedConversationPage.js +36 -2
- package/dist/connection/conversation/ConnectedConversationPage.js.map +2 -2
- package/dist/connection/conversation/ConversationSendButton.d.ts +1 -0
- package/dist/connection/conversation/ConversationSendButton.js +3 -2
- package/dist/connection/conversation/ConversationSendButton.js.map +2 -2
- package/dist/connection/conversation/DocumentTargetNotice.d.ts +7 -0
- package/dist/connection/conversation/DocumentTargetNotice.js +45 -0
- package/dist/connection/conversation/DocumentTargetNotice.js.map +7 -0
- package/dist/connection/conversation/documentSwitch.d.ts +9 -0
- package/dist/connection/conversation/documentSwitch.js +40 -0
- package/dist/connection/conversation/documentSwitch.js.map +7 -0
- package/dist/connection/workflows/ConnectedWorkflowsPage.js +10 -3
- package/dist/connection/workflows/ConnectedWorkflowsPage.js.map +2 -2
- package/dist/connection/workflows/useWorkflowsPageState.d.ts +1 -0
- package/dist/connection/workflows/useWorkflowsPageState.js.map +2 -2
- package/dist/dashboards/index.cjs +23 -23
- package/dist/docx/NativeDocxEditor.js +3 -1
- package/dist/docx/NativeDocxEditor.js.map +2 -2
- package/dist/docx/index.cjs +38 -38
- package/dist/docx/signatures/SignatureFields.d.ts +2 -0
- package/dist/docx/signatures/SignatureFields.js +40 -2
- package/dist/docx/signatures/SignatureFields.js.map +2 -2
- package/dist/embed/index.cjs +50 -50
- package/dist/facts/index.cjs +44 -44
- package/dist/files/index.cjs +226 -226
- package/dist/home/index.cjs +32 -32
- package/dist/index.cjs +1694 -1694
- package/dist/provider/environment.d.ts +5 -0
- package/dist/provider/environment.js +1 -1
- package/dist/provider/environment.js.map +2 -2
- package/dist/provider/requests.d.ts +2 -0
- package/dist/provider/requests.js.map +2 -2
- package/dist/retrieval/index.cjs +4 -4
- package/dist/settings/index.cjs +147 -147
- package/dist/shell/index.cjs +91 -91
- package/dist/studio/index.cjs +42 -42
- package/dist/styles.css +1 -1
- package/dist/workflow-canvas/index.cjs +116 -74
- package/dist/workflow-canvas/index.cjs.map +1 -1
- package/dist/workspaces/index.cjs +27 -27
- package/node_modules/@arbidocs/coedit/package.json +1 -1
- package/package.json +5 -5
- package/dist/ai-EMNMGDAN.cjs.map +0 -1
- package/dist/chunk-4ED7CNOX.cjs.map +0 -1
- package/dist/chunk-IFOGBMAE.cjs.map +0 -1
- package/dist/chunk-L52N2LVE.cjs +0 -18
- package/dist/chunk-U5T46QCS.cjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/chat/MessageAlert.tsx","../src/chat/AssistantModeToggle.tsx","../src/chat/ConversationEmpty.tsx","../src/chat/ContextChip.tsx","../src/chat/CitationMark.tsx","../src/chat/chat-page-types.ts","../src/chat/ChatMessageContent.tsx","../src/chat/ChatDocuments.tsx","../src/chat/ChatThreads.tsx","../src/chat/chat-surface.ts","../src/chat/useStartRequestedConversation.ts","../src/chat/useControlledThread.ts","../src/lib/useFillHeight.ts","../src/chat/ChatPage.tsx"],"names":["jsx","cn","jsxs","RotateCw","AlertCircle","Button","MessagesSquare","Bot","Tooltip","TooltipTrigger","testIdOr","TooltipContent","assistantCopy","FileUp","useAssistantCopy","Sparkles","GanttChartSquare","ArrowUpRight","forwardRef","ContextChip","useState","Pencil","FileText","Popover","PopoverTrigger","PopoverContent","useMemo","useCallback","Fragment","MarkdownRenderer","closeOpenEmphasis","trimOpenCitation","Loader2","Upload","MessageSquarePlus","Trash2","useEffect","useSyncExternalStore","useRef","useIntentRequest","conversationStartRequest","useLayoutEffect","observeResize","WorkflowStepChip","Message","useMentionAutocomplete","parseSlashTokenInProgress","filterSlashItems","useListKeyNav","useElementSize","rootFontSizePx","useStreamAnnouncement","toMessageMentions","extractMentions","PanelRight","MessageList","ScrollToBottom","Composer","SlashMenu","MentionMenu","Square"],"mappings":"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","file":"chunk-6LQN4BMX.cjs","sourcesContent":["import type { ReactNode } from 'react'\nimport { AlertCircle, RotateCw } from 'lucide-react'\nimport { Button, cn } from '@arbidocs/react/ui'\n\n/** Every fixed string of the alert. Pass a partial `labels` to translate or reword. */\nexport interface MessageAlertLabels {\n retrying: string\n /** Name of the retry button rendered for `onActivate`. */\n retry: string\n}\n\nexport const DEFAULT_MESSAGE_ALERT_LABELS: MessageAlertLabels = {\n retrying: 'Retrying...',\n retry: 'Retry',\n}\n\nexport interface MessageAlertProps {\n title: string\n description: string\n /** A retry is in flight: shows a spinner and the busy title. */\n isBusy?: boolean\n /** Title while busy; wins over `labels.retrying`. */\n busyTitle?: string\n labels?: Partial<MessageAlertLabels>\n /** Adds a Retry button (a real, keyboard-operable one) that runs this. */\n onActivate?: () => void\n /** Explicit buttons under the text (e.g. a Retry button). */\n actions?: ReactNode\n className?: string\n testId?: string\n}\n\n/** Tinted alert above the composer: a send that failed, or an answer that never arrived. */\nexport function MessageAlert({\n title,\n description,\n isBusy = false,\n busyTitle,\n labels,\n onActivate,\n actions,\n className,\n testId = 'message-alert',\n}: MessageAlertProps) {\n const l = { ...DEFAULT_MESSAGE_ALERT_LABELS, ...labels }\n return (\n <div\n data-slot=\"message-alert\"\n // A failure interrupts (alert); a retry in flight is only progress (status).\n role={isBusy ? 'status' : 'alert'}\n aria-busy={isBusy}\n className={cn(\n 'mb-3 rounded-lg border border-red-border bg-red-bg px-4 py-2 transition-colors',\n className\n )}\n data-testid={testId}\n >\n <div className=\"flex items-start gap-3\">\n {isBusy ? (\n <RotateCw\n aria-hidden=\"true\"\n className=\"mt-0.5 h-5 w-5 shrink-0 animate-spin text-red-text motion-reduce:animate-none\"\n />\n ) : (\n <AlertCircle aria-hidden=\"true\" className=\"mt-0.5 h-5 w-5 shrink-0 text-red-text\" />\n )}\n <div className=\"min-w-0 flex-1\">\n <p className=\"mb-1 text-base font-medium text-red-text\">\n {isBusy ? (busyTitle ?? l.retrying) : title}\n </p>\n <p className=\"mb-1 text-sm text-muted-foreground\">{description}</p>\n {(actions || onActivate) && (\n <div className=\"mt-2 flex flex-wrap gap-2\">\n {actions}\n {onActivate && (\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n className=\"pointer-coarse:min-h-11\"\n disabled={isBusy}\n onClick={onActivate}\n data-testid={`${testId}-retry`}\n >\n <RotateCw aria-hidden=\"true\" className=\"mr-2 h-4 w-4\" />\n {l.retry}\n </Button>\n )}\n </div>\n )}\n </div>\n </div>\n </div>\n )\n}\n","import { Bot, MessagesSquare } from 'lucide-react'\nimport { Button, cn, Tooltip, TooltipContent, TooltipTrigger } from '@arbidocs/react/ui'\nimport { testIdOr } from './test-id'\n\n/** When the assistant answers in a conversation (the API's `AssistantMode`). */\nexport type AssistantMode = 'always' | 'mentioned'\n\n/** Every fixed string of the toggle. Pass a partial `labels` to reword. */\nexport interface AssistantModeToggleLabels {\n always: string\n mentioned: string\n /** Tooltip / accessible description per mode. */\n alwaysHint: string\n mentionedHint: string\n}\n\nexport const DEFAULT_ASSISTANT_MODE_TOGGLE_LABELS: AssistantModeToggleLabels = {\n always: 'Assistant replies',\n mentioned: 'Thread',\n alwaysHint: 'The assistant answers every message. Click to make this a thread.',\n mentionedHint:\n 'A thread: messages are comments between people. @mention the assistant to get an answer. Click to have it answer every message.',\n}\n\nexport interface AssistantModeToggleProps {\n mode: AssistantMode\n onModeChange: (mode: AssistantMode) => void\n disabled?: boolean\n labels?: Partial<AssistantModeToggleLabels>\n className?: string\n /** Test id (default `assistant-mode-toggle`); the current mode lands on `data-mode`. */\n testId?: string\n}\n\n/**\n * Composer-toolbar switch between an ordinary chat (`always`: every message gets an answer) and a\n * thread (`mentioned`: the assistant only answers when @mentioned).\n */\nexport function AssistantModeToggle({\n mode,\n onModeChange,\n disabled,\n labels,\n className,\n testId,\n}: AssistantModeToggleProps) {\n const l = { ...DEFAULT_ASSISTANT_MODE_TOGGLE_LABELS, ...labels }\n const isThread = mode === 'mentioned'\n const hint = isThread ? l.mentionedHint : l.alwaysHint\n const Icon = isThread ? MessagesSquare : Bot\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n disabled={disabled}\n aria-pressed={isThread}\n aria-label={`${isThread ? l.mentioned : l.always}. ${hint}`}\n onClick={() => onModeChange(isThread ? 'always' : 'mentioned')}\n className={cn(\n 'h-8 gap-1.5 px-2 text-xs text-muted-foreground hover:bg-muted pointer-coarse:h-11',\n isThread && 'bg-accent text-accent-foreground',\n className\n )}\n data-mode={mode}\n data-testid={testIdOr(testId, { testId: 'assistant-mode-toggle' })}\n >\n <Icon className=\"h-3.5 w-3.5\" aria-hidden=\"true\" />\n <span>{isThread ? l.mentioned : l.always}</span>\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"top\" className=\"max-w-xs\">\n {hint}\n </TooltipContent>\n </Tooltip>\n )\n}\n","import type { ReactNode } from 'react'\nimport { ArrowUpRight, FileUp, GanttChartSquare, Sparkles } from 'lucide-react'\nimport { cn } from '@arbidocs/react/ui'\nimport { assistantCopy, useAssistantCopy } from '@arbidocs/react/shell'\nimport { testIdOr } from './test-id'\n\nexport interface ConversationShortcut {\n /** Short button label. */\n label: string\n /** Full prompt the host drops into the composer. */\n prompt: string\n}\n\n/** Every fixed string of the empty state. Pass a partial `labels` to translate or reword. */\nexport interface ConversationEmptyLabels {\n title: string\n description: string\n dropDocuments: string\n}\n\n/** ARBI's own phrases (the defaults below). */\nconst ARBI = assistantCopy()\n\nexport const DEFAULT_CONVERSATION_EMPTY_LABELS: ConversationEmptyLabels = {\n title: ARBI.askAboutDocuments,\n description: 'Ask a question and verify every answer against the source.',\n dropDocuments: 'Drop documents here to add them',\n}\n\nexport interface ConversationEmptyProps {\n /** Does the workspace have documents to ask about? Picks the layout. */\n hasDocuments: boolean\n /** Starter questions (has-documents state). */\n prompts: ReadonlyArray<string>\n /** Featured action-shaped shortcut that leads the row. */\n shortcut?: ConversationShortcut\n /** Drop a prompt into the composer. */\n onUsePrompt: (text: string) => void\n /** Add documents: dropped files, or no argument to open the picker. */\n onAddDocuments: (files?: File[]) => void\n /** Rendered instead of the starters when there are no documents (upload box, alt sources). */\n noDocuments: ReactNode\n /**\n * Extra content under the starters (the host's list of things to start). It lives INSIDE the\n * empty state's own scroll area, never in the composer dock: the composer stays anchored at the\n * bottom whatever the length, and a long list scrolls here, above it.\n */\n below?: ReactNode\n /** Heading; wins over `labels.title`. */\n title?: string\n /** Sub-heading; wins over `labels.description`. */\n description?: string\n className?: string\n labels?: Partial<ConversationEmptyLabels>\n /** Per-part test ids; defaults are the current ids. */\n testIds?: Partial<{\n root: string\n upload: string\n shortcut: string\n prompt: string\n }>\n}\n\n/** Quiet \"drop documents here\" row for the has-documents state. */\nfunction AddDocumentsArea({\n onAddDocuments,\n label,\n testId,\n}: {\n onAddDocuments: (files?: File[]) => void\n label: string\n testId: string\n}) {\n return (\n <button\n type=\"button\"\n onClick={() => onAddDocuments()}\n onDragOver={(e) => {\n if (e.dataTransfer.types.includes('Files')) {\n e.preventDefault()\n e.dataTransfer.dropEffect = 'copy'\n }\n }}\n onDrop={(e) => {\n const files = Array.from(e.dataTransfer.files ?? [])\n if (files.length > 0) {\n e.preventDefault()\n onAddDocuments(files)\n }\n }}\n data-testid={testId}\n className=\"mx-auto flex w-full max-w-sm items-center justify-center gap-2 rounded-lg border border-border bg-card px-3 py-2.5 text-sm text-muted-foreground transition-colors hover:border-ring/50 hover:bg-accent/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring pointer-coarse:min-h-11\"\n >\n <FileUp className=\"h-4 w-4 shrink-0\" />\n <span>{label}</span>\n </button>\n )\n}\n\n/** The host's list under the starters: wider than the starters, centred, text left-aligned. */\nconst BELOW = 'mx-auto w-full max-w-4xl text-left'\n\nconst CHIP =\n 'group inline-flex items-center rounded-md border border-border bg-card px-3.5 py-2 text-left text-sm text-foreground transition-colors hover:border-ring/50 hover:bg-accent/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring pointer-coarse:min-h-11'\n\n/**\n * Empty state of a brand-new conversation. With no documents the first job is adding one, so\n * the host's upload box leads. With documents it is a one-line framing, a few clickable starter\n * prompts that prefill the composer, and a quiet \"add more\" row.\n */\nexport function ConversationEmpty({\n hasDocuments,\n prompts,\n shortcut,\n onUsePrompt,\n onAddDocuments,\n noDocuments,\n below,\n title,\n description,\n className,\n labels,\n testIds,\n}: ConversationEmptyProps) {\n const assistant = useAssistantCopy()\n const l = {\n ...DEFAULT_CONVERSATION_EMPTY_LABELS,\n title: assistant.askAboutDocuments,\n ...labels,\n }\n const rootTestId = testIdOr(testIds?.root, { testId: 'conversation-empty-state' })\n const uploadTestId = testIdOr(testIds?.upload, { testId: 'conversation-empty-upload' })\n const shortcutTestId = testIdOr(testIds?.shortcut, {\n testId: 'conversation-shortcut-main-events',\n })\n const promptTestId = testIdOr(testIds?.prompt, { testId: 'conversation-example-prompt' })\n // `pb-28` reserves the composer's height so the content reads as centred above the input;\n // the parent is `position: relative`, so inset-0 fills it.\n if (!hasDocuments) {\n return (\n <div\n data-slot=\"conversation-empty\"\n className={cn(\n 'absolute inset-0 flex flex-col items-center overflow-y-auto px-6 py-8 pb-28',\n className\n )}\n data-testid={rootTestId}\n >\n <div className=\"my-auto flex w-full flex-col items-center gap-8\">\n <div className=\"flex w-full max-w-xl flex-col items-center gap-3\">{noDocuments}</div>\n {below && <div className={BELOW}>{below}</div>}\n </div>\n </div>\n )\n }\n\n return (\n <div\n data-slot=\"conversation-empty\"\n className={cn('absolute inset-0 flex overflow-y-auto p-6 pb-28', className)}\n data-testid={rootTestId}\n >\n <div className=\"m-auto flex w-full flex-col\">\n <div className=\"mx-auto w-full max-w-xl text-center\">\n <div className=\"mx-auto mb-4 flex h-12 w-12 items-center justify-center rounded-lg bg-ai-soft text-ai-ink\">\n <Sparkles className=\"h-6 w-6\" />\n </div>\n <h2 className=\"text-lg font-semibold text-foreground\">{title ?? l.title}</h2>\n <p className=\"mt-1.5 text-sm text-muted-foreground\">{description ?? l.description}</p>\n </div>\n\n {/* The host's list comes straight after the heading: it is what the user came for, and on\n a phone it must not sit below the fold behind the starters. */}\n {below && <div className={cn(BELOW, 'mt-6')}>{below}</div>}\n\n <div className=\"mx-auto w-full max-w-xl text-center\">\n <div className={cn('flex flex-wrap justify-center gap-2', below ? 'mt-8' : 'mt-5')}>\n {shortcut && (\n <button\n type=\"button\"\n onClick={() => onUsePrompt(shortcut.prompt)}\n title={shortcut.prompt}\n className={cn(CHIP, 'gap-2 font-medium')}\n data-testid={shortcutTestId}\n >\n <GanttChartSquare className=\"h-4 w-4 shrink-0 text-ai-ink\" />\n <span>{shortcut.label}</span>\n <ArrowUpRight className=\"h-3.5 w-3.5 shrink-0 text-muted-foreground\" />\n </button>\n )}\n {prompts.map((prompt) => (\n <button\n key={prompt}\n type=\"button\"\n onClick={() => onUsePrompt(prompt)}\n className={cn(CHIP, 'gap-1.5')}\n data-testid={promptTestId}\n >\n {prompt}\n <ArrowUpRight className=\"h-3.5 w-3.5 text-muted-foreground\" />\n </button>\n ))}\n </div>\n\n <div className=\"mt-5\">\n <AddDocumentsArea\n onAddDocuments={onAddDocuments}\n label={l.dropDocuments}\n testId={uploadTestId}\n />\n </div>\n </div>\n </div>\n </div>\n )\n}\n","import { forwardRef, useState, type FocusEvent, type MouseEvent, type ReactNode } from 'react'\nimport { FileText, Pencil } from 'lucide-react'\nimport { Button, cn, type ButtonProps } from '@arbidocs/react/ui'\n\nexport interface ContextChipProps extends Omit<\n ButtonProps,\n 'children' | 'asChild' | 'size' | 'variant'\n> {\n /** How many documents are attached to this chat. */\n count: number\n /** Accessible name, e.g. \"3 documents in this chat\". */\n label: string\n /** True while the panel the chip opens is showing: the chip stays in its \"edit\" state. */\n isOpen?: boolean\n /** Extra content after the count (e.g. the pinned-document chip). */\n children?: ReactNode\n}\n\n/** True when the primary pointer can hover; touch screens emulate mouseenter on a tap. */\nfunction canHover(): boolean {\n return typeof window !== 'undefined' && !!window.matchMedia?.('(hover: hover)').matches\n}\n\n/** `:focus-visible` is keyboard focus; where unsupported, treat any focus as visible. */\nfunction isFocusVisible(el: HTMLElement): boolean {\n try {\n return el.matches(':focus-visible')\n } catch {\n return true\n }\n}\n\n/**\n * The composer's single compact context chip: a document icon and the number of documents in the\n * chat, nothing else. On hover (mouse) or keyboard focus, and while its panel is open, the icon\n * swaps to a pencil to say \"change what is attached\". Touch devices never hover, so they keep the\n * document icon and a tap opens the panel. Forwards its ref and props so it can be a Radix trigger.\n */\nexport const ContextChip = forwardRef<HTMLButtonElement, ContextChipProps>(function ContextChip(\n {\n count,\n label,\n isOpen = false,\n children,\n className,\n onMouseEnter,\n onMouseLeave,\n onFocus,\n onBlur,\n ...props\n },\n ref\n) {\n const [isHovered, setIsHovered] = useState(false)\n const [isFocused, setIsFocused] = useState(false)\n const isEditing = isHovered || isFocused || isOpen\n const Icon = isEditing ? Pencil : FileText\n\n return (\n <Button\n ref={ref}\n type=\"button\"\n variant=\"outline\"\n aria-label={label}\n aria-haspopup=\"dialog\"\n aria-expanded={isOpen}\n data-slot=\"context-chip\"\n data-icon={isEditing ? 'edit' : 'document'}\n className={cn(\n 'flex h-8 min-w-0 max-w-[280px] flex-shrink-0 items-center gap-1.5 rounded-md px-2.5',\n className\n )}\n {...props}\n onMouseEnter={(e: MouseEvent<HTMLButtonElement>) => {\n onMouseEnter?.(e)\n if (canHover()) setIsHovered(true)\n }}\n onMouseLeave={(e: MouseEvent<HTMLButtonElement>) => {\n onMouseLeave?.(e)\n setIsHovered(false)\n }}\n onFocus={(e: FocusEvent<HTMLButtonElement>) => {\n onFocus?.(e)\n setIsFocused(isFocusVisible(e.currentTarget))\n }}\n onBlur={(e: FocusEvent<HTMLButtonElement>) => {\n onBlur?.(e)\n setIsFocused(false)\n }}\n >\n <Icon className=\"h-3.5 w-3.5 flex-shrink-0\" aria-hidden=\"true\" />\n <span className=\"flex-shrink-0 text-sm font-medium\" data-testid=\"context-chip-count\">\n {count >= 1000 ? '999+' : count}\n </span>\n {children}\n </Button>\n )\n})\n","import { useState } from 'react'\nimport { FileText } from 'lucide-react'\nimport { Button, Popover, PopoverContent, PopoverTrigger, cn } from '@arbidocs/react/ui'\nimport type {\n ChatCitationTarget,\n ChatPageCitation,\n ChatPageLabels,\n ChatPagePassage,\n} from './chat-page-types'\n\nexport type CitationLabels = Pick<\n ChatPageLabels,\n 'citation' | 'citationHeading' | 'citationNoSource' | 'openDocument' | 'page'\n>\n\nexport interface CitationMarkProps {\n num: string\n /** The source behind the mark. Without it the mark is a quiet, non-interactive number. */\n citation?: ChatPageCitation\n labels: CitationLabels\n /** Opens the cited document in the host's viewer; without it the popover has no open action. */\n onOpen?: (target: ChatCitationTarget) => void\n className?: string\n}\n\nconst MARK =\n 'ml-px align-super text-[max(0.8em,var(--text-xs))] font-semibold leading-none tabular-nums text-muted-foreground'\n\nfunction sourceLabel(citation: ChatPageCitation, labels: CitationLabels): string {\n return [citation.documentTitle, citation.page != null ? labels.page(citation.page) : '']\n .filter(Boolean)\n .join(', ')\n}\n\n/**\n * The mark after a cited statement: a small superscript number, not an underline over the whole\n * sentence. With citation data it is a button that opens a popover with the source document, the\n * page and the cited passage(s), and (when the host passes `onOpen`) an \"Open document\" action;\n * without data (still streaming, an old message with no stored sources) it is the number alone.\n */\nexport function CitationMark({ num, citation, labels, onOpen, className }: CitationMarkProps) {\n const [isOpen, setIsOpen] = useState(false)\n if (!citation) {\n return (\n <sup className={cn(MARK, className)} data-cite={num}>\n {num}\n </sup>\n )\n }\n\n const open = (passage: ChatPagePassage | null) => {\n setIsOpen(false)\n onOpen?.({\n documentId: passage?.documentId ?? null,\n documentTitle: passage?.documentTitle ?? citation.documentTitle,\n page: passage?.page ?? citation.page,\n passage,\n citation,\n })\n }\n\n return (\n <Popover open={isOpen} onOpenChange={setIsOpen}>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n data-cite={num}\n data-testid={`chat-citation-${num}`}\n aria-label={labels.citation(num, sourceLabel(citation, labels))}\n className={cn(\n MARK,\n // A pill hit area: 44px on touch without moving the text.\n 'relative -my-1 inline-flex min-w-[1.1em] justify-center rounded px-1 py-1 hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring data-[state=open]:bg-muted data-[state=open]:text-foreground',\n \"pointer-coarse:after:absolute pointer-coarse:after:-inset-3 pointer-coarse:after:content-['']\",\n className\n )}\n >\n {num}\n </button>\n </PopoverTrigger>\n <PopoverContent\n align=\"start\"\n aria-label={labels.citationHeading(num)}\n data-testid={`chat-citation-popover-${num}`}\n className=\"w-96 max-w-[calc(100vw-1rem)] p-0 text-sm\"\n >\n <div className=\"border-b border-border px-3 py-2 text-xs font-semibold text-muted-foreground\">\n {labels.citationHeading(num)}\n </div>\n {citation.passages.length === 0 ? (\n <p className=\"px-3 py-3 text-muted-foreground\">{labels.citationNoSource}</p>\n ) : (\n <ul className=\"divide-y divide-border\">\n {citation.passages.map((passage) => (\n <li key={passage.id} className=\"space-y-1.5 px-3 py-3\">\n <div className=\"flex items-start gap-2\">\n <FileText\n className=\"mt-0.5 size-4 shrink-0 text-muted-foreground\"\n aria-hidden=\"true\"\n />\n <div className=\"min-w-0 flex-1\">\n <div className=\"break-words font-medium text-foreground\">\n {passage.documentTitle}\n </div>\n {passage.page != null && (\n <div className=\"text-xs text-muted-foreground\">\n {labels.page(passage.page)}\n </div>\n )}\n </div>\n </div>\n <blockquote className=\"line-clamp-6 border-l-2 border-border pl-3 text-xs italic text-muted-foreground\">\n {passage.text}\n </blockquote>\n {onOpen && (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"pointer-coarse:min-h-11\"\n onClick={() => open(passage)}\n data-testid={`chat-citation-open-${num}`}\n >\n {labels.openDocument}\n </Button>\n )}\n </li>\n ))}\n </ul>\n )}\n </PopoverContent>\n </Popover>\n )\n}\n","import type { ReactNode } from 'react'\nimport type { WorkflowStepKind } from '../agents/workflows/stepKinds'\nimport type { WorkflowStepPhase } from '../agents/workflows/run'\nimport type { MentionCandidate, MessageMentionRef } from '@arbidocs/react/shell'\nimport type { SlashMenuItem } from './SlashMenu'\n\n/**\n * The view-model of a chat page. It is the shape `useConversation()` from `@arbidocs/react` returns,\n * so `<ChatPage chat={useConversation(...)} />` works without an adapter; any other source (a demo,\n * another backend) can fill it in. Plain data and callbacks: no SDK, store or router.\n */\n/** One passage of a source document behind a citation. */\nexport interface ChatPagePassage {\n id: string\n /** The source document's id, when known (what an \"open document\" action needs). */\n documentId: string | null\n documentTitle: string\n page: number | null\n text: string\n}\n\n/** The source behind `[statement](#cite-N)` marks of an answer. */\nexport interface ChatPageCitation {\n /** The number in `(#cite-N)`. */\n num: string\n statement: string\n documentTitle: string\n page: number | null\n passages: ReadonlyArray<ChatPagePassage>\n}\n\n/** What the host gets when the reader opens a cited document. */\nexport interface ChatCitationTarget {\n documentId: string | null\n documentTitle: string\n page: number | null\n /** The cited passage (the one opened from, or the first). */\n passage: ChatPagePassage | null\n citation: ChatPageCitation\n}\n\nexport interface ChatPageMessage {\n senderName?: string\n /**\n * Written by someone else in a shared thread: shown on the left. Unset (the reader's own, or a\n * one-person chat): on the right.\n */\n fromOther?: boolean\n id: string\n role: 'user' | 'assistant'\n /** Markdown for an assistant message, plain text for a user message. */\n content: string\n status: 'streaming' | 'complete' | 'error'\n /** Why an assistant message failed. */\n error?: string\n /** Agent steps the answer took so far. */\n stepCount?: number\n /** Sources of the `[..](#cite-N)` marks in `content`. Without them the marks are quiet numbers. */\n citations?: ReadonlyArray<ChatPageCitation>\n /** The reader stopped the answer; `content` is what had streamed. */\n stopped?: boolean\n /** A user message that started a workflow step (its id): shown as that step's chip. */\n workflowStep?: string\n}\n\nexport interface ChatPageThread {\n id: string\n /** Empty until the first question titles it. */\n title: string\n}\n\nexport interface ChatPageDocument {\n id: string\n name: string\n isSelected: boolean\n}\n\n/**\n * The composer's `/` menu: its rows (commands and skills) and what picking or typing a skill does.\n * `useConnectedChat` fills it from the connection; the page filters the rows by the draft.\n */\nexport interface ChatPageSlash {\n items: ReadonlyArray<SlashMenuItem>\n /** A picked row: true when it was handled (a skill's form opened); otherwise `/name ` is inserted. */\n pick: (item: SlashMenuItem) => boolean\n /** A submitted draft: true when it named a skill (its form opened), so nothing is sent. */\n startDraft: (draft: string) => boolean\n /** The menu's \"Browse skills\" footer. Omit to hide it. */\n onBrowse?: () => void\n /** Rendered once with the composer (the skill's form). */\n launcher?: ReactNode\n}\n\nexport interface ChatPageController {\n /** The composer's `/` menu. Omit for none. */\n slash?: ChatPageSlash\n assistantMode?: 'always' | 'mentioned'\n setAssistantMode?: (mode: 'always' | 'mentioned') => void | Promise<void>\n isUpdatingAssistantMode?: boolean\n isPostingComment?: boolean\n mentionCandidates?: ReadonlyArray<MentionCandidate>\n threads: ReadonlyArray<ChatPageThread>\n activeThreadId: string\n messages: ReadonlyArray<ChatPageMessage>\n isRunning: boolean\n /** The last turn failed. */\n error: string | null\n /** A stored conversation's messages are loading. */\n isLoadingThread?: boolean\n /** The conversation list is loading. */\n isLoadingThreads?: boolean\n /** Loading or deleting a stored conversation failed. */\n historyError?: string | null\n documents: ReadonlyArray<ChatPageDocument>\n isLoadingDocuments: boolean\n isUploading: boolean\n uploadError: string | null\n send: (text: string, options?: { mentions?: MessageMentionRef[] }) => void | Promise<void>\n retry: () => void | Promise<void>\n /** Stops the running answer. Omit when the source cannot be aborted: no stop button then. */\n stop?: () => void\n selectThread: (id: string) => void\n newThread: () => void\n /** Omit to hide the delete action. */\n deleteThread?: (id: string) => void\n toggleDocument: (id: string) => void\n selectAllDocuments: () => void\n upload: (files: File[]) => void | Promise<void>\n}\n\n/** Every fixed string of the chat page. Pass a partial `labels` to translate or reword. */\nexport interface ChatPageLabels {\n /** Accessible name of the whole chat. */\n chat: string\n conversations: string\n newChat: string\n untitled: string\n deleteConversation: (title: string) => string\n /** Assistant name on the answer's byline. */\n assistant: string\n thinking: string\n steps: (count: number) => string\n responseFailed: string\n answerFailedTitle: string\n uploadFailedTitle: string\n placeholder: string\n composerAriaLabel: string\n documentsInChat: (selected: number, total: number) => string\n documentsHeading: string\n selectAllDocuments: string\n noDocuments: string\n uploadDocuments: string\n uploading: string\n emptyTitle: string\n emptyDescription: string\n emptyUploadTitle: string\n emptyUploadDescription: string\n workflows: string\n loadingDocuments: string\n stop: string\n stopped: string\n loadingConversation: string\n historyFailedTitle: string\n /** Accessible name of a citation mark. */\n citation: (num: string, source: string) => string\n /** Heading of the citation popover. */\n citationHeading: (num: string) => string\n citationNoSource: string\n openDocument: string\n page: (page: number) => string\n morePassages: (count: number) => string\n}\n\nexport const DEFAULT_CHAT_PAGE_LABELS: ChatPageLabels = {\n chat: 'Assistant chat',\n conversations: 'Conversations',\n newChat: 'New chat',\n untitled: 'New chat',\n deleteConversation: (title) => `Delete conversation ${title}`,\n assistant: 'Assistant',\n thinking: 'Thinking…',\n steps: (count) => (count === 1 ? '1 step' : `${count} steps`),\n responseFailed: 'Response failed',\n answerFailedTitle: 'The answer could not be completed',\n uploadFailedTitle: 'The upload failed',\n placeholder: 'Ask about your documents',\n composerAriaLabel: 'Message the assistant',\n documentsInChat: (selected, total) => `${selected} of ${total} documents in this chat`,\n documentsHeading: 'Documents in this chat',\n selectAllDocuments: 'Select all',\n noDocuments: 'No documents yet',\n uploadDocuments: 'Upload documents',\n uploading: 'Uploading…',\n emptyTitle: 'Ask about your documents',\n emptyDescription: 'Every answer is grounded in the selected documents and cites its sources.',\n emptyUploadTitle: 'Add a document to start',\n emptyUploadDescription: 'Upload the documents you want to ask about.',\n workflows: 'Workflows',\n loadingDocuments: 'Loading documents…',\n stop: 'Stop generating',\n stopped: 'Stopped',\n loadingConversation: 'Loading conversation…',\n historyFailedTitle: 'The conversation history could not be used',\n citation: (num, source) => (source ? `Source ${num}: ${source}` : `Source ${num}`),\n citationHeading: (num) => `Source ${num}`,\n citationNoSource: 'The passage for this source is not available.',\n openDocument: 'Open document',\n page: (page) => `Page ${page}`,\n morePassages: (count) => (count === 1 ? '1 more passage' : `${count} more passages`),\n}\n\nexport interface ChatPageProps {\n /** Open a notification at its original message once history has loaded. */\n targetMessageId?: string\n chat: ChatPageController\n /**\n * The stored thread the host names (a `?conversation=` link): selected once the thread list has it. With\n * `onConversationChange` the host hears which stored thread is on screen (`null` after a new thread) and can\n * mirror it; a link the list has not loaded yet is kept meanwhile. Absent: the chat picks its own thread.\n */\n conversationId?: string | null\n onConversationChange?: (conversationId: string | null) => void\n /**\n * `page` (default): a full-page chat; while it is mounted the dock yields (see\n * `useChatSurface`). `dock`: the same chat in the dock, which does not claim the page slot.\n */\n surface?: 'page' | 'dock'\n /** Replaces the heading (default: the active conversation's title). */\n header?: ReactNode\n /** Actions at the right of the header bar. */\n headerActions?: ReactNode\n /**\n * The workflow launcher column. A column beside the chat when the container is wide, a\n * collapsible panel under the header when it is not (so an open dock never squeezes it).\n */\n aside?: ReactNode\n /** Starter questions on the empty conversation; clicking one fills the composer. */\n prompts?: ReadonlyArray<string>\n /** Whether the empty state asks for documents before offering starter prompts. */\n documentsRequired?: boolean\n /** Heading of the empty state; wins over `labels.emptyTitle`. */\n emptyTitle?: string\n /** Sub-heading of the empty state; wins over `labels.emptyDescription`. */\n emptyDescription?: string\n /**\n * Renders an answer. Default: `ChatMessageContent` (markdown: lists, tables, a quiet numbered\n * mark with a source popover for each citation).\n */\n renderContent?: (message: ChatPageMessage) => ReactNode\n /**\n * Opens the cited document (and page) in the host's viewer. Without it the citation popover\n * shows the source and passage and offers no open action.\n */\n onOpenCitation?: (target: ChatCitationTarget) => void\n /**\n * A workflow step by id — its title, kind and phase: a message that started a step shows as that\n * step's chip, as the thread's bar draws it (else its id, as an AI step).\n */\n workflowStepOf?: (stepId: string) => WorkflowStepView | undefined\n /**\n * Container width, in rem, from which `aside` is a column beside the chat; narrower, it is a\n * button-toggled panel over the transcript. Default 60.\n */\n asideBreakpoint?: number\n /**\n * Fill the height left in the nearest scrolling ancestor below the chat's own top (the page\n * header above it, the shell bars around it), measured in dynamic viewport units so a phone's\n * collapsing URL bar cannot cut it. Use it for a chat card placed under a page header.\n */\n fillHeight?: boolean\n /** Smallest height `fillHeight` gives, in px. Default 360. */\n minHeight?: number\n /**\n * One conversation only (e.g. a workflow run's thread): no conversation list, select or New\n * chat; the host picks the thread (`chat.selectThread`).\n */\n singleThread?: boolean\n /** Drop the heading from the header bar (the host's page header already names the chat). */\n compactHeader?: boolean\n /** Accepted upload types for the file picker. */\n accept?: string\n labels?: Partial<ChatPageLabels>\n className?: string\n testIds?: Partial<{\n root: string\n transcript: string\n input: string\n send: string\n documents: string\n upload: string\n alert: string\n asideToggle: string\n aside: string\n }>\n}\n\n/** A workflow step as a chat shows it: its title, kind and where it is. */\nexport interface WorkflowStepView {\n title?: string\n kind?: WorkflowStepKind\n phase?: WorkflowStepPhase\n /** The step's document (its latest version): opened from beside its chip. */\n document?: { name: string; onOpen: () => void }\n}\n","import { useCallback, useMemo, type ReactNode } from 'react'\nimport { MarkdownRenderer, closeOpenEmphasis, trimOpenCitation } from '@arbidocs/react/ui'\nimport { CitationMark } from './CitationMark'\nimport {\n DEFAULT_CHAT_PAGE_LABELS,\n type ChatCitationTarget,\n type ChatPageLabels,\n type ChatPageMessage,\n} from './chat-page-types'\n\nexport interface ChatMessageContentProps {\n message: ChatPageMessage\n labels?: Partial<ChatPageLabels>\n /** Opens the cited document in the host's viewer. */\n onOpenCitation?: (target: ChatCitationTarget) => void\n className?: string\n}\n\n/**\n * The one renderer of an assistant answer, used by `ChatPage` and `AssistantDock` (the dock is the\n * same page). Markdown (lists, tables, code) where each `[statement](#cite-N)` shows the statement\n * as plain text followed by a quiet numbered mark; the mark opens the source popover when the\n * message carries `citations`. Literal `(*Source: ...*)` notes are tidied by the markdown\n * normaliser; a stopped answer says so.\n */\nexport function ChatMessageContent({\n message,\n labels,\n onOpenCitation,\n className,\n}: ChatMessageContentProps) {\n const l = { ...DEFAULT_CHAT_PAGE_LABELS, ...labels }\n // Only the citation labels reach the marks, and they are stable unless the host swaps them, so\n // a re-render (a streaming token) never makes the markdown re-parse every block.\n const { citation, citationHeading, citationNoSource, openDocument, page } = l\n const citationLabels = useMemo(\n () => ({ citation, citationHeading, citationNoSource, openDocument, page }),\n [citation, citationHeading, citationNoSource, openDocument, page]\n )\n const byNum = useMemo(\n () => new Map((message.citations ?? []).map((c) => [c.num, c])),\n [message.citations]\n )\n const renderCitation = useCallback(\n ({ num, children }: { num: string; children: ReactNode }) => (\n <>\n {children}\n <CitationMark\n num={num}\n citation={byNum.get(num)}\n labels={citationLabels}\n onOpen={onOpenCitation}\n />\n </>\n ),\n [byNum, citationLabels, onOpenCitation]\n )\n return (\n <>\n <MarkdownRenderer\n isStreaming={message.status === 'streaming'}\n renderCitation={renderCitation}\n className={className}\n >\n {/* While streaming the renderer tidies the open tail itself; a stopped answer stays open. */}\n {message.stopped ? closeOpenEmphasis(trimOpenCitation(message.content)) : message.content}\n </MarkdownRenderer>\n {message.stopped && (\n <p className=\"mt-2 text-xs italic text-muted-foreground\" data-testid=\"chat-stopped\">\n {l.stopped}\n </p>\n )}\n </>\n )\n}\n","import { useState } from 'react'\nimport { Loader2, Upload } from 'lucide-react'\nimport { Button, Popover, PopoverContent, PopoverTrigger } from '@arbidocs/react/ui'\nimport { ContextChip } from './ContextChip'\nimport { testIdOr } from './test-id'\nimport type { ChatPageController, ChatPageLabels } from './chat-page-types'\n\ninterface ChatDocumentsProps {\n chat: Pick<\n ChatPageController,\n 'documents' | 'isUploading' | 'toggleDocument' | 'selectAllDocuments'\n >\n labels: ChatPageLabels\n onPickFiles: () => void\n testIds?: Partial<{ documents: string; upload: string }>\n}\n\n/**\n * The document context chip of the composer: how many documents the questions are grounded on,\n * and a popover to pick them or upload more. The count is on the chip, the names are in the list,\n * so the same part reads in a dock (no room) and on a page.\n */\nexport function ChatDocuments({ chat, labels, onPickFiles, testIds }: ChatDocumentsProps) {\n const [isOpen, setIsOpen] = useState(false)\n const selected = chat.documents.filter((d) => d.isSelected).length\n const total = chat.documents.length\n return (\n <Popover open={isOpen} onOpenChange={setIsOpen}>\n <PopoverTrigger asChild>\n <ContextChip\n count={selected}\n label={labels.documentsInChat(selected, total)}\n isOpen={isOpen}\n data-testid={testIdOr(testIds?.documents, { testId: 'chat-documents' })}\n className=\"pointer-coarse:h-11\"\n />\n </PopoverTrigger>\n <PopoverContent\n align=\"start\"\n className=\"w-80 p-3\"\n aria-label={labels.documentsHeading}\n data-testid=\"chat-documents-panel\"\n >\n <div className=\"mb-2 flex items-center justify-between gap-2\">\n <h3 className=\"text-sm font-medium text-foreground\">{labels.documentsHeading}</h3>\n {total > 0 && selected < total && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"pointer-coarse:min-h-11\"\n onClick={chat.selectAllDocuments}\n >\n {labels.selectAllDocuments}\n </Button>\n )}\n </div>\n {total === 0 ? (\n <p className=\"py-2 text-sm text-muted-foreground\">{labels.noDocuments}</p>\n ) : (\n <ul className=\"max-h-60 overflow-y-auto\">\n {chat.documents.map((doc) => (\n <li key={doc.id}>\n <label className=\"flex cursor-pointer items-center gap-2 rounded-md px-1 py-1.5 text-sm hover:bg-muted pointer-coarse:min-h-11\">\n <input\n type=\"checkbox\"\n checked={doc.isSelected}\n onChange={() => chat.toggleDocument(doc.id)}\n className=\"size-4 shrink-0 accent-[hsl(var(--primary))]\"\n />\n <span className=\"min-w-0 truncate\" title={doc.name}>\n {doc.name}\n </span>\n </label>\n </li>\n ))}\n </ul>\n )}\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"mt-2 w-full gap-2 pointer-coarse:min-h-11\"\n disabled={chat.isUploading}\n onClick={onPickFiles}\n data-testid={testIdOr(testIds?.upload, { testId: 'chat-upload' })}\n >\n {chat.isUploading ? (\n <Loader2 className=\"size-4 animate-spin\" aria-hidden=\"true\" />\n ) : (\n <Upload className=\"size-4\" aria-hidden=\"true\" />\n )}\n {chat.isUploading ? labels.uploading : labels.uploadDocuments}\n </Button>\n </PopoverContent>\n </Popover>\n )\n}\n","import { MessageSquarePlus, Trash2 } from 'lucide-react'\nimport { Button, cn } from '@arbidocs/react/ui'\nimport { testIdOr } from './test-id'\nimport type { ChatPageLabels, ChatPageThread } from './chat-page-types'\n\ninterface ThreadProps {\n threads: ReadonlyArray<ChatPageThread>\n activeId: string\n labels: ChatPageLabels\n onSelect: (id: string) => void\n onNew: () => void\n onDelete?: (id: string) => void\n /** The stored conversations are still loading. */\n isLoading?: boolean\n testIds?: Partial<{ list: string; row: string; delete: string; new: string; select: string }>\n}\n\n/**\n * The conversation list as a column (wide containers): New chat on top, one row per thread with a\n * delete action. The active row is `aria-current`. Rows are real buttons, so keyboard and touch\n * work; delete is always visible on touch and appears on hover/focus elsewhere.\n */\nexport function ChatThreadList({\n threads,\n activeId,\n labels,\n onSelect,\n onNew,\n onDelete,\n isLoading,\n testIds,\n}: ThreadProps) {\n return (\n <nav\n aria-label={labels.conversations}\n data-slot=\"chat-thread-list\"\n data-testid={testIdOr(testIds?.list, { testId: 'chat-thread-list' })}\n className=\"flex min-h-0 flex-1 flex-col gap-2 p-3\"\n >\n <Button\n type=\"button\"\n variant=\"outline\"\n className=\"w-full justify-start gap-2 pointer-coarse:min-h-11\"\n onClick={onNew}\n data-testid={testIdOr(testIds?.new, { testId: 'chat-new' })}\n >\n <MessageSquarePlus className=\"size-4\" aria-hidden=\"true\" />\n {labels.newChat}\n </Button>\n <ul\n className=\"flex min-h-0 flex-1 flex-col gap-0.5 overflow-y-auto\"\n aria-busy={isLoading ? 'true' : undefined}\n >\n {threads.map((thread) => {\n const isActive = thread.id === activeId\n const title = thread.title || labels.untitled\n return (\n <li key={thread.id} className=\"group relative\">\n <button\n type=\"button\"\n onClick={() => onSelect(thread.id)}\n aria-current={isActive ? 'true' : undefined}\n title={title}\n data-testid={`${testIdOr(testIds?.row, { testId: 'chat-conversation' })}-${thread.id}`}\n className={cn(\n 'flex w-full items-center rounded-md px-3 py-2 pr-10 text-left text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring pointer-coarse:min-h-11',\n isActive\n ? 'bg-muted font-medium text-foreground'\n : 'text-muted-foreground hover:bg-muted/60 hover:text-foreground'\n )}\n >\n <span className=\"truncate\">{title}</span>\n </button>\n {onDelete && (\n <button\n type=\"button\"\n onClick={() => onDelete(thread.id)}\n aria-label={labels.deleteConversation(title)}\n data-testid={`${testIdOr(testIds?.delete, { testId: 'chat-delete' })}-${thread.id}`}\n className=\"absolute right-1 top-1/2 flex size-8 -translate-y-1/2 items-center justify-center rounded-md text-muted-foreground opacity-100 hover:bg-background hover:text-foreground focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring pointer-fine:opacity-0 pointer-fine:group-hover:opacity-100 pointer-coarse:size-11\"\n >\n <Trash2 className=\"size-4\" aria-hidden=\"true\" />\n </button>\n )}\n </li>\n )\n })}\n </ul>\n </nav>\n )\n}\n\n/**\n * The conversation list as one native select (narrow containers, the dock). Native on purpose:\n * the platform picker on a phone, a label for screen readers, text at least 16px on touch.\n */\nexport function ChatThreadSelect({\n threads,\n activeId,\n labels,\n onSelect,\n testIds,\n}: Pick<ThreadProps, 'threads' | 'activeId' | 'labels' | 'onSelect' | 'testIds'>) {\n return (\n <select\n aria-label={labels.conversations}\n value={activeId}\n onChange={(e) => onSelect(e.target.value)}\n data-testid={testIdOr(testIds?.select, { testId: 'chat-conversation-select' })}\n className=\"h-9 min-w-0 flex-1 truncate rounded-md border border-input bg-background px-2 text-sm font-medium text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring pointer-coarse:h-11 pointer-coarse:text-base\"\n >\n {threads.map((thread) => (\n <option key={thread.id} value={thread.id}>\n {thread.title || labels.untitled}\n </option>\n ))}\n </select>\n )\n}\n","import { useEffect, useSyncExternalStore } from 'react'\n\n/**\n * Which chat surface is on screen. A full-page chat (`ChatPage`, `surface=\"page\"`) and the\n * docked chat must never be offered together: the page chat registers itself while mounted,\n * and the host's dock reads `useChatSurface()` to yield.\n *\n * ```tsx\n * const { isDockAvailable } = useChatSurface()\n * {isDockAvailable && <ChatDockToggle />} // topbar button\n * {isDockAvailable && <ChatDock />} // the Shell.Dock\n * ```\n *\n * The dock keeps its own open/closed state, so it comes back as it was when the user leaves the\n * page chat. A module-level counter (not React context) so the page and the dock agree wherever\n * they sit in the tree, and nested or concurrent page chats are counted rather than overwritten.\n */\nlet embeddedCount = 0\nconst listeners = new Set<() => void>()\n\nfunction subscribe(listener: () => void): () => void {\n listeners.add(listener)\n return () => listeners.delete(listener)\n}\n\nfunction emit() {\n listeners.forEach((l) => l())\n}\n\n/** Claims the page-chat slot while `enabled` and the caller is mounted. `ChatPage` calls this. */\nexport function useRegisterEmbeddedChat(enabled = true): void {\n useEffect(() => {\n if (!enabled) return\n embeddedCount += 1\n emit()\n return () => {\n embeddedCount -= 1\n emit()\n }\n }, [enabled])\n}\n\nexport interface ChatSurface {\n /** A full-page chat is mounted. */\n hasEmbeddedChat: boolean\n /** The dock (and its topbar button) may be offered: false while a page chat is mounted. */\n isDockAvailable: boolean\n}\n\nexport function useChatSurface(): ChatSurface {\n const count = useSyncExternalStore(\n subscribe,\n () => embeddedCount,\n () => 0\n )\n return { hasEmbeddedChat: count > 0, isDockAvailable: count === 0 }\n}\n","/**\n * A chat's side of `openNewConversation({ prompt })`: when a prompt is asked for, open a fresh\n * conversation (unless the one on screen is already empty) and send the prompt once it, and the\n * documents it is grounded on, are ready.\n */\nimport { useEffect, useRef } from 'react'\nimport { conversationStartRequest, useIntentRequest } from '../provider/requests'\nimport type { ChatPageController } from './chat-page-types'\n\ntype StartableChat = Pick<\n ChatPageController,\n 'activeThreadId' | 'messages' | 'isRunning' | 'isLoadingDocuments' | 'newThread' | 'send'\n>\n\n/** The active conversation is new and empty (a stored one's id starts with `con-`). */\nfunction isBlank(chat: StartableChat): boolean {\n return !chat.activeThreadId.startsWith('con-') && chat.messages.length === 0\n}\n\n/** Take the requested first messages while `enabled` (the chat on screen takes them). */\nexport function useStartRequestedConversation(chat: StartableChat, enabled = true): void {\n const pending = useRef<string | null>(null)\n useIntentRequest(\n conversationStartRequest,\n (prompt) => {\n pending.current = prompt\n if (!isBlank(chat)) chat.newThread()\n },\n enabled\n )\n const isFresh = isBlank(chat) && !chat.isRunning && !chat.isLoadingDocuments\n const { send } = chat\n useEffect(() => {\n if (!pending.current || !isFresh) return\n const prompt = pending.current\n pending.current = null\n void send(prompt)\n }, [isFresh, send])\n}\n","/**\n * A chat's thread, controlled by the host (a `?conversation=` link): `conversationId` selects that stored thread\n * once the thread list has it, and `onConversationChange` reports the stored thread on screen (`null` after a new\n * thread), so the host can mirror it. A link to a thread the list has not loaded yet is kept, not overwritten by\n * the thread on screen meanwhile.\n */\nimport { useCallback, useEffect, useRef } from 'react'\nimport type { ChatPageController } from './chat-page-types'\n\ntype ControlledChat = Pick<\n ChatPageController,\n 'threads' | 'activeThreadId' | 'selectThread' | 'newThread'\n>\n\n/** Returns the chat's `newThread`, which also reports `null`. Inert without `conversationId` and the callback. */\nexport function useControlledThread(\n chat: ControlledChat,\n conversationId: string | null | undefined,\n onConversationChange?: (conversationId: string | null) => void\n): () => void {\n const { threads, activeThreadId, selectThread, newThread } = chat\n // The thread the host's id last named and this hook acted on, and the one a selection is still switching to.\n const applied = useRef<string | null>(null)\n const switching = useRef<string | null>(null)\n const report = useRef(onConversationChange)\n report.current = onConversationChange\n\n useEffect(() => {\n if (!conversationId || applied.current === conversationId) return\n if (!threads.some((t) => t.id === conversationId)) return\n applied.current = conversationId\n if (activeThreadId !== conversationId) {\n switching.current = conversationId\n selectThread(conversationId)\n }\n }, [conversationId, selectThread, threads, activeThreadId])\n\n useEffect(() => {\n if (!report.current) return\n if (switching.current) {\n if (activeThreadId !== switching.current) return\n switching.current = null\n }\n // A linked thread that has not been applied yet (the list is still loading) keeps the link.\n if (conversationId && applied.current !== conversationId) return\n // Only a stored thread (`con-…`) has an id to link to; a new one is reported by `newThread`.\n if (!activeThreadId.startsWith('con-') || activeThreadId === conversationId) return\n applied.current = activeThreadId\n report.current(activeThreadId)\n }, [activeThreadId, conversationId])\n\n return useCallback(() => {\n newThread()\n applied.current = null\n report.current?.(null)\n }, [newThread])\n}\n","import { useLayoutEffect, useState, type RefObject } from 'react'\nimport { observeResize } from './observe-resize'\n\n/** Space below the element that its ancestors (up to and including `until`) keep for themselves. */\nfunction bottomSpace(el: HTMLElement, until: HTMLElement): number {\n let space = 0\n for (let node = el.parentElement; node; node = node.parentElement) {\n const style = getComputedStyle(node)\n space += (parseFloat(style.paddingBottom) || 0) + (parseFloat(style.borderBottomWidth) || 0)\n if (node === until) break\n }\n return space\n}\n\nfunction scrollParent(el: HTMLElement): HTMLElement | null {\n for (let node = el.parentElement; node; node = node.parentElement) {\n const overflowY = getComputedStyle(node).overflowY\n if (overflowY === 'auto' || overflowY === 'scroll') return node\n }\n return null\n}\n\n/**\n * The height an element should take to fill what is left of its scrolling ancestor below its own\n * top (page header above it, shell bars around it): the ancestor's visible height minus the\n * element's offset inside its content and the ancestor's bottom padding. With no scrolling ancestor\n * it is the visual viewport below the element. Dynamic viewport units end up in the ancestor\n * (the shell is `h-dvh`), so a phone's collapsing URL bar cannot cut the chat. `null` until\n * measured or when disabled.\n */\nexport function useFillHeight(\n ref: RefObject<HTMLElement | null>,\n enabled: boolean,\n minHeight: number\n): number | null {\n const [height, setHeight] = useState<number | null>(null)\n useLayoutEffect(() => {\n const el = ref.current\n if (!enabled || !el) return\n const scroller = scrollParent(el)\n const measure = () => {\n const viewport = window.visualViewport?.height ?? window.innerHeight\n const rect = el.getBoundingClientRect()\n const scrolled = scroller ? scroller.scrollTop : window.scrollY\n let available: number\n if (scroller) {\n // The element's offset inside the scroll content, not in the viewport.\n const top = rect.top - scroller.getBoundingClientRect().top\n available = scroller.clientHeight - (top + scrolled) - bottomSpace(el, scroller)\n } else {\n available = viewport - rect.top\n }\n // Never run under a pinned phone tab bar (a host whose page scrolls the window, or a\n // scroller that extends below the bar): the composer must stay above it. The bar's own\n // inset is read from it directly (`--shell-bottom-inset` also counts the composer itself).\n const bar = document.querySelector('[data-slot=\"mobile-tab-bar\"]')?.getBoundingClientRect()\n const barHeight = bar && bar.height > 0 ? Math.max(0, viewport - bar.top) : 0\n available = Math.min(available, viewport - barHeight - (rect.top + scrolled))\n setHeight(Math.max(minHeight, Math.floor(available)))\n }\n measure()\n window.addEventListener('resize', measure)\n window.visualViewport?.addEventListener('resize', measure)\n const stopObserving = scroller ? observeResize(scroller, measure) : () => {}\n return () => {\n window.removeEventListener('resize', measure)\n window.visualViewport?.removeEventListener('resize', measure)\n stopObserving()\n }\n }, [ref, enabled, minHeight])\n return enabled ? height : null\n}\n","import { useCallback, useEffect, useMemo, useRef, useState, type FormEvent } from 'react'\nimport { Loader2, MessageSquarePlus, PanelRight, Square, Upload } from 'lucide-react'\nimport { Button, cn } from '@arbidocs/react/ui'\nimport { rootFontSizePx, useElementSize } from '../lib/useElementSize'\nimport { useFillHeight } from '../lib/useFillHeight'\nimport { ChatMessageContent } from './ChatMessageContent'\nimport { ChatDocuments } from './ChatDocuments'\nimport { ChatThreadList, ChatThreadSelect } from './ChatThreads'\nimport { useRegisterEmbeddedChat } from './chat-surface'\nimport { useStartRequestedConversation } from './useStartRequestedConversation'\nimport { useControlledThread } from './useControlledThread'\nimport {\n DEFAULT_CHAT_PAGE_LABELS,\n type ChatPageLabels,\n type ChatPageMessage,\n type ChatPageProps,\n} from './chat-page-types'\nimport { Composer, ScrollToBottom } from './Composer'\nimport { ConversationEmpty } from './ConversationEmpty'\nimport { Message } from './Message'\nimport { MessageAlert } from './MessageAlert'\nimport { MessageList } from './MessageList'\nimport { AssistantModeToggle } from './AssistantModeToggle'\nimport { MentionMenu } from './MentionMenu'\nimport { SlashMenu, type SlashMenuItem } from './SlashMenu'\nimport { filterSlashItems, parseSlashToken } from './slash-menu-helpers'\nimport { useListKeyNav } from '../lib/useListKeyNav'\nimport { useMentionAutocomplete } from './useMentionAutocomplete'\nimport { extractMentions, toMessageMentions } from '@arbidocs/react/shell'\nimport { testIdOr } from './test-id'\nimport { useStreamAnnouncement } from './useStreamAnnouncement'\nimport { WorkflowStepChip } from './WorkflowStepChip'\n\n/**\n * The user bubble, themeable with two optional tokens (HSL triplets, like every colour token):\n * `--chat-user-bubble` and `--chat-user-bubble-foreground`. They default to the tonal\n * `--muted` / `--foreground` pair; a brand sets a dark bubble with light text by defining both.\n * Markdown inside inherits the bubble's text colour.\n */\nconst USER_BUBBLE =\n 'bg-[color:hsl(var(--chat-user-bubble,var(--muted)))] text-[color:hsl(var(--chat-user-bubble-foreground,var(--foreground)))]'\n\nconst NEAR_BOTTOM_PX = 96\n\n/** Container width, in rem, from which the conversation list is a column instead of a select. */\nconst LIST_COLUMN_REM = 48\nconst DEFAULT_ASIDE_BREAKPOINT_REM = 60\n\ninterface MessageRowProps {\n message: ChatPageMessage\n renderContent: ChatPageProps['renderContent']\n onOpenCitation: ChatPageProps['onOpenCitation']\n workflowStepOf: ChatPageProps['workflowStepOf']\n labels: ChatPageLabels\n}\n\nfunction MessageRow({\n message,\n renderContent,\n onOpenCitation,\n workflowStepOf,\n labels,\n}: MessageRowProps) {\n if (message.role === 'user' && message.workflowStep) {\n // Centred, as the step itself: not a bubble from whoever started the run.\n return (\n <WorkflowStepChip\n step={message.workflowStep}\n {...workflowStepOf?.(message.workflowStep)}\n content={message.content}\n messageId={message.id}\n />\n )\n }\n if (message.role === 'user') {\n return (\n <Message.Root role=\"user\" messageId={message.id}>\n <Message.Content\n role=\"user\"\n messageId={message.id}\n align={message.fromOther ? 'start' : 'end'}\n >\n {message.senderName && (\n <span className=\"text-xs text-muted-foreground\">{message.senderName}</span>\n )}\n <Message.Bubble\n role=\"user\"\n messageId={message.id}\n className={USER_BUBBLE}\n testId=\"chat-message-user\"\n >\n <p className=\"m-0 whitespace-pre-wrap break-words text-base leading-relaxed\">\n {message.content}\n </p>\n </Message.Bubble>\n </Message.Content>\n </Message.Root>\n )\n }\n const isStreaming = message.status === 'streaming'\n const isFailed = message.status === 'error'\n const hasText = message.content.trim() !== ''\n return (\n <Message.Root role=\"assistant\" messageId={message.id} tone={isFailed ? 'error' : undefined}>\n <Message.Content role=\"assistant\" messageId={message.id}>\n <Message.Bubble role=\"assistant\" messageId={message.id} testId=\"chat-message-assistant\">\n <Message.Byline\n messageId={message.id}\n identity={<span className=\"font-medium\">{labels.assistant}</span>}\n timeLabel={message.stepCount ? labels.steps(message.stepCount) : ''}\n isSettled={!isStreaming}\n isFailed={isFailed}\n statusLabel={isFailed ? labels.responseFailed : ''}\n />\n {hasText &&\n (renderContent?.(message) ?? (\n <ChatMessageContent\n message={message}\n labels={labels}\n onOpenCitation={onOpenCitation}\n />\n ))}\n {!hasText && message.stopped && (\n <p className=\"text-xs italic text-muted-foreground\" data-testid=\"chat-stopped\">\n {labels.stopped}\n </p>\n )}\n {isStreaming && !hasText && (\n <span\n className=\"flex items-center gap-2 text-muted-foreground\"\n data-testid=\"chat-streaming\"\n >\n <Loader2 className=\"size-4 animate-spin motion-reduce:animate-none\" aria-hidden />\n {labels.thinking}\n </span>\n )}\n </Message.Bubble>\n </Message.Content>\n </Message.Root>\n )\n}\n\n/**\n * A complete assistant chat, composed from the same parts as the dock: conversation list with\n * titles (stored conversations included), message list with source popovers on citations,\n * composer with the document chip, upload and stop, empty state, error and retry. Drive it with\n * `useConversation()` from `@arbidocs/react` (or fill `ChatPageController`).\n *\n * It lays itself out by its own width, not the viewport's, so it holds up in a card, beside an\n * open dock or on a phone: the conversation list is a column from 48rem and a select below; the\n * `aside` slot (workflow launcher) is a column from `asideBreakpoint` (60rem) and below that one\n * button-toggled panel over the transcript, so it never pushes the conversation down. Every part\n * renders once. Give it a height (`h-full` of a sized parent, a `className`) or `fillHeight`\n * under a page header. Colours come from the tokens only; the user bubble has two optional ones\n * (see `USER_BUBBLE`).\n *\n * With `surface=\"page\"` it claims the page-chat slot, so `useChatSurface()` tells the host's dock\n * to yield: one chat on screen, never two.\n */\nexport function ChatPage({\n chat: hostChat,\n conversationId,\n onConversationChange,\n surface = 'page',\n header,\n headerActions,\n aside,\n prompts = [],\n documentsRequired = true,\n emptyTitle,\n emptyDescription,\n renderContent,\n onOpenCitation,\n workflowStepOf,\n singleThread,\n targetMessageId,\n asideBreakpoint = DEFAULT_ASIDE_BREAKPOINT_REM,\n fillHeight = false,\n minHeight = 360,\n compactHeader = false,\n accept,\n labels,\n className,\n testIds,\n}: ChatPageProps) {\n const l = { ...DEFAULT_CHAT_PAGE_LABELS, ...labels }\n const controlledNewThread = useControlledThread(hostChat, conversationId, onConversationChange)\n const isControlled = conversationId !== undefined || onConversationChange !== undefined\n const chat = useMemo(\n () => (isControlled ? { ...hostChat, newThread: controlledNewThread } : hostChat),\n [hostChat, isControlled, controlledNewThread]\n )\n useRegisterEmbeddedChat(surface === 'page')\n // The page chat takes `openNewConversation({ prompt })`: a fresh conversation, sent on arrival.\n useStartRequestedConversation(chat, surface === 'page' && !singleThread)\n\n const [draft, setDraft] = useState('')\n const [isAsideOpen, setIsAsideOpen] = useState(false)\n const [isAway, setIsAway] = useState(false)\n const rootRef = useRef<HTMLElement>(null)\n const headerRef = useRef<HTMLDivElement>(null)\n const asideToggleRef = useRef<HTMLButtonElement>(null)\n const asideRef = useRef<HTMLElement>(null)\n const scrollRef = useRef<HTMLDivElement>(null)\n const jumpedToMessage = useRef<string | null>(null)\n const fileRef = useRef<HTMLInputElement>(null)\n const textareaRef = useRef<HTMLTextAreaElement>(null)\n const currentThreadRef = useRef(chat.activeThreadId)\n currentThreadRef.current = chat.activeThreadId\n const mentions = useMentionAutocomplete({\n value: draft,\n onValueChange: setDraft,\n candidates: chat.mentionCandidates ?? [],\n textareaRef,\n })\n\n // The `/` menu (when the chat has one): the rows matching the slash command being typed. A\n // picked skill opens its form (`slash.pick`); anything else is inserted as `/name `.\n const slash = chat.slash\n const slashToken = slash ? parseSlashToken(draft) : null\n const slashItems = useMemo(\n () => (slash && slashToken !== null ? filterSlashItems([...slash.items], slashToken) : []),\n [slash, slashToken]\n )\n const isSlashOpen = slashItems.length > 0\n const pickSlash = (item: SlashMenuItem) => {\n if (slash?.pick(item)) {\n setDraft('')\n return\n }\n const next = `/${item.name} `\n setDraft(next)\n requestAnimationFrame(() => {\n textareaRef.current?.focus()\n textareaRef.current?.setSelectionRange(next.length, next.length)\n })\n }\n const slashNav = useListKeyNav({\n open: isSlashOpen,\n items: slashItems,\n onPick: pickSlash,\n // Clear the leading slash to dismiss; otherwise the menu reopens on the next letter.\n onDismiss: () => setDraft(''),\n resetKey: slashToken,\n })\n\n // Layout modes come from the chat's own width (a container query with a configurable\n // threshold), so each part is in the DOM once. Unmeasured (0) is the narrow layout.\n const { width } = useElementSize(rootRef)\n const { height: headerHeight } = useElementSize(headerRef)\n const rem = rootFontSizePx()\n const hasListColumn = !singleThread && width >= LIST_COLUMN_REM * rem\n const hasAsideColumn = width > 0 && width >= asideBreakpoint * rem\n const fillPx = useFillHeight(rootRef, fillHeight, minHeight)\n\n const closeAside = useCallback(() => setIsAsideOpen(false), [])\n const isAsidePanelOpen = !!aside && !hasAsideColumn && isAsideOpen\n useEffect(() => {\n if (!isAsidePanelOpen) return\n const onKey = (e: KeyboardEvent) => {\n if (e.key !== 'Escape') return\n closeAside()\n asideToggleRef.current?.focus()\n }\n const onPointer = (e: PointerEvent) => {\n const target = e.target as Node\n if (asideRef.current?.contains(target) || asideToggleRef.current?.contains(target)) return\n closeAside()\n }\n document.addEventListener('keydown', onKey)\n document.addEventListener('pointerdown', onPointer)\n return () => {\n document.removeEventListener('keydown', onKey)\n document.removeEventListener('pointerdown', onPointer)\n }\n }, [isAsidePanelOpen, closeAside])\n\n const last = chat.messages[chat.messages.length - 1]\n const announcement = useStreamAnnouncement({\n isStreaming: chat.isRunning,\n text: last?.role === 'assistant' ? last.content : '',\n resetKey: chat.activeThreadId,\n })\n\n const scrollToEnd = useCallback(() => {\n const el = scrollRef.current\n if (el) el.scrollTop = el.scrollHeight\n }, [])\n\n // Follow the answer while the reader is at the bottom; leave them alone once they scroll up.\n useEffect(() => {\n if (!isAway) scrollToEnd()\n }, [chat.messages, isAway, scrollToEnd])\n\n useEffect(() => {\n if (!targetMessageId) {\n jumpedToMessage.current = null\n return\n }\n const key = `${chat.activeThreadId}:${targetMessageId}`\n if (jumpedToMessage.current === key) return\n const row = Array.from(\n scrollRef.current?.querySelectorAll<HTMLElement>('[data-message-id]') || []\n ).find((element) => element.dataset.messageId === targetMessageId)\n if (!row) return\n jumpedToMessage.current = key\n row.scrollIntoView({ block: 'center' })\n setIsAway(true)\n }, [targetMessageId, chat.activeThreadId, chat.messages])\n useEffect(() => {\n setIsAway(false)\n }, [chat.activeThreadId])\n\n const onScroll = () => {\n const el = scrollRef.current\n if (el) setIsAway(el.scrollHeight - el.scrollTop - el.clientHeight > NEAR_BOTTOM_PX)\n }\n\n const submit = (e?: FormEvent) => {\n e?.preventDefault()\n const text = draft.trim()\n if (\n !text ||\n chat.isRunning ||\n chat.isPostingComment ||\n chat.isUpdatingAssistantMode ||\n chat.isLoadingThread ||\n chat.historyError\n )\n return\n setDraft('')\n // `/skill text` opens the skill's form with the text filled in; it is not sent as typed.\n if (slash?.startDraft(text)) return\n setIsAway(false)\n const selectedMentions = toMessageMentions(extractMentions(text, chat.mentionCandidates ?? []))\n const threadId = chat.activeThreadId\n const restoreDraft = () => {\n if (currentThreadRef.current === threadId) setDraft((current) => current || text)\n }\n try {\n const sent = selectedMentions.length\n ? chat.send(text, { mentions: selectedMentions })\n : chat.send(text)\n void Promise.resolve(sent).catch(restoreDraft)\n } catch {\n restoreDraft()\n }\n }\n\n const pickFiles = () => fileRef.current?.click()\n const onFiles = (files: File[]) => {\n if (files.length > 0) void chat.upload(files)\n }\n\n // Nothing to show in the bar: a compact chat with the list column and no actions or launcher toggle.\n const hasHeader = !(\n compactHeader &&\n hasListColumn &&\n !headerActions &&\n !(aside && !hasAsideColumn)\n )\n const activeThread = chat.threads.find((t) => t.id === chat.activeThreadId)\n const hasDocuments = chat.documents.length > 0\n const isEmpty = chat.messages.length === 0\n const heading = compactHeader\n ? null\n : (header ?? (\n <h2 className=\"min-w-0 truncate text-sm font-semibold text-foreground\">\n {activeThread?.title || l.untitled}\n </h2>\n ))\n\n return (\n <section\n ref={rootRef}\n aria-label={l.chat}\n data-slot=\"chat-page\"\n data-surface={surface}\n data-list={hasListColumn ? 'column' : 'select'}\n data-aside={aside ? (hasAsideColumn ? 'column' : 'panel') : undefined}\n data-testid={testIdOr(testIds?.root, { testId: 'chat-page' })}\n style={fillPx != null ? { height: fillPx } : undefined}\n className={cn(\n '@container/chat relative flex min-h-0 w-full overflow-hidden bg-background text-foreground',\n fillHeight ? 'h-[70dvh]' : 'h-full',\n className\n )}\n >\n {/* Conversation list: a column from 48rem of chat width. */}\n {hasListColumn && (\n <div className=\"flex w-64 shrink-0 flex-col border-r border-border\">\n <ChatThreadList\n threads={chat.threads}\n activeId={chat.activeThreadId}\n isLoading={chat.isLoadingThreads}\n labels={l}\n onSelect={chat.selectThread}\n onNew={chat.newThread}\n onDelete={chat.deleteThread}\n />\n </div>\n )}\n\n <div className=\"flex min-w-0 flex-1 flex-col\">\n {hasHeader && (\n <div\n ref={headerRef}\n data-slot=\"chat-page-header\"\n className=\"flex min-h-12 shrink-0 items-center gap-2 border-b border-border px-3 py-1.5\"\n >\n {/* Narrow: the list is a select and New chat a button; wide: both live in the column. */}\n {hasListColumn || singleThread ? (\n <div className=\"flex min-w-0 flex-1 items-center\">{heading}</div>\n ) : (\n <div className=\"flex min-w-0 flex-1 items-center gap-2\">\n {heading ? <div className=\"min-w-0 shrink\">{heading}</div> : null}\n <ChatThreadSelect\n threads={chat.threads}\n activeId={chat.activeThreadId}\n labels={l}\n onSelect={chat.selectThread}\n />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-9 shrink-0 pointer-coarse:size-11\"\n aria-label={l.newChat}\n onClick={chat.newThread}\n data-testid=\"chat-new-compact\"\n >\n <MessageSquarePlus className=\"size-4\" aria-hidden=\"true\" />\n </Button>\n </div>\n )}\n {aside && !hasAsideColumn && (\n <Button\n ref={asideToggleRef}\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"shrink-0 gap-1.5 pointer-coarse:min-h-11\"\n aria-expanded={isAsideOpen}\n aria-controls=\"chat-page-aside\"\n onClick={() => setIsAsideOpen((v) => !v)}\n data-testid={testIdOr(testIds?.asideToggle, { testId: 'chat-aside-toggle' })}\n >\n <PanelRight className=\"size-4\" aria-hidden=\"true\" />\n {l.workflows}\n </Button>\n )}\n {headerActions}\n </div>\n )}\n\n <MessageList.Root\n isBusy={chat.isRunning}\n testId={testIdOr(testIds?.transcript, { testId: 'chat-messages' })}\n className=\"relative flex min-h-0 flex-1 flex-col\"\n >\n <MessageList.Status message={announcement} />\n <div\n ref={scrollRef}\n onScroll={onScroll}\n data-slot=\"chat-page-scroll\"\n className=\"scrollbar-themed relative min-h-0 flex-1 overflow-y-auto overscroll-contain\"\n >\n {isEmpty ? (\n chat.isLoadingDocuments || chat.isLoadingThread ? (\n <div\n role=\"status\"\n className=\"flex h-full items-center justify-center text-sm text-muted-foreground\"\n data-testid=\"chat-loading\"\n >\n {chat.isLoadingThread ? l.loadingConversation : l.loadingDocuments}\n </div>\n ) : (\n <ConversationEmpty\n hasDocuments={hasDocuments || !documentsRequired}\n prompts={prompts}\n onUsePrompt={(text) => {\n setDraft(text)\n textareaRef.current?.focus()\n }}\n onAddDocuments={(files) => (files ? onFiles(files) : pickFiles())}\n title={emptyTitle ?? l.emptyTitle}\n description={emptyDescription ?? l.emptyDescription}\n className=\"pb-6\"\n noDocuments={\n <>\n <div className=\"text-center\">\n <h2 className=\"text-lg font-semibold\">{l.emptyUploadTitle}</h2>\n <p className=\"mt-1 text-sm text-muted-foreground\">\n {l.emptyUploadDescription}\n </p>\n </div>\n <Button\n type=\"button\"\n className=\"gap-2 pointer-coarse:min-h-11\"\n onClick={pickFiles}\n disabled={chat.isUploading}\n >\n <Upload className=\"size-4\" aria-hidden=\"true\" />\n {chat.isUploading ? l.uploading : l.uploadDocuments}\n </Button>\n </>\n }\n />\n )\n ) : (\n <div\n role=\"list\"\n aria-label=\"Conversation messages\"\n className=\"mx-auto flex w-full max-w-3xl flex-col gap-5 px-3 py-5 @lg/chat:px-6\"\n >\n {chat.messages.map((message) => (\n <div\n key={message.id}\n role=\"listitem\"\n data-message-id={message.id}\n className={\n message.id === targetMessageId\n ? 'rounded-lg ring-2 ring-primary/40'\n : undefined\n }\n >\n <MessageRow\n message={message}\n renderContent={renderContent}\n onOpenCitation={onOpenCitation}\n workflowStepOf={workflowStepOf}\n labels={l}\n />\n </div>\n ))}\n </div>\n )}\n </div>\n <ScrollToBottom\n className=\"bottom-3 top-auto\"\n show={isAway && !isEmpty}\n onClick={() => {\n setIsAway(false)\n scrollToEnd()\n }}\n />\n </MessageList.Root>\n\n <div className=\"shrink-0 border-t border-border/60 bg-background px-3 pb-3 pt-2 @lg/chat:px-6\">\n <div className=\"mx-auto w-full max-w-3xl\">\n {chat.error && (\n <MessageAlert\n title={l.answerFailedTitle}\n description={chat.error}\n isBusy={chat.isRunning}\n onActivate={() => void chat.retry()}\n testId={testIdOr(testIds?.alert, { testId: 'chat-alert' })}\n />\n )}\n {chat.historyError && (\n <MessageAlert\n title={l.historyFailedTitle}\n description={chat.historyError}\n testId=\"chat-history-alert\"\n />\n )}\n {chat.uploadError && (\n <MessageAlert\n title={l.uploadFailedTitle}\n description={chat.uploadError}\n testId=\"chat-upload-alert\"\n />\n )}\n {slash?.launcher}\n <Composer.Root onSubmit={submit} testId=\"chat-composer\">\n <Composer.Frame className=\"px-3 py-2 shadow-sm\">\n <SlashMenu\n open={isSlashOpen}\n items={slashItems}\n selectedIndex={slashNav.selectedIndex}\n setSelectedIndex={slashNav.setSelectedIndex}\n listboxId={slashNav.listboxId}\n onSelect={pickSlash}\n onBrowse={slash?.onBrowse}\n />\n <MentionMenu\n open={mentions.isOpen}\n items={mentions.items}\n selectedIndex={mentions.nav.selectedIndex}\n setSelectedIndex={mentions.nav.setSelectedIndex}\n listboxId={mentions.nav.listboxId}\n onSelect={mentions.pick}\n />\n <Composer.Input\n value={draft}\n onValueChange={mentions.onValueChange}\n onKeyDown={(event) => {\n if (slashNav.handleKeyDown(event)) return\n mentions.nav.handleKeyDown(event)\n }}\n textareaProps={{\n ...mentions.textareaProps,\n ...(isSlashOpen\n ? slashNav.comboboxProps\n : chat.mentionCandidates?.length\n ? mentions.nav.comboboxProps\n : {}),\n }}\n placeholder={l.placeholder}\n ariaLabel={l.composerAriaLabel}\n textareaRef={textareaRef}\n testId={testIdOr(testIds?.input, { testId: 'chat-input' })}\n />\n <Composer.Toolbar\n leading={\n <>\n {chat.assistantMode && chat.setAssistantMode && (\n <AssistantModeToggle\n mode={chat.assistantMode}\n onModeChange={(mode) => void chat.setAssistantMode?.(mode)}\n disabled={\n chat.isRunning || chat.isPostingComment || chat.isUpdatingAssistantMode\n }\n />\n )}\n <ChatDocuments\n chat={chat}\n labels={l}\n onPickFiles={pickFiles}\n testIds={{ documents: testIds?.documents, upload: testIds?.upload }}\n />\n </>\n }\n trailing={\n chat.isRunning && chat.stop ? (\n <Button\n type=\"button\"\n size=\"icon\"\n variant=\"outline\"\n className=\"h-9 w-9 shrink-0 pointer-coarse:h-11 pointer-coarse:w-11\"\n aria-label={l.stop}\n title={l.stop}\n onClick={chat.stop}\n data-testid=\"chat-stop\"\n >\n <Square className=\"h-3.5 w-3.5 fill-current\" aria-hidden=\"true\" />\n </Button>\n ) : (\n <Composer.Send\n onSend={() => submit()}\n disabled={\n chat.isRunning ||\n chat.isPostingComment ||\n chat.isUpdatingAssistantMode ||\n chat.isLoadingThread ||\n Boolean(chat.historyError) ||\n draft.trim() === ''\n }\n testIds={{ send: testIdOr(testIds?.send, { testId: 'chat-send' }) }}\n />\n )\n }\n />\n </Composer.Frame>\n </Composer.Root>\n </div>\n </div>\n </div>\n\n {/*\n The workflow launcher, rendered once: a column beside the chat from `asideBreakpoint`, and\n below it a panel anchored under the header that floats over the transcript (nothing is\n pushed down) and opens with the header button.\n */}\n {aside && (\n <aside\n ref={asideRef}\n id=\"chat-page-aside\"\n aria-label={l.workflows}\n data-slot=\"chat-page-aside\"\n data-mode={hasAsideColumn ? 'column' : 'panel'}\n data-testid={testIdOr(testIds?.aside, { testId: 'chat-aside' })}\n hidden={!hasAsideColumn && !isAsideOpen}\n style={hasAsideColumn ? undefined : { top: headerHeight + 4 }}\n className={cn(\n 'scrollbar-themed overflow-y-auto bg-background',\n hasAsideColumn\n ? 'w-72 shrink-0 border-l border-border p-4'\n : 'absolute right-2 z-20 max-h-[min(60%,32rem)] w-[min(22rem,calc(100%-1rem))] rounded-lg border border-border bg-popover p-3 text-popover-foreground shadow-lg'\n )}\n >\n {aside}\n </aside>\n )}\n\n <input\n ref={fileRef}\n type=\"file\"\n multiple\n accept={accept}\n className=\"sr-only\"\n tabIndex={-1}\n aria-hidden=\"true\"\n data-testid=\"chat-file-input\"\n onChange={(e) => {\n onFiles(Array.from(e.target.files ?? []))\n e.target.value = ''\n }}\n />\n </section>\n )\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/chat/MessageAlert.tsx","../src/chat/AssistantModeToggle.tsx","../src/chat/ConversationEmpty.tsx","../src/chat/ContextChip.tsx","../src/chat/CitationMark.tsx","../src/chat/chat-page-types.ts","../src/chat/ChatMessageContent.tsx","../src/chat/ChatDocuments.tsx","../src/chat/ChatThreads.tsx","../src/chat/chat-surface.ts","../src/chat/useStartRequestedConversation.ts","../src/chat/useControlledThread.ts","../src/lib/useFillHeight.ts","../src/chat/ChatPage.tsx"],"names":["jsx","cn","jsxs","RotateCw","AlertCircle","Button","MessagesSquare","Bot","Tooltip","TooltipTrigger","testIdOr","TooltipContent","assistantCopy","FileUp","useAssistantCopy","Sparkles","GanttChartSquare","ArrowUpRight","forwardRef","ContextChip","useState","Pencil","FileText","Popover","PopoverTrigger","PopoverContent","useMemo","useCallback","Fragment","MarkdownRenderer","closeOpenEmphasis","trimOpenCitation","Loader2","Upload","MessageSquarePlus","Trash2","useEffect","useSyncExternalStore","useRef","useIntentRequest","conversationStartRequest","useLayoutEffect","observeResize","WorkflowStepChip","Message","useMentionAutocomplete","parseSlashTokenInProgress","filterSlashItems","useListKeyNav","useElementSize","rootFontSizePx","useStreamAnnouncement","toMessageMentions","extractMentions","PanelRight","MessageList","ScrollToBottom","Composer","SlashMenu","MentionMenu","Square"],"mappings":"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","file":"chunk-IDCD5TEZ.cjs","sourcesContent":["import type { ReactNode } from 'react'\nimport { AlertCircle, RotateCw } from 'lucide-react'\nimport { Button, cn } from '@arbidocs/react/ui'\n\n/** Every fixed string of the alert. Pass a partial `labels` to translate or reword. */\nexport interface MessageAlertLabels {\n retrying: string\n /** Name of the retry button rendered for `onActivate`. */\n retry: string\n}\n\nexport const DEFAULT_MESSAGE_ALERT_LABELS: MessageAlertLabels = {\n retrying: 'Retrying...',\n retry: 'Retry',\n}\n\nexport interface MessageAlertProps {\n title: string\n description: string\n /** A retry is in flight: shows a spinner and the busy title. */\n isBusy?: boolean\n /** Title while busy; wins over `labels.retrying`. */\n busyTitle?: string\n labels?: Partial<MessageAlertLabels>\n /** Adds a Retry button (a real, keyboard-operable one) that runs this. */\n onActivate?: () => void\n /** Explicit buttons under the text (e.g. a Retry button). */\n actions?: ReactNode\n className?: string\n testId?: string\n}\n\n/** Tinted alert above the composer: a send that failed, or an answer that never arrived. */\nexport function MessageAlert({\n title,\n description,\n isBusy = false,\n busyTitle,\n labels,\n onActivate,\n actions,\n className,\n testId = 'message-alert',\n}: MessageAlertProps) {\n const l = { ...DEFAULT_MESSAGE_ALERT_LABELS, ...labels }\n return (\n <div\n data-slot=\"message-alert\"\n // A failure interrupts (alert); a retry in flight is only progress (status).\n role={isBusy ? 'status' : 'alert'}\n aria-busy={isBusy}\n className={cn(\n 'mb-3 rounded-lg border border-red-border bg-red-bg px-4 py-2 transition-colors',\n className\n )}\n data-testid={testId}\n >\n <div className=\"flex items-start gap-3\">\n {isBusy ? (\n <RotateCw\n aria-hidden=\"true\"\n className=\"mt-0.5 h-5 w-5 shrink-0 animate-spin text-red-text motion-reduce:animate-none\"\n />\n ) : (\n <AlertCircle aria-hidden=\"true\" className=\"mt-0.5 h-5 w-5 shrink-0 text-red-text\" />\n )}\n <div className=\"min-w-0 flex-1\">\n <p className=\"mb-1 text-base font-medium text-red-text\">\n {isBusy ? (busyTitle ?? l.retrying) : title}\n </p>\n <p className=\"mb-1 text-sm text-muted-foreground\">{description}</p>\n {(actions || onActivate) && (\n <div className=\"mt-2 flex flex-wrap gap-2\">\n {actions}\n {onActivate && (\n <Button\n type=\"button\"\n size=\"sm\"\n variant=\"outline\"\n className=\"pointer-coarse:min-h-11\"\n disabled={isBusy}\n onClick={onActivate}\n data-testid={`${testId}-retry`}\n >\n <RotateCw aria-hidden=\"true\" className=\"mr-2 h-4 w-4\" />\n {l.retry}\n </Button>\n )}\n </div>\n )}\n </div>\n </div>\n </div>\n )\n}\n","import { Bot, MessagesSquare } from 'lucide-react'\nimport { Button, cn, Tooltip, TooltipContent, TooltipTrigger } from '@arbidocs/react/ui'\nimport { testIdOr } from './test-id'\n\n/** When the assistant answers in a conversation (the API's `AssistantMode`). */\nexport type AssistantMode = 'always' | 'mentioned'\n\n/** Every fixed string of the toggle. Pass a partial `labels` to reword. */\nexport interface AssistantModeToggleLabels {\n always: string\n mentioned: string\n /** Tooltip / accessible description per mode. */\n alwaysHint: string\n mentionedHint: string\n}\n\nexport const DEFAULT_ASSISTANT_MODE_TOGGLE_LABELS: AssistantModeToggleLabels = {\n always: 'Assistant replies',\n mentioned: 'Thread',\n alwaysHint: 'The assistant answers every message. Click to make this a thread.',\n mentionedHint:\n 'A thread: messages are comments between people. @mention the assistant to get an answer. Click to have it answer every message.',\n}\n\nexport interface AssistantModeToggleProps {\n mode: AssistantMode\n onModeChange: (mode: AssistantMode) => void\n disabled?: boolean\n labels?: Partial<AssistantModeToggleLabels>\n className?: string\n /** Test id (default `assistant-mode-toggle`); the current mode lands on `data-mode`. */\n testId?: string\n}\n\n/**\n * Composer-toolbar switch between an ordinary chat (`always`: every message gets an answer) and a\n * thread (`mentioned`: the assistant only answers when @mentioned).\n */\nexport function AssistantModeToggle({\n mode,\n onModeChange,\n disabled,\n labels,\n className,\n testId,\n}: AssistantModeToggleProps) {\n const l = { ...DEFAULT_ASSISTANT_MODE_TOGGLE_LABELS, ...labels }\n const isThread = mode === 'mentioned'\n const hint = isThread ? l.mentionedHint : l.alwaysHint\n const Icon = isThread ? MessagesSquare : Bot\n return (\n <Tooltip>\n <TooltipTrigger asChild>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n disabled={disabled}\n aria-pressed={isThread}\n aria-label={`${isThread ? l.mentioned : l.always}. ${hint}`}\n onClick={() => onModeChange(isThread ? 'always' : 'mentioned')}\n className={cn(\n 'h-8 gap-1.5 px-2 text-xs text-muted-foreground hover:bg-muted pointer-coarse:h-11',\n isThread && 'bg-accent text-accent-foreground',\n className\n )}\n data-mode={mode}\n data-testid={testIdOr(testId, { testId: 'assistant-mode-toggle' })}\n >\n <Icon className=\"h-3.5 w-3.5\" aria-hidden=\"true\" />\n <span>{isThread ? l.mentioned : l.always}</span>\n </Button>\n </TooltipTrigger>\n <TooltipContent side=\"top\" className=\"max-w-xs\">\n {hint}\n </TooltipContent>\n </Tooltip>\n )\n}\n","import type { ReactNode } from 'react'\nimport { ArrowUpRight, FileUp, GanttChartSquare, Sparkles } from 'lucide-react'\nimport { cn } from '@arbidocs/react/ui'\nimport { assistantCopy, useAssistantCopy } from '@arbidocs/react/shell'\nimport { testIdOr } from './test-id'\n\nexport interface ConversationShortcut {\n /** Short button label. */\n label: string\n /** Full prompt the host drops into the composer. */\n prompt: string\n}\n\n/** Every fixed string of the empty state. Pass a partial `labels` to translate or reword. */\nexport interface ConversationEmptyLabels {\n title: string\n description: string\n dropDocuments: string\n}\n\n/** ARBI's own phrases (the defaults below). */\nconst ARBI = assistantCopy()\n\nexport const DEFAULT_CONVERSATION_EMPTY_LABELS: ConversationEmptyLabels = {\n title: ARBI.askAboutDocuments,\n description: 'Ask a question and verify every answer against the source.',\n dropDocuments: 'Drop documents here to add them',\n}\n\nexport interface ConversationEmptyProps {\n /** Does the workspace have documents to ask about? Picks the layout. */\n hasDocuments: boolean\n /** Starter questions (has-documents state). */\n prompts: ReadonlyArray<string>\n /** Featured action-shaped shortcut that leads the row. */\n shortcut?: ConversationShortcut\n /** Drop a prompt into the composer. */\n onUsePrompt: (text: string) => void\n /** Add documents: dropped files, or no argument to open the picker. */\n onAddDocuments: (files?: File[]) => void\n /** Rendered instead of the starters when there are no documents (upload box, alt sources). */\n noDocuments: ReactNode\n /**\n * Extra content under the starters (the host's list of things to start). It lives INSIDE the\n * empty state's own scroll area, never in the composer dock: the composer stays anchored at the\n * bottom whatever the length, and a long list scrolls here, above it.\n */\n below?: ReactNode\n /** Heading; wins over `labels.title`. */\n title?: string\n /** Sub-heading; wins over `labels.description`. */\n description?: string\n className?: string\n labels?: Partial<ConversationEmptyLabels>\n /** Per-part test ids; defaults are the current ids. */\n testIds?: Partial<{\n root: string\n upload: string\n shortcut: string\n prompt: string\n }>\n}\n\n/** Quiet \"drop documents here\" row for the has-documents state. */\nfunction AddDocumentsArea({\n onAddDocuments,\n label,\n testId,\n}: {\n onAddDocuments: (files?: File[]) => void\n label: string\n testId: string\n}) {\n return (\n <button\n type=\"button\"\n onClick={() => onAddDocuments()}\n onDragOver={(e) => {\n if (e.dataTransfer.types.includes('Files')) {\n e.preventDefault()\n e.dataTransfer.dropEffect = 'copy'\n }\n }}\n onDrop={(e) => {\n const files = Array.from(e.dataTransfer.files ?? [])\n if (files.length > 0) {\n e.preventDefault()\n onAddDocuments(files)\n }\n }}\n data-testid={testId}\n className=\"mx-auto flex w-full max-w-sm items-center justify-center gap-2 rounded-lg border border-border bg-card px-3 py-2.5 text-sm text-muted-foreground transition-colors hover:border-ring/50 hover:bg-accent/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring pointer-coarse:min-h-11\"\n >\n <FileUp className=\"h-4 w-4 shrink-0\" />\n <span>{label}</span>\n </button>\n )\n}\n\n/** The host's list under the starters: wider than the starters, centred, text left-aligned. */\nconst BELOW = 'mx-auto w-full max-w-4xl text-left'\n\nconst CHIP =\n 'group inline-flex items-center rounded-md border border-border bg-card px-3.5 py-2 text-left text-sm text-foreground transition-colors hover:border-ring/50 hover:bg-accent/40 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring pointer-coarse:min-h-11'\n\n/**\n * Empty state of a brand-new conversation. With no documents the first job is adding one, so\n * the host's upload box leads. With documents it is a one-line framing, a few clickable starter\n * prompts that prefill the composer, and a quiet \"add more\" row.\n */\nexport function ConversationEmpty({\n hasDocuments,\n prompts,\n shortcut,\n onUsePrompt,\n onAddDocuments,\n noDocuments,\n below,\n title,\n description,\n className,\n labels,\n testIds,\n}: ConversationEmptyProps) {\n const assistant = useAssistantCopy()\n const l = {\n ...DEFAULT_CONVERSATION_EMPTY_LABELS,\n title: assistant.askAboutDocuments,\n ...labels,\n }\n const rootTestId = testIdOr(testIds?.root, { testId: 'conversation-empty-state' })\n const uploadTestId = testIdOr(testIds?.upload, { testId: 'conversation-empty-upload' })\n const shortcutTestId = testIdOr(testIds?.shortcut, {\n testId: 'conversation-shortcut-main-events',\n })\n const promptTestId = testIdOr(testIds?.prompt, { testId: 'conversation-example-prompt' })\n // `pb-28` reserves the composer's height so the content reads as centred above the input;\n // the parent is `position: relative`, so inset-0 fills it.\n if (!hasDocuments) {\n return (\n <div\n data-slot=\"conversation-empty\"\n className={cn(\n 'absolute inset-0 flex flex-col items-center overflow-y-auto px-6 py-8 pb-28',\n className\n )}\n data-testid={rootTestId}\n >\n <div className=\"my-auto flex w-full flex-col items-center gap-8\">\n <div className=\"flex w-full max-w-xl flex-col items-center gap-3\">{noDocuments}</div>\n {below && <div className={BELOW}>{below}</div>}\n </div>\n </div>\n )\n }\n\n return (\n <div\n data-slot=\"conversation-empty\"\n className={cn('absolute inset-0 flex overflow-y-auto p-6 pb-28', className)}\n data-testid={rootTestId}\n >\n <div className=\"m-auto flex w-full flex-col\">\n <div className=\"mx-auto w-full max-w-xl text-center\">\n <div className=\"mx-auto mb-4 flex h-12 w-12 items-center justify-center rounded-lg bg-ai-soft text-ai-ink\">\n <Sparkles className=\"h-6 w-6\" />\n </div>\n <h2 className=\"text-lg font-semibold text-foreground\">{title ?? l.title}</h2>\n <p className=\"mt-1.5 text-sm text-muted-foreground\">{description ?? l.description}</p>\n </div>\n\n {/* The host's list comes straight after the heading: it is what the user came for, and on\n a phone it must not sit below the fold behind the starters. */}\n {below && <div className={cn(BELOW, 'mt-6')}>{below}</div>}\n\n <div className=\"mx-auto w-full max-w-xl text-center\">\n <div className={cn('flex flex-wrap justify-center gap-2', below ? 'mt-8' : 'mt-5')}>\n {shortcut && (\n <button\n type=\"button\"\n onClick={() => onUsePrompt(shortcut.prompt)}\n title={shortcut.prompt}\n className={cn(CHIP, 'gap-2 font-medium')}\n data-testid={shortcutTestId}\n >\n <GanttChartSquare className=\"h-4 w-4 shrink-0 text-ai-ink\" />\n <span>{shortcut.label}</span>\n <ArrowUpRight className=\"h-3.5 w-3.5 shrink-0 text-muted-foreground\" />\n </button>\n )}\n {prompts.map((prompt) => (\n <button\n key={prompt}\n type=\"button\"\n onClick={() => onUsePrompt(prompt)}\n className={cn(CHIP, 'gap-1.5')}\n data-testid={promptTestId}\n >\n {prompt}\n <ArrowUpRight className=\"h-3.5 w-3.5 text-muted-foreground\" />\n </button>\n ))}\n </div>\n\n <div className=\"mt-5\">\n <AddDocumentsArea\n onAddDocuments={onAddDocuments}\n label={l.dropDocuments}\n testId={uploadTestId}\n />\n </div>\n </div>\n </div>\n </div>\n )\n}\n","import { forwardRef, useState, type FocusEvent, type MouseEvent, type ReactNode } from 'react'\nimport { FileText, Pencil } from 'lucide-react'\nimport { Button, cn, type ButtonProps } from '@arbidocs/react/ui'\n\nexport interface ContextChipProps extends Omit<\n ButtonProps,\n 'children' | 'asChild' | 'size' | 'variant'\n> {\n /** How many documents are attached to this chat. */\n count: number\n /** Accessible name, e.g. \"3 documents in this chat\". */\n label: string\n /** True while the panel the chip opens is showing: the chip stays in its \"edit\" state. */\n isOpen?: boolean\n /** Extra content after the count (e.g. the pinned-document chip). */\n children?: ReactNode\n}\n\n/** True when the primary pointer can hover; touch screens emulate mouseenter on a tap. */\nfunction canHover(): boolean {\n return typeof window !== 'undefined' && !!window.matchMedia?.('(hover: hover)').matches\n}\n\n/** `:focus-visible` is keyboard focus; where unsupported, treat any focus as visible. */\nfunction isFocusVisible(el: HTMLElement): boolean {\n try {\n return el.matches(':focus-visible')\n } catch {\n return true\n }\n}\n\n/**\n * The composer's single compact context chip: a document icon and the number of documents in the\n * chat, nothing else. On hover (mouse) or keyboard focus, and while its panel is open, the icon\n * swaps to a pencil to say \"change what is attached\". Touch devices never hover, so they keep the\n * document icon and a tap opens the panel. Forwards its ref and props so it can be a Radix trigger.\n */\nexport const ContextChip = forwardRef<HTMLButtonElement, ContextChipProps>(function ContextChip(\n {\n count,\n label,\n isOpen = false,\n children,\n className,\n onMouseEnter,\n onMouseLeave,\n onFocus,\n onBlur,\n ...props\n },\n ref\n) {\n const [isHovered, setIsHovered] = useState(false)\n const [isFocused, setIsFocused] = useState(false)\n const isEditing = isHovered || isFocused || isOpen\n const Icon = isEditing ? Pencil : FileText\n\n return (\n <Button\n ref={ref}\n type=\"button\"\n variant=\"outline\"\n aria-label={label}\n aria-haspopup=\"dialog\"\n aria-expanded={isOpen}\n data-slot=\"context-chip\"\n data-icon={isEditing ? 'edit' : 'document'}\n className={cn(\n 'flex h-8 min-w-0 max-w-[280px] flex-shrink-0 items-center gap-1.5 rounded-md px-2.5',\n className\n )}\n {...props}\n onMouseEnter={(e: MouseEvent<HTMLButtonElement>) => {\n onMouseEnter?.(e)\n if (canHover()) setIsHovered(true)\n }}\n onMouseLeave={(e: MouseEvent<HTMLButtonElement>) => {\n onMouseLeave?.(e)\n setIsHovered(false)\n }}\n onFocus={(e: FocusEvent<HTMLButtonElement>) => {\n onFocus?.(e)\n setIsFocused(isFocusVisible(e.currentTarget))\n }}\n onBlur={(e: FocusEvent<HTMLButtonElement>) => {\n onBlur?.(e)\n setIsFocused(false)\n }}\n >\n <Icon className=\"h-3.5 w-3.5 flex-shrink-0\" aria-hidden=\"true\" />\n <span className=\"flex-shrink-0 text-sm font-medium\" data-testid=\"context-chip-count\">\n {count >= 1000 ? '999+' : count}\n </span>\n {children}\n </Button>\n )\n})\n","import { useState } from 'react'\nimport { FileText } from 'lucide-react'\nimport { Button, Popover, PopoverContent, PopoverTrigger, cn } from '@arbidocs/react/ui'\nimport type {\n ChatCitationTarget,\n ChatPageCitation,\n ChatPageLabels,\n ChatPagePassage,\n} from './chat-page-types'\n\nexport type CitationLabels = Pick<\n ChatPageLabels,\n 'citation' | 'citationHeading' | 'citationNoSource' | 'openDocument' | 'page'\n>\n\nexport interface CitationMarkProps {\n num: string\n /** The source behind the mark. Without it the mark is a quiet, non-interactive number. */\n citation?: ChatPageCitation\n labels: CitationLabels\n /** Opens the cited document in the host's viewer; without it the popover has no open action. */\n onOpen?: (target: ChatCitationTarget) => void\n className?: string\n}\n\nconst MARK =\n 'ml-px align-super text-[max(0.8em,var(--text-xs))] font-semibold leading-none tabular-nums text-muted-foreground'\n\nfunction sourceLabel(citation: ChatPageCitation, labels: CitationLabels): string {\n return [citation.documentTitle, citation.page != null ? labels.page(citation.page) : '']\n .filter(Boolean)\n .join(', ')\n}\n\n/**\n * The mark after a cited statement: a small superscript number, not an underline over the whole\n * sentence. With citation data it is a button that opens a popover with the source document, the\n * page and the cited passage(s), and (when the host passes `onOpen`) an \"Open document\" action;\n * without data (still streaming, an old message with no stored sources) it is the number alone.\n */\nexport function CitationMark({ num, citation, labels, onOpen, className }: CitationMarkProps) {\n const [isOpen, setIsOpen] = useState(false)\n if (!citation) {\n return (\n <sup className={cn(MARK, className)} data-cite={num}>\n {num}\n </sup>\n )\n }\n\n const open = (passage: ChatPagePassage | null) => {\n setIsOpen(false)\n onOpen?.({\n documentId: passage?.documentId ?? null,\n documentTitle: passage?.documentTitle ?? citation.documentTitle,\n page: passage?.page ?? citation.page,\n passage,\n citation,\n })\n }\n\n return (\n <Popover open={isOpen} onOpenChange={setIsOpen}>\n <PopoverTrigger asChild>\n <button\n type=\"button\"\n data-cite={num}\n data-testid={`chat-citation-${num}`}\n aria-label={labels.citation(num, sourceLabel(citation, labels))}\n className={cn(\n MARK,\n // A pill hit area: 44px on touch without moving the text.\n 'relative -my-1 inline-flex min-w-[1.1em] justify-center rounded px-1 py-1 hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring data-[state=open]:bg-muted data-[state=open]:text-foreground',\n \"pointer-coarse:after:absolute pointer-coarse:after:-inset-3 pointer-coarse:after:content-['']\",\n className\n )}\n >\n {num}\n </button>\n </PopoverTrigger>\n <PopoverContent\n align=\"start\"\n aria-label={labels.citationHeading(num)}\n data-testid={`chat-citation-popover-${num}`}\n className=\"w-96 max-w-[calc(100vw-1rem)] p-0 text-sm\"\n >\n <div className=\"border-b border-border px-3 py-2 text-xs font-semibold text-muted-foreground\">\n {labels.citationHeading(num)}\n </div>\n {citation.passages.length === 0 ? (\n <p className=\"px-3 py-3 text-muted-foreground\">{labels.citationNoSource}</p>\n ) : (\n <ul className=\"divide-y divide-border\">\n {citation.passages.map((passage) => (\n <li key={passage.id} className=\"space-y-1.5 px-3 py-3\">\n <div className=\"flex items-start gap-2\">\n <FileText\n className=\"mt-0.5 size-4 shrink-0 text-muted-foreground\"\n aria-hidden=\"true\"\n />\n <div className=\"min-w-0 flex-1\">\n <div className=\"break-words font-medium text-foreground\">\n {passage.documentTitle}\n </div>\n {passage.page != null && (\n <div className=\"text-xs text-muted-foreground\">\n {labels.page(passage.page)}\n </div>\n )}\n </div>\n </div>\n <blockquote className=\"line-clamp-6 border-l-2 border-border pl-3 text-xs italic text-muted-foreground\">\n {passage.text}\n </blockquote>\n {onOpen && (\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"pointer-coarse:min-h-11\"\n onClick={() => open(passage)}\n data-testid={`chat-citation-open-${num}`}\n >\n {labels.openDocument}\n </Button>\n )}\n </li>\n ))}\n </ul>\n )}\n </PopoverContent>\n </Popover>\n )\n}\n","import type { ReactNode } from 'react'\nimport type { WorkflowStepKind } from '../agents/workflows/stepKinds'\nimport type { WorkflowStepPhase } from '../agents/workflows/run'\nimport type { MentionCandidate, MessageMentionRef } from '@arbidocs/react/shell'\nimport type { SlashMenuItem } from './SlashMenu'\n\n/**\n * The view-model of a chat page. It is the shape `useConversation()` from `@arbidocs/react` returns,\n * so `<ChatPage chat={useConversation(...)} />` works without an adapter; any other source (a demo,\n * another backend) can fill it in. Plain data and callbacks: no SDK, store or router.\n */\n/** One passage of a source document behind a citation. */\nexport interface ChatPagePassage {\n id: string\n /** The source document's id, when known (what an \"open document\" action needs). */\n documentId: string | null\n documentTitle: string\n page: number | null\n text: string\n}\n\n/** The source behind `[statement](#cite-N)` marks of an answer. */\nexport interface ChatPageCitation {\n /** The number in `(#cite-N)`. */\n num: string\n statement: string\n documentTitle: string\n page: number | null\n passages: ReadonlyArray<ChatPagePassage>\n}\n\n/** What the host gets when the reader opens a cited document. */\nexport interface ChatCitationTarget {\n documentId: string | null\n documentTitle: string\n page: number | null\n /** The cited passage (the one opened from, or the first). */\n passage: ChatPagePassage | null\n citation: ChatPageCitation\n}\n\nexport interface ChatPageMessage {\n senderName?: string\n /**\n * Written by someone else in a shared thread: shown on the left. Unset (the reader's own, or a\n * one-person chat): on the right.\n */\n fromOther?: boolean\n id: string\n role: 'user' | 'assistant'\n /** Markdown for an assistant message, plain text for a user message. */\n content: string\n status: 'streaming' | 'complete' | 'error'\n /** Why an assistant message failed. */\n error?: string\n /** Agent steps the answer took so far. */\n stepCount?: number\n /** Sources of the `[..](#cite-N)` marks in `content`. Without them the marks are quiet numbers. */\n citations?: ReadonlyArray<ChatPageCitation>\n /** The reader stopped the answer; `content` is what had streamed. */\n stopped?: boolean\n /** A user message that started a workflow step (its id): shown as that step's chip. */\n workflowStep?: string\n}\n\nexport interface ChatPageThread {\n id: string\n /** Empty until the first question titles it. */\n title: string\n}\n\nexport interface ChatPageDocument {\n id: string\n name: string\n isSelected: boolean\n}\n\n/**\n * The composer's `/` menu: its rows (commands and skills) and what picking or typing a skill does.\n * `useConnectedChat` fills it from the connection; the page filters the rows by the draft.\n */\nexport interface ChatPageSlash {\n items: ReadonlyArray<SlashMenuItem>\n /** A picked row: true when it was handled (a skill's form opened); otherwise `/name ` is inserted. */\n pick: (item: SlashMenuItem) => boolean\n /** A submitted draft: true when it named a skill (its form opened), so nothing is sent. */\n startDraft: (draft: string) => boolean\n /** The menu's \"Browse skills\" footer. Omit to hide it. */\n onBrowse?: () => void\n /** Rendered once with the composer (the skill's form). */\n launcher?: ReactNode\n}\n\nexport interface ChatPageController {\n /** The composer's `/` menu. Omit for none. */\n slash?: ChatPageSlash\n assistantMode?: 'always' | 'mentioned'\n setAssistantMode?: (mode: 'always' | 'mentioned') => void | Promise<void>\n isUpdatingAssistantMode?: boolean\n isPostingComment?: boolean\n mentionCandidates?: ReadonlyArray<MentionCandidate>\n threads: ReadonlyArray<ChatPageThread>\n activeThreadId: string\n messages: ReadonlyArray<ChatPageMessage>\n isRunning: boolean\n /** The last turn failed. */\n error: string | null\n /** A stored conversation's messages are loading. */\n isLoadingThread?: boolean\n /** The conversation list is loading. */\n isLoadingThreads?: boolean\n /** Loading or deleting a stored conversation failed. */\n historyError?: string | null\n documents: ReadonlyArray<ChatPageDocument>\n isLoadingDocuments: boolean\n isUploading: boolean\n uploadError: string | null\n send: (text: string, options?: { mentions?: MessageMentionRef[] }) => void | Promise<void>\n retry: () => void | Promise<void>\n /** Stops the running answer. Omit when the source cannot be aborted: no stop button then. */\n stop?: () => void\n selectThread: (id: string) => void\n newThread: () => void\n /** Omit to hide the delete action. */\n deleteThread?: (id: string) => void\n toggleDocument: (id: string) => void\n selectAllDocuments: () => void\n upload: (files: File[]) => void | Promise<void>\n}\n\n/** Every fixed string of the chat page. Pass a partial `labels` to translate or reword. */\nexport interface ChatPageLabels {\n /** Accessible name of the whole chat. */\n chat: string\n conversations: string\n newChat: string\n untitled: string\n deleteConversation: (title: string) => string\n /** Assistant name on the answer's byline. */\n assistant: string\n thinking: string\n steps: (count: number) => string\n responseFailed: string\n answerFailedTitle: string\n uploadFailedTitle: string\n placeholder: string\n composerAriaLabel: string\n documentsInChat: (selected: number, total: number) => string\n documentsHeading: string\n selectAllDocuments: string\n noDocuments: string\n uploadDocuments: string\n uploading: string\n emptyTitle: string\n emptyDescription: string\n emptyUploadTitle: string\n emptyUploadDescription: string\n workflows: string\n loadingDocuments: string\n stop: string\n stopped: string\n loadingConversation: string\n historyFailedTitle: string\n /** Accessible name of a citation mark. */\n citation: (num: string, source: string) => string\n /** Heading of the citation popover. */\n citationHeading: (num: string) => string\n citationNoSource: string\n openDocument: string\n page: (page: number) => string\n morePassages: (count: number) => string\n}\n\nexport const DEFAULT_CHAT_PAGE_LABELS: ChatPageLabels = {\n chat: 'Assistant chat',\n conversations: 'Conversations',\n newChat: 'New chat',\n untitled: 'New chat',\n deleteConversation: (title) => `Delete conversation ${title}`,\n assistant: 'Assistant',\n thinking: 'Thinking…',\n steps: (count) => (count === 1 ? '1 step' : `${count} steps`),\n responseFailed: 'Response failed',\n answerFailedTitle: 'The answer could not be completed',\n uploadFailedTitle: 'The upload failed',\n placeholder: 'Ask about your documents',\n composerAriaLabel: 'Message the assistant',\n documentsInChat: (selected, total) => `${selected} of ${total} documents in this chat`,\n documentsHeading: 'Documents in this chat',\n selectAllDocuments: 'Select all',\n noDocuments: 'No documents yet',\n uploadDocuments: 'Upload documents',\n uploading: 'Uploading…',\n emptyTitle: 'Ask about your documents',\n emptyDescription: 'Every answer is grounded in the selected documents and cites its sources.',\n emptyUploadTitle: 'Add a document to start',\n emptyUploadDescription: 'Upload the documents you want to ask about.',\n workflows: 'Workflows',\n loadingDocuments: 'Loading documents…',\n stop: 'Stop generating',\n stopped: 'Stopped',\n loadingConversation: 'Loading conversation…',\n historyFailedTitle: 'The conversation history could not be used',\n citation: (num, source) => (source ? `Source ${num}: ${source}` : `Source ${num}`),\n citationHeading: (num) => `Source ${num}`,\n citationNoSource: 'The passage for this source is not available.',\n openDocument: 'Open document',\n page: (page) => `Page ${page}`,\n morePassages: (count) => (count === 1 ? '1 more passage' : `${count} more passages`),\n}\n\nexport interface ChatPageProps {\n /** Open a notification at its original message once history has loaded. */\n targetMessageId?: string\n chat: ChatPageController\n /**\n * The stored thread the host names (a `?conversation=` link): selected once the thread list has it. With\n * `onConversationChange` the host hears which stored thread is on screen (`null` after a new thread) and can\n * mirror it; a link the list has not loaded yet is kept meanwhile. Absent: the chat picks its own thread.\n */\n conversationId?: string | null\n onConversationChange?: (conversationId: string | null) => void\n /**\n * `page` (default): a full-page chat; while it is mounted the dock yields (see\n * `useChatSurface`). `dock`: the same chat in the dock, which does not claim the page slot.\n */\n surface?: 'page' | 'dock'\n /** Replaces the heading (default: the active conversation's title). */\n header?: ReactNode\n /** Actions at the right of the header bar. */\n headerActions?: ReactNode\n /**\n * The workflow launcher column. A column beside the chat when the container is wide, a\n * collapsible panel under the header when it is not (so an open dock never squeezes it).\n */\n aside?: ReactNode\n /** Starter questions on the empty conversation; clicking one fills the composer. */\n prompts?: ReadonlyArray<string>\n /** Whether the empty state asks for documents before offering starter prompts. */\n documentsRequired?: boolean\n /** Heading of the empty state; wins over `labels.emptyTitle`. */\n emptyTitle?: string\n /** Sub-heading of the empty state; wins over `labels.emptyDescription`. */\n emptyDescription?: string\n /**\n * Renders an answer. Default: `ChatMessageContent` (markdown: lists, tables, a quiet numbered\n * mark with a source popover for each citation).\n */\n renderContent?: (message: ChatPageMessage) => ReactNode\n /**\n * Opens the cited document (and page) in the host's viewer. Without it the citation popover\n * shows the source and passage and offers no open action.\n */\n onOpenCitation?: (target: ChatCitationTarget) => void\n /**\n * A workflow step by id — its title, kind and phase: a message that started a step shows as that\n * step's chip, as the thread's bar draws it (else its id, as an AI step).\n */\n workflowStepOf?: (stepId: string) => WorkflowStepView | undefined\n /**\n * Container width, in rem, from which `aside` is a column beside the chat; narrower, it is a\n * button-toggled panel over the transcript. Default 60.\n */\n asideBreakpoint?: number\n /**\n * Fill the height left in the nearest scrolling ancestor below the chat's own top (the page\n * header above it, the shell bars around it), measured in dynamic viewport units so a phone's\n * collapsing URL bar cannot cut it. Use it for a chat card placed under a page header.\n */\n fillHeight?: boolean\n /** Smallest height `fillHeight` gives, in px. Default 360. */\n minHeight?: number\n /**\n * One conversation only (e.g. a workflow run's thread): no conversation list, select or New\n * chat; the host picks the thread (`chat.selectThread`).\n */\n singleThread?: boolean\n /** Drop the heading from the header bar (the host's page header already names the chat). */\n compactHeader?: boolean\n /** Accepted upload types for the file picker. */\n accept?: string\n labels?: Partial<ChatPageLabels>\n className?: string\n testIds?: Partial<{\n root: string\n transcript: string\n input: string\n send: string\n documents: string\n upload: string\n alert: string\n asideToggle: string\n aside: string\n }>\n}\n\n/** A workflow step as a chat shows it: its title, kind and where it is. */\nexport interface WorkflowStepView {\n title?: string\n kind?: WorkflowStepKind\n phase?: WorkflowStepPhase\n /** The step's document (its latest version): opened from beside its chip. */\n document?: { name: string; onOpen: () => void }\n}\n","import { useCallback, useMemo, type ReactNode } from 'react'\nimport { MarkdownRenderer, closeOpenEmphasis, trimOpenCitation } from '@arbidocs/react/ui'\nimport { CitationMark } from './CitationMark'\nimport {\n DEFAULT_CHAT_PAGE_LABELS,\n type ChatCitationTarget,\n type ChatPageLabels,\n type ChatPageMessage,\n} from './chat-page-types'\n\nexport interface ChatMessageContentProps {\n message: ChatPageMessage\n labels?: Partial<ChatPageLabels>\n /** Opens the cited document in the host's viewer. */\n onOpenCitation?: (target: ChatCitationTarget) => void\n className?: string\n}\n\n/**\n * The one renderer of an assistant answer, used by `ChatPage` and `AssistantDock` (the dock is the\n * same page). Markdown (lists, tables, code) where each `[statement](#cite-N)` shows the statement\n * as plain text followed by a quiet numbered mark; the mark opens the source popover when the\n * message carries `citations`. Literal `(*Source: ...*)` notes are tidied by the markdown\n * normaliser; a stopped answer says so.\n */\nexport function ChatMessageContent({\n message,\n labels,\n onOpenCitation,\n className,\n}: ChatMessageContentProps) {\n const l = { ...DEFAULT_CHAT_PAGE_LABELS, ...labels }\n // Only the citation labels reach the marks, and they are stable unless the host swaps them, so\n // a re-render (a streaming token) never makes the markdown re-parse every block.\n const { citation, citationHeading, citationNoSource, openDocument, page } = l\n const citationLabels = useMemo(\n () => ({ citation, citationHeading, citationNoSource, openDocument, page }),\n [citation, citationHeading, citationNoSource, openDocument, page]\n )\n const byNum = useMemo(\n () => new Map((message.citations ?? []).map((c) => [c.num, c])),\n [message.citations]\n )\n const renderCitation = useCallback(\n ({ num, children }: { num: string; children: ReactNode }) => (\n <>\n {children}\n <CitationMark\n num={num}\n citation={byNum.get(num)}\n labels={citationLabels}\n onOpen={onOpenCitation}\n />\n </>\n ),\n [byNum, citationLabels, onOpenCitation]\n )\n return (\n <>\n <MarkdownRenderer\n isStreaming={message.status === 'streaming'}\n renderCitation={renderCitation}\n className={className}\n >\n {/* While streaming the renderer tidies the open tail itself; a stopped answer stays open. */}\n {message.stopped ? closeOpenEmphasis(trimOpenCitation(message.content)) : message.content}\n </MarkdownRenderer>\n {message.stopped && (\n <p className=\"mt-2 text-xs italic text-muted-foreground\" data-testid=\"chat-stopped\">\n {l.stopped}\n </p>\n )}\n </>\n )\n}\n","import { useState } from 'react'\nimport { Loader2, Upload } from 'lucide-react'\nimport { Button, Popover, PopoverContent, PopoverTrigger } from '@arbidocs/react/ui'\nimport { ContextChip } from './ContextChip'\nimport { testIdOr } from './test-id'\nimport type { ChatPageController, ChatPageLabels } from './chat-page-types'\n\ninterface ChatDocumentsProps {\n chat: Pick<\n ChatPageController,\n 'documents' | 'isUploading' | 'toggleDocument' | 'selectAllDocuments'\n >\n labels: ChatPageLabels\n onPickFiles: () => void\n testIds?: Partial<{ documents: string; upload: string }>\n}\n\n/**\n * The document context chip of the composer: how many documents the questions are grounded on,\n * and a popover to pick them or upload more. The count is on the chip, the names are in the list,\n * so the same part reads in a dock (no room) and on a page.\n */\nexport function ChatDocuments({ chat, labels, onPickFiles, testIds }: ChatDocumentsProps) {\n const [isOpen, setIsOpen] = useState(false)\n const selected = chat.documents.filter((d) => d.isSelected).length\n const total = chat.documents.length\n return (\n <Popover open={isOpen} onOpenChange={setIsOpen}>\n <PopoverTrigger asChild>\n <ContextChip\n count={selected}\n label={labels.documentsInChat(selected, total)}\n isOpen={isOpen}\n data-testid={testIdOr(testIds?.documents, { testId: 'chat-documents' })}\n className=\"pointer-coarse:h-11\"\n />\n </PopoverTrigger>\n <PopoverContent\n align=\"start\"\n className=\"w-80 p-3\"\n aria-label={labels.documentsHeading}\n data-testid=\"chat-documents-panel\"\n >\n <div className=\"mb-2 flex items-center justify-between gap-2\">\n <h3 className=\"text-sm font-medium text-foreground\">{labels.documentsHeading}</h3>\n {total > 0 && selected < total && (\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"pointer-coarse:min-h-11\"\n onClick={chat.selectAllDocuments}\n >\n {labels.selectAllDocuments}\n </Button>\n )}\n </div>\n {total === 0 ? (\n <p className=\"py-2 text-sm text-muted-foreground\">{labels.noDocuments}</p>\n ) : (\n <ul className=\"max-h-60 overflow-y-auto\">\n {chat.documents.map((doc) => (\n <li key={doc.id}>\n <label className=\"flex cursor-pointer items-center gap-2 rounded-md px-1 py-1.5 text-sm hover:bg-muted pointer-coarse:min-h-11\">\n <input\n type=\"checkbox\"\n checked={doc.isSelected}\n onChange={() => chat.toggleDocument(doc.id)}\n className=\"size-4 shrink-0 accent-[hsl(var(--primary))]\"\n />\n <span className=\"min-w-0 truncate\" title={doc.name}>\n {doc.name}\n </span>\n </label>\n </li>\n ))}\n </ul>\n )}\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"mt-2 w-full gap-2 pointer-coarse:min-h-11\"\n disabled={chat.isUploading}\n onClick={onPickFiles}\n data-testid={testIdOr(testIds?.upload, { testId: 'chat-upload' })}\n >\n {chat.isUploading ? (\n <Loader2 className=\"size-4 animate-spin\" aria-hidden=\"true\" />\n ) : (\n <Upload className=\"size-4\" aria-hidden=\"true\" />\n )}\n {chat.isUploading ? labels.uploading : labels.uploadDocuments}\n </Button>\n </PopoverContent>\n </Popover>\n )\n}\n","import { MessageSquarePlus, Trash2 } from 'lucide-react'\nimport { Button, cn } from '@arbidocs/react/ui'\nimport { testIdOr } from './test-id'\nimport type { ChatPageLabels, ChatPageThread } from './chat-page-types'\n\ninterface ThreadProps {\n threads: ReadonlyArray<ChatPageThread>\n activeId: string\n labels: ChatPageLabels\n onSelect: (id: string) => void\n onNew: () => void\n onDelete?: (id: string) => void\n /** The stored conversations are still loading. */\n isLoading?: boolean\n testIds?: Partial<{ list: string; row: string; delete: string; new: string; select: string }>\n}\n\n/**\n * The conversation list as a column (wide containers): New chat on top, one row per thread with a\n * delete action. The active row is `aria-current`. Rows are real buttons, so keyboard and touch\n * work; delete is always visible on touch and appears on hover/focus elsewhere.\n */\nexport function ChatThreadList({\n threads,\n activeId,\n labels,\n onSelect,\n onNew,\n onDelete,\n isLoading,\n testIds,\n}: ThreadProps) {\n return (\n <nav\n aria-label={labels.conversations}\n data-slot=\"chat-thread-list\"\n data-testid={testIdOr(testIds?.list, { testId: 'chat-thread-list' })}\n className=\"flex min-h-0 flex-1 flex-col gap-2 p-3\"\n >\n <Button\n type=\"button\"\n variant=\"outline\"\n className=\"w-full justify-start gap-2 pointer-coarse:min-h-11\"\n onClick={onNew}\n data-testid={testIdOr(testIds?.new, { testId: 'chat-new' })}\n >\n <MessageSquarePlus className=\"size-4\" aria-hidden=\"true\" />\n {labels.newChat}\n </Button>\n <ul\n className=\"flex min-h-0 flex-1 flex-col gap-0.5 overflow-y-auto\"\n aria-busy={isLoading ? 'true' : undefined}\n >\n {threads.map((thread) => {\n const isActive = thread.id === activeId\n const title = thread.title || labels.untitled\n return (\n <li key={thread.id} className=\"group relative\">\n <button\n type=\"button\"\n onClick={() => onSelect(thread.id)}\n aria-current={isActive ? 'true' : undefined}\n title={title}\n data-testid={`${testIdOr(testIds?.row, { testId: 'chat-conversation' })}-${thread.id}`}\n className={cn(\n 'flex w-full items-center rounded-md px-3 py-2 pr-10 text-left text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring pointer-coarse:min-h-11',\n isActive\n ? 'bg-muted font-medium text-foreground'\n : 'text-muted-foreground hover:bg-muted/60 hover:text-foreground'\n )}\n >\n <span className=\"truncate\">{title}</span>\n </button>\n {onDelete && (\n <button\n type=\"button\"\n onClick={() => onDelete(thread.id)}\n aria-label={labels.deleteConversation(title)}\n data-testid={`${testIdOr(testIds?.delete, { testId: 'chat-delete' })}-${thread.id}`}\n className=\"absolute right-1 top-1/2 flex size-8 -translate-y-1/2 items-center justify-center rounded-md text-muted-foreground opacity-100 hover:bg-background hover:text-foreground focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring pointer-fine:opacity-0 pointer-fine:group-hover:opacity-100 pointer-coarse:size-11\"\n >\n <Trash2 className=\"size-4\" aria-hidden=\"true\" />\n </button>\n )}\n </li>\n )\n })}\n </ul>\n </nav>\n )\n}\n\n/**\n * The conversation list as one native select (narrow containers, the dock). Native on purpose:\n * the platform picker on a phone, a label for screen readers, text at least 16px on touch.\n */\nexport function ChatThreadSelect({\n threads,\n activeId,\n labels,\n onSelect,\n testIds,\n}: Pick<ThreadProps, 'threads' | 'activeId' | 'labels' | 'onSelect' | 'testIds'>) {\n return (\n <select\n aria-label={labels.conversations}\n value={activeId}\n onChange={(e) => onSelect(e.target.value)}\n data-testid={testIdOr(testIds?.select, { testId: 'chat-conversation-select' })}\n className=\"h-9 min-w-0 flex-1 truncate rounded-md border border-input bg-background px-2 text-sm font-medium text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring pointer-coarse:h-11 pointer-coarse:text-base\"\n >\n {threads.map((thread) => (\n <option key={thread.id} value={thread.id}>\n {thread.title || labels.untitled}\n </option>\n ))}\n </select>\n )\n}\n","import { useEffect, useSyncExternalStore } from 'react'\n\n/**\n * Which chat surface is on screen. A full-page chat (`ChatPage`, `surface=\"page\"`) and the\n * docked chat must never be offered together: the page chat registers itself while mounted,\n * and the host's dock reads `useChatSurface()` to yield.\n *\n * ```tsx\n * const { isDockAvailable } = useChatSurface()\n * {isDockAvailable && <ChatDockToggle />} // topbar button\n * {isDockAvailable && <ChatDock />} // the Shell.Dock\n * ```\n *\n * The dock keeps its own open/closed state, so it comes back as it was when the user leaves the\n * page chat. A module-level counter (not React context) so the page and the dock agree wherever\n * they sit in the tree, and nested or concurrent page chats are counted rather than overwritten.\n */\nlet embeddedCount = 0\nconst listeners = new Set<() => void>()\n\nfunction subscribe(listener: () => void): () => void {\n listeners.add(listener)\n return () => listeners.delete(listener)\n}\n\nfunction emit() {\n listeners.forEach((l) => l())\n}\n\n/** Claims the page-chat slot while `enabled` and the caller is mounted. `ChatPage` calls this. */\nexport function useRegisterEmbeddedChat(enabled = true): void {\n useEffect(() => {\n if (!enabled) return\n embeddedCount += 1\n emit()\n return () => {\n embeddedCount -= 1\n emit()\n }\n }, [enabled])\n}\n\nexport interface ChatSurface {\n /** A full-page chat is mounted. */\n hasEmbeddedChat: boolean\n /** The dock (and its topbar button) may be offered: false while a page chat is mounted. */\n isDockAvailable: boolean\n}\n\nexport function useChatSurface(): ChatSurface {\n const count = useSyncExternalStore(\n subscribe,\n () => embeddedCount,\n () => 0\n )\n return { hasEmbeddedChat: count > 0, isDockAvailable: count === 0 }\n}\n","/**\n * A chat's side of `openNewConversation({ prompt })`: when a prompt is asked for, open a fresh\n * conversation (unless the one on screen is already empty) and send the prompt once it, and the\n * documents it is grounded on, are ready.\n */\nimport { useEffect, useRef } from 'react'\nimport { conversationStartRequest, useIntentRequest } from '../provider/requests'\nimport type { ChatPageController } from './chat-page-types'\n\ntype StartableChat = Pick<\n ChatPageController,\n 'activeThreadId' | 'messages' | 'isRunning' | 'isLoadingDocuments' | 'newThread' | 'send'\n>\n\n/** The active conversation is new and empty (a stored one's id starts with `con-`). */\nfunction isBlank(chat: StartableChat): boolean {\n return !chat.activeThreadId.startsWith('con-') && chat.messages.length === 0\n}\n\n/** Take the requested first messages while `enabled` (the chat on screen takes them). */\nexport function useStartRequestedConversation(chat: StartableChat, enabled = true): void {\n const pending = useRef<string | null>(null)\n useIntentRequest(\n conversationStartRequest,\n (prompt) => {\n pending.current = prompt\n if (!isBlank(chat)) chat.newThread()\n },\n enabled\n )\n const isFresh = isBlank(chat) && !chat.isRunning && !chat.isLoadingDocuments\n const { send } = chat\n useEffect(() => {\n if (!pending.current || !isFresh) return\n const prompt = pending.current\n pending.current = null\n void send(prompt)\n }, [isFresh, send])\n}\n","/**\n * A chat's thread, controlled by the host (a `?conversation=` link): `conversationId` selects that stored thread\n * once the thread list has it, and `onConversationChange` reports the stored thread on screen (`null` after a new\n * thread), so the host can mirror it. A link to a thread the list has not loaded yet is kept, not overwritten by\n * the thread on screen meanwhile.\n */\nimport { useCallback, useEffect, useRef } from 'react'\nimport type { ChatPageController } from './chat-page-types'\n\ntype ControlledChat = Pick<\n ChatPageController,\n 'threads' | 'activeThreadId' | 'selectThread' | 'newThread'\n>\n\n/** Returns the chat's `newThread`, which also reports `null`. Inert without `conversationId` and the callback. */\nexport function useControlledThread(\n chat: ControlledChat,\n conversationId: string | null | undefined,\n onConversationChange?: (conversationId: string | null) => void\n): () => void {\n const { threads, activeThreadId, selectThread, newThread } = chat\n // The thread the host's id last named and this hook acted on, and the one a selection is still switching to.\n const applied = useRef<string | null>(null)\n const switching = useRef<string | null>(null)\n const report = useRef(onConversationChange)\n report.current = onConversationChange\n\n useEffect(() => {\n if (!conversationId || applied.current === conversationId) return\n if (!threads.some((t) => t.id === conversationId)) return\n applied.current = conversationId\n if (activeThreadId !== conversationId) {\n switching.current = conversationId\n selectThread(conversationId)\n }\n }, [conversationId, selectThread, threads, activeThreadId])\n\n useEffect(() => {\n if (!report.current) return\n if (switching.current) {\n if (activeThreadId !== switching.current) return\n switching.current = null\n }\n // A linked thread that has not been applied yet (the list is still loading) keeps the link.\n if (conversationId && applied.current !== conversationId) return\n // Only a stored thread (`con-…`) has an id to link to; a new one is reported by `newThread`.\n if (!activeThreadId.startsWith('con-') || activeThreadId === conversationId) return\n applied.current = activeThreadId\n report.current(activeThreadId)\n }, [activeThreadId, conversationId])\n\n return useCallback(() => {\n newThread()\n applied.current = null\n report.current?.(null)\n }, [newThread])\n}\n","import { useLayoutEffect, useState, type RefObject } from 'react'\nimport { observeResize } from './observe-resize'\n\n/** Space below the element that its ancestors (up to and including `until`) keep for themselves. */\nfunction bottomSpace(el: HTMLElement, until: HTMLElement): number {\n let space = 0\n for (let node = el.parentElement; node; node = node.parentElement) {\n const style = getComputedStyle(node)\n space += (parseFloat(style.paddingBottom) || 0) + (parseFloat(style.borderBottomWidth) || 0)\n if (node === until) break\n }\n return space\n}\n\nfunction scrollParent(el: HTMLElement): HTMLElement | null {\n for (let node = el.parentElement; node; node = node.parentElement) {\n const overflowY = getComputedStyle(node).overflowY\n if (overflowY === 'auto' || overflowY === 'scroll') return node\n }\n return null\n}\n\n/**\n * The height an element should take to fill what is left of its scrolling ancestor below its own\n * top (page header above it, shell bars around it): the ancestor's visible height minus the\n * element's offset inside its content and the ancestor's bottom padding. With no scrolling ancestor\n * it is the visual viewport below the element. Dynamic viewport units end up in the ancestor\n * (the shell is `h-dvh`), so a phone's collapsing URL bar cannot cut the chat. `null` until\n * measured or when disabled.\n */\nexport function useFillHeight(\n ref: RefObject<HTMLElement | null>,\n enabled: boolean,\n minHeight: number\n): number | null {\n const [height, setHeight] = useState<number | null>(null)\n useLayoutEffect(() => {\n const el = ref.current\n if (!enabled || !el) return\n const scroller = scrollParent(el)\n const measure = () => {\n const viewport = window.visualViewport?.height ?? window.innerHeight\n const rect = el.getBoundingClientRect()\n const scrolled = scroller ? scroller.scrollTop : window.scrollY\n let available: number\n if (scroller) {\n // The element's offset inside the scroll content, not in the viewport.\n const top = rect.top - scroller.getBoundingClientRect().top\n available = scroller.clientHeight - (top + scrolled) - bottomSpace(el, scroller)\n } else {\n available = viewport - rect.top\n }\n // Never run under a pinned phone tab bar (a host whose page scrolls the window, or a\n // scroller that extends below the bar): the composer must stay above it. The bar's own\n // inset is read from it directly (`--shell-bottom-inset` also counts the composer itself).\n const bar = document.querySelector('[data-slot=\"mobile-tab-bar\"]')?.getBoundingClientRect()\n const barHeight = bar && bar.height > 0 ? Math.max(0, viewport - bar.top) : 0\n available = Math.min(available, viewport - barHeight - (rect.top + scrolled))\n setHeight(Math.max(minHeight, Math.floor(available)))\n }\n measure()\n window.addEventListener('resize', measure)\n window.visualViewport?.addEventListener('resize', measure)\n const stopObserving = scroller ? observeResize(scroller, measure) : () => {}\n return () => {\n window.removeEventListener('resize', measure)\n window.visualViewport?.removeEventListener('resize', measure)\n stopObserving()\n }\n }, [ref, enabled, minHeight])\n return enabled ? height : null\n}\n","import { useCallback, useEffect, useMemo, useRef, useState, type FormEvent } from 'react'\nimport { Loader2, MessageSquarePlus, PanelRight, Square, Upload } from 'lucide-react'\nimport { Button, cn } from '@arbidocs/react/ui'\nimport { rootFontSizePx, useElementSize } from '../lib/useElementSize'\nimport { useFillHeight } from '../lib/useFillHeight'\nimport { ChatMessageContent } from './ChatMessageContent'\nimport { ChatDocuments } from './ChatDocuments'\nimport { ChatThreadList, ChatThreadSelect } from './ChatThreads'\nimport { useRegisterEmbeddedChat } from './chat-surface'\nimport { useStartRequestedConversation } from './useStartRequestedConversation'\nimport { useControlledThread } from './useControlledThread'\nimport {\n DEFAULT_CHAT_PAGE_LABELS,\n type ChatPageLabels,\n type ChatPageMessage,\n type ChatPageProps,\n} from './chat-page-types'\nimport { Composer, ScrollToBottom } from './Composer'\nimport { ConversationEmpty } from './ConversationEmpty'\nimport { Message } from './Message'\nimport { MessageAlert } from './MessageAlert'\nimport { MessageList } from './MessageList'\nimport { AssistantModeToggle } from './AssistantModeToggle'\nimport { MentionMenu } from './MentionMenu'\nimport { SlashMenu, type SlashMenuItem } from './SlashMenu'\nimport { filterSlashItems, parseSlashToken } from './slash-menu-helpers'\nimport { useListKeyNav } from '../lib/useListKeyNav'\nimport { useMentionAutocomplete } from './useMentionAutocomplete'\nimport { extractMentions, toMessageMentions } from '@arbidocs/react/shell'\nimport { testIdOr } from './test-id'\nimport { useStreamAnnouncement } from './useStreamAnnouncement'\nimport { WorkflowStepChip } from './WorkflowStepChip'\n\n/**\n * The user bubble, themeable with two optional tokens (HSL triplets, like every colour token):\n * `--chat-user-bubble` and `--chat-user-bubble-foreground`. They default to the tonal\n * `--muted` / `--foreground` pair; a brand sets a dark bubble with light text by defining both.\n * Markdown inside inherits the bubble's text colour.\n */\nconst USER_BUBBLE =\n 'bg-[color:hsl(var(--chat-user-bubble,var(--muted)))] text-[color:hsl(var(--chat-user-bubble-foreground,var(--foreground)))]'\n\nconst NEAR_BOTTOM_PX = 96\n\n/** Container width, in rem, from which the conversation list is a column instead of a select. */\nconst LIST_COLUMN_REM = 48\nconst DEFAULT_ASIDE_BREAKPOINT_REM = 60\n\ninterface MessageRowProps {\n message: ChatPageMessage\n renderContent: ChatPageProps['renderContent']\n onOpenCitation: ChatPageProps['onOpenCitation']\n workflowStepOf: ChatPageProps['workflowStepOf']\n labels: ChatPageLabels\n}\n\nfunction MessageRow({\n message,\n renderContent,\n onOpenCitation,\n workflowStepOf,\n labels,\n}: MessageRowProps) {\n if (message.role === 'user' && message.workflowStep) {\n // Centred, as the step itself: not a bubble from whoever started the run.\n return (\n <WorkflowStepChip\n step={message.workflowStep}\n {...workflowStepOf?.(message.workflowStep)}\n content={message.content}\n messageId={message.id}\n />\n )\n }\n if (message.role === 'user') {\n return (\n <Message.Root role=\"user\" messageId={message.id}>\n <Message.Content\n role=\"user\"\n messageId={message.id}\n align={message.fromOther ? 'start' : 'end'}\n >\n {message.senderName && (\n <span className=\"text-xs text-muted-foreground\">{message.senderName}</span>\n )}\n <Message.Bubble\n role=\"user\"\n messageId={message.id}\n className={USER_BUBBLE}\n testId=\"chat-message-user\"\n >\n <p className=\"m-0 whitespace-pre-wrap break-words text-base leading-relaxed\">\n {message.content}\n </p>\n </Message.Bubble>\n </Message.Content>\n </Message.Root>\n )\n }\n const isStreaming = message.status === 'streaming'\n const isFailed = message.status === 'error'\n const hasText = message.content.trim() !== ''\n return (\n <Message.Root role=\"assistant\" messageId={message.id} tone={isFailed ? 'error' : undefined}>\n <Message.Content role=\"assistant\" messageId={message.id}>\n <Message.Bubble role=\"assistant\" messageId={message.id} testId=\"chat-message-assistant\">\n <Message.Byline\n messageId={message.id}\n identity={<span className=\"font-medium\">{labels.assistant}</span>}\n timeLabel={message.stepCount ? labels.steps(message.stepCount) : ''}\n isSettled={!isStreaming}\n isFailed={isFailed}\n statusLabel={isFailed ? labels.responseFailed : ''}\n />\n {hasText &&\n (renderContent?.(message) ?? (\n <ChatMessageContent\n message={message}\n labels={labels}\n onOpenCitation={onOpenCitation}\n />\n ))}\n {!hasText && message.stopped && (\n <p className=\"text-xs italic text-muted-foreground\" data-testid=\"chat-stopped\">\n {labels.stopped}\n </p>\n )}\n {isStreaming && !hasText && (\n <span\n className=\"flex items-center gap-2 text-muted-foreground\"\n data-testid=\"chat-streaming\"\n >\n <Loader2 className=\"size-4 animate-spin motion-reduce:animate-none\" aria-hidden />\n {labels.thinking}\n </span>\n )}\n </Message.Bubble>\n </Message.Content>\n </Message.Root>\n )\n}\n\n/**\n * A complete assistant chat, composed from the same parts as the dock: conversation list with\n * titles (stored conversations included), message list with source popovers on citations,\n * composer with the document chip, upload and stop, empty state, error and retry. Drive it with\n * `useConversation()` from `@arbidocs/react` (or fill `ChatPageController`).\n *\n * It lays itself out by its own width, not the viewport's, so it holds up in a card, beside an\n * open dock or on a phone: the conversation list is a column from 48rem and a select below; the\n * `aside` slot (workflow launcher) is a column from `asideBreakpoint` (60rem) and below that one\n * button-toggled panel over the transcript, so it never pushes the conversation down. Every part\n * renders once. Give it a height (`h-full` of a sized parent, a `className`) or `fillHeight`\n * under a page header. Colours come from the tokens only; the user bubble has two optional ones\n * (see `USER_BUBBLE`).\n *\n * With `surface=\"page\"` it claims the page-chat slot, so `useChatSurface()` tells the host's dock\n * to yield: one chat on screen, never two.\n */\nexport function ChatPage({\n chat: hostChat,\n conversationId,\n onConversationChange,\n surface = 'page',\n header,\n headerActions,\n aside,\n prompts = [],\n documentsRequired = true,\n emptyTitle,\n emptyDescription,\n renderContent,\n onOpenCitation,\n workflowStepOf,\n singleThread,\n targetMessageId,\n asideBreakpoint = DEFAULT_ASIDE_BREAKPOINT_REM,\n fillHeight = false,\n minHeight = 360,\n compactHeader = false,\n accept,\n labels,\n className,\n testIds,\n}: ChatPageProps) {\n const l = { ...DEFAULT_CHAT_PAGE_LABELS, ...labels }\n const controlledNewThread = useControlledThread(hostChat, conversationId, onConversationChange)\n const isControlled = conversationId !== undefined || onConversationChange !== undefined\n const chat = useMemo(\n () => (isControlled ? { ...hostChat, newThread: controlledNewThread } : hostChat),\n [hostChat, isControlled, controlledNewThread]\n )\n useRegisterEmbeddedChat(surface === 'page')\n // The page chat takes `openNewConversation({ prompt })`: a fresh conversation, sent on arrival.\n useStartRequestedConversation(chat, surface === 'page' && !singleThread)\n\n const [draft, setDraft] = useState('')\n const [isAsideOpen, setIsAsideOpen] = useState(false)\n const [isAway, setIsAway] = useState(false)\n const rootRef = useRef<HTMLElement>(null)\n const headerRef = useRef<HTMLDivElement>(null)\n const asideToggleRef = useRef<HTMLButtonElement>(null)\n const asideRef = useRef<HTMLElement>(null)\n const scrollRef = useRef<HTMLDivElement>(null)\n const jumpedToMessage = useRef<string | null>(null)\n const fileRef = useRef<HTMLInputElement>(null)\n const textareaRef = useRef<HTMLTextAreaElement>(null)\n const currentThreadRef = useRef(chat.activeThreadId)\n currentThreadRef.current = chat.activeThreadId\n const mentions = useMentionAutocomplete({\n value: draft,\n onValueChange: setDraft,\n candidates: chat.mentionCandidates ?? [],\n textareaRef,\n })\n\n // The `/` menu (when the chat has one): the rows matching the slash command being typed. A\n // picked skill opens its form (`slash.pick`); anything else is inserted as `/name `.\n const slash = chat.slash\n const slashToken = slash ? parseSlashToken(draft) : null\n const slashItems = useMemo(\n () => (slash && slashToken !== null ? filterSlashItems([...slash.items], slashToken) : []),\n [slash, slashToken]\n )\n const isSlashOpen = slashItems.length > 0\n const pickSlash = (item: SlashMenuItem) => {\n if (slash?.pick(item)) {\n setDraft('')\n return\n }\n const next = `/${item.name} `\n setDraft(next)\n requestAnimationFrame(() => {\n textareaRef.current?.focus()\n textareaRef.current?.setSelectionRange(next.length, next.length)\n })\n }\n const slashNav = useListKeyNav({\n open: isSlashOpen,\n items: slashItems,\n onPick: pickSlash,\n // Clear the leading slash to dismiss; otherwise the menu reopens on the next letter.\n onDismiss: () => setDraft(''),\n resetKey: slashToken,\n })\n\n // Layout modes come from the chat's own width (a container query with a configurable\n // threshold), so each part is in the DOM once. Unmeasured (0) is the narrow layout.\n const { width } = useElementSize(rootRef)\n const { height: headerHeight } = useElementSize(headerRef)\n const rem = rootFontSizePx()\n const hasListColumn = !singleThread && width >= LIST_COLUMN_REM * rem\n const hasAsideColumn = width > 0 && width >= asideBreakpoint * rem\n const fillPx = useFillHeight(rootRef, fillHeight, minHeight)\n\n const closeAside = useCallback(() => setIsAsideOpen(false), [])\n const isAsidePanelOpen = !!aside && !hasAsideColumn && isAsideOpen\n useEffect(() => {\n if (!isAsidePanelOpen) return\n const onKey = (e: KeyboardEvent) => {\n if (e.key !== 'Escape') return\n closeAside()\n asideToggleRef.current?.focus()\n }\n const onPointer = (e: PointerEvent) => {\n const target = e.target as Node\n if (asideRef.current?.contains(target) || asideToggleRef.current?.contains(target)) return\n closeAside()\n }\n document.addEventListener('keydown', onKey)\n document.addEventListener('pointerdown', onPointer)\n return () => {\n document.removeEventListener('keydown', onKey)\n document.removeEventListener('pointerdown', onPointer)\n }\n }, [isAsidePanelOpen, closeAside])\n\n const last = chat.messages[chat.messages.length - 1]\n const announcement = useStreamAnnouncement({\n isStreaming: chat.isRunning,\n text: last?.role === 'assistant' ? last.content : '',\n resetKey: chat.activeThreadId,\n })\n\n const scrollToEnd = useCallback(() => {\n const el = scrollRef.current\n if (el) el.scrollTop = el.scrollHeight\n }, [])\n\n // Follow the answer while the reader is at the bottom; leave them alone once they scroll up.\n useEffect(() => {\n if (!isAway) scrollToEnd()\n }, [chat.messages, isAway, scrollToEnd])\n\n useEffect(() => {\n if (!targetMessageId) {\n jumpedToMessage.current = null\n return\n }\n const key = `${chat.activeThreadId}:${targetMessageId}`\n if (jumpedToMessage.current === key) return\n const row = Array.from(\n scrollRef.current?.querySelectorAll<HTMLElement>('[data-message-id]') || []\n ).find((element) => element.dataset.messageId === targetMessageId)\n if (!row) return\n jumpedToMessage.current = key\n row.scrollIntoView({ block: 'center' })\n setIsAway(true)\n }, [targetMessageId, chat.activeThreadId, chat.messages])\n useEffect(() => {\n setIsAway(false)\n }, [chat.activeThreadId])\n\n const onScroll = () => {\n const el = scrollRef.current\n if (el) setIsAway(el.scrollHeight - el.scrollTop - el.clientHeight > NEAR_BOTTOM_PX)\n }\n\n const submit = (e?: FormEvent) => {\n e?.preventDefault()\n const text = draft.trim()\n if (\n !text ||\n chat.isRunning ||\n chat.isPostingComment ||\n chat.isUpdatingAssistantMode ||\n chat.isLoadingThread ||\n chat.historyError\n )\n return\n setDraft('')\n // `/skill text` opens the skill's form with the text filled in; it is not sent as typed.\n if (slash?.startDraft(text)) return\n setIsAway(false)\n const selectedMentions = toMessageMentions(extractMentions(text, chat.mentionCandidates ?? []))\n const threadId = chat.activeThreadId\n const restoreDraft = () => {\n if (currentThreadRef.current === threadId) setDraft((current) => current || text)\n }\n try {\n const sent = selectedMentions.length\n ? chat.send(text, { mentions: selectedMentions })\n : chat.send(text)\n void Promise.resolve(sent).catch(restoreDraft)\n } catch {\n restoreDraft()\n }\n }\n\n const pickFiles = () => fileRef.current?.click()\n const onFiles = (files: File[]) => {\n if (files.length > 0) void chat.upload(files)\n }\n\n // Nothing to show in the bar: a compact chat with the list column and no actions or launcher toggle.\n const hasHeader = !(\n compactHeader &&\n hasListColumn &&\n !headerActions &&\n !(aside && !hasAsideColumn)\n )\n const activeThread = chat.threads.find((t) => t.id === chat.activeThreadId)\n const hasDocuments = chat.documents.length > 0\n const isEmpty = chat.messages.length === 0\n const heading = compactHeader\n ? null\n : (header ?? (\n <h2 className=\"min-w-0 truncate text-sm font-semibold text-foreground\">\n {activeThread?.title || l.untitled}\n </h2>\n ))\n\n return (\n <section\n ref={rootRef}\n aria-label={l.chat}\n data-slot=\"chat-page\"\n data-surface={surface}\n data-list={hasListColumn ? 'column' : 'select'}\n data-aside={aside ? (hasAsideColumn ? 'column' : 'panel') : undefined}\n data-testid={testIdOr(testIds?.root, { testId: 'chat-page' })}\n style={fillPx != null ? { height: fillPx } : undefined}\n className={cn(\n '@container/chat relative flex min-h-0 w-full overflow-hidden bg-background text-foreground',\n fillHeight ? 'h-[70dvh]' : 'h-full',\n className\n )}\n >\n {/* Conversation list: a column from 48rem of chat width. */}\n {hasListColumn && (\n <div className=\"flex w-64 shrink-0 flex-col border-r border-border\">\n <ChatThreadList\n threads={chat.threads}\n activeId={chat.activeThreadId}\n isLoading={chat.isLoadingThreads}\n labels={l}\n onSelect={chat.selectThread}\n onNew={chat.newThread}\n onDelete={chat.deleteThread}\n />\n </div>\n )}\n\n <div className=\"flex min-w-0 flex-1 flex-col\">\n {hasHeader && (\n <div\n ref={headerRef}\n data-slot=\"chat-page-header\"\n className=\"flex min-h-12 shrink-0 items-center gap-2 border-b border-border px-3 py-1.5\"\n >\n {/* Narrow: the list is a select and New chat a button; wide: both live in the column. */}\n {hasListColumn || singleThread ? (\n <div className=\"flex min-w-0 flex-1 items-center\">{heading}</div>\n ) : (\n <div className=\"flex min-w-0 flex-1 items-center gap-2\">\n {heading ? <div className=\"min-w-0 shrink\">{heading}</div> : null}\n <ChatThreadSelect\n threads={chat.threads}\n activeId={chat.activeThreadId}\n labels={l}\n onSelect={chat.selectThread}\n />\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"icon\"\n className=\"size-9 shrink-0 pointer-coarse:size-11\"\n aria-label={l.newChat}\n onClick={chat.newThread}\n data-testid=\"chat-new-compact\"\n >\n <MessageSquarePlus className=\"size-4\" aria-hidden=\"true\" />\n </Button>\n </div>\n )}\n {aside && !hasAsideColumn && (\n <Button\n ref={asideToggleRef}\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"shrink-0 gap-1.5 pointer-coarse:min-h-11\"\n aria-expanded={isAsideOpen}\n aria-controls=\"chat-page-aside\"\n onClick={() => setIsAsideOpen((v) => !v)}\n data-testid={testIdOr(testIds?.asideToggle, { testId: 'chat-aside-toggle' })}\n >\n <PanelRight className=\"size-4\" aria-hidden=\"true\" />\n {l.workflows}\n </Button>\n )}\n {headerActions}\n </div>\n )}\n\n <MessageList.Root\n isBusy={chat.isRunning}\n testId={testIdOr(testIds?.transcript, { testId: 'chat-messages' })}\n className=\"relative flex min-h-0 flex-1 flex-col\"\n >\n <MessageList.Status message={announcement} />\n <div\n ref={scrollRef}\n onScroll={onScroll}\n data-slot=\"chat-page-scroll\"\n className=\"scrollbar-themed relative min-h-0 flex-1 overflow-y-auto overscroll-contain\"\n >\n {isEmpty ? (\n chat.isLoadingDocuments || chat.isLoadingThread ? (\n <div\n role=\"status\"\n className=\"flex h-full items-center justify-center text-sm text-muted-foreground\"\n data-testid=\"chat-loading\"\n >\n {chat.isLoadingThread ? l.loadingConversation : l.loadingDocuments}\n </div>\n ) : (\n <ConversationEmpty\n hasDocuments={hasDocuments || !documentsRequired}\n prompts={prompts}\n onUsePrompt={(text) => {\n setDraft(text)\n textareaRef.current?.focus()\n }}\n onAddDocuments={(files) => (files ? onFiles(files) : pickFiles())}\n title={emptyTitle ?? l.emptyTitle}\n description={emptyDescription ?? l.emptyDescription}\n className=\"pb-6\"\n noDocuments={\n <>\n <div className=\"text-center\">\n <h2 className=\"text-lg font-semibold\">{l.emptyUploadTitle}</h2>\n <p className=\"mt-1 text-sm text-muted-foreground\">\n {l.emptyUploadDescription}\n </p>\n </div>\n <Button\n type=\"button\"\n className=\"gap-2 pointer-coarse:min-h-11\"\n onClick={pickFiles}\n disabled={chat.isUploading}\n >\n <Upload className=\"size-4\" aria-hidden=\"true\" />\n {chat.isUploading ? l.uploading : l.uploadDocuments}\n </Button>\n </>\n }\n />\n )\n ) : (\n <div\n role=\"list\"\n aria-label=\"Conversation messages\"\n className=\"mx-auto flex w-full max-w-3xl flex-col gap-5 px-3 py-5 @lg/chat:px-6\"\n >\n {chat.messages.map((message) => (\n <div\n key={message.id}\n role=\"listitem\"\n data-message-id={message.id}\n className={\n message.id === targetMessageId\n ? 'rounded-lg ring-2 ring-primary/40'\n : undefined\n }\n >\n <MessageRow\n message={message}\n renderContent={renderContent}\n onOpenCitation={onOpenCitation}\n workflowStepOf={workflowStepOf}\n labels={l}\n />\n </div>\n ))}\n </div>\n )}\n </div>\n <ScrollToBottom\n className=\"bottom-3 top-auto\"\n show={isAway && !isEmpty}\n onClick={() => {\n setIsAway(false)\n scrollToEnd()\n }}\n />\n </MessageList.Root>\n\n <div className=\"shrink-0 border-t border-border/60 bg-background px-3 pb-3 pt-2 @lg/chat:px-6\">\n <div className=\"mx-auto w-full max-w-3xl\">\n {chat.error && (\n <MessageAlert\n title={l.answerFailedTitle}\n description={chat.error}\n isBusy={chat.isRunning}\n onActivate={() => void chat.retry()}\n testId={testIdOr(testIds?.alert, { testId: 'chat-alert' })}\n />\n )}\n {chat.historyError && (\n <MessageAlert\n title={l.historyFailedTitle}\n description={chat.historyError}\n testId=\"chat-history-alert\"\n />\n )}\n {chat.uploadError && (\n <MessageAlert\n title={l.uploadFailedTitle}\n description={chat.uploadError}\n testId=\"chat-upload-alert\"\n />\n )}\n {slash?.launcher}\n <Composer.Root onSubmit={submit} testId=\"chat-composer\">\n <Composer.Frame className=\"px-3 py-2 shadow-sm\">\n <SlashMenu\n open={isSlashOpen}\n items={slashItems}\n selectedIndex={slashNav.selectedIndex}\n setSelectedIndex={slashNav.setSelectedIndex}\n listboxId={slashNav.listboxId}\n onSelect={pickSlash}\n onBrowse={slash?.onBrowse}\n />\n <MentionMenu\n open={mentions.isOpen}\n items={mentions.items}\n selectedIndex={mentions.nav.selectedIndex}\n setSelectedIndex={mentions.nav.setSelectedIndex}\n listboxId={mentions.nav.listboxId}\n onSelect={mentions.pick}\n />\n <Composer.Input\n value={draft}\n onValueChange={mentions.onValueChange}\n onKeyDown={(event) => {\n if (slashNav.handleKeyDown(event)) return\n mentions.nav.handleKeyDown(event)\n }}\n textareaProps={{\n ...mentions.textareaProps,\n ...(isSlashOpen\n ? slashNav.comboboxProps\n : chat.mentionCandidates?.length\n ? mentions.nav.comboboxProps\n : {}),\n }}\n placeholder={l.placeholder}\n ariaLabel={l.composerAriaLabel}\n textareaRef={textareaRef}\n testId={testIdOr(testIds?.input, { testId: 'chat-input' })}\n />\n <Composer.Toolbar\n leading={\n <>\n {chat.assistantMode && chat.setAssistantMode && (\n <AssistantModeToggle\n mode={chat.assistantMode}\n onModeChange={(mode) => void chat.setAssistantMode?.(mode)}\n disabled={\n chat.isRunning || chat.isPostingComment || chat.isUpdatingAssistantMode\n }\n />\n )}\n <ChatDocuments\n chat={chat}\n labels={l}\n onPickFiles={pickFiles}\n testIds={{ documents: testIds?.documents, upload: testIds?.upload }}\n />\n </>\n }\n trailing={\n chat.isRunning && chat.stop ? (\n <Button\n type=\"button\"\n size=\"icon\"\n variant=\"outline\"\n className=\"h-9 w-9 shrink-0 pointer-coarse:h-11 pointer-coarse:w-11\"\n aria-label={l.stop}\n title={l.stop}\n onClick={chat.stop}\n data-testid=\"chat-stop\"\n >\n <Square className=\"h-3.5 w-3.5 fill-current\" aria-hidden=\"true\" />\n </Button>\n ) : (\n <Composer.Send\n onSend={() => submit()}\n disabled={\n chat.isRunning ||\n chat.isPostingComment ||\n chat.isUpdatingAssistantMode ||\n chat.isLoadingThread ||\n Boolean(chat.historyError) ||\n draft.trim() === ''\n }\n testIds={{ send: testIdOr(testIds?.send, { testId: 'chat-send' }) }}\n />\n )\n }\n />\n </Composer.Frame>\n </Composer.Root>\n </div>\n </div>\n </div>\n\n {/*\n The workflow launcher, rendered once: a column beside the chat from `asideBreakpoint`, and\n below it a panel anchored under the header that floats over the transcript (nothing is\n pushed down) and opens with the header button.\n */}\n {aside && (\n <aside\n ref={asideRef}\n id=\"chat-page-aside\"\n aria-label={l.workflows}\n data-slot=\"chat-page-aside\"\n data-mode={hasAsideColumn ? 'column' : 'panel'}\n data-testid={testIdOr(testIds?.aside, { testId: 'chat-aside' })}\n hidden={!hasAsideColumn && !isAsideOpen}\n style={hasAsideColumn ? undefined : { top: headerHeight + 4 }}\n className={cn(\n 'scrollbar-themed overflow-y-auto bg-background',\n hasAsideColumn\n ? 'w-72 shrink-0 border-l border-border p-4'\n : 'absolute right-2 z-20 max-h-[min(60%,32rem)] w-[min(22rem,calc(100%-1rem))] rounded-lg border border-border bg-popover p-3 text-popover-foreground shadow-lg'\n )}\n >\n {aside}\n </aside>\n )}\n\n <input\n ref={fileRef}\n type=\"file\"\n multiple\n accept={accept}\n className=\"sr-only\"\n tabIndex={-1}\n aria-hidden=\"true\"\n data-testid=\"chat-file-input\"\n onChange={(e) => {\n onFiles(Array.from(e.target.files ?? []))\n e.target.value = ''\n }}\n />\n </section>\n )\n}\n"]}
|