@case-framework/survey-assistant 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -4
- package/dist/{authoring-references-CW38pYzK.mjs → authoring-references-BJQ_1nMX.mjs} +2 -2
- package/dist/authoring-references-BJQ_1nMX.mjs.map +1 -0
- package/dist/capabilities-1KNnNO1_.mjs +73 -0
- package/dist/capabilities-1KNnNO1_.mjs.map +1 -0
- package/dist/capabilities-default.d.mts +1 -1
- package/dist/capabilities-default.d.mts.map +1 -1
- package/dist/capabilities-default.mjs +22 -25
- package/dist/capabilities-default.mjs.map +1 -1
- package/dist/{constants-BMGTgfjv.d.mts → constants-Be91Gay9.d.mts} +3 -3
- package/dist/{constants-BMGTgfjv.d.mts.map → constants-Be91Gay9.d.mts.map} +1 -1
- package/dist/{controller-proxy-DMTqer6T.mjs → controller-proxy-BH05e-C2.mjs} +21 -8
- package/dist/controller-proxy-BH05e-C2.mjs.map +1 -0
- package/dist/{controller-proxy-mRvez2qw.d.mts → controller-proxy-Bd0ZHBPF.d.mts} +11 -11
- package/dist/controller-proxy-Bd0ZHBPF.d.mts.map +1 -0
- package/dist/{engine-CQwOAcwK.mjs → engine-Bo85Oyj0.mjs} +2985 -2347
- package/dist/engine-Bo85Oyj0.mjs.map +1 -0
- package/dist/engine.d.mts +2 -2
- package/dist/engine.mjs +3 -3
- package/dist/{index-D6nqkz0O.d.mts → index-Tnqv-yKW.d.mts} +56 -71
- package/dist/index-Tnqv-yKW.d.mts.map +1 -0
- package/dist/index-l_EK4yK7.d.mts +404 -0
- package/dist/index-l_EK4yK7.d.mts.map +1 -0
- package/dist/{index-DvTqML-0.d.mts → index-nhrgbgO5.d.mts} +19 -5
- package/dist/index-nhrgbgO5.d.mts.map +1 -0
- package/dist/{index-B0lxsAzx.d.mts → index-x0qprHgK.d.mts} +19 -7
- package/dist/index-x0qprHgK.d.mts.map +1 -0
- package/dist/{lifecycle-BmGAIUlv.d.mts → lifecycle-Bx0aq_4S.d.mts} +7 -1
- package/dist/{lifecycle-BmGAIUlv.d.mts.map → lifecycle-Bx0aq_4S.d.mts.map} +1 -1
- package/dist/{memory-thread-repository-CjFGVNZh.mjs → memory-thread-repository-KWHQWFEW.mjs} +43 -12
- package/dist/memory-thread-repository-KWHQWFEW.mjs.map +1 -0
- package/dist/{protocol-DJUP4gc0.mjs → protocol-BhzQbx81.mjs} +66 -16
- package/dist/protocol-BhzQbx81.mjs.map +1 -0
- package/dist/protocol.d.mts +3 -3
- package/dist/protocol.mjs +2 -2
- package/dist/react-B3ybjJ-X.mjs +1620 -0
- package/dist/react-B3ybjJ-X.mjs.map +1 -0
- package/dist/react-integration.d.mts +1 -1
- package/dist/react-integration.mjs +1 -1
- package/dist/react.d.mts +3 -3
- package/dist/react.mjs +3 -3
- package/dist/references/assistant-operations.md +45 -39
- package/dist/references/expressions.md +28 -0
- package/dist/references/item-types.md +1 -1
- package/dist/references/localization.md +5 -4
- package/dist/references/rich-text-content.md +60 -27
- package/dist/references/source-material-surveys.md +9 -2
- package/dist/references/survey-data-model.md +9 -1
- package/dist/{request-context-BjTHNcDd.mjs → request-context-CG4SWijt.mjs} +3 -3
- package/dist/{request-context-BjTHNcDd.mjs.map → request-context-CG4SWijt.mjs.map} +1 -1
- package/dist/server-agent.d.mts +19 -8
- package/dist/server-agent.d.mts.map +1 -1
- package/dist/server-agent.mjs +7 -11
- package/dist/server-agent.mjs.map +1 -1
- package/dist/server-runtime.d.mts +19 -13
- package/dist/server-runtime.d.mts.map +1 -1
- package/dist/server-runtime.mjs +7 -2
- package/dist/server-runtime.mjs.map +1 -1
- package/dist/server-tasks.d.mts +1 -1
- package/dist/server-tasks.mjs +2 -2
- package/dist/server-tools.d.mts +1 -1
- package/dist/server-tools.mjs +1 -1
- package/dist/server.d.mts +5 -5
- package/dist/server.mjs +3 -3
- package/dist/{tasks-DxzD25Zc.d.mts → tasks-CYqrcaRO.d.mts} +4 -4
- package/dist/{tasks-DxzD25Zc.d.mts.map → tasks-CYqrcaRO.d.mts.map} +1 -1
- package/dist/{thread-handlers-AbQbt4sX.d.mts → thread-handlers-DBAaU7BA.d.mts} +6 -4
- package/dist/thread-handlers-DBAaU7BA.d.mts.map +1 -0
- package/dist/{tools-CFh35R4d.mjs → tools-BvSovehT.mjs} +431 -495
- package/dist/tools-BvSovehT.mjs.map +1 -0
- package/dist/ui.css +1 -1
- package/dist/ui.d.mts +5 -4
- package/dist/ui.d.mts.map +1 -1
- package/dist/ui.mjs +619 -66
- package/dist/ui.mjs.map +1 -1
- package/docs/integration.md +40 -0
- package/package.json +21 -19
- package/dist/authoring-references-CW38pYzK.mjs.map +0 -1
- package/dist/controller-proxy-DMTqer6T.mjs.map +0 -1
- package/dist/controller-proxy-mRvez2qw.d.mts.map +0 -1
- package/dist/engine-CQwOAcwK.mjs.map +0 -1
- package/dist/form-authoring-kQDgC5oz.mjs +0 -155
- package/dist/form-authoring-kQDgC5oz.mjs.map +0 -1
- package/dist/index-B0lxsAzx.d.mts.map +0 -1
- package/dist/index-BS-Xjk1h.d.mts +0 -224
- package/dist/index-BS-Xjk1h.d.mts.map +0 -1
- package/dist/index-D6nqkz0O.d.mts.map +0 -1
- package/dist/index-DvTqML-0.d.mts.map +0 -1
- package/dist/memory-thread-repository-CjFGVNZh.mjs.map +0 -1
- package/dist/protocol-DJUP4gc0.mjs.map +0 -1
- package/dist/react-Dqlmasrs.mjs +0 -768
- package/dist/react-Dqlmasrs.mjs.map +0 -1
- package/dist/thread-handlers-AbQbt4sX.d.mts.map +0 -1
- package/dist/tools-CFh35R4d.mjs.map +0 -1
package/dist/ui.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ui.mjs","names":["Collapsible","CollapsiblePrimitive","Collapsible","TooltipPrimitive","Tooltip","Tooltip","Select","SelectPrimitive","Select","isRecord","Collapsible"],"sources":["../src/ui/internal/collapsible.tsx","../src/ui/utils.ts","../src/ui/internal/shimmer.tsx","../src/ui/localizations/en.ts","../src/ui/localizations/nl.ts","../src/ui/localization.tsx","../src/ui/internal/chain-of-thought.tsx","../src/ui/internal/button.tsx","../src/ui/internal/conversation.tsx","../src/ui/internal/message.tsx","../src/ui/internal/tooltip.tsx","../src/ui/internal/prompt-input.tsx","../src/ui/internal/select.tsx","../src/ui/survey-assistant-prompt-input.tsx","../src/ui/internal/tool-technical-details.ts","../src/ui/internal/code-block.tsx","../src/ui/internal/response.tsx","../src/ui/internal/message-timing.ts","../src/ui/internal/message-turn-status.ts","../src/ui/initial-thread-load.ts","../src/ui/survey-assistant-panel.tsx","../src/ui/survey-assistant-thread-launcher-prompt.tsx","../src/ui/connected-survey-assistant-panel.tsx"],"sourcesContent":["\"use client\";\n\nimport { Collapsible as CollapsiblePrimitive } from \"radix-ui\";\n\nfunction Collapsible({ ...props }: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {\n return <CollapsiblePrimitive.Root data-slot=\"collapsible\" {...props} />;\n}\n\nfunction CollapsibleTrigger({\n ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {\n return <CollapsiblePrimitive.CollapsibleTrigger data-slot=\"collapsible-trigger\" {...props} />;\n}\n\nfunction CollapsibleContent({\n ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {\n return <CollapsiblePrimitive.CollapsibleContent data-slot=\"collapsible-content\" {...props} />;\n}\n\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent };\n","import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport const cn = (...inputs: ClassValue[]) => twMerge(clsx(inputs));\n","\"use client\";\n\n/* eslint-disable react-hooks/static-components */\n\nimport { cn } from \"../utils\";\nimport type { MotionProps } from \"motion/react\";\nimport { motion } from \"motion/react\";\nimport type { CSSProperties, ElementType, JSX } from \"react\";\nimport { memo, useMemo } from \"react\";\n\ntype MotionHTMLProps = MotionProps & Record<string, unknown>;\n\n// Cache motion components at module level to avoid creating during render\nconst motionComponentCache = new Map<\n keyof JSX.IntrinsicElements,\n React.ComponentType<MotionHTMLProps>\n>();\n\nconst getMotionComponent = (element: keyof JSX.IntrinsicElements) => {\n let component = motionComponentCache.get(element);\n if (!component) {\n component = motion.create(element);\n motionComponentCache.set(element, component);\n }\n return component;\n};\n\nexport interface TextShimmerProps {\n children: string;\n as?: ElementType;\n className?: string;\n duration?: number;\n spread?: number;\n}\n\nconst ShimmerComponent = ({\n children,\n as: Component = \"p\",\n className,\n duration = 2,\n spread = 2,\n}: TextShimmerProps) => {\n const MotionComponent = getMotionComponent(Component as keyof JSX.IntrinsicElements);\n\n const dynamicSpread = useMemo(() => (children?.length ?? 0) * spread, [children, spread]);\n\n return (\n <MotionComponent\n animate={{ backgroundPosition: \"0% center\" }}\n className={cn(\n \"relative inline-block bg-[length:250%_100%,auto] bg-clip-text text-transparent\",\n \"[--bg:linear-gradient(90deg,#0000_calc(50%-var(--spread)),var(--color-background),#0000_calc(50%+var(--spread)))] [background-repeat:no-repeat,padding-box]\",\n className,\n )}\n initial={{ backgroundPosition: \"100% center\" }}\n style={\n {\n \"--spread\": `${dynamicSpread}px`,\n backgroundImage:\n \"var(--bg), linear-gradient(var(--color-muted-foreground), var(--color-muted-foreground))\",\n } as CSSProperties\n }\n transition={{\n duration,\n ease: \"linear\",\n repeat: Number.POSITIVE_INFINITY,\n }}\n >\n {children}\n </MotionComponent>\n );\n};\n\nexport const Shimmer = memo(ShimmerComponent);\n","import type { LocalizationMessages } from \"@case-framework/ui-localization\";\n\nexport const surveyAssistantEnMessages: LocalizationMessages = {\n panel: {\n ariaLabel: \"Survey assistant\",\n title: \"Assistant\",\n loadingChats: \"Loading chats\",\n controlsUnavailable: \"Assistant controls unavailable\",\n },\n empty: {\n title: \"What are you working on?\",\n description:\n \"Draft, inspect, or refine your survey - just describe what you need, or start with one of these.\",\n newSurveyTitle: \"Create with the assistant\",\n newSurveyDescription:\n \"Describe the survey you need, share a brief, or plan the right questions together.\",\n },\n quickActions: {\n draftSurvey: {\n label: \"Draft a survey\",\n description: \"Create a first draft from your goals\",\n prompt:\n \"Help me create a first draft of a new survey. Ask me about its topic, audience, and goals before drafting it.\",\n },\n useBrief: {\n label: \"Use a brief or notes\",\n description: \"Turn requirements into a survey\",\n prompt:\n \"Help me turn a brief or set of notes into a survey. Ask me to paste the text or attach the document.\",\n },\n planSurvey: {\n label: \"Plan the questions\",\n description: \"Outline the structure before drafting\",\n prompt: \"Help me plan the questions and structure for a new survey before we draft it.\",\n },\n review: {\n label: \"Review survey\",\n description: \"Spot issues and suggest improvements\",\n prompt:\n \"Run a deterministic audit of the current survey, including expression-reference integrity, then review its quality and suggest improvements.\",\n },\n create: {\n label: \"New question\",\n description: \"Draft a question to add\",\n prompt: \"Help me create a new survey question.\",\n },\n refine: {\n label: \"Refine wording\",\n description: \"Polish respondent-facing text\",\n prompt: \"Suggest improvements to the respondent-facing wording.\",\n },\n refineSelection: {\n label: \"Refine selected item\",\n description: \"Polish the wording in context\",\n prompt: \"Suggest improvements to the respondent-facing wording of the selected item.\",\n },\n },\n input: {\n placeholder: \"Ask about the survey...\",\n attachFiles: \"Attach a PDF, PNG, or JPG\",\n dropFiles: \"Drop a PDF, PNG, or JPG to attach\",\n supportedFiles: \"Supported: PDF, PNG, and JPG. Export Word documents as PDF.\",\n unsupportedFiles: \"{filenames} can't be attached. Supported formats: PDF, PNG, and JPG.\",\n wordFilesUnsupported:\n \"Word documents aren't supported. Export {filenames} as PDF, then attach the PDF.\",\n removeFile: \"Remove {filename}\",\n send: \"Send message\",\n stop: \"Stop response\",\n model: \"Assistant model\",\n defaultModel: \"Default model\",\n },\n conversation: {\n loadEarlier: \"Load earlier messages\",\n loadingEarlier: \"Loading earlier messages…\",\n noMessages: \"No messages yet\",\n startConversation: \"Start a conversation to see messages here\",\n scrollToLatest: \"Scroll to latest message\",\n working: \"Working...\",\n stopped: \"Stopped\",\n incomplete: \"Response interrupted\",\n },\n turn: {\n failedTitle: \"The assistant did not complete this turn.\",\n abortedTitle: \"The turn was stopped.\",\n reasons: {\n clientAbort: \"The request was stopped by the client.\",\n firstResponseTimeout: \"No meaningful response arrived before the initial deadline.\",\n idleTimeout: \"The assistant stopped producing activity.\",\n maxDuration: \"The one-hour execution ceiling was reached.\",\n maxSteps: \"The assistant reached its tool-step limit before finishing.\",\n lengthLimit: \"The model reached its output-length limit.\",\n contentFilter: \"The provider stopped the response because of its content policy.\",\n providerError: \"The model provider reported an error.\",\n streamError: \"The response stream ended with an error.\",\n incompleteResponse: \"The response ended without a normal completion.\",\n unknown: \"The response ended before completion.\",\n },\n },\n status: {\n applying: \"Applying changes\",\n applied: \"Changes applied\",\n stopped: \"Stopped\",\n attention: \"Needs attention\",\n ready: \"Ready\",\n connecting: \"Connecting to the assistant\",\n thinking: \"Thinking through your request\",\n writing: \"Writing the response\",\n working: \"Working on your request\",\n },\n activity: {\n label: \"Activity\",\n working: \"Working...\",\n workedFor: \"Worked for {duration}\",\n technicalDetails: \"View technical details\",\n hideTechnicalDetails: \"Hide technical details\",\n waitingApproval: \"Waiting for approval\",\n approvalReceived: \"Approval received\",\n continuingApproval: \"Continuing after approval\",\n preparingStep: \"Preparing the next step\",\n usingResult: \"Using the result\",\n continuingWithoutStep: \"Continuing without that step\",\n recoveringToolError: \"Recovering from a tool error\",\n skipped: \"Skipped\",\n failed: \"Failed\",\n workingShort: \"Working\",\n done: \"Done\",\n stopped: \"Stopped\",\n expressionChange: \"Expression change\",\n surveyChange: \"Survey change\",\n genericActive: \"Working with survey\",\n genericComplete: \"Survey step complete\",\n failedSuffix: \"{name} failed\",\n skippedSuffix: \"{name} skipped\",\n tools: {\n survey_inspect: { active: \"Reviewing survey\", complete: \"Survey reviewed\" },\n survey_change: { active: \"Preparing change\", complete: \"Change prepared\" },\n survey_expression: { active: \"Preparing expression\", complete: \"Expression prepared\" },\n survey_authoring_reference: {\n active: \"Checking authoring guidance\",\n complete: \"Authoring guidance checked\",\n },\n survey_attachment: { active: \"Opening attachment\", complete: \"Attachment opened\" },\n recall: {\n active: \"Checking earlier conversation\",\n complete: \"Earlier conversation checked\",\n },\n },\n },\n changes: {\n applied: \"Change applied\",\n stale: \"Change not applied\",\n failed: \"Change could not be applied\",\n prepared: \"Change prepared\",\n rejected: \"Change could not be prepared\",\n operationCount: \"{count} operation\",\n operationCountPlural: \"{count} operations\",\n issueCount: \"{count} issue\",\n issueCountPlural: \"{count} issues\",\n warningCount: \"{count} warning\",\n warningCountPlural: \"{count} warnings\",\n incompleteTitle: \"The requested changes were not completed.\",\n blocked:\n \"No survey changes were applied because {count} rejected change proposal remains unresolved.\",\n blockedPlural:\n \"No survey changes were applied because {count} rejected change proposals remain unresolved.\",\n partial: \"{applied} change set was applied; {failed} could not be applied.\",\n partialPlural: \"{applied} change sets were applied; {failed} could not be applied.\",\n reviewBeforeRetry: \"Review the change steps above before retrying.\",\n },\n errors: {\n dismiss: \"Dismiss\",\n dismissAssistant: \"Dismiss assistant error\",\n retry: \"Try again\",\n fallbackDetail: \"The assistant hit an error on the previous turn.\",\n model_unavailable: {\n title: \"Model unavailable\",\n hint: \"Select a model available to this account, then send the message again.\",\n },\n rate_limited: {\n title: \"Assistant temporarily busy\",\n hint: \"Wait a moment, then send the message again.\",\n },\n authorization_failed: {\n title: \"Assistant unavailable\",\n hint: \"Check your access or sign in again before retrying.\",\n },\n attachment_unavailable: {\n title: \"Attachment unavailable\",\n hint: \"Attach the file again or continue without it.\",\n },\n request_failed: {\n title: \"Assistant could not complete request\",\n hint: \"You can continue with another message.\",\n },\n },\n threads: {\n newChat: \"New chat\",\n history: \"Chat history\",\n recent: \"Recent chats\",\n search: \"Search chats\",\n searching: \"Searching older chats…\",\n noMatches: \"No matching chats\",\n loadOlder: \"Load older chats\",\n loadingOlder: \"Loading older chats…\",\n automaticTitle: \"Use automatic title\",\n automaticShort: \"Auto\",\n rename: \"Rename {title}\",\n renameTitle: \"Rename chat\",\n delete: \"Delete {title}\",\n deleteTitle: \"Delete chat\",\n deleteConfirm: 'Delete \"{title}\" and its attachments?',\n },\n};\n","import type { LocalizationMessages } from \"@case-framework/ui-localization\";\n\nexport const surveyAssistantNlMessages: LocalizationMessages = {\n panel: {\n ariaLabel: \"Surveyassistent\",\n title: \"Assistent\",\n loadingChats: \"Chats laden\",\n controlsUnavailable: \"Bediening van de assistent niet beschikbaar\",\n },\n empty: {\n title: \"Waar werk je aan?\",\n description:\n \"Maak, controleer of verbeter je survey. Beschrijf wat je nodig hebt of kies een van deze opties.\",\n newSurveyTitle: \"Maak iets met de assistent\",\n newSurveyDescription:\n \"Beschrijf de survey die je nodig hebt, deel een briefing of plan samen de juiste vragen.\",\n },\n quickActions: {\n draftSurvey: {\n label: \"Een survey opstellen\",\n description: \"Maak een eerste versie vanuit je doelen\",\n prompt:\n \"Help me een eerste versie van een nieuwe survey te maken. Vraag me vóór het opstellen naar het onderwerp, de doelgroep en de doelen.\",\n },\n useBrief: {\n label: \"Gebruik een briefing of notities\",\n description: \"Zet vereisten om in een survey\",\n prompt:\n \"Help me een briefing of verzameling notities om te zetten in een survey. Vraag me de tekst te plakken of het document toe te voegen.\",\n },\n planSurvey: {\n label: \"Plan de vragen\",\n description: \"Schets eerst de structuur\",\n prompt:\n \"Help me de vragen en structuur voor een nieuwe survey te plannen voordat we die opstellen.\",\n },\n review: {\n label: \"Survey controleren\",\n description: \"Problemen vinden en verbeteringen voorstellen\",\n prompt:\n \"Voer een deterministische controle van de huidige survey uit, inclusief de geldigheid van expressieverwijzingen, beoordeel daarna de kwaliteit en stel verbeteringen voor.\",\n },\n create: {\n label: \"Nieuwe vraag\",\n description: \"Een vraag opstellen en toevoegen\",\n prompt: \"Help me een nieuwe surveyvraag te maken.\",\n },\n refine: {\n label: \"Formulering verbeteren\",\n description: \"Tekst voor respondenten aanscherpen\",\n prompt: \"Stel verbeteringen voor voor de tekst die respondenten zien.\",\n },\n refineSelection: {\n label: \"Geselecteerd item verbeteren\",\n description: \"Scherp de formulering in context aan\",\n prompt:\n \"Stel verbeteringen voor voor de respondentgerichte formulering van het geselecteerde item.\",\n },\n },\n input: {\n placeholder: \"Vraag iets over de survey...\",\n attachFiles: \"Een pdf-, png- of jpg-bestand toevoegen\",\n dropFiles: \"Sleep een pdf-, png- of jpg-bestand hierheen om het toe te voegen\",\n supportedFiles: \"Ondersteund: pdf, png en jpg. Exporteer Word-documenten als pdf.\",\n unsupportedFiles:\n \"{filenames} kan niet worden toegevoegd. Ondersteunde formaten: pdf, png en jpg.\",\n wordFilesUnsupported:\n \"Word-documenten worden niet ondersteund. Exporteer {filenames} als pdf en voeg daarna de pdf toe.\",\n removeFile: \"{filename} verwijderen\",\n send: \"Bericht verzenden\",\n stop: \"Antwoord stoppen\",\n model: \"Assistentmodel\",\n defaultModel: \"Standaardmodel\",\n },\n conversation: {\n loadEarlier: \"Eerdere berichten laden\",\n loadingEarlier: \"Eerdere berichten laden…\",\n noMessages: \"Nog geen berichten\",\n startConversation: \"Start een gesprek om hier berichten te zien\",\n scrollToLatest: \"Naar het nieuwste bericht scrollen\",\n working: \"Bezig...\",\n stopped: \"Gestopt\",\n incomplete: \"Antwoord onderbroken\",\n },\n turn: {\n failedTitle: \"De assistent heeft deze beurt niet voltooid.\",\n abortedTitle: \"De beurt is gestopt.\",\n reasons: {\n clientAbort: \"Het verzoek is door de client gestopt.\",\n firstResponseTimeout: \"Er kwam geen betekenisvol antwoord vóór de eerste tijdslimiet.\",\n idleTimeout: \"De assistent produceerde geen activiteit meer.\",\n maxDuration: \"De maximale uitvoertijd van één uur is bereikt.\",\n maxSteps: \"De assistent bereikte de limiet voor hulpmiddelstappen voordat hij klaar was.\",\n lengthLimit: \"Het model bereikte de maximale antwoordlengte.\",\n contentFilter: \"De provider stopte het antwoord vanwege het inhoudsbeleid.\",\n providerError: \"De modelprovider meldde een fout.\",\n streamError: \"De antwoordstream eindigde met een fout.\",\n incompleteResponse: \"Het antwoord eindigde zonder normale voltooiing.\",\n unknown: \"Het antwoord eindigde voordat het voltooid was.\",\n },\n },\n status: {\n applying: \"Wijzigingen toepassen\",\n applied: \"Wijzigingen toegepast\",\n stopped: \"Gestopt\",\n attention: \"Aandacht nodig\",\n ready: \"Gereed\",\n connecting: \"Verbinding maken met de assistent\",\n thinking: \"Verzoek doordenken\",\n writing: \"Antwoord schrijven\",\n working: \"Aan je verzoek werken\",\n },\n activity: {\n label: \"Activiteit\",\n working: \"Bezig...\",\n workedFor: \"{duration} gewerkt\",\n technicalDetails: \"Technische details tonen\",\n hideTechnicalDetails: \"Technische details verbergen\",\n waitingApproval: \"Wachten op goedkeuring\",\n approvalReceived: \"Goedkeuring ontvangen\",\n continuingApproval: \"Doorgaan na goedkeuring\",\n preparingStep: \"Volgende stap voorbereiden\",\n usingResult: \"Resultaat gebruiken\",\n continuingWithoutStep: \"Doorgaan zonder die stap\",\n recoveringToolError: \"Herstellen van een fout in een hulpmiddel\",\n skipped: \"Overgeslagen\",\n failed: \"Mislukt\",\n workingShort: \"Bezig\",\n done: \"Gereed\",\n stopped: \"Gestopt\",\n expressionChange: \"Expressiewijziging\",\n surveyChange: \"Surveywijziging\",\n genericActive: \"Werken met de survey\",\n genericComplete: \"Surveystap voltooid\",\n failedSuffix: \"{name} mislukt\",\n skippedSuffix: \"{name} overgeslagen\",\n tools: {\n survey_inspect: { active: \"Survey controleren\", complete: \"Survey gecontroleerd\" },\n survey_change: { active: \"Wijziging voorbereiden\", complete: \"Wijziging voorbereid\" },\n survey_expression: {\n active: \"Expressie voorbereiden\",\n complete: \"Expressie voorbereid\",\n },\n survey_authoring_reference: {\n active: \"Auteursrichtlijnen controleren\",\n complete: \"Auteursrichtlijnen gecontroleerd\",\n },\n survey_attachment: { active: \"Bijlage openen\", complete: \"Bijlage geopend\" },\n recall: {\n active: \"Eerder gesprek controleren\",\n complete: \"Eerder gesprek gecontroleerd\",\n },\n },\n },\n changes: {\n applied: \"Wijziging toegepast\",\n stale: \"Wijziging niet toegepast\",\n failed: \"Wijziging kon niet worden toegepast\",\n prepared: \"Wijziging voorbereid\",\n rejected: \"Wijziging kon niet worden voorbereid\",\n operationCount: \"{count} bewerking\",\n operationCountPlural: \"{count} bewerkingen\",\n issueCount: \"{count} probleem\",\n issueCountPlural: \"{count} problemen\",\n warningCount: \"{count} waarschuwing\",\n warningCountPlural: \"{count} waarschuwingen\",\n incompleteTitle: \"De gevraagde wijzigingen zijn niet voltooid.\",\n blocked:\n \"Er zijn geen surveywijzigingen toegepast omdat {count} afgewezen wijzigingsvoorstel nog niet is opgelost.\",\n blockedPlural:\n \"Er zijn geen surveywijzigingen toegepast omdat {count} afgewezen wijzigingsvoorstellen nog niet zijn opgelost.\",\n partial: \"{applied} wijzigingsset is toegepast; {failed} kon niet worden toegepast.\",\n partialPlural:\n \"{applied} wijzigingssets zijn toegepast; {failed} konden niet worden toegepast.\",\n reviewBeforeRetry:\n \"Controleer de bovenstaande wijzigingsstappen voordat je het opnieuw probeert.\",\n },\n errors: {\n dismiss: \"Sluiten\",\n dismissAssistant: \"Assistentfout sluiten\",\n retry: \"Opnieuw proberen\",\n fallbackDetail: \"Er is tijdens de vorige beurt een fout opgetreden.\",\n model_unavailable: {\n title: \"Model niet beschikbaar\",\n hint: \"Selecteer een model dat beschikbaar is voor dit account en verzend het bericht opnieuw.\",\n },\n rate_limited: {\n title: \"Assistent tijdelijk bezet\",\n hint: \"Wacht even en verzend het bericht daarna opnieuw.\",\n },\n authorization_failed: {\n title: \"Assistent niet beschikbaar\",\n hint: \"Controleer je toegang of meld je opnieuw aan voordat je het opnieuw probeert.\",\n },\n attachment_unavailable: {\n title: \"Bijlage niet beschikbaar\",\n hint: \"Voeg het bestand opnieuw toe of ga verder zonder het bestand.\",\n },\n request_failed: {\n title: \"Assistent kon het verzoek niet voltooien\",\n hint: \"Je kunt doorgaan met een nieuw bericht.\",\n },\n },\n threads: {\n newChat: \"Nieuwe chat\",\n history: \"Chatgeschiedenis\",\n recent: \"Recente chats\",\n search: \"Chats zoeken\",\n searching: \"Oudere chats zoeken…\",\n noMatches: \"Geen overeenkomende chats\",\n loadOlder: \"Oudere chats laden\",\n loadingOlder: \"Oudere chats laden…\",\n automaticTitle: \"Automatische titel gebruiken\",\n automaticShort: \"Automatisch\",\n rename: \"{title} hernoemen\",\n renameTitle: \"Chat hernoemen\",\n delete: \"{title} verwijderen\",\n deleteTitle: \"Chat verwijderen\",\n deleteConfirm: '\"{title}\" en de bijlagen verwijderen?',\n },\n};\n","\"use client\";\n\nimport {\n createLocalizationTranslator,\n mergeLocalizationCatalogs,\n type LocalizationCatalog,\n type LocalizationTranslate,\n} from \"@case-framework/ui-localization\";\nimport { createContext, useContext, useMemo, type ReactNode } from \"react\";\nimport { surveyAssistantEnMessages } from \"./localizations/en\";\nimport { surveyAssistantNlMessages } from \"./localizations/nl\";\n\nexport { surveyAssistantEnMessages } from \"./localizations/en\";\nexport { surveyAssistantNlMessages } from \"./localizations/nl\";\n\nexport const defaultSurveyAssistantLocalizations: LocalizationCatalog = {\n en: surveyAssistantEnMessages,\n nl: surveyAssistantNlMessages,\n};\n\nconst SurveyAssistantLocalizationContext = createContext<LocalizationTranslate | null>(null);\n\nexport interface SurveyAssistantLocalizationProviderProps {\n children: ReactNode;\n language?: string;\n localizations?: LocalizationCatalog;\n}\n\nexport const SurveyAssistantLocalizationProvider = ({\n children,\n language = \"en\",\n localizations,\n}: SurveyAssistantLocalizationProviderProps) => {\n const translate = useMemo(\n () =>\n createLocalizationTranslator({\n fallbackLocale: \"en\",\n locale: language,\n localizations: mergeLocalizationCatalogs(\n defaultSurveyAssistantLocalizations,\n localizations,\n ),\n onMissing: (key, locale) =>\n console.log(\n `[SurveyAssistant] Missing localization for key \"${key}\" in language \"${locale}\".`,\n ),\n }),\n [language, localizations],\n );\n\n return (\n <SurveyAssistantLocalizationContext.Provider value={translate}>\n {children}\n </SurveyAssistantLocalizationContext.Provider>\n );\n};\n\nexport const useSurveyAssistantTranslation = (): LocalizationTranslate => {\n const translate = useContext(SurveyAssistantLocalizationContext);\n if (!translate) {\n throw new Error(\n \"useSurveyAssistantTranslation must be used within SurveyAssistantLocalizationProvider.\",\n );\n }\n return translate;\n};\n","\"use client\";\n\nimport { Collapsible, CollapsibleContent, CollapsibleTrigger } from \"./collapsible\";\nimport { cn } from \"../utils\";\nimport { useControllableState } from \"@radix-ui/react-use-controllable-state\";\nimport { BrainIcon, ChevronDownIcon, DotIcon, type LucideIcon } from \"lucide-react\";\nimport type { ComponentProps, ReactNode } from \"react\";\nimport {\n createContext,\n memo,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { Shimmer } from \"./shimmer\";\nimport { useSurveyAssistantTranslation } from \"../localization\";\n\ninterface ChainOfThoughtContextValue {\n isOpen: boolean;\n setIsOpen: (open: boolean) => void;\n isStreaming: boolean;\n duration: number | undefined;\n}\n\nconst ChainOfThoughtContext = createContext<ChainOfThoughtContextValue | null>(null);\n\nexport const useChainOfThought = () => {\n const context = useContext(ChainOfThoughtContext);\n if (!context) {\n throw new Error(\"ChainOfThought components must be used within ChainOfThought\");\n }\n return context;\n};\n\nexport type ChainOfThoughtProps = ComponentProps<typeof Collapsible> & {\n isStreaming?: boolean;\n defaultOpen?: boolean;\n defaultDuration?: number;\n duration?: number;\n autoClose?: boolean;\n};\n\nconst AUTO_CLOSE_DELAY = 1000;\nconst MS_IN_S = 1000;\n\nconst formatDuration = (durationSeconds: number) => {\n const hours = Math.floor(durationSeconds / 3600);\n const minutes = Math.floor((durationSeconds % 3600) / 60);\n const seconds = durationSeconds % 60;\n\n if (hours > 0) return `${hours}h ${minutes}m`;\n if (minutes > 0) return seconds > 0 ? `${minutes}m ${seconds}s` : `${minutes}m`;\n return `${seconds}s`;\n};\n\nexport const ChainOfThought = memo(\n ({\n className,\n isStreaming = false,\n open,\n defaultOpen,\n defaultDuration,\n onOpenChange,\n duration: durationProp,\n autoClose = true,\n children,\n ...props\n }: ChainOfThoughtProps) => {\n const resolvedDefaultOpen = defaultOpen ?? isStreaming;\n // Track if defaultOpen was explicitly set to false (to prevent auto-open)\n const isExplicitlyClosed = defaultOpen === false;\n\n const [isOpen, setIsOpen] = useControllableState<boolean>({\n defaultProp: resolvedDefaultOpen,\n onChange: onOpenChange,\n prop: open,\n });\n const [duration, setDuration] = useControllableState<number | undefined>({\n defaultProp: defaultDuration,\n prop: durationProp,\n });\n\n const hasEverStreamedRef = useRef(isStreaming);\n const [hasAutoClosed, setHasAutoClosed] = useState(false);\n const startTimeRef = useRef<number | null>(null);\n\n // Track when streaming starts and compute duration\n useEffect(() => {\n if (isStreaming) {\n hasEverStreamedRef.current = true;\n if (startTimeRef.current === null) {\n startTimeRef.current = Date.now();\n }\n } else if (startTimeRef.current !== null) {\n setDuration(Math.ceil((Date.now() - startTimeRef.current) / MS_IN_S));\n startTimeRef.current = null;\n }\n }, [isStreaming, setDuration]);\n\n // Auto-open when streaming starts (unless explicitly closed)\n useEffect(() => {\n if (isStreaming && !isOpen && !isExplicitlyClosed) {\n setIsOpen(true);\n }\n }, [isStreaming, isOpen, setIsOpen, isExplicitlyClosed]);\n\n // Auto-close when streaming ends (once only, and only if it ever streamed)\n useEffect(() => {\n if (autoClose && hasEverStreamedRef.current && !isStreaming && isOpen && !hasAutoClosed) {\n const timer = setTimeout(() => {\n setIsOpen(false);\n setHasAutoClosed(true);\n }, AUTO_CLOSE_DELAY);\n\n return () => clearTimeout(timer);\n }\n }, [autoClose, isStreaming, isOpen, setIsOpen, hasAutoClosed]);\n\n const handleOpenChange = useCallback(\n (newOpen: boolean) => {\n setIsOpen(newOpen);\n },\n [setIsOpen],\n );\n\n const contextValue = useMemo(\n () => ({ duration, isOpen, isStreaming, setIsOpen }),\n [duration, isOpen, isStreaming, setIsOpen],\n );\n\n return (\n <ChainOfThoughtContext.Provider value={contextValue}>\n <Collapsible\n className={cn(\"not-prose w-full\", className)}\n onOpenChange={handleOpenChange}\n open={isOpen}\n {...props}\n >\n {children}\n </Collapsible>\n </ChainOfThoughtContext.Provider>\n );\n },\n);\n\nexport type ChainOfThoughtHeaderProps = ComponentProps<typeof CollapsibleTrigger> & {\n getThinkingMessage?: (isStreaming: boolean, duration?: number) => ReactNode;\n};\n\nexport const ChainOfThoughtHeader = memo(\n ({ className, children, getThinkingMessage, ...props }: ChainOfThoughtHeaderProps) => {\n const { isOpen, isStreaming, duration } = useChainOfThought();\n const t = useSurveyAssistantTranslation();\n const defaultThinkingMessage = isStreaming ? (\n <Shimmer duration={1}>{t(\"activity.working\")}</Shimmer>\n ) : duration === undefined ? (\n <span>{t(\"activity.label\")}</span>\n ) : (\n <span>{t(\"activity.workedFor\", { duration: formatDuration(duration) })}</span>\n );\n\n return (\n <CollapsibleTrigger\n className={cn(\n \"flex w-full items-center gap-1.5 text-muted-foreground text-sm transition-colors hover:text-foreground\",\n className,\n )}\n {...props}\n >\n <BrainIcon className=\"size-3.5 shrink-0\" />\n <span className=\"flex-1 text-left\">\n {children ?? getThinkingMessage?.(isStreaming, duration) ?? defaultThinkingMessage}\n </span>\n <ChevronDownIcon\n className={cn(\n \"size-3.5 shrink-0 transition-transform\",\n isOpen ? \"rotate-180\" : \"rotate-0\",\n )}\n />\n </CollapsibleTrigger>\n );\n },\n);\n\nexport type ChainOfThoughtContentProps = ComponentProps<typeof CollapsibleContent>;\n\nexport const ChainOfThoughtContent = memo(({ className, ...props }: ChainOfThoughtContentProps) => (\n <CollapsibleContent\n className={cn(\n \"mt-2\",\n \"data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 outline-none data-[state=closed]:animate-out data-[state=open]:animate-in\",\n className,\n )}\n {...props}\n />\n));\n\nexport type ChainOfThoughtStepProps = ComponentProps<\"div\"> & {\n icon?: LucideIcon;\n label: ReactNode;\n description?: ReactNode;\n result?: ReactNode;\n status?: \"complete\" | \"active\" | \"pending\";\n isLast?: boolean;\n};\n\nconst stepStatusStyles = {\n complete: \"text-muted-foreground\",\n active: \"text-foreground\",\n pending: \"text-muted-foreground/50\",\n} as const;\n\nexport const ChainOfThoughtStep = memo(\n ({\n className,\n icon: Icon = DotIcon,\n label,\n description,\n result,\n status = \"complete\",\n isLast = false,\n children,\n ...props\n }: ChainOfThoughtStepProps) => (\n <div\n className={cn(\n \"fade-in-0 slide-in-from-top-2 relative animate-in text-xs\",\n isLast ? \"pb-0\" : \"pb-2.5\",\n stepStatusStyles[status],\n className,\n )}\n {...props}\n >\n <div className=\"flex gap-2\">\n <div className=\"relative z-10 mt-0.5 shrink-0 bg-background\">\n <Icon className=\"size-3.5\" />\n </div>\n <div className=\"min-w-0 flex-1\">\n <div className=\"wrap-break-word\">{label}</div>\n {description && <div className=\"mt-1.5 text-muted-foreground text-xs\">{description}</div>}\n </div>\n </div>\n {result && <div className=\"relative mt-1.5 ml-[22px]\">{result}</div>}\n {children && <div className=\"mt-1.5 ml-[22px] space-y-1.5\">{children}</div>}\n </div>\n ),\n);\n\nChainOfThought.displayName = \"ChainOfThought\";\nChainOfThoughtHeader.displayName = \"ChainOfThoughtHeader\";\nChainOfThoughtContent.displayName = \"ChainOfThoughtContent\";\nChainOfThoughtStep.displayName = \"ChainOfThoughtStep\";\n","import { cva, type VariantProps } from \"class-variance-authority\";\nimport { Slot } from \"radix-ui\";\nimport type { ComponentProps } from \"react\";\nimport { cn } from \"../utils\";\n\nconst buttonVariants = cva(\n \"inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n secondary: \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n ghost: \"hover:bg-muted hover:text-foreground\",\n },\n size: {\n default: \"h-9 px-4 py-2\",\n icon: \"size-9\",\n \"icon-sm\": \"size-8\",\n },\n },\n defaultVariants: { variant: \"default\", size: \"default\" },\n },\n);\n\nexport const Button = ({\n className,\n variant = \"default\",\n size = \"default\",\n asChild = false,\n ...props\n}: ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean;\n }) => {\n const Component = asChild ? Slot.Root : \"button\";\n return <Component className={cn(buttonVariants({ variant, size, className }))} {...props} />;\n};\n","\"use client\";\n\nimport { Button } from \"./button\";\nimport { cn } from \"../utils\";\nimport { ArrowDownIcon } from \"lucide-react\";\nimport type { ComponentProps, ReactNode } from \"react\";\nimport { useCallback } from \"react\";\nimport { StickToBottom, useStickToBottomContext } from \"use-stick-to-bottom\";\nimport { useSurveyAssistantTranslation } from \"../localization\";\n\nexport type ConversationProps = ComponentProps<typeof StickToBottom>;\n\nexport const Conversation = ({ className, ...props }: ConversationProps) => (\n <StickToBottom\n className={cn(\"relative min-h-0 flex-1 overflow-y-hidden\", className)}\n initial=\"smooth\"\n role=\"log\"\n resize=\"smooth\"\n {...props}\n />\n);\n\nexport type ConversationContentProps = ComponentProps<typeof StickToBottom.Content>;\n\nexport const ConversationContent = ({ className, ...props }: ConversationContentProps) => (\n <StickToBottom.Content className={cn(\"flex flex-col gap-8 p-4\", className)} {...props} />\n);\n\nexport type ConversationEmptyStateProps = ComponentProps<\"div\"> & {\n title?: string;\n description?: string;\n icon?: ReactNode;\n};\n\nexport const ConversationEmptyState = ({\n className,\n title,\n description,\n icon,\n children,\n ...props\n}: ConversationEmptyStateProps) => {\n const t = useSurveyAssistantTranslation();\n const resolvedTitle = title ?? t(\"conversation.noMessages\");\n const resolvedDescription = description ?? t(\"conversation.startConversation\");\n\n return (\n <div\n className={cn(\n \"flex size-full flex-col items-center justify-center gap-3 p-8 text-center\",\n className,\n )}\n {...props}\n >\n {children ?? (\n <>\n {icon && <div className=\"text-muted-foreground\">{icon}</div>}\n <div className=\"space-y-1\">\n <h3 className=\"font-medium text-sm\">{resolvedTitle}</h3>\n {resolvedDescription && (\n <p className=\"text-muted-foreground text-sm\">{resolvedDescription}</p>\n )}\n </div>\n </>\n )}\n </div>\n );\n};\n\nexport type ConversationScrollButtonProps = ComponentProps<typeof Button>;\n\nexport const ConversationScrollButton = ({\n className,\n ...props\n}: ConversationScrollButtonProps) => {\n const { isAtBottom, scrollToBottom } = useStickToBottomContext();\n const t = useSurveyAssistantTranslation();\n\n const handleScrollToBottom = useCallback(() => {\n scrollToBottom();\n }, [scrollToBottom]);\n\n return (\n !isAtBottom && (\n <Button\n className={cn(\n \"absolute left-1/2 z-10 size-8 -translate-x-1/2 rounded-full border border-background/60 bg-foreground text-background shadow-lg ring-1 ring-border/50 hover:bg-foreground/85 hover:text-background\",\n className,\n )}\n aria-label={t(\"conversation.scrollToLatest\")}\n onClick={handleScrollToBottom}\n size=\"icon-sm\"\n type=\"button\"\n variant=\"secondary\"\n {...props}\n >\n <ArrowDownIcon className=\"size-4\" />\n </Button>\n )\n );\n};\n","\"use client\";\n\nimport { cn } from \"../utils\";\nimport type { UIMessage } from \"ai\";\nimport type { HTMLAttributes } from \"react\";\n\nexport type MessageProps = HTMLAttributes<HTMLDivElement> & {\n from: UIMessage[\"role\"];\n};\n\nexport const Message = ({ className, from, ...props }: MessageProps) => (\n <div\n className={cn(\n \"group flex w-full max-w-[95%] flex-col gap-2\",\n from === \"user\" ? \"ml-auto items-end\" : \"items-start\",\n className,\n )}\n data-role={from}\n {...props}\n />\n);\n\nexport type MessageContentProps = HTMLAttributes<HTMLDivElement>;\n\nexport const MessageContent = ({ children, className, ...props }: MessageContentProps) => (\n <div\n className={cn(\n \"w-fit min-w-0 max-w-full break-words text-sm\",\n \"group-data-[role=user]:whitespace-pre-wrap group-data-[role=user]:rounded-xl group-data-[role=user]:border group-data-[role=user]:border-blue-200/70 group-data-[role=user]:bg-blue-50/80 group-data-[role=user]:px-3 group-data-[role=user]:py-2 group-data-[role=user]:text-foreground group-data-[role=user]:shadow-xs dark:group-data-[role=user]:border-blue-800/60 dark:group-data-[role=user]:bg-blue-950/50\",\n \"group-data-[role=assistant]:text-foreground\",\n className,\n )}\n {...props}\n >\n {children}\n </div>\n);\n\nexport type MessageResponseProps = HTMLAttributes<HTMLDivElement>;\n\nexport const MessageResponse = ({ className, ...props }: MessageResponseProps) => (\n <div className={cn(\"leading-6\", className)} {...props} />\n);\n","\"use client\";\n\nimport { Tooltip as TooltipPrimitive } from \"radix-ui\";\nimport type { ComponentProps } from \"react\";\nimport { cn } from \"../utils\";\n\nexport const TooltipProvider = TooltipPrimitive.Provider;\nexport const Tooltip = TooltipPrimitive.Root;\nexport const TooltipTrigger = TooltipPrimitive.Trigger;\n\nexport const TooltipContent = ({\n className,\n sideOffset = 6,\n ...props\n}: ComponentProps<typeof TooltipPrimitive.Content>) => (\n <TooltipPrimitive.Portal>\n <div className=\"case-survey-assistant case-survey-assistant-portal\">\n <TooltipPrimitive.Content\n className={cn(\n \"z-50 max-w-64 rounded-md bg-foreground px-3 py-1.5 text-center text-background text-xs shadow-md data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0\",\n className,\n )}\n sideOffset={sideOffset}\n {...props}\n />\n </div>\n </TooltipPrimitive.Portal>\n);\n","\"use client\";\n\nimport { cn } from \"../utils\";\nimport {\n isSurveyAssistantAttachmentMediaType,\n SURVEY_ASSISTANT_ATTACHMENT_MEDIA_TYPES,\n} from \"../../protocol/attachments\";\nimport type { ChatStatus, FileUIPart } from \"ai\";\nimport { ArrowUpIcon, FileIcon, PaperclipIcon, SquareIcon, XIcon } from \"lucide-react\";\nimport {\n createContext,\n useCallback,\n useContext,\n useMemo,\n useRef,\n useState,\n type ClipboardEvent,\n type ComponentProps,\n type DragEvent,\n type FormEvent,\n type HTMLAttributes,\n} from \"react\";\nimport { useSurveyAssistantTranslation } from \"../localization\";\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"./tooltip\";\n\nconst SUPPORTED_FILE_ACCEPT = [\n \".pdf\",\n \".png\",\n \".jpg\",\n \".jpeg\",\n ...SURVEY_ASSISTANT_ATTACHMENT_MEDIA_TYPES,\n].join(\",\");\n\nexport type UnsupportedAttachmentKind = \"word\" | \"other\";\n\nconst WORD_DOCUMENT_MEDIA_TYPES = new Set([\n \"application/msword\",\n \"application/vnd.ms-word\",\n \"application/vnd.ms-word.document.macroenabled.12\",\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.template\",\n]);\n\nexport const getUnsupportedAttachmentKind = ({\n name,\n type,\n}: Pick<File, \"name\" | \"type\">): UnsupportedAttachmentKind | null => {\n if (isSurveyAssistantAttachmentMediaType(type)) return null;\n if (\n WORD_DOCUMENT_MEDIA_TYPES.has(type.toLowerCase()) ||\n /\\.(?:doc|docm|docx|dot|dotm|dotx)$/i.test(name)\n ) {\n return \"word\";\n }\n return \"other\";\n};\n\nconst formatFileSize = (size: number) => {\n if (size < 1024 * 1024) {\n return `${Math.max(1, Math.round(size / 1024))} KB`;\n }\n\n return `${(size / (1024 * 1024)).toFixed(size < 10 * 1024 * 1024 ? 1 : 0)} MB`;\n};\n\nconst fileToUIPart = async (file: File): Promise<FileUIPart> => {\n const mediaType = file.type || \"application/octet-stream\";\n const bytes = new Uint8Array(await file.arrayBuffer());\n const chunkSize = 0x8000;\n let binary = \"\";\n\n for (let offset = 0; offset < bytes.length; offset += chunkSize) {\n binary += String.fromCharCode(...bytes.subarray(offset, offset + chunkSize));\n }\n\n return {\n type: \"file\",\n mediaType,\n filename: file.name,\n url: `data:${mediaType};base64,${btoa(binary)}`,\n };\n};\n\nexport interface PromptInputMessage {\n text: string;\n files: FileUIPart[];\n}\n\ntype PromptInputContextValue = {\n value: string;\n setValue: (value: string) => void;\n files: File[];\n addFiles: (files: FileList | null) => void;\n removeFile: (index: number) => void;\n unsupportedFiles: Array<{ kind: UnsupportedAttachmentKind; name: string }>;\n};\n\nconst PromptInputContext = createContext<PromptInputContextValue | null>(null);\n\nconst usePromptInput = () => {\n const context = useContext(PromptInputContext);\n if (!context) {\n throw new Error(\"PromptInput components must be used within PromptInput.\");\n }\n return context;\n};\n\nexport type PromptInputProps = Omit<ComponentProps<\"form\">, \"onSubmit\"> & {\n attachmentsDisabled?: boolean;\n onValueChange?: (value: string) => void;\n onSubmit: (\n message: PromptInputMessage,\n event: FormEvent<HTMLFormElement>,\n ) => boolean | void | Promise<boolean | void>;\n value?: string;\n};\n\nexport const PromptInput = ({\n attachmentsDisabled = false,\n children,\n className,\n onDragEnter,\n onDragLeave,\n onDragOver,\n onDrop,\n onPaste,\n onSubmit,\n onValueChange,\n value: controlledValue,\n ...props\n}: PromptInputProps) => {\n const [uncontrolledValue, setUncontrolledValue] = useState(\"\");\n const [files, setFiles] = useState<File[]>([]);\n const [isDraggingFiles, setIsDraggingFiles] = useState(false);\n const [unsupportedFiles, setUnsupportedFiles] = useState<\n Array<{ kind: UnsupportedAttachmentKind; name: string }>\n >([]);\n const fileDragDepthRef = useRef(0);\n const t = useSurveyAssistantTranslation();\n const value = controlledValue ?? uncontrolledValue;\n const setValue = useCallback(\n (nextValue: string) => {\n if (controlledValue === undefined) setUncontrolledValue(nextValue);\n onValueChange?.(nextValue);\n },\n [controlledValue, onValueChange],\n );\n\n const addFiles = useCallback((fileList: FileList | null) => {\n const nextFiles = Array.from(fileList ?? []);\n const supportedFiles = nextFiles.filter((file) => getUnsupportedAttachmentKind(file) === null);\n const rejectedFiles = nextFiles.flatMap((file) => {\n const kind = getUnsupportedAttachmentKind(file);\n return kind ? [{ kind, name: file.name }] : [];\n });\n\n setFiles((currentFiles) => [...currentFiles, ...supportedFiles]);\n setUnsupportedFiles(rejectedFiles);\n }, []);\n\n const removeFile = useCallback((index: number) => {\n setFiles((currentFiles) => currentFiles.filter((_, fileIndex) => fileIndex !== index));\n }, []);\n\n const contextValue = useMemo(\n () => ({\n value,\n setValue,\n files,\n addFiles,\n removeFile,\n unsupportedFiles,\n }),\n [addFiles, files, removeFile, unsupportedFiles, value],\n );\n\n const handleSubmit = useCallback(\n async (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n const text = value.trim();\n if (!text && files.length === 0) {\n return;\n }\n\n const fileUIParts = await Promise.all(files.map(fileToUIPart));\n const accepted = await onSubmit({ text, files: fileUIParts }, event);\n if (accepted === false) return;\n setValue(\"\");\n setFiles([]);\n setUnsupportedFiles([]);\n },\n [files, onSubmit, value],\n );\n\n const isFileDrag = (event: DragEvent<HTMLFormElement>) =>\n event.dataTransfer.types.includes(\"Files\");\n\n const handleDragEnter = (event: DragEvent<HTMLFormElement>) => {\n onDragEnter?.(event);\n if (event.defaultPrevented || !isFileDrag(event)) return;\n\n event.preventDefault();\n fileDragDepthRef.current += 1;\n if (!attachmentsDisabled) setIsDraggingFiles(true);\n };\n\n const handleDragLeave = (event: DragEvent<HTMLFormElement>) => {\n onDragLeave?.(event);\n if (!isFileDrag(event)) return;\n\n fileDragDepthRef.current = Math.max(0, fileDragDepthRef.current - 1);\n if (fileDragDepthRef.current === 0) setIsDraggingFiles(false);\n };\n\n const handleDragOver = (event: DragEvent<HTMLFormElement>) => {\n onDragOver?.(event);\n if (event.defaultPrevented || !isFileDrag(event)) return;\n\n event.preventDefault();\n event.dataTransfer.dropEffect = attachmentsDisabled ? \"none\" : \"copy\";\n };\n\n const handleDrop = (event: DragEvent<HTMLFormElement>) => {\n onDrop?.(event);\n if (!isFileDrag(event)) return;\n\n fileDragDepthRef.current = 0;\n setIsDraggingFiles(false);\n if (event.defaultPrevented) return;\n\n event.preventDefault();\n if (!attachmentsDisabled) addFiles(event.dataTransfer.files);\n };\n\n const handlePaste = (event: ClipboardEvent<HTMLFormElement>) => {\n onPaste?.(event);\n if (event.defaultPrevented || attachmentsDisabled || event.clipboardData.files.length === 0) {\n return;\n }\n\n event.preventDefault();\n addFiles(event.clipboardData.files);\n };\n\n return (\n <PromptInputContext.Provider value={contextValue}>\n <form\n className={cn(\"relative rounded-xl border border-input bg-background\", className)}\n onDragEnter={handleDragEnter}\n onDragLeave={handleDragLeave}\n onDragOver={handleDragOver}\n onDrop={handleDrop}\n onPaste={handlePaste}\n onSubmit={handleSubmit}\n {...props}\n >\n {children}\n {isDraggingFiles && (\n <div className=\"pointer-events-none absolute inset-0 z-10 flex items-center justify-center rounded-[inherit] border-2 border-primary bg-background/90 px-4 text-center font-medium text-sm text-foreground\">\n {t(\"input.dropFiles\")}\n </div>\n )}\n </form>\n </PromptInputContext.Provider>\n );\n};\n\nexport type PromptInputBodyProps = HTMLAttributes<HTMLDivElement>;\n\nexport const PromptInputBody = ({ children, className, ...props }: PromptInputBodyProps) => {\n const { files, removeFile, unsupportedFiles } = usePromptInput();\n const t = useSurveyAssistantTranslation();\n const unsupportedWordFileNames = unsupportedFiles\n .filter((file) => file.kind === \"word\")\n .map((file) => file.name);\n const unsupportedOtherFileNames = unsupportedFiles\n .filter((file) => file.kind === \"other\")\n .map((file) => file.name);\n\n return (\n <div className={cn(\"contents\", className)} {...props}>\n {children}\n {(files.length > 0 || unsupportedFiles.length > 0) && (\n <div className=\"flex flex-wrap gap-2 px-3 pb-2\">\n {files.map((file, index) => (\n <div\n className=\"inline-flex max-w-full items-center gap-2 rounded-md border border-border bg-muted px-2 py-1 text-xs\"\n key={`${file.name}-${file.lastModified}-${index}`}\n >\n <FileIcon className=\"size-3.5 shrink-0 text-muted-foreground\" />\n <span className=\"min-w-0 truncate\">{file.name}</span>\n <span className=\"shrink-0 text-muted-foreground\">{formatFileSize(file.size)}</span>\n <button\n className=\"shrink-0 rounded-sm text-muted-foreground hover:text-foreground\"\n onClick={() => removeFile(index)}\n type=\"button\"\n >\n <XIcon className=\"size-3.5\" />\n <span className=\"sr-only\">{t(\"input.removeFile\", { filename: file.name })}</span>\n </button>\n </div>\n ))}\n {unsupportedWordFileNames.length > 0 && (\n <div className=\"text-destructive text-xs\">\n {t(\"input.wordFilesUnsupported\", {\n filenames: unsupportedWordFileNames.join(\", \"),\n })}\n </div>\n )}\n {unsupportedOtherFileNames.length > 0 && (\n <div className=\"text-destructive text-xs\">\n {t(\"input.unsupportedFiles\", {\n filenames: unsupportedOtherFileNames.join(\", \"),\n })}\n </div>\n )}\n </div>\n )}\n </div>\n );\n};\n\nexport type PromptInputTextareaProps = ComponentProps<\"textarea\">;\n\nexport const PromptInputTextarea = ({\n className,\n onChange,\n onKeyDown,\n ...props\n}: PromptInputTextareaProps) => {\n const { value, setValue } = usePromptInput();\n\n return (\n <textarea\n className={cn(\n \"max-h-40 min-h-20 w-full resize-none bg-transparent px-3 py-2 text-sm outline-none placeholder:text-muted-foreground\",\n className,\n )}\n onChange={(event) => {\n setValue(event.target.value);\n onChange?.(event);\n }}\n onKeyDown={(event) => {\n onKeyDown?.(event);\n if (event.defaultPrevented || event.shiftKey || event.key !== \"Enter\") {\n return;\n }\n event.preventDefault();\n event.currentTarget.form?.requestSubmit();\n }}\n value={value}\n {...props}\n />\n );\n};\n\nexport type PromptInputFooterProps = HTMLAttributes<HTMLDivElement>;\n\nexport const PromptInputFooter = ({ className, ...props }: PromptInputFooterProps) => (\n <div\n className={cn(\"flex items-center gap-2 border-t border-border px-2 py-2\", className)}\n {...props}\n />\n);\n\nexport type PromptInputAttachmentButtonProps = Omit<ComponentProps<\"input\">, \"type\">;\n\nexport const PromptInputAttachmentButton = ({\n accept = SUPPORTED_FILE_ACCEPT,\n className,\n disabled,\n onChange,\n ...props\n}: PromptInputAttachmentButtonProps) => {\n const { addFiles } = usePromptInput();\n const t = useSurveyAssistantTranslation();\n\n return (\n <TooltipProvider delayDuration={300}>\n <Tooltip>\n <TooltipTrigger asChild>\n <label\n className={cn(\n \"inline-flex size-8 cursor-pointer items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\",\n disabled && \"pointer-events-none cursor-default opacity-50\",\n className,\n )}\n >\n <PaperclipIcon className=\"size-4\" />\n <span className=\"sr-only\">{t(\"input.attachFiles\")}</span>\n <input\n accept={accept}\n className=\"sr-only\"\n disabled={disabled}\n multiple\n onChange={(event) => {\n addFiles(event.currentTarget.files);\n onChange?.(event);\n event.currentTarget.value = \"\";\n }}\n type=\"file\"\n {...props}\n />\n </label>\n </TooltipTrigger>\n <TooltipContent align=\"start\" side=\"top\">\n {t(\"input.supportedFiles\")}\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n );\n};\n\nexport type PromptInputSubmitProps = ComponentProps<\"button\"> & {\n status?: ChatStatus;\n onStop?: () => void;\n};\n\nexport const PromptInputSubmit = ({\n className,\n status,\n onStop,\n onClick,\n ...props\n}: PromptInputSubmitProps) => {\n const isGenerating = status === \"submitted\" || status === \"streaming\";\n const t = useSurveyAssistantTranslation();\n\n return (\n <button\n className={cn(\n \"inline-flex size-8 items-center justify-center rounded-full bg-foreground text-background transition-opacity hover:opacity-90 disabled:pointer-events-none disabled:opacity-50\",\n className,\n )}\n onClick={(event) => {\n if (isGenerating && onStop) {\n event.preventDefault();\n onStop();\n return;\n }\n onClick?.(event);\n }}\n type=\"submit\"\n {...props}\n >\n {isGenerating ? <SquareIcon className=\"size-3.5\" /> : <ArrowUpIcon className=\"size-4\" />}\n <span className=\"sr-only\">{isGenerating ? t(\"input.stop\") : t(\"input.send\")}</span>\n </button>\n );\n};\n","\"use client\";\n\nimport * as React from \"react\";\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon } from \"lucide-react\";\nimport { Select as SelectPrimitive } from \"radix-ui\";\n\nimport { cn } from \"../utils\";\n\nfunction Select({ ...props }: React.ComponentProps<typeof SelectPrimitive.Root>) {\n return <SelectPrimitive.Root data-slot=\"select\" {...props} />;\n}\n\nfunction SelectGroup({ ...props }: React.ComponentProps<typeof SelectPrimitive.Group>) {\n return <SelectPrimitive.Group data-slot=\"select-group\" {...props} />;\n}\n\nfunction SelectValue({ ...props }: React.ComponentProps<typeof SelectPrimitive.Value>) {\n return <SelectPrimitive.Value data-slot=\"select-value\" {...props} />;\n}\n\nfunction SelectTrigger({\n className,\n size = \"default\",\n children,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {\n size?: \"sm\" | \"default\";\n}) {\n return (\n <SelectPrimitive.Trigger\n data-slot=\"select-trigger\"\n data-size={size}\n className={cn(\n \"flex w-fit items-center justify-between gap-2 rounded-md border border-input bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[placeholder]:text-muted-foreground data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground\",\n className,\n )}\n {...props}\n >\n {children}\n <SelectPrimitive.Icon asChild>\n <ChevronDownIcon className=\"size-4 opacity-50\" />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n );\n}\n\nfunction SelectContent({\n className,\n children,\n position = \"item-aligned\",\n align = \"center\",\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Content>) {\n return (\n <SelectPrimitive.Portal>\n <div className=\"case-survey-assistant case-survey-assistant-portal\">\n <SelectPrimitive.Content\n data-slot=\"select-content\"\n className={cn(\n \"relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border bg-popover text-popover-foreground shadow-md data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95\",\n position === \"popper\" &&\n \"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\",\n className,\n )}\n position={position}\n align={align}\n {...props}\n >\n <SelectScrollUpButton />\n <SelectPrimitive.Viewport\n className={cn(\n \"p-1\",\n position === \"popper\" &&\n \"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1\",\n )}\n >\n {children}\n </SelectPrimitive.Viewport>\n <SelectScrollDownButton />\n </SelectPrimitive.Content>\n </div>\n </SelectPrimitive.Portal>\n );\n}\n\nfunction SelectLabel({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.Label>) {\n return (\n <SelectPrimitive.Label\n data-slot=\"select-label\"\n className={cn(\"px-2 py-1.5 text-xs text-muted-foreground\", className)}\n {...props}\n />\n );\n}\n\nfunction SelectItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Item>) {\n return (\n <SelectPrimitive.Item\n data-slot=\"select-item\"\n className={cn(\n \"relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2\",\n className,\n )}\n {...props}\n >\n <span\n data-slot=\"select-item-indicator\"\n className=\"absolute right-2 flex size-3.5 items-center justify-center\"\n >\n <SelectPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </SelectPrimitive.ItemIndicator>\n </span>\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n );\n}\n\nfunction SelectSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Separator>) {\n return (\n <SelectPrimitive.Separator\n data-slot=\"select-separator\"\n className={cn(\"pointer-events-none -mx-1 my-1 h-px bg-border\", className)}\n {...props}\n />\n );\n}\n\nfunction SelectScrollUpButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {\n return (\n <SelectPrimitive.ScrollUpButton\n data-slot=\"select-scroll-up-button\"\n className={cn(\"flex cursor-default items-center justify-center py-1\", className)}\n {...props}\n >\n <ChevronUpIcon className=\"size-4\" />\n </SelectPrimitive.ScrollUpButton>\n );\n}\n\nfunction SelectScrollDownButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {\n return (\n <SelectPrimitive.ScrollDownButton\n data-slot=\"select-scroll-down-button\"\n className={cn(\"flex cursor-default items-center justify-center py-1\", className)}\n {...props}\n >\n <ChevronDownIcon className=\"size-4\" />\n </SelectPrimitive.ScrollDownButton>\n );\n}\n\nexport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectScrollDownButton,\n SelectScrollUpButton,\n SelectSeparator,\n SelectTrigger,\n SelectValue,\n};\n","\"use client\";\n\nimport type { SurveyAssistantModelOption } from \"../protocol\";\nimport type { ChatStatus } from \"ai\";\nimport { BotIcon } from \"lucide-react\";\nimport type { ComponentProps, Ref } from \"react\";\nimport {\n PromptInput,\n PromptInputAttachmentButton,\n PromptInputBody,\n PromptInputFooter,\n PromptInputSubmit,\n PromptInputTextarea,\n type PromptInputMessage,\n type PromptInputProps,\n} from \"./internal/prompt-input\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"./internal/select\";\nimport { useSurveyAssistantTranslation } from \"./localization\";\nimport { cn } from \"./utils\";\n\ninterface SurveyAssistantModelSelectProps {\n disabled?: boolean;\n modelId?: string;\n models: SurveyAssistantModelOption[];\n onModelChange(modelId: string): void;\n}\n\nconst SurveyAssistantModelSelect = ({\n disabled = false,\n modelId,\n models,\n onModelChange,\n}: SurveyAssistantModelSelectProps) => {\n const t = useSurveyAssistantTranslation();\n const selectedModelLabel =\n models.find((model) => model.id === modelId)?.label ?? modelId ?? t(\"input.defaultModel\");\n\n if (models.length > 1) {\n return (\n <Select disabled={disabled} onValueChange={onModelChange} value={modelId ?? \"\"}>\n <SelectTrigger\n aria-label={t(\"input.model\")}\n className=\"h-8 min-w-0 max-w-48 gap-1.5 border-0 bg-transparent px-2 text-xs shadow-none hover:bg-muted hover:text-foreground focus-visible:ring-1\"\n size=\"sm\"\n title={modelId}\n >\n <BotIcon className=\"size-3.5\" />\n <SelectValue />\n </SelectTrigger>\n <SelectContent\n align=\"end\"\n className=\"min-w-52 rounded-lg border-border p-0 shadow-lg\"\n position=\"popper\"\n >\n {models.map((model) => (\n <SelectItem\n className=\"min-h-9 rounded-md px-2 py-2 text-xs focus:bg-muted\"\n key={model.id}\n title={model.id}\n value={model.id}\n >\n {model.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n );\n }\n\n return (\n <div\n className=\"flex h-8 min-w-0 max-w-48 items-center gap-1.5 px-2 text-muted-foreground text-xs\"\n title={modelId}\n >\n <BotIcon className=\"size-3.5 shrink-0\" />\n <span className=\"truncate\">{selectedModelLabel}</span>\n </div>\n );\n};\n\nexport interface SurveyAssistantPromptInputProps {\n attachmentsDisabled?: boolean;\n attachmentButtonClassName?: string;\n className?: string;\n disabled?: boolean;\n footerClassName?: string;\n formProps?: Omit<\n PromptInputProps,\n \"attachmentsDisabled\" | \"children\" | \"className\" | \"onSubmit\" | \"onValueChange\" | \"value\"\n >;\n modelDisabled?: boolean;\n modelId?: string;\n models: SurveyAssistantModelOption[];\n onModelChange(modelId: string): void;\n onStop?(): void;\n onSubmit: PromptInputProps[\"onSubmit\"];\n onValueChange?(value: string): void;\n placeholder?: string;\n status?: ChatStatus;\n textareaClassName?: string;\n textareaProps?: Omit<\n ComponentProps<\"textarea\">,\n \"className\" | \"disabled\" | \"placeholder\" | \"ref\"\n >;\n textareaRef?: Ref<HTMLTextAreaElement>;\n value?: string;\n}\n\nexport const SurveyAssistantPromptInput = ({\n attachmentsDisabled = false,\n attachmentButtonClassName,\n className,\n disabled = false,\n footerClassName,\n formProps,\n modelDisabled = false,\n modelId,\n models,\n onModelChange,\n onStop,\n onSubmit,\n onValueChange,\n placeholder,\n status,\n textareaClassName,\n textareaProps,\n textareaRef,\n value,\n}: SurveyAssistantPromptInputProps) => {\n const t = useSurveyAssistantTranslation();\n const canStop = Boolean(onStop) && (status === \"submitted\" || status === \"streaming\");\n\n return (\n <PromptInput\n {...formProps}\n attachmentsDisabled={attachmentsDisabled || disabled}\n className={cn(\"rounded-xl border-border bg-background shadow-sm\", className)}\n onSubmit={onSubmit}\n onValueChange={onValueChange}\n value={value}\n >\n <PromptInputBody>\n <PromptInputTextarea\n {...textareaProps}\n className={cn(\n \"min-h-20 px-3 py-2 disabled:cursor-not-allowed disabled:text-muted-foreground\",\n textareaClassName,\n )}\n disabled={disabled}\n placeholder={placeholder ?? t(\"input.placeholder\")}\n ref={textareaRef}\n />\n </PromptInputBody>\n <PromptInputFooter\n className={cn(\"justify-between border-0 px-1.5 pt-0 pb-1.5\", footerClassName)}\n >\n <PromptInputAttachmentButton\n className={attachmentButtonClassName}\n disabled={attachmentsDisabled || disabled}\n />\n <div className=\"flex min-w-0 items-center justify-end gap-1\">\n <SurveyAssistantModelSelect\n disabled={disabled || modelDisabled}\n modelId={modelId}\n models={models}\n onModelChange={onModelChange}\n />\n <PromptInputSubmit disabled={disabled && !canStop} onStop={onStop} status={status} />\n </div>\n </PromptInputFooter>\n </PromptInput>\n );\n};\n\nexport type { PromptInputMessage as SurveyAssistantPromptInputMessage };\n","const formatOmittedLength = (length: number) => length.toLocaleString(\"en-US\");\n\nexport const stringifyToolTechnicalDetails = (value: unknown): string =>\n JSON.stringify(\n value,\n function redactEmbeddedBinary(this: unknown, key, currentValue) {\n const parent =\n this && typeof this === \"object\" ? (this as Record<string, unknown>) : undefined;\n if (\n key === \"data\" &&\n typeof currentValue === \"string\" &&\n parent?.type === \"embedded\" &&\n parent.encoding === \"base64\"\n ) {\n return `[embedded base64 omitted: ${formatOmittedLength(currentValue.length)} characters]`;\n }\n\n if (\n typeof currentValue === \"string\" &&\n currentValue.length > 512 &&\n /^data:[^;,]+;base64,/.test(currentValue)\n ) {\n return `[base64 data URL omitted: ${formatOmittedLength(currentValue.length)} characters]`;\n }\n\n return currentValue;\n },\n 2,\n );\n","\"use client\";\n\n/* eslint-disable react-hooks/refs */\n\nimport { Button } from \"./button\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"./select\";\nimport { cn } from \"../utils\";\nimport { CheckIcon, CopyIcon } from \"lucide-react\";\nimport type { ComponentProps, CSSProperties, HTMLAttributes } from \"react\";\nimport {\n createContext,\n memo,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type { BundledLanguage, BundledTheme, HighlighterGeneric, ThemedToken } from \"shiki\";\n\n// Shiki uses bitflags for font styles: 1=italic, 2=bold, 4=underline\n// oxlint-disable-next-line eslint(no-bitwise)\nconst isItalic = (fontStyle: number | undefined) => fontStyle && fontStyle & 1;\n// oxlint-disable-next-line eslint(no-bitwise)\nconst isBold = (fontStyle: number | undefined) => fontStyle && fontStyle & 2;\nconst isUnderline = (fontStyle: number | undefined) =>\n // oxlint-disable-next-line eslint(no-bitwise)\n fontStyle && fontStyle & 4;\n\n// Transform tokens to include pre-computed keys to avoid noArrayIndexKey lint\ninterface KeyedToken {\n token: ThemedToken;\n key: string;\n}\ninterface KeyedLine {\n tokens: KeyedToken[];\n key: string;\n}\n\nconst addKeysToTokens = (lines: ThemedToken[][]): KeyedLine[] =>\n lines.map((line, lineIdx) => ({\n key: `line-${lineIdx}`,\n tokens: line.map((token, tokenIdx) => ({\n key: `line-${lineIdx}-${tokenIdx}`,\n token,\n })),\n }));\n\n// Token rendering component\nconst TokenSpan = ({ token }: { token: ThemedToken }) => (\n <span\n className=\"dark:!bg-[var(--shiki-dark-bg)] dark:!text-[var(--shiki-dark)]\"\n style={\n {\n backgroundColor: token.bgColor,\n color: token.color,\n fontStyle: isItalic(token.fontStyle) ? \"italic\" : undefined,\n fontWeight: isBold(token.fontStyle) ? \"bold\" : undefined,\n textDecoration: isUnderline(token.fontStyle) ? \"underline\" : undefined,\n ...token.htmlStyle,\n } as CSSProperties\n }\n >\n {token.content}\n </span>\n);\n\n// Line number styles using CSS counters\nconst LINE_NUMBER_CLASSES = cn(\n \"block\",\n \"before:content-[counter(line)]\",\n \"before:inline-block\",\n \"before:[counter-increment:line]\",\n \"before:w-8\",\n \"before:mr-4\",\n \"before:text-right\",\n \"before:text-muted-foreground/50\",\n \"before:font-mono\",\n \"before:select-none\",\n);\n\n// Line rendering component\nconst LineSpan = ({\n keyedLine,\n showLineNumbers,\n}: {\n keyedLine: KeyedLine;\n showLineNumbers: boolean;\n}) => (\n <span className={showLineNumbers ? LINE_NUMBER_CLASSES : \"block\"}>\n {keyedLine.tokens.length === 0\n ? \"\\n\"\n : keyedLine.tokens.map(({ token, key }) => <TokenSpan key={key} token={token} />)}\n </span>\n);\n\n// Types\ntype CodeBlockProps = HTMLAttributes<HTMLDivElement> & {\n code: string;\n language: BundledLanguage;\n showLineNumbers?: boolean;\n};\n\ninterface TokenizedCode {\n tokens: ThemedToken[][];\n fg: string;\n bg: string;\n}\n\ninterface CodeBlockContextType {\n code: string;\n}\n\n// Context\nconst CodeBlockContext = createContext<CodeBlockContextType>({\n code: \"\",\n});\n\n// Highlighter cache (singleton per language)\nconst highlighterCache = new Map<\n string,\n Promise<HighlighterGeneric<BundledLanguage, BundledTheme>>\n>();\n\n// Token cache\nconst tokensCache = new Map<string, TokenizedCode>();\n\n// Subscribers for async token updates\nconst subscribers = new Map<string, Set<(result: TokenizedCode) => void>>();\n\nconst getTokensCacheKey = (code: string, language: BundledLanguage) => {\n const start = code.slice(0, 100);\n const end = code.length > 100 ? code.slice(-100) : \"\";\n return `${language}:${code.length}:${start}:${end}`;\n};\n\nconst getHighlighter = (\n language: BundledLanguage,\n): Promise<HighlighterGeneric<BundledLanguage, BundledTheme>> => {\n const cached = highlighterCache.get(language);\n if (cached) {\n return cached;\n }\n\n const highlighterPromise = import(\"shiki\").then(({ createHighlighter }) =>\n createHighlighter({\n langs: [language],\n themes: [\"github-light\", \"github-dark\"],\n }),\n );\n\n highlighterCache.set(language, highlighterPromise);\n return highlighterPromise;\n};\n\n// Create raw tokens for immediate display while highlighting loads\nconst createRawTokens = (code: string): TokenizedCode => ({\n bg: \"transparent\",\n fg: \"inherit\",\n tokens: code.split(\"\\n\").map((line) =>\n line === \"\"\n ? []\n : [\n {\n color: \"inherit\",\n content: line,\n } as ThemedToken,\n ],\n ),\n});\n\n// Synchronous highlight with callback for async results\nexport const highlightCode = (\n code: string,\n language: BundledLanguage,\n // oxlint-disable-next-line eslint-plugin-promise(prefer-await-to-callbacks)\n callback?: (result: TokenizedCode) => void,\n): TokenizedCode | null => {\n const tokensCacheKey = getTokensCacheKey(code, language);\n\n // Return cached result if available\n const cached = tokensCache.get(tokensCacheKey);\n if (cached) {\n return cached;\n }\n\n // Subscribe callback if provided\n if (callback) {\n if (!subscribers.has(tokensCacheKey)) {\n subscribers.set(tokensCacheKey, new Set());\n }\n subscribers.get(tokensCacheKey)?.add(callback);\n }\n\n // Start highlighting in background - fire-and-forget async pattern\n getHighlighter(language)\n // oxlint-disable-next-line eslint-plugin-promise(prefer-await-to-then)\n .then((highlighter) => {\n const availableLangs = highlighter.getLoadedLanguages();\n const langToUse = availableLangs.includes(language) ? language : \"text\";\n\n const result = highlighter.codeToTokens(code, {\n lang: langToUse,\n themes: {\n dark: \"github-dark\",\n light: \"github-light\",\n },\n });\n\n const tokenized: TokenizedCode = {\n bg: result.bg ?? \"transparent\",\n fg: result.fg ?? \"inherit\",\n tokens: result.tokens,\n };\n\n // Cache the result\n tokensCache.set(tokensCacheKey, tokenized);\n\n // Notify all subscribers\n const subs = subscribers.get(tokensCacheKey);\n if (subs) {\n for (const sub of subs) {\n sub(tokenized);\n }\n subscribers.delete(tokensCacheKey);\n }\n })\n // oxlint-disable-next-line eslint-plugin-promise(prefer-await-to-then), eslint-plugin-promise(prefer-await-to-callbacks)\n .catch((error) => {\n console.error(\"Failed to highlight code:\", error);\n subscribers.delete(tokensCacheKey);\n });\n\n return null;\n};\n\nconst CodeBlockBody = memo(\n ({\n tokenized,\n showLineNumbers,\n className,\n }: {\n tokenized: TokenizedCode;\n showLineNumbers: boolean;\n className?: string;\n }) => {\n const preStyle = useMemo(\n () => ({\n backgroundColor: tokenized.bg,\n color: tokenized.fg,\n }),\n [tokenized.bg, tokenized.fg],\n );\n\n const keyedLines = useMemo(() => addKeysToTokens(tokenized.tokens), [tokenized.tokens]);\n\n return (\n <pre\n className={cn(\n \"dark:!bg-[var(--shiki-dark-bg)] dark:!text-[var(--shiki-dark)] m-0 p-4 text-sm\",\n className,\n )}\n style={preStyle}\n >\n <code\n className={cn(\n \"font-mono text-sm\",\n showLineNumbers && \"[counter-increment:line_0] [counter-reset:line]\",\n )}\n >\n {keyedLines.map((keyedLine) => (\n <LineSpan key={keyedLine.key} keyedLine={keyedLine} showLineNumbers={showLineNumbers} />\n ))}\n </code>\n </pre>\n );\n },\n (prevProps, nextProps) =>\n prevProps.tokenized === nextProps.tokenized &&\n prevProps.showLineNumbers === nextProps.showLineNumbers &&\n prevProps.className === nextProps.className,\n);\n\nCodeBlockBody.displayName = \"CodeBlockBody\";\n\nexport const CodeBlockContainer = ({\n className,\n language,\n style,\n ...props\n}: HTMLAttributes<HTMLDivElement> & { language: string }) => (\n <div\n className={cn(\n \"group relative w-full overflow-hidden rounded-md border bg-background text-foreground\",\n className,\n )}\n data-language={language}\n style={{\n containIntrinsicSize: \"auto 200px\",\n contentVisibility: \"auto\",\n ...style,\n }}\n {...props}\n />\n);\n\nexport const CodeBlockHeader = ({\n children,\n className,\n ...props\n}: HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n \"flex items-center justify-between border-b bg-muted/80 px-3 py-2 text-muted-foreground text-xs\",\n className,\n )}\n {...props}\n >\n {children}\n </div>\n);\n\nexport const CodeBlockTitle = ({\n children,\n className,\n ...props\n}: HTMLAttributes<HTMLDivElement>) => (\n <div className={cn(\"flex items-center gap-2\", className)} {...props}>\n {children}\n </div>\n);\n\nexport const CodeBlockFilename = ({\n children,\n className,\n ...props\n}: HTMLAttributes<HTMLSpanElement>) => (\n <span className={cn(\"font-mono\", className)} {...props}>\n {children}\n </span>\n);\n\nexport const CodeBlockActions = ({\n children,\n className,\n ...props\n}: HTMLAttributes<HTMLDivElement>) => (\n <div className={cn(\"-my-1 -mr-1 flex items-center gap-2\", className)} {...props}>\n {children}\n </div>\n);\n\nexport const CodeBlockContent = ({\n code,\n language,\n showLineNumbers = false,\n}: {\n code: string;\n language: BundledLanguage;\n showLineNumbers?: boolean;\n}) => {\n // Memoized raw tokens for immediate display\n const rawTokens = useMemo(() => createRawTokens(code), [code]);\n\n // Synchronous cache lookup — avoids setState in effect for cached results\n const syncTokens = useMemo(\n () => highlightCode(code, language) ?? rawTokens,\n [code, language, rawTokens],\n );\n\n // Async highlighting result (populated after shiki loads)\n const [asyncTokens, setAsyncTokens] = useState<TokenizedCode | null>(null);\n const asyncKeyRef = useRef({ code, language });\n\n // Invalidate stale async tokens synchronously during render\n if (asyncKeyRef.current.code !== code || asyncKeyRef.current.language !== language) {\n asyncKeyRef.current = { code, language };\n setAsyncTokens(null);\n }\n\n useEffect(() => {\n let cancelled = false;\n\n highlightCode(code, language, (result) => {\n if (!cancelled) {\n setAsyncTokens(result);\n }\n });\n\n return () => {\n cancelled = true;\n };\n }, [code, language]);\n\n const tokenized = asyncTokens ?? syncTokens;\n\n return (\n <div className=\"relative overflow-auto\">\n <CodeBlockBody showLineNumbers={showLineNumbers} tokenized={tokenized} />\n </div>\n );\n};\n\nexport const CodeBlock = ({\n code,\n language,\n showLineNumbers = false,\n className,\n children,\n ...props\n}: CodeBlockProps) => {\n const contextValue = useMemo(() => ({ code }), [code]);\n\n return (\n <CodeBlockContext.Provider value={contextValue}>\n <CodeBlockContainer className={className} language={language} {...props}>\n {children}\n <CodeBlockContent code={code} language={language} showLineNumbers={showLineNumbers} />\n </CodeBlockContainer>\n </CodeBlockContext.Provider>\n );\n};\n\nexport type CodeBlockCopyButtonProps = ComponentProps<typeof Button> & {\n onCopy?: () => void;\n onError?: (error: Error) => void;\n timeout?: number;\n};\n\nexport const CodeBlockCopyButton = ({\n onCopy,\n onError,\n timeout = 2000,\n children,\n className,\n ...props\n}: CodeBlockCopyButtonProps) => {\n const [isCopied, setIsCopied] = useState(false);\n const timeoutRef = useRef<number>(0);\n const { code } = useContext(CodeBlockContext);\n\n const copyToClipboard = useCallback(async () => {\n if (typeof window === \"undefined\" || !navigator?.clipboard?.writeText) {\n onError?.(new Error(\"Clipboard API not available\"));\n return;\n }\n\n try {\n if (!isCopied) {\n await navigator.clipboard.writeText(code);\n setIsCopied(true);\n onCopy?.();\n timeoutRef.current = window.setTimeout(() => setIsCopied(false), timeout);\n }\n } catch (error) {\n onError?.(error as Error);\n }\n }, [code, onCopy, onError, timeout, isCopied]);\n\n useEffect(\n () => () => {\n window.clearTimeout(timeoutRef.current);\n },\n [],\n );\n\n const Icon = isCopied ? CheckIcon : CopyIcon;\n\n return (\n <Button\n className={cn(\"shrink-0\", className)}\n onClick={copyToClipboard}\n size=\"icon\"\n variant=\"ghost\"\n {...props}\n >\n {children ?? <Icon size={14} />}\n </Button>\n );\n};\n\nexport type CodeBlockLanguageSelectorProps = ComponentProps<typeof Select>;\n\nexport const CodeBlockLanguageSelector = (props: CodeBlockLanguageSelectorProps) => (\n <Select {...props} />\n);\n\nexport type CodeBlockLanguageSelectorTriggerProps = ComponentProps<typeof SelectTrigger>;\n\nexport const CodeBlockLanguageSelectorTrigger = ({\n className,\n ...props\n}: CodeBlockLanguageSelectorTriggerProps) => (\n <SelectTrigger\n className={cn(\"h-7 border-none bg-transparent px-2 text-xs shadow-none\", className)}\n size=\"sm\"\n {...props}\n />\n);\n\nexport type CodeBlockLanguageSelectorValueProps = ComponentProps<typeof SelectValue>;\n\nexport const CodeBlockLanguageSelectorValue = (props: CodeBlockLanguageSelectorValueProps) => (\n <SelectValue {...props} />\n);\n\nexport type CodeBlockLanguageSelectorContentProps = ComponentProps<typeof SelectContent>;\n\nexport const CodeBlockLanguageSelectorContent = ({\n align = \"end\",\n ...props\n}: CodeBlockLanguageSelectorContentProps) => <SelectContent align={align} {...props} />;\n\nexport type CodeBlockLanguageSelectorItemProps = ComponentProps<typeof SelectItem>;\n\nexport const CodeBlockLanguageSelectorItem = (props: CodeBlockLanguageSelectorItemProps) => (\n <SelectItem {...props} />\n);\n","\"use client\";\n\nimport { cn } from \"../utils\";\nimport { highlightCode } from \"./code-block\";\nimport { Streamdown, type CodeHighlighterPlugin, type StreamdownProps } from \"streamdown\";\nimport { useMemo } from \"react\";\nimport { bundledLanguages } from \"shiki/langs\";\nimport type { BundledLanguage } from \"shiki\";\n\nconst highlightedLanguages = Object.keys(bundledLanguages) as BundledLanguage[];\n\nconst codeHighlighter = {\n getSupportedLanguages: () => highlightedLanguages,\n getThemes: () => [\"github-light\", \"github-dark\"],\n highlight: ({ code, language }, callback) => highlightCode(code, language, callback),\n name: \"shiki\",\n supportsLanguage: (language) => language in bundledLanguages,\n type: \"code-highlighter\",\n} satisfies CodeHighlighterPlugin;\n\nexport type ResponseProps = Omit<StreamdownProps, \"children\"> & {\n children: string;\n};\n\nexport const Response = ({\n children,\n className,\n controls = false,\n plugins,\n ...props\n}: ResponseProps) => {\n const responsePlugins = useMemo(\n () => ({ ...plugins, code: plugins?.code ?? codeHighlighter }),\n [plugins],\n );\n\n return (\n <Streamdown\n className={cn(\n \"leading-6\",\n \"*:first:mt-0 *:last:mb-0\",\n \"[&_a]:text-primary [&_a]:underline [&_a]:underline-offset-2\",\n \"[&_blockquote]:my-3 [&_blockquote]:border-l-2 [&_blockquote]:border-border [&_blockquote]:pl-3 [&_blockquote]:text-muted-foreground\",\n \"[&_h1]:mb-2 [&_h1]:mt-4 [&_h1]:text-base [&_h1]:font-semibold\",\n \"[&_h2]:mb-2 [&_h2]:mt-4 [&_h2]:text-sm [&_h2]:font-semibold\",\n \"[&_h3]:mb-1.5 [&_h3]:mt-3 [&_h3]:text-sm [&_h3]:font-semibold\",\n \"[&_li]:my-1 [&_ol]:my-2 [&_ol]:list-decimal [&_ol]:pl-5 [&_ul]:my-2 [&_ul]:list-disc [&_ul]:pl-5\",\n \"[&_p]:my-2\",\n \"**:data-[streamdown=inline-code]:text-[length:inherit] **:data-[streamdown=inline-code]:leading-[inherit]\",\n \"**:data-[streamdown=code-block]:my-3 **:data-[streamdown=code-block]:gap-0 **:data-[streamdown=code-block]:overflow-hidden **:data-[streamdown=code-block]:rounded-lg **:data-[streamdown=code-block]:bg-muted/40 **:data-[streamdown=code-block]:p-0\",\n \"**:data-[streamdown=code-block-header]:px-2\",\n \"**:data-[streamdown=code-block-body]:rounded-none **:data-[streamdown=code-block-body]:border-0 **:data-[streamdown=code-block-body]:border-t **:data-[streamdown=code-block-body]:bg-background **:data-[streamdown=code-block-body]:p-3\",\n \"[&_strong]:font-semibold\",\n \"[&_table]:my-3 [&_table]:w-full [&_table]:border-collapse [&_td]:border [&_td]:border-border [&_td]:px-2 [&_td]:py-1 [&_th]:border [&_th]:border-border [&_th]:px-2 [&_th]:py-1 [&_th]:text-left [&_th]:font-semibold\",\n className,\n )}\n controls={controls}\n plugins={responsePlugins}\n {...props}\n >\n {children}\n </Streamdown>\n );\n};\n","import type { UIMessage } from \"ai\";\nimport {\n SURVEY_ASSISTANT_TURN_FINAL_PART_TYPE,\n surveyAssistantTurnFinalSchema,\n} from \"../../protocol\";\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst asTimestamp = (value: unknown): number | undefined => {\n if (value instanceof Date) return Number.isFinite(value.getTime()) ? value.getTime() : undefined;\n if (typeof value === \"number\") return Number.isFinite(value) ? value : undefined;\n if (typeof value !== \"string\") return undefined;\n\n const timestamp = Date.parse(value);\n return Number.isFinite(timestamp) ? timestamp : undefined;\n};\n\nconst getMastraCreatedAt = (value: unknown): number | undefined => {\n if (!isRecord(value) || !isRecord(value.mastra)) return undefined;\n return asTimestamp(value.mastra.createdAt);\n};\n\nconst getPartTimestamps = (part: UIMessage[\"parts\"][number]): number[] => {\n const value = part as unknown as Record<string, unknown>;\n return [\n getMastraCreatedAt(value.providerMetadata),\n getMastraCreatedAt(value.callProviderMetadata),\n getMastraCreatedAt(value.resultProviderMetadata),\n ].filter((timestamp): timestamp is number => timestamp !== undefined);\n};\n\n/**\n * Mastra persists message and part timestamps already. Reconstructing elapsed\n * time here keeps restored chats informative without a second timing store.\n */\nexport const getPersistedMessageDurationSeconds = (message: UIMessage): number | undefined => {\n const turnFinalPart = message.parts.find(\n (part) => part.type === SURVEY_ASSISTANT_TURN_FINAL_PART_TYPE,\n );\n const turnFinal = surveyAssistantTurnFinalSchema.safeParse(\n turnFinalPart && \"data\" in turnFinalPart ? turnFinalPart.data : undefined,\n );\n if (turnFinal.success && turnFinal.data.durationMs !== undefined) {\n return Math.max(1, Math.ceil(turnFinal.data.durationMs / 1000));\n }\n\n if (!isRecord(message.metadata)) return undefined;\n\n const startedAt = asTimestamp(message.metadata.createdAt);\n if (startedAt === undefined) return undefined;\n\n const completedAt = Math.max(...message.parts.flatMap(getPartTimestamps));\n if (!Number.isFinite(completedAt) || completedAt < startedAt) return undefined;\n\n return Math.max(1, Math.ceil((completedAt - startedAt) / 1000));\n};\n","import {\n SURVEY_ASSISTANT_TURN_FINAL_PART_TYPE,\n surveyAssistantTurnFinalSchema,\n type SurveyAssistantTurnFinal,\n} from \"../../protocol\";\nimport type { UIMessage } from \"ai\";\n\nexport const getPersistedMessageTurnStatus = (\n message: UIMessage,\n): SurveyAssistantTurnFinal[\"status\"] | undefined => {\n for (let index = message.parts.length - 1; index >= 0; index -= 1) {\n const part = message.parts[index];\n if (part?.type !== SURVEY_ASSISTANT_TURN_FINAL_PART_TYPE || !(\"data\" in part)) continue;\n\n const parsed = surveyAssistantTurnFinalSchema.safeParse(part.data);\n if (parsed.success) return parsed.data.status;\n }\n\n return undefined;\n};\n","export type SurveyAssistantInitialThreadLoadState = \"error\" | \"loading\" | null;\n\nexport const getSurveyAssistantInitialThreadLoadState = ({\n error,\n hasSelectedThread,\n loading,\n}: {\n error: string | null;\n hasSelectedThread: boolean;\n loading: boolean;\n}): SurveyAssistantInitialThreadLoadState => {\n if (loading) return \"loading\";\n if (!hasSelectedThread) return error ? \"error\" : \"loading\";\n return null;\n};\n","\"use client\";\n\nimport {\n ChainOfThought,\n ChainOfThoughtContent,\n ChainOfThoughtHeader,\n ChainOfThoughtStep,\n} from \"./internal/chain-of-thought\";\nimport {\n Conversation,\n ConversationContent,\n ConversationEmptyState,\n ConversationScrollButton,\n} from \"./internal/conversation\";\nimport { Message, MessageContent } from \"./internal/message\";\nimport {\n SurveyAssistantPromptInput,\n type SurveyAssistantPromptInputMessage,\n} from \"./survey-assistant-prompt-input\";\nimport { stringifyToolTechnicalDetails } from \"./internal/tool-technical-details\";\nimport { Response } from \"./internal/response\";\nimport { CodeBlock } from \"./internal/code-block\";\nimport { Collapsible, CollapsibleContent, CollapsibleTrigger } from \"./internal/collapsible\";\nimport { cn } from \"./utils\";\nimport { parseSurveyAssistantError, SURVEY_ASSISTANT_ATTACHMENT_PART_TYPE } from \"../protocol\";\nimport type {\n SurveyApplyResult,\n SurveyAssistantAttachmentReference,\n SurveyAssistantSnapshot,\n SurveyAssistantModelOption,\n SurveyAssistantThread,\n SurveyAssistantThreadList,\n SurveyChangeSet,\n} from \"../protocol\";\nimport {\n createSurveyAssistantThreadClient,\n isSurveyAssistantTurnActive,\n parseSurveyChangeSet,\n type SurveyAssistantThreadClient,\n type SurveyAssistantSessionOptions,\n type SurveyTurnOutcome,\n unwrapSurveyAssistantToolOutput,\n useSurveyAssistantSession,\n} from \"../react\";\nimport {\n connectSurveyAssistantThreadLauncher,\n type SurveyAssistantThreadLaunch,\n type SurveyAssistantThreadLauncher,\n} from \"../react/thread-launcher\";\nimport type { LocalizationCatalog, LocalizationTranslate } from \"@case-framework/ui-localization\";\nimport {\n getToolName,\n isFileUIPart,\n isReasoningUIPart,\n isToolUIPart,\n type DynamicToolUIPart,\n type FileUIPart,\n type ToolUIPart,\n type UIMessage,\n} from \"ai\";\nimport {\n CheckCircleIcon,\n ChevronRightIcon,\n ClockIcon,\n FileIcon,\n HistoryIcon,\n ListChecksIcon,\n LoaderCircleIcon,\n MessageSquarePlusIcon,\n PencilIcon,\n PlusIcon,\n SearchIcon,\n SparklesIcon,\n Trash2Icon,\n WandSparklesIcon,\n WrenchIcon,\n XCircleIcon,\n} from \"lucide-react\";\nimport { type ReactNode, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { SurveyAssistantLocalizationProvider, useSurveyAssistantTranslation } from \"./localization\";\nimport { getPersistedMessageDurationSeconds } from \"./internal/message-timing\";\nimport { getPersistedMessageTurnStatus } from \"./internal/message-turn-status\";\nimport { getSurveyAssistantInitialThreadLoadState } from \"./initial-thread-load\";\n\ntype ToolPart = ToolUIPart | DynamicToolUIPart;\n\ntype AssistantEmptyStateContext = \"new-survey\" | \"selected-item\" | \"survey\";\n\nconst isRootSurveyItem = (item: SurveyAssistantSnapshot[\"survey\"][\"surveyItems\"][number]) =>\n typeof item.config === \"object\" &&\n item.config !== null &&\n (item.config as { isRoot?: unknown }).isRoot === true;\n\nconst getAssistantEmptyStateContext = (\n controller: SurveyAssistantSessionOptions[\"controller\"],\n): AssistantEmptyStateContext => {\n try {\n const snapshot = controller?.getSnapshot();\n if (!snapshot) return \"survey\";\n\n const surveyItems = snapshot.survey.surveyItems.filter((item) => !isRootSurveyItem(item));\n if (surveyItems.length === 0) return \"new-survey\";\n if (surveyItems.some((item) => item.id === snapshot.ui.selectedItemId)) return \"selected-item\";\n return \"survey\";\n } catch {\n return \"survey\";\n }\n};\n\nconst getAssistantQuickPrompts = (\n t: LocalizationTranslate,\n context: AssistantEmptyStateContext,\n) => {\n if (context === \"new-survey\") {\n return [\n {\n label: t(\"quickActions.draftSurvey.label\"),\n description: t(\"quickActions.draftSurvey.description\"),\n icon: WandSparklesIcon,\n prompt: t(\"quickActions.draftSurvey.prompt\"),\n },\n {\n label: t(\"quickActions.useBrief.label\"),\n description: t(\"quickActions.useBrief.description\"),\n icon: FileIcon,\n prompt: t(\"quickActions.useBrief.prompt\"),\n },\n {\n label: t(\"quickActions.planSurvey.label\"),\n description: t(\"quickActions.planSurvey.description\"),\n icon: ListChecksIcon,\n prompt: t(\"quickActions.planSurvey.prompt\"),\n },\n ];\n }\n\n return [\n {\n label: t(\"quickActions.review.label\"),\n description: t(\"quickActions.review.description\"),\n icon: ListChecksIcon,\n prompt: t(\"quickActions.review.prompt\"),\n },\n {\n label: t(\"quickActions.create.label\"),\n description: t(\"quickActions.create.description\"),\n icon: MessageSquarePlusIcon,\n prompt: t(\"quickActions.create.prompt\"),\n },\n {\n label: t(\n context === \"selected-item\"\n ? \"quickActions.refineSelection.label\"\n : \"quickActions.refine.label\",\n ),\n description: t(\n context === \"selected-item\"\n ? \"quickActions.refineSelection.description\"\n : \"quickActions.refine.description\",\n ),\n icon: WandSparklesIcon,\n prompt: t(\n context === \"selected-item\"\n ? \"quickActions.refineSelection.prompt\"\n : \"quickActions.refine.prompt\",\n ),\n },\n ];\n};\n\nconst isSurveyAssistantAttachmentReferencePart = (\n part: UIMessage[\"parts\"][number],\n): part is {\n type: typeof SURVEY_ASSISTANT_ATTACHMENT_PART_TYPE;\n data: SurveyAssistantAttachmentReference;\n} => {\n if (\n part.type !== SURVEY_ASSISTANT_ATTACHMENT_PART_TYPE ||\n typeof part.data !== \"object\" ||\n part.data === null\n ) {\n return false;\n }\n const data = part.data as Partial<SurveyAssistantAttachmentReference>;\n return (\n typeof data.filename === \"string\" &&\n typeof data.mediaType === \"string\" &&\n typeof data.bytes === \"number\"\n );\n};\n\nconst hasRenderableParts = (message: UIMessage) => {\n return message.parts.some(\n (part) =>\n (part.type === \"text\" && part.text.length > 0) ||\n isFileUIPart(part) ||\n isSurveyAssistantAttachmentReferencePart(part) ||\n (isReasoningUIPart(part) && part.text.trim().length > 0) ||\n isToolUIPart(part),\n );\n};\n\nconst getFilePartLabel = (part: FileUIPart) => part.filename ?? part.mediaType;\n\nconst getToolOutput = (part: ToolPart) =>\n part.state === \"output-available\" ? part.output : undefined;\n\nconst getToolErrorText = (part: ToolPart) =>\n part.state === \"output-error\" ? part.errorText : undefined;\n\nconst localizedToolNames = new Set([\n \"survey_inspect\",\n \"survey_change\",\n \"survey_expression\",\n \"survey_authoring_reference\",\n \"survey_attachment\",\n \"recall\",\n]);\n\nconst getToolDisplayName = (\n t: LocalizationTranslate,\n toolName: string,\n phase: \"active\" | \"complete\" = \"complete\",\n) =>\n localizedToolNames.has(toolName)\n ? t(`activity.tools.${toolName}.${phase}`)\n : t(phase === \"active\" ? \"activity.genericActive\" : \"activity.genericComplete\");\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst unwrapOutput = unwrapSurveyAssistantToolOutput;\n\ntype AssistantErrorPresentation = {\n description: string;\n hint: string;\n retryable: boolean;\n title: string;\n tone: \"warning\" | \"error\";\n};\n\nconst getAssistantErrorPresentation = (\n error: unknown,\n t: LocalizationTranslate,\n): AssistantErrorPresentation => {\n const parsed = parseSurveyAssistantError(error);\n return {\n title: t(`errors.${parsed.code}.title`),\n description: parsed.detail ?? t(\"errors.fallbackDetail\"),\n hint: t(`errors.${parsed.code}.hint`),\n retryable:\n parsed.retryable ?? (parsed.code === \"rate_limited\" || parsed.code === \"request_failed\"),\n tone:\n parsed.code === \"model_unavailable\" || parsed.code === \"rate_limited\" ? \"warning\" : \"error\",\n };\n};\n\nconst getChangeSet = parseSurveyChangeSet;\n\nconst isChangeSet = (output: unknown): output is SurveyChangeSet => {\n return getChangeSet(output) !== null;\n};\n\nconst getValidationCounts = (validation: unknown) => {\n if (!isRecord(validation)) {\n return { issueCount: 0, warningCount: 0 };\n }\n\n return {\n issueCount: Array.isArray(validation.issues) ? validation.issues.length : 0,\n warningCount: Array.isArray(validation.warnings) ? validation.warnings.length : 0,\n };\n};\n\nconst SurveyAssistantToolOutputSummary = ({\n applyResult,\n output,\n}: {\n applyResult?: SurveyApplyResult;\n output: unknown;\n}) => {\n const t = useSurveyAssistantTranslation();\n const unwrappedOutput = unwrapOutput(output);\n\n if (isChangeSet(unwrappedOutput)) {\n const { issueCount, warningCount } = getValidationCounts(unwrappedOutput.validation);\n const isValid = unwrappedOutput.status === \"validated\";\n const status = applyResult?.status ?? (isValid ? \"validated\" : \"rejected\");\n const isPositiveStatus = status === \"applied\" || status === \"validated\";\n const statusLabel =\n status === \"applied\"\n ? t(\"changes.applied\")\n : status === \"stale\"\n ? t(\"changes.stale\")\n : status === \"failed\"\n ? t(\"changes.failed\")\n : isValid\n ? t(\"changes.prepared\")\n : t(\"changes.rejected\");\n const statusMessage = applyResult?.message ?? unwrappedOutput.summary;\n\n return (\n <div\n className={cn(\n \"relative rounded-md border px-2.5 py-2 text-xs\",\n isPositiveStatus\n ? \"border-emerald-200/70 bg-emerald-50/40 text-emerald-950\"\n : status === \"stale\"\n ? \"border-amber-200/70 bg-amber-50/40 text-amber-900\"\n : \"border-red-200/70 bg-red-50/40 text-red-900\",\n )}\n >\n <div className=\"flex items-center gap-2 font-medium\">\n {isPositiveStatus ? (\n <CheckCircleIcon className=\"size-3.5 shrink-0\" />\n ) : (\n <XCircleIcon className=\"size-3.5 shrink-0\" />\n )}\n <span>{statusLabel}</span>\n </div>\n <div className=\"mt-1 text-xs\">\n {statusMessage}\n {unwrappedOutput.operations.length > 0 && (\n <span className=\"text-current/70\">\n {\" \"}\n (\n {t(\n unwrappedOutput.operations.length === 1\n ? \"changes.operationCount\"\n : \"changes.operationCountPlural\",\n { count: unwrappedOutput.operations.length },\n )}\n )\n </span>\n )}\n </div>\n {(issueCount > 0 || warningCount > 0) && (\n <div className=\"mt-1 text-current/70\">\n {issueCount > 0 &&\n t(issueCount === 1 ? \"changes.issueCount\" : \"changes.issueCountPlural\", {\n count: issueCount,\n })}\n {issueCount > 0 && warningCount > 0 && \", \"}\n {warningCount > 0 &&\n t(warningCount === 1 ? \"changes.warningCount\" : \"changes.warningCountPlural\", {\n count: warningCount,\n })}\n </div>\n )}\n </div>\n );\n }\n\n return null;\n};\n\nconst getToolTitle = (t: LocalizationTranslate, toolName: string, state: ToolPart[\"state\"]) => {\n if (state === \"output-available\") {\n return getToolDisplayName(t, toolName, \"complete\");\n }\n if (state === \"output-error\") {\n return t(\"activity.failedSuffix\", { name: getToolDisplayName(t, toolName, \"complete\") });\n }\n if (state === \"output-denied\") {\n return t(\"activity.skippedSuffix\", { name: getToolDisplayName(t, toolName, \"active\") });\n }\n\n return getToolDisplayName(t, toolName, \"active\");\n};\n\nconst getToolProgressLabel = (t: LocalizationTranslate, part: ToolPart) => {\n switch (part.state) {\n case \"approval-requested\":\n return t(\"activity.waitingApproval\");\n case \"approval-responded\":\n return t(\"activity.continuingApproval\");\n case \"input-streaming\":\n return t(\"activity.preparingStep\");\n case \"input-available\":\n return getToolDisplayName(t, getToolName(part), \"active\");\n case \"output-available\":\n return t(\"activity.usingResult\");\n case \"output-denied\":\n return t(\"activity.continuingWithoutStep\");\n case \"output-error\":\n return t(\"activity.recoveringToolError\");\n }\n};\n\nconst getToolStatusMeta = (\n t: LocalizationTranslate,\n): Record<\n ToolPart[\"state\"],\n { icon: ReactNode; label: string | null; stepStatus: \"active\" | \"complete\" }\n> => ({\n \"approval-requested\": {\n icon: <ClockIcon className=\"size-3 text-amber-600\" />,\n label: t(\"activity.waitingApproval\"),\n stepStatus: \"active\",\n },\n \"approval-responded\": {\n icon: <CheckCircleIcon className=\"size-3 text-blue-600\" />,\n label: t(\"activity.approvalReceived\"),\n stepStatus: \"complete\",\n },\n \"input-available\": {\n icon: <LoaderCircleIcon className=\"size-3 animate-spin text-blue-600\" />,\n label: null,\n stepStatus: \"active\",\n },\n \"input-streaming\": {\n icon: <LoaderCircleIcon className=\"size-3 animate-spin text-blue-600\" />,\n label: null,\n stepStatus: \"active\",\n },\n \"output-available\": {\n icon: <CheckCircleIcon className=\"size-3 text-emerald-600\" />,\n label: null,\n stepStatus: \"complete\",\n },\n \"output-denied\": {\n icon: <XCircleIcon className=\"size-3 text-orange-600\" />,\n label: null,\n stepStatus: \"complete\",\n },\n \"output-error\": {\n icon: <XCircleIcon className=\"size-3 text-red-600\" />,\n label: null,\n stepStatus: \"complete\",\n },\n});\n\nconst getStoppedToolStatusMeta = (t: LocalizationTranslate) => ({\n icon: <XCircleIcon className=\"size-3 text-muted-foreground\" />,\n label: t(\"activity.stopped\"),\n stepStatus: \"complete\" as const,\n});\n\nconst SurveyAssistantToolStep = ({\n applyResultsByChangeId,\n terminalTurnStatus,\n part,\n isLast,\n}: {\n applyResultsByChangeId: Record<string, SurveyApplyResult>;\n terminalTurnStatus?: \"aborted\" | \"failed\";\n part: ToolPart;\n isLast: boolean;\n}) => {\n const t = useSurveyAssistantTranslation();\n const toolStatusMeta = getToolStatusMeta(t);\n const toolName = getToolName(part);\n const output = getToolOutput(part);\n const errorText = getToolErrorText(part);\n const changeSet = output === undefined ? null : getChangeSet(output);\n const applyResult = changeSet ? applyResultsByChangeId[changeSet.id] : undefined;\n const changeHasError =\n changeSet?.status === \"rejected\" ||\n applyResult?.status === \"rejected\" ||\n applyResult?.status === \"failed\";\n const title = changeSet\n ? toolName === \"survey_expression\"\n ? t(\"activity.expressionChange\")\n : t(\"activity.surveyChange\")\n : getToolTitle(t, toolName, part.state);\n const meta =\n terminalTurnStatus && toolStatusMeta[part.state].stepStatus === \"active\"\n ? terminalTurnStatus === \"aborted\"\n ? getStoppedToolStatusMeta(t)\n : {\n icon: <XCircleIcon className=\"size-3 text-red-600\" />,\n label: t(\"activity.failed\"),\n stepStatus: \"complete\" as const,\n }\n : changeHasError\n ? {\n icon: <XCircleIcon className=\"size-3 text-red-900\" />,\n label: null,\n stepStatus: \"complete\" as const,\n }\n : applyResult?.status === \"stale\"\n ? {\n icon: <ClockIcon className=\"size-3 text-amber-600\" />,\n label: null,\n stepStatus: \"complete\" as const,\n }\n : toolStatusMeta[part.state];\n const metaTitle =\n meta.label ??\n (part.state === \"output-denied\"\n ? t(\"activity.skipped\")\n : part.state === \"output-error\"\n ? t(\"activity.failed\")\n : meta.stepStatus === \"active\"\n ? t(\"activity.workingShort\")\n : t(\"activity.done\"));\n const [detailsOpen, setDetailsOpen] = useState(part.state === \"output-error\");\n const hasDetails = part.input !== undefined || output !== undefined || Boolean(errorText);\n\n return (\n <ChainOfThoughtStep\n icon={WrenchIcon}\n isLast={isLast}\n label={\n <span className=\"flex flex-wrap items-center gap-x-2 gap-y-0.5\">\n <span>{title}</span>\n <span\n className={cn(\n \"inline-flex shrink-0 items-center gap-1 text-[11px] font-normal\",\n meta.stepStatus === \"active\" ? \"text-blue-700\" : \"text-muted-foreground\",\n )}\n title={metaTitle}\n >\n {meta.icon}\n {meta.label && <span>{meta.label}</span>}\n {!meta.label && <span className=\"sr-only\">{metaTitle}</span>}\n </span>\n </span>\n }\n result={\n output !== undefined ? (\n <SurveyAssistantToolOutputSummary applyResult={applyResult} output={output} />\n ) : undefined\n }\n status={meta.stepStatus}\n >\n {hasDetails && (\n <Collapsible onOpenChange={setDetailsOpen} open={detailsOpen}>\n <CollapsibleTrigger className=\"-ml-1 flex items-center gap-0.5 rounded px-1 py-0.5 text-[11px] text-muted-foreground/80 transition-colors hover:bg-background/60 hover:text-foreground\">\n <ChevronRightIcon\n className={cn(\"size-3 transition-transform\", detailsOpen && \"rotate-90\")}\n />\n {t(detailsOpen ? \"activity.hideTechnicalDetails\" : \"activity.technicalDetails\")}\n </CollapsibleTrigger>\n <CollapsibleContent className=\"mt-1.5 space-y-1.5\">\n {part.input !== undefined && (\n <CodeBlock\n className=\"border-border/60 bg-background/70 [&_code]:text-xs [&_pre]:p-2.5 [&_pre]:text-xs\"\n code={stringifyToolTechnicalDetails(part.input)}\n language=\"json\"\n />\n )}\n {(output !== undefined || errorText) && (\n <CodeBlock\n className={cn(\n \"bg-background/70 [&_code]:text-xs [&_pre]:p-2.5 [&_pre]:text-xs\",\n errorText ? \"border-destructive/25\" : \"border-border/60\",\n )}\n code={errorText ?? stringifyToolTechnicalDetails(output)}\n language=\"json\"\n />\n )}\n </CollapsibleContent>\n </Collapsible>\n )}\n </ChainOfThoughtStep>\n );\n};\n\nconst getStreamingProgressLabel = (t: LocalizationTranslate, message?: UIMessage) => {\n if (!message || message.role !== \"assistant\") {\n return t(\"status.connecting\");\n }\n\n const lastPart = message.parts.at(-1);\n if (!lastPart) {\n return t(\"status.thinking\");\n }\n\n if (isReasoningUIPart(lastPart)) {\n return t(\"status.thinking\");\n }\n\n if (isToolUIPart(lastPart)) {\n return getToolProgressLabel(t, lastPart);\n }\n\n if (lastPart.type === \"text\") {\n return t(\"status.writing\");\n }\n\n return t(\"status.working\");\n};\n\nconst SurveyAssistantProgressIndicator = ({ message }: { message?: UIMessage }) => {\n const t = useSurveyAssistantTranslation();\n return (\n <div\n aria-live=\"polite\"\n className=\"mt-2 flex items-center gap-2 px-1 text-muted-foreground text-xs\"\n role=\"status\"\n >\n <LoaderCircleIcon className=\"size-3.5 animate-spin text-blue-600\" />\n <span>{getStreamingProgressLabel(t, message)}</span>\n </div>\n );\n};\n\ntype ChainOfThoughtEntry =\n | { type: \"reasoning\"; key: string; text: string }\n | { type: \"tool\"; key: string; part: ToolPart };\n\ntype MessageBlock =\n | {\n type: \"attachment-reference\";\n key: string;\n attachment: SurveyAssistantAttachmentReference;\n }\n | { type: \"chain\"; key: string; entries: ChainOfThoughtEntry[] }\n | { type: \"file\"; key: string; part: FileUIPart }\n | { type: \"text\"; key: string; text: string };\n\n// Group the message's parts into ordered blocks, keeping text interleaved\n// with reasoning/tool-call chains in the exact order they were emitted,\n// instead of hoisting all reasoning/tool calls above all text output.\nconst buildMessageBlocks = (parts: UIMessage[\"parts\"]): MessageBlock[] => {\n const blocks: MessageBlock[] = [];\n let pendingEntries: ChainOfThoughtEntry[] = [];\n\n const flushChain = () => {\n if (pendingEntries.length > 0) {\n blocks.push({\n type: \"chain\",\n key: `chain-${pendingEntries[0].key}`,\n entries: pendingEntries,\n });\n pendingEntries = [];\n }\n };\n\n parts.forEach((part, index) => {\n if (isReasoningUIPart(part)) {\n if (part.text) {\n pendingEntries.push({ type: \"reasoning\", key: `reasoning-${index}`, text: part.text });\n }\n return;\n }\n\n if (isToolUIPart(part)) {\n pendingEntries.push({ type: \"tool\", key: `tool-${part.toolCallId}`, part });\n return;\n }\n\n if (part.type === \"text\") {\n flushChain();\n blocks.push({ type: \"text\", key: `text-${index}`, text: part.text });\n return;\n }\n\n if (isFileUIPart(part)) {\n flushChain();\n blocks.push({ type: \"file\", key: `file-${index}`, part });\n return;\n }\n\n if (isSurveyAssistantAttachmentReferencePart(part)) {\n flushChain();\n blocks.push({\n type: \"attachment-reference\",\n key: `attachment-reference-${index}`,\n attachment: part.data,\n });\n }\n });\n\n flushChain();\n\n return blocks;\n};\n\nconst SurveyAssistantMessageParts = ({\n applyResultsByChangeId,\n isLastMessage,\n isStreaming,\n message,\n showProgress,\n terminalTurnStatus,\n}: {\n applyResultsByChangeId: Record<string, SurveyApplyResult>;\n isLastMessage: boolean;\n isStreaming: boolean;\n message: UIMessage;\n showProgress?: boolean;\n terminalTurnStatus?: \"aborted\" | \"failed\";\n}) => {\n const blocks = useMemo(() => buildMessageBlocks(message.parts), [message.parts]);\n const persistedDuration = useMemo(() => getPersistedMessageDurationSeconds(message), [message]);\n const lastPart = message.parts.at(-1);\n const hasActiveToolMessage =\n lastPart !== undefined &&\n isToolUIPart(lastPart) &&\n (lastPart.state === \"input-streaming\" || lastPart.state === \"input-available\");\n\n return (\n <>\n {blocks.map((block, blockIndex) => {\n const isLastBlock = blockIndex === blocks.length - 1;\n\n if (block.type === \"text\") {\n if (message.role === \"assistant\") {\n return (\n <Response\n className=\"leading-5 [&_li]:my-0.5 [&_p]:my-1.5 [&_p:first-child]:mt-0 [&_p:last-child]:mb-0\"\n key={block.key}\n >\n {block.text}\n </Response>\n );\n }\n\n return <span key={block.key}>{block.text}</span>;\n }\n\n if (block.type === \"file\") {\n return (\n <span\n className=\"inline-flex max-w-full items-center gap-2 rounded-md border border-border bg-muted px-2 py-1 text-xs\"\n key={block.key}\n title={getFilePartLabel(block.part)}\n >\n <FileIcon className=\"size-3.5 shrink-0 text-muted-foreground\" />\n <span className=\"min-w-0 truncate\">{getFilePartLabel(block.part)}</span>\n <span className=\"shrink-0 text-muted-foreground\">{block.part.mediaType}</span>\n </span>\n );\n }\n\n if (block.type === \"attachment-reference\") {\n return (\n <span\n className=\"inline-flex max-w-full items-center gap-2 rounded-md border border-border bg-muted px-2 py-1 text-xs\"\n key={block.key}\n title={block.attachment.filename}\n >\n <FileIcon className=\"size-3.5 shrink-0 text-muted-foreground\" />\n <span className=\"min-w-0 truncate\">{block.attachment.filename}</span>\n <span className=\"shrink-0 text-muted-foreground\">{block.attachment.mediaType}</span>\n </span>\n );\n }\n\n const isChainActive = isLastMessage && isStreaming && isLastBlock;\n\n return (\n <ChainOfThought\n autoClose\n className=\"w-full rounded-md bg-muted/60 px-2 py-1.5\"\n defaultDuration={persistedDuration}\n defaultOpen={isChainActive}\n duration={isChainActive ? undefined : persistedDuration}\n isStreaming={isChainActive}\n key={block.key}\n >\n <ChainOfThoughtHeader className=\"text-xs font-medium\" />\n <ChainOfThoughtContent className=\"relative mt-2\">\n <div\n aria-hidden=\"true\"\n className=\"absolute top-0 bottom-0 left-1.75 w-px bg-border\"\n />\n {block.entries.map((entry, index) => {\n const isLastEntry = index === block.entries.length - 1;\n\n if (entry.type === \"reasoning\") {\n return (\n <Response\n className={cn(\n \"pr-1 pl-5 text-muted-foreground text-xs leading-5 [&_p]:my-1 [&_p:first-child]:mt-0 [&_p:last-child]:mb-0\",\n !isLastEntry && \"mb-2\",\n )}\n key={entry.key}\n >\n {entry.text}\n </Response>\n );\n }\n\n return (\n <SurveyAssistantToolStep\n applyResultsByChangeId={applyResultsByChangeId}\n isLast={isLastEntry}\n key={entry.key}\n part={entry.part}\n terminalTurnStatus={terminalTurnStatus}\n />\n );\n })}\n </ChainOfThoughtContent>\n </ChainOfThought>\n );\n })}\n {showProgress &&\n !hasActiveToolMessage &&\n (lastPart === undefined || !isReasoningUIPart(lastPart)) && (\n <SurveyAssistantProgressIndicator message={message} />\n )}\n </>\n );\n};\n\nexport type SurveyAssistantPanelProps = Omit<\n SurveyAssistantSessionOptions,\n \"initialMessages\" | \"modelId\" | \"resourceId\" | \"threadId\"\n> & {\n embedded?: boolean;\n language?: string;\n localizations?: LocalizationCatalog;\n modelId?: string;\n models?: SurveyAssistantModelOption[];\n onConfirmDeleteThread?: (thread: SurveyAssistantThread) => boolean | Promise<boolean>;\n onModelChange?(modelId: string): void;\n resourceId: string;\n selectedThreadStorageKey?: string | false;\n threadApi?: string;\n threadClient?: SurveyAssistantThreadClient;\n /** Allows host UI outside the panel to create a new thread and execute its first prompt. */\n threadLauncher?: SurveyAssistantThreadLauncher;\n};\n\ntype SurveyAssistantChatPanelProps = SurveyAssistantSessionOptions & {\n embedded?: boolean;\n focusPromptOnMount?: boolean;\n hasEarlierMessages: boolean;\n initialLaunch?: SurveyAssistantThreadLaunch;\n models: SurveyAssistantModelOption[];\n onInitialLaunchHandled(): void;\n onModelChange(modelId: string): void;\n onFirstSubmit(text: string): void;\n onLoadEarlierMessages(): Promise<UIMessage[]>;\n onTurnSettled(): void;\n threadControls: ReactNode;\n threadTitle: string;\n};\n\nconst SurveyAssistantTurnOutcomeNotice = (outcome: SurveyTurnOutcome) => {\n const t = useSurveyAssistantTranslation();\n if (outcome.status === \"failed\" || outcome.status === \"aborted\") {\n const reason = (() => {\n switch (outcome.terminationReason) {\n case \"client-abort\":\n return t(\"turn.reasons.clientAbort\");\n case \"first-response-timeout\":\n return t(\"turn.reasons.firstResponseTimeout\");\n case \"idle-timeout\":\n return t(\"turn.reasons.idleTimeout\");\n case \"max-duration\":\n return t(\"turn.reasons.maxDuration\");\n case \"max-steps\":\n return t(\"turn.reasons.maxSteps\");\n case \"length-limit\":\n return t(\"turn.reasons.lengthLimit\");\n case \"content-filter\":\n return t(\"turn.reasons.contentFilter\");\n case \"provider-error\":\n return t(\"turn.reasons.providerError\");\n case \"stream-error\":\n return t(\"turn.reasons.streamError\");\n case \"incomplete-response\":\n return t(\"turn.reasons.incompleteResponse\");\n default:\n return t(\"turn.reasons.unknown\");\n }\n })();\n\n return (\n <div\n className={cn(\n \"rounded-lg border px-3 py-2 text-xs\",\n outcome.status === \"aborted\"\n ? \"border-border bg-muted/50 text-foreground\"\n : \"border-destructive/20 bg-destructive/5 text-foreground\",\n )}\n >\n <div className=\"font-medium\">\n {t(outcome.status === \"aborted\" ? \"turn.abortedTitle\" : \"turn.failedTitle\")}\n </div>\n <div className=\"mt-1 text-muted-foreground\">{reason}</div>\n </div>\n );\n }\n\n const description =\n outcome.status === \"blocked\"\n ? t(outcome.blockedChangeSetCount === 1 ? \"changes.blocked\" : \"changes.blockedPlural\", {\n count: outcome.blockedChangeSetCount,\n })\n : t(outcome.appliedChangeSetCount === 1 ? \"changes.partial\" : \"changes.partialPlural\", {\n applied: outcome.appliedChangeSetCount,\n failed: outcome.failedChangeSetCount,\n });\n\n return (\n <div className=\"rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-amber-950 text-xs\">\n <div className=\"font-medium\">{t(\"changes.incompleteTitle\")}</div>\n <div className=\"mt-1\">\n {description} {t(\"changes.reviewBeforeRetry\")}\n </div>\n </div>\n );\n};\n\nconst SurveyAssistantHeaderIdentity = ({\n indicatorClassName,\n status,\n title,\n}: {\n indicatorClassName: string;\n status: string;\n title: string;\n}) => (\n <div className=\"flex min-w-0 items-center gap-2\">\n <div className=\"relative flex size-6 shrink-0 items-center justify-center rounded-md bg-foreground text-background shadow-sm\">\n <SparklesIcon className=\"size-3.5\" />\n <span\n aria-hidden=\"true\"\n className={cn(\n \"absolute -right-px -bottom-px size-1.5 rounded-full border border-background\",\n indicatorClassName,\n )}\n />\n </div>\n <div className=\"min-w-0\">\n <h2 className=\"truncate font-semibold text-[13px] leading-4\">{title}</h2>\n <span\n aria-live=\"polite\"\n className=\"block truncate text-[10px] text-muted-foreground leading-3\"\n role=\"status\"\n >\n {status}\n </span>\n </div>\n </div>\n);\n\nconst SurveyAssistantChatPanel = ({\n api,\n applyPolicy,\n controller,\n embedded = false,\n focusPromptOnMount = false,\n hasEarlierMessages,\n initialLaunch,\n initialMessages,\n modelId,\n models,\n onInitialLaunchHandled,\n onModelChange,\n onFirstSubmit,\n onLoadEarlierMessages,\n onTurnSettled,\n onApplyReceipts,\n onSettleApply,\n onReviewChangeSets,\n onTurnActiveChange,\n resourceId,\n surveyId,\n threadControls,\n threadId,\n threadTitle,\n}: SurveyAssistantChatPanelProps) => {\n const t = useSurveyAssistantTranslation();\n const emptyStateContext = getAssistantEmptyStateContext(controller);\n const assistantQuickPrompts = getAssistantQuickPrompts(t, emptyStateContext);\n const {\n applyResultsByChangeId,\n authorizationError,\n dismissError,\n error,\n isStreaming,\n latestTurnOutcome,\n messages,\n prependMessages,\n state,\n status,\n stop,\n submit,\n retry,\n } = useSurveyAssistantSession({\n api,\n applyPolicy,\n controller,\n initialMessages,\n modelId,\n onApplyReceipts,\n onSettleApply,\n onReviewChangeSets,\n onTurnActiveChange,\n resourceId,\n surveyId,\n threadId,\n });\n const hasSubmittedMessageRef = useRef((initialMessages?.length ?? 0) > 0);\n const showAssistantError = Boolean(authorizationError) || Boolean(error);\n const assistantErrorPresentation = getAssistantErrorPresentation(authorizationError ?? error, t);\n const lastMessage = messages.at(-1);\n const isAssistantTurnActive = isSurveyAssistantTurnActive({ isStreaming, state });\n const promptTextareaRef = useRef<HTMLTextAreaElement>(null);\n const shouldRestorePromptFocusRef = useRef(false);\n const turnWasActiveRef = useRef(false);\n const [loadingEarlierMessages, setLoadingEarlierMessages] = useState(false);\n\n const loadEarlierMessages = useCallback(async () => {\n if (loadingEarlierMessages) return;\n setLoadingEarlierMessages(true);\n try {\n prependMessages(await onLoadEarlierMessages());\n } finally {\n setLoadingEarlierMessages(false);\n }\n }, [loadingEarlierMessages, onLoadEarlierMessages, prependMessages]);\n const isAssistantTurnSettled =\n !isStreaming &&\n (state === \"completed\" || state === \"failed\" || state === \"aborted\" || state === \"applied\");\n\n useEffect(() => {\n if (!isAssistantTurnActive) {\n if (shouldRestorePromptFocusRef.current) {\n shouldRestorePromptFocusRef.current = false;\n promptTextareaRef.current?.focus();\n }\n return;\n }\n\n const cancelFocusRestoreOnPointerDown = (event: PointerEvent) => {\n if (event.target !== promptTextareaRef.current) {\n shouldRestorePromptFocusRef.current = false;\n }\n };\n const cancelFocusRestore = () => {\n shouldRestorePromptFocusRef.current = false;\n };\n\n document.addEventListener(\"focusin\", cancelFocusRestore, true);\n document.addEventListener(\"pointerdown\", cancelFocusRestoreOnPointerDown, true);\n window.addEventListener(\"blur\", cancelFocusRestore);\n\n return () => {\n document.removeEventListener(\"focusin\", cancelFocusRestore, true);\n document.removeEventListener(\"pointerdown\", cancelFocusRestoreOnPointerDown, true);\n window.removeEventListener(\"blur\", cancelFocusRestore);\n };\n }, [isAssistantTurnActive]);\n\n useEffect(() => {\n if (isAssistantTurnActive) {\n turnWasActiveRef.current = true;\n return;\n }\n if (!turnWasActiveRef.current || !isAssistantTurnSettled) return;\n\n turnWasActiveRef.current = false;\n onTurnSettled();\n }, [isAssistantTurnActive, isAssistantTurnSettled, onTurnSettled]);\n\n const showPendingAssistantRow =\n isAssistantTurnActive && (!lastMessage || lastMessage.role !== \"assistant\");\n const sessionStatusLabel =\n state === \"applying\"\n ? t(\"status.applying\")\n : state === \"applied\"\n ? t(\"status.applied\")\n : state === \"aborted\"\n ? t(\"status.stopped\")\n : isAssistantTurnActive\n ? getStreamingProgressLabel(t, lastMessage)\n : showAssistantError || state === \"failed\"\n ? t(\"status.attention\")\n : t(\"status.ready\");\n\n const handleSubmit = useCallback(\n (message: SurveyAssistantPromptInputMessage) => {\n if (isAssistantTurnActive) return false;\n const submittedFromFocusedPrompt = document.activeElement === promptTextareaRef.current;\n const accepted = submit({ files: message.files, text: message.text });\n if (accepted) {\n shouldRestorePromptFocusRef.current = submittedFromFocusedPrompt;\n if (!hasSubmittedMessageRef.current) {\n hasSubmittedMessageRef.current = true;\n onFirstSubmit(message.text);\n }\n }\n return accepted;\n },\n [isAssistantTurnActive, onFirstSubmit, submit],\n );\n\n const handleQuickPrompt = useCallback(\n (prompt: string) => handleSubmit({ files: [], text: prompt }),\n [handleSubmit],\n );\n\n useEffect(() => {\n if (!initialLaunch) return;\n if (initialLaunch.modelId) onModelChange(initialLaunch.modelId);\n const accepted = submit({\n files: initialLaunch.files ?? [],\n modelId: initialLaunch.modelId,\n text: initialLaunch.prompt,\n uiContext: initialLaunch.uiContext,\n });\n if (accepted) {\n if (!hasSubmittedMessageRef.current) {\n hasSubmittedMessageRef.current = true;\n onFirstSubmit(initialLaunch.prompt);\n }\n onInitialLaunchHandled();\n }\n }, [initialLaunch, onFirstSubmit, onInitialLaunchHandled, onModelChange, submit]);\n\n return (\n <aside\n aria-label={t(\"panel.ariaLabel\")}\n className={cn(\n \"flex h-full min-h-0 flex-col overflow-visible bg-background\",\n !embedded && \"rounded-xl border border-border shadow-sm\",\n )}\n >\n <header className=\"box-content flex h-9 shrink-0 items-center justify-between gap-2 border-b border-border bg-background px-2.5\">\n <SurveyAssistantHeaderIdentity\n indicatorClassName={\n showAssistantError || state === \"failed\"\n ? \"bg-destructive\"\n : isAssistantTurnActive\n ? \"animate-pulse bg-blue-500\"\n : state === \"aborted\"\n ? \"bg-muted-foreground\"\n : \"bg-emerald-500\"\n }\n status={sessionStatusLabel}\n title={threadTitle}\n />\n {threadControls}\n </header>\n\n <Conversation className=\"min-h-0 bg-(--surface-bg-color)\">\n <ConversationContent className=\"gap-3 px-3 py-2.5\">\n {messages.length === 0 ? (\n <ConversationEmptyState className=\"min-h-full items-stretch justify-center gap-0 px-1 py-6 text-left\">\n <div className=\"mx-auto w-full max-w-sm\">\n <div className=\"mb-3 flex size-9 items-center justify-center rounded-xl border border-border bg-muted text-foreground shadow-xs\">\n <SparklesIcon className=\"size-4\" />\n </div>\n <h3 className=\"font-semibold text-foreground text-base tracking-tight\">\n {t(emptyStateContext === \"new-survey\" ? \"empty.newSurveyTitle\" : \"empty.title\")}\n </h3>\n <p className=\"mt-1 text-muted-foreground text-xs leading-relaxed\">\n {t(\n emptyStateContext === \"new-survey\"\n ? \"empty.newSurveyDescription\"\n : \"empty.description\",\n )}\n </p>\n <div className=\"mt-4 flex flex-col gap-1.5\">\n {assistantQuickPrompts.map(({ label, description, icon: Icon, prompt }) => (\n <button\n className=\"group flex w-full items-center gap-2.5 rounded-lg border border-border bg-popover px-2.5 py-2 text-left shadow-xs transition-colors hover:border-foreground/20 hover:bg-muted/60\"\n key={label}\n onClick={() => handleQuickPrompt(prompt)}\n type=\"button\"\n >\n <span className=\"flex size-7 shrink-0 items-center justify-center rounded-md bg-muted text-muted-foreground transition-colors group-hover:bg-background group-hover:text-foreground\">\n <Icon className=\"size-3.5\" />\n </span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate font-medium text-foreground text-xs\">\n {label}\n </span>\n <span className=\"block truncate text-[11px] text-muted-foreground\">\n {description}\n </span>\n </span>\n <ChevronRightIcon className=\"size-3.5 shrink-0 text-muted-foreground/40 transition-transform group-hover:translate-x-0.5 group-hover:text-muted-foreground\" />\n </button>\n ))}\n </div>\n </div>\n </ConversationEmptyState>\n ) : (\n <>\n {hasEarlierMessages && (\n <button\n className=\"mx-auto flex h-8 items-center justify-center rounded-md px-3 text-muted-foreground text-xs hover:bg-muted hover:text-foreground disabled:pointer-events-none\"\n disabled={loadingEarlierMessages || isAssistantTurnActive}\n onClick={() => void loadEarlierMessages()}\n type=\"button\"\n >\n {loadingEarlierMessages && (\n <LoaderCircleIcon className=\"mr-1.5 size-3.5 animate-spin\" />\n )}\n {loadingEarlierMessages\n ? t(\"conversation.loadingEarlier\")\n : t(\"conversation.loadEarlier\")}\n </button>\n )}\n {messages.map((message, index) => {\n const isLastMessage = index === messages.length - 1;\n const persistedTurnStatus = getPersistedMessageTurnStatus(message);\n const terminalTurnStatus =\n persistedTurnStatus === \"aborted\" || persistedTurnStatus === \"failed\"\n ? persistedTurnStatus\n : isLastMessage && (state === \"aborted\" || state === \"failed\")\n ? state\n : undefined;\n const shouldShowProgress =\n isAssistantTurnActive && isLastMessage && message.role === \"assistant\";\n\n return (\n <Message className=\"max-w-[96%] gap-1\" from={message.role} key={message.id}>\n <MessageContent\n className={cn(message.role === \"assistant\" && \"w-full space-y-2\")}\n >\n {hasRenderableParts(message) ? (\n <>\n <SurveyAssistantMessageParts\n applyResultsByChangeId={applyResultsByChangeId}\n isLastMessage={isLastMessage}\n isStreaming={isAssistantTurnActive}\n message={message}\n showProgress={shouldShowProgress}\n terminalTurnStatus={terminalTurnStatus}\n />\n {isLastMessage && latestTurnOutcome && (\n <SurveyAssistantTurnOutcomeNotice {...latestTurnOutcome} />\n )}\n </>\n ) : shouldShowProgress ? (\n <SurveyAssistantProgressIndicator message={message} />\n ) : isLastMessage && latestTurnOutcome ? (\n <SurveyAssistantTurnOutcomeNotice {...latestTurnOutcome} />\n ) : state === \"aborted\" ? (\n <span className=\"text-muted-foreground text-sm\">\n {t(\"conversation.stopped\")}\n </span>\n ) : (\n <span className=\"text-muted-foreground text-sm\">\n {t(\"conversation.incomplete\")}\n </span>\n )}\n </MessageContent>\n </Message>\n );\n })}\n {showPendingAssistantRow && (\n <Message className=\"max-w-[96%] gap-1\" from=\"assistant\">\n <MessageContent className=\"w-full\">\n <SurveyAssistantProgressIndicator />\n </MessageContent>\n </Message>\n )}\n </>\n )}\n </ConversationContent>\n <ConversationScrollButton className=\"bottom-2.5\" />\n </Conversation>\n\n {showAssistantError && (\n <div\n className={cn(\n \"flex items-start justify-between gap-3 border-t px-3 py-2.5 text-sm\",\n assistantErrorPresentation.tone === \"warning\"\n ? \"border-amber-200 bg-amber-50/60\"\n : \"border-destructive/20 bg-destructive/5\",\n )}\n role=\"alert\"\n >\n <div className=\"flex min-w-0 gap-2.5\">\n {assistantErrorPresentation.tone === \"warning\" ? (\n <WrenchIcon className=\"mt-0.5 size-4 shrink-0 text-amber-700\" />\n ) : (\n <XCircleIcon className=\"mt-0.5 size-4 shrink-0 text-destructive\" />\n )}\n <div className=\"min-w-0\">\n <div className=\"font-medium text-foreground\">{assistantErrorPresentation.title}</div>\n <p className=\"mt-0.5 wrap-break-word text-muted-foreground\">\n {assistantErrorPresentation.description}\n </p>\n <p className=\"mt-1 text-muted-foreground/80\">{assistantErrorPresentation.hint}</p>\n {assistantErrorPresentation.retryable && (\n <button\n className=\"mt-1.5 font-medium text-foreground text-xs hover:underline\"\n onClick={retry}\n type=\"button\"\n >\n {t(\"errors.retry\")}\n </button>\n )}\n </div>\n </div>\n <button\n aria-label={t(\"errors.dismissAssistant\")}\n className=\"shrink-0 text-muted-foreground text-xs hover:text-foreground\"\n onClick={dismissError}\n type=\"button\"\n >\n {t(\"errors.dismiss\")}\n </button>\n </div>\n )}\n\n <div className=\"shrink-0 border-t border-border bg-background p-2\">\n <SurveyAssistantPromptInput\n attachmentButtonClassName=\"size-8\"\n className={cn(\n \"rounded-xl border-border bg-popover shadow-sm transition-colors\",\n isAssistantTurnActive && \"border-border/60 bg-muted/50 shadow-none\",\n )}\n disabled={isAssistantTurnActive}\n footerClassName={cn(\"transition-colors\", isAssistantTurnActive && \"bg-muted/30\")}\n formProps={{ \"aria-busy\": isAssistantTurnActive }}\n modelId={modelId}\n models={models}\n onModelChange={onModelChange}\n onStop={stop}\n onSubmit={handleSubmit}\n status={status}\n textareaClassName=\"min-h-11 max-h-28 px-3 pt-2.5 pb-1.5 transition-colors disabled:placeholder:text-muted-foreground/60\"\n textareaProps={{ autoFocus: focusPromptOnMount }}\n textareaRef={promptTextareaRef}\n />\n </div>\n </aside>\n );\n};\n\nconst SELECTED_THREAD_STORAGE_KEY = \"survey-assistant-selected-thread\";\n\nconst createThreadTitle = (text: string, fallback: string) => {\n const normalized = text.replace(/\\s+/g, \" \").trim();\n if (!normalized) return fallback;\n const words = normalized.split(\" \").slice(0, 8).join(\" \");\n return words.length > 64 ? `${words.slice(0, 61).trimEnd()}...` : words;\n};\n\nconst mergeThreads = (\n current: SurveyAssistantThread[],\n incoming: SurveyAssistantThread[],\n): SurveyAssistantThread[] => {\n const byId = new Map(current.map((thread) => [thread.id, thread]));\n for (const thread of incoming) byId.set(thread.id, thread);\n return [...byId.values()].sort(\n (left, right) => Date.parse(right.updatedAt) - Date.parse(left.updatedAt),\n );\n};\n\nconst mergeRecentThreadPage = (\n current: SurveyAssistantThread[],\n recent: SurveyAssistantThread[],\n): SurveyAssistantThread[] => {\n if (recent.length === 0) return [];\n const oldestRecentUpdate = Math.min(...recent.map((thread) => Date.parse(thread.updatedAt)));\n const olderThreads = Number.isFinite(oldestRecentUpdate)\n ? current.filter((thread) => Date.parse(thread.updatedAt) <= oldestRecentUpdate)\n : current;\n return mergeThreads(olderThreads, recent);\n};\n\nconst listThreadPage = async (\n client: SurveyAssistantThreadClient,\n cursor?: string,\n): Promise<SurveyAssistantThreadList> => {\n if (client.listPage) return client.listPage(cursor ? { cursor } : undefined);\n return cursor ? { threads: [] } : { threads: await client.list() };\n};\n\ntype SurveyAssistantPanelContentProps = Omit<\n SurveyAssistantPanelProps,\n \"language\" | \"localizations\"\n>;\n\ninterface PendingInitialLaunch {\n input: SurveyAssistantThreadLaunch;\n onSubmitted(): void;\n}\n\nconst SurveyAssistantPanelContent = ({\n embedded = false,\n modelId,\n models = [],\n onConfirmDeleteThread,\n onModelChange = () => {},\n onTurnActiveChange: onAssistantTurnActiveChange,\n resourceId,\n selectedThreadStorageKey,\n surveyId,\n threadApi,\n threadClient: providedThreadClient,\n threadLauncher,\n ...sessionProps\n}: SurveyAssistantPanelContentProps) => {\n const t = useSurveyAssistantTranslation();\n const threadClient = useMemo(\n () => providedThreadClient ?? createSurveyAssistantThreadClient(threadApi),\n [providedThreadClient, threadApi],\n );\n const storageKey =\n selectedThreadStorageKey === false\n ? null\n : (selectedThreadStorageKey ??\n `${SELECTED_THREAD_STORAGE_KEY}:${encodeURIComponent(resourceId)}${\n surveyId ? `:${encodeURIComponent(surveyId)}` : \"\"\n }`);\n const [threads, setThreads] = useState<SurveyAssistantThread[]>([]);\n const [nextThreadCursor, setNextThreadCursor] = useState<string>();\n const [selectedThread, setSelectedThread] = useState<SurveyAssistantThread | null>(null);\n const [initialMessages, setInitialMessages] = useState<UIMessage[]>([]);\n const [nextMessageCursor, setNextMessageCursor] = useState<string>();\n const [historyOpen, setHistoryOpen] = useState(false);\n const [threadSearch, setThreadSearch] = useState(\"\");\n const [loadingOlderThreads, setLoadingOlderThreads] = useState(false);\n const [editingThreadId, setEditingThreadId] = useState<string | null>(null);\n const [editingTitle, setEditingTitle] = useState(\"\");\n const [threadError, setThreadError] = useState<string | null>(null);\n const [loadingThread, setLoadingThread] = useState(true);\n const [threadLoadAttempt, setThreadLoadAttempt] = useState(0);\n const [assistantTurnActive, setAssistantTurnActive] = useState(false);\n const [initialLaunch, setInitialLaunch] = useState<PendingInitialLaunch>();\n const [promptFocusThreadId, setPromptFocusThreadId] = useState<string>();\n const historyControlsRef = useRef<HTMLDivElement>(null);\n const loadingAllThreadsRef = useRef(false);\n\n const selectModel = useCallback(\n (modelId: string) => {\n if (!models.some((model) => model.id === modelId)) return;\n onModelChange(modelId);\n },\n [models, onModelChange],\n );\n\n const selectThread = useCallback(\n async (thread: Pick<SurveyAssistantThread, \"id\">, reportError = true) => {\n setPromptFocusThreadId(undefined);\n setLoadingThread(true);\n setThreadError(null);\n try {\n const transcript = await threadClient.read(thread.id);\n setSelectedThread(transcript.thread);\n setInitialMessages(transcript.messages as UIMessage[]);\n setNextMessageCursor(transcript.nextCursor);\n setHistoryOpen(false);\n if (storageKey) window.localStorage.setItem(storageKey, thread.id);\n return transcript.thread;\n } catch (error) {\n if (reportError) {\n setThreadError(parseSurveyAssistantError(error).detail ?? t(\"errors.fallbackDetail\"));\n }\n return null;\n } finally {\n setLoadingThread(false);\n }\n },\n [storageKey, t, threadClient],\n );\n\n const createThread = useCallback(\n async (launch?: SurveyAssistantThreadLaunch) => {\n setLoadingThread(true);\n setThreadError(null);\n try {\n const thread = await threadClient.create(launch?.title);\n setPromptFocusThreadId(launch ? undefined : thread.id);\n setThreads((current) => mergeThreads(current, [thread]));\n setSelectedThread(thread);\n setInitialMessages([]);\n setNextMessageCursor(undefined);\n setHistoryOpen(false);\n if (storageKey) window.localStorage.setItem(storageKey, thread.id);\n return thread;\n } catch (error) {\n setThreadError(parseSurveyAssistantError(error).detail ?? t(\"errors.fallbackDetail\"));\n if (launch) throw error;\n return null;\n } finally {\n setLoadingThread(false);\n }\n },\n [storageKey, t, threadClient],\n );\n\n useEffect(() => {\n let cancelled = false;\n void listThreadPage(threadClient)\n .then(async (page) => {\n if (cancelled) return;\n const availableThreads = page.threads;\n setThreads(availableThreads);\n setNextThreadCursor(page.nextCursor);\n const rememberedId = storageKey ? window.localStorage.getItem(storageKey) : null;\n const rememberedThread = availableThreads.find((thread) => thread.id === rememberedId);\n if (rememberedId && !rememberedThread) {\n const restored = await selectThread({ id: rememberedId }, false);\n if (restored) {\n setThreads((current) => mergeThreads(current, [restored]));\n return;\n }\n }\n const initialThread = rememberedThread ?? availableThreads[0];\n if (initialThread) {\n await selectThread(initialThread);\n } else {\n await createThread();\n }\n })\n .catch((error) => {\n if (!cancelled) {\n setThreadError(parseSurveyAssistantError(error).detail ?? t(\"errors.fallbackDetail\"));\n setLoadingThread(false);\n }\n });\n return () => {\n cancelled = true;\n };\n }, [createThread, selectThread, storageKey, t, threadClient, threadLoadAttempt]);\n\n const retryInitialThreadLoad = useCallback(() => {\n setThreadError(null);\n setLoadingThread(true);\n setThreadLoadAttempt((attempt) => attempt + 1);\n }, []);\n\n const loadOlderThreads = useCallback(async () => {\n if (!nextThreadCursor || loadingOlderThreads) return;\n setLoadingOlderThreads(true);\n try {\n const page = await listThreadPage(threadClient, nextThreadCursor);\n setThreads((current) => mergeThreads(current, page.threads));\n setNextThreadCursor(page.nextCursor);\n } catch (error) {\n setThreadError(parseSurveyAssistantError(error).detail ?? t(\"errors.fallbackDetail\"));\n } finally {\n setLoadingOlderThreads(false);\n }\n }, [loadingOlderThreads, nextThreadCursor, t, threadClient]);\n\n const loadEarlierMessages = useCallback(async (): Promise<UIMessage[]> => {\n if (!selectedThread || !nextMessageCursor) return [];\n try {\n const transcript = await threadClient.read(selectedThread.id, nextMessageCursor);\n setNextMessageCursor(transcript.nextCursor);\n return transcript.messages as UIMessage[];\n } catch (error) {\n setThreadError(parseSurveyAssistantError(error).detail ?? t(\"errors.fallbackDetail\"));\n return [];\n }\n }, [nextMessageCursor, selectedThread, t, threadClient]);\n\n const loadAllThreadsForSearch = useCallback(async () => {\n if (!nextThreadCursor || loadingAllThreadsRef.current) return;\n loadingAllThreadsRef.current = true;\n setLoadingOlderThreads(true);\n try {\n let cursor: string | undefined = nextThreadCursor;\n while (cursor) {\n const page = await listThreadPage(threadClient, cursor);\n setThreads((current) => mergeThreads(current, page.threads));\n cursor = page.nextCursor;\n setNextThreadCursor(cursor);\n }\n } catch (error) {\n setThreadError(parseSurveyAssistantError(error).detail ?? t(\"errors.fallbackDetail\"));\n } finally {\n loadingAllThreadsRef.current = false;\n setLoadingOlderThreads(false);\n }\n }, [nextThreadCursor, t, threadClient]);\n\n useEffect(() => {\n if (threadSearch.trim()) void loadAllThreadsForSearch();\n }, [loadAllThreadsForSearch, threadSearch]);\n\n useEffect(() => {\n if (!threadLauncher || loadingThread) return;\n return connectSurveyAssistantThreadLauncher(threadLauncher, async (launch) => {\n const thread = await createThread(launch);\n if (!thread) throw new Error(\"The survey assistant thread could not be created.\");\n return new Promise<SurveyAssistantThread>((resolve) => {\n setInitialLaunch({\n input: launch,\n onSubmitted: () => resolve(thread),\n });\n });\n });\n }, [createThread, loadingThread, threadLauncher]);\n\n const renameThread = useCallback(\n async (thread: SurveyAssistantThread, title: string) => {\n const normalized = title.trim();\n if (!normalized || normalized === thread.title) {\n setEditingThreadId(null);\n setEditingTitle(\"\");\n return;\n }\n try {\n const updated = await threadClient.rename(thread.id, normalized);\n setThreads((current) => current.map((item) => (item.id === updated.id ? updated : item)));\n setSelectedThread((current) => (current?.id === updated.id ? updated : current));\n setEditingThreadId(null);\n setEditingTitle(\"\");\n } catch (error) {\n setThreadError(parseSurveyAssistantError(error).detail ?? t(\"errors.fallbackDetail\"));\n }\n },\n [t, threadClient],\n );\n\n const setAutomaticTitle = useCallback(\n async (thread: SurveyAssistantThread, title?: string) => {\n try {\n const updated = await threadClient.setAutomaticTitle(thread.id, title);\n setThreads((current) => current.map((item) => (item.id === updated.id ? updated : item)));\n setSelectedThread((current) => (current?.id === updated.id ? updated : current));\n setEditingThreadId(null);\n setEditingTitle(\"\");\n } catch (error) {\n setThreadError(parseSurveyAssistantError(error).detail ?? t(\"errors.fallbackDetail\"));\n }\n },\n [t, threadClient],\n );\n\n const beginEditingThread = useCallback((thread: SurveyAssistantThread) => {\n setEditingThreadId(thread.id);\n setEditingTitle(thread.title);\n }, []);\n\n const cancelEditingThread = useCallback(() => {\n setEditingThreadId(null);\n setEditingTitle(\"\");\n }, []);\n\n const handleTurnActiveChange = useCallback(\n (active: boolean) => {\n setAssistantTurnActive(active);\n onAssistantTurnActiveChange?.(active);\n if (active) {\n cancelEditingThread();\n setHistoryOpen(false);\n }\n },\n [cancelEditingThread, onAssistantTurnActiveChange],\n );\n\n const commitEditingThread = useCallback(async () => {\n if (!editingThreadId) return;\n const thread = threads.find((item) => item.id === editingThreadId);\n const title = editingTitle;\n if (thread) await renameThread(thread, title);\n }, [editingThreadId, editingTitle, renameThread, threads]);\n\n const deleteThread = useCallback(\n async (thread: SurveyAssistantThread) => {\n const confirmed = onConfirmDeleteThread\n ? await onConfirmDeleteThread(thread)\n : window.confirm(t(\"threads.deleteConfirm\", { title: thread.title }));\n if (!confirmed) return;\n try {\n await threadClient.delete(thread.id);\n const remaining = threads.filter((item) => item.id !== thread.id);\n setThreads(remaining);\n if (selectedThread?.id === thread.id) {\n if (remaining[0]) await selectThread(remaining[0]);\n else await createThread();\n }\n } catch (error) {\n setThreadError(parseSurveyAssistantError(error).detail ?? t(\"errors.fallbackDetail\"));\n }\n },\n [createThread, onConfirmDeleteThread, selectThread, selectedThread, t, threadClient, threads],\n );\n\n const handleFirstSubmit = useCallback(\n (text: string) => {\n if (!selectedThread || selectedThread.titleMode === \"manual\") {\n return;\n }\n void setAutomaticTitle(selectedThread, createThreadTitle(text, t(\"threads.newChat\")));\n },\n [selectedThread, setAutomaticTitle, t],\n );\n\n const handleInitialLaunchHandled = useCallback(() => {\n if (!initialLaunch) return;\n setInitialLaunch(undefined);\n initialLaunch.onSubmitted();\n }, [initialLaunch]);\n\n const refreshThreadList = useCallback(\n async (reportError: boolean) => {\n try {\n const page = await listThreadPage(threadClient);\n setThreads((current) => mergeRecentThreadPage(current, page.threads));\n const current = page.threads.find((thread) => thread.id === selectedThread?.id);\n if (current && !editingThreadId) {\n setSelectedThread((selected) => {\n if (!selected || selected.id !== current.id) return selected;\n return selected.title === current.title &&\n selected.titleMode === current.titleMode &&\n selected.updatedAt === current.updatedAt\n ? selected\n : current;\n });\n }\n } catch (error) {\n if (reportError) {\n setThreadError(parseSurveyAssistantError(error).detail ?? t(\"errors.fallbackDetail\"));\n }\n }\n },\n [editingThreadId, selectedThread?.id, t, threadClient],\n );\n\n const toggleHistory = useCallback(() => {\n if (historyOpen) {\n void commitEditingThread();\n setHistoryOpen(false);\n return;\n }\n\n setHistoryOpen(true);\n void refreshThreadList(true);\n }, [commitEditingThread, historyOpen, refreshThreadList]);\n\n const handleTurnSettled = useCallback(() => {\n void refreshThreadList(false);\n }, [refreshThreadList]);\n\n useEffect(() => {\n if (!historyOpen) return;\n\n const handlePointerDown = (event: PointerEvent) => {\n if (!historyControlsRef.current?.contains(event.target as Node)) {\n void commitEditingThread();\n setHistoryOpen(false);\n }\n };\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n cancelEditingThread();\n setHistoryOpen(false);\n }\n };\n\n document.addEventListener(\"pointerdown\", handlePointerDown);\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => {\n document.removeEventListener(\"pointerdown\", handlePointerDown);\n document.removeEventListener(\"keydown\", handleKeyDown);\n };\n }, [cancelEditingThread, commitEditingThread, historyOpen]);\n\n useEffect(() => {\n if (!loadingThread && selectedThread?.id === promptFocusThreadId) {\n setPromptFocusThreadId(undefined);\n }\n }, [loadingThread, promptFocusThreadId, selectedThread?.id]);\n\n useEffect(() => {\n const handleFocus = () => {\n void refreshThreadList(false);\n };\n\n window.addEventListener(\"focus\", handleFocus);\n return () => window.removeEventListener(\"focus\", handleFocus);\n }, [refreshThreadList]);\n\n const initialThreadLoadState = getSurveyAssistantInitialThreadLoadState({\n error: threadError,\n hasSelectedThread: Boolean(selectedThread),\n loading: loadingThread,\n });\n if (initialThreadLoadState || !selectedThread) {\n const initialLoadFailed = initialThreadLoadState === \"error\";\n return (\n <aside\n className={cn(\n \"flex h-full min-h-0 flex-col overflow-visible bg-background\",\n !embedded && \"rounded-xl border border-border shadow-sm\",\n )}\n >\n <header className=\"box-content flex h-9 shrink-0 items-center border-b border-border bg-background px-2.5\">\n <SurveyAssistantHeaderIdentity\n indicatorClassName={initialLoadFailed ? \"bg-destructive\" : \"animate-pulse bg-blue-500\"}\n status={initialLoadFailed ? t(\"panel.controlsUnavailable\") : t(\"panel.loadingChats\")}\n title={t(\"panel.title\")}\n />\n </header>\n <div className=\"flex min-h-0 flex-1 items-center justify-center p-6 text-sm\">\n {initialLoadFailed ? (\n <div className=\"max-w-sm text-center\">\n <div className=\"font-medium text-foreground\">{t(\"panel.controlsUnavailable\")}</div>\n <div className=\"mt-1 text-muted-foreground\">{threadError}</div>\n <button\n className=\"mt-3 rounded-md border border-border bg-background px-3 py-1.5 font-medium text-foreground hover:bg-muted\"\n onClick={retryInitialThreadLoad}\n type=\"button\"\n >\n {t(\"errors.retry\")}\n </button>\n </div>\n ) : (\n <div className=\"flex items-center text-muted-foreground\">\n <LoaderCircleIcon className=\"mr-2 size-4 animate-spin\" />\n {t(\"panel.loadingChats\")}\n </div>\n )}\n </div>\n </aside>\n );\n }\n\n const normalizedThreadSearch = threadSearch.trim().toLocaleLowerCase();\n const visibleThreads = normalizedThreadSearch\n ? threads.filter((thread) => thread.title.toLocaleLowerCase().includes(normalizedThreadSearch))\n : threads;\n\n const threadControls = (\n <div className=\"relative flex shrink-0 items-center gap-1\" ref={historyControlsRef}>\n <button\n aria-label={t(\"threads.newChat\")}\n className=\"flex size-8 items-center justify-center rounded-lg text-muted-foreground hover:bg-muted hover:text-foreground disabled:pointer-events-none disabled:opacity-50\"\n disabled={assistantTurnActive}\n onClick={() => void createThread()}\n title={t(\"threads.newChat\")}\n type=\"button\"\n >\n <PlusIcon className=\"size-4\" />\n </button>\n <button\n aria-expanded={historyOpen}\n aria-label={t(\"threads.history\")}\n className=\"flex size-8 items-center justify-center rounded-lg text-muted-foreground hover:bg-muted hover:text-foreground disabled:pointer-events-none disabled:opacity-50\"\n disabled={assistantTurnActive}\n onClick={toggleHistory}\n title={t(\"threads.history\")}\n type=\"button\"\n >\n <HistoryIcon className=\"size-4\" />\n </button>\n {historyOpen && (\n <div className=\"absolute top-10 right-0 z-30 w-72 overflow-hidden rounded-lg border border-border bg-popover text-popover-foreground shadow-lg\">\n <div className=\"border-b border-border px-3 py-2 font-medium text-xs\">\n {t(\"threads.recent\")}\n </div>\n <div className=\"relative border-b border-border p-2\">\n <SearchIcon className=\"pointer-events-none absolute top-1/2 left-4 size-3.5 -translate-y-1/2 text-muted-foreground\" />\n <input\n aria-label={t(\"threads.search\")}\n className=\"h-8 w-full rounded-md border border-input bg-background pr-2 pl-8 text-xs outline-none placeholder:text-muted-foreground focus:ring-1 focus:ring-ring\"\n onChange={(event) => setThreadSearch(event.currentTarget.value)}\n placeholder={t(\"threads.search\")}\n type=\"search\"\n value={threadSearch}\n />\n </div>\n <div className=\"max-h-72 overflow-y-auto p-1\">\n {visibleThreads.map((thread) => (\n <div\n className={cn(\n \"group flex min-h-10 items-center gap-1 rounded-md px-2\",\n thread.id === selectedThread.id ? \"bg-muted\" : \"hover:bg-muted/60\",\n )}\n key={thread.id}\n >\n {editingThreadId === thread.id ? (\n <>\n <input\n autoFocus\n className=\"min-w-0 flex-1 rounded border border-input bg-background px-1.5 py-1 text-xs outline-none focus:ring-1 focus:ring-ring\"\n onBlur={() => void commitEditingThread()}\n onChange={(event) => setEditingTitle(event.currentTarget.value)}\n onKeyDown={(event) => {\n if (event.key === \"Enter\") {\n event.preventDefault();\n void commitEditingThread();\n }\n if (event.key === \"Escape\") {\n event.preventDefault();\n event.stopPropagation();\n cancelEditingThread();\n setHistoryOpen(false);\n }\n }}\n value={editingTitle}\n />\n {thread.titleMode === \"manual\" && (\n <button\n aria-label={t(\"threads.automaticTitle\")}\n className=\"flex h-7 shrink-0 items-center gap-1 rounded px-1.5 text-muted-foreground text-xs hover:bg-background hover:text-foreground\"\n onClick={() => void setAutomaticTitle(thread)}\n onMouseDown={(event) => event.preventDefault()}\n title={t(\"threads.automaticTitle\")}\n type=\"button\"\n >\n <SparklesIcon className=\"size-3\" />\n <span>{t(\"threads.automaticShort\")}</span>\n </button>\n )}\n </>\n ) : (\n <button\n className=\"min-w-0 flex-1 truncate py-2 text-left text-xs\"\n onClick={() => void selectThread(thread)}\n type=\"button\"\n >\n {thread.title}\n </button>\n )}\n <button\n aria-label={t(\"threads.rename\", { title: thread.title })}\n className=\"flex size-7 shrink-0 items-center justify-center rounded text-muted-foreground opacity-0 hover:bg-background hover:text-foreground group-hover:opacity-100\"\n onClick={() => beginEditingThread(thread)}\n title={t(\"threads.renameTitle\")}\n type=\"button\"\n >\n <PencilIcon className=\"size-3.5\" />\n </button>\n <button\n aria-label={t(\"threads.delete\", { title: thread.title })}\n className=\"flex size-7 shrink-0 items-center justify-center rounded text-muted-foreground opacity-0 hover:bg-background hover:text-foreground group-hover:opacity-100\"\n onClick={() => void deleteThread(thread)}\n title={t(\"threads.deleteTitle\")}\n type=\"button\"\n >\n <Trash2Icon className=\"size-3.5\" />\n </button>\n </div>\n ))}\n {visibleThreads.length === 0 && !loadingOlderThreads && (\n <div className=\"px-3 py-5 text-center text-muted-foreground text-xs\">\n {t(\"threads.noMatches\")}\n </div>\n )}\n {(nextThreadCursor || loadingOlderThreads) && (\n <button\n className=\"flex h-9 w-full items-center justify-center rounded-md text-muted-foreground text-xs hover:bg-muted hover:text-foreground disabled:pointer-events-none\"\n disabled={loadingOlderThreads || Boolean(normalizedThreadSearch)}\n onClick={() => void loadOlderThreads()}\n type=\"button\"\n >\n {loadingOlderThreads ? (\n <>\n <LoaderCircleIcon className=\"mr-1.5 size-3.5 animate-spin\" />\n {normalizedThreadSearch ? t(\"threads.searching\") : t(\"threads.loadingOlder\")}\n </>\n ) : (\n t(\"threads.loadOlder\")\n )}\n </button>\n )}\n </div>\n </div>\n )}\n </div>\n );\n\n return (\n <div className=\"relative h-full min-h-0\">\n <SurveyAssistantChatPanel\n {...sessionProps}\n embedded={embedded}\n focusPromptOnMount={selectedThread.id === promptFocusThreadId}\n hasEarlierMessages={Boolean(nextMessageCursor)}\n initialLaunch={initialLaunch?.input}\n initialMessages={initialMessages}\n key={selectedThread.id}\n modelId={modelId}\n models={models}\n onInitialLaunchHandled={handleInitialLaunchHandled}\n onModelChange={selectModel}\n onFirstSubmit={handleFirstSubmit}\n onLoadEarlierMessages={loadEarlierMessages}\n onTurnSettled={handleTurnSettled}\n onTurnActiveChange={handleTurnActiveChange}\n resourceId={resourceId}\n surveyId={surveyId}\n threadControls={threadControls}\n threadId={selectedThread.id}\n threadTitle={selectedThread.title}\n />\n {threadError && (\n <div className=\"absolute right-3 bottom-3 left-3 z-40 rounded-lg border border-destructive/20 bg-popover px-3 py-2 text-xs shadow-lg\">\n <div className=\"font-medium\">{t(\"panel.controlsUnavailable\")}</div>\n <div className=\"mt-0.5 text-muted-foreground\">{threadError}</div>\n <button\n className=\"mt-1 font-medium hover:underline\"\n onClick={() => setThreadError(null)}\n type=\"button\"\n >\n {t(\"errors.dismiss\")}\n </button>\n </div>\n )}\n </div>\n );\n};\n\nexport const SurveyAssistantPanel = ({\n language,\n localizations,\n ...props\n}: SurveyAssistantPanelProps) => (\n <div className=\"case-survey-assistant\">\n <SurveyAssistantLocalizationProvider language={language} localizations={localizations}>\n <SurveyAssistantPanelContent\n {...props}\n key={JSON.stringify([props.resourceId, props.surveyId])}\n />\n </SurveyAssistantLocalizationProvider>\n </div>\n);\n","\"use client\";\n\nimport {\n useSurveyAssistantModelCatalog,\n type SurveyAssistantLaunchUIContext,\n type SurveyAssistantThreadLauncher,\n} from \"../react\";\nimport { useCallback, useEffect, useState, type Ref } from \"react\";\nimport { SurveyAssistantLocalizationProvider } from \"./localization\";\nimport {\n SurveyAssistantPromptInput,\n type SurveyAssistantPromptInputMessage,\n} from \"./survey-assistant-prompt-input\";\nimport type { LocalizationCatalog } from \"@case-framework/ui-localization\";\nimport type { ComponentProps } from \"react\";\n\nexport interface SurveyAssistantThreadLauncherPromptProps {\n className?: string;\n disabled?: boolean;\n language?: string;\n localizations?: LocalizationCatalog;\n modelCatalogApi?: string;\n modelStorageKey?: string | false;\n onError?(error: unknown): void;\n onModelCatalogError?(error: Error): void;\n onSubmitted(): void;\n onValueChange?(value: string): void;\n placeholder?: string;\n textareaClassName?: string;\n textareaProps?: Omit<ComponentProps<\"textarea\">, \"className\" | \"placeholder\" | \"ref\">;\n textareaRef?: Ref<HTMLTextAreaElement>;\n threadLauncher: SurveyAssistantThreadLauncher;\n uiContext?: SurveyAssistantLaunchUIContext;\n value?: string;\n}\n\nconst SurveyAssistantThreadLauncherPromptContent = ({\n className,\n disabled = false,\n modelCatalogApi,\n modelStorageKey,\n onError,\n onModelCatalogError,\n onSubmitted,\n onValueChange,\n placeholder,\n textareaClassName,\n textareaProps,\n textareaRef,\n threadLauncher,\n uiContext,\n value,\n}: Omit<SurveyAssistantThreadLauncherPromptProps, \"language\" | \"localizations\">) => {\n const catalog = useSurveyAssistantModelCatalog({\n api: modelCatalogApi,\n storageKey: modelStorageKey,\n });\n const [submitting, setSubmitting] = useState(false);\n\n useEffect(() => {\n if (catalog.error) onModelCatalogError?.(catalog.error);\n }, [catalog.error, onModelCatalogError]);\n\n const submit = useCallback(\n async ({ files, text }: SurveyAssistantPromptInputMessage) => {\n if (disabled || submitting) return false;\n setSubmitting(true);\n try {\n await threadLauncher.startThread({\n files,\n modelId: catalog.modelId,\n prompt: text,\n uiContext,\n });\n onSubmitted();\n return true;\n } catch (error) {\n onError?.(error);\n return false;\n } finally {\n setSubmitting(false);\n }\n },\n [catalog.modelId, disabled, onError, onSubmitted, submitting, threadLauncher, uiContext],\n );\n\n return (\n <SurveyAssistantPromptInput\n attachmentsDisabled={submitting}\n className={className}\n disabled={disabled || submitting}\n modelDisabled={catalog.loading || submitting}\n modelId={catalog.modelId}\n models={catalog.models}\n onModelChange={catalog.selectModel}\n onSubmit={submit}\n onValueChange={onValueChange}\n placeholder={placeholder}\n textareaClassName={textareaClassName}\n textareaProps={textareaProps}\n textareaRef={textareaRef}\n value={value}\n />\n );\n};\n\nexport const SurveyAssistantThreadLauncherPrompt = ({\n language,\n localizations,\n ...props\n}: SurveyAssistantThreadLauncherPromptProps) => (\n <div className=\"case-survey-assistant\">\n <SurveyAssistantLocalizationProvider language={language} localizations={localizations}>\n <SurveyAssistantThreadLauncherPromptContent {...props} />\n </SurveyAssistantLocalizationProvider>\n </div>\n);\n","\"use client\";\n\nimport { useEffect } from \"react\";\nimport { useSurveyAssistantModelCatalog } from \"../react\";\nimport { SurveyAssistantPanel, type SurveyAssistantPanelProps } from \"./survey-assistant-panel\";\n\ntype SurveyAssistantPanelContentProps = Omit<\n SurveyAssistantPanelProps,\n \"modelId\" | \"models\" | \"onModelChange\"\n>;\n\nexport type ConnectedSurveyAssistantPanelProps = SurveyAssistantPanelContentProps & {\n modelCatalogApi?: string;\n modelStorageKey?: string | false;\n onModelCatalogError?(error: Error): void;\n onModelChange?(modelId: string): void;\n};\n\nexport const ConnectedSurveyAssistantPanel = ({\n modelCatalogApi,\n modelStorageKey,\n onModelCatalogError,\n onModelChange,\n ...props\n}: ConnectedSurveyAssistantPanelProps) => {\n const catalog = useSurveyAssistantModelCatalog({\n api: modelCatalogApi,\n onModelChange,\n storageKey: modelStorageKey,\n });\n\n useEffect(() => {\n if (catalog.error) onModelCatalogError?.(catalog.error);\n }, [catalog.error, onModelCatalogError]);\n\n return (\n <SurveyAssistantPanel\n {...props}\n modelId={catalog.modelId}\n models={catalog.models}\n onModelChange={catalog.selectModel}\n />\n );\n};\n"],"mappings":"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F,QAAQ;IACN,QAAQ;IACR,UAAU;IACX;GACF;EACF;CACD,SAAS;EACP,SAAS;EACT,OAAO;EACP,QAAQ;EACR,UAAU;EACV,UAAU;EACV,gBAAgB;EAChB,sBAAsB;EACtB,YAAY;EACZ,kBAAkB;EAClB,cAAc;EACd,oBAAoB;EACpB,iBAAiB;EACjB,SACE;EACF,eACE;EACF,SAAS;EACT,eAAe;EACf,mBAAmB;EACpB;CACD,QAAQ;EACN,SAAS;EACT,kBAAkB;EAClB,OAAO;EACP,gBAAgB;EAChB,mBAAmB;GACjB,OAAO;GACP,MAAM;GACP;EACD,cAAc;GACZ,OAAO;GACP,MAAM;GACP;EACD,sBAAsB;GACpB,OAAO;GACP,MAAM;GACP;EACD,wBAAwB;GACtB,OAAO;GACP,MAAM;GACP;EACD,gBAAgB;GACd,OAAO;GACP,MAAM;GACP;EACF;CACD,SAAS;EACP,SAAS;EACT,SAAS;EACT,QAAQ;EACR,QAAQ;EACR,WAAW;EACX,WAAW;EACX,WAAW;EACX,cAAc;EACd,gBAAgB;EAChB,gBAAgB;EAChB,QAAQ;EACR,aAAa;EACb,QAAQ;EACR,aAAa;EACb,eAAe;EAChB;CACF;;;AClND,MAAa,4BAAkD;CAC7D,OAAO;EACL,WAAW;EACX,OAAO;EACP,cAAc;EACd,qBAAqB;EACtB;CACD,OAAO;EACL,OAAO;EACP,aACE;EACF,gBAAgB;EAChB,sBACE;EACH;CACD,cAAc;EACZ,aAAa;GACX,OAAO;GACP,aAAa;GACb,QACE;GACH;EACD,UAAU;GACR,OAAO;GACP,aAAa;GACb,QACE;GACH;EACD,YAAY;GACV,OAAO;GACP,aAAa;GACb,QACE;GACH;EACD,QAAQ;GACN,OAAO;GACP,aAAa;GACb,QACE;GACH;EACD,QAAQ;GACN,OAAO;GACP,aAAa;GACb,QAAQ;GACT;EACD,QAAQ;GACN,OAAO;GACP,aAAa;GACb,QAAQ;GACT;EACD,iBAAiB;GACf,OAAO;GACP,aAAa;GACb,QACE;GACH;EACF;CACD,OAAO;EACL,aAAa;EACb,aAAa;EACb,WAAW;EACX,gBAAgB;EAChB,kBA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"}
|
|
1
|
+
{"version":3,"file":"ui.mjs","names":["Collapsible","CollapsiblePrimitive","Collapsible","TooltipPrimitive","Tooltip","Tooltip","Select","SelectPrimitive","Select","isRecord","Checkbox","CheckboxPrimitive","Dialog","DialogPrimitive","Dialog","Checkbox","Collapsible"],"sources":["../src/ui/internal/collapsible.tsx","../src/ui/utils.ts","../src/ui/internal/shimmer.tsx","../src/ui/localizations/en.ts","../src/ui/localizations/nl.ts","../src/ui/localization.tsx","../src/ui/internal/chain-of-thought.tsx","../src/ui/internal/button.tsx","../src/ui/internal/conversation.tsx","../src/ui/internal/message.tsx","../src/ui/internal/tooltip.tsx","../src/ui/internal/prompt-input.tsx","../src/ui/internal/select.tsx","../src/ui/survey-assistant-prompt-input.tsx","../src/ui/internal/tool-technical-details.ts","../src/ui/internal/code-block.tsx","../src/ui/internal/response.tsx","../src/ui/internal/message-timing.ts","../src/ui/internal/message-turn-status.ts","../src/ui/initial-thread-load.ts","../src/ui/assistant-error-presentation.ts","../src/ui/internal/checkbox.tsx","../src/ui/internal/dialog.tsx","../src/ui/support-bundle-dialog.tsx","../src/ui/survey-assistant-panel.tsx","../src/ui/survey-assistant-thread-launcher-prompt.tsx","../src/ui/connected-survey-assistant-panel.tsx"],"sourcesContent":["\"use client\";\n\nimport { Collapsible as CollapsiblePrimitive } from \"radix-ui\";\n\nfunction Collapsible({ ...props }: React.ComponentProps<typeof CollapsiblePrimitive.Root>) {\n return <CollapsiblePrimitive.Root data-slot=\"collapsible\" {...props} />;\n}\n\nfunction CollapsibleTrigger({\n ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleTrigger>) {\n return <CollapsiblePrimitive.CollapsibleTrigger data-slot=\"collapsible-trigger\" {...props} />;\n}\n\nfunction CollapsibleContent({\n ...props\n}: React.ComponentProps<typeof CollapsiblePrimitive.CollapsibleContent>) {\n return <CollapsiblePrimitive.CollapsibleContent data-slot=\"collapsible-content\" {...props} />;\n}\n\nexport { Collapsible, CollapsibleTrigger, CollapsibleContent };\n","import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport const cn = (...inputs: ClassValue[]) => twMerge(clsx(inputs));\n","\"use client\";\n\n/* eslint-disable react-hooks/static-components */\n\nimport { cn } from \"../utils\";\nimport type { MotionProps } from \"motion/react\";\nimport { motion } from \"motion/react\";\nimport type { CSSProperties, ElementType, JSX } from \"react\";\nimport { memo, useMemo } from \"react\";\n\ntype MotionHTMLProps = MotionProps & Record<string, unknown>;\n\n// Cache motion components at module level to avoid creating during render\nconst motionComponentCache = new Map<\n keyof JSX.IntrinsicElements,\n React.ComponentType<MotionHTMLProps>\n>();\n\nconst getMotionComponent = (element: keyof JSX.IntrinsicElements) => {\n let component = motionComponentCache.get(element);\n if (!component) {\n component = motion.create(element);\n motionComponentCache.set(element, component);\n }\n return component;\n};\n\nexport interface TextShimmerProps {\n children: string;\n as?: ElementType;\n className?: string;\n duration?: number;\n spread?: number;\n}\n\nconst ShimmerComponent = ({\n children,\n as: Component = \"p\",\n className,\n duration = 2,\n spread = 2,\n}: TextShimmerProps) => {\n const MotionComponent = getMotionComponent(Component as keyof JSX.IntrinsicElements);\n\n const dynamicSpread = useMemo(() => (children?.length ?? 0) * spread, [children, spread]);\n\n return (\n <MotionComponent\n animate={{ backgroundPosition: \"0% center\" }}\n className={cn(\n \"relative inline-block bg-[length:250%_100%,auto] bg-clip-text text-transparent\",\n \"[--bg:linear-gradient(90deg,#0000_calc(50%-var(--spread)),var(--color-background),#0000_calc(50%+var(--spread)))] [background-repeat:no-repeat,padding-box]\",\n className,\n )}\n initial={{ backgroundPosition: \"100% center\" }}\n style={\n {\n \"--spread\": `${dynamicSpread}px`,\n backgroundImage:\n \"var(--bg), linear-gradient(var(--color-muted-foreground), var(--color-muted-foreground))\",\n } as CSSProperties\n }\n transition={{\n duration,\n ease: \"linear\",\n repeat: Number.POSITIVE_INFINITY,\n }}\n >\n {children}\n </MotionComponent>\n );\n};\n\nexport const Shimmer = memo(ShimmerComponent);\n","import type { LocalizationMessages } from \"@case-framework/ui-localization\";\n\nexport const surveyAssistantEnMessages: LocalizationMessages = {\n panel: {\n ariaLabel: \"Survey assistant\",\n title: \"Assistant\",\n loadingChats: \"Loading chats\",\n controlsUnavailable: \"Assistant controls unavailable\",\n },\n empty: {\n title: \"What are you working on?\",\n description:\n \"Draft, inspect, or refine your survey - just describe what you need, or start with one of these.\",\n newSurveyTitle: \"Create with the assistant\",\n newSurveyDescription:\n \"Describe the survey you need, share a brief, or plan the right questions together.\",\n },\n quickActions: {\n draftSurvey: {\n label: \"Draft a survey\",\n description: \"Create a first draft from your goals\",\n prompt:\n \"Help me create a first draft of a new survey. Ask me about its topic, audience, and goals before drafting it.\",\n },\n useBrief: {\n label: \"Use a brief or notes\",\n description: \"Turn requirements into a survey\",\n prompt:\n \"Help me turn a brief or set of notes into a survey. Ask me to paste the text or attach the document.\",\n },\n planSurvey: {\n label: \"Plan the questions\",\n description: \"Outline the structure before drafting\",\n prompt: \"Help me plan the questions and structure for a new survey before we draft it.\",\n },\n review: {\n label: \"Review survey\",\n description: \"Spot issues and suggest improvements\",\n prompt:\n \"Run a deterministic audit of the current survey, including expression-reference integrity, then review its quality and suggest improvements.\",\n },\n create: {\n label: \"New question\",\n description: \"Draft a question to add\",\n prompt: \"Help me create a new survey question.\",\n },\n refine: {\n label: \"Refine wording\",\n description: \"Polish respondent-facing text\",\n prompt: \"Suggest improvements to the respondent-facing wording.\",\n },\n refineSelection: {\n label: \"Refine selected item\",\n description: \"Polish the wording in context\",\n prompt: \"Suggest improvements to the respondent-facing wording of the selected item.\",\n },\n },\n input: {\n placeholder: \"Ask about the survey...\",\n attachFiles: \"Attach a PDF, PNG, or JPG\",\n dropFiles: \"Drop a PDF, PNG, or JPG to attach\",\n supportedFiles: \"Supported: PDF, PNG, and JPG. Export Word documents as PDF.\",\n unsupportedFiles: \"{filenames} can't be attached. Supported formats: PDF, PNG, and JPG.\",\n wordFilesUnsupported:\n \"Word documents aren't supported. Export {filenames} as PDF, then attach the PDF.\",\n removeFile: \"Remove {filename}\",\n send: \"Send message\",\n stop: \"Stop response\",\n model: \"Assistant model\",\n defaultModel: \"Default model\",\n },\n conversation: {\n loadEarlier: \"Load earlier messages\",\n loadingEarlier: \"Loading earlier messages…\",\n noMessages: \"No messages yet\",\n startConversation: \"Start a conversation to see messages here\",\n scrollToLatest: \"Scroll to latest message\",\n working: \"Working...\",\n stopped: \"Stopped\",\n incomplete: \"Response interrupted\",\n },\n turn: {\n failedTitle: \"The assistant did not complete this turn.\",\n abortedTitle: \"The turn was stopped.\",\n reasons: {\n clientAbort: \"The request was stopped by the client.\",\n firstResponseTimeout: \"No meaningful response arrived before the initial deadline.\",\n idleTimeout: \"The assistant stopped producing activity.\",\n maxDuration: \"The one-hour execution ceiling was reached.\",\n maxSteps: \"The assistant reached its tool-step limit before finishing.\",\n lengthLimit: \"The model reached its output-length limit.\",\n contentFilter: \"The provider stopped the response because of its content policy.\",\n providerError: \"The model provider reported an error.\",\n streamError: \"The response stream ended with an error.\",\n incompleteResponse: \"The response ended without a normal completion.\",\n unknown: \"The response ended before completion.\",\n },\n },\n status: {\n applying: \"Applying changes\",\n applied: \"Changes applied\",\n stopped: \"Stopped\",\n attention: \"Needs attention\",\n ready: \"Ready\",\n connecting: \"Connecting to the assistant\",\n thinking: \"Thinking through your request\",\n writing: \"Writing the response\",\n working: \"Working on your request\",\n },\n activity: {\n label: \"Activity\",\n working: \"Working...\",\n workedFor: \"Worked for {duration}\",\n technicalDetails: \"View technical details\",\n hideTechnicalDetails: \"Hide technical details\",\n waitingApproval: \"Waiting for approval\",\n approvalReceived: \"Approval received\",\n continuingApproval: \"Continuing after approval\",\n preparingStep: \"Preparing the next step\",\n usingResult: \"Using the result\",\n continuingWithoutStep: \"Continuing without that step\",\n recoveringToolError: \"Recovering from a tool error\",\n skipped: \"Skipped\",\n failed: \"Failed\",\n workingShort: \"Working\",\n done: \"Done\",\n stopped: \"Stopped\",\n expressionChange: \"Expression change\",\n surveyChange: \"Survey change\",\n genericActive: \"Working with survey\",\n genericComplete: \"Survey step complete\",\n failedSuffix: \"{name} failed\",\n skippedSuffix: \"{name} skipped\",\n tools: {\n survey_inspect: { active: \"Reviewing survey\", complete: \"Survey reviewed\" },\n survey_change: { active: \"Preparing change\", complete: \"Change prepared\" },\n survey_expression: { active: \"Preparing expression\", complete: \"Expression prepared\" },\n survey_authoring_reference: {\n active: \"Checking authoring guidance\",\n complete: \"Authoring guidance checked\",\n },\n survey_attachment: { active: \"Opening attachment\", complete: \"Attachment opened\" },\n recall: {\n active: \"Checking earlier conversation\",\n complete: \"Earlier conversation checked\",\n },\n },\n },\n changes: {\n applied: \"Change applied\",\n stale: \"Change not applied\",\n failed: \"Change could not be applied\",\n prepared: \"Change prepared\",\n rejected: \"Change could not be prepared\",\n operationCount: \"{count} operation\",\n operationCountPlural: \"{count} operations\",\n issueCount: \"{count} issue\",\n issueCountPlural: \"{count} issues\",\n warningCount: \"{count} warning\",\n warningCountPlural: \"{count} warnings\",\n incompleteTitle: \"The requested changes were not completed.\",\n blocked:\n \"No survey changes were applied because {count} rejected change proposal remains unresolved.\",\n blockedPlural:\n \"No survey changes were applied because {count} rejected change proposals remain unresolved.\",\n partial: \"{applied} change set was applied; {failed} could not be applied.\",\n partialPlural: \"{applied} change sets were applied; {failed} could not be applied.\",\n reviewBeforeRetry: \"Review the change steps above before retrying.\",\n },\n errors: {\n dismiss: \"Dismiss\",\n dismissAssistant: \"Dismiss assistant error\",\n retry: \"Try again\",\n exportDetails: \"Export details\",\n showProviderDetails: \"Show full provider message\",\n hideProviderDetails: \"Hide provider message\",\n upstreamStatus: \"Provider status {status}\",\n providerRequestId: \"Request {requestId}\",\n fallbackDetail: \"The assistant hit an error on the previous turn.\",\n model_unavailable: {\n title: \"Model unavailable\",\n hint: \"Select a model available to this account, then send the message again.\",\n },\n rate_limited: {\n title: \"Assistant temporarily busy\",\n hint: \"Wait a moment, then send the message again.\",\n },\n authorization_failed: {\n title: \"Assistant unavailable\",\n hint: \"Check your access or sign in again before retrying.\",\n },\n attachment_unavailable: {\n title: \"Attachment unavailable\",\n hint: \"Attach the file again or continue without it.\",\n },\n request_failed: {\n title: \"Assistant could not complete request\",\n hint: \"You can continue with another message.\",\n },\n },\n threads: {\n newChat: \"New chat\",\n history: \"Chat history\",\n exportSupportBundle: \"Export support bundle\",\n recent: \"Recent chats\",\n search: \"Search chats\",\n searching: \"Searching older chats…\",\n noMatches: \"No matching chats\",\n loadOlder: \"Load older chats\",\n loadingOlder: \"Loading older chats…\",\n automaticTitle: \"Use automatic title\",\n automaticShort: \"Auto\",\n rename: \"Rename {title}\",\n renameTitle: \"Rename chat\",\n delete: \"Delete {title}\",\n deleteTitle: \"Delete chat\",\n deleteConfirm: 'Delete \"{title}\" and its attachments?',\n },\n supportBundle: {\n title: \"Export support bundle\",\n description:\n \"Choose which broad data categories to include. The ZIP is created and downloaded in this browser.\",\n close: \"Close export dialog\",\n preparing: \"Preparing diagnostic data…\",\n preparationFailed: \"The support bundle could not be prepared\",\n generationFailed: \"The support bundle could not be generated.\",\n chooseData: \"Data to include\",\n core: {\n title: \"Core technical diagnostics (always included)\",\n description:\n \"Request and turn identifiers, timing, status and error details, counters, and availability information.\",\n },\n categories: {\n conversation: {\n title: \"Conversation and agent activity\",\n description: \"Messages, visible reasoning, tool activity, and apply results.\",\n },\n survey: {\n title: \"Survey data\",\n description: \"The submitted survey and a snapshot captured when this dialog opened.\",\n },\n attachments: {\n title: \"Attachments\",\n description: \"Available source PDFs and images from this browser session.\",\n },\n },\n sensitiveNote:\n \"Conversation, reasoning, surveys, and attachments can contain sensitive research or authoring data. Deselect a category if you do not want to share it.\",\n estimatedSize: \"Estimated ZIP size\",\n emailWarning: \"This may be too large for some email providers.\",\n tooLarge: \"The selection is too large. Deselect a category before downloading.\",\n unavailable: \"{count} diagnostic component is unavailable or was truncated.\",\n unavailablePlural: \"{count} diagnostic components are unavailable or were truncated.\",\n localOnly:\n \"Nothing is sent automatically. You decide whether and how to share the downloaded ZIP.\",\n download: \"Download support bundle\",\n downloadAgain: \"Download again\",\n downloaded: \"Downloaded {filename}. Attach it manually when contacting support.\",\n openEmail: \"Open email draft\",\n supportDetails: \"Support details to include with your request\",\n copyDetails: \"Copy support details\",\n detailsCopied: \"Support details copied\",\n copyDetailsFailed: \"The support details could not be copied. Select and copy them manually.\",\n },\n};\n","import type { LocalizationMessages } from \"@case-framework/ui-localization\";\n\nexport const surveyAssistantNlMessages: LocalizationMessages = {\n panel: {\n ariaLabel: \"Surveyassistent\",\n title: \"Assistent\",\n loadingChats: \"Chats laden\",\n controlsUnavailable: \"Bediening van de assistent niet beschikbaar\",\n },\n empty: {\n title: \"Waar werk je aan?\",\n description:\n \"Maak, controleer of verbeter je survey. Beschrijf wat je nodig hebt of kies een van deze opties.\",\n newSurveyTitle: \"Maak iets met de assistent\",\n newSurveyDescription:\n \"Beschrijf de survey die je nodig hebt, deel een briefing of plan samen de juiste vragen.\",\n },\n quickActions: {\n draftSurvey: {\n label: \"Een survey opstellen\",\n description: \"Maak een eerste versie vanuit je doelen\",\n prompt:\n \"Help me een eerste versie van een nieuwe survey te maken. Vraag me vóór het opstellen naar het onderwerp, de doelgroep en de doelen.\",\n },\n useBrief: {\n label: \"Gebruik een briefing of notities\",\n description: \"Zet vereisten om in een survey\",\n prompt:\n \"Help me een briefing of verzameling notities om te zetten in een survey. Vraag me de tekst te plakken of het document toe te voegen.\",\n },\n planSurvey: {\n label: \"Plan de vragen\",\n description: \"Schets eerst de structuur\",\n prompt:\n \"Help me de vragen en structuur voor een nieuwe survey te plannen voordat we die opstellen.\",\n },\n review: {\n label: \"Survey controleren\",\n description: \"Problemen vinden en verbeteringen voorstellen\",\n prompt:\n \"Voer een deterministische controle van de huidige survey uit, inclusief de geldigheid van expressieverwijzingen, beoordeel daarna de kwaliteit en stel verbeteringen voor.\",\n },\n create: {\n label: \"Nieuwe vraag\",\n description: \"Een vraag opstellen en toevoegen\",\n prompt: \"Help me een nieuwe surveyvraag te maken.\",\n },\n refine: {\n label: \"Formulering verbeteren\",\n description: \"Tekst voor respondenten aanscherpen\",\n prompt: \"Stel verbeteringen voor voor de tekst die respondenten zien.\",\n },\n refineSelection: {\n label: \"Geselecteerd item verbeteren\",\n description: \"Scherp de formulering in context aan\",\n prompt:\n \"Stel verbeteringen voor voor de respondentgerichte formulering van het geselecteerde item.\",\n },\n },\n input: {\n placeholder: \"Vraag iets over de survey...\",\n attachFiles: \"Een pdf-, png- of jpg-bestand toevoegen\",\n dropFiles: \"Sleep een pdf-, png- of jpg-bestand hierheen om het toe te voegen\",\n supportedFiles: \"Ondersteund: pdf, png en jpg. Exporteer Word-documenten als pdf.\",\n unsupportedFiles:\n \"{filenames} kan niet worden toegevoegd. Ondersteunde formaten: pdf, png en jpg.\",\n wordFilesUnsupported:\n \"Word-documenten worden niet ondersteund. Exporteer {filenames} als pdf en voeg daarna de pdf toe.\",\n removeFile: \"{filename} verwijderen\",\n send: \"Bericht verzenden\",\n stop: \"Antwoord stoppen\",\n model: \"Assistentmodel\",\n defaultModel: \"Standaardmodel\",\n },\n conversation: {\n loadEarlier: \"Eerdere berichten laden\",\n loadingEarlier: \"Eerdere berichten laden…\",\n noMessages: \"Nog geen berichten\",\n startConversation: \"Start een gesprek om hier berichten te zien\",\n scrollToLatest: \"Naar het nieuwste bericht scrollen\",\n working: \"Bezig...\",\n stopped: \"Gestopt\",\n incomplete: \"Antwoord onderbroken\",\n },\n turn: {\n failedTitle: \"De assistent heeft deze beurt niet voltooid.\",\n abortedTitle: \"De beurt is gestopt.\",\n reasons: {\n clientAbort: \"Het verzoek is door de client gestopt.\",\n firstResponseTimeout: \"Er kwam geen betekenisvol antwoord vóór de eerste tijdslimiet.\",\n idleTimeout: \"De assistent produceerde geen activiteit meer.\",\n maxDuration: \"De maximale uitvoertijd van één uur is bereikt.\",\n maxSteps: \"De assistent bereikte de limiet voor hulpmiddelstappen voordat hij klaar was.\",\n lengthLimit: \"Het model bereikte de maximale antwoordlengte.\",\n contentFilter: \"De provider stopte het antwoord vanwege het inhoudsbeleid.\",\n providerError: \"De modelprovider meldde een fout.\",\n streamError: \"De antwoordstream eindigde met een fout.\",\n incompleteResponse: \"Het antwoord eindigde zonder normale voltooiing.\",\n unknown: \"Het antwoord eindigde voordat het voltooid was.\",\n },\n },\n status: {\n applying: \"Wijzigingen toepassen\",\n applied: \"Wijzigingen toegepast\",\n stopped: \"Gestopt\",\n attention: \"Aandacht nodig\",\n ready: \"Gereed\",\n connecting: \"Verbinding maken met de assistent\",\n thinking: \"Verzoek doordenken\",\n writing: \"Antwoord schrijven\",\n working: \"Aan je verzoek werken\",\n },\n activity: {\n label: \"Activiteit\",\n working: \"Bezig...\",\n workedFor: \"{duration} gewerkt\",\n technicalDetails: \"Technische details tonen\",\n hideTechnicalDetails: \"Technische details verbergen\",\n waitingApproval: \"Wachten op goedkeuring\",\n approvalReceived: \"Goedkeuring ontvangen\",\n continuingApproval: \"Doorgaan na goedkeuring\",\n preparingStep: \"Volgende stap voorbereiden\",\n usingResult: \"Resultaat gebruiken\",\n continuingWithoutStep: \"Doorgaan zonder die stap\",\n recoveringToolError: \"Herstellen van een fout in een hulpmiddel\",\n skipped: \"Overgeslagen\",\n failed: \"Mislukt\",\n workingShort: \"Bezig\",\n done: \"Gereed\",\n stopped: \"Gestopt\",\n expressionChange: \"Expressiewijziging\",\n surveyChange: \"Surveywijziging\",\n genericActive: \"Werken met de survey\",\n genericComplete: \"Surveystap voltooid\",\n failedSuffix: \"{name} mislukt\",\n skippedSuffix: \"{name} overgeslagen\",\n tools: {\n survey_inspect: { active: \"Survey controleren\", complete: \"Survey gecontroleerd\" },\n survey_change: { active: \"Wijziging voorbereiden\", complete: \"Wijziging voorbereid\" },\n survey_expression: {\n active: \"Expressie voorbereiden\",\n complete: \"Expressie voorbereid\",\n },\n survey_authoring_reference: {\n active: \"Auteursrichtlijnen controleren\",\n complete: \"Auteursrichtlijnen gecontroleerd\",\n },\n survey_attachment: { active: \"Bijlage openen\", complete: \"Bijlage geopend\" },\n recall: {\n active: \"Eerder gesprek controleren\",\n complete: \"Eerder gesprek gecontroleerd\",\n },\n },\n },\n changes: {\n applied: \"Wijziging toegepast\",\n stale: \"Wijziging niet toegepast\",\n failed: \"Wijziging kon niet worden toegepast\",\n prepared: \"Wijziging voorbereid\",\n rejected: \"Wijziging kon niet worden voorbereid\",\n operationCount: \"{count} bewerking\",\n operationCountPlural: \"{count} bewerkingen\",\n issueCount: \"{count} probleem\",\n issueCountPlural: \"{count} problemen\",\n warningCount: \"{count} waarschuwing\",\n warningCountPlural: \"{count} waarschuwingen\",\n incompleteTitle: \"De gevraagde wijzigingen zijn niet voltooid.\",\n blocked:\n \"Er zijn geen surveywijzigingen toegepast omdat {count} afgewezen wijzigingsvoorstel nog niet is opgelost.\",\n blockedPlural:\n \"Er zijn geen surveywijzigingen toegepast omdat {count} afgewezen wijzigingsvoorstellen nog niet zijn opgelost.\",\n partial: \"{applied} wijzigingsset is toegepast; {failed} kon niet worden toegepast.\",\n partialPlural:\n \"{applied} wijzigingssets zijn toegepast; {failed} konden niet worden toegepast.\",\n reviewBeforeRetry:\n \"Controleer de bovenstaande wijzigingsstappen voordat je het opnieuw probeert.\",\n },\n errors: {\n dismiss: \"Sluiten\",\n dismissAssistant: \"Assistentfout sluiten\",\n retry: \"Opnieuw proberen\",\n exportDetails: \"Details exporteren\",\n showProviderDetails: \"Volledig providerbericht tonen\",\n hideProviderDetails: \"Providerbericht verbergen\",\n upstreamStatus: \"Providerstatus {status}\",\n providerRequestId: \"Verzoek {requestId}\",\n fallbackDetail: \"Er is tijdens de vorige beurt een fout opgetreden.\",\n model_unavailable: {\n title: \"Model niet beschikbaar\",\n hint: \"Selecteer een model dat beschikbaar is voor dit account en verzend het bericht opnieuw.\",\n },\n rate_limited: {\n title: \"Assistent tijdelijk bezet\",\n hint: \"Wacht even en verzend het bericht daarna opnieuw.\",\n },\n authorization_failed: {\n title: \"Assistent niet beschikbaar\",\n hint: \"Controleer je toegang of meld je opnieuw aan voordat je het opnieuw probeert.\",\n },\n attachment_unavailable: {\n title: \"Bijlage niet beschikbaar\",\n hint: \"Voeg het bestand opnieuw toe of ga verder zonder het bestand.\",\n },\n request_failed: {\n title: \"Assistent kon het verzoek niet voltooien\",\n hint: \"Je kunt doorgaan met een nieuw bericht.\",\n },\n },\n threads: {\n newChat: \"Nieuwe chat\",\n history: \"Chatgeschiedenis\",\n exportSupportBundle: \"Supportbundel exporteren\",\n recent: \"Recente chats\",\n search: \"Chats zoeken\",\n searching: \"Oudere chats zoeken…\",\n noMatches: \"Geen overeenkomende chats\",\n loadOlder: \"Oudere chats laden\",\n loadingOlder: \"Oudere chats laden…\",\n automaticTitle: \"Automatische titel gebruiken\",\n automaticShort: \"Automatisch\",\n rename: \"{title} hernoemen\",\n renameTitle: \"Chat hernoemen\",\n delete: \"{title} verwijderen\",\n deleteTitle: \"Chat verwijderen\",\n deleteConfirm: '\"{title}\" en de bijlagen verwijderen?',\n },\n supportBundle: {\n title: \"Supportbundel exporteren\",\n description:\n \"Kies welke brede gegevenscategorieën worden opgenomen. Het ZIP-bestand wordt in deze browser gemaakt en gedownload.\",\n close: \"Exportvenster sluiten\",\n preparing: \"Diagnostische gegevens voorbereiden…\",\n preparationFailed: \"De supportbundel kon niet worden voorbereid\",\n generationFailed: \"De supportbundel kon niet worden gemaakt.\",\n chooseData: \"Op te nemen gegevens\",\n core: {\n title: \"Technische basisgegevens (altijd opgenomen)\",\n description:\n \"Verzoek- en beurt-ID's, timing, status- en foutdetails, aantallen en beschikbaarheid.\",\n },\n categories: {\n conversation: {\n title: \"Gesprek en agentactiviteit\",\n description:\n \"Berichten, zichtbare redenering, hulpmiddelactiviteit en toepassingsresultaten.\",\n },\n survey: {\n title: \"Surveygegevens\",\n description: \"De verzonden survey en een momentopname van toen dit venster werd geopend.\",\n },\n attachments: {\n title: \"Bijlagen\",\n description: \"Beschikbare bron-pdf's en afbeeldingen uit deze browsersessie.\",\n },\n },\n sensitiveNote:\n \"Gesprek, redenering, surveys en bijlagen kunnen gevoelige onderzoeks- of auteursgegevens bevatten. Schakel een categorie uit als je die niet wilt delen.\",\n estimatedSize: \"Geschatte ZIP-grootte\",\n emailWarning: \"Dit bestand kan te groot zijn voor sommige e-mailproviders.\",\n tooLarge: \"De selectie is te groot. Schakel een categorie uit voordat je downloadt.\",\n unavailable: \"{count} diagnostisch onderdeel is niet beschikbaar of is ingekort.\",\n unavailablePlural: \"{count} diagnostische onderdelen zijn niet beschikbaar of zijn ingekort.\",\n localOnly:\n \"Er wordt niets automatisch verzonden. Je bepaalt zelf of en hoe je het gedownloade ZIP-bestand deelt.\",\n download: \"Supportbundel downloaden\",\n downloadAgain: \"Opnieuw downloaden\",\n downloaded:\n \"{filename} is gedownload. Voeg het handmatig toe wanneer je contact opneemt met support.\",\n openEmail: \"E-mailconcept openen\",\n supportDetails: \"Supportgegevens voor je verzoek\",\n copyDetails: \"Supportgegevens kopiëren\",\n detailsCopied: \"Supportgegevens gekopieerd\",\n copyDetailsFailed:\n \"De supportgegevens konden niet worden gekopieerd. Selecteer en kopieer ze handmatig.\",\n },\n};\n","\"use client\";\n\nimport {\n createLocalizationTranslator,\n mergeLocalizationCatalogs,\n type LocalizationCatalog,\n type LocalizationTranslate,\n} from \"@case-framework/ui-localization\";\nimport { createContext, useContext, useMemo, type ReactNode } from \"react\";\nimport { surveyAssistantEnMessages } from \"./localizations/en\";\nimport { surveyAssistantNlMessages } from \"./localizations/nl\";\n\nexport { surveyAssistantEnMessages } from \"./localizations/en\";\nexport { surveyAssistantNlMessages } from \"./localizations/nl\";\n\nexport const defaultSurveyAssistantLocalizations: LocalizationCatalog = {\n en: surveyAssistantEnMessages,\n nl: surveyAssistantNlMessages,\n};\n\nconst SurveyAssistantLocalizationContext = createContext<LocalizationTranslate | null>(null);\n\nexport interface SurveyAssistantLocalizationProviderProps {\n children: ReactNode;\n language?: string;\n localizations?: LocalizationCatalog;\n}\n\nexport const SurveyAssistantLocalizationProvider = ({\n children,\n language = \"en\",\n localizations,\n}: SurveyAssistantLocalizationProviderProps) => {\n const translate = useMemo(\n () =>\n createLocalizationTranslator({\n fallbackLocale: \"en\",\n locale: language,\n localizations: mergeLocalizationCatalogs(\n defaultSurveyAssistantLocalizations,\n localizations,\n ),\n onMissing: (key, locale) =>\n console.log(\n `[SurveyAssistant] Missing localization for key \"${key}\" in language \"${locale}\".`,\n ),\n }),\n [language, localizations],\n );\n\n return (\n <SurveyAssistantLocalizationContext.Provider value={translate}>\n {children}\n </SurveyAssistantLocalizationContext.Provider>\n );\n};\n\nexport const useSurveyAssistantTranslation = (): LocalizationTranslate => {\n const translate = useContext(SurveyAssistantLocalizationContext);\n if (!translate) {\n throw new Error(\n \"useSurveyAssistantTranslation must be used within SurveyAssistantLocalizationProvider.\",\n );\n }\n return translate;\n};\n","\"use client\";\n\nimport { Collapsible, CollapsibleContent, CollapsibleTrigger } from \"./collapsible\";\nimport { cn } from \"../utils\";\nimport { useControllableState } from \"@radix-ui/react-use-controllable-state\";\nimport { BrainIcon, ChevronDownIcon, DotIcon, type LucideIcon } from \"lucide-react\";\nimport type { ComponentProps, ReactNode } from \"react\";\nimport {\n createContext,\n memo,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\n\nimport { Shimmer } from \"./shimmer\";\nimport { useSurveyAssistantTranslation } from \"../localization\";\n\ninterface ChainOfThoughtContextValue {\n isOpen: boolean;\n setIsOpen: (open: boolean) => void;\n isStreaming: boolean;\n duration: number | undefined;\n}\n\nconst ChainOfThoughtContext = createContext<ChainOfThoughtContextValue | null>(null);\n\nexport const useChainOfThought = () => {\n const context = useContext(ChainOfThoughtContext);\n if (!context) {\n throw new Error(\"ChainOfThought components must be used within ChainOfThought\");\n }\n return context;\n};\n\nexport type ChainOfThoughtProps = ComponentProps<typeof Collapsible> & {\n isStreaming?: boolean;\n defaultOpen?: boolean;\n defaultDuration?: number;\n duration?: number;\n autoClose?: boolean;\n};\n\nconst AUTO_CLOSE_DELAY = 1000;\nconst MS_IN_S = 1000;\n\nconst formatDuration = (durationSeconds: number) => {\n const hours = Math.floor(durationSeconds / 3600);\n const minutes = Math.floor((durationSeconds % 3600) / 60);\n const seconds = durationSeconds % 60;\n\n if (hours > 0) return `${hours}h ${minutes}m`;\n if (minutes > 0) return seconds > 0 ? `${minutes}m ${seconds}s` : `${minutes}m`;\n return `${seconds}s`;\n};\n\nexport const ChainOfThought = memo(\n ({\n className,\n isStreaming = false,\n open,\n defaultOpen,\n defaultDuration,\n onOpenChange,\n duration: durationProp,\n autoClose = true,\n children,\n ...props\n }: ChainOfThoughtProps) => {\n const resolvedDefaultOpen = defaultOpen ?? isStreaming;\n // Track if defaultOpen was explicitly set to false (to prevent auto-open)\n const isExplicitlyClosed = defaultOpen === false;\n\n const [isOpen, setIsOpen] = useControllableState<boolean>({\n defaultProp: resolvedDefaultOpen,\n onChange: onOpenChange,\n prop: open,\n });\n const [duration, setDuration] = useControllableState<number | undefined>({\n defaultProp: defaultDuration,\n prop: durationProp,\n });\n\n const hasEverStreamedRef = useRef(isStreaming);\n const [hasAutoClosed, setHasAutoClosed] = useState(false);\n const startTimeRef = useRef<number | null>(null);\n\n // Track when streaming starts and compute duration\n useEffect(() => {\n if (isStreaming) {\n hasEverStreamedRef.current = true;\n if (startTimeRef.current === null) {\n startTimeRef.current = Date.now();\n }\n } else if (startTimeRef.current !== null) {\n setDuration(Math.ceil((Date.now() - startTimeRef.current) / MS_IN_S));\n startTimeRef.current = null;\n }\n }, [isStreaming, setDuration]);\n\n // Auto-open when streaming starts (unless explicitly closed)\n useEffect(() => {\n if (isStreaming && !isOpen && !isExplicitlyClosed) {\n setIsOpen(true);\n }\n }, [isStreaming, isOpen, setIsOpen, isExplicitlyClosed]);\n\n // Auto-close when streaming ends (once only, and only if it ever streamed)\n useEffect(() => {\n if (autoClose && hasEverStreamedRef.current && !isStreaming && isOpen && !hasAutoClosed) {\n const timer = setTimeout(() => {\n setIsOpen(false);\n setHasAutoClosed(true);\n }, AUTO_CLOSE_DELAY);\n\n return () => clearTimeout(timer);\n }\n }, [autoClose, isStreaming, isOpen, setIsOpen, hasAutoClosed]);\n\n const handleOpenChange = useCallback(\n (newOpen: boolean) => {\n setIsOpen(newOpen);\n },\n [setIsOpen],\n );\n\n const contextValue = useMemo(\n () => ({ duration, isOpen, isStreaming, setIsOpen }),\n [duration, isOpen, isStreaming, setIsOpen],\n );\n\n return (\n <ChainOfThoughtContext.Provider value={contextValue}>\n <Collapsible\n className={cn(\"not-prose w-full\", className)}\n onOpenChange={handleOpenChange}\n open={isOpen}\n {...props}\n >\n {children}\n </Collapsible>\n </ChainOfThoughtContext.Provider>\n );\n },\n);\n\nexport type ChainOfThoughtHeaderProps = ComponentProps<typeof CollapsibleTrigger> & {\n getThinkingMessage?: (isStreaming: boolean, duration?: number) => ReactNode;\n};\n\nexport const ChainOfThoughtHeader = memo(\n ({ className, children, getThinkingMessage, ...props }: ChainOfThoughtHeaderProps) => {\n const { isOpen, isStreaming, duration } = useChainOfThought();\n const t = useSurveyAssistantTranslation();\n const defaultThinkingMessage = isStreaming ? (\n <Shimmer duration={1}>{t(\"activity.working\")}</Shimmer>\n ) : duration === undefined ? (\n <span>{t(\"activity.label\")}</span>\n ) : (\n <span>{t(\"activity.workedFor\", { duration: formatDuration(duration) })}</span>\n );\n\n return (\n <CollapsibleTrigger\n className={cn(\n \"flex w-full items-center gap-1.5 text-muted-foreground text-sm transition-colors hover:text-foreground\",\n className,\n )}\n {...props}\n >\n <BrainIcon className=\"size-3.5 shrink-0\" />\n <span className=\"flex-1 text-left\">\n {children ?? getThinkingMessage?.(isStreaming, duration) ?? defaultThinkingMessage}\n </span>\n <ChevronDownIcon\n className={cn(\n \"size-3.5 shrink-0 transition-transform\",\n isOpen ? \"rotate-180\" : \"rotate-0\",\n )}\n />\n </CollapsibleTrigger>\n );\n },\n);\n\nexport type ChainOfThoughtContentProps = ComponentProps<typeof CollapsibleContent>;\n\nexport const ChainOfThoughtContent = memo(({ className, ...props }: ChainOfThoughtContentProps) => (\n <CollapsibleContent\n className={cn(\n \"mt-2\",\n \"data-[state=closed]:fade-out-0 data-[state=closed]:slide-out-to-top-2 data-[state=open]:slide-in-from-top-2 outline-none data-[state=closed]:animate-out data-[state=open]:animate-in\",\n className,\n )}\n {...props}\n />\n));\n\nexport type ChainOfThoughtStepProps = ComponentProps<\"div\"> & {\n icon?: LucideIcon;\n label: ReactNode;\n description?: ReactNode;\n result?: ReactNode;\n status?: \"complete\" | \"active\" | \"pending\";\n isLast?: boolean;\n};\n\nconst stepStatusStyles = {\n complete: \"text-muted-foreground\",\n active: \"text-foreground\",\n pending: \"text-muted-foreground/50\",\n} as const;\n\nexport const ChainOfThoughtStep = memo(\n ({\n className,\n icon: Icon = DotIcon,\n label,\n description,\n result,\n status = \"complete\",\n isLast = false,\n children,\n ...props\n }: ChainOfThoughtStepProps) => (\n <div\n className={cn(\n \"fade-in-0 slide-in-from-top-2 relative animate-in text-xs\",\n isLast ? \"pb-0\" : \"pb-2.5\",\n stepStatusStyles[status],\n className,\n )}\n {...props}\n >\n <div className=\"flex gap-2\">\n <div className=\"relative z-10 mt-0.5 shrink-0 bg-background\">\n <Icon className=\"size-3.5\" />\n </div>\n <div className=\"min-w-0 flex-1\">\n <div className=\"wrap-break-word\">{label}</div>\n {description && <div className=\"mt-1.5 text-muted-foreground text-xs\">{description}</div>}\n </div>\n </div>\n {result && <div className=\"relative mt-1.5 ml-[22px]\">{result}</div>}\n {children && <div className=\"mt-1.5 ml-[22px] space-y-1.5\">{children}</div>}\n </div>\n ),\n);\n\nChainOfThought.displayName = \"ChainOfThought\";\nChainOfThoughtHeader.displayName = \"ChainOfThoughtHeader\";\nChainOfThoughtContent.displayName = \"ChainOfThoughtContent\";\nChainOfThoughtStep.displayName = \"ChainOfThoughtStep\";\n","import { cva, type VariantProps } from \"class-variance-authority\";\nimport { Slot } from \"radix-ui\";\nimport type { ComponentProps } from \"react\";\nimport { cn } from \"../utils\";\n\nconst buttonVariants = cva(\n \"inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm font-medium whitespace-nowrap transition-all outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground hover:bg-primary/90\",\n secondary: \"bg-secondary text-secondary-foreground hover:bg-secondary/80\",\n ghost: \"hover:bg-muted hover:text-foreground\",\n },\n size: {\n default: \"h-9 px-4 py-2\",\n icon: \"size-9\",\n \"icon-sm\": \"size-8\",\n },\n },\n defaultVariants: { variant: \"default\", size: \"default\" },\n },\n);\n\nexport const Button = ({\n className,\n variant = \"default\",\n size = \"default\",\n asChild = false,\n ...props\n}: ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean;\n }) => {\n const Component = asChild ? Slot.Root : \"button\";\n return <Component className={cn(buttonVariants({ variant, size, className }))} {...props} />;\n};\n","\"use client\";\n\nimport { Button } from \"./button\";\nimport { cn } from \"../utils\";\nimport { ArrowDownIcon } from \"lucide-react\";\nimport type { ComponentProps, ReactNode } from \"react\";\nimport { useCallback } from \"react\";\nimport { StickToBottom, useStickToBottomContext } from \"use-stick-to-bottom\";\nimport { useSurveyAssistantTranslation } from \"../localization\";\n\nexport type ConversationProps = ComponentProps<typeof StickToBottom>;\n\nexport const Conversation = ({ className, ...props }: ConversationProps) => (\n <StickToBottom\n className={cn(\"relative min-h-0 flex-1 overflow-y-hidden\", className)}\n initial=\"smooth\"\n role=\"log\"\n resize=\"smooth\"\n {...props}\n />\n);\n\nexport type ConversationContentProps = ComponentProps<typeof StickToBottom.Content>;\n\nexport const ConversationContent = ({ className, ...props }: ConversationContentProps) => (\n <StickToBottom.Content className={cn(\"flex flex-col gap-8 p-4\", className)} {...props} />\n);\n\nexport type ConversationEmptyStateProps = ComponentProps<\"div\"> & {\n title?: string;\n description?: string;\n icon?: ReactNode;\n};\n\nexport const ConversationEmptyState = ({\n className,\n title,\n description,\n icon,\n children,\n ...props\n}: ConversationEmptyStateProps) => {\n const t = useSurveyAssistantTranslation();\n const resolvedTitle = title ?? t(\"conversation.noMessages\");\n const resolvedDescription = description ?? t(\"conversation.startConversation\");\n\n return (\n <div\n className={cn(\n \"flex size-full flex-col items-center justify-center gap-3 p-8 text-center\",\n className,\n )}\n {...props}\n >\n {children ?? (\n <>\n {icon && <div className=\"text-muted-foreground\">{icon}</div>}\n <div className=\"space-y-1\">\n <h3 className=\"font-medium text-sm\">{resolvedTitle}</h3>\n {resolvedDescription && (\n <p className=\"text-muted-foreground text-sm\">{resolvedDescription}</p>\n )}\n </div>\n </>\n )}\n </div>\n );\n};\n\nexport type ConversationScrollButtonProps = ComponentProps<typeof Button>;\n\nexport const ConversationScrollButton = ({\n className,\n ...props\n}: ConversationScrollButtonProps) => {\n const { isAtBottom, scrollToBottom } = useStickToBottomContext();\n const t = useSurveyAssistantTranslation();\n\n const handleScrollToBottom = useCallback(() => {\n scrollToBottom();\n }, [scrollToBottom]);\n\n return (\n !isAtBottom && (\n <Button\n className={cn(\n \"absolute left-1/2 z-10 size-8 -translate-x-1/2 rounded-full border border-background/60 bg-foreground text-background shadow-lg ring-1 ring-border/50 hover:bg-foreground/85 hover:text-background\",\n className,\n )}\n aria-label={t(\"conversation.scrollToLatest\")}\n onClick={handleScrollToBottom}\n size=\"icon-sm\"\n type=\"button\"\n variant=\"secondary\"\n {...props}\n >\n <ArrowDownIcon className=\"size-4\" />\n </Button>\n )\n );\n};\n","\"use client\";\n\nimport { cn } from \"../utils\";\nimport type { UIMessage } from \"ai\";\nimport type { HTMLAttributes } from \"react\";\n\nexport type MessageProps = HTMLAttributes<HTMLDivElement> & {\n from: UIMessage[\"role\"];\n};\n\nexport const Message = ({ className, from, ...props }: MessageProps) => (\n <div\n className={cn(\n \"group flex w-full max-w-[95%] flex-col gap-2\",\n from === \"user\" ? \"ml-auto items-end\" : \"items-start\",\n className,\n )}\n data-role={from}\n {...props}\n />\n);\n\nexport type MessageContentProps = HTMLAttributes<HTMLDivElement>;\n\nexport const MessageContent = ({ children, className, ...props }: MessageContentProps) => (\n <div\n className={cn(\n \"w-fit min-w-0 max-w-full break-words text-sm\",\n \"group-data-[role=user]:whitespace-pre-wrap group-data-[role=user]:rounded-xl group-data-[role=user]:border group-data-[role=user]:border-blue-200/70 group-data-[role=user]:bg-blue-50/80 group-data-[role=user]:px-3 group-data-[role=user]:py-2 group-data-[role=user]:text-foreground group-data-[role=user]:shadow-xs dark:group-data-[role=user]:border-blue-800/60 dark:group-data-[role=user]:bg-blue-950/50\",\n \"group-data-[role=assistant]:text-foreground\",\n className,\n )}\n {...props}\n >\n {children}\n </div>\n);\n\nexport type MessageResponseProps = HTMLAttributes<HTMLDivElement>;\n\nexport const MessageResponse = ({ className, ...props }: MessageResponseProps) => (\n <div className={cn(\"leading-6\", className)} {...props} />\n);\n","\"use client\";\n\nimport { Tooltip as TooltipPrimitive } from \"radix-ui\";\nimport type { ComponentProps } from \"react\";\nimport { cn } from \"../utils\";\n\nexport const TooltipProvider = TooltipPrimitive.Provider;\nexport const Tooltip = TooltipPrimitive.Root;\nexport const TooltipTrigger = TooltipPrimitive.Trigger;\n\nexport const TooltipContent = ({\n className,\n sideOffset = 6,\n ...props\n}: ComponentProps<typeof TooltipPrimitive.Content>) => (\n <TooltipPrimitive.Portal>\n <div className=\"case-survey-assistant case-survey-assistant-portal\">\n <TooltipPrimitive.Content\n className={cn(\n \"z-50 max-w-64 rounded-md bg-foreground px-3 py-1.5 text-center text-background text-xs shadow-md data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:animate-in data-[state=open]:fade-in-0\",\n className,\n )}\n sideOffset={sideOffset}\n {...props}\n />\n </div>\n </TooltipPrimitive.Portal>\n);\n","\"use client\";\n\nimport { cn } from \"../utils\";\nimport {\n isSurveyAssistantAttachmentMediaType,\n SURVEY_ASSISTANT_ATTACHMENT_MEDIA_TYPES,\n} from \"../../protocol/attachments\";\nimport type { ChatStatus, FileUIPart } from \"ai\";\nimport { ArrowUpIcon, FileIcon, PaperclipIcon, SquareIcon, XIcon } from \"lucide-react\";\nimport {\n createContext,\n useCallback,\n useContext,\n useMemo,\n useRef,\n useState,\n type ClipboardEvent,\n type ComponentProps,\n type DragEvent,\n type FormEvent,\n type HTMLAttributes,\n} from \"react\";\nimport { useSurveyAssistantTranslation } from \"../localization\";\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from \"./tooltip\";\n\nconst SUPPORTED_FILE_ACCEPT = [\n \".pdf\",\n \".png\",\n \".jpg\",\n \".jpeg\",\n ...SURVEY_ASSISTANT_ATTACHMENT_MEDIA_TYPES,\n].join(\",\");\n\nexport type UnsupportedAttachmentKind = \"word\" | \"other\";\n\nconst WORD_DOCUMENT_MEDIA_TYPES = new Set([\n \"application/msword\",\n \"application/vnd.ms-word\",\n \"application/vnd.ms-word.document.macroenabled.12\",\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.template\",\n]);\n\nexport const getUnsupportedAttachmentKind = ({\n name,\n type,\n}: Pick<File, \"name\" | \"type\">): UnsupportedAttachmentKind | null => {\n if (isSurveyAssistantAttachmentMediaType(type)) return null;\n if (\n WORD_DOCUMENT_MEDIA_TYPES.has(type.toLowerCase()) ||\n /\\.(?:doc|docm|docx|dot|dotm|dotx)$/i.test(name)\n ) {\n return \"word\";\n }\n return \"other\";\n};\n\nconst formatFileSize = (size: number) => {\n if (size < 1024 * 1024) {\n return `${Math.max(1, Math.round(size / 1024))} KB`;\n }\n\n return `${(size / (1024 * 1024)).toFixed(size < 10 * 1024 * 1024 ? 1 : 0)} MB`;\n};\n\nconst fileToUIPart = async (file: File): Promise<FileUIPart> => {\n const mediaType = file.type || \"application/octet-stream\";\n const bytes = new Uint8Array(await file.arrayBuffer());\n const chunkSize = 0x8000;\n let binary = \"\";\n\n for (let offset = 0; offset < bytes.length; offset += chunkSize) {\n binary += String.fromCharCode(...bytes.subarray(offset, offset + chunkSize));\n }\n\n return {\n type: \"file\",\n mediaType,\n filename: file.name,\n url: `data:${mediaType};base64,${btoa(binary)}`,\n };\n};\n\nexport interface PromptInputMessage {\n text: string;\n files: FileUIPart[];\n}\n\ntype PromptInputContextValue = {\n value: string;\n setValue: (value: string) => void;\n files: File[];\n addFiles: (files: FileList | null) => void;\n removeFile: (index: number) => void;\n unsupportedFiles: Array<{ kind: UnsupportedAttachmentKind; name: string }>;\n};\n\nconst PromptInputContext = createContext<PromptInputContextValue | null>(null);\n\nconst usePromptInput = () => {\n const context = useContext(PromptInputContext);\n if (!context) {\n throw new Error(\"PromptInput components must be used within PromptInput.\");\n }\n return context;\n};\n\nexport type PromptInputProps = Omit<ComponentProps<\"form\">, \"onSubmit\"> & {\n attachmentsDisabled?: boolean;\n onValueChange?: (value: string) => void;\n onSubmit: (\n message: PromptInputMessage,\n event: FormEvent<HTMLFormElement>,\n ) => boolean | void | Promise<boolean | void>;\n value?: string;\n};\n\nexport const PromptInput = ({\n attachmentsDisabled = false,\n children,\n className,\n onDragEnter,\n onDragLeave,\n onDragOver,\n onDrop,\n onPaste,\n onSubmit,\n onValueChange,\n value: controlledValue,\n ...props\n}: PromptInputProps) => {\n const [uncontrolledValue, setUncontrolledValue] = useState(\"\");\n const [files, setFiles] = useState<File[]>([]);\n const [isDraggingFiles, setIsDraggingFiles] = useState(false);\n const [unsupportedFiles, setUnsupportedFiles] = useState<\n Array<{ kind: UnsupportedAttachmentKind; name: string }>\n >([]);\n const fileDragDepthRef = useRef(0);\n const t = useSurveyAssistantTranslation();\n const value = controlledValue ?? uncontrolledValue;\n const setValue = useCallback(\n (nextValue: string) => {\n if (controlledValue === undefined) setUncontrolledValue(nextValue);\n onValueChange?.(nextValue);\n },\n [controlledValue, onValueChange],\n );\n\n const addFiles = useCallback((fileList: FileList | null) => {\n const nextFiles = Array.from(fileList ?? []);\n const supportedFiles = nextFiles.filter((file) => getUnsupportedAttachmentKind(file) === null);\n const rejectedFiles = nextFiles.flatMap((file) => {\n const kind = getUnsupportedAttachmentKind(file);\n return kind ? [{ kind, name: file.name }] : [];\n });\n\n setFiles((currentFiles) => [...currentFiles, ...supportedFiles]);\n setUnsupportedFiles(rejectedFiles);\n }, []);\n\n const removeFile = useCallback((index: number) => {\n setFiles((currentFiles) => currentFiles.filter((_, fileIndex) => fileIndex !== index));\n }, []);\n\n const contextValue = useMemo(\n () => ({\n value,\n setValue,\n files,\n addFiles,\n removeFile,\n unsupportedFiles,\n }),\n [addFiles, files, removeFile, unsupportedFiles, value],\n );\n\n const handleSubmit = useCallback(\n async (event: FormEvent<HTMLFormElement>) => {\n event.preventDefault();\n const text = value.trim();\n if (!text && files.length === 0) {\n return;\n }\n\n const fileUIParts = await Promise.all(files.map(fileToUIPart));\n const accepted = await onSubmit({ text, files: fileUIParts }, event);\n if (accepted === false) return;\n setValue(\"\");\n setFiles([]);\n setUnsupportedFiles([]);\n },\n [files, onSubmit, value],\n );\n\n const isFileDrag = (event: DragEvent<HTMLFormElement>) =>\n event.dataTransfer.types.includes(\"Files\");\n\n const handleDragEnter = (event: DragEvent<HTMLFormElement>) => {\n onDragEnter?.(event);\n if (event.defaultPrevented || !isFileDrag(event)) return;\n\n event.preventDefault();\n fileDragDepthRef.current += 1;\n if (!attachmentsDisabled) setIsDraggingFiles(true);\n };\n\n const handleDragLeave = (event: DragEvent<HTMLFormElement>) => {\n onDragLeave?.(event);\n if (!isFileDrag(event)) return;\n\n fileDragDepthRef.current = Math.max(0, fileDragDepthRef.current - 1);\n if (fileDragDepthRef.current === 0) setIsDraggingFiles(false);\n };\n\n const handleDragOver = (event: DragEvent<HTMLFormElement>) => {\n onDragOver?.(event);\n if (event.defaultPrevented || !isFileDrag(event)) return;\n\n event.preventDefault();\n event.dataTransfer.dropEffect = attachmentsDisabled ? \"none\" : \"copy\";\n };\n\n const handleDrop = (event: DragEvent<HTMLFormElement>) => {\n onDrop?.(event);\n if (!isFileDrag(event)) return;\n\n fileDragDepthRef.current = 0;\n setIsDraggingFiles(false);\n if (event.defaultPrevented) return;\n\n event.preventDefault();\n if (!attachmentsDisabled) addFiles(event.dataTransfer.files);\n };\n\n const handlePaste = (event: ClipboardEvent<HTMLFormElement>) => {\n onPaste?.(event);\n if (event.defaultPrevented || attachmentsDisabled || event.clipboardData.files.length === 0) {\n return;\n }\n\n event.preventDefault();\n addFiles(event.clipboardData.files);\n };\n\n return (\n <PromptInputContext.Provider value={contextValue}>\n <form\n className={cn(\"relative rounded-xl border border-input bg-background\", className)}\n onDragEnter={handleDragEnter}\n onDragLeave={handleDragLeave}\n onDragOver={handleDragOver}\n onDrop={handleDrop}\n onPaste={handlePaste}\n onSubmit={handleSubmit}\n {...props}\n >\n {children}\n {isDraggingFiles && (\n <div className=\"pointer-events-none absolute inset-0 z-10 flex items-center justify-center rounded-[inherit] border-2 border-primary bg-background/90 px-4 text-center font-medium text-sm text-foreground\">\n {t(\"input.dropFiles\")}\n </div>\n )}\n </form>\n </PromptInputContext.Provider>\n );\n};\n\nexport type PromptInputBodyProps = HTMLAttributes<HTMLDivElement>;\n\nexport const PromptInputBody = ({ children, className, ...props }: PromptInputBodyProps) => {\n const { files, removeFile, unsupportedFiles } = usePromptInput();\n const t = useSurveyAssistantTranslation();\n const unsupportedWordFileNames = unsupportedFiles\n .filter((file) => file.kind === \"word\")\n .map((file) => file.name);\n const unsupportedOtherFileNames = unsupportedFiles\n .filter((file) => file.kind === \"other\")\n .map((file) => file.name);\n\n return (\n <div className={cn(\"contents\", className)} {...props}>\n {children}\n {(files.length > 0 || unsupportedFiles.length > 0) && (\n <div className=\"flex flex-wrap gap-2 px-3 pb-2\">\n {files.map((file, index) => (\n <div\n className=\"inline-flex max-w-full items-center gap-2 rounded-md border border-border bg-muted px-2 py-1 text-xs\"\n key={`${file.name}-${file.lastModified}-${index}`}\n >\n <FileIcon className=\"size-3.5 shrink-0 text-muted-foreground\" />\n <span className=\"min-w-0 truncate\">{file.name}</span>\n <span className=\"shrink-0 text-muted-foreground\">{formatFileSize(file.size)}</span>\n <button\n className=\"shrink-0 rounded-sm text-muted-foreground hover:text-foreground\"\n onClick={() => removeFile(index)}\n type=\"button\"\n >\n <XIcon className=\"size-3.5\" />\n <span className=\"sr-only\">{t(\"input.removeFile\", { filename: file.name })}</span>\n </button>\n </div>\n ))}\n {unsupportedWordFileNames.length > 0 && (\n <div className=\"text-destructive text-xs\">\n {t(\"input.wordFilesUnsupported\", {\n filenames: unsupportedWordFileNames.join(\", \"),\n })}\n </div>\n )}\n {unsupportedOtherFileNames.length > 0 && (\n <div className=\"text-destructive text-xs\">\n {t(\"input.unsupportedFiles\", {\n filenames: unsupportedOtherFileNames.join(\", \"),\n })}\n </div>\n )}\n </div>\n )}\n </div>\n );\n};\n\nexport type PromptInputTextareaProps = ComponentProps<\"textarea\">;\n\nexport const PromptInputTextarea = ({\n className,\n onChange,\n onKeyDown,\n ...props\n}: PromptInputTextareaProps) => {\n const { value, setValue } = usePromptInput();\n\n return (\n <textarea\n className={cn(\n \"max-h-40 min-h-20 w-full resize-none bg-transparent px-3 py-2 text-sm outline-none placeholder:text-muted-foreground\",\n className,\n )}\n onChange={(event) => {\n setValue(event.target.value);\n onChange?.(event);\n }}\n onKeyDown={(event) => {\n onKeyDown?.(event);\n if (event.defaultPrevented || event.shiftKey || event.key !== \"Enter\") {\n return;\n }\n event.preventDefault();\n event.currentTarget.form?.requestSubmit();\n }}\n value={value}\n {...props}\n />\n );\n};\n\nexport type PromptInputFooterProps = HTMLAttributes<HTMLDivElement>;\n\nexport const PromptInputFooter = ({ className, ...props }: PromptInputFooterProps) => (\n <div\n className={cn(\"flex items-center gap-2 border-t border-border px-2 py-2\", className)}\n {...props}\n />\n);\n\nexport type PromptInputAttachmentButtonProps = Omit<ComponentProps<\"input\">, \"type\">;\n\nexport const PromptInputAttachmentButton = ({\n accept = SUPPORTED_FILE_ACCEPT,\n className,\n disabled,\n onChange,\n ...props\n}: PromptInputAttachmentButtonProps) => {\n const { addFiles } = usePromptInput();\n const t = useSurveyAssistantTranslation();\n\n return (\n <TooltipProvider delayDuration={300}>\n <Tooltip>\n <TooltipTrigger asChild>\n <label\n className={cn(\n \"inline-flex size-8 cursor-pointer items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-muted hover:text-foreground\",\n disabled && \"pointer-events-none cursor-default opacity-50\",\n className,\n )}\n >\n <PaperclipIcon className=\"size-4\" />\n <span className=\"sr-only\">{t(\"input.attachFiles\")}</span>\n <input\n accept={accept}\n className=\"sr-only\"\n disabled={disabled}\n multiple\n onChange={(event) => {\n addFiles(event.currentTarget.files);\n onChange?.(event);\n event.currentTarget.value = \"\";\n }}\n type=\"file\"\n {...props}\n />\n </label>\n </TooltipTrigger>\n <TooltipContent align=\"start\" side=\"top\">\n {t(\"input.supportedFiles\")}\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n );\n};\n\nexport type PromptInputSubmitProps = ComponentProps<\"button\"> & {\n status?: ChatStatus;\n onStop?: () => void;\n};\n\nexport const PromptInputSubmit = ({\n className,\n status,\n onStop,\n onClick,\n ...props\n}: PromptInputSubmitProps) => {\n const isGenerating = status === \"submitted\" || status === \"streaming\";\n const t = useSurveyAssistantTranslation();\n\n return (\n <button\n className={cn(\n \"inline-flex size-8 items-center justify-center rounded-full bg-foreground text-background transition-opacity hover:opacity-90 disabled:pointer-events-none disabled:opacity-50\",\n className,\n )}\n onClick={(event) => {\n if (isGenerating && onStop) {\n event.preventDefault();\n onStop();\n return;\n }\n onClick?.(event);\n }}\n type=\"submit\"\n {...props}\n >\n {isGenerating ? <SquareIcon className=\"size-3.5\" /> : <ArrowUpIcon className=\"size-4\" />}\n <span className=\"sr-only\">{isGenerating ? t(\"input.stop\") : t(\"input.send\")}</span>\n </button>\n );\n};\n","\"use client\";\n\nimport * as React from \"react\";\nimport { CheckIcon, ChevronDownIcon, ChevronUpIcon } from \"lucide-react\";\nimport { Select as SelectPrimitive } from \"radix-ui\";\n\nimport { cn } from \"../utils\";\n\nfunction Select({ ...props }: React.ComponentProps<typeof SelectPrimitive.Root>) {\n return <SelectPrimitive.Root data-slot=\"select\" {...props} />;\n}\n\nfunction SelectGroup({ ...props }: React.ComponentProps<typeof SelectPrimitive.Group>) {\n return <SelectPrimitive.Group data-slot=\"select-group\" {...props} />;\n}\n\nfunction SelectValue({ ...props }: React.ComponentProps<typeof SelectPrimitive.Value>) {\n return <SelectPrimitive.Value data-slot=\"select-value\" {...props} />;\n}\n\nfunction SelectTrigger({\n className,\n size = \"default\",\n children,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Trigger> & {\n size?: \"sm\" | \"default\";\n}) {\n return (\n <SelectPrimitive.Trigger\n data-slot=\"select-trigger\"\n data-size={size}\n className={cn(\n \"flex w-fit items-center justify-between gap-2 rounded-md border border-input bg-transparent px-3 py-2 text-sm whitespace-nowrap shadow-xs transition-[color,box-shadow] outline-none focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 disabled:cursor-not-allowed disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-destructive/20 data-[placeholder]:text-muted-foreground data-[size=default]:h-9 data-[size=sm]:h-8 *:data-[slot=select-value]:line-clamp-1 *:data-[slot=select-value]:flex *:data-[slot=select-value]:items-center *:data-[slot=select-value]:gap-2 dark:bg-input/30 dark:hover:bg-input/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground\",\n className,\n )}\n {...props}\n >\n {children}\n <SelectPrimitive.Icon asChild>\n <ChevronDownIcon className=\"size-4 opacity-50\" />\n </SelectPrimitive.Icon>\n </SelectPrimitive.Trigger>\n );\n}\n\nfunction SelectContent({\n className,\n children,\n position = \"item-aligned\",\n align = \"center\",\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Content>) {\n return (\n <SelectPrimitive.Portal>\n <div className=\"case-survey-assistant case-survey-assistant-portal\">\n <SelectPrimitive.Content\n data-slot=\"select-content\"\n className={cn(\n \"relative z-50 max-h-(--radix-select-content-available-height) min-w-[8rem] origin-(--radix-select-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-md border bg-popover text-popover-foreground shadow-md data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95\",\n position === \"popper\" &&\n \"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1\",\n className,\n )}\n position={position}\n align={align}\n {...props}\n >\n <SelectScrollUpButton />\n <SelectPrimitive.Viewport\n className={cn(\n \"p-1\",\n position === \"popper\" &&\n \"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)] scroll-my-1\",\n )}\n >\n {children}\n </SelectPrimitive.Viewport>\n <SelectScrollDownButton />\n </SelectPrimitive.Content>\n </div>\n </SelectPrimitive.Portal>\n );\n}\n\nfunction SelectLabel({ className, ...props }: React.ComponentProps<typeof SelectPrimitive.Label>) {\n return (\n <SelectPrimitive.Label\n data-slot=\"select-label\"\n className={cn(\"px-2 py-1.5 text-xs text-muted-foreground\", className)}\n {...props}\n />\n );\n}\n\nfunction SelectItem({\n className,\n children,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Item>) {\n return (\n <SelectPrimitive.Item\n data-slot=\"select-item\"\n className={cn(\n \"relative flex w-full cursor-default items-center gap-2 rounded-sm py-1.5 pr-8 pl-2 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 [&_svg:not([class*='text-'])]:text-muted-foreground *:[span]:last:flex *:[span]:last:items-center *:[span]:last:gap-2\",\n className,\n )}\n {...props}\n >\n <span\n data-slot=\"select-item-indicator\"\n className=\"absolute right-2 flex size-3.5 items-center justify-center\"\n >\n <SelectPrimitive.ItemIndicator>\n <CheckIcon className=\"size-4\" />\n </SelectPrimitive.ItemIndicator>\n </span>\n <SelectPrimitive.ItemText>{children}</SelectPrimitive.ItemText>\n </SelectPrimitive.Item>\n );\n}\n\nfunction SelectSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.Separator>) {\n return (\n <SelectPrimitive.Separator\n data-slot=\"select-separator\"\n className={cn(\"pointer-events-none -mx-1 my-1 h-px bg-border\", className)}\n {...props}\n />\n );\n}\n\nfunction SelectScrollUpButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollUpButton>) {\n return (\n <SelectPrimitive.ScrollUpButton\n data-slot=\"select-scroll-up-button\"\n className={cn(\"flex cursor-default items-center justify-center py-1\", className)}\n {...props}\n >\n <ChevronUpIcon className=\"size-4\" />\n </SelectPrimitive.ScrollUpButton>\n );\n}\n\nfunction SelectScrollDownButton({\n className,\n ...props\n}: React.ComponentProps<typeof SelectPrimitive.ScrollDownButton>) {\n return (\n <SelectPrimitive.ScrollDownButton\n data-slot=\"select-scroll-down-button\"\n className={cn(\"flex cursor-default items-center justify-center py-1\", className)}\n {...props}\n >\n <ChevronDownIcon className=\"size-4\" />\n </SelectPrimitive.ScrollDownButton>\n );\n}\n\nexport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectScrollDownButton,\n SelectScrollUpButton,\n SelectSeparator,\n SelectTrigger,\n SelectValue,\n};\n","\"use client\";\n\nimport type { SurveyAssistantModelOption } from \"../protocol\";\nimport type { ChatStatus } from \"ai\";\nimport { BotIcon } from \"lucide-react\";\nimport type { ComponentProps, Ref } from \"react\";\nimport {\n PromptInput,\n PromptInputAttachmentButton,\n PromptInputBody,\n PromptInputFooter,\n PromptInputSubmit,\n PromptInputTextarea,\n type PromptInputMessage,\n type PromptInputProps,\n} from \"./internal/prompt-input\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"./internal/select\";\nimport { useSurveyAssistantTranslation } from \"./localization\";\nimport { cn } from \"./utils\";\n\ninterface SurveyAssistantModelSelectProps {\n disabled?: boolean;\n modelId?: string;\n models: SurveyAssistantModelOption[];\n onModelChange(modelId: string): void;\n}\n\nconst SurveyAssistantModelSelect = ({\n disabled = false,\n modelId,\n models,\n onModelChange,\n}: SurveyAssistantModelSelectProps) => {\n const t = useSurveyAssistantTranslation();\n const selectedModelLabel =\n models.find((model) => model.id === modelId)?.label ?? modelId ?? t(\"input.defaultModel\");\n\n if (models.length > 1) {\n return (\n <Select disabled={disabled} onValueChange={onModelChange} value={modelId ?? \"\"}>\n <SelectTrigger\n aria-label={t(\"input.model\")}\n className=\"h-8 min-w-0 max-w-48 gap-1.5 border-0 bg-transparent px-2 text-xs shadow-none hover:bg-muted hover:text-foreground focus-visible:ring-1\"\n size=\"sm\"\n title={modelId}\n >\n <BotIcon className=\"size-3.5\" />\n <SelectValue />\n </SelectTrigger>\n <SelectContent\n align=\"end\"\n className=\"min-w-52 rounded-lg border-border p-0 shadow-lg\"\n position=\"popper\"\n >\n {models.map((model) => (\n <SelectItem\n className=\"min-h-9 rounded-md px-2 py-2 text-xs focus:bg-muted\"\n key={model.id}\n title={model.id}\n value={model.id}\n >\n {model.label}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n );\n }\n\n return (\n <div\n className=\"flex h-8 min-w-0 max-w-48 items-center gap-1.5 px-2 text-muted-foreground text-xs\"\n title={modelId}\n >\n <BotIcon className=\"size-3.5 shrink-0\" />\n <span className=\"truncate\">{selectedModelLabel}</span>\n </div>\n );\n};\n\nexport interface SurveyAssistantPromptInputProps {\n attachmentsDisabled?: boolean;\n attachmentButtonClassName?: string;\n className?: string;\n disabled?: boolean;\n footerClassName?: string;\n formProps?: Omit<\n PromptInputProps,\n \"attachmentsDisabled\" | \"children\" | \"className\" | \"onSubmit\" | \"onValueChange\" | \"value\"\n >;\n modelDisabled?: boolean;\n modelId?: string;\n models: SurveyAssistantModelOption[];\n onModelChange(modelId: string): void;\n onStop?(): void;\n onSubmit: PromptInputProps[\"onSubmit\"];\n onValueChange?(value: string): void;\n placeholder?: string;\n status?: ChatStatus;\n textareaClassName?: string;\n textareaProps?: Omit<\n ComponentProps<\"textarea\">,\n \"className\" | \"disabled\" | \"placeholder\" | \"ref\"\n >;\n textareaRef?: Ref<HTMLTextAreaElement>;\n value?: string;\n}\n\nexport const SurveyAssistantPromptInput = ({\n attachmentsDisabled = false,\n attachmentButtonClassName,\n className,\n disabled = false,\n footerClassName,\n formProps,\n modelDisabled = false,\n modelId,\n models,\n onModelChange,\n onStop,\n onSubmit,\n onValueChange,\n placeholder,\n status,\n textareaClassName,\n textareaProps,\n textareaRef,\n value,\n}: SurveyAssistantPromptInputProps) => {\n const t = useSurveyAssistantTranslation();\n const canStop = Boolean(onStop) && (status === \"submitted\" || status === \"streaming\");\n\n return (\n <PromptInput\n {...formProps}\n attachmentsDisabled={attachmentsDisabled || disabled}\n className={cn(\"rounded-xl border-border bg-background shadow-sm\", className)}\n onSubmit={onSubmit}\n onValueChange={onValueChange}\n value={value}\n >\n <PromptInputBody>\n <PromptInputTextarea\n {...textareaProps}\n className={cn(\n \"min-h-20 px-3 py-2 disabled:cursor-not-allowed disabled:text-muted-foreground\",\n textareaClassName,\n )}\n disabled={disabled}\n placeholder={placeholder ?? t(\"input.placeholder\")}\n ref={textareaRef}\n />\n </PromptInputBody>\n <PromptInputFooter\n className={cn(\"justify-between border-0 px-1.5 pt-0 pb-1.5\", footerClassName)}\n >\n <PromptInputAttachmentButton\n className={attachmentButtonClassName}\n disabled={attachmentsDisabled || disabled}\n />\n <div className=\"flex min-w-0 items-center justify-end gap-1\">\n <SurveyAssistantModelSelect\n disabled={disabled || modelDisabled}\n modelId={modelId}\n models={models}\n onModelChange={onModelChange}\n />\n <PromptInputSubmit disabled={disabled && !canStop} onStop={onStop} status={status} />\n </div>\n </PromptInputFooter>\n </PromptInput>\n );\n};\n\nexport type { PromptInputMessage as SurveyAssistantPromptInputMessage };\n","import { getSurveyAssistantEmbeddedBinaryMarker } from \"../../protocol\";\n\nconst formatOmittedLength = (length: number) => length.toLocaleString(\"en-US\");\n\nexport const stringifyToolTechnicalDetails = (value: unknown): string =>\n JSON.stringify(\n value,\n function redactEmbeddedBinary(this: unknown, key, currentValue) {\n const parent =\n this && typeof this === \"object\" ? (this as Record<string, unknown>) : undefined;\n const marker = getSurveyAssistantEmbeddedBinaryMarker(currentValue, parent, key);\n if (marker?.redacted === \"base64\")\n return `[embedded base64 omitted: ${formatOmittedLength(marker.characters)} characters]`;\n if (marker?.redacted === \"data-url\")\n return `[base64 data URL omitted: ${formatOmittedLength(marker.characters)} characters]`;\n\n return currentValue;\n },\n 2,\n );\n","\"use client\";\n\n/* eslint-disable react-hooks/refs */\n\nimport { Button } from \"./button\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"./select\";\nimport { cn } from \"../utils\";\nimport { CheckIcon, CopyIcon } from \"lucide-react\";\nimport type { ComponentProps, CSSProperties, HTMLAttributes } from \"react\";\nimport {\n createContext,\n memo,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type { BundledLanguage, BundledTheme, HighlighterGeneric, ThemedToken } from \"shiki\";\n\n// Shiki uses bitflags for font styles: 1=italic, 2=bold, 4=underline\n// oxlint-disable-next-line eslint(no-bitwise)\nconst isItalic = (fontStyle: number | undefined) => fontStyle && fontStyle & 1;\n// oxlint-disable-next-line eslint(no-bitwise)\nconst isBold = (fontStyle: number | undefined) => fontStyle && fontStyle & 2;\nconst isUnderline = (fontStyle: number | undefined) =>\n // oxlint-disable-next-line eslint(no-bitwise)\n fontStyle && fontStyle & 4;\n\n// Transform tokens to include pre-computed keys to avoid noArrayIndexKey lint\ninterface KeyedToken {\n token: ThemedToken;\n key: string;\n}\ninterface KeyedLine {\n tokens: KeyedToken[];\n key: string;\n}\n\nconst addKeysToTokens = (lines: ThemedToken[][]): KeyedLine[] =>\n lines.map((line, lineIdx) => ({\n key: `line-${lineIdx}`,\n tokens: line.map((token, tokenIdx) => ({\n key: `line-${lineIdx}-${tokenIdx}`,\n token,\n })),\n }));\n\n// Token rendering component\nconst TokenSpan = ({ token }: { token: ThemedToken }) => (\n <span\n className=\"dark:!bg-[var(--shiki-dark-bg)] dark:!text-[var(--shiki-dark)]\"\n style={\n {\n backgroundColor: token.bgColor,\n color: token.color,\n fontStyle: isItalic(token.fontStyle) ? \"italic\" : undefined,\n fontWeight: isBold(token.fontStyle) ? \"bold\" : undefined,\n textDecoration: isUnderline(token.fontStyle) ? \"underline\" : undefined,\n ...token.htmlStyle,\n } as CSSProperties\n }\n >\n {token.content}\n </span>\n);\n\n// Line number styles using CSS counters\nconst LINE_NUMBER_CLASSES = cn(\n \"block\",\n \"before:content-[counter(line)]\",\n \"before:inline-block\",\n \"before:[counter-increment:line]\",\n \"before:w-8\",\n \"before:mr-4\",\n \"before:text-right\",\n \"before:text-muted-foreground/50\",\n \"before:font-mono\",\n \"before:select-none\",\n);\n\n// Line rendering component\nconst LineSpan = ({\n keyedLine,\n showLineNumbers,\n}: {\n keyedLine: KeyedLine;\n showLineNumbers: boolean;\n}) => (\n <span className={showLineNumbers ? LINE_NUMBER_CLASSES : \"block\"}>\n {keyedLine.tokens.length === 0\n ? \"\\n\"\n : keyedLine.tokens.map(({ token, key }) => <TokenSpan key={key} token={token} />)}\n </span>\n);\n\n// Types\ntype CodeBlockProps = HTMLAttributes<HTMLDivElement> & {\n code: string;\n language: BundledLanguage;\n showLineNumbers?: boolean;\n};\n\ninterface TokenizedCode {\n tokens: ThemedToken[][];\n fg: string;\n bg: string;\n}\n\ninterface CodeBlockContextType {\n code: string;\n}\n\n// Context\nconst CodeBlockContext = createContext<CodeBlockContextType>({\n code: \"\",\n});\n\n// Highlighter cache (singleton per language)\nconst highlighterCache = new Map<\n string,\n Promise<HighlighterGeneric<BundledLanguage, BundledTheme>>\n>();\n\n// Token cache\nconst tokensCache = new Map<string, TokenizedCode>();\n\n// Subscribers for async token updates\nconst subscribers = new Map<string, Set<(result: TokenizedCode) => void>>();\n\nconst getTokensCacheKey = (code: string, language: BundledLanguage) => {\n const start = code.slice(0, 100);\n const end = code.length > 100 ? code.slice(-100) : \"\";\n return `${language}:${code.length}:${start}:${end}`;\n};\n\nconst getHighlighter = (\n language: BundledLanguage,\n): Promise<HighlighterGeneric<BundledLanguage, BundledTheme>> => {\n const cached = highlighterCache.get(language);\n if (cached) {\n return cached;\n }\n\n const highlighterPromise = import(\"shiki\").then(({ createHighlighter }) =>\n createHighlighter({\n langs: [language],\n themes: [\"github-light\", \"github-dark\"],\n }),\n );\n\n highlighterCache.set(language, highlighterPromise);\n return highlighterPromise;\n};\n\n// Create raw tokens for immediate display while highlighting loads\nconst createRawTokens = (code: string): TokenizedCode => ({\n bg: \"transparent\",\n fg: \"inherit\",\n tokens: code.split(\"\\n\").map((line) =>\n line === \"\"\n ? []\n : [\n {\n color: \"inherit\",\n content: line,\n } as ThemedToken,\n ],\n ),\n});\n\n// Synchronous highlight with callback for async results\nexport const highlightCode = (\n code: string,\n language: BundledLanguage,\n // oxlint-disable-next-line eslint-plugin-promise(prefer-await-to-callbacks)\n callback?: (result: TokenizedCode) => void,\n): TokenizedCode | null => {\n const tokensCacheKey = getTokensCacheKey(code, language);\n\n // Return cached result if available\n const cached = tokensCache.get(tokensCacheKey);\n if (cached) {\n return cached;\n }\n\n // Subscribe callback if provided\n if (callback) {\n if (!subscribers.has(tokensCacheKey)) {\n subscribers.set(tokensCacheKey, new Set());\n }\n subscribers.get(tokensCacheKey)?.add(callback);\n }\n\n // Start highlighting in background - fire-and-forget async pattern\n getHighlighter(language)\n // oxlint-disable-next-line eslint-plugin-promise(prefer-await-to-then)\n .then((highlighter) => {\n const availableLangs = highlighter.getLoadedLanguages();\n const langToUse = availableLangs.includes(language) ? language : \"text\";\n\n const result = highlighter.codeToTokens(code, {\n lang: langToUse,\n themes: {\n dark: \"github-dark\",\n light: \"github-light\",\n },\n });\n\n const tokenized: TokenizedCode = {\n bg: result.bg ?? \"transparent\",\n fg: result.fg ?? \"inherit\",\n tokens: result.tokens,\n };\n\n // Cache the result\n tokensCache.set(tokensCacheKey, tokenized);\n\n // Notify all subscribers\n const subs = subscribers.get(tokensCacheKey);\n if (subs) {\n for (const sub of subs) {\n sub(tokenized);\n }\n subscribers.delete(tokensCacheKey);\n }\n })\n // oxlint-disable-next-line eslint-plugin-promise(prefer-await-to-then), eslint-plugin-promise(prefer-await-to-callbacks)\n .catch((error) => {\n console.error(\"Failed to highlight code:\", error);\n subscribers.delete(tokensCacheKey);\n });\n\n return null;\n};\n\nconst CodeBlockBody = memo(\n ({\n tokenized,\n showLineNumbers,\n className,\n }: {\n tokenized: TokenizedCode;\n showLineNumbers: boolean;\n className?: string;\n }) => {\n const preStyle = useMemo(\n () => ({\n backgroundColor: tokenized.bg,\n color: tokenized.fg,\n }),\n [tokenized.bg, tokenized.fg],\n );\n\n const keyedLines = useMemo(() => addKeysToTokens(tokenized.tokens), [tokenized.tokens]);\n\n return (\n <pre\n className={cn(\n \"dark:!bg-[var(--shiki-dark-bg)] dark:!text-[var(--shiki-dark)] m-0 p-4 text-sm\",\n className,\n )}\n style={preStyle}\n >\n <code\n className={cn(\n \"font-mono text-sm\",\n showLineNumbers && \"[counter-increment:line_0] [counter-reset:line]\",\n )}\n >\n {keyedLines.map((keyedLine) => (\n <LineSpan key={keyedLine.key} keyedLine={keyedLine} showLineNumbers={showLineNumbers} />\n ))}\n </code>\n </pre>\n );\n },\n (prevProps, nextProps) =>\n prevProps.tokenized === nextProps.tokenized &&\n prevProps.showLineNumbers === nextProps.showLineNumbers &&\n prevProps.className === nextProps.className,\n);\n\nCodeBlockBody.displayName = \"CodeBlockBody\";\n\nexport const CodeBlockContainer = ({\n className,\n language,\n style,\n ...props\n}: HTMLAttributes<HTMLDivElement> & { language: string }) => (\n <div\n className={cn(\n \"group relative w-full overflow-hidden rounded-md border bg-background text-foreground\",\n className,\n )}\n data-language={language}\n style={{\n containIntrinsicSize: \"auto 200px\",\n contentVisibility: \"auto\",\n ...style,\n }}\n {...props}\n />\n);\n\nexport const CodeBlockHeader = ({\n children,\n className,\n ...props\n}: HTMLAttributes<HTMLDivElement>) => (\n <div\n className={cn(\n \"flex items-center justify-between border-b bg-muted/80 px-3 py-2 text-muted-foreground text-xs\",\n className,\n )}\n {...props}\n >\n {children}\n </div>\n);\n\nexport const CodeBlockTitle = ({\n children,\n className,\n ...props\n}: HTMLAttributes<HTMLDivElement>) => (\n <div className={cn(\"flex items-center gap-2\", className)} {...props}>\n {children}\n </div>\n);\n\nexport const CodeBlockFilename = ({\n children,\n className,\n ...props\n}: HTMLAttributes<HTMLSpanElement>) => (\n <span className={cn(\"font-mono\", className)} {...props}>\n {children}\n </span>\n);\n\nexport const CodeBlockActions = ({\n children,\n className,\n ...props\n}: HTMLAttributes<HTMLDivElement>) => (\n <div className={cn(\"-my-1 -mr-1 flex items-center gap-2\", className)} {...props}>\n {children}\n </div>\n);\n\nexport const CodeBlockContent = ({\n code,\n language,\n showLineNumbers = false,\n}: {\n code: string;\n language: BundledLanguage;\n showLineNumbers?: boolean;\n}) => {\n // Memoized raw tokens for immediate display\n const rawTokens = useMemo(() => createRawTokens(code), [code]);\n\n // Synchronous cache lookup — avoids setState in effect for cached results\n const syncTokens = useMemo(\n () => highlightCode(code, language) ?? rawTokens,\n [code, language, rawTokens],\n );\n\n // Async highlighting result (populated after shiki loads)\n const [asyncTokens, setAsyncTokens] = useState<TokenizedCode | null>(null);\n const asyncKeyRef = useRef({ code, language });\n\n // Invalidate stale async tokens synchronously during render\n if (asyncKeyRef.current.code !== code || asyncKeyRef.current.language !== language) {\n asyncKeyRef.current = { code, language };\n setAsyncTokens(null);\n }\n\n useEffect(() => {\n let cancelled = false;\n\n highlightCode(code, language, (result) => {\n if (!cancelled) {\n setAsyncTokens(result);\n }\n });\n\n return () => {\n cancelled = true;\n };\n }, [code, language]);\n\n const tokenized = asyncTokens ?? syncTokens;\n\n return (\n <div className=\"relative overflow-auto\">\n <CodeBlockBody showLineNumbers={showLineNumbers} tokenized={tokenized} />\n </div>\n );\n};\n\nexport const CodeBlock = ({\n code,\n language,\n showLineNumbers = false,\n className,\n children,\n ...props\n}: CodeBlockProps) => {\n const contextValue = useMemo(() => ({ code }), [code]);\n\n return (\n <CodeBlockContext.Provider value={contextValue}>\n <CodeBlockContainer className={className} language={language} {...props}>\n {children}\n <CodeBlockContent code={code} language={language} showLineNumbers={showLineNumbers} />\n </CodeBlockContainer>\n </CodeBlockContext.Provider>\n );\n};\n\nexport type CodeBlockCopyButtonProps = ComponentProps<typeof Button> & {\n onCopy?: () => void;\n onError?: (error: Error) => void;\n timeout?: number;\n};\n\nexport const CodeBlockCopyButton = ({\n onCopy,\n onError,\n timeout = 2000,\n children,\n className,\n ...props\n}: CodeBlockCopyButtonProps) => {\n const [isCopied, setIsCopied] = useState(false);\n const timeoutRef = useRef<number>(0);\n const { code } = useContext(CodeBlockContext);\n\n const copyToClipboard = useCallback(async () => {\n if (typeof window === \"undefined\" || !navigator?.clipboard?.writeText) {\n onError?.(new Error(\"Clipboard API not available\"));\n return;\n }\n\n try {\n if (!isCopied) {\n await navigator.clipboard.writeText(code);\n setIsCopied(true);\n onCopy?.();\n timeoutRef.current = window.setTimeout(() => setIsCopied(false), timeout);\n }\n } catch (error) {\n onError?.(error as Error);\n }\n }, [code, onCopy, onError, timeout, isCopied]);\n\n useEffect(\n () => () => {\n window.clearTimeout(timeoutRef.current);\n },\n [],\n );\n\n const Icon = isCopied ? CheckIcon : CopyIcon;\n\n return (\n <Button\n className={cn(\"shrink-0\", className)}\n onClick={copyToClipboard}\n size=\"icon\"\n variant=\"ghost\"\n {...props}\n >\n {children ?? <Icon size={14} />}\n </Button>\n );\n};\n\nexport type CodeBlockLanguageSelectorProps = ComponentProps<typeof Select>;\n\nexport const CodeBlockLanguageSelector = (props: CodeBlockLanguageSelectorProps) => (\n <Select {...props} />\n);\n\nexport type CodeBlockLanguageSelectorTriggerProps = ComponentProps<typeof SelectTrigger>;\n\nexport const CodeBlockLanguageSelectorTrigger = ({\n className,\n ...props\n}: CodeBlockLanguageSelectorTriggerProps) => (\n <SelectTrigger\n className={cn(\"h-7 border-none bg-transparent px-2 text-xs shadow-none\", className)}\n size=\"sm\"\n {...props}\n />\n);\n\nexport type CodeBlockLanguageSelectorValueProps = ComponentProps<typeof SelectValue>;\n\nexport const CodeBlockLanguageSelectorValue = (props: CodeBlockLanguageSelectorValueProps) => (\n <SelectValue {...props} />\n);\n\nexport type CodeBlockLanguageSelectorContentProps = ComponentProps<typeof SelectContent>;\n\nexport const CodeBlockLanguageSelectorContent = ({\n align = \"end\",\n ...props\n}: CodeBlockLanguageSelectorContentProps) => <SelectContent align={align} {...props} />;\n\nexport type CodeBlockLanguageSelectorItemProps = ComponentProps<typeof SelectItem>;\n\nexport const CodeBlockLanguageSelectorItem = (props: CodeBlockLanguageSelectorItemProps) => (\n <SelectItem {...props} />\n);\n","\"use client\";\n\nimport { cn } from \"../utils\";\nimport { highlightCode } from \"./code-block\";\nimport { Streamdown, type CodeHighlighterPlugin, type StreamdownProps } from \"streamdown\";\nimport { useMemo } from \"react\";\nimport { bundledLanguages } from \"shiki/langs\";\nimport type { BundledLanguage } from \"shiki\";\n\nconst highlightedLanguages = Object.keys(bundledLanguages) as BundledLanguage[];\n\nconst codeHighlighter = {\n getSupportedLanguages: () => highlightedLanguages,\n getThemes: () => [\"github-light\", \"github-dark\"],\n highlight: ({ code, language }, callback) => highlightCode(code, language, callback),\n name: \"shiki\",\n supportsLanguage: (language) => language in bundledLanguages,\n type: \"code-highlighter\",\n} satisfies CodeHighlighterPlugin;\n\nexport type ResponseProps = Omit<StreamdownProps, \"children\"> & {\n children: string;\n};\n\nexport const Response = ({\n children,\n className,\n controls = false,\n plugins,\n ...props\n}: ResponseProps) => {\n const responsePlugins = useMemo(\n () => ({ ...plugins, code: plugins?.code ?? codeHighlighter }),\n [plugins],\n );\n\n return (\n <Streamdown\n className={cn(\n \"leading-6\",\n \"*:first:mt-0 *:last:mb-0\",\n \"[&_a]:text-primary [&_a]:underline [&_a]:underline-offset-2\",\n \"[&_blockquote]:my-3 [&_blockquote]:border-l-2 [&_blockquote]:border-border [&_blockquote]:pl-3 [&_blockquote]:text-muted-foreground\",\n \"[&_h1]:mb-2 [&_h1]:mt-4 [&_h1]:text-base [&_h1]:font-semibold\",\n \"[&_h2]:mb-2 [&_h2]:mt-4 [&_h2]:text-sm [&_h2]:font-semibold\",\n \"[&_h3]:mb-1.5 [&_h3]:mt-3 [&_h3]:text-sm [&_h3]:font-semibold\",\n \"[&_li]:my-1 [&_ol]:my-2 [&_ol]:list-decimal [&_ol]:pl-5 [&_ul]:my-2 [&_ul]:list-disc [&_ul]:pl-5\",\n \"[&_p]:my-2\",\n \"**:data-[streamdown=inline-code]:text-[length:inherit] **:data-[streamdown=inline-code]:leading-[inherit]\",\n \"**:data-[streamdown=code-block]:my-3 **:data-[streamdown=code-block]:gap-0 **:data-[streamdown=code-block]:overflow-hidden **:data-[streamdown=code-block]:rounded-lg **:data-[streamdown=code-block]:bg-muted/40 **:data-[streamdown=code-block]:p-0\",\n \"**:data-[streamdown=code-block-header]:px-2\",\n \"**:data-[streamdown=code-block-body]:rounded-none **:data-[streamdown=code-block-body]:border-0 **:data-[streamdown=code-block-body]:border-t **:data-[streamdown=code-block-body]:bg-background **:data-[streamdown=code-block-body]:p-3\",\n \"[&_strong]:font-semibold\",\n \"[&_table]:my-3 [&_table]:w-full [&_table]:border-collapse [&_td]:border [&_td]:border-border [&_td]:px-2 [&_td]:py-1 [&_th]:border [&_th]:border-border [&_th]:px-2 [&_th]:py-1 [&_th]:text-left [&_th]:font-semibold\",\n className,\n )}\n controls={controls}\n plugins={responsePlugins}\n {...props}\n >\n {children}\n </Streamdown>\n );\n};\n","import type { UIMessage } from \"ai\";\nimport {\n SURVEY_ASSISTANT_TURN_FINAL_PART_TYPE,\n surveyAssistantTurnFinalSchema,\n} from \"../../protocol\";\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst asTimestamp = (value: unknown): number | undefined => {\n if (value instanceof Date) return Number.isFinite(value.getTime()) ? value.getTime() : undefined;\n if (typeof value === \"number\") return Number.isFinite(value) ? value : undefined;\n if (typeof value !== \"string\") return undefined;\n\n const timestamp = Date.parse(value);\n return Number.isFinite(timestamp) ? timestamp : undefined;\n};\n\nconst getMastraCreatedAt = (value: unknown): number | undefined => {\n if (!isRecord(value) || !isRecord(value.mastra)) return undefined;\n return asTimestamp(value.mastra.createdAt);\n};\n\nconst getPartTimestamps = (part: UIMessage[\"parts\"][number]): number[] => {\n const value = part as unknown as Record<string, unknown>;\n return [\n getMastraCreatedAt(value.providerMetadata),\n getMastraCreatedAt(value.callProviderMetadata),\n getMastraCreatedAt(value.resultProviderMetadata),\n ].filter((timestamp): timestamp is number => timestamp !== undefined);\n};\n\n/**\n * Mastra persists message and part timestamps already. Reconstructing elapsed\n * time here keeps restored chats informative without a second timing store.\n */\nexport const getPersistedMessageDurationSeconds = (message: UIMessage): number | undefined => {\n const turnFinalPart = message.parts.find(\n (part) => part.type === SURVEY_ASSISTANT_TURN_FINAL_PART_TYPE,\n );\n const turnFinal = surveyAssistantTurnFinalSchema.safeParse(\n turnFinalPart && \"data\" in turnFinalPart ? turnFinalPart.data : undefined,\n );\n if (turnFinal.success && turnFinal.data.durationMs !== undefined) {\n return Math.max(1, Math.ceil(turnFinal.data.durationMs / 1000));\n }\n\n if (!isRecord(message.metadata)) return undefined;\n\n const startedAt = asTimestamp(message.metadata.createdAt);\n if (startedAt === undefined) return undefined;\n\n const completedAt = Math.max(...message.parts.flatMap(getPartTimestamps));\n if (!Number.isFinite(completedAt) || completedAt < startedAt) return undefined;\n\n return Math.max(1, Math.ceil((completedAt - startedAt) / 1000));\n};\n","import {\n SURVEY_ASSISTANT_TURN_FINAL_PART_TYPE,\n surveyAssistantTurnFinalSchema,\n type SurveyAssistantTurnFinal,\n} from \"../../protocol\";\nimport type { UIMessage } from \"ai\";\n\nexport const getPersistedMessageTurnStatus = (\n message: UIMessage,\n): SurveyAssistantTurnFinal[\"status\"] | undefined => {\n for (let index = message.parts.length - 1; index >= 0; index -= 1) {\n const part = message.parts[index];\n if (part?.type !== SURVEY_ASSISTANT_TURN_FINAL_PART_TYPE || !(\"data\" in part)) continue;\n\n const parsed = surveyAssistantTurnFinalSchema.safeParse(part.data);\n if (parsed.success) return parsed.data.status;\n }\n\n return undefined;\n};\n","export type SurveyAssistantInitialThreadLoadState = \"error\" | \"loading\" | null;\n\nexport const getSurveyAssistantInitialThreadLoadState = ({\n error,\n hasSelectedThread,\n loading,\n}: {\n error: string | null;\n hasSelectedThread: boolean;\n loading: boolean;\n}): SurveyAssistantInitialThreadLoadState => {\n if (loading) return \"loading\";\n if (!hasSelectedThread) return error ? \"error\" : \"loading\";\n return null;\n};\n","import type { LocalizationTranslate } from \"@case-framework/ui-localization\";\nimport { isSurveyAssistantErrorRetryable, parseSurveyAssistantError } from \"../protocol\";\n\nexport type AssistantErrorPresentation = {\n description: string;\n hint: string;\n providerMessage?: string;\n providerRequestId?: string;\n retryable: boolean;\n title: string;\n tone: \"warning\" | \"error\";\n upstreamStatus?: number;\n};\n\nexport const getAssistantErrorPresentation = ({\n authorizationError,\n error,\n t,\n}: {\n authorizationError: string | null;\n error: unknown;\n t: LocalizationTranslate;\n}): AssistantErrorPresentation => {\n const parsed = parseSurveyAssistantError(\n authorizationError\n ? { code: \"request_failed\", detail: authorizationError, retryable: false }\n : error,\n );\n\n return {\n title: t(`errors.${parsed.code}.title`),\n description: parsed.detail ?? t(\"errors.fallbackDetail\"),\n hint: t(`errors.${parsed.code}.hint`),\n providerMessage: parsed.providerMessage,\n providerRequestId: parsed.providerRequestId,\n retryable: isSurveyAssistantErrorRetryable(parsed),\n tone:\n parsed.code === \"model_unavailable\" || parsed.code === \"rate_limited\" ? \"warning\" : \"error\",\n upstreamStatus: parsed.upstreamStatus,\n };\n};\n","\"use client\";\n\nimport { CheckIcon } from \"lucide-react\";\nimport { Checkbox as CheckboxPrimitive } from \"radix-ui\";\nimport type { ComponentProps } from \"react\";\nimport { cn } from \"../utils\";\n\nexport const Checkbox = ({\n className,\n ...props\n}: ComponentProps<typeof CheckboxPrimitive.Root>) => (\n <CheckboxPrimitive.Root\n className={cn(\n \"relative flex size-4 shrink-0 items-center justify-center rounded border border-input outline-none transition-colors focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/40 disabled:cursor-not-allowed disabled:opacity-50 data-checked:border-primary data-checked:bg-primary data-checked:text-primary-foreground\",\n className,\n )}\n {...props}\n >\n <CheckboxPrimitive.Indicator className=\"grid place-content-center text-current\">\n <CheckIcon className=\"size-3.5\" />\n </CheckboxPrimitive.Indicator>\n </CheckboxPrimitive.Root>\n);\n","\"use client\";\n\nimport { XIcon } from \"lucide-react\";\nimport { Dialog as DialogPrimitive } from \"radix-ui\";\nimport type { ComponentProps } from \"react\";\nimport { cn } from \"../utils\";\n\nexport const Dialog = DialogPrimitive.Root;\nexport const DialogTitle = DialogPrimitive.Title;\nexport const DialogDescription = DialogPrimitive.Description;\n\nexport const DialogContent = ({\n children,\n className,\n closeLabel,\n ...props\n}: ComponentProps<typeof DialogPrimitive.Content> & { closeLabel: string }) => (\n <DialogPrimitive.Portal>\n <div className=\"case-survey-assistant case-survey-assistant-portal\">\n <DialogPrimitive.Overlay className=\"fixed inset-0 z-50 bg-black/20 backdrop-blur-[1px] data-[state=closed]:animate-out data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0\" />\n <DialogPrimitive.Content\n className={cn(\n \"fixed top-1/2 left-1/2 z-50 grid max-h-[min(42rem,calc(100vh-2rem))] w-[min(30rem,calc(100vw-2rem))] -translate-x-1/2 -translate-y-1/2 gap-4 overflow-y-auto rounded-xl border border-border bg-background p-4 text-foreground shadow-xl outline-none data-[state=closed]:animate-out data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95\",\n className,\n )}\n {...props}\n >\n {children}\n <DialogPrimitive.Close\n aria-label={closeLabel}\n className=\"absolute top-2.5 right-2.5 flex size-7 items-center justify-center rounded-md text-muted-foreground hover:bg-muted hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring\"\n type=\"button\"\n >\n <XIcon className=\"size-4\" />\n </DialogPrimitive.Close>\n </DialogPrimitive.Content>\n </div>\n </DialogPrimitive.Portal>\n);\n","\"use client\";\n\nimport { CheckIcon, CopyIcon, DownloadIcon, LoaderCircleIcon, MailIcon } from \"lucide-react\";\nimport { useEffect, useMemo, useRef, useState, type RefObject } from \"react\";\nimport {\n createSurveyAssistantSupportMailto,\n createSurveyAssistantSupportDetails,\n downloadSurveyAssistantSupportBundle,\n estimateSurveyAssistantSupportBundleBytes,\n generateSurveyAssistantSupportBundle,\n SURVEY_ASSISTANT_DEFAULT_SUPPORT_BUNDLE_SELECTION,\n type GeneratedSurveyAssistantSupportBundle,\n type PreparedSurveyAssistantSupportBundle,\n type SurveyAssistantSupportBundleCategory,\n type SurveyAssistantSupportBundleConfig,\n type SurveyAssistantSupportBundleSelection,\n} from \"../react\";\nimport { Button } from \"./internal/button\";\nimport { Checkbox } from \"./internal/checkbox\";\nimport { Dialog, DialogContent, DialogDescription, DialogTitle } from \"./internal/dialog\";\nimport { useSurveyAssistantTranslation } from \"./localization\";\n\nconst CATEGORIES: SurveyAssistantSupportBundleCategory[] = [\n \"conversation\",\n \"survey\",\n \"attachments\",\n];\n\nconst formatBytes = (bytes: number) => {\n if (bytes < 1024) return `${bytes} B`;\n if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KiB`;\n return `${(bytes / (1024 * 1024)).toFixed(1)} MiB`;\n};\n\nexport interface SurveyAssistantSupportBundleDialogProps {\n config?: SurveyAssistantSupportBundleConfig;\n error?: string;\n fallbackFocusReturnRef?: RefObject<HTMLElement | null>;\n focusReturnRef?: RefObject<HTMLElement | null>;\n loading: boolean;\n onOpenChange(open: boolean): void;\n open: boolean;\n prepared?: PreparedSurveyAssistantSupportBundle;\n}\n\nexport const SurveyAssistantSupportBundleDialog = ({\n config,\n error,\n fallbackFocusReturnRef,\n focusReturnRef,\n loading,\n onOpenChange,\n open,\n prepared,\n}: SurveyAssistantSupportBundleDialogProps) => {\n const t = useSurveyAssistantTranslation();\n const [selection, setSelection] = useState<SurveyAssistantSupportBundleSelection>({\n ...SURVEY_ASSISTANT_DEFAULT_SUPPORT_BUNDLE_SELECTION,\n });\n const [generated, setGenerated] = useState<GeneratedSurveyAssistantSupportBundle>();\n const [generationError, setGenerationError] = useState<string>();\n const [generating, setGenerating] = useState(false);\n const [supportDetailsCopied, setSupportDetailsCopied] = useState(false);\n const [supportDetailsCopyError, setSupportDetailsCopyError] = useState<string>();\n const generationSequenceRef = useRef(0);\n const supportDetailsRef = useRef<HTMLTextAreaElement>(null);\n\n useEffect(() => {\n generationSequenceRef.current += 1;\n if (open) setSelection({ ...SURVEY_ASSISTANT_DEFAULT_SUPPORT_BUNDLE_SELECTION });\n setGenerated(undefined);\n setGenerationError(undefined);\n setGenerating(false);\n setSupportDetailsCopied(false);\n setSupportDetailsCopyError(undefined);\n }, [open, prepared?.threadId]);\n\n const selectedBytes = useMemo(\n () => (prepared ? estimateSurveyAssistantSupportBundleBytes(prepared, selection, config) : 0),\n [config, prepared, selection],\n );\n const blocked = Boolean(prepared && selectedBytes > prepared.limits.bundleBytes);\n const warning = Boolean(prepared && selectedBytes > prepared.limits.emailWarningBytes);\n\n const generate = async () => {\n if (!prepared || blocked) return;\n const generationSequence = generationSequenceRef.current + 1;\n generationSequenceRef.current = generationSequence;\n setGenerating(true);\n setSupportDetailsCopied(false);\n setSupportDetailsCopyError(undefined);\n try {\n const bundle = await generateSurveyAssistantSupportBundle(prepared, selection, config);\n if (generationSequenceRef.current !== generationSequence) return;\n downloadSurveyAssistantSupportBundle(bundle);\n setGenerated(bundle);\n setGenerationError(undefined);\n setSupportDetailsCopied(false);\n setSupportDetailsCopyError(undefined);\n } catch {\n if (generationSequenceRef.current === generationSequence) {\n setGenerationError(t(\"supportBundle.generationFailed\"));\n }\n } finally {\n if (generationSequenceRef.current === generationSequence) setGenerating(false);\n }\n };\n\n const updateSelection = (category: SurveyAssistantSupportBundleCategory, checked: boolean) => {\n generationSequenceRef.current += 1;\n setSelection((current) => ({ ...current, [category]: checked }));\n setGenerated(undefined);\n setGenerationError(undefined);\n setGenerating(false);\n setSupportDetailsCopied(false);\n setSupportDetailsCopyError(undefined);\n };\n\n const mailto =\n generated && prepared && config\n ? createSurveyAssistantSupportMailto({ bundle: generated, config, prepared })\n : undefined;\n const supportDetails =\n generated && prepared\n ? createSurveyAssistantSupportDetails({ bundle: generated, prepared })\n : \"\";\n\n const copySupportDetails = async () => {\n if (!supportDetails) return;\n const copySequence = generationSequenceRef.current + 1;\n generationSequenceRef.current = copySequence;\n setSupportDetailsCopied(false);\n setSupportDetailsCopyError(undefined);\n try {\n if (navigator.clipboard?.writeText) {\n await navigator.clipboard.writeText(supportDetails);\n } else {\n if (!supportDetailsRef.current) throw new Error(\"Support details are not available.\");\n supportDetailsRef.current.select();\n if (!document.execCommand(\"copy\")) throw new Error(\"Copy was not available.\");\n }\n if (generationSequenceRef.current !== copySequence) return;\n setSupportDetailsCopied(true);\n setSupportDetailsCopyError(undefined);\n } catch {\n if (generationSequenceRef.current !== copySequence) return;\n setSupportDetailsCopied(false);\n setSupportDetailsCopyError(t(\"supportBundle.copyDetailsFailed\"));\n }\n };\n\n return (\n <Dialog onOpenChange={onOpenChange} open={open}>\n <DialogContent\n aria-describedby=\"survey-assistant-support-bundle-description\"\n closeLabel={t(\"supportBundle.close\")}\n onCloseAutoFocus={(event) => {\n const target = focusReturnRef?.current?.isConnected\n ? focusReturnRef.current\n : fallbackFocusReturnRef?.current?.isConnected\n ? fallbackFocusReturnRef.current\n : null;\n if (!target) return;\n event.preventDefault();\n target.focus();\n }}\n >\n <div className=\"pr-8\">\n <DialogTitle className=\"font-semibold text-base\">{t(\"supportBundle.title\")}</DialogTitle>\n <DialogDescription\n className=\"mt-1 text-muted-foreground text-sm\"\n id=\"survey-assistant-support-bundle-description\"\n >\n {t(\"supportBundle.description\")}\n </DialogDescription>\n </div>\n\n {loading ? (\n <div\n aria-live=\"polite\"\n className=\"flex min-h-28 items-center justify-center text-muted-foreground text-sm\"\n role=\"status\"\n >\n <LoaderCircleIcon className=\"mr-2 size-4 animate-spin\" />\n {t(\"supportBundle.preparing\")}\n </div>\n ) : error ? (\n <div className=\"rounded-md border border-destructive/20 bg-destructive/5 p-3 text-sm\">\n <div className=\"font-medium\">{t(\"supportBundle.preparationFailed\")}</div>\n <div className=\"mt-1 text-muted-foreground\">{error}</div>\n </div>\n ) : prepared ? (\n <>\n <div className=\"rounded-md border border-border bg-muted/30 p-3 text-xs\">\n <div className=\"font-medium\">{t(\"supportBundle.core.title\")}</div>\n <div className=\"mt-1 text-muted-foreground\">\n {t(\"supportBundle.core.description\")}\n </div>\n </div>\n\n <fieldset className=\"grid gap-2\" aria-describedby=\"support-bundle-sensitive-note\">\n <legend className=\"mb-1 font-medium text-sm\">{t(\"supportBundle.chooseData\")}</legend>\n {CATEGORIES.map((category) => {\n const id = `support-bundle-${category}`;\n return (\n <label\n className=\"flex cursor-pointer items-start gap-3 rounded-md border border-border p-3 hover:bg-muted/30\"\n htmlFor={id}\n key={category}\n >\n <Checkbox\n checked={selection[category]}\n id={id}\n onCheckedChange={(checked) => updateSelection(category, checked === true)}\n />\n <span className=\"min-w-0 flex-1\">\n <span className=\"flex items-center justify-between gap-2 font-medium text-sm\">\n <span>{t(`supportBundle.categories.${category}.title`)}</span>\n <span className=\"shrink-0 text-muted-foreground text-xs\">\n {formatBytes(prepared.categoryBytes[category])}\n </span>\n </span>\n <span className=\"mt-0.5 block text-muted-foreground text-xs\">\n {t(`supportBundle.categories.${category}.description`)}\n </span>\n </span>\n </label>\n );\n })}\n </fieldset>\n\n <p className=\"text-muted-foreground text-xs\" id=\"support-bundle-sensitive-note\">\n {t(\"supportBundle.sensitiveNote\")}\n </p>\n\n <div\n aria-live=\"polite\"\n className=\"rounded-md bg-muted/40 px-3 py-2 text-xs\"\n role=\"status\"\n >\n <div className=\"flex justify-between gap-3\">\n <span>{t(\"supportBundle.estimatedSize\")}</span>\n <span className=\"font-medium\">{formatBytes(selectedBytes)}</span>\n </div>\n {warning && !blocked && (\n <div className=\"mt-1 text-amber-700\">{t(\"supportBundle.emailWarning\")}</div>\n )}\n {blocked && (\n <div className=\"mt-1 text-destructive\">{t(\"supportBundle.tooLarge\")}</div>\n )}\n {prepared.unavailable.length > 0 && (\n <div className=\"mt-1 text-muted-foreground\">\n {t(\n prepared.unavailable.length === 1\n ? \"supportBundle.unavailable\"\n : \"supportBundle.unavailablePlural\",\n { count: prepared.unavailable.length },\n )}\n </div>\n )}\n {(generationError ?? error) && (\n <div className=\"mt-1 text-destructive\">{generationError ?? error}</div>\n )}\n </div>\n\n {generated ? (\n <>\n {!mailto && (\n <div className=\"grid gap-2 rounded-md border border-border p-3\">\n <label className=\"font-medium text-xs\" htmlFor=\"support-bundle-details\">\n {t(\"supportBundle.supportDetails\")}\n </label>\n <textarea\n className=\"min-h-24 resize-y rounded-md border border-input bg-background p-2 font-mono text-xs\"\n id=\"support-bundle-details\"\n readOnly\n ref={supportDetailsRef}\n value={supportDetails}\n />\n <div className=\"flex justify-end\">\n <Button\n disabled={generating}\n onClick={() => void copySupportDetails()}\n type=\"button\"\n variant=\"secondary\"\n >\n {supportDetailsCopied ? <CheckIcon /> : <CopyIcon />}\n {t(\n supportDetailsCopied\n ? \"supportBundle.detailsCopied\"\n : \"supportBundle.copyDetails\",\n )}\n </Button>\n </div>\n {supportDetailsCopyError && (\n <div aria-live=\"polite\" className=\"text-destructive text-xs\" role=\"status\">\n {supportDetailsCopyError}\n </div>\n )}\n </div>\n )}\n <div className=\"flex flex-wrap justify-end gap-2\">\n {mailto && (\n <Button asChild variant=\"secondary\">\n <a href={mailto}>\n <MailIcon />\n {t(\"supportBundle.openEmail\")}\n </a>\n </Button>\n )}\n <Button disabled={generating} onClick={() => void generate()} type=\"button\">\n {generating ? <LoaderCircleIcon className=\"animate-spin\" /> : <DownloadIcon />}\n {t(\"supportBundle.downloadAgain\")}\n </Button>\n </div>\n </>\n ) : (\n <div className=\"flex justify-end\">\n <Button\n disabled={blocked || generating}\n onClick={() => void generate()}\n type=\"button\"\n >\n {generating ? <LoaderCircleIcon className=\"animate-spin\" /> : <DownloadIcon />}\n {t(\"supportBundle.download\")}\n </Button>\n </div>\n )}\n <p className=\"text-muted-foreground text-xs\">\n {generated\n ? t(\"supportBundle.downloaded\", { filename: generated.filename })\n : t(\"supportBundle.localOnly\")}\n </p>\n </>\n ) : null}\n </DialogContent>\n </Dialog>\n );\n};\n","\"use client\";\n\nimport {\n ChainOfThought,\n ChainOfThoughtContent,\n ChainOfThoughtHeader,\n ChainOfThoughtStep,\n} from \"./internal/chain-of-thought\";\nimport {\n Conversation,\n ConversationContent,\n ConversationEmptyState,\n ConversationScrollButton,\n} from \"./internal/conversation\";\nimport { Message, MessageContent } from \"./internal/message\";\nimport {\n SurveyAssistantPromptInput,\n type SurveyAssistantPromptInputMessage,\n} from \"./survey-assistant-prompt-input\";\nimport { stringifyToolTechnicalDetails } from \"./internal/tool-technical-details\";\nimport { Response } from \"./internal/response\";\nimport { CodeBlock } from \"./internal/code-block\";\nimport { Collapsible, CollapsibleContent, CollapsibleTrigger } from \"./internal/collapsible\";\nimport { cn } from \"./utils\";\nimport { parseSurveyAssistantError, SURVEY_ASSISTANT_ATTACHMENT_PART_TYPE } from \"../protocol\";\nimport type {\n SurveyApplyResult,\n SurveyAssistantAttachmentReference,\n SurveyAssistantSnapshot,\n SurveyAssistantModelOption,\n SurveyAssistantThread,\n SurveyAssistantThreadList,\n SurveyChangeSet,\n} from \"../protocol\";\nimport {\n createSurveyAssistantThreadClient,\n createSurveyAssistantDiagnosticStore,\n isSurveyAssistantTurnActive,\n isSurveyAssistantSupportBundleEnabled,\n parseSurveyChangeSet,\n prepareSurveyAssistantSupportBundle,\n type PreparedSurveyAssistantSupportBundle,\n type SurveyAssistantDiagnosticStore,\n type SurveyAssistantSupportBundleConfig,\n type SurveyAssistantThreadClient,\n type SurveyAssistantSessionOptions,\n type SurveyTurnOutcome,\n unwrapSurveyAssistantToolOutput,\n useSurveyAssistantSession,\n} from \"../react\";\nimport {\n connectSurveyAssistantThreadLauncher,\n type SurveyAssistantThreadLaunch,\n type SurveyAssistantThreadLauncher,\n} from \"../react/thread-launcher\";\nimport type { LocalizationCatalog, LocalizationTranslate } from \"@case-framework/ui-localization\";\nimport {\n getToolName,\n isFileUIPart,\n isReasoningUIPart,\n isToolUIPart,\n type DynamicToolUIPart,\n type FileUIPart,\n type ToolUIPart,\n type UIMessage,\n} from \"ai\";\nimport {\n CheckCircleIcon,\n ChevronRightIcon,\n ClockIcon,\n FileIcon,\n HistoryIcon,\n ListChecksIcon,\n LoaderCircleIcon,\n MessageSquarePlusIcon,\n PencilIcon,\n PlusIcon,\n SearchIcon,\n SparklesIcon,\n Trash2Icon,\n PackageOpenIcon,\n WandSparklesIcon,\n WrenchIcon,\n XCircleIcon,\n} from \"lucide-react\";\nimport { type ReactNode, useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { SurveyAssistantLocalizationProvider, useSurveyAssistantTranslation } from \"./localization\";\nimport { getPersistedMessageDurationSeconds } from \"./internal/message-timing\";\nimport { getPersistedMessageTurnStatus } from \"./internal/message-turn-status\";\nimport { getSurveyAssistantInitialThreadLoadState } from \"./initial-thread-load\";\nimport { getAssistantErrorPresentation } from \"./assistant-error-presentation\";\nimport { SurveyAssistantSupportBundleDialog } from \"./support-bundle-dialog\";\n\ntype ToolPart = ToolUIPart | DynamicToolUIPart;\n\ntype AssistantEmptyStateContext = \"new-survey\" | \"selected-item\" | \"survey\";\n\nconst isRootSurveyItem = (item: SurveyAssistantSnapshot[\"survey\"][\"surveyItems\"][number]) =>\n typeof item.config === \"object\" &&\n item.config !== null &&\n (item.config as { isRoot?: unknown }).isRoot === true;\n\nconst getAssistantEmptyStateContext = (\n controller: SurveyAssistantSessionOptions[\"controller\"],\n): AssistantEmptyStateContext => {\n try {\n const snapshot = controller?.getSnapshot();\n if (!snapshot) return \"survey\";\n\n const surveyItems = snapshot.survey.surveyItems.filter((item) => !isRootSurveyItem(item));\n if (surveyItems.length === 0) return \"new-survey\";\n if (surveyItems.some((item) => item.id === snapshot.ui.selectedItemId)) return \"selected-item\";\n return \"survey\";\n } catch {\n return \"survey\";\n }\n};\n\nconst getAssistantQuickPrompts = (\n t: LocalizationTranslate,\n context: AssistantEmptyStateContext,\n) => {\n if (context === \"new-survey\") {\n return [\n {\n label: t(\"quickActions.draftSurvey.label\"),\n description: t(\"quickActions.draftSurvey.description\"),\n icon: WandSparklesIcon,\n prompt: t(\"quickActions.draftSurvey.prompt\"),\n },\n {\n label: t(\"quickActions.useBrief.label\"),\n description: t(\"quickActions.useBrief.description\"),\n icon: FileIcon,\n prompt: t(\"quickActions.useBrief.prompt\"),\n },\n {\n label: t(\"quickActions.planSurvey.label\"),\n description: t(\"quickActions.planSurvey.description\"),\n icon: ListChecksIcon,\n prompt: t(\"quickActions.planSurvey.prompt\"),\n },\n ];\n }\n\n return [\n {\n label: t(\"quickActions.review.label\"),\n description: t(\"quickActions.review.description\"),\n icon: ListChecksIcon,\n prompt: t(\"quickActions.review.prompt\"),\n },\n {\n label: t(\"quickActions.create.label\"),\n description: t(\"quickActions.create.description\"),\n icon: MessageSquarePlusIcon,\n prompt: t(\"quickActions.create.prompt\"),\n },\n {\n label: t(\n context === \"selected-item\"\n ? \"quickActions.refineSelection.label\"\n : \"quickActions.refine.label\",\n ),\n description: t(\n context === \"selected-item\"\n ? \"quickActions.refineSelection.description\"\n : \"quickActions.refine.description\",\n ),\n icon: WandSparklesIcon,\n prompt: t(\n context === \"selected-item\"\n ? \"quickActions.refineSelection.prompt\"\n : \"quickActions.refine.prompt\",\n ),\n },\n ];\n};\n\nconst isSurveyAssistantAttachmentReferencePart = (\n part: UIMessage[\"parts\"][number],\n): part is {\n type: typeof SURVEY_ASSISTANT_ATTACHMENT_PART_TYPE;\n data: SurveyAssistantAttachmentReference;\n} => {\n if (\n part.type !== SURVEY_ASSISTANT_ATTACHMENT_PART_TYPE ||\n typeof part.data !== \"object\" ||\n part.data === null\n ) {\n return false;\n }\n const data = part.data as Partial<SurveyAssistantAttachmentReference>;\n return (\n typeof data.filename === \"string\" &&\n typeof data.mediaType === \"string\" &&\n typeof data.bytes === \"number\"\n );\n};\n\nconst hasRenderableParts = (message: UIMessage) => {\n return message.parts.some(\n (part) =>\n (part.type === \"text\" && part.text.length > 0) ||\n isFileUIPart(part) ||\n isSurveyAssistantAttachmentReferencePart(part) ||\n (isReasoningUIPart(part) && part.text.trim().length > 0) ||\n isToolUIPart(part),\n );\n};\n\nconst getFilePartLabel = (part: FileUIPart) => part.filename ?? part.mediaType;\n\nconst getToolOutput = (part: ToolPart) =>\n part.state === \"output-available\" ? part.output : undefined;\n\nconst getToolErrorText = (part: ToolPart) =>\n part.state === \"output-error\" ? part.errorText : undefined;\n\nconst localizedToolNames = new Set([\n \"survey_inspect\",\n \"survey_change\",\n \"survey_expression\",\n \"survey_authoring_reference\",\n \"survey_attachment\",\n \"recall\",\n]);\n\nconst getToolDisplayName = (\n t: LocalizationTranslate,\n toolName: string,\n phase: \"active\" | \"complete\" = \"complete\",\n) =>\n localizedToolNames.has(toolName)\n ? t(`activity.tools.${toolName}.${phase}`)\n : t(phase === \"active\" ? \"activity.genericActive\" : \"activity.genericComplete\");\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst unwrapOutput = unwrapSurveyAssistantToolOutput;\n\nconst getChangeSet = parseSurveyChangeSet;\n\nconst isChangeSet = (output: unknown): output is SurveyChangeSet => {\n return getChangeSet(output) !== null;\n};\n\nconst getValidationCounts = (validation: unknown) => {\n if (!isRecord(validation)) {\n return { issueCount: 0, warningCount: 0 };\n }\n\n return {\n issueCount: Array.isArray(validation.issues) ? validation.issues.length : 0,\n warningCount: Array.isArray(validation.warnings) ? validation.warnings.length : 0,\n };\n};\n\nconst SurveyAssistantToolOutputSummary = ({\n applyResult,\n output,\n}: {\n applyResult?: SurveyApplyResult;\n output: unknown;\n}) => {\n const t = useSurveyAssistantTranslation();\n const unwrappedOutput = unwrapOutput(output);\n\n if (isChangeSet(unwrappedOutput)) {\n const { issueCount, warningCount } = getValidationCounts(unwrappedOutput.validation);\n const isValid = unwrappedOutput.status === \"validated\";\n const status = applyResult?.status ?? (isValid ? \"validated\" : \"rejected\");\n const isPositiveStatus = status === \"applied\" || status === \"validated\";\n const statusLabel =\n status === \"applied\"\n ? t(\"changes.applied\")\n : status === \"stale\"\n ? t(\"changes.stale\")\n : status === \"failed\"\n ? t(\"changes.failed\")\n : isValid\n ? t(\"changes.prepared\")\n : t(\"changes.rejected\");\n const statusMessage = applyResult?.message ?? unwrappedOutput.summary;\n\n return (\n <div\n className={cn(\n \"relative rounded-md border px-2.5 py-2 text-xs\",\n isPositiveStatus\n ? \"border-emerald-200/70 bg-emerald-50/40 text-emerald-950\"\n : status === \"stale\"\n ? \"border-amber-200/70 bg-amber-50/40 text-amber-900\"\n : \"border-red-200/70 bg-red-50/40 text-red-900\",\n )}\n >\n <div className=\"flex items-center gap-2 font-medium\">\n {isPositiveStatus ? (\n <CheckCircleIcon className=\"size-3.5 shrink-0\" />\n ) : (\n <XCircleIcon className=\"size-3.5 shrink-0\" />\n )}\n <span>{statusLabel}</span>\n </div>\n <div className=\"mt-1 text-xs\">\n {statusMessage}\n {unwrappedOutput.operations.length > 0 && (\n <span className=\"text-current/70\">\n {\" \"}\n (\n {t(\n unwrappedOutput.operations.length === 1\n ? \"changes.operationCount\"\n : \"changes.operationCountPlural\",\n { count: unwrappedOutput.operations.length },\n )}\n )\n </span>\n )}\n </div>\n {(issueCount > 0 || warningCount > 0) && (\n <div className=\"mt-1 text-current/70\">\n {issueCount > 0 &&\n t(issueCount === 1 ? \"changes.issueCount\" : \"changes.issueCountPlural\", {\n count: issueCount,\n })}\n {issueCount > 0 && warningCount > 0 && \", \"}\n {warningCount > 0 &&\n t(warningCount === 1 ? \"changes.warningCount\" : \"changes.warningCountPlural\", {\n count: warningCount,\n })}\n </div>\n )}\n </div>\n );\n }\n\n return null;\n};\n\nconst getToolTitle = (t: LocalizationTranslate, toolName: string, state: ToolPart[\"state\"]) => {\n if (state === \"output-available\") {\n return getToolDisplayName(t, toolName, \"complete\");\n }\n if (state === \"output-error\") {\n return t(\"activity.failedSuffix\", { name: getToolDisplayName(t, toolName, \"complete\") });\n }\n if (state === \"output-denied\") {\n return t(\"activity.skippedSuffix\", { name: getToolDisplayName(t, toolName, \"active\") });\n }\n\n return getToolDisplayName(t, toolName, \"active\");\n};\n\nconst getToolProgressLabel = (t: LocalizationTranslate, part: ToolPart) => {\n switch (part.state) {\n case \"approval-requested\":\n return t(\"activity.waitingApproval\");\n case \"approval-responded\":\n return t(\"activity.continuingApproval\");\n case \"input-streaming\":\n return t(\"activity.preparingStep\");\n case \"input-available\":\n return getToolDisplayName(t, getToolName(part), \"active\");\n case \"output-available\":\n return t(\"activity.usingResult\");\n case \"output-denied\":\n return t(\"activity.continuingWithoutStep\");\n case \"output-error\":\n return t(\"activity.recoveringToolError\");\n }\n};\n\nconst getToolStatusMeta = (\n t: LocalizationTranslate,\n): Record<\n ToolPart[\"state\"],\n { icon: ReactNode; label: string | null; stepStatus: \"active\" | \"complete\" }\n> => ({\n \"approval-requested\": {\n icon: <ClockIcon className=\"size-3 text-amber-600\" />,\n label: t(\"activity.waitingApproval\"),\n stepStatus: \"active\",\n },\n \"approval-responded\": {\n icon: <CheckCircleIcon className=\"size-3 text-blue-600\" />,\n label: t(\"activity.approvalReceived\"),\n stepStatus: \"complete\",\n },\n \"input-available\": {\n icon: <LoaderCircleIcon className=\"size-3 animate-spin text-blue-600\" />,\n label: null,\n stepStatus: \"active\",\n },\n \"input-streaming\": {\n icon: <LoaderCircleIcon className=\"size-3 animate-spin text-blue-600\" />,\n label: null,\n stepStatus: \"active\",\n },\n \"output-available\": {\n icon: <CheckCircleIcon className=\"size-3 text-emerald-600\" />,\n label: null,\n stepStatus: \"complete\",\n },\n \"output-denied\": {\n icon: <XCircleIcon className=\"size-3 text-orange-600\" />,\n label: null,\n stepStatus: \"complete\",\n },\n \"output-error\": {\n icon: <XCircleIcon className=\"size-3 text-red-600\" />,\n label: null,\n stepStatus: \"complete\",\n },\n});\n\nconst getStoppedToolStatusMeta = (t: LocalizationTranslate) => ({\n icon: <XCircleIcon className=\"size-3 text-muted-foreground\" />,\n label: t(\"activity.stopped\"),\n stepStatus: \"complete\" as const,\n});\n\nconst SurveyAssistantToolStep = ({\n applyResultsByChangeId,\n terminalTurnStatus,\n part,\n isLast,\n}: {\n applyResultsByChangeId: Record<string, SurveyApplyResult>;\n terminalTurnStatus?: \"aborted\" | \"failed\";\n part: ToolPart;\n isLast: boolean;\n}) => {\n const t = useSurveyAssistantTranslation();\n const toolStatusMeta = getToolStatusMeta(t);\n const toolName = getToolName(part);\n const output = getToolOutput(part);\n const errorText = getToolErrorText(part);\n const changeSet = output === undefined ? null : getChangeSet(output);\n const applyResult = changeSet ? applyResultsByChangeId[changeSet.id] : undefined;\n const changeHasError =\n changeSet?.status === \"rejected\" ||\n applyResult?.status === \"rejected\" ||\n applyResult?.status === \"failed\";\n const title = changeSet\n ? toolName === \"survey_expression\"\n ? t(\"activity.expressionChange\")\n : t(\"activity.surveyChange\")\n : getToolTitle(t, toolName, part.state);\n const meta =\n terminalTurnStatus && toolStatusMeta[part.state].stepStatus === \"active\"\n ? terminalTurnStatus === \"aborted\"\n ? getStoppedToolStatusMeta(t)\n : {\n icon: <XCircleIcon className=\"size-3 text-red-600\" />,\n label: t(\"activity.failed\"),\n stepStatus: \"complete\" as const,\n }\n : changeHasError\n ? {\n icon: <XCircleIcon className=\"size-3 text-red-900\" />,\n label: null,\n stepStatus: \"complete\" as const,\n }\n : applyResult?.status === \"stale\"\n ? {\n icon: <ClockIcon className=\"size-3 text-amber-600\" />,\n label: null,\n stepStatus: \"complete\" as const,\n }\n : toolStatusMeta[part.state];\n const metaTitle =\n meta.label ??\n (part.state === \"output-denied\"\n ? t(\"activity.skipped\")\n : part.state === \"output-error\"\n ? t(\"activity.failed\")\n : meta.stepStatus === \"active\"\n ? t(\"activity.workingShort\")\n : t(\"activity.done\"));\n const [detailsOpen, setDetailsOpen] = useState(part.state === \"output-error\");\n const hasDetails = part.input !== undefined || output !== undefined || Boolean(errorText);\n\n return (\n <ChainOfThoughtStep\n icon={WrenchIcon}\n isLast={isLast}\n label={\n <span className=\"flex flex-wrap items-center gap-x-2 gap-y-0.5\">\n <span>{title}</span>\n <span\n className={cn(\n \"inline-flex shrink-0 items-center gap-1 text-[11px] font-normal\",\n meta.stepStatus === \"active\" ? \"text-blue-700\" : \"text-muted-foreground\",\n )}\n title={metaTitle}\n >\n {meta.icon}\n {meta.label && <span>{meta.label}</span>}\n {!meta.label && <span className=\"sr-only\">{metaTitle}</span>}\n </span>\n </span>\n }\n result={\n output !== undefined ? (\n <SurveyAssistantToolOutputSummary applyResult={applyResult} output={output} />\n ) : undefined\n }\n status={meta.stepStatus}\n >\n {hasDetails && (\n <Collapsible onOpenChange={setDetailsOpen} open={detailsOpen}>\n <CollapsibleTrigger className=\"-ml-1 flex items-center gap-0.5 rounded px-1 py-0.5 text-[11px] text-muted-foreground/80 transition-colors hover:bg-background/60 hover:text-foreground\">\n <ChevronRightIcon\n className={cn(\"size-3 transition-transform\", detailsOpen && \"rotate-90\")}\n />\n {t(detailsOpen ? \"activity.hideTechnicalDetails\" : \"activity.technicalDetails\")}\n </CollapsibleTrigger>\n <CollapsibleContent className=\"mt-1.5 space-y-1.5\">\n {part.input !== undefined && (\n <CodeBlock\n className=\"border-border/60 bg-background/70 [&_code]:text-xs [&_pre]:p-2.5 [&_pre]:text-xs\"\n code={stringifyToolTechnicalDetails(part.input)}\n language=\"json\"\n />\n )}\n {(output !== undefined || errorText) && (\n <CodeBlock\n className={cn(\n \"bg-background/70 [&_code]:text-xs [&_pre]:p-2.5 [&_pre]:text-xs\",\n errorText ? \"border-destructive/25\" : \"border-border/60\",\n )}\n code={errorText ?? stringifyToolTechnicalDetails(output)}\n language=\"json\"\n />\n )}\n </CollapsibleContent>\n </Collapsible>\n )}\n </ChainOfThoughtStep>\n );\n};\n\nconst getStreamingProgressLabel = (t: LocalizationTranslate, message?: UIMessage) => {\n if (!message || message.role !== \"assistant\") {\n return t(\"status.connecting\");\n }\n\n const lastPart = message.parts.at(-1);\n if (!lastPart) {\n return t(\"status.thinking\");\n }\n\n if (isReasoningUIPart(lastPart)) {\n return t(\"status.thinking\");\n }\n\n if (isToolUIPart(lastPart)) {\n return getToolProgressLabel(t, lastPart);\n }\n\n if (lastPart.type === \"text\") {\n return t(\"status.writing\");\n }\n\n return t(\"status.working\");\n};\n\nconst SurveyAssistantProgressIndicator = ({ message }: { message?: UIMessage }) => {\n const t = useSurveyAssistantTranslation();\n return (\n <div\n aria-live=\"polite\"\n className=\"mt-2 flex items-center gap-2 px-1 text-muted-foreground text-xs\"\n role=\"status\"\n >\n <LoaderCircleIcon className=\"size-3.5 animate-spin text-blue-600\" />\n <span>{getStreamingProgressLabel(t, message)}</span>\n </div>\n );\n};\n\ntype ChainOfThoughtEntry =\n | { type: \"reasoning\"; key: string; text: string }\n | { type: \"tool\"; key: string; part: ToolPart };\n\ntype MessageBlock =\n | {\n type: \"attachment-reference\";\n key: string;\n attachment: SurveyAssistantAttachmentReference;\n }\n | { type: \"chain\"; key: string; entries: ChainOfThoughtEntry[] }\n | { type: \"file\"; key: string; part: FileUIPart }\n | { type: \"text\"; key: string; text: string };\n\n// Group the message's parts into ordered blocks, keeping text interleaved\n// with reasoning/tool-call chains in the exact order they were emitted,\n// instead of hoisting all reasoning/tool calls above all text output.\nconst buildMessageBlocks = (parts: UIMessage[\"parts\"]): MessageBlock[] => {\n const blocks: MessageBlock[] = [];\n let pendingEntries: ChainOfThoughtEntry[] = [];\n\n const flushChain = () => {\n if (pendingEntries.length > 0) {\n blocks.push({\n type: \"chain\",\n key: `chain-${pendingEntries[0].key}`,\n entries: pendingEntries,\n });\n pendingEntries = [];\n }\n };\n\n parts.forEach((part, index) => {\n if (isReasoningUIPart(part)) {\n if (part.text) {\n pendingEntries.push({ type: \"reasoning\", key: `reasoning-${index}`, text: part.text });\n }\n return;\n }\n\n if (isToolUIPart(part)) {\n pendingEntries.push({ type: \"tool\", key: `tool-${part.toolCallId}`, part });\n return;\n }\n\n if (part.type === \"text\") {\n flushChain();\n blocks.push({ type: \"text\", key: `text-${index}`, text: part.text });\n return;\n }\n\n if (isFileUIPart(part)) {\n flushChain();\n blocks.push({ type: \"file\", key: `file-${index}`, part });\n return;\n }\n\n if (isSurveyAssistantAttachmentReferencePart(part)) {\n flushChain();\n blocks.push({\n type: \"attachment-reference\",\n key: `attachment-reference-${index}`,\n attachment: part.data,\n });\n }\n });\n\n flushChain();\n\n return blocks;\n};\n\nconst SurveyAssistantMessageParts = ({\n applyResultsByChangeId,\n isLastMessage,\n isStreaming,\n message,\n showProgress,\n terminalTurnStatus,\n}: {\n applyResultsByChangeId: Record<string, SurveyApplyResult>;\n isLastMessage: boolean;\n isStreaming: boolean;\n message: UIMessage;\n showProgress?: boolean;\n terminalTurnStatus?: \"aborted\" | \"failed\";\n}) => {\n const blocks = useMemo(() => buildMessageBlocks(message.parts), [message.parts]);\n const persistedDuration = useMemo(() => getPersistedMessageDurationSeconds(message), [message]);\n const lastPart = message.parts.at(-1);\n const hasActiveToolMessage =\n lastPart !== undefined &&\n isToolUIPart(lastPart) &&\n (lastPart.state === \"input-streaming\" || lastPart.state === \"input-available\");\n\n return (\n <>\n {blocks.map((block, blockIndex) => {\n const isLastBlock = blockIndex === blocks.length - 1;\n\n if (block.type === \"text\") {\n if (message.role === \"assistant\") {\n return (\n <Response\n className=\"leading-5 [&_li]:my-0.5 [&_p]:my-1.5 [&_p:first-child]:mt-0 [&_p:last-child]:mb-0\"\n key={block.key}\n >\n {block.text}\n </Response>\n );\n }\n\n return <span key={block.key}>{block.text}</span>;\n }\n\n if (block.type === \"file\") {\n return (\n <span\n className=\"inline-flex max-w-full items-center gap-2 rounded-md border border-border bg-muted px-2 py-1 text-xs\"\n key={block.key}\n title={getFilePartLabel(block.part)}\n >\n <FileIcon className=\"size-3.5 shrink-0 text-muted-foreground\" />\n <span className=\"min-w-0 truncate\">{getFilePartLabel(block.part)}</span>\n <span className=\"shrink-0 text-muted-foreground\">{block.part.mediaType}</span>\n </span>\n );\n }\n\n if (block.type === \"attachment-reference\") {\n return (\n <span\n className=\"inline-flex max-w-full items-center gap-2 rounded-md border border-border bg-muted px-2 py-1 text-xs\"\n key={block.key}\n title={block.attachment.filename}\n >\n <FileIcon className=\"size-3.5 shrink-0 text-muted-foreground\" />\n <span className=\"min-w-0 truncate\">{block.attachment.filename}</span>\n <span className=\"shrink-0 text-muted-foreground\">{block.attachment.mediaType}</span>\n </span>\n );\n }\n\n const isChainActive = isLastMessage && isStreaming && isLastBlock;\n\n return (\n <ChainOfThought\n autoClose\n className=\"w-full rounded-md bg-muted/60 px-2 py-1.5\"\n defaultDuration={persistedDuration}\n defaultOpen={isChainActive}\n duration={isChainActive ? undefined : persistedDuration}\n isStreaming={isChainActive}\n key={block.key}\n >\n <ChainOfThoughtHeader className=\"text-xs font-medium\" />\n <ChainOfThoughtContent className=\"relative mt-2\">\n <div\n aria-hidden=\"true\"\n className=\"absolute top-0 bottom-0 left-1.75 w-px bg-border\"\n />\n {block.entries.map((entry, index) => {\n const isLastEntry = index === block.entries.length - 1;\n\n if (entry.type === \"reasoning\") {\n return (\n <Response\n className={cn(\n \"pr-1 pl-5 text-muted-foreground text-xs leading-5 [&_p]:my-1 [&_p:first-child]:mt-0 [&_p:last-child]:mb-0\",\n !isLastEntry && \"mb-2\",\n )}\n key={entry.key}\n >\n {entry.text}\n </Response>\n );\n }\n\n return (\n <SurveyAssistantToolStep\n applyResultsByChangeId={applyResultsByChangeId}\n isLast={isLastEntry}\n key={entry.key}\n part={entry.part}\n terminalTurnStatus={terminalTurnStatus}\n />\n );\n })}\n </ChainOfThoughtContent>\n </ChainOfThought>\n );\n })}\n {showProgress &&\n !hasActiveToolMessage &&\n (lastPart === undefined || !isReasoningUIPart(lastPart)) && (\n <SurveyAssistantProgressIndicator message={message} />\n )}\n </>\n );\n};\n\nexport type SurveyAssistantPanelProps = Omit<\n SurveyAssistantSessionOptions,\n \"diagnosticStore\" | \"initialMessages\" | \"modelId\" | \"resourceId\" | \"threadId\"\n> & {\n embedded?: boolean;\n language?: string;\n localizations?: LocalizationCatalog;\n modelId?: string;\n models?: SurveyAssistantModelOption[];\n onConfirmDeleteThread?: (thread: SurveyAssistantThread) => boolean | Promise<boolean>;\n onModelChange?(modelId: string): void;\n resourceId: string;\n selectedThreadStorageKey?: string | false;\n supportBundle?: SurveyAssistantSupportBundleConfig;\n threadApi?: string;\n threadClient?: SurveyAssistantThreadClient;\n /** Allows host UI outside the panel to create a new thread and execute its first prompt. */\n threadLauncher?: SurveyAssistantThreadLauncher;\n};\n\ntype SurveyAssistantChatPanelProps = SurveyAssistantSessionOptions & {\n embedded?: boolean;\n focusPromptOnMount?: boolean;\n hasEarlierMessages: boolean;\n initialLaunch?: SurveyAssistantThreadLaunch;\n models: SurveyAssistantModelOption[];\n onInitialLaunchHandled(): void;\n onModelChange(modelId: string): void;\n onFirstSubmit(text: string): void;\n onExportDetails?(trigger: HTMLElement | null): void;\n onLoadEarlierMessages(): Promise<UIMessage[]>;\n onTurnSettled(): void;\n threadControls: ReactNode;\n threadTitle: string;\n};\n\nconst SurveyAssistantTurnOutcomeNotice = (outcome: SurveyTurnOutcome) => {\n const t = useSurveyAssistantTranslation();\n if (outcome.status === \"failed\" || outcome.status === \"aborted\") {\n const reason = (() => {\n switch (outcome.terminationReason) {\n case \"client-abort\":\n return t(\"turn.reasons.clientAbort\");\n case \"first-response-timeout\":\n return t(\"turn.reasons.firstResponseTimeout\");\n case \"idle-timeout\":\n return t(\"turn.reasons.idleTimeout\");\n case \"max-duration\":\n return t(\"turn.reasons.maxDuration\");\n case \"max-steps\":\n return t(\"turn.reasons.maxSteps\");\n case \"length-limit\":\n return t(\"turn.reasons.lengthLimit\");\n case \"content-filter\":\n return t(\"turn.reasons.contentFilter\");\n case \"provider-error\":\n return t(\"turn.reasons.providerError\");\n case \"stream-error\":\n return t(\"turn.reasons.streamError\");\n case \"incomplete-response\":\n return t(\"turn.reasons.incompleteResponse\");\n default:\n return t(\"turn.reasons.unknown\");\n }\n })();\n\n return (\n <div\n className={cn(\n \"rounded-lg border px-3 py-2 text-xs\",\n outcome.status === \"aborted\"\n ? \"border-border bg-muted/50 text-foreground\"\n : \"border-destructive/20 bg-destructive/5 text-foreground\",\n )}\n >\n <div className=\"font-medium\">\n {t(outcome.status === \"aborted\" ? \"turn.abortedTitle\" : \"turn.failedTitle\")}\n </div>\n <div className=\"mt-1 text-muted-foreground\">{reason}</div>\n </div>\n );\n }\n\n const description =\n outcome.status === \"blocked\"\n ? t(outcome.blockedChangeSetCount === 1 ? \"changes.blocked\" : \"changes.blockedPlural\", {\n count: outcome.blockedChangeSetCount,\n })\n : t(outcome.appliedChangeSetCount === 1 ? \"changes.partial\" : \"changes.partialPlural\", {\n applied: outcome.appliedChangeSetCount,\n failed: outcome.failedChangeSetCount,\n });\n\n return (\n <div className=\"rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-amber-950 text-xs\">\n <div className=\"font-medium\">{t(\"changes.incompleteTitle\")}</div>\n <div className=\"mt-1\">\n {description} {t(\"changes.reviewBeforeRetry\")}\n </div>\n </div>\n );\n};\n\nconst SurveyAssistantHeaderIdentity = ({\n indicatorClassName,\n status,\n title,\n}: {\n indicatorClassName: string;\n status: string;\n title: string;\n}) => (\n <div className=\"flex min-w-0 items-center gap-2\">\n <div className=\"relative flex size-6 shrink-0 items-center justify-center rounded-md bg-foreground text-background shadow-sm\">\n <SparklesIcon className=\"size-3.5\" />\n <span\n aria-hidden=\"true\"\n className={cn(\n \"absolute -right-px -bottom-px size-1.5 rounded-full border border-background\",\n indicatorClassName,\n )}\n />\n </div>\n <div className=\"min-w-0\">\n <h2 className=\"truncate font-semibold text-[13px] leading-4\">{title}</h2>\n <span\n aria-live=\"polite\"\n className=\"block truncate text-[10px] text-muted-foreground leading-3\"\n role=\"status\"\n >\n {status}\n </span>\n </div>\n </div>\n);\n\nconst SurveyAssistantChatPanel = ({\n api,\n applyPolicy,\n controller,\n diagnosticStore,\n embedded = false,\n focusPromptOnMount = false,\n hasEarlierMessages,\n initialLaunch,\n initialMessages,\n modelId,\n models,\n onInitialLaunchHandled,\n onModelChange,\n onFirstSubmit,\n onExportDetails,\n onLoadEarlierMessages,\n onTurnSettled,\n onApplyReceipts,\n onSettleApply,\n onReviewChangeSets,\n onTurnActiveChange,\n resourceId,\n surveyId,\n threadControls,\n threadId,\n threadTitle,\n}: SurveyAssistantChatPanelProps) => {\n const t = useSurveyAssistantTranslation();\n const emptyStateContext = getAssistantEmptyStateContext(controller);\n const assistantQuickPrompts = getAssistantQuickPrompts(t, emptyStateContext);\n const {\n applyResultsByChangeId,\n authorizationError,\n dismissError,\n error,\n isStreaming,\n latestTurnOutcome,\n messages,\n prependMessages,\n state,\n status,\n stop,\n submit,\n retry,\n } = useSurveyAssistantSession({\n api,\n applyPolicy,\n controller,\n diagnosticStore,\n initialMessages,\n modelId,\n onApplyReceipts,\n onSettleApply,\n onReviewChangeSets,\n onTurnActiveChange,\n resourceId,\n surveyId,\n threadId,\n });\n const hasSubmittedMessageRef = useRef((initialMessages?.length ?? 0) > 0);\n const showAssistantError = Boolean(authorizationError) || Boolean(error);\n const assistantErrorPresentation = getAssistantErrorPresentation({\n authorizationError,\n error,\n t,\n });\n const lastMessage = messages.at(-1);\n const isAssistantTurnActive = isSurveyAssistantTurnActive({ isStreaming, state });\n const promptTextareaRef = useRef<HTMLTextAreaElement>(null);\n const exportDetailsButtonRef = useRef<HTMLButtonElement>(null);\n const shouldRestorePromptFocusRef = useRef(false);\n const turnWasActiveRef = useRef(false);\n const [loadingEarlierMessages, setLoadingEarlierMessages] = useState(false);\n const [providerMessageExpanded, setProviderMessageExpanded] = useState(false);\n\n const loadEarlierMessages = useCallback(async () => {\n if (loadingEarlierMessages) return;\n setLoadingEarlierMessages(true);\n try {\n prependMessages(await onLoadEarlierMessages());\n } finally {\n setLoadingEarlierMessages(false);\n }\n }, [loadingEarlierMessages, onLoadEarlierMessages, prependMessages]);\n const isAssistantTurnSettled =\n !isStreaming &&\n (state === \"completed\" || state === \"failed\" || state === \"aborted\" || state === \"applied\");\n\n useEffect(() => {\n if (!isAssistantTurnActive) {\n if (shouldRestorePromptFocusRef.current) {\n shouldRestorePromptFocusRef.current = false;\n promptTextareaRef.current?.focus();\n }\n return;\n }\n\n const cancelFocusRestoreOnPointerDown = (event: PointerEvent) => {\n if (event.target !== promptTextareaRef.current) {\n shouldRestorePromptFocusRef.current = false;\n }\n };\n const cancelFocusRestore = () => {\n shouldRestorePromptFocusRef.current = false;\n };\n\n document.addEventListener(\"focusin\", cancelFocusRestore, true);\n document.addEventListener(\"pointerdown\", cancelFocusRestoreOnPointerDown, true);\n window.addEventListener(\"blur\", cancelFocusRestore);\n\n return () => {\n document.removeEventListener(\"focusin\", cancelFocusRestore, true);\n document.removeEventListener(\"pointerdown\", cancelFocusRestoreOnPointerDown, true);\n window.removeEventListener(\"blur\", cancelFocusRestore);\n };\n }, [isAssistantTurnActive]);\n\n useEffect(() => {\n if (isAssistantTurnActive) {\n turnWasActiveRef.current = true;\n return;\n }\n if (!turnWasActiveRef.current || !isAssistantTurnSettled) return;\n\n turnWasActiveRef.current = false;\n onTurnSettled();\n }, [isAssistantTurnActive, isAssistantTurnSettled, onTurnSettled]);\n\n const showPendingAssistantRow =\n isAssistantTurnActive && (!lastMessage || lastMessage.role !== \"assistant\");\n const sessionStatusLabel =\n state === \"applying\"\n ? t(\"status.applying\")\n : state === \"applied\"\n ? t(\"status.applied\")\n : state === \"aborted\"\n ? t(\"status.stopped\")\n : isAssistantTurnActive\n ? getStreamingProgressLabel(t, lastMessage)\n : showAssistantError || state === \"failed\"\n ? t(\"status.attention\")\n : t(\"status.ready\");\n\n const handleSubmit = useCallback(\n (message: SurveyAssistantPromptInputMessage) => {\n if (isAssistantTurnActive) return false;\n const submittedFromFocusedPrompt = document.activeElement === promptTextareaRef.current;\n const accepted = submit({ files: message.files, text: message.text });\n if (accepted) {\n shouldRestorePromptFocusRef.current = submittedFromFocusedPrompt;\n if (!hasSubmittedMessageRef.current) {\n hasSubmittedMessageRef.current = true;\n onFirstSubmit(message.text);\n }\n }\n return accepted;\n },\n [isAssistantTurnActive, onFirstSubmit, submit],\n );\n\n const handleQuickPrompt = useCallback(\n (prompt: string) => handleSubmit({ files: [], text: prompt }),\n [handleSubmit],\n );\n\n useEffect(() => {\n if (!initialLaunch) return;\n if (initialLaunch.modelId) onModelChange(initialLaunch.modelId);\n const accepted = submit({\n files: initialLaunch.files ?? [],\n modelId: initialLaunch.modelId,\n text: initialLaunch.prompt,\n uiContext: initialLaunch.uiContext,\n });\n if (accepted) {\n if (!hasSubmittedMessageRef.current) {\n hasSubmittedMessageRef.current = true;\n onFirstSubmit(initialLaunch.prompt);\n }\n onInitialLaunchHandled();\n }\n }, [initialLaunch, onFirstSubmit, onInitialLaunchHandled, onModelChange, submit]);\n\n return (\n <aside\n aria-label={t(\"panel.ariaLabel\")}\n className={cn(\n \"flex h-full min-h-0 flex-col overflow-visible bg-background\",\n !embedded && \"rounded-xl border border-border shadow-sm\",\n )}\n >\n <header className=\"box-content flex h-9 shrink-0 items-center justify-between gap-2 border-b border-border bg-background px-2.5\">\n <SurveyAssistantHeaderIdentity\n indicatorClassName={\n showAssistantError || state === \"failed\"\n ? \"bg-destructive\"\n : isAssistantTurnActive\n ? \"animate-pulse bg-blue-500\"\n : state === \"aborted\"\n ? \"bg-muted-foreground\"\n : \"bg-emerald-500\"\n }\n status={sessionStatusLabel}\n title={threadTitle}\n />\n {threadControls}\n </header>\n\n <Conversation className=\"min-h-0 bg-(--surface-bg-color)\">\n <ConversationContent className=\"gap-3 px-3 py-2.5\">\n {messages.length === 0 ? (\n <ConversationEmptyState className=\"min-h-full items-stretch justify-center gap-0 px-1 py-6 text-left\">\n <div className=\"mx-auto w-full max-w-sm\">\n <div className=\"mb-3 flex size-9 items-center justify-center rounded-xl border border-border bg-muted text-foreground shadow-xs\">\n <SparklesIcon className=\"size-4\" />\n </div>\n <h3 className=\"font-semibold text-foreground text-base tracking-tight\">\n {t(emptyStateContext === \"new-survey\" ? \"empty.newSurveyTitle\" : \"empty.title\")}\n </h3>\n <p className=\"mt-1 text-muted-foreground text-xs leading-relaxed\">\n {t(\n emptyStateContext === \"new-survey\"\n ? \"empty.newSurveyDescription\"\n : \"empty.description\",\n )}\n </p>\n <div className=\"mt-4 flex flex-col gap-1.5\">\n {assistantQuickPrompts.map(({ label, description, icon: Icon, prompt }) => (\n <button\n className=\"group flex w-full items-center gap-2.5 rounded-lg border border-border bg-popover px-2.5 py-2 text-left shadow-xs transition-colors hover:border-foreground/20 hover:bg-muted/60\"\n key={label}\n onClick={() => handleQuickPrompt(prompt)}\n type=\"button\"\n >\n <span className=\"flex size-7 shrink-0 items-center justify-center rounded-md bg-muted text-muted-foreground transition-colors group-hover:bg-background group-hover:text-foreground\">\n <Icon className=\"size-3.5\" />\n </span>\n <span className=\"min-w-0 flex-1\">\n <span className=\"block truncate font-medium text-foreground text-xs\">\n {label}\n </span>\n <span className=\"block truncate text-[11px] text-muted-foreground\">\n {description}\n </span>\n </span>\n <ChevronRightIcon className=\"size-3.5 shrink-0 text-muted-foreground/40 transition-transform group-hover:translate-x-0.5 group-hover:text-muted-foreground\" />\n </button>\n ))}\n </div>\n </div>\n </ConversationEmptyState>\n ) : (\n <>\n {hasEarlierMessages && (\n <button\n className=\"mx-auto flex h-8 items-center justify-center rounded-md px-3 text-muted-foreground text-xs hover:bg-muted hover:text-foreground disabled:pointer-events-none\"\n disabled={loadingEarlierMessages || isAssistantTurnActive}\n onClick={() => void loadEarlierMessages()}\n type=\"button\"\n >\n {loadingEarlierMessages && (\n <LoaderCircleIcon className=\"mr-1.5 size-3.5 animate-spin\" />\n )}\n {loadingEarlierMessages\n ? t(\"conversation.loadingEarlier\")\n : t(\"conversation.loadEarlier\")}\n </button>\n )}\n {messages.map((message, index) => {\n const isLastMessage = index === messages.length - 1;\n const persistedTurnStatus = getPersistedMessageTurnStatus(message);\n const terminalTurnStatus =\n persistedTurnStatus === \"aborted\" || persistedTurnStatus === \"failed\"\n ? persistedTurnStatus\n : isLastMessage && (state === \"aborted\" || state === \"failed\")\n ? state\n : undefined;\n const shouldShowProgress =\n isAssistantTurnActive && isLastMessage && message.role === \"assistant\";\n\n return (\n <Message className=\"max-w-[96%] gap-1\" from={message.role} key={message.id}>\n <MessageContent\n className={cn(message.role === \"assistant\" && \"w-full space-y-2\")}\n >\n {hasRenderableParts(message) ? (\n <>\n <SurveyAssistantMessageParts\n applyResultsByChangeId={applyResultsByChangeId}\n isLastMessage={isLastMessage}\n isStreaming={isAssistantTurnActive}\n message={message}\n showProgress={shouldShowProgress}\n terminalTurnStatus={terminalTurnStatus}\n />\n {isLastMessage && latestTurnOutcome && (\n <SurveyAssistantTurnOutcomeNotice {...latestTurnOutcome} />\n )}\n </>\n ) : shouldShowProgress ? (\n <SurveyAssistantProgressIndicator message={message} />\n ) : isLastMessage && latestTurnOutcome ? (\n <SurveyAssistantTurnOutcomeNotice {...latestTurnOutcome} />\n ) : state === \"aborted\" ? (\n <span className=\"text-muted-foreground text-sm\">\n {t(\"conversation.stopped\")}\n </span>\n ) : (\n <span className=\"text-muted-foreground text-sm\">\n {t(\"conversation.incomplete\")}\n </span>\n )}\n </MessageContent>\n </Message>\n );\n })}\n {showPendingAssistantRow && (\n <Message className=\"max-w-[96%] gap-1\" from=\"assistant\">\n <MessageContent className=\"w-full\">\n <SurveyAssistantProgressIndicator />\n </MessageContent>\n </Message>\n )}\n </>\n )}\n </ConversationContent>\n <ConversationScrollButton className=\"bottom-2.5\" />\n </Conversation>\n\n {showAssistantError && (\n <div\n className={cn(\n \"flex items-start justify-between gap-3 border-t px-3 py-2.5 text-sm\",\n assistantErrorPresentation.tone === \"warning\"\n ? \"border-amber-200 bg-amber-50/60\"\n : \"border-destructive/20 bg-destructive/5\",\n )}\n role=\"alert\"\n >\n <div className=\"flex min-w-0 gap-2.5\">\n {assistantErrorPresentation.tone === \"warning\" ? (\n <WrenchIcon className=\"mt-0.5 size-4 shrink-0 text-amber-700\" />\n ) : (\n <XCircleIcon className=\"mt-0.5 size-4 shrink-0 text-destructive\" />\n )}\n <div className=\"min-w-0\">\n <div className=\"font-medium text-foreground\">{assistantErrorPresentation.title}</div>\n <p className=\"mt-0.5 wrap-break-word text-muted-foreground\">\n {assistantErrorPresentation.description}\n </p>\n {assistantErrorPresentation.providerMessage && (\n <div className=\"mt-1\">\n <p\n className={cn(\n \"wrap-break-word text-muted-foreground text-xs\",\n !providerMessageExpanded && \"line-clamp-3\",\n )}\n >\n {assistantErrorPresentation.providerMessage}\n </p>\n {assistantErrorPresentation.providerMessage.length > 180 && (\n <button\n className=\"mt-0.5 font-medium text-foreground text-xs hover:underline\"\n onClick={() => setProviderMessageExpanded((current) => !current)}\n type=\"button\"\n >\n {t(\n providerMessageExpanded\n ? \"errors.hideProviderDetails\"\n : \"errors.showProviderDetails\",\n )}\n </button>\n )}\n </div>\n )}\n {(assistantErrorPresentation.upstreamStatus ||\n assistantErrorPresentation.providerRequestId) && (\n <p className=\"mt-1 text-[11px] text-muted-foreground/80\">\n {[\n assistantErrorPresentation.upstreamStatus\n ? t(\"errors.upstreamStatus\", {\n status: assistantErrorPresentation.upstreamStatus,\n })\n : null,\n assistantErrorPresentation.providerRequestId\n ? t(\"errors.providerRequestId\", {\n requestId: assistantErrorPresentation.providerRequestId,\n })\n : null,\n ]\n .filter(Boolean)\n .join(\" · \")}\n </p>\n )}\n <p className=\"mt-1 text-muted-foreground/80\">{assistantErrorPresentation.hint}</p>\n {(assistantErrorPresentation.retryable || onExportDetails) && (\n <div className=\"mt-1.5 flex flex-wrap gap-x-3 gap-y-1\">\n {assistantErrorPresentation.retryable && (\n <button\n className=\"font-medium text-foreground text-xs hover:underline\"\n onClick={retry}\n type=\"button\"\n >\n {t(\"errors.retry\")}\n </button>\n )}\n {onExportDetails && (\n <button\n className=\"font-medium text-foreground text-xs hover:underline\"\n onClick={() => onExportDetails(exportDetailsButtonRef.current)}\n ref={exportDetailsButtonRef}\n type=\"button\"\n >\n {t(\"errors.exportDetails\")}\n </button>\n )}\n </div>\n )}\n </div>\n </div>\n <button\n aria-label={t(\"errors.dismissAssistant\")}\n className=\"shrink-0 text-muted-foreground text-xs hover:text-foreground\"\n onClick={dismissError}\n type=\"button\"\n >\n {t(\"errors.dismiss\")}\n </button>\n </div>\n )}\n\n <div className=\"shrink-0 border-t border-border bg-background p-2\">\n <SurveyAssistantPromptInput\n attachmentButtonClassName=\"size-8\"\n className={cn(\n \"rounded-xl border-border bg-popover shadow-sm transition-colors\",\n isAssistantTurnActive && \"border-border/60 bg-muted/50 shadow-none\",\n )}\n disabled={isAssistantTurnActive}\n footerClassName={cn(\"transition-colors\", isAssistantTurnActive && \"bg-muted/30\")}\n formProps={{ \"aria-busy\": isAssistantTurnActive }}\n modelId={modelId}\n models={models}\n onModelChange={onModelChange}\n onStop={stop}\n onSubmit={handleSubmit}\n status={status}\n textareaClassName=\"min-h-11 max-h-28 px-3 pt-2.5 pb-1.5 transition-colors disabled:placeholder:text-muted-foreground/60\"\n textareaProps={{ autoFocus: focusPromptOnMount }}\n textareaRef={promptTextareaRef}\n />\n </div>\n </aside>\n );\n};\n\nconst SELECTED_THREAD_STORAGE_KEY = \"survey-assistant-selected-thread\";\n\nconst createThreadTitle = (text: string, fallback: string) => {\n const normalized = text.replace(/\\s+/g, \" \").trim();\n if (!normalized) return fallback;\n const words = normalized.split(\" \").slice(0, 8).join(\" \");\n return words.length > 64 ? `${words.slice(0, 61).trimEnd()}...` : words;\n};\n\nconst mergeThreads = (\n current: SurveyAssistantThread[],\n incoming: SurveyAssistantThread[],\n): SurveyAssistantThread[] => {\n const byId = new Map(current.map((thread) => [thread.id, thread]));\n for (const thread of incoming) byId.set(thread.id, thread);\n return [...byId.values()].sort(\n (left, right) => Date.parse(right.updatedAt) - Date.parse(left.updatedAt),\n );\n};\n\nconst mergeRecentThreadPage = (\n current: SurveyAssistantThread[],\n recent: SurveyAssistantThread[],\n): SurveyAssistantThread[] => {\n if (recent.length === 0) return [];\n const oldestRecentUpdate = Math.min(...recent.map((thread) => Date.parse(thread.updatedAt)));\n const olderThreads = Number.isFinite(oldestRecentUpdate)\n ? current.filter((thread) => Date.parse(thread.updatedAt) <= oldestRecentUpdate)\n : current;\n return mergeThreads(olderThreads, recent);\n};\n\nconst listThreadPage = async (\n client: SurveyAssistantThreadClient,\n cursor?: string,\n): Promise<SurveyAssistantThreadList> => {\n if (client.listPage) return client.listPage(cursor ? { cursor } : undefined);\n return cursor ? { threads: [] } : { threads: await client.list() };\n};\n\ntype SurveyAssistantPanelContentProps = Omit<\n SurveyAssistantPanelProps,\n \"language\" | \"localizations\"\n>;\n\ninterface PendingInitialLaunch {\n input: SurveyAssistantThreadLaunch;\n onSubmitted(): void;\n}\n\nconst SurveyAssistantPanelContent = ({\n embedded = false,\n modelId,\n models = [],\n onConfirmDeleteThread,\n onModelChange = () => {},\n onTurnActiveChange: onAssistantTurnActiveChange,\n resourceId,\n selectedThreadStorageKey,\n supportBundle,\n surveyId,\n threadApi,\n threadClient: providedThreadClient,\n threadLauncher,\n ...sessionProps\n}: SurveyAssistantPanelContentProps) => {\n const t = useSurveyAssistantTranslation();\n const supportBundleEnabled = isSurveyAssistantSupportBundleEnabled(supportBundle);\n const threadClient = useMemo(\n () => providedThreadClient ?? createSurveyAssistantThreadClient(threadApi),\n [providedThreadClient, threadApi],\n );\n const storageKey =\n selectedThreadStorageKey === false\n ? null\n : (selectedThreadStorageKey ??\n `${SELECTED_THREAD_STORAGE_KEY}:${encodeURIComponent(resourceId)}${\n surveyId ? `:${encodeURIComponent(surveyId)}` : \"\"\n }`);\n const [threads, setThreads] = useState<SurveyAssistantThread[]>([]);\n const [nextThreadCursor, setNextThreadCursor] = useState<string>();\n const [selectedThread, setSelectedThread] = useState<SurveyAssistantThread | null>(null);\n const [initialMessages, setInitialMessages] = useState<UIMessage[]>([]);\n const [nextMessageCursor, setNextMessageCursor] = useState<string>();\n const [historyOpen, setHistoryOpen] = useState(false);\n const [threadSearch, setThreadSearch] = useState(\"\");\n const [loadingOlderThreads, setLoadingOlderThreads] = useState(false);\n const [editingThreadId, setEditingThreadId] = useState<string | null>(null);\n const [editingTitle, setEditingTitle] = useState(\"\");\n const [threadError, setThreadError] = useState<string | null>(null);\n const [loadingThread, setLoadingThread] = useState(true);\n const [threadLoadAttempt, setThreadLoadAttempt] = useState(0);\n const [assistantTurnActive, setAssistantTurnActive] = useState(false);\n const [initialLaunch, setInitialLaunch] = useState<PendingInitialLaunch>();\n const [promptFocusThreadId, setPromptFocusThreadId] = useState<string>();\n const [diagnosticStore] = useState<SurveyAssistantDiagnosticStore>(() => {\n try {\n return createSurveyAssistantDiagnosticStore(supportBundle?.limits);\n } catch {\n return createSurveyAssistantDiagnosticStore();\n }\n });\n const [supportBundleOpen, setSupportBundleOpen] = useState(false);\n const [supportBundleLoading, setSupportBundleLoading] = useState(false);\n const [supportBundleError, setSupportBundleError] = useState<string>();\n const [preparedSupportBundle, setPreparedSupportBundle] =\n useState<PreparedSurveyAssistantSupportBundle>();\n const historyControlsRef = useRef<HTMLDivElement>(null);\n const historyButtonRef = useRef<HTMLButtonElement>(null);\n const loadingAllThreadsRef = useRef(false);\n const supportBundleAbortRef = useRef<AbortController | null>(null);\n const supportBundleFocusReturnRef = useRef<HTMLElement | null>(null);\n const supportBundleThreadIdRef = useRef<string>(undefined);\n\n const selectModel = useCallback(\n (modelId: string) => {\n if (!models.some((model) => model.id === modelId)) return;\n onModelChange(modelId);\n },\n [models, onModelChange],\n );\n\n const selectThread = useCallback(\n async (thread: Pick<SurveyAssistantThread, \"id\">, reportError = true) => {\n setPromptFocusThreadId(undefined);\n setLoadingThread(true);\n setThreadError(null);\n try {\n const transcript = await threadClient.read(thread.id);\n setSelectedThread(transcript.thread);\n setInitialMessages(transcript.messages as UIMessage[]);\n setNextMessageCursor(transcript.nextCursor);\n setHistoryOpen(false);\n if (storageKey) window.localStorage.setItem(storageKey, thread.id);\n return transcript.thread;\n } catch (error) {\n if (reportError) {\n setThreadError(parseSurveyAssistantError(error).detail ?? t(\"errors.fallbackDetail\"));\n }\n return null;\n } finally {\n setLoadingThread(false);\n }\n },\n [storageKey, t, threadClient],\n );\n\n const createThread = useCallback(\n async (launch?: SurveyAssistantThreadLaunch) => {\n setLoadingThread(true);\n setThreadError(null);\n try {\n const thread = await threadClient.create(launch?.title);\n setPromptFocusThreadId(launch ? undefined : thread.id);\n setThreads((current) => mergeThreads(current, [thread]));\n setSelectedThread(thread);\n setInitialMessages([]);\n setNextMessageCursor(undefined);\n setHistoryOpen(false);\n if (storageKey) window.localStorage.setItem(storageKey, thread.id);\n return thread;\n } catch (error) {\n setThreadError(parseSurveyAssistantError(error).detail ?? t(\"errors.fallbackDetail\"));\n if (launch) throw error;\n return null;\n } finally {\n setLoadingThread(false);\n }\n },\n [storageKey, t, threadClient],\n );\n\n useEffect(() => {\n let cancelled = false;\n void listThreadPage(threadClient)\n .then(async (page) => {\n if (cancelled) return;\n const availableThreads = page.threads;\n setThreads(availableThreads);\n setNextThreadCursor(page.nextCursor);\n const rememberedId = storageKey ? window.localStorage.getItem(storageKey) : null;\n const rememberedThread = availableThreads.find((thread) => thread.id === rememberedId);\n if (rememberedId && !rememberedThread) {\n const restored = await selectThread({ id: rememberedId }, false);\n if (restored) {\n setThreads((current) => mergeThreads(current, [restored]));\n return;\n }\n }\n const initialThread = rememberedThread ?? availableThreads[0];\n if (initialThread) {\n await selectThread(initialThread);\n } else {\n await createThread();\n }\n })\n .catch((error) => {\n if (!cancelled) {\n setThreadError(parseSurveyAssistantError(error).detail ?? t(\"errors.fallbackDetail\"));\n setLoadingThread(false);\n }\n });\n return () => {\n cancelled = true;\n };\n }, [createThread, selectThread, storageKey, t, threadClient, threadLoadAttempt]);\n\n const retryInitialThreadLoad = useCallback(() => {\n setThreadError(null);\n setLoadingThread(true);\n setThreadLoadAttempt((attempt) => attempt + 1);\n }, []);\n\n const loadOlderThreads = useCallback(async () => {\n if (!nextThreadCursor || loadingOlderThreads) return;\n setLoadingOlderThreads(true);\n try {\n const page = await listThreadPage(threadClient, nextThreadCursor);\n setThreads((current) => mergeThreads(current, page.threads));\n setNextThreadCursor(page.nextCursor);\n } catch (error) {\n setThreadError(parseSurveyAssistantError(error).detail ?? t(\"errors.fallbackDetail\"));\n } finally {\n setLoadingOlderThreads(false);\n }\n }, [loadingOlderThreads, nextThreadCursor, t, threadClient]);\n\n const loadEarlierMessages = useCallback(async (): Promise<UIMessage[]> => {\n if (!selectedThread || !nextMessageCursor) return [];\n try {\n const transcript = await threadClient.read(selectedThread.id, nextMessageCursor);\n setNextMessageCursor(transcript.nextCursor);\n return transcript.messages as UIMessage[];\n } catch (error) {\n setThreadError(parseSurveyAssistantError(error).detail ?? t(\"errors.fallbackDetail\"));\n return [];\n }\n }, [nextMessageCursor, selectedThread, t, threadClient]);\n\n const loadAllThreadsForSearch = useCallback(async () => {\n if (!nextThreadCursor || loadingAllThreadsRef.current) return;\n loadingAllThreadsRef.current = true;\n setLoadingOlderThreads(true);\n try {\n let cursor: string | undefined = nextThreadCursor;\n while (cursor) {\n const page = await listThreadPage(threadClient, cursor);\n setThreads((current) => mergeThreads(current, page.threads));\n cursor = page.nextCursor;\n setNextThreadCursor(cursor);\n }\n } catch (error) {\n setThreadError(parseSurveyAssistantError(error).detail ?? t(\"errors.fallbackDetail\"));\n } finally {\n loadingAllThreadsRef.current = false;\n setLoadingOlderThreads(false);\n }\n }, [nextThreadCursor, t, threadClient]);\n\n useEffect(() => {\n if (threadSearch.trim()) void loadAllThreadsForSearch();\n }, [loadAllThreadsForSearch, threadSearch]);\n\n useEffect(() => {\n if (!threadLauncher || loadingThread) return;\n return connectSurveyAssistantThreadLauncher(threadLauncher, async (launch) => {\n const thread = await createThread(launch);\n if (!thread) throw new Error(\"The survey assistant thread could not be created.\");\n return new Promise<SurveyAssistantThread>((resolve) => {\n setInitialLaunch({\n input: launch,\n onSubmitted: () => resolve(thread),\n });\n });\n });\n }, [createThread, loadingThread, threadLauncher]);\n\n const renameThread = useCallback(\n async (thread: SurveyAssistantThread, title: string) => {\n const normalized = title.trim();\n if (!normalized || normalized === thread.title) {\n setEditingThreadId(null);\n setEditingTitle(\"\");\n return;\n }\n try {\n const updated = await threadClient.rename(thread.id, normalized);\n setThreads((current) => current.map((item) => (item.id === updated.id ? updated : item)));\n setSelectedThread((current) => (current?.id === updated.id ? updated : current));\n setEditingThreadId(null);\n setEditingTitle(\"\");\n } catch (error) {\n setThreadError(parseSurveyAssistantError(error).detail ?? t(\"errors.fallbackDetail\"));\n }\n },\n [t, threadClient],\n );\n\n const setAutomaticTitle = useCallback(\n async (thread: SurveyAssistantThread, title?: string) => {\n try {\n const updated = await threadClient.setAutomaticTitle(thread.id, title);\n setThreads((current) => current.map((item) => (item.id === updated.id ? updated : item)));\n setSelectedThread((current) => (current?.id === updated.id ? updated : current));\n setEditingThreadId(null);\n setEditingTitle(\"\");\n } catch (error) {\n setThreadError(parseSurveyAssistantError(error).detail ?? t(\"errors.fallbackDetail\"));\n }\n },\n [t, threadClient],\n );\n\n const beginEditingThread = useCallback((thread: SurveyAssistantThread) => {\n setEditingThreadId(thread.id);\n setEditingTitle(thread.title);\n }, []);\n\n const cancelEditingThread = useCallback(() => {\n setEditingThreadId(null);\n setEditingTitle(\"\");\n }, []);\n\n const handleTurnActiveChange = useCallback(\n (active: boolean) => {\n setAssistantTurnActive(active);\n onAssistantTurnActiveChange?.(active);\n if (active) {\n cancelEditingThread();\n setHistoryOpen(false);\n }\n },\n [cancelEditingThread, onAssistantTurnActiveChange],\n );\n\n const commitEditingThread = useCallback(async () => {\n if (!editingThreadId) return;\n const thread = threads.find((item) => item.id === editingThreadId);\n const title = editingTitle;\n if (thread) await renameThread(thread, title);\n }, [editingThreadId, editingTitle, renameThread, threads]);\n\n const closeSupportBundle = useCallback(() => {\n supportBundleAbortRef.current?.abort();\n supportBundleAbortRef.current = null;\n setSupportBundleOpen(false);\n setSupportBundleLoading(false);\n setPreparedSupportBundle(undefined);\n }, []);\n\n const openSupportBundle = useCallback(\n async (focusReturnElement?: HTMLElement | null) => {\n if (!supportBundleEnabled || !selectedThread || assistantTurnActive) return;\n supportBundleFocusReturnRef.current = focusReturnElement ?? historyButtonRef.current;\n await commitEditingThread();\n setHistoryOpen(false);\n supportBundleAbortRef.current?.abort();\n const abortController = new AbortController();\n supportBundleAbortRef.current = abortController;\n setSupportBundleOpen(true);\n supportBundleThreadIdRef.current = selectedThread.id;\n setSupportBundleLoading(true);\n setSupportBundleError(undefined);\n setPreparedSupportBundle(undefined);\n try {\n const prepared = await prepareSurveyAssistantSupportBundle({\n config: supportBundle,\n controller: sessionProps.controller,\n diagnosticStore,\n resourceId,\n signal: abortController.signal,\n threadClient,\n threadId: selectedThread.id,\n });\n if (abortController.signal.aborted || selectedThread.id !== prepared.threadId) return;\n setPreparedSupportBundle(prepared);\n } catch (error) {\n if (abortController.signal.aborted) return;\n setSupportBundleError(\n parseSurveyAssistantError(error).detail ?? t(\"supportBundle.preparationFailed\"),\n );\n } finally {\n if (supportBundleAbortRef.current === abortController) {\n supportBundleAbortRef.current = null;\n setSupportBundleLoading(false);\n }\n }\n },\n [\n assistantTurnActive,\n commitEditingThread,\n diagnosticStore,\n resourceId,\n selectedThread,\n sessionProps.controller,\n supportBundle,\n supportBundleEnabled,\n t,\n threadClient,\n ],\n );\n\n useEffect(\n () => () => {\n supportBundleAbortRef.current?.abort();\n },\n [],\n );\n\n const deleteThread = useCallback(\n async (thread: SurveyAssistantThread) => {\n const confirmed = onConfirmDeleteThread\n ? await onConfirmDeleteThread(thread)\n : window.confirm(t(\"threads.deleteConfirm\", { title: thread.title }));\n if (!confirmed) return;\n try {\n await threadClient.delete(thread.id);\n diagnosticStore.deleteThread(thread.id);\n const remaining = threads.filter((item) => item.id !== thread.id);\n setThreads(remaining);\n if (selectedThread?.id === thread.id) {\n if (remaining[0]) await selectThread(remaining[0]);\n else await createThread();\n }\n } catch (error) {\n setThreadError(parseSurveyAssistantError(error).detail ?? t(\"errors.fallbackDetail\"));\n }\n },\n [\n createThread,\n diagnosticStore,\n onConfirmDeleteThread,\n selectThread,\n selectedThread,\n t,\n threadClient,\n threads,\n ],\n );\n\n const handleFirstSubmit = useCallback(\n (text: string) => {\n if (!selectedThread || selectedThread.titleMode === \"manual\") {\n return;\n }\n void setAutomaticTitle(selectedThread, createThreadTitle(text, t(\"threads.newChat\")));\n },\n [selectedThread, setAutomaticTitle, t],\n );\n\n const handleInitialLaunchHandled = useCallback(() => {\n if (!initialLaunch) return;\n setInitialLaunch(undefined);\n initialLaunch.onSubmitted();\n }, [initialLaunch]);\n\n const refreshThreadList = useCallback(\n async (reportError: boolean) => {\n try {\n const page = await listThreadPage(threadClient);\n setThreads((current) => mergeRecentThreadPage(current, page.threads));\n const current = page.threads.find((thread) => thread.id === selectedThread?.id);\n if (current && !editingThreadId) {\n setSelectedThread((selected) => {\n if (!selected || selected.id !== current.id) return selected;\n return selected.title === current.title &&\n selected.titleMode === current.titleMode &&\n selected.updatedAt === current.updatedAt\n ? selected\n : current;\n });\n }\n } catch (error) {\n if (reportError) {\n setThreadError(parseSurveyAssistantError(error).detail ?? t(\"errors.fallbackDetail\"));\n }\n }\n },\n [editingThreadId, selectedThread?.id, t, threadClient],\n );\n\n const toggleHistory = useCallback(() => {\n if (historyOpen) {\n void commitEditingThread();\n setHistoryOpen(false);\n return;\n }\n\n setHistoryOpen(true);\n void refreshThreadList(true);\n }, [commitEditingThread, historyOpen, refreshThreadList]);\n\n const handleTurnSettled = useCallback(() => {\n void refreshThreadList(false);\n }, [refreshThreadList]);\n\n useEffect(() => {\n if (!historyOpen) return;\n\n const handlePointerDown = (event: PointerEvent) => {\n if (!historyControlsRef.current?.contains(event.target as Node)) {\n void commitEditingThread();\n setHistoryOpen(false);\n }\n };\n const handleKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n cancelEditingThread();\n setHistoryOpen(false);\n }\n };\n\n document.addEventListener(\"pointerdown\", handlePointerDown);\n document.addEventListener(\"keydown\", handleKeyDown);\n return () => {\n document.removeEventListener(\"pointerdown\", handlePointerDown);\n document.removeEventListener(\"keydown\", handleKeyDown);\n };\n }, [cancelEditingThread, commitEditingThread, historyOpen]);\n\n useEffect(() => {\n if (!loadingThread && selectedThread?.id === promptFocusThreadId) {\n setPromptFocusThreadId(undefined);\n }\n }, [loadingThread, promptFocusThreadId, selectedThread?.id]);\n\n useEffect(() => {\n if (!supportBundleOpen || supportBundleThreadIdRef.current === selectedThread?.id) {\n return;\n }\n closeSupportBundle();\n }, [closeSupportBundle, selectedThread?.id, supportBundleOpen]);\n\n useEffect(() => {\n const handleFocus = () => {\n void refreshThreadList(false);\n };\n\n window.addEventListener(\"focus\", handleFocus);\n return () => window.removeEventListener(\"focus\", handleFocus);\n }, [refreshThreadList]);\n\n const initialThreadLoadState = getSurveyAssistantInitialThreadLoadState({\n error: threadError,\n hasSelectedThread: Boolean(selectedThread),\n loading: loadingThread,\n });\n if (initialThreadLoadState || !selectedThread) {\n const initialLoadFailed = initialThreadLoadState === \"error\";\n return (\n <aside\n className={cn(\n \"flex h-full min-h-0 flex-col overflow-visible bg-background\",\n !embedded && \"rounded-xl border border-border shadow-sm\",\n )}\n >\n <header className=\"box-content flex h-9 shrink-0 items-center border-b border-border bg-background px-2.5\">\n <SurveyAssistantHeaderIdentity\n indicatorClassName={initialLoadFailed ? \"bg-destructive\" : \"animate-pulse bg-blue-500\"}\n status={initialLoadFailed ? t(\"panel.controlsUnavailable\") : t(\"panel.loadingChats\")}\n title={t(\"panel.title\")}\n />\n </header>\n <div className=\"flex min-h-0 flex-1 items-center justify-center p-6 text-sm\">\n {initialLoadFailed ? (\n <div className=\"max-w-sm text-center\">\n <div className=\"font-medium text-foreground\">{t(\"panel.controlsUnavailable\")}</div>\n <div className=\"mt-1 text-muted-foreground\">{threadError}</div>\n <button\n className=\"mt-3 rounded-md border border-border bg-background px-3 py-1.5 font-medium text-foreground hover:bg-muted\"\n onClick={retryInitialThreadLoad}\n type=\"button\"\n >\n {t(\"errors.retry\")}\n </button>\n </div>\n ) : (\n <div className=\"flex items-center text-muted-foreground\">\n <LoaderCircleIcon className=\"mr-2 size-4 animate-spin\" />\n {t(\"panel.loadingChats\")}\n </div>\n )}\n </div>\n </aside>\n );\n }\n\n const normalizedThreadSearch = threadSearch.trim().toLocaleLowerCase();\n const visibleThreads = normalizedThreadSearch\n ? threads.filter((thread) => thread.title.toLocaleLowerCase().includes(normalizedThreadSearch))\n : threads;\n\n const threadControls = (\n <div className=\"relative flex shrink-0 items-center gap-1\" ref={historyControlsRef}>\n <button\n aria-label={t(\"threads.newChat\")}\n className=\"flex size-8 items-center justify-center rounded-lg text-muted-foreground hover:bg-muted hover:text-foreground disabled:pointer-events-none disabled:opacity-50\"\n disabled={assistantTurnActive}\n onClick={() => void createThread()}\n title={t(\"threads.newChat\")}\n type=\"button\"\n >\n <PlusIcon className=\"size-4\" />\n </button>\n <button\n aria-expanded={historyOpen}\n aria-label={t(\"threads.history\")}\n className=\"flex size-8 items-center justify-center rounded-lg text-muted-foreground hover:bg-muted hover:text-foreground disabled:pointer-events-none disabled:opacity-50\"\n disabled={assistantTurnActive}\n onClick={toggleHistory}\n ref={historyButtonRef}\n title={t(\"threads.history\")}\n type=\"button\"\n >\n <HistoryIcon className=\"size-4\" />\n </button>\n {historyOpen && (\n <div className=\"absolute top-10 right-0 z-30 w-72 overflow-hidden rounded-lg border border-border bg-popover text-popover-foreground shadow-lg\">\n <div className=\"border-b border-border px-3 py-2 font-medium text-xs\">\n {t(\"threads.recent\")}\n </div>\n <div className=\"relative border-b border-border p-2\">\n <SearchIcon className=\"pointer-events-none absolute top-1/2 left-4 size-3.5 -translate-y-1/2 text-muted-foreground\" />\n <input\n aria-label={t(\"threads.search\")}\n className=\"h-8 w-full rounded-md border border-input bg-background pr-2 pl-8 text-xs outline-none placeholder:text-muted-foreground focus:ring-1 focus:ring-ring\"\n onChange={(event) => setThreadSearch(event.currentTarget.value)}\n placeholder={t(\"threads.search\")}\n type=\"search\"\n value={threadSearch}\n />\n </div>\n <div className=\"max-h-72 overflow-y-auto p-1\">\n {visibleThreads.map((thread) => (\n <div\n className={cn(\n \"group flex min-h-10 items-center gap-1 rounded-md px-2\",\n thread.id === selectedThread.id ? \"bg-muted\" : \"hover:bg-muted/60\",\n )}\n key={thread.id}\n >\n {editingThreadId === thread.id ? (\n <>\n <input\n autoFocus\n className=\"min-w-0 flex-1 rounded border border-input bg-background px-1.5 py-1 text-xs outline-none focus:ring-1 focus:ring-ring\"\n onBlur={() => void commitEditingThread()}\n onChange={(event) => setEditingTitle(event.currentTarget.value)}\n onKeyDown={(event) => {\n if (event.key === \"Enter\") {\n event.preventDefault();\n void commitEditingThread();\n }\n if (event.key === \"Escape\") {\n event.preventDefault();\n event.stopPropagation();\n cancelEditingThread();\n setHistoryOpen(false);\n }\n }}\n value={editingTitle}\n />\n {thread.titleMode === \"manual\" && (\n <button\n aria-label={t(\"threads.automaticTitle\")}\n className=\"flex h-7 shrink-0 items-center gap-1 rounded px-1.5 text-muted-foreground text-xs hover:bg-background hover:text-foreground\"\n onClick={() => void setAutomaticTitle(thread)}\n onMouseDown={(event) => event.preventDefault()}\n title={t(\"threads.automaticTitle\")}\n type=\"button\"\n >\n <SparklesIcon className=\"size-3\" />\n <span>{t(\"threads.automaticShort\")}</span>\n </button>\n )}\n </>\n ) : (\n <button\n className=\"min-w-0 flex-1 truncate py-2 text-left text-xs\"\n onClick={() => void selectThread(thread)}\n type=\"button\"\n >\n {thread.title}\n </button>\n )}\n <button\n aria-label={t(\"threads.rename\", { title: thread.title })}\n className=\"flex size-7 shrink-0 items-center justify-center rounded text-muted-foreground opacity-0 hover:bg-background hover:text-foreground group-hover:opacity-100\"\n onClick={() => beginEditingThread(thread)}\n title={t(\"threads.renameTitle\")}\n type=\"button\"\n >\n <PencilIcon className=\"size-3.5\" />\n </button>\n <button\n aria-label={t(\"threads.delete\", { title: thread.title })}\n className=\"flex size-7 shrink-0 items-center justify-center rounded text-muted-foreground opacity-0 hover:bg-background hover:text-foreground group-hover:opacity-100\"\n onClick={() => void deleteThread(thread)}\n title={t(\"threads.deleteTitle\")}\n type=\"button\"\n >\n <Trash2Icon className=\"size-3.5\" />\n </button>\n </div>\n ))}\n {visibleThreads.length === 0 && !loadingOlderThreads && (\n <div className=\"px-3 py-5 text-center text-muted-foreground text-xs\">\n {t(\"threads.noMatches\")}\n </div>\n )}\n {(nextThreadCursor || loadingOlderThreads) && (\n <button\n className=\"flex h-9 w-full items-center justify-center rounded-md text-muted-foreground text-xs hover:bg-muted hover:text-foreground disabled:pointer-events-none\"\n disabled={loadingOlderThreads || Boolean(normalizedThreadSearch)}\n onClick={() => void loadOlderThreads()}\n type=\"button\"\n >\n {loadingOlderThreads ? (\n <>\n <LoaderCircleIcon className=\"mr-1.5 size-3.5 animate-spin\" />\n {normalizedThreadSearch ? t(\"threads.searching\") : t(\"threads.loadingOlder\")}\n </>\n ) : (\n t(\"threads.loadOlder\")\n )}\n </button>\n )}\n </div>\n {supportBundleEnabled && (\n <div className=\"border-t border-border p-1\">\n <button\n className=\"flex h-9 w-full items-center gap-2 rounded-md px-2 text-left text-muted-foreground text-xs hover:bg-muted hover:text-foreground\"\n onClick={() => void openSupportBundle(historyButtonRef.current)}\n type=\"button\"\n >\n <PackageOpenIcon className=\"size-3.5\" />\n {t(\"threads.exportSupportBundle\")}\n </button>\n </div>\n )}\n </div>\n )}\n </div>\n );\n\n return (\n <div className=\"relative h-full min-h-0\">\n <SurveyAssistantChatPanel\n {...sessionProps}\n embedded={embedded}\n focusPromptOnMount={selectedThread.id === promptFocusThreadId}\n hasEarlierMessages={Boolean(nextMessageCursor)}\n initialLaunch={initialLaunch?.input}\n initialMessages={initialMessages}\n key={selectedThread.id}\n modelId={modelId}\n models={models}\n diagnosticStore={diagnosticStore}\n onExportDetails={\n supportBundleEnabled ? (trigger) => void openSupportBundle(trigger) : undefined\n }\n onInitialLaunchHandled={handleInitialLaunchHandled}\n onModelChange={selectModel}\n onFirstSubmit={handleFirstSubmit}\n onLoadEarlierMessages={loadEarlierMessages}\n onTurnSettled={handleTurnSettled}\n onTurnActiveChange={handleTurnActiveChange}\n resourceId={resourceId}\n surveyId={surveyId}\n threadControls={threadControls}\n threadId={selectedThread.id}\n threadTitle={selectedThread.title}\n />\n {supportBundleEnabled && (\n <SurveyAssistantSupportBundleDialog\n config={supportBundle}\n error={supportBundleError}\n fallbackFocusReturnRef={historyButtonRef}\n focusReturnRef={supportBundleFocusReturnRef}\n loading={supportBundleLoading}\n onOpenChange={(open) => {\n if (!open) closeSupportBundle();\n }}\n open={supportBundleOpen}\n prepared={preparedSupportBundle}\n />\n )}\n {threadError && (\n <div className=\"absolute right-3 bottom-3 left-3 z-40 rounded-lg border border-destructive/20 bg-popover px-3 py-2 text-xs shadow-lg\">\n <div className=\"font-medium\">{t(\"panel.controlsUnavailable\")}</div>\n <div className=\"mt-0.5 text-muted-foreground\">{threadError}</div>\n <button\n className=\"mt-1 font-medium hover:underline\"\n onClick={() => setThreadError(null)}\n type=\"button\"\n >\n {t(\"errors.dismiss\")}\n </button>\n </div>\n )}\n </div>\n );\n};\n\nexport const SurveyAssistantPanel = ({\n language,\n localizations,\n ...props\n}: SurveyAssistantPanelProps) => (\n <div className=\"case-survey-assistant\">\n <SurveyAssistantLocalizationProvider language={language} localizations={localizations}>\n <SurveyAssistantPanelContent\n {...props}\n key={JSON.stringify([props.resourceId, props.surveyId])}\n />\n </SurveyAssistantLocalizationProvider>\n </div>\n);\n","\"use client\";\n\nimport {\n useSurveyAssistantModelCatalog,\n type SurveyAssistantLaunchUIContext,\n type SurveyAssistantThreadLauncher,\n} from \"../react\";\nimport { useCallback, useEffect, useState, type Ref } from \"react\";\nimport { SurveyAssistantLocalizationProvider } from \"./localization\";\nimport {\n SurveyAssistantPromptInput,\n type SurveyAssistantPromptInputMessage,\n} from \"./survey-assistant-prompt-input\";\nimport type { LocalizationCatalog } from \"@case-framework/ui-localization\";\nimport type { ComponentProps } from \"react\";\n\nexport interface SurveyAssistantThreadLauncherPromptProps {\n className?: string;\n disabled?: boolean;\n language?: string;\n localizations?: LocalizationCatalog;\n modelCatalogApi?: string;\n modelStorageKey?: string | false;\n onError?(error: unknown): void;\n onModelCatalogError?(error: Error): void;\n onSubmitted(): void;\n onValueChange?(value: string): void;\n placeholder?: string;\n textareaClassName?: string;\n textareaProps?: Omit<ComponentProps<\"textarea\">, \"className\" | \"placeholder\" | \"ref\">;\n textareaRef?: Ref<HTMLTextAreaElement>;\n threadLauncher: SurveyAssistantThreadLauncher;\n uiContext?: SurveyAssistantLaunchUIContext;\n value?: string;\n}\n\nconst SurveyAssistantThreadLauncherPromptContent = ({\n className,\n disabled = false,\n modelCatalogApi,\n modelStorageKey,\n onError,\n onModelCatalogError,\n onSubmitted,\n onValueChange,\n placeholder,\n textareaClassName,\n textareaProps,\n textareaRef,\n threadLauncher,\n uiContext,\n value,\n}: Omit<SurveyAssistantThreadLauncherPromptProps, \"language\" | \"localizations\">) => {\n const catalog = useSurveyAssistantModelCatalog({\n api: modelCatalogApi,\n storageKey: modelStorageKey,\n });\n const [submitting, setSubmitting] = useState(false);\n\n useEffect(() => {\n if (catalog.error) onModelCatalogError?.(catalog.error);\n }, [catalog.error, onModelCatalogError]);\n\n const submit = useCallback(\n async ({ files, text }: SurveyAssistantPromptInputMessage) => {\n if (disabled || submitting) return false;\n setSubmitting(true);\n try {\n await threadLauncher.startThread({\n files,\n modelId: catalog.modelId,\n prompt: text,\n uiContext,\n });\n onSubmitted();\n return true;\n } catch (error) {\n onError?.(error);\n return false;\n } finally {\n setSubmitting(false);\n }\n },\n [catalog.modelId, disabled, onError, onSubmitted, submitting, threadLauncher, uiContext],\n );\n\n return (\n <SurveyAssistantPromptInput\n attachmentsDisabled={submitting}\n className={className}\n disabled={disabled || submitting}\n modelDisabled={catalog.loading || submitting}\n modelId={catalog.modelId}\n models={catalog.models}\n onModelChange={catalog.selectModel}\n onSubmit={submit}\n onValueChange={onValueChange}\n placeholder={placeholder}\n textareaClassName={textareaClassName}\n textareaProps={textareaProps}\n textareaRef={textareaRef}\n value={value}\n />\n );\n};\n\nexport const SurveyAssistantThreadLauncherPrompt = ({\n language,\n localizations,\n ...props\n}: SurveyAssistantThreadLauncherPromptProps) => (\n <div className=\"case-survey-assistant\">\n <SurveyAssistantLocalizationProvider language={language} localizations={localizations}>\n <SurveyAssistantThreadLauncherPromptContent {...props} />\n </SurveyAssistantLocalizationProvider>\n </div>\n);\n","\"use client\";\n\nimport { useEffect } from \"react\";\nimport { useSurveyAssistantModelCatalog } from \"../react\";\nimport { SurveyAssistantPanel, type SurveyAssistantPanelProps } from \"./survey-assistant-panel\";\n\ntype SurveyAssistantPanelContentProps = Omit<\n SurveyAssistantPanelProps,\n \"modelId\" | \"models\" | \"onModelChange\"\n>;\n\nexport type ConnectedSurveyAssistantPanelProps = SurveyAssistantPanelContentProps & {\n modelCatalogApi?: string;\n modelStorageKey?: string | false;\n onModelCatalogError?(error: Error): void;\n onModelChange?(modelId: string): void;\n};\n\nexport const ConnectedSurveyAssistantPanel = ({\n modelCatalogApi,\n modelStorageKey,\n onModelCatalogError,\n onModelChange,\n ...props\n}: ConnectedSurveyAssistantPanelProps) => {\n const catalog = useSurveyAssistantModelCatalog({\n api: modelCatalogApi,\n onModelChange,\n storageKey: modelStorageKey,\n });\n\n useEffect(() => {\n if (catalog.error) onModelCatalogError?.(catalog.error);\n }, [catalog.error, onModelCatalogError]);\n\n return (\n <SurveyAssistantPanel\n {...props}\n modelId={catalog.modelId}\n models={catalog.models}\n onModelChange={catalog.selectModel}\n />\n );\n};\n"],"mappings":"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EACP,cAAc;EACd,qBAAqB;EACtB;CACD,OAAO;EACL,OAAO;EACP,aACE;EACF,gBAAgB;EAChB,sBACE;EACH;CACD,cAAc;EACZ,aAAa;GACX,OAAO;GACP,aAAa;GACb,QACE;GACH;EACD,UAAU;GACR,OAAO;GACP,aAAa;GACb,QACE;GACH;EACD,YAAY;GACV,OAAO;GACP,aAAa;GACb,QACE;GACH;EACD,QAAQ;GACN,OAAO;GACP,aAAa;GACb,QACE;GACH;EACD,QAAQ;GACN,OAAO;GACP,aAAa;GACb,QAAQ;GACT;EACD,QAAQ;GACN,OAAO;GACP,aAAa;GACb,QAAQ;GACT;EACD,iBAAiB;GACf,OAAO;GACP,aAAa;GACb,QACE;GACH;EACF;CACD,OAAO;EACL,aAAa;EACb,aAAa;EACb,WAAW;EACX,gBAAgB;EAChB,kBACE;EACF,sBACE;EACF,YAAY;EACZ,MAAM;EACN,MAAM;EACN,OAAO;EACP,cAAc;EACf;CACD,cAAc;EACZ,aAAa;EACb,gBAAgB;EAChB,YAAY;EACZ,mBAAmB;EACnB,gBAAgB;EAChB,SAAS;EACT,SAAS;EACT,YAAY;EACb;CACD,MAAM;EACJ,aAAa;EACb,cAAc;EACd,SAAS;GACP,aAAa;GACb,sBAAsB;GACtB,aAAa;GACb,aAAa;GACb,UAAU;GACV,aAAa;GACb,eAAe;GACf,eAAe;GACf,aAAa;GACb,oBAAoB;GACpB,SAAS;GACV;EACF;CACD,QAAQ;EACN,UAAU;EACV,SAAS;EACT,SAAS;EACT,WAAW;EACX,OAAO;EACP,YAAY;EACZ,UAAU;EACV,SAAS;EACT,SAAS;EACV;CACD,UAAU;EACR,OAAO;EACP,SAAS;EACT,WAAW;EACX,kBAAkB;EAClB,sBAAsB;EACtB,iBAAiB;EACjB,kBAAkB;EAClB,oBAAoB;EACpB,eAAe;EACf,aAAa;EACb,uBAAuB;EACvB,qBAAqB;EACrB,SAAS;EACT,QAAQ;EACR,cAAc;EACd,MAAM;EACN,SAAS;EACT,kBAAkB;EAClB,cAAc;EACd,eAAe;EACf,iBAAiB;EACjB,cAAc;EACd,eAAe;EACf,OAAO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"}
|