@firstlovecenter/ai-chat 0.9.0 → 0.9.2
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/CHANGELOG.md +26 -0
- package/dist/ui/index.cjs +65 -14
- package/dist/ui/index.cjs.map +1 -1
- package/dist/ui/index.d.cts +18 -2
- package/dist/ui/index.d.ts +18 -2
- package/dist/ui/index.js +65 -14
- package/dist/ui/index.js.map +1 -1
- package/package.json +1 -1
package/dist/ui/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/ui/_shared/cn.ts","../../src/ui/_shared/dropdown-menu.tsx","../../src/ui/_shared/title-editors.tsx","../../src/ui/_shared/chart-card.tsx","../../src/ui/_shared/chart.tsx","../../src/ui/answer-blocks.tsx","../../src/ui/ai-chat.tsx","../../src/ui/vercel-chat.tsx","../../src/ui/index.tsx"],"names":["DropdownMenuPrimitive","jsx","useState","useEffect","jsxs","React","RechartsPrimitive","config","Fragment","useMemo","PieChart","Pie","Cell","Label","BarChart","CartesianGrid","XAxis","YAxis","Bar","LineChart","Line","useRouter","useRef","useLayoutEffect","useCallback","PanelLeftClose","Plus","Link","Pencil","Trash2","Menu","Sparkles","Loader2","ChevronDown","Check","ArrowUp","Copy","RotateCcw","ChevronUp","formatDuration","PROVIDER_LABELS","TEXTAREA_MAX_PX","PROVIDER_DESCRIPTIONS","data","useChat","AnswerView","blocksToPlainText","UserChip","stored"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Minimal class-name combiner. The host uses `clsx + tailwind-merge`;\n * for the package we just filter falsy values and join. Duplicate or\n * conflicting tailwind classes are harmless at runtime — the host can\n * still layer its own `cn` if it cares about deduping.\n */\nexport function cn(...args: unknown[]): string {\n const out: string[] = [];\n for (const a of args) {\n if (!a) continue;\n if (typeof a === 'string') {\n out.push(a);\n } else if (Array.isArray(a)) {\n const inner = cn(...a);\n if (inner) out.push(inner);\n } else if (typeof a === 'object') {\n for (const [k, v] of Object.entries(a as Record<string, unknown>)) {\n if (v) out.push(k);\n }\n }\n }\n return out.join(' ');\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport { DropdownMenu as DropdownMenuPrimitive } from \"radix-ui\"\n\nimport { cn } from \"./cn\"\nimport { CheckIcon, ChevronRightIcon } from \"lucide-react\"\n\nfunction DropdownMenu({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {\n return <DropdownMenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />\n}\n\nfunction DropdownMenuPortal({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {\n return (\n <DropdownMenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />\n )\n}\n\nfunction DropdownMenuTrigger({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {\n return (\n <DropdownMenuPrimitive.Trigger\n data-slot=\"dropdown-menu-trigger\"\n {...props}\n />\n )\n}\n\nfunction DropdownMenuContent({\n className,\n align = \"start\",\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {\n return (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n data-slot=\"dropdown-menu-content\"\n sideOffset={sideOffset}\n align={align}\n className={cn(\"z-50 max-h-(--radix-dropdown-menu-content-available-height) w-(--radix-dropdown-menu-trigger-width) min-w-32 origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 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]:overflow-hidden data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\", className )}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n )\n}\n\nfunction DropdownMenuGroup({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {\n return (\n <DropdownMenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />\n )\n}\n\nfunction DropdownMenuItem({\n className,\n inset,\n variant = \"default\",\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean\n variant?: \"default\" | \"destructive\"\n}) {\n return (\n <DropdownMenuPrimitive.Item\n data-slot=\"dropdown-menu-item\"\n data-inset={inset}\n data-variant={variant}\n className={cn(\n \"group/dropdown-menu-item relative flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-[variant=destructive]:*:[svg]:text-destructive\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuCheckboxItem({\n className,\n children,\n checked,\n inset,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem> & {\n inset?: boolean\n}) {\n return (\n <DropdownMenuPrimitive.CheckboxItem\n data-slot=\"dropdown-menu-checkbox-item\"\n data-inset={inset}\n className={cn(\n \"relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n checked={checked}\n {...props}\n >\n <span\n className=\"pointer-events-none absolute right-2 flex items-center justify-center\"\n data-slot=\"dropdown-menu-checkbox-item-indicator\"\n >\n <DropdownMenuPrimitive.ItemIndicator>\n <CheckIcon\n />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n )\n}\n\nfunction DropdownMenuRadioGroup({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {\n return (\n <DropdownMenuPrimitive.RadioGroup\n data-slot=\"dropdown-menu-radio-group\"\n {...props}\n />\n )\n}\n\nfunction DropdownMenuRadioItem({\n className,\n children,\n inset,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem> & {\n inset?: boolean\n}) {\n return (\n <DropdownMenuPrimitive.RadioItem\n data-slot=\"dropdown-menu-radio-item\"\n data-inset={inset}\n className={cn(\n \"relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n <span\n className=\"pointer-events-none absolute right-2 flex items-center justify-center\"\n data-slot=\"dropdown-menu-radio-item-indicator\"\n >\n <DropdownMenuPrimitive.ItemIndicator>\n <CheckIcon\n />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n )\n}\n\nfunction DropdownMenuLabel({\n className,\n inset,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {\n inset?: boolean\n}) {\n return (\n <DropdownMenuPrimitive.Label\n data-slot=\"dropdown-menu-label\"\n data-inset={inset}\n className={cn(\n \"px-1.5 py-1 text-xs font-medium text-muted-foreground data-inset:pl-7\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n return (\n <DropdownMenuPrimitive.Separator\n data-slot=\"dropdown-menu-separator\"\n className={cn(\"-mx-1 my-1 h-px bg-border\", className)}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuShortcut({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"dropdown-menu-shortcut\"\n className={cn(\n \"ml-auto text-xs tracking-widest text-muted-foreground group-focus/dropdown-menu-item:text-accent-foreground\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuSub({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {\n return <DropdownMenuPrimitive.Sub data-slot=\"dropdown-menu-sub\" {...props} />\n}\n\nfunction DropdownMenuSubTrigger({\n className,\n inset,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {\n inset?: boolean\n}) {\n return (\n <DropdownMenuPrimitive.SubTrigger\n data-slot=\"dropdown-menu-sub-trigger\"\n data-inset={inset}\n className={cn(\n \"flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7 data-open:bg-accent data-open:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n {children}\n <ChevronRightIcon className=\"ml-auto\" />\n </DropdownMenuPrimitive.SubTrigger>\n )\n}\n\nfunction DropdownMenuSubContent({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {\n return (\n <DropdownMenuPrimitive.SubContent\n data-slot=\"dropdown-menu-sub-content\"\n className={cn(\"z-50 min-w-[96px] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-lg bg-popover p-1 text-popover-foreground shadow-lg ring-1 ring-foreground/10 duration-100 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-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\", className )}\n {...props}\n />\n )\n}\n\nexport {\n DropdownMenu,\n DropdownMenuPortal,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuLabel,\n DropdownMenuItem,\n DropdownMenuCheckboxItem,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubTrigger,\n DropdownMenuSubContent,\n}\n","/**\n * Shared inline title editors used by both the custom `AiChat` shell and\n * the Vercel AI SDK `VercelChat` shell. Lifted verbatim from\n * `ai-chat.tsx` so the two chat shells render identical sidebar/header\n * editors without divergence over time.\n */\n'use client';\n\nimport { useEffect, useState } from 'react';\n\n/**\n * Inline editor for a sidebar session row. Renders an autofocused\n * input with the row's current title pre-selected. Enter or blur\n * commits, Escape cancels — the parent decides what to do with the\n * resulting string (PATCH and update sidebar state, in our case).\n */\nexport function SidebarTitleEditor({\n initial,\n onSave,\n onCancel\n}: {\n initial: string;\n onSave: (next: string) => void;\n onCancel: () => void;\n}) {\n const [draft, setDraft] = useState(initial);\n const commit = () => {\n const trimmed = draft.trim();\n if (trimmed && trimmed !== initial) onSave(trimmed);\n else onCancel();\n };\n return (\n <input\n autoFocus\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n onFocus={(e) => e.currentTarget.select()}\n onClick={(e) => e.stopPropagation()}\n onBlur={commit}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n commit();\n } else if (e.key === 'Escape') {\n e.preventDefault();\n onCancel();\n }\n }}\n maxLength={200}\n className=\"w-full rounded-md border border-sidebar-border bg-sidebar-accent/40 px-2 py-1.5 text-sm text-sidebar-foreground focus:outline-none focus:ring-1 focus:ring-ring\"\n />\n );\n}\n\n/**\n * Inline-editable title for the chat header. Click the label to enter\n * edit mode — the input pre-selects the current title so a fresh name\n * just overwrites it. Enter or blur commits via `onSave`, Escape\n * cancels. Mirrors `SidebarTitleEditor` so renaming feels identical\n * whether the user clicks the title in the header or the pencil in\n * the sidebar.\n */\nexport function EditableTitle({\n title,\n onSave\n}: {\n title: string;\n onSave: (next: string) => void;\n}) {\n const [editing, setEditing] = useState(false);\n const [draft, setDraft] = useState(title);\n\n useEffect(() => {\n if (!editing) setDraft(title);\n }, [title, editing]);\n\n if (!editing) {\n return (\n <button\n type=\"button\"\n onClick={() => {\n setDraft(title);\n setEditing(true);\n }}\n className=\"w-64 max-w-full min-w-0 truncate rounded px-2 py-0.5 text-left hover:bg-accent hover:text-foreground\"\n title=\"Click to rename\"\n >\n {title}\n </button>\n );\n }\n\n const commit = () => {\n const trimmed = draft.trim();\n setEditing(false);\n if (trimmed && trimmed !== title) onSave(trimmed);\n };\n\n return (\n <input\n autoFocus\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n onFocus={(e) => e.currentTarget.select()}\n onBlur={commit}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n commit();\n } else if (e.key === 'Escape') {\n e.preventDefault();\n setEditing(false);\n setDraft(title);\n }\n }}\n className=\"w-64 max-w-full min-w-0 rounded border border-border bg-background px-2 py-0.5 text-sm text-foreground focus:outline-none focus:ring-1 focus:ring-ring\"\n maxLength={200}\n />\n );\n}\n","'use client';\n\nimport type { ReactNode } from 'react';\n\nimport { cn } from './cn';\n\n/**\n * Minimal port of the host's `ChartCard`. The host wraps its shadcn\n * `Card` primitive; we inline an equivalent flex-column with a header\n * and content area so the package doesn't need the full Card family.\n * Tailwind class semantics match (rounded/border/text-card-foreground).\n */\nexport function ChartCard({\n title,\n subtitle,\n children,\n className\n}: {\n title: string;\n subtitle?: string;\n children: ReactNode;\n className?: string;\n}) {\n return (\n <div\n className={cn(\n 'flex flex-col rounded-xl border border-border bg-card text-card-foreground shadow-sm',\n className\n )}\n >\n <div className=\"flex flex-col gap-1.5 p-6\">\n <h3 className=\"font-semibold leading-none tracking-tight\">{title}</h3>\n {subtitle ? (\n <p className=\"text-sm text-muted-foreground\">{subtitle}</p>\n ) : null}\n </div>\n <div className=\"p-6 pt-0\">{children}</div>\n </div>\n );\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as RechartsPrimitive from \"recharts\"\nimport type { TooltipValueType } from \"recharts\"\n\nimport { cn } from \"./cn\"\n\n// Format: { THEME_NAME: CSS_SELECTOR }\nconst THEMES = { light: \"\", dark: \".dark\" } as const\n\nconst INITIAL_DIMENSION = { width: 320, height: 200 } as const\ntype TooltipNameType = number | string\n\nexport type ChartConfig = Record<\n string,\n {\n label?: React.ReactNode\n icon?: React.ComponentType\n } & (\n | { color?: string; theme?: never }\n | { color?: never; theme: Record<keyof typeof THEMES, string> }\n )\n>\n\ntype ChartContextProps = {\n config: ChartConfig\n}\n\nconst ChartContext = React.createContext<ChartContextProps | null>(null)\n\nfunction useChart() {\n const context = React.useContext(ChartContext)\n\n if (!context) {\n throw new Error(\"useChart must be used within a <ChartContainer />\")\n }\n\n return context\n}\n\nfunction ChartContainer({\n id,\n className,\n children,\n config,\n initialDimension = INITIAL_DIMENSION,\n ...props\n}: React.ComponentProps<\"div\"> & {\n config: ChartConfig\n children: React.ComponentProps<\n typeof RechartsPrimitive.ResponsiveContainer\n >[\"children\"]\n initialDimension?: {\n width: number\n height: number\n }\n}) {\n const uniqueId = React.useId()\n const chartId = `chart-${id ?? uniqueId.replace(/:/g, \"\")}`\n\n return (\n <ChartContext.Provider value={{ config }}>\n <div\n data-slot=\"chart\"\n data-chart={chartId}\n className={cn(\n \"flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-hidden [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border [&_.recharts-sector]:outline-hidden [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-surface]:outline-hidden\",\n className\n )}\n {...props}\n >\n <ChartStyle id={chartId} config={config} />\n <RechartsPrimitive.ResponsiveContainer\n initialDimension={initialDimension}\n >\n {children}\n </RechartsPrimitive.ResponsiveContainer>\n </div>\n </ChartContext.Provider>\n )\n}\n\nconst ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {\n const colorConfig = Object.entries(config).filter(\n ([, config]) => config.theme ?? config.color\n )\n\n if (!colorConfig.length) {\n return null\n }\n\n return (\n <style\n dangerouslySetInnerHTML={{\n __html: Object.entries(THEMES)\n .map(\n ([theme, prefix]) => `\n${prefix} [data-chart=${id}] {\n${colorConfig\n .map(([key, itemConfig]) => {\n const color =\n itemConfig.theme?.[theme as keyof typeof itemConfig.theme] ??\n itemConfig.color\n return color ? ` --color-${key}: ${color};` : null\n })\n .join(\"\\n\")}\n}\n`\n )\n .join(\"\\n\"),\n }}\n />\n )\n}\n\nconst ChartTooltip = RechartsPrimitive.Tooltip\n\nfunction ChartTooltipContent({\n active,\n payload,\n className,\n indicator = \"dot\",\n hideLabel = false,\n hideIndicator = false,\n label,\n labelFormatter,\n labelClassName,\n formatter,\n color,\n nameKey,\n labelKey,\n}: React.ComponentProps<typeof RechartsPrimitive.Tooltip> &\n React.ComponentProps<\"div\"> & {\n hideLabel?: boolean\n hideIndicator?: boolean\n indicator?: \"line\" | \"dot\" | \"dashed\"\n nameKey?: string\n labelKey?: string\n } & Omit<\n RechartsPrimitive.DefaultTooltipContentProps<\n TooltipValueType,\n TooltipNameType\n >,\n \"accessibilityLayer\"\n >) {\n const { config } = useChart()\n\n const tooltipLabel = React.useMemo(() => {\n if (hideLabel || !payload?.length) {\n return null\n }\n\n const [item] = payload\n const key = `${labelKey ?? item?.dataKey ?? item?.name ?? \"value\"}`\n const itemConfig = getPayloadConfigFromPayload(config, item, key)\n const value =\n !labelKey && typeof label === \"string\"\n ? (config[label]?.label ?? label)\n : itemConfig?.label\n\n if (labelFormatter) {\n return (\n <div className={cn(\"font-medium\", labelClassName)}>\n {labelFormatter(value, payload)}\n </div>\n )\n }\n\n if (!value) {\n return null\n }\n\n return <div className={cn(\"font-medium\", labelClassName)}>{value}</div>\n }, [\n label,\n labelFormatter,\n payload,\n hideLabel,\n labelClassName,\n config,\n labelKey,\n ])\n\n if (!active || !payload?.length) {\n return null\n }\n\n const nestLabel = payload.length === 1 && indicator !== \"dot\"\n\n return (\n <div\n className={cn(\n \"grid min-w-32 items-start gap-1.5 rounded-lg border border-border/50 bg-background px-2.5 py-1.5 text-xs shadow-xl\",\n className\n )}\n >\n {!nestLabel ? tooltipLabel : null}\n <div className=\"grid gap-1.5\">\n {payload\n .filter((item) => item.type !== \"none\")\n .map((item, index) => {\n const key = `${nameKey ?? item.name ?? item.dataKey ?? \"value\"}`\n const itemConfig = getPayloadConfigFromPayload(config, item, key)\n const indicatorColor = color ?? item.payload?.fill ?? item.color\n\n return (\n <div\n key={index}\n className={cn(\n \"flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-muted-foreground\",\n indicator === \"dot\" && \"items-center\"\n )}\n >\n {formatter && item?.value !== undefined && item.name ? (\n formatter(item.value, item.name, item, index, item.payload)\n ) : (\n <>\n {itemConfig?.icon ? (\n <itemConfig.icon />\n ) : (\n !hideIndicator && (\n <div\n className={cn(\n \"shrink-0 rounded-[2px] border-(--color-border) bg-(--color-bg)\",\n {\n \"h-2.5 w-2.5\": indicator === \"dot\",\n \"w-1\": indicator === \"line\",\n \"w-0 border-[1.5px] border-dashed bg-transparent\":\n indicator === \"dashed\",\n \"my-0.5\": nestLabel && indicator === \"dashed\",\n }\n )}\n style={\n {\n \"--color-bg\": indicatorColor,\n \"--color-border\": indicatorColor,\n } as React.CSSProperties\n }\n />\n )\n )}\n <div\n className={cn(\n \"flex flex-1 justify-between leading-none\",\n nestLabel ? \"items-end\" : \"items-center\"\n )}\n >\n <div className=\"grid gap-1.5\">\n {nestLabel ? tooltipLabel : null}\n <span className=\"text-muted-foreground\">\n {itemConfig?.label ?? item.name}\n </span>\n </div>\n {item.value != null && (\n <span className=\"font-mono font-medium text-foreground tabular-nums\">\n {typeof item.value === \"number\"\n ? item.value.toLocaleString()\n : String(item.value)}\n </span>\n )}\n </div>\n </>\n )}\n </div>\n )\n })}\n </div>\n </div>\n )\n}\n\nconst ChartLegend = RechartsPrimitive.Legend\n\nfunction ChartLegendContent({\n className,\n hideIcon = false,\n payload,\n verticalAlign = \"bottom\",\n nameKey,\n}: React.ComponentProps<\"div\"> & {\n hideIcon?: boolean\n nameKey?: string\n} & RechartsPrimitive.DefaultLegendContentProps) {\n const { config } = useChart()\n\n if (!payload?.length) {\n return null\n }\n\n return (\n <div\n className={cn(\n \"flex items-center justify-center gap-4\",\n verticalAlign === \"top\" ? \"pb-3\" : \"pt-3\",\n className\n )}\n >\n {payload\n .filter((item) => item.type !== \"none\")\n .map((item, index) => {\n const key = `${nameKey ?? item.dataKey ?? \"value\"}`\n const itemConfig = getPayloadConfigFromPayload(config, item, key)\n\n return (\n <div\n key={index}\n className={cn(\n \"flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3 [&>svg]:text-muted-foreground\"\n )}\n >\n {itemConfig?.icon && !hideIcon ? (\n <itemConfig.icon />\n ) : (\n <div\n className=\"h-2 w-2 shrink-0 rounded-[2px]\"\n style={{\n backgroundColor: item.color,\n }}\n />\n )}\n {itemConfig?.label}\n </div>\n )\n })}\n </div>\n )\n}\n\nfunction getPayloadConfigFromPayload(\n config: ChartConfig,\n payload: unknown,\n key: string\n) {\n if (typeof payload !== \"object\" || payload === null) {\n return undefined\n }\n\n const payloadPayload =\n \"payload\" in payload &&\n typeof payload.payload === \"object\" &&\n payload.payload !== null\n ? payload.payload\n : undefined\n\n let configLabelKey: string = key\n\n if (\n key in payload &&\n typeof payload[key as keyof typeof payload] === \"string\"\n ) {\n configLabelKey = payload[key as keyof typeof payload] as string\n } else if (\n payloadPayload &&\n key in payloadPayload &&\n typeof payloadPayload[key as keyof typeof payloadPayload] === \"string\"\n ) {\n configLabelKey = payloadPayload[\n key as keyof typeof payloadPayload\n ] as string\n }\n\n return configLabelKey in config ? config[configLabelKey] : config[key]\n}\n\nexport {\n ChartContainer,\n ChartTooltip,\n ChartTooltipContent,\n ChartLegend,\n ChartLegendContent,\n ChartStyle,\n}\n","/**\n * Renders the structured answer of an `/api/agent` turn — the\n * `paragraph_brief | list | chart | table | callout` blocks that come\n * back over the SSE stream. Extracted from the original AskChat so both\n * the AiChat shell at /chat and the legacy renderer can share it\n * (and any visual tweak hits both pages at once).\n */\n'use client';\n\nimport { useMemo } from 'react';\nimport {\n Bar,\n BarChart,\n CartesianGrid,\n Cell,\n Label,\n Line,\n LineChart,\n Pie,\n PieChart,\n XAxis,\n YAxis\n} from 'recharts';\n\nimport { ChartCard } from './_shared/chart-card';\nimport {\n ChartContainer,\n ChartLegend,\n ChartLegendContent,\n ChartTooltip,\n ChartTooltipContent,\n type ChartConfig\n} from './_shared/chart';\nimport type { Block, ChartSpec } from '../server/tools/types';\n\nconst AI_CHART_PALETTE = [\n 'var(--chart-1)',\n 'var(--chart-2)',\n 'var(--chart-3)',\n 'var(--chart-4)',\n 'var(--chart-5)'\n];\n\nfunction aiChartConfig(keys: string[]): ChartConfig {\n const out: ChartConfig = {};\n keys.forEach((key, idx) => {\n out[key] = {\n label: key,\n color: AI_CHART_PALETTE[idx % AI_CHART_PALETTE.length]\n };\n });\n return out;\n}\n\nexport type BlockState =\n | { kind: 'paragraph_brief'; topic: string; key_facts: string[]; prose: string }\n | { kind: 'list'; style: 'bullet' | 'numbered'; items: string[]; title?: string }\n | { kind: 'chart'; title: string; spec: ChartSpec; data: Array<Record<string, unknown>> }\n | { kind: 'table'; title: string; columns: string[]; rows: unknown[][] }\n | { kind: 'callout'; tone: 'info' | 'warn' | 'success'; text: string };\n\nexport function sanitiseBlock(input: Block & { index: number }): BlockState {\n if (input.kind === 'paragraph_brief') {\n return {\n kind: 'paragraph_brief',\n topic: input.topic,\n key_facts: input.key_facts,\n prose: ''\n };\n }\n if (input.kind === 'list') {\n return { kind: 'list', style: input.style, items: input.items, title: input.title };\n }\n if (input.kind === 'chart') {\n return { kind: 'chart', title: input.title, spec: input.spec, data: input.data };\n }\n if (input.kind === 'table') {\n return {\n kind: 'table',\n title: input.title,\n columns: input.columns,\n rows: input.rows\n };\n }\n return { kind: 'callout', tone: input.tone, text: input.text };\n}\n\n/** Treat null / undefined / non-string entries as empty. Stored chats from\n * truncated reasoning-model responses can contain `null` items in\n * `key_facts` / `items`, and we don't want a defensive render to crash on\n * `null.trim()`. */\nfunction isBlankString(v: unknown): boolean {\n return typeof v !== 'string' || !v.trim();\n}\n\n/**\n * True when a block has no user-visible content. We hide these on render\n * so the model serving up an empty `callout` or `paragraph_brief` (e.g.\n * after being forced through a schema-satisfying present() call without\n * real data) doesn't paint a row of empty placeholder boxes for the\n * user. The agent loop tries to salvage these into a synthetic\n * paragraph_brief upstream — this is the defensive fallback.\n *\n * Defensive against malformed historical rows (null entries, missing\n * arrays, non-string values) — hydrating a previously-corrupted session\n * must never throw.\n */\nfunction isBlockEmpty(b: BlockState): boolean {\n if (b.kind === 'paragraph_brief') {\n if (typeof b.prose === 'string' && b.prose.trim()) return false;\n const facts = Array.isArray(b.key_facts) ? b.key_facts : [];\n return facts.length === 0 || facts.every(isBlankString);\n }\n if (b.kind === 'list') {\n const items = Array.isArray(b.items) ? b.items : [];\n return items.length === 0 || items.every(isBlankString);\n }\n if (b.kind === 'callout') return isBlankString(b.text);\n if (b.kind === 'chart') return !Array.isArray(b.data) || b.data.length === 0;\n if (b.kind === 'table') return !Array.isArray(b.rows) || b.rows.length === 0;\n return false;\n}\n\nexport function AnswerBlocks({ blocks }: { blocks: BlockState[] }) {\n const visible = blocks.filter((b) => !isBlockEmpty(b));\n return (\n <div className=\"flex flex-col gap-3\">\n {visible.map((b, i) => (\n <BlockView key={i} block={b} />\n ))}\n </div>\n );\n}\n\nfunction BlockView({ block }: { block: BlockState }) {\n if (block.kind === 'paragraph_brief') {\n return (\n <p className=\"whitespace-pre-wrap text-sm leading-6 text-foreground\">\n {block.prose || (\n <span className=\"text-muted-foreground\">{block.key_facts.join('. ')}…</span>\n )}\n </p>\n );\n }\n if (block.kind === 'list') {\n const Tag = block.style === 'numbered' ? 'ol' : 'ul';\n return (\n <div>\n {block.title && <p className=\"mb-1 text-sm font-medium\">{block.title}</p>}\n <Tag className={block.style === 'numbered' ? 'list-decimal pl-6' : 'list-disc pl-6'}>\n {block.items.map((it, i) => (\n <li key={i} className=\"text-sm leading-6\">\n {it}\n </li>\n ))}\n </Tag>\n </div>\n );\n }\n if (block.kind === 'chart') {\n return <AiChartBlock block={block} />;\n }\n if (block.kind === 'table') {\n return (\n <div className=\"overflow-x-auto rounded border border-border\">\n <p className=\"border-b border-border px-3 py-2 text-sm font-medium\">{block.title}</p>\n <table className=\"min-w-full text-sm\">\n <thead className=\"bg-muted/40\">\n <tr>\n {block.columns.map((c) => (\n <th key={c} className=\"px-3 py-2 text-left font-medium text-muted-foreground\">\n {c}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {block.rows.map((row, i) => (\n <tr key={i} className=\"border-t border-border\">\n {row.map((cell, j) => (\n <td key={j} className=\"px-3 py-2 text-foreground\">\n {cell == null ? '—' : String(cell)}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n }\n if (block.kind === 'callout') {\n const cls =\n block.tone === 'warn'\n ? 'border-amber-300 dark:border-amber-800 bg-amber-50 dark:bg-amber-950/30 text-amber-900 dark:text-amber-100'\n : block.tone === 'success'\n ? 'border-emerald-300 dark:border-emerald-800 bg-emerald-50 dark:bg-emerald-950/30 text-emerald-900 dark:text-emerald-100'\n : 'border-sky-300 bg-sky-50 text-sky-900';\n return <div className={`rounded border p-3 text-sm ${cls}`}>{block.text}</div>;\n }\n return null;\n}\n\nfunction AiChartBlock({ block }: { block: Extract<BlockState, { kind: 'chart' }> }) {\n const yKeys = Array.isArray(block.spec.y) ? block.spec.y : [block.spec.y];\n if (block.spec.type === 'pie') {\n return <AiPieChart block={block} valueKey={yKeys[0]} />;\n }\n if (block.spec.type === 'bar' || block.spec.type === 'stacked_bar') {\n return <AiBarChart block={block} yKeys={yKeys} stacked={block.spec.type === 'stacked_bar'} />;\n }\n return <AiLineChart block={block} yKeys={yKeys} />;\n}\n\nfunction AiPieChart({\n block,\n valueKey\n}: {\n block: Extract<BlockState, { kind: 'chart' }>;\n valueKey: string;\n}) {\n const config = useMemo(\n () => aiChartConfig(block.data.map((row) => String(row[block.spec.x] ?? ''))),\n [block.data, block.spec.x]\n );\n return (\n <ChartCard title={block.title}>\n <ChartContainer config={config} className=\"h-72 w-full\">\n <PieChart>\n <ChartTooltip content={<ChartTooltipContent hideLabel />} />\n <Pie\n data={block.data}\n dataKey={valueKey}\n nameKey={block.spec.x}\n innerRadius={60}\n strokeWidth={2}\n >\n {block.data.map((row, idx) => {\n const sliceKey = String(row[block.spec.x] ?? '');\n return <Cell key={sliceKey || idx} fill={`var(--color-${sliceKey})`} />;\n })}\n <Label\n content={({ viewBox }) => {\n if (!viewBox || !('cx' in viewBox)) return null;\n return (\n <text\n x={viewBox.cx}\n y={viewBox.cy}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n className=\"fill-foreground text-sm font-medium\"\n >\n {valueKey}\n </text>\n );\n }}\n />\n </Pie>\n <ChartLegend content={<ChartLegendContent nameKey={block.spec.x} />} />\n </PieChart>\n </ChartContainer>\n </ChartCard>\n );\n}\n\nfunction AiBarChart({\n block,\n yKeys,\n stacked\n}: {\n block: Extract<BlockState, { kind: 'chart' }>;\n yKeys: string[];\n stacked: boolean;\n}) {\n const config = useMemo(() => aiChartConfig(yKeys), [yKeys]);\n return (\n <ChartCard title={block.title}>\n <ChartContainer config={config} className=\"h-72 w-full\">\n <BarChart data={block.data} margin={{ left: 12, right: 12, top: 4 }}>\n <CartesianGrid vertical={false} strokeDasharray=\"3 3\" />\n <XAxis dataKey={block.spec.x} tickLine={false} axisLine={false} tickMargin={8} />\n <YAxis tickLine={false} axisLine={false} tickMargin={8} width={64} />\n <ChartTooltip content={<ChartTooltipContent />} />\n <ChartLegend content={<ChartLegendContent />} />\n {yKeys.map((k) => (\n <Bar\n key={k}\n dataKey={k}\n stackId={stacked ? 'stack' : undefined}\n fill={`var(--color-${k})`}\n radius={stacked ? [2, 2, 0, 0] : [4, 4, 0, 0]}\n />\n ))}\n </BarChart>\n </ChartContainer>\n </ChartCard>\n );\n}\n\nfunction AiLineChart({\n block,\n yKeys\n}: {\n block: Extract<BlockState, { kind: 'chart' }>;\n yKeys: string[];\n}) {\n const config = useMemo(() => aiChartConfig(yKeys), [yKeys]);\n return (\n <ChartCard title={block.title}>\n <ChartContainer config={config} className=\"h-72 w-full\">\n <LineChart data={block.data} margin={{ left: 12, right: 12, top: 4 }}>\n <CartesianGrid vertical={false} strokeDasharray=\"3 3\" />\n <XAxis dataKey={block.spec.x} tickLine={false} axisLine={false} tickMargin={8} />\n <YAxis tickLine={false} axisLine={false} tickMargin={8} width={64} />\n <ChartTooltip content={<ChartTooltipContent />} />\n <ChartLegend content={<ChartLegendContent />} />\n {yKeys.map((k) => (\n <Line\n key={k}\n type=\"monotone\"\n dataKey={k}\n stroke={`var(--color-${k})`}\n strokeWidth={2}\n dot={false}\n activeDot={{ r: 4 }}\n />\n ))}\n </LineChart>\n </ChartContainer>\n </ChartCard>\n );\n}\n","/**\n * AiChat — the shared chat shell rendered both at /chat (head\n * pastors / any authed user) and at /admin/ai (super_admin admin\n * surface). One component, one set of pixels: tweaks here propagate to\n * both pages.\n *\n * Layout:\n * ┌── collapsible session sidebar (chat history) ──┬── chat panel ──┐\n * │ + New chat │ empty hero │\n * │ • session 1 │ ─ or ─ │\n * │ • session 2 │ message list │\n * │ • … │ │\n * └────────────────────────────────────────────────┴── input pill ──┘\n *\n * Streaming protocol matches `app/api/agent/route.ts`: `meta`, `block`,\n * `prose`, `error`, `done` SSE frames. Sessions are persisted via\n * `/api/chat/sessions/*`; the agent route writes both the user turn\n * (on POST) and the assistant turn (when it finishes) when the client\n * passes `chatSessionId`.\n */\n'use client';\n\nimport {\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState\n} from 'react';\nimport { useRouter } from 'next/navigation';\nimport Link from 'next/link';\nimport {\n ArrowUp,\n Check,\n ChevronDown,\n ChevronUp,\n Copy,\n Loader2,\n Menu,\n PanelLeftClose,\n Pencil,\n Plus,\n RotateCcw,\n Sparkles,\n Trash2\n} from 'lucide-react';\n\nimport { cn } from './_shared/cn';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger\n} from './_shared/dropdown-menu';\nimport { SidebarTitleEditor, EditableTitle } from './_shared/title-editors';\nimport {\n AnswerBlocks,\n sanitiseBlock,\n type BlockState\n} from './answer-blocks';\nimport type { Block } from '../server/tools/types';\n\ntype NarrativeProvider = 'claude' | 'grok' | 'gemini';\n\ntype AnswerState = {\n question: string;\n blocks: BlockState[];\n done: boolean;\n error?: { code: string; message: string };\n /** ms timestamp when the question was submitted; missing for restored history. */\n startedAt?: number;\n /** Wall-clock ms it took for the agent to mark `done`. Set in the same update that flips `done: true`. Missing for restored history. */\n durationMs?: number;\n};\n\n/** Short human-readable duration: 5s, 45s, 1m, 1m 30s, 12m 5s. */\nfunction formatDuration(ms: number): string {\n if (ms < 0) ms = 0;\n const totalSec = Math.round(ms / 1000);\n if (totalSec < 60) return `${totalSec}s`;\n const m = Math.floor(totalSec / 60);\n const s = totalSec % 60;\n return s === 0 ? `${m}m` : `${m}m ${s}s`;\n}\n\nexport type AiChatSessionSummary = {\n id: string;\n title: string;\n updatedAt: string | null;\n};\n\ntype StoredMessage = {\n id: string;\n role: 'user' | 'assistant';\n question: string | null;\n blocks: Block[] | null;\n prose: Record<string, string> | null;\n errorJson: { code: string; message: string } | null;\n};\n\nexport type AiChatProps = {\n userFirstName: string;\n /** Data scope label shown as a chip beneath the input (eg. \"All countries\"). */\n scopeLabel: string;\n /** User's stored narrative provider, surfaced as the model picker default. */\n initialProvider: NarrativeProvider;\n /**\n * Session to open on mount. The host resolves this from the URL\n * (`/chat/[id]`) so reload/bookmark/multi-tab restore the exact\n * conversation. `null` (or omitted) renders the empty new-chat state.\n */\n initialSessionId?: string | null;\n};\n\nconst PROVIDER_LABELS: Record<NarrativeProvider, string> = {\n claude: 'Claude',\n grok: 'Grok',\n gemini: 'Gemini'\n};\n\n// Auto-grow cap. The textarea is `leading-6` (24px) with `py-1`\n// (4px top + 4px bottom). 7 visible lines = 7×24 + 8 = 176px; past\n// that, vertical scrolling kicks in inside the textarea.\nconst TEXTAREA_MAX_PX = 176;\n\nconst PROVIDER_DESCRIPTIONS: Record<NarrativeProvider, string> = {\n claude: 'Anthropic Claude on Vertex AI',\n grok: 'xAI Grok on Vertex AI',\n gemini: 'Google Gemini on Vertex AI'\n};\n\nexport function AiChat({\n userFirstName,\n scopeLabel,\n initialProvider,\n initialSessionId = null\n}: AiChatProps) {\n const router = useRouter();\n const [sessions, setSessions] = useState<AiChatSessionSummary[]>([]);\n const [activeSessionId, setActiveSessionId] = useState<string | null>(\n initialSessionId\n );\n const [answers, setAnswers] = useState<AnswerState[]>([]);\n const [pending, setPending] = useState(false);\n const [question, setQuestion] = useState('');\n // Sidebar overlays the chat panel rather than pushing it sideways, so\n // it starts closed; the hamburger in the chat header opens it.\n const [sidebarOpen, setSidebarOpen] = useState(false);\n const [loadingSession, setLoadingSession] = useState(false);\n const [provider, setProvider] = useState<NarrativeProvider>(initialProvider);\n const [providerSaving, setProviderSaving] = useState(false);\n // When non-null, the sidebar row for this session is in inline-edit\n // mode and renders an <input> instead of the static title button.\n const [editingSidebarId, setEditingSidebarId] = useState<string | null>(null);\n const abortRef = useRef<AbortController | null>(null);\n const threadRef = useRef<HTMLDivElement | null>(null);\n const textareaRef = useRef<HTMLTextAreaElement | null>(null);\n // Ref to the most recently submitted answer's container. We snap it\n // to the top of the thread on submit so the AI response gets a fresh\n // viewport below the question, mirroring Claude/ChatGPT.\n const lastAnswerRef = useRef<HTMLDivElement | null>(null);\n const prevAnswersLen = useRef(0);\n\n // Auto-grow the textarea up to TEXTAREA_MAX_LINES (≈7 lines), then\n // start scrolling internally. We measure with scrollHeight after\n // resetting height to 0, mirroring the standard auto-grow pattern.\n useLayoutEffect(() => {\n const el = textareaRef.current;\n if (!el) return;\n el.style.height = '0px';\n const next = Math.min(el.scrollHeight, TEXTAREA_MAX_PX);\n el.style.height = `${next}px`;\n }, [question]);\n\n // Initial session list load (independent of which session is active —\n // the URL is now the source of truth for that, so we just hydrate the\n // sidebar here).\n useEffect(() => {\n let cancelled = false;\n async function load() {\n try {\n const res = await fetch('/api/chat/sessions', { cache: 'no-store' });\n if (!res.ok) return;\n const data = (await res.json()) as { sessions: AiChatSessionSummary[] };\n if (cancelled) return;\n setSessions(data.sessions ?? []);\n } catch {\n // network blip — sidebar will just be empty until next nav.\n }\n }\n void load();\n return () => {\n cancelled = true;\n };\n }, []);\n\n // Hydrate the active session's messages on first mount when the host\n // routed us to /chat/[id]. The URL is authoritative, so we treat\n // `initialSessionId` as the only signal — never auto-open a different\n // session. We deliberately depend only on `initialSessionId` so that\n // navigating between /chat/[a] and /chat/[b] (which remounts the page\n // with a new prop) reloads the right thread.\n useEffect(() => {\n if (initialSessionId == null) {\n setAnswers([]);\n return;\n }\n let cancelled = false;\n async function load(id: string) {\n setLoadingSession(true);\n try {\n const res = await fetch(`/api/chat/sessions/${id}`, { cache: 'no-store' });\n if (cancelled) return;\n if (!res.ok) {\n setAnswers([]);\n return;\n }\n const data = (await res.json()) as { messages: StoredMessage[] };\n if (cancelled) return;\n setAnswers(messagesToAnswers(data.messages ?? []));\n } catch {\n if (!cancelled) setAnswers([]);\n } finally {\n if (!cancelled) setLoadingSession(false);\n }\n }\n void load(initialSessionId);\n return () => {\n cancelled = true;\n };\n }, [initialSessionId]);\n\n // Snap the newly submitted question to the top of the thread when a\n // new answer is appended. We deliberately do NOT auto-scroll on\n // every prose/block update — the user's reading flow stays put as\n // the response streams below the pinned question, and they can\n // scroll up to revisit prior turns. Mirrors Claude / ChatGPT.\n useEffect(() => {\n if (answers.length > prevAnswersLen.current && lastAnswerRef.current) {\n lastAnswerRef.current.scrollIntoView({ behavior: 'smooth', block: 'start' });\n }\n prevAnswersLen.current = answers.length;\n }, [answers.length]);\n\n const refreshSessions = useCallback(async () => {\n try {\n const res = await fetch('/api/chat/sessions', { cache: 'no-store' });\n if (!res.ok) return;\n const data = (await res.json()) as { sessions: AiChatSessionSummary[] };\n setSessions(data.sessions ?? []);\n } catch {\n /* noop */\n }\n }, []);\n\n // Push `/chat/<id>` (or `/chat`) so reload, bookmarks, and multi-tab\n // restore the exact session the user is viewing. Wrapped in a callback\n // so we can call it from every code path that mutates `activeSessionId`.\n const syncUrl = useCallback(\n (id: string | null) => {\n router.push(id == null ? '/chat' : `/chat/${id}`);\n },\n [router]\n );\n\n // \"+ New chat\" navigates to /chat?new — the host's /chat route\n // redirects to the most-recent session by default, but the `?new`\n // hint suppresses that so the user lands on the empty hero. Without\n // this escape hatch, clicking \"+ New chat\" would bounce back to the\n // session you were trying to leave.\n const newChat = useCallback(() => {\n setActiveSessionId(null);\n setAnswers([]);\n setQuestion('');\n router.push('/chat?new');\n }, [router]);\n\n const changeProvider = useCallback(\n async (next: NarrativeProvider) => {\n if (next === provider || providerSaving) return;\n setProvider(next);\n setProviderSaving(true);\n try {\n const res = await fetch('/api/settings/me', {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ narrative_provider: next })\n });\n if (!res.ok) {\n // Roll back the optimistic update on failure.\n setProvider((curr) => (curr === next ? provider : curr));\n }\n } catch {\n setProvider((curr) => (curr === next ? provider : curr));\n } finally {\n setProviderSaving(false);\n }\n },\n [provider, providerSaving]\n );\n\n const openSession = useCallback(\n async (id: string) => {\n setLoadingSession(true);\n setActiveSessionId(id);\n syncUrl(id);\n try {\n const res = await fetch(`/api/chat/sessions/${id}`, { cache: 'no-store' });\n if (!res.ok) {\n setAnswers([]);\n return;\n }\n const data = (await res.json()) as { messages: StoredMessage[] };\n setAnswers(messagesToAnswers(data.messages ?? []));\n } catch {\n setAnswers([]);\n } finally {\n setLoadingSession(false);\n }\n },\n [syncUrl]\n );\n\n const persistTitle = useCallback(\n async (id: string, title: string) => {\n const trimmed = title.trim();\n if (!trimmed) return;\n const res = await fetch(`/api/chat/sessions/${id}`, {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ title: trimmed })\n });\n if (res.ok) {\n setSessions((prev) =>\n prev.map((s) => (s.id === id ? { ...s, title: trimmed } : s))\n );\n }\n },\n []\n );\n\n const startSidebarRename = useCallback((id: string) => {\n setEditingSidebarId(id);\n }, []);\n\n const deleteSession = useCallback(\n async (id: string) => {\n if (!window.confirm('Delete this chat? This cannot be undone.')) return;\n const res = await fetch(`/api/chat/sessions/${id}`, { method: 'DELETE' });\n if (!res.ok) return;\n setSessions((prev) => prev.filter((s) => s.id !== id));\n if (activeSessionId === id) {\n setActiveSessionId(null);\n setAnswers([]);\n syncUrl(null);\n }\n },\n [activeSessionId, syncUrl]\n );\n\n const submit = useCallback(\n async (q: string) => {\n const trimmed = q.trim();\n if (!trimmed || pending) return;\n setPending(true);\n setQuestion('');\n\n // Lazily create a session on first submit so empty \"New chat\" rows\n // don't litter the sidebar.\n let sessionId = activeSessionId;\n if (sessionId == null) {\n try {\n const create = await fetch('/api/chat/sessions', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({})\n });\n if (create.ok) {\n const data = (await create.json()) as {\n session: AiChatSessionSummary;\n };\n sessionId = data.session.id;\n setActiveSessionId(sessionId);\n // Pin the URL to the new session so reload restores this thread.\n syncUrl(sessionId);\n setSessions((prev) => [\n { id: data.session.id, title: data.session.title, updatedAt: null },\n ...prev\n ]);\n }\n } catch {\n // Session create failed — proceed without persistence.\n }\n }\n\n setAnswers((prev) => [\n ...prev,\n { question: trimmed, blocks: [], done: false, startedAt: Date.now() }\n ]);\n\n const ac = new AbortController();\n abortRef.current = ac;\n let res: Response;\n try {\n res = await fetch('/api/agent', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n question: trimmed,\n chatSessionId: sessionId\n }),\n signal: ac.signal\n });\n } catch (e) {\n const message = (e as Error).message ?? 'Request failed';\n setAnswers((prev) =>\n updateLast(prev, (a) => ({\n ...a,\n done: true,\n durationMs: a.startedAt != null ? Date.now() - a.startedAt : undefined,\n error: { code: 'NETWORK', message }\n }))\n );\n setPending(false);\n return;\n }\n if (!res.body) {\n setAnswers((prev) =>\n updateLast(prev, (a) => ({\n ...a,\n done: true,\n durationMs: a.startedAt != null ? Date.now() - a.startedAt : undefined,\n error: { code: 'NO_BODY', message: 'No response stream.' }\n }))\n );\n setPending(false);\n return;\n }\n\n const reader = res.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n try {\n while (true) {\n const { value, done } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n const events = buffer.split('\\n\\n');\n buffer = events.pop() ?? '';\n for (const raw of events) {\n handleEvent(raw, setAnswers);\n }\n }\n } catch (e) {\n const message = (e as Error).message ?? 'Stream interrupted';\n setAnswers((prev) =>\n updateLast(prev, (a) => ({\n ...a,\n done: true,\n durationMs: a.startedAt != null ? Date.now() - a.startedAt : undefined,\n error: { code: 'STREAM', message }\n }))\n );\n } finally {\n setPending(false);\n abortRef.current = null;\n // Persisted title may have been auto-generated on the server —\n // refresh sidebar so the new label appears.\n void refreshSessions();\n }\n },\n [activeSessionId, pending, refreshSessions, syncUrl]\n );\n\n const heroVisible = answers.length === 0 && !loadingSession;\n const greeting = useMemo(\n () =>\n `Hi ${userFirstName || 'there'}${\n userFirstName.endsWith('s') ? '' : ''\n },`,\n [userFirstName]\n );\n\n const activeTitle = activeSessionId\n ? sessions.find((s) => s.id === activeSessionId)?.title ?? 'Chat'\n : 'New chat';\n\n return (\n <div className=\"relative flex h-full min-h-0 w-full overflow-hidden rounded-lg border border-border bg-background\">\n {/* Backdrop: click to close. Pointer-events only when open so the\n chat panel underneath stays interactive when the sidebar is\n closed. */}\n <div\n onClick={() => setSidebarOpen(false)}\n aria-hidden=\"true\"\n className={cn(\n 'absolute inset-0 z-10 bg-background/60 backdrop-blur-sm transition-opacity duration-200',\n sidebarOpen\n ? 'opacity-100'\n : 'pointer-events-none opacity-0'\n )}\n />\n\n {/* Overlay session sidebar — slides in from the left, never\n shrinks the chat panel. z-20 so it sits above the backdrop. */}\n <aside\n inert={!sidebarOpen}\n className={cn(\n 'absolute inset-y-0 left-0 z-20 flex w-72 max-w-[85vw] flex-col border-r border-border bg-sidebar text-sidebar-foreground shadow-lg transition-transform duration-200 ease-out',\n sidebarOpen ? 'translate-x-0' : '-translate-x-full'\n )}\n >\n <div className=\"flex items-center gap-2 border-b border-sidebar-border p-2\">\n <button\n type=\"button\"\n onClick={() => setSidebarOpen(false)}\n className=\"inline-flex size-8 items-center justify-center rounded-md text-sidebar-foreground/70 hover:bg-sidebar-accent hover:text-sidebar-foreground\"\n aria-label=\"Close sidebar\"\n >\n <PanelLeftClose className=\"size-4\" />\n </button>\n <button\n type=\"button\"\n onClick={() => {\n newChat();\n setSidebarOpen(false);\n }}\n className=\"ml-auto inline-flex items-center gap-1.5 rounded-full border border-sidebar-border bg-sidebar-accent px-3 py-1.5 text-xs font-medium text-sidebar-accent-foreground hover:bg-sidebar-accent/80\"\n >\n <Plus className=\"size-3.5\" />\n New chat\n </button>\n </div>\n <div className=\"flex-1 overflow-y-auto p-2\">\n {sessions.length === 0 ? (\n <p className=\"px-2 py-3 text-xs text-sidebar-foreground/60\">\n No chats yet. Ask something below to start.\n </p>\n ) : (\n <ul className=\"flex flex-col gap-0.5\">\n {sessions.map((s) => {\n const active = s.id === activeSessionId;\n const editing = s.id === editingSidebarId;\n if (editing) {\n return (\n <li key={s.id} className=\"px-1 py-1\">\n <SidebarTitleEditor\n initial={s.title}\n onCancel={() => setEditingSidebarId(null)}\n onSave={(next) => {\n setEditingSidebarId(null);\n void persistTitle(s.id, next);\n }}\n />\n </li>\n );\n }\n return (\n <li key={s.id} className=\"group relative\">\n <Link\n href={`/chat/${s.id}`}\n onClick={() => setSidebarOpen(false)}\n className={cn(\n 'flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm',\n active\n ? 'bg-sidebar-accent text-sidebar-accent-foreground'\n : 'text-sidebar-foreground/80 hover:bg-sidebar-accent/60 hover:text-sidebar-foreground'\n )}\n title={s.title}\n >\n <span className=\"truncate\">{s.title}</span>\n </Link>\n <div className=\"absolute right-1 top-1/2 hidden -translate-y-1/2 items-center gap-0.5 group-hover:flex\">\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n startSidebarRename(s.id);\n }}\n aria-label=\"Rename\"\n className=\"inline-flex size-6 items-center justify-center rounded text-sidebar-foreground/60 hover:bg-sidebar hover:text-sidebar-foreground\"\n >\n <Pencil className=\"size-3\" />\n </button>\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n void deleteSession(s.id);\n }}\n aria-label=\"Delete\"\n className=\"inline-flex size-6 items-center justify-center rounded text-sidebar-foreground/60 hover:bg-sidebar hover:text-destructive\"\n >\n <Trash2 className=\"size-3\" />\n </button>\n </div>\n </li>\n );\n })}\n </ul>\n )}\n </div>\n </aside>\n\n <section className=\"relative flex flex-1 flex-col overflow-hidden\">\n <header className=\"flex items-center gap-2 px-3 py-3 text-sm text-muted-foreground\">\n <button\n type=\"button\"\n onClick={() => setSidebarOpen(true)}\n aria-label=\"Open chat history\"\n className=\"inline-flex size-8 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground\"\n >\n <Menu className=\"size-4\" />\n </button>\n <Sparkles className=\"size-4 text-primary\" />\n {activeSessionId != null ? (\n <EditableTitle\n key={activeSessionId}\n title={activeTitle}\n onSave={(next) => void persistTitle(activeSessionId, next)}\n />\n ) : (\n <span className=\"truncate\">{activeTitle}</span>\n )}\n </header>\n\n <div\n ref={threadRef}\n className=\"min-h-0 flex-1 overflow-y-auto px-4 pb-6 pt-2\"\n >\n {loadingSession ? (\n <div className=\"flex h-full items-center justify-center text-sm text-muted-foreground\">\n <Loader2 className=\"mr-2 size-4 animate-spin\" /> Loading conversation…\n </div>\n ) : heroVisible ? (\n <div className=\"flex h-full flex-col items-center justify-center text-center\">\n <h1 className=\"text-2xl font-medium tracking-tight text-foreground sm:text-3xl\">\n {greeting}\n </h1>\n <p className=\"mt-2 text-2xl font-light tracking-tight text-muted-foreground sm:text-3xl\">\n What's on your mind?\n </p>\n </div>\n ) : (\n <div className=\"mx-auto flex w-full max-w-3xl flex-col gap-6\">\n {answers.map((a, idx) => (\n <AnswerView\n key={idx}\n answer={a}\n onRetry={() => void submit(a.question)}\n forwardRef={idx === answers.length - 1 ? lastAnswerRef : undefined}\n // The last turn reserves enough viewport so the AI\n // response has room to stream below the question\n // without the user needing to scroll. Calc subtracts\n // the input-pill area (~14rem) and a comfort buffer.\n isLast={idx === answers.length - 1}\n />\n ))}\n </div>\n )}\n </div>\n\n <div className=\"shrink-0 px-4 pb-4 pt-2\">\n <form\n className=\"mx-auto w-full max-w-3xl\"\n onSubmit={(e) => {\n e.preventDefault();\n void submit(question);\n }}\n >\n <div className=\"flex flex-col gap-2 rounded-3xl border border-border bg-background px-4 py-3 shadow-sm\">\n <textarea\n ref={textareaRef}\n value={question}\n onChange={(e) => setQuestion(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n void submit(question);\n }\n }}\n placeholder=\"Ask AI...\"\n rows={1}\n disabled={pending}\n style={{ maxHeight: TEXTAREA_MAX_PX }}\n className=\"w-full resize-none overflow-y-auto border-0 bg-transparent py-1 text-sm leading-6 text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-0 disabled:opacity-60\"\n />\n <div className=\"flex items-center justify-between gap-2\">\n <span\n className=\"inline-flex max-w-[60%] items-center gap-1.5 truncate rounded-full border border-border bg-muted/40 px-2.5 py-1 text-xs font-medium text-muted-foreground\"\n title={`Scope: ${scopeLabel}`}\n >\n Scope: <span className=\"truncate text-foreground\">{scopeLabel}</span>\n </span>\n <div className=\"flex items-center gap-2\">\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n className=\"inline-flex items-center gap-1 rounded-full px-2.5 py-1 text-xs font-medium text-muted-foreground hover:bg-accent hover:text-foreground\"\n aria-label=\"Choose model\"\n >\n {PROVIDER_LABELS[provider]}\n <ChevronDown className=\"size-3.5\" />\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-56\">\n {(['claude', 'grok', 'gemini'] as const).map((p) => (\n <DropdownMenuItem\n key={p}\n onSelect={() => void changeProvider(p)}\n className=\"flex items-start gap-2\"\n >\n <Check\n className={cn(\n 'mt-0.5 size-4',\n provider === p ? 'opacity-100' : 'opacity-0'\n )}\n />\n <div className=\"flex flex-col\">\n <span className=\"text-sm font-medium\">\n {PROVIDER_LABELS[p]}\n </span>\n <span className=\"text-xs text-muted-foreground\">\n {PROVIDER_DESCRIPTIONS[p]}\n </span>\n </div>\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n <button\n type=\"submit\"\n disabled={pending || !question.trim()}\n aria-label=\"Send\"\n className=\"inline-flex size-8 shrink-0 items-center justify-center rounded-full bg-primary text-primary-foreground transition-colors enabled:hover:bg-primary/90 disabled:opacity-40\"\n >\n {pending ? (\n <Loader2 className=\"size-4 animate-spin\" />\n ) : (\n <ArrowUp className=\"size-4\" />\n )}\n </button>\n </div>\n </div>\n </div>\n <p className=\"mt-2 text-center text-xs text-muted-foreground\">\n {PROVIDER_LABELS[provider]} is AI and can make mistakes.\n </p>\n </form>\n </div>\n </section>\n </div>\n );\n}\n\nfunction AnswerView({\n answer,\n onRetry,\n forwardRef,\n isLast\n}: {\n answer: AnswerState;\n onRetry: () => void;\n /** Attached to the outer container so the parent can scroll the latest turn into view on submit. */\n forwardRef?: React.RefObject<HTMLDivElement | null>;\n /**\n * The last turn reserves enough viewport that the AI response has\n * room to grow under the pinned question. The parent flex column\n * uses `min-h-[...]` here so a short answer doesn't leave a\n * ridiculous gap, but a long-running response can stream below\n * without the user being autoscrolled.\n */\n isLast?: boolean;\n}) {\n const [copied, setCopied] = useState(false);\n\n const handleCopy = useCallback(async () => {\n // Prefer the structured response; fall back to the error envelope\n // when the turn produced no blocks so the user can still copy the\n // failure (eg. quota error message → paste into an issue).\n const blockText = blocksToPlainText(answer.blocks);\n const text =\n blockText ||\n (answer.error\n ? `${answer.error.code}: ${answer.error.message}`\n : '');\n if (!text) return;\n try {\n await navigator.clipboard.writeText(text);\n setCopied(true);\n window.setTimeout(() => setCopied(false), 1500);\n } catch {\n // Clipboard blocked (insecure context, permission denied) — silent.\n }\n }, [answer.blocks, answer.error]);\n\n const showActions =\n answer.done && (answer.blocks.length > 0 || answer.error != null);\n // While the agent is still computing the first block, drop the\n // nested-column layout entirely and render a single flex row. The\n // normal layout has an empty `AnswerBlocks` wrapper that contributes\n // a 12px flex-gap to the column even when it has no blocks, which\n // throws `items-center` off so the icon and \"Thinking…\" don't align.\n const isThinking =\n !answer.done && answer.blocks.length === 0 && !answer.error;\n\n // Live ticker — re-renders once a second while the agent is thinking\n // so the inline \"(5s)\" counter advances. We force a re-render via a\n // dummy state instead of recomputing elapsed in a useEffect because\n // the elapsed value is derived from `answer.startedAt` (a prop) and\n // `Date.now()` — anything stored in state would just duplicate that.\n const [, forceTick] = useState(0);\n useEffect(() => {\n if (answer.done || answer.startedAt == null) return;\n const id = window.setInterval(() => forceTick((n) => n + 1), 1000);\n return () => window.clearInterval(id);\n }, [answer.done, answer.startedAt]);\n\n // Live elapsed for the thinking state; final stamped duration once done.\n const liveElapsed =\n answer.startedAt != null ? Date.now() - answer.startedAt : null;\n const finalDuration = answer.durationMs;\n\n return (\n <div\n ref={forwardRef}\n // scroll-mt nudges scrollIntoView so the question doesn't kiss\n // the very top of the thread container.\n className={cn(\n 'flex flex-col gap-4 scroll-mt-2',\n // Reserve space below the latest turn so the AI response has a\n // full screen to fill without bouncing the user. Calc subtracts\n // the chat header (~3rem) and the input pill area (~10rem) from\n // the dynamic viewport height.\n isLast && 'min-h-[calc(100dvh-13rem)]'\n )}\n >\n <div className=\"flex justify-end\">\n <UserChip text={answer.question} />\n </div>\n {isThinking ? (\n <div className=\"flex items-center gap-3\">\n <div className=\"flex size-7 shrink-0 items-center justify-center rounded-full bg-primary/10 text-primary\">\n <Sparkles className=\"size-4\" />\n </div>\n <p className=\"flex items-center text-sm text-muted-foreground\">\n <Loader2 className=\"mr-1 inline size-3.5 animate-spin\" />\n Thinking…\n {liveElapsed != null && liveElapsed >= 1000 && (\n <span className=\"ml-2 text-xs tabular-nums\">\n ({formatDuration(liveElapsed)})\n </span>\n )}\n </p>\n </div>\n ) : (\n <div className=\"flex items-start gap-3\">\n <div className=\"mt-0.5 flex size-7 shrink-0 items-center justify-center rounded-full bg-primary/10 text-primary\">\n <Sparkles className=\"size-4\" />\n </div>\n <div className=\"flex min-w-0 flex-1 flex-col gap-3\">\n <AnswerBlocks blocks={answer.blocks} />\n {answer.error && (\n <div className=\"wrap-break-word whitespace-pre-wrap rounded border border-amber-300 bg-amber-50 p-3 text-sm text-amber-900 dark:border-amber-800 dark:bg-amber-950/30 dark:text-amber-100\">\n {answer.error.code}: {answer.error.message}\n </div>\n )}\n {showActions && (\n <div className=\"flex items-center gap-1\">\n {(answer.blocks.length > 0 || answer.error != null) && (\n <button\n type=\"button\"\n onClick={handleCopy}\n aria-label={\n answer.blocks.length === 0 && answer.error\n ? 'Copy error'\n : 'Copy response'\n }\n title={copied ? 'Copied' : 'Copy'}\n className=\"inline-flex size-8 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground\"\n >\n {copied ? (\n <Check className=\"size-4\" />\n ) : (\n <Copy className=\"size-4\" />\n )}\n </button>\n )}\n <button\n type=\"button\"\n onClick={onRetry}\n aria-label=\"Retry\"\n title=\"Retry\"\n className=\"inline-flex size-8 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground\"\n >\n <RotateCcw className=\"size-4\" />\n </button>\n {finalDuration != null && finalDuration >= 1000 && (\n <span\n className=\"ml-1 text-xs text-muted-foreground tabular-nums\"\n title=\"Time taken to generate this response\"\n >\n {formatDuration(finalDuration)}\n </span>\n )}\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n );\n}\n\n/**\n * Flatten an assistant turn's blocks into plain text for the clipboard\n * — paragraph prose, list items, callouts, and a tab-separated table\n * dump. Charts are referenced by title since the visual is what\n * matters there.\n */\nfunction blocksToPlainText(blocks: BlockState[]): string {\n return blocks\n .map((b) => {\n if (b.kind === 'paragraph_brief') {\n return b.prose || b.key_facts.join('. ');\n }\n if (b.kind === 'list') {\n const lines = b.items.map((it, i) =>\n b.style === 'numbered' ? `${i + 1}. ${it}` : `- ${it}`\n );\n return [b.title, ...lines].filter(Boolean).join('\\n');\n }\n if (b.kind === 'chart') {\n return `${b.title} (chart)`;\n }\n if (b.kind === 'table') {\n const header = b.columns.join('\\t');\n const rows = b.rows.map((r) =>\n r.map((c) => (c == null ? '—' : String(c))).join('\\t')\n );\n return [b.title, header, ...rows].join('\\n');\n }\n if (b.kind === 'callout') return b.text;\n return '';\n })\n .filter(Boolean)\n .join('\\n\\n');\n}\n\n/**\n * User-message bubble. Wraps long content (including unspaced strings\n * via `wrap-break-word`); when collapsed it caps at 3 lines and fades\n * the last line into the bubble background instead of using a hard\n * ellipsis. A chevron + \"Show more / Show less\" toggle reveals only\n * when the cap actually truncates content.\n */\nfunction UserChip({ text }: { text: string }) {\n const [expanded, setExpanded] = useState(false);\n const [overflowing, setOverflowing] = useState(false);\n const ref = useRef<HTMLDivElement | null>(null);\n\n useLayoutEffect(() => {\n const el = ref.current;\n if (!el || expanded) return;\n setOverflowing(el.scrollHeight > el.clientHeight + 1);\n }, [text, expanded]);\n\n return (\n <div className=\"max-w-[85%] rounded-2xl bg-muted px-4 py-2 text-sm text-foreground\">\n <div className=\"relative\">\n <div\n ref={ref}\n className={cn(\n 'whitespace-pre-wrap wrap-break-word leading-6',\n // 3 lines × leading-6 (24px) = 72px → max-h-18.\n !expanded && 'max-h-18 overflow-hidden'\n )}\n >\n {text}\n </div>\n {!expanded && overflowing && (\n <div\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-x-0 bottom-0 h-6 bg-linear-to-t from-muted to-transparent\"\n />\n )}\n </div>\n {(overflowing || expanded) && (\n <button\n type=\"button\"\n onClick={() => setExpanded((v) => !v)}\n className=\"mt-1 inline-flex items-center gap-1 text-xs font-medium text-muted-foreground hover:text-foreground\"\n >\n {expanded ? (\n <>\n <ChevronUp className=\"size-3.5\" />\n Show less\n </>\n ) : (\n <>\n <ChevronDown className=\"size-3.5\" />\n Show more\n </>\n )}\n </button>\n )}\n </div>\n );\n}\n\nfunction handleEvent(\n raw: string,\n setAnswers: React.Dispatch<React.SetStateAction<AnswerState[]>>\n): void {\n const lines = raw.split('\\n');\n let event = '';\n let dataStr = '';\n for (const line of lines) {\n if (line.startsWith('event: ')) event = line.slice(7).trim();\n else if (line.startsWith('data: ')) dataStr += line.slice(6);\n }\n if (!event) return;\n let data: unknown = {};\n try {\n data = JSON.parse(dataStr || '{}');\n } catch {\n return;\n }\n\n if (event === 'block') {\n const blockData = data as Block & { index: number };\n const block = sanitiseBlock(blockData);\n setAnswers((prev) =>\n updateLast(prev, (a) => {\n const blocks = [...a.blocks];\n blocks[blockData.index] = block;\n return { ...a, blocks };\n })\n );\n } else if (event === 'prose') {\n const { block_index, delta } = data as { block_index: number; delta: string };\n setAnswers((prev) =>\n updateLast(prev, (a) => {\n const blocks = [...a.blocks];\n const target = blocks[block_index];\n if (target && target.kind === 'paragraph_brief') {\n blocks[block_index] = { ...target, prose: target.prose + delta };\n }\n return { ...a, blocks };\n })\n );\n } else if (event === 'done') {\n setAnswers((prev) =>\n updateLast(prev, (a) => ({\n ...a,\n done: true,\n durationMs: a.startedAt != null ? Date.now() - a.startedAt : undefined\n }))\n );\n } else if (event === 'error') {\n setAnswers((prev) =>\n updateLast(prev, (a) => ({\n ...a,\n error: data as { code: string; message: string }\n }))\n );\n }\n}\n\nfunction updateLast(\n prev: AnswerState[],\n updater: (a: AnswerState) => AnswerState\n): AnswerState[] {\n if (prev.length === 0) return prev;\n const next = [...prev];\n next[next.length - 1] = updater(next[next.length - 1]);\n return next;\n}\n\nfunction messagesToAnswers(messages: StoredMessage[]): AnswerState[] {\n // Stored messages alternate user → assistant. Pair them into AnswerState.\n const out: AnswerState[] = [];\n let pendingUser: string | null = null;\n for (const m of messages) {\n if (m.role === 'user') {\n pendingUser = m.question ?? '';\n } else if (m.role === 'assistant') {\n const question = pendingUser ?? '';\n pendingUser = null;\n const blocks: BlockState[] = [];\n const stored = (m.blocks ?? []) as Block[];\n stored.forEach((b, i) => {\n const sanitised = sanitiseBlock({ ...(b as Block), index: i } as Block & {\n index: number;\n });\n if (sanitised.kind === 'paragraph_brief') {\n sanitised.prose = m.prose?.[String(i)] ?? '';\n }\n blocks[i] = sanitised;\n });\n out.push({\n question,\n blocks,\n done: true,\n error: m.errorJson ?? undefined\n });\n }\n }\n if (pendingUser !== null) {\n // Trailing user message with no assistant reply (likely interrupted).\n out.push({ question: pendingUser, blocks: [], done: true });\n }\n return out;\n}\n","/**\n * VercelChat — sibling chat shell driven by the Vercel AI SDK\n * (`@ai-sdk/react`'s `useChat`) instead of the bespoke SSE protocol used\n * by `AiChat`. Layout, sidebar, header, thread, and input pill are\n * lifted from `ai-chat.tsx` so the two interfaces render identical\n * pixels — only the streaming wire format differs.\n *\n * Wire shape (matches `routes/agent-vercel.ts`):\n * POST /api/agent/vercel\n * body: { messages, chatSessionId, model }\n * ← Vercel data stream (text deltas + custom data parts)\n *\n * Custom data parts surface in `useChat`'s top-level `data` array as\n * `JSONValue` items. We pick out `{ type: 'block', value: { index, ... } }`\n * entries and feed them through `sanitiseBlock` → `AnswerBlocks`.\n *\n * Hydration: `useChat`'s `setMessages` doesn't repopulate the `data`\n * array, so a session opened from `/api/chat/sessions/[id]` carries its\n * `Block[]` rows via a per-message map (`hydratedBlocks`) instead of\n * `data`. The renderer reads from both — live-streamed blocks come from\n * `data`, hydrated blocks come from the map — so each turn paints\n * identically regardless of origin.\n */\n'use client';\n\nimport {\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState\n} from 'react';\nimport { useRouter } from 'next/navigation';\nimport Link from 'next/link';\nimport {\n ArrowUp,\n Check,\n ChevronDown,\n ChevronUp,\n Copy,\n Loader2,\n Menu,\n PanelLeftClose,\n Pencil,\n Plus,\n RotateCcw,\n Sparkles,\n Trash2\n} from 'lucide-react';\nimport { useChat, type Message as UIMessage } from '@ai-sdk/react';\n\nimport { cn } from './_shared/cn';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger\n} from './_shared/dropdown-menu';\nimport { SidebarTitleEditor, EditableTitle } from './_shared/title-editors';\nimport {\n AnswerBlocks,\n sanitiseBlock,\n type BlockState\n} from './answer-blocks';\nimport type { Block } from '../server/tools/types';\nimport type { AiChatProps, AiChatSessionSummary } from './types';\n\ntype NarrativeProvider = 'claude' | 'grok' | 'gemini';\n\ntype AnswerState = {\n question: string;\n blocks: BlockState[];\n prose: string;\n done: boolean;\n error?: { code: string; message: string };\n /** ms timestamp when the question was submitted; missing for restored history. */\n startedAt?: number;\n /** Wall-clock ms it took for the agent to mark `done`. Set in the same update that flips `done: true`. Missing for restored history. */\n durationMs?: number;\n};\n\n/** Short human-readable duration: 5s, 45s, 1m, 1m 30s, 12m 5s. */\nfunction formatDuration(ms: number): string {\n if (ms < 0) ms = 0;\n const totalSec = Math.round(ms / 1000);\n if (totalSec < 60) return `${totalSec}s`;\n const m = Math.floor(totalSec / 60);\n const s = totalSec % 60;\n return s === 0 ? `${m}m` : `${m}m ${s}s`;\n}\n\ntype StoredMessage = {\n id: string;\n role: 'user' | 'assistant';\n question: string | null;\n blocks: Block[] | null;\n prose: Record<string, string> | null;\n errorJson: { code: string; message: string } | null;\n};\n\nconst PROVIDER_LABELS: Record<NarrativeProvider, string> = {\n claude: 'Claude',\n grok: 'Grok',\n gemini: 'Gemini'\n};\n\n// Auto-grow cap. The textarea is `leading-6` (24px) with `py-1`\n// (4px top + 4px bottom). 7 visible lines = 7×24 + 8 = 176px; past\n// that, vertical scrolling kicks in inside the textarea.\nconst TEXTAREA_MAX_PX = 176;\n\nconst PROVIDER_DESCRIPTIONS: Record<NarrativeProvider, string> = {\n claude: 'Anthropic Claude on Vertex AI',\n grok: 'xAI Grok on Vertex AI',\n gemini: 'Google Gemini on Vertex AI'\n};\n\n/**\n * A single `data` entry from `useChat` representing one of our custom\n * stream parts. `useChat`'s `data` is typed as `JSONValue[] | undefined`\n * — we cast through `unknown` at the boundary and narrow with this\n * helper before reading `type`/`value`.\n */\ntype DataPart =\n | { type: 'meta'; value: { chatSessionId: string | null; scopeLabel?: string } }\n | { type: 'block'; value: Block & { index: number } }\n | { type: 'error'; value: { code: string; message: string } };\n\nfunction asDataPart(v: unknown): DataPart | null {\n if (typeof v !== 'object' || v === null || Array.isArray(v)) return null;\n const t = (v as { type?: unknown }).type;\n if (typeof t !== 'string') return null;\n return v as DataPart;\n}\n\nexport function VercelChat({\n userFirstName,\n scopeLabel,\n initialProvider,\n initialSessionId = null\n}: AiChatProps) {\n const router = useRouter();\n const [sessions, setSessions] = useState<AiChatSessionSummary[]>([]);\n const [activeSessionId, setActiveSessionId] = useState<string | null>(\n initialSessionId\n );\n // Sidebar overlays the chat panel rather than pushing it sideways, so\n // it starts closed; the hamburger in the chat header opens it.\n const [sidebarOpen, setSidebarOpen] = useState(false);\n const [loadingSession, setLoadingSession] = useState(false);\n const [provider, setProvider] = useState<NarrativeProvider>(initialProvider);\n const [providerSaving, setProviderSaving] = useState(false);\n // When non-null, the sidebar row for this session is in inline-edit\n // mode and renders an <input> instead of the static title button.\n const [editingSidebarId, setEditingSidebarId] = useState<string | null>(null);\n // Map of assistant messageId → reconstructed blocks, populated when we\n // hydrate a stored session via `setMessages`. Live-streamed turns\n // bypass this and read blocks from the top-level `data` array.\n const [hydratedBlocks, setHydratedBlocks] = useState<Record<string, BlockState[]>>({});\n // Map of assistant messageId → reconstructed prose, populated alongside\n // `hydratedBlocks` so the same lookup answers both shapes.\n const [hydratedProse, setHydratedProse] = useState<Record<string, string>>({});\n // Map of assistant messageId → stored error envelope, populated for\n // turns that surfaced an error before the agent could `present`.\n const [hydratedErrors, setHydratedErrors] = useState<\n Record<string, { code: string; message: string }>\n >({});\n // Map of user messageId → submission timestamp, used to compute the\n // live \"Thinking… (5s)\" ticker for the in-flight assistant turn.\n const [startedAt, setStartedAt] = useState<Record<string, number>>({});\n\n const threadRef = useRef<HTMLDivElement | null>(null);\n const textareaRef = useRef<HTMLTextAreaElement | null>(null);\n // Ref to the most recently submitted answer's container. We snap it\n // to the top of the thread on submit so the AI response gets a fresh\n // viewport below the question, mirroring Claude/ChatGPT.\n const lastAnswerRef = useRef<HTMLDivElement | null>(null);\n const prevAnswersLen = useRef(0);\n\n // Live mirrors so async callbacks (handleSubmit, prepareRequestBody)\n // always see the freshest values without stale closures.\n const activeSessionIdRef = useRef<string | null>(activeSessionId);\n const providerRef = useRef<NarrativeProvider>(provider);\n useEffect(() => {\n activeSessionIdRef.current = activeSessionId;\n }, [activeSessionId]);\n useEffect(() => {\n providerRef.current = provider;\n }, [provider]);\n\n const refreshSessions = useCallback(async () => {\n try {\n const res = await fetch('/api/chat/sessions', { cache: 'no-store' });\n if (!res.ok) return;\n const data = (await res.json()) as { sessions: AiChatSessionSummary[] };\n setSessions(data.sessions ?? []);\n } catch {\n /* noop */\n }\n }, []);\n\n const {\n messages,\n input,\n handleInputChange,\n handleSubmit,\n status,\n setMessages,\n setInput,\n data\n } = useChat({\n api: '/api/agent/vercel',\n // `body` here is captured at hook init and stale-closes over\n // `activeSessionId`/`provider`. Real per-submit body comes through\n // `experimental_prepareRequestBody` below, which reads from refs.\n experimental_prepareRequestBody: ({ messages: msgs }) => ({\n messages: msgs,\n chatSessionId: activeSessionIdRef.current,\n model: providerRef.current\n }),\n onFinish: () => {\n // Persisted title may have been auto-generated on the server —\n // refresh sidebar so the new label appears.\n void refreshSessions();\n }\n });\n\n // Auto-grow the textarea up to TEXTAREA_MAX_LINES (≈7 lines), then\n // start scrolling internally. We measure with scrollHeight after\n // resetting height to 0, mirroring the standard auto-grow pattern.\n useLayoutEffect(() => {\n const el = textareaRef.current;\n if (!el) return;\n el.style.height = '0px';\n const next = Math.min(el.scrollHeight, TEXTAREA_MAX_PX);\n el.style.height = `${next}px`;\n }, [input]);\n\n // Initial session list load (independent of which session is active —\n // the URL is now the source of truth for that, so we just hydrate the\n // sidebar here).\n useEffect(() => {\n let cancelled = false;\n async function load() {\n try {\n const res = await fetch('/api/chat/sessions', { cache: 'no-store' });\n if (!res.ok) return;\n const json = (await res.json()) as { sessions: AiChatSessionSummary[] };\n if (cancelled) return;\n setSessions(json.sessions ?? []);\n } catch {\n // network blip — sidebar will just be empty until next nav.\n }\n }\n void load();\n return () => {\n cancelled = true;\n };\n }, []);\n\n // Hydrate the active session's messages on first mount when the host\n // routed us to /chat/[id]. The URL is authoritative, so we treat\n // `initialSessionId` as the only signal — never auto-open a different\n // session. Re-runs when the prop changes (navigating between\n // /chat/[a] ↔ /chat/[b] remounts with a new prop).\n useEffect(() => {\n if (initialSessionId == null) {\n setMessages([]);\n setHydratedBlocks({});\n setHydratedProse({});\n setHydratedErrors({});\n return;\n }\n let cancelled = false;\n async function load(id: string) {\n setLoadingSession(true);\n try {\n const res = await fetch(`/api/chat/sessions/${id}`, { cache: 'no-store' });\n if (cancelled) return;\n if (!res.ok) {\n setMessages([]);\n setHydratedBlocks({});\n setHydratedProse({});\n setHydratedErrors({});\n return;\n }\n const json = (await res.json()) as { messages: StoredMessage[] };\n if (cancelled) return;\n const { uiMessages, blocksMap, proseMap, errorsMap } = storedToUseChat(\n json.messages ?? []\n );\n setMessages(uiMessages);\n setHydratedBlocks(blocksMap);\n setHydratedProse(proseMap);\n setHydratedErrors(errorsMap);\n setStartedAt({});\n } catch {\n if (!cancelled) {\n setMessages([]);\n setHydratedBlocks({});\n setHydratedProse({});\n setHydratedErrors({});\n }\n } finally {\n if (!cancelled) setLoadingSession(false);\n }\n }\n void load(initialSessionId);\n return () => {\n cancelled = true;\n };\n }, [initialSessionId, setMessages]);\n\n // Pair user → assistant messages and attach the right block slice to\n // each assistant turn. Live blocks come from the top-level `data`\n // array; hydrated blocks come from the per-message maps populated in\n // `openSession`. The result is the same `AnswerState[]` shape used by\n // `AiChat` so the rendered markup matches.\n const answers = useMemo<AnswerState[]>(() => {\n // Pull all live block parts from the cumulative `data` array. They\n // arrive in append order; we walk the messages array and assign\n // contiguous block runs to each assistant message that does NOT\n // already have a hydrated entry (since hydration replaces the run).\n const liveBlocks: Array<Block & { index: number }> = [];\n const liveErrors: Array<{ code: string; message: string }> = [];\n if (Array.isArray(data)) {\n for (const raw of data) {\n const part = asDataPart(raw);\n if (!part) continue;\n if (part.type === 'block') liveBlocks.push(part.value);\n else if (part.type === 'error') liveErrors.push(part.value);\n }\n }\n\n // Reduce live blocks to a sparse array indexed by `index`. A second\n // assistant turn would reset the index back to 0, so we track which\n // assistant turn each block run targets by counting assistant\n // messages that lack hydrated blocks.\n const out: AnswerState[] = [];\n let pendingQuestion: string | null = null;\n let liveAssistantSeen = 0;\n // Group live blocks by their assistant-turn ordinal. We assume the\n // server resets `index` back to 0 for each new turn, so a block\n // with `index === 0` after a non-zero index marks a new turn.\n const liveTurns: Array<Array<Block & { index: number }>> = [];\n {\n let current: Array<Block & { index: number }> = [];\n let lastIdx = -1;\n for (const b of liveBlocks) {\n if (b.index <= lastIdx && current.length > 0) {\n liveTurns.push(current);\n current = [];\n }\n current.push(b);\n lastIdx = b.index;\n }\n if (current.length > 0) liveTurns.push(current);\n }\n\n for (const m of messages) {\n if (m.role === 'user') {\n pendingQuestion = m.content;\n continue;\n }\n if (m.role !== 'assistant') continue;\n\n const question = pendingQuestion ?? '';\n pendingQuestion = null;\n\n const hydrated = hydratedBlocks[m.id];\n const hydratedProseStr = hydratedProse[m.id];\n const hydratedError = hydratedErrors[m.id];\n\n let blocks: BlockState[] = [];\n let prose = '';\n let error: { code: string; message: string } | undefined;\n\n if (hydrated != null) {\n // Hydrated assistant turn — blocks/prose/error already mapped\n // out of stored shape; the live data array is irrelevant here.\n blocks = hydrated;\n prose = hydratedProseStr ?? '';\n error = hydratedError;\n } else {\n // Live-streamed assistant turn — splice the next live-turn run\n // into a sparse BlockState[] using sanitiseBlock.\n const run = liveTurns[liveAssistantSeen] ?? [];\n const acc: BlockState[] = [];\n for (const raw of run) {\n acc[raw.index] = sanitiseBlock(raw);\n }\n blocks = acc;\n prose = m.content ?? '';\n error = liveErrors[liveAssistantSeen];\n liveAssistantSeen += 1;\n }\n\n // Attribute streamed prose to the FIRST paragraph_brief block, so\n // the renderer prints it via the existing `paragraph_brief` path\n // and the on-disk shape persisted by the route lines up.\n if (prose) {\n const firstPb = blocks.findIndex((b) => b && b.kind === 'paragraph_brief');\n if (firstPb >= 0) {\n const target = blocks[firstPb];\n if (target.kind === 'paragraph_brief') {\n blocks[firstPb] = { ...target, prose };\n }\n }\n }\n\n const isLive = hydrated == null;\n const turnDone = !isLive || status === 'ready' || status === 'error';\n const startedTs = startedAt[m.id];\n\n out.push({\n question,\n blocks: blocks.filter(Boolean),\n prose,\n done: turnDone,\n error,\n startedAt: startedTs,\n durationMs:\n turnDone && startedTs != null ? Date.now() - startedTs : undefined\n });\n }\n\n // Trailing user message with no assistant reply yet (in flight) —\n // surface it as a thinking turn so the user sees the question\n // pinned and a spinner rendered below.\n if (pendingQuestion != null) {\n const lastUser = [...messages].reverse().find((m) => m.role === 'user');\n const ts = lastUser ? startedAt[lastUser.id] : undefined;\n out.push({\n question: pendingQuestion,\n blocks: [],\n prose: '',\n done: false,\n startedAt: ts\n });\n }\n\n return out;\n }, [messages, data, hydratedBlocks, hydratedProse, hydratedErrors, status, startedAt]);\n\n // Snap the newly submitted question to the top of the thread when a\n // new answer is appended. We deliberately do NOT auto-scroll on\n // every prose/block update — the user's reading flow stays put as\n // the response streams below the pinned question, and they can\n // scroll up to revisit prior turns. Mirrors Claude / ChatGPT.\n useEffect(() => {\n if (answers.length > prevAnswersLen.current && lastAnswerRef.current) {\n lastAnswerRef.current.scrollIntoView({ behavior: 'smooth', block: 'start' });\n }\n prevAnswersLen.current = answers.length;\n }, [answers.length]);\n\n // Push `/chat/<id>` (or `/chat`) so reload, bookmarks, and multi-tab\n // restore the exact session the user is viewing.\n const syncUrl = useCallback(\n (id: string | null) => {\n router.push(id == null ? '/chat' : `/chat/${id}`);\n },\n [router]\n );\n\n // \"+ New chat\" navigates to /chat?new — the host's /chat route\n // redirects to the most-recent session by default, but the `?new`\n // hint suppresses that so the user lands on the empty hero. Without\n // this escape hatch, clicking \"+ New chat\" would bounce back to the\n // session you were trying to leave.\n const newChat = useCallback(() => {\n setActiveSessionId(null);\n setMessages([]);\n setHydratedBlocks({});\n setHydratedProse({});\n setHydratedErrors({});\n setStartedAt({});\n setInput('');\n router.push('/chat?new');\n }, [setMessages, setInput, router]);\n\n const changeProvider = useCallback(\n async (next: NarrativeProvider) => {\n if (next === provider || providerSaving) return;\n setProvider(next);\n setProviderSaving(true);\n try {\n const res = await fetch('/api/settings/me', {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ narrative_provider: next })\n });\n if (!res.ok) {\n // Roll back the optimistic update on failure.\n setProvider((curr) => (curr === next ? provider : curr));\n }\n } catch {\n setProvider((curr) => (curr === next ? provider : curr));\n } finally {\n setProviderSaving(false);\n }\n },\n [provider, providerSaving]\n );\n\n const openSession = useCallback(\n async (id: string) => {\n setLoadingSession(true);\n setActiveSessionId(id);\n syncUrl(id);\n try {\n const res = await fetch(`/api/chat/sessions/${id}`, { cache: 'no-store' });\n if (!res.ok) {\n setMessages([]);\n setHydratedBlocks({});\n setHydratedProse({});\n setHydratedErrors({});\n return;\n }\n const json = (await res.json()) as { messages: StoredMessage[] };\n const { uiMessages, blocksMap, proseMap, errorsMap } = storedToUseChat(\n json.messages ?? []\n );\n setMessages(uiMessages);\n setHydratedBlocks(blocksMap);\n setHydratedProse(proseMap);\n setHydratedErrors(errorsMap);\n setStartedAt({});\n } catch {\n setMessages([]);\n setHydratedBlocks({});\n setHydratedProse({});\n setHydratedErrors({});\n } finally {\n setLoadingSession(false);\n }\n },\n [setMessages, syncUrl]\n );\n\n const persistTitle = useCallback(\n async (id: string, title: string) => {\n const trimmed = title.trim();\n if (!trimmed) return;\n const res = await fetch(`/api/chat/sessions/${id}`, {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ title: trimmed })\n });\n if (res.ok) {\n setSessions((prev) =>\n prev.map((s) => (s.id === id ? { ...s, title: trimmed } : s))\n );\n }\n },\n []\n );\n\n const startSidebarRename = useCallback((id: string) => {\n setEditingSidebarId(id);\n }, []);\n\n const deleteSession = useCallback(\n async (id: string) => {\n if (!window.confirm('Delete this chat? This cannot be undone.')) return;\n const res = await fetch(`/api/chat/sessions/${id}`, { method: 'DELETE' });\n if (!res.ok) return;\n setSessions((prev) => prev.filter((s) => s.id !== id));\n if (activeSessionId === id) {\n setActiveSessionId(null);\n setMessages([]);\n setHydratedBlocks({});\n setHydratedProse({});\n setHydratedErrors({});\n syncUrl(null);\n }\n },\n [activeSessionId, setMessages, syncUrl]\n );\n\n // Wraps `useChat`'s handleSubmit so we can lazily create a session on\n // first turn (sidebar would otherwise sprout empty \"New chat\" rows).\n // The form's onSubmit calls `e.preventDefault()` itself; this helper\n // only needs to do the session-create dance and forward to\n // `handleSubmit`. The user message id is generated inside `useChat`\n // and sampled in the `messages` effect below for `startedAt` tracking.\n const submitForm = useCallback(\n async (e: React.FormEvent<HTMLFormElement>) => {\n const trimmed = input.trim();\n if (!trimmed || status !== 'ready') return;\n\n if (activeSessionIdRef.current == null) {\n try {\n const create = await fetch('/api/chat/sessions', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({})\n });\n if (create.ok) {\n const json = (await create.json()) as {\n session: AiChatSessionSummary;\n };\n activeSessionIdRef.current = json.session.id;\n setActiveSessionId(json.session.id);\n // Pin the URL to the new session so reload restores this thread.\n syncUrl(json.session.id);\n setSessions((prev) => [\n { id: json.session.id, title: json.session.title, updatedAt: null },\n ...prev\n ]);\n }\n } catch {\n // Session create failed — proceed without persistence.\n }\n }\n\n handleSubmit(e);\n },\n [input, status, handleSubmit, syncUrl]\n );\n\n // Stamp `startedAt` for any user message we haven't seen yet. This\n // runs on every messages update, but only writes new entries — stable\n // across re-renders so it doesn't cause loops.\n useEffect(() => {\n setStartedAt((prev) => {\n let changed = false;\n const next = { ...prev };\n for (const m of messages) {\n if (m.role === 'user' && next[m.id] == null) {\n next[m.id] = Date.now();\n changed = true;\n }\n if (m.role === 'assistant' && next[m.id] == null) {\n // Reuse the user's startedAt for the immediately-prior user\n // turn so duration tracks the full question→answer span.\n const idx = messages.findIndex((mm) => mm.id === m.id);\n for (let i = idx - 1; i >= 0; i -= 1) {\n const prior = messages[i];\n if (prior.role === 'user' && next[prior.id] != null) {\n next[m.id] = next[prior.id];\n changed = true;\n break;\n }\n }\n }\n }\n return changed ? next : prev;\n });\n }, [messages]);\n\n const heroVisible = answers.length === 0 && !loadingSession;\n const greeting = useMemo(\n () =>\n `Hi ${userFirstName || 'there'}${\n userFirstName.endsWith('s') ? '' : ''\n },`,\n [userFirstName]\n );\n\n const activeTitle = activeSessionId\n ? sessions.find((s) => s.id === activeSessionId)?.title ?? 'Chat'\n : 'New chat';\n\n // Retry resubmits the last user question via setInput + a synthetic\n // submit; the form's submit handler does the lazy-session-create dance.\n const retry = useCallback(\n (q: string) => {\n setInput(q);\n // Defer one tick so `input` is updated before the submit reads it.\n window.setTimeout(() => {\n const form = textareaRef.current?.form;\n if (form) form.requestSubmit();\n }, 0);\n },\n [setInput]\n );\n\n return (\n <div className=\"relative flex h-full min-h-0 w-full overflow-hidden rounded-lg border border-border bg-background\">\n {/* Backdrop: click to close. Pointer-events only when open so the\n chat panel underneath stays interactive when the sidebar is\n closed. */}\n <div\n onClick={() => setSidebarOpen(false)}\n aria-hidden=\"true\"\n className={cn(\n 'absolute inset-0 z-10 bg-background/60 backdrop-blur-sm transition-opacity duration-200',\n sidebarOpen\n ? 'opacity-100'\n : 'pointer-events-none opacity-0'\n )}\n />\n\n {/* Overlay session sidebar — slides in from the left, never\n shrinks the chat panel. z-20 so it sits above the backdrop. */}\n <aside\n inert={!sidebarOpen}\n className={cn(\n 'absolute inset-y-0 left-0 z-20 flex w-72 max-w-[85vw] flex-col border-r border-border bg-sidebar text-sidebar-foreground shadow-lg transition-transform duration-200 ease-out',\n sidebarOpen ? 'translate-x-0' : '-translate-x-full'\n )}\n >\n <div className=\"flex items-center gap-2 border-b border-sidebar-border p-2\">\n <button\n type=\"button\"\n onClick={() => setSidebarOpen(false)}\n className=\"inline-flex size-8 items-center justify-center rounded-md text-sidebar-foreground/70 hover:bg-sidebar-accent hover:text-sidebar-foreground\"\n aria-label=\"Close sidebar\"\n >\n <PanelLeftClose className=\"size-4\" />\n </button>\n <button\n type=\"button\"\n onClick={() => {\n newChat();\n setSidebarOpen(false);\n }}\n className=\"ml-auto inline-flex items-center gap-1.5 rounded-full border border-sidebar-border bg-sidebar-accent px-3 py-1.5 text-xs font-medium text-sidebar-accent-foreground hover:bg-sidebar-accent/80\"\n >\n <Plus className=\"size-3.5\" />\n New chat\n </button>\n </div>\n <div className=\"flex-1 overflow-y-auto p-2\">\n {sessions.length === 0 ? (\n <p className=\"px-2 py-3 text-xs text-sidebar-foreground/60\">\n No chats yet. Ask something below to start.\n </p>\n ) : (\n <ul className=\"flex flex-col gap-0.5\">\n {sessions.map((s) => {\n const active = s.id === activeSessionId;\n const editing = s.id === editingSidebarId;\n if (editing) {\n return (\n <li key={s.id} className=\"px-1 py-1\">\n <SidebarTitleEditor\n initial={s.title}\n onCancel={() => setEditingSidebarId(null)}\n onSave={(next) => {\n setEditingSidebarId(null);\n void persistTitle(s.id, next);\n }}\n />\n </li>\n );\n }\n return (\n <li key={s.id} className=\"group relative\">\n <Link\n href={`/chat/${s.id}`}\n onClick={() => setSidebarOpen(false)}\n className={cn(\n 'flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm',\n active\n ? 'bg-sidebar-accent text-sidebar-accent-foreground'\n : 'text-sidebar-foreground/80 hover:bg-sidebar-accent/60 hover:text-sidebar-foreground'\n )}\n title={s.title}\n >\n <span className=\"truncate\">{s.title}</span>\n </Link>\n <div className=\"absolute right-1 top-1/2 hidden -translate-y-1/2 items-center gap-0.5 group-hover:flex\">\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n startSidebarRename(s.id);\n }}\n aria-label=\"Rename\"\n className=\"inline-flex size-6 items-center justify-center rounded text-sidebar-foreground/60 hover:bg-sidebar hover:text-sidebar-foreground\"\n >\n <Pencil className=\"size-3\" />\n </button>\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n void deleteSession(s.id);\n }}\n aria-label=\"Delete\"\n className=\"inline-flex size-6 items-center justify-center rounded text-sidebar-foreground/60 hover:bg-sidebar hover:text-destructive\"\n >\n <Trash2 className=\"size-3\" />\n </button>\n </div>\n </li>\n );\n })}\n </ul>\n )}\n </div>\n </aside>\n\n <section className=\"relative flex flex-1 flex-col overflow-hidden\">\n <header className=\"flex items-center gap-2 px-3 py-3 text-sm text-muted-foreground\">\n <button\n type=\"button\"\n onClick={() => setSidebarOpen(true)}\n aria-label=\"Open chat history\"\n className=\"inline-flex size-8 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground\"\n >\n <Menu className=\"size-4\" />\n </button>\n <Sparkles className=\"size-4 text-primary\" />\n {activeSessionId != null ? (\n <EditableTitle\n key={activeSessionId}\n title={activeTitle}\n onSave={(next) => void persistTitle(activeSessionId, next)}\n />\n ) : (\n <span className=\"truncate\">{activeTitle}</span>\n )}\n </header>\n\n <div\n ref={threadRef}\n className=\"min-h-0 flex-1 overflow-y-auto px-4 pb-6 pt-2\"\n >\n {loadingSession ? (\n <div className=\"flex h-full items-center justify-center text-sm text-muted-foreground\">\n <Loader2 className=\"mr-2 size-4 animate-spin\" /> Loading conversation…\n </div>\n ) : heroVisible ? (\n <div className=\"flex h-full flex-col items-center justify-center text-center\">\n <h1 className=\"text-2xl font-medium tracking-tight text-foreground sm:text-3xl\">\n {greeting}\n </h1>\n <p className=\"mt-2 text-2xl font-light tracking-tight text-muted-foreground sm:text-3xl\">\n What's on your mind?\n </p>\n </div>\n ) : (\n <div className=\"mx-auto flex w-full max-w-3xl flex-col gap-6\">\n {answers.map((a, idx) => (\n <AnswerView\n key={idx}\n answer={a}\n onRetry={() => retry(a.question)}\n forwardRef={idx === answers.length - 1 ? lastAnswerRef : undefined}\n // The last turn reserves enough viewport so the AI\n // response has room to stream below the question\n // without the user needing to scroll. Calc subtracts\n // the input-pill area (~14rem) and a comfort buffer.\n isLast={idx === answers.length - 1}\n />\n ))}\n </div>\n )}\n </div>\n\n <div className=\"shrink-0 px-4 pb-4 pt-2\">\n <form\n className=\"mx-auto w-full max-w-3xl\"\n onSubmit={(e) => {\n e.preventDefault();\n void submitForm(e);\n }}\n >\n <div className=\"flex flex-col gap-2 rounded-3xl border border-border bg-background px-4 py-3 shadow-sm\">\n <textarea\n ref={textareaRef}\n value={input}\n onChange={handleInputChange}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n e.currentTarget.form?.requestSubmit();\n }\n }}\n placeholder=\"Ask AI...\"\n rows={1}\n disabled={status !== 'ready'}\n style={{ maxHeight: TEXTAREA_MAX_PX }}\n className=\"w-full resize-none overflow-y-auto border-0 bg-transparent py-1 text-sm leading-6 text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-0 disabled:opacity-60\"\n />\n <div className=\"flex items-center justify-between gap-2\">\n <span\n className=\"inline-flex max-w-[60%] items-center gap-1.5 truncate rounded-full border border-border bg-muted/40 px-2.5 py-1 text-xs font-medium text-muted-foreground\"\n title={`Scope: ${scopeLabel}`}\n >\n Scope: <span className=\"truncate text-foreground\">{scopeLabel}</span>\n </span>\n <div className=\"flex items-center gap-2\">\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n className=\"inline-flex items-center gap-1 rounded-full px-2.5 py-1 text-xs font-medium text-muted-foreground hover:bg-accent hover:text-foreground\"\n aria-label=\"Choose model\"\n >\n {PROVIDER_LABELS[provider]}\n <ChevronDown className=\"size-3.5\" />\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-56\">\n {(['claude', 'grok', 'gemini'] as const).map((p) => (\n <DropdownMenuItem\n key={p}\n onSelect={() => void changeProvider(p)}\n className=\"flex items-start gap-2\"\n >\n <Check\n className={cn(\n 'mt-0.5 size-4',\n provider === p ? 'opacity-100' : 'opacity-0'\n )}\n />\n <div className=\"flex flex-col\">\n <span className=\"text-sm font-medium\">\n {PROVIDER_LABELS[p]}\n </span>\n <span className=\"text-xs text-muted-foreground\">\n {PROVIDER_DESCRIPTIONS[p]}\n </span>\n </div>\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n <button\n type=\"submit\"\n disabled={status !== 'ready' || !input.trim()}\n aria-label=\"Send\"\n className=\"inline-flex size-8 shrink-0 items-center justify-center rounded-full bg-primary text-primary-foreground transition-colors enabled:hover:bg-primary/90 disabled:opacity-40\"\n >\n {status === 'streaming' || status === 'submitted' ? (\n <Loader2 className=\"size-4 animate-spin\" />\n ) : (\n <ArrowUp className=\"size-4\" />\n )}\n </button>\n </div>\n </div>\n </div>\n <p className=\"mt-2 text-center text-xs text-muted-foreground\">\n {PROVIDER_LABELS[provider]} is AI and can make mistakes.\n </p>\n </form>\n </div>\n </section>\n </div>\n );\n}\n\nfunction AnswerView({\n answer,\n onRetry,\n forwardRef,\n isLast\n}: {\n answer: AnswerState;\n onRetry: () => void;\n /** Attached to the outer container so the parent can scroll the latest turn into view on submit. */\n forwardRef?: React.RefObject<HTMLDivElement | null>;\n /**\n * The last turn reserves enough viewport that the AI response has\n * room to grow under the pinned question. The parent flex column\n * uses `min-h-[...]` here so a short answer doesn't leave a\n * ridiculous gap, but a long-running response can stream below\n * without the user being autoscrolled.\n */\n isLast?: boolean;\n}) {\n const [copied, setCopied] = useState(false);\n\n const handleCopy = useCallback(async () => {\n // Prefer the structured response; fall back to the error envelope\n // when the turn produced no blocks so the user can still copy the\n // failure (eg. quota error message → paste into an issue).\n const blockText = blocksToPlainText(answer.blocks);\n const text =\n blockText ||\n (answer.error\n ? `${answer.error.code}: ${answer.error.message}`\n : '');\n if (!text) return;\n try {\n await navigator.clipboard.writeText(text);\n setCopied(true);\n window.setTimeout(() => setCopied(false), 1500);\n } catch {\n // Clipboard blocked (insecure context, permission denied) — silent.\n }\n }, [answer.blocks, answer.error]);\n\n const showActions =\n answer.done && (answer.blocks.length > 0 || answer.error != null);\n // While the agent is still computing the first block, drop the\n // nested-column layout entirely and render a single flex row. The\n // normal layout has an empty `AnswerBlocks` wrapper that contributes\n // a 12px flex-gap to the column even when it has no blocks, which\n // throws `items-center` off so the icon and \"Thinking…\" don't align.\n const isThinking =\n !answer.done && answer.blocks.length === 0 && !answer.error;\n\n // Live ticker — re-renders once a second while the agent is thinking\n // so the inline \"(5s)\" counter advances. We force a re-render via a\n // dummy state instead of recomputing elapsed in a useEffect because\n // the elapsed value is derived from `answer.startedAt` (a prop) and\n // `Date.now()` — anything stored in state would just duplicate that.\n const [, forceTick] = useState(0);\n useEffect(() => {\n if (answer.done || answer.startedAt == null) return;\n const id = window.setInterval(() => forceTick((n) => n + 1), 1000);\n return () => window.clearInterval(id);\n }, [answer.done, answer.startedAt]);\n\n // Live elapsed for the thinking state; final stamped duration once done.\n const liveElapsed =\n answer.startedAt != null ? Date.now() - answer.startedAt : null;\n const finalDuration = answer.durationMs;\n\n return (\n <div\n ref={forwardRef}\n // scroll-mt nudges scrollIntoView so the question doesn't kiss\n // the very top of the thread container.\n className={cn(\n 'flex flex-col gap-4 scroll-mt-2',\n // Reserve space below the latest turn so the AI response has a\n // full screen to fill without bouncing the user. Calc subtracts\n // the chat header (~3rem) and the input pill area (~10rem) from\n // the dynamic viewport height.\n isLast && 'min-h-[calc(100dvh-13rem)]'\n )}\n >\n <div className=\"flex justify-end\">\n <UserChip text={answer.question} />\n </div>\n {isThinking ? (\n <div className=\"flex items-center gap-3\">\n <div className=\"flex size-7 shrink-0 items-center justify-center rounded-full bg-primary/10 text-primary\">\n <Sparkles className=\"size-4\" />\n </div>\n <p className=\"flex items-center text-sm text-muted-foreground\">\n <Loader2 className=\"mr-1 inline size-3.5 animate-spin\" />\n Thinking…\n {liveElapsed != null && liveElapsed >= 1000 && (\n <span className=\"ml-2 text-xs tabular-nums\">\n ({formatDuration(liveElapsed)})\n </span>\n )}\n </p>\n </div>\n ) : (\n <div className=\"flex items-start gap-3\">\n <div className=\"mt-0.5 flex size-7 shrink-0 items-center justify-center rounded-full bg-primary/10 text-primary\">\n <Sparkles className=\"size-4\" />\n </div>\n <div className=\"flex min-w-0 flex-1 flex-col gap-3\">\n <AnswerBlocks blocks={answer.blocks} />\n {answer.error && (\n <div className=\"wrap-break-word whitespace-pre-wrap rounded border border-amber-300 bg-amber-50 p-3 text-sm text-amber-900 dark:border-amber-800 dark:bg-amber-950/30 dark:text-amber-100\">\n {answer.error.code}: {answer.error.message}\n </div>\n )}\n {showActions && (\n <div className=\"flex items-center gap-1\">\n {(answer.blocks.length > 0 || answer.error != null) && (\n <button\n type=\"button\"\n onClick={handleCopy}\n aria-label={\n answer.blocks.length === 0 && answer.error\n ? 'Copy error'\n : 'Copy response'\n }\n title={copied ? 'Copied' : 'Copy'}\n className=\"inline-flex size-8 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground\"\n >\n {copied ? (\n <Check className=\"size-4\" />\n ) : (\n <Copy className=\"size-4\" />\n )}\n </button>\n )}\n <button\n type=\"button\"\n onClick={onRetry}\n aria-label=\"Retry\"\n title=\"Retry\"\n className=\"inline-flex size-8 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground\"\n >\n <RotateCcw className=\"size-4\" />\n </button>\n {finalDuration != null && finalDuration >= 1000 && (\n <span\n className=\"ml-1 text-xs text-muted-foreground tabular-nums\"\n title=\"Time taken to generate this response\"\n >\n {formatDuration(finalDuration)}\n </span>\n )}\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n );\n}\n\n/**\n * Flatten an assistant turn's blocks into plain text for the clipboard\n * — paragraph prose, list items, callouts, and a tab-separated table\n * dump. Charts are referenced by title since the visual is what\n * matters there.\n */\nfunction blocksToPlainText(blocks: BlockState[]): string {\n return blocks\n .map((b) => {\n if (b.kind === 'paragraph_brief') {\n return b.prose || b.key_facts.join('. ');\n }\n if (b.kind === 'list') {\n const lines = b.items.map((it, i) =>\n b.style === 'numbered' ? `${i + 1}. ${it}` : `- ${it}`\n );\n return [b.title, ...lines].filter(Boolean).join('\\n');\n }\n if (b.kind === 'chart') {\n return `${b.title} (chart)`;\n }\n if (b.kind === 'table') {\n const header = b.columns.join('\\t');\n const rows = b.rows.map((r) =>\n r.map((c) => (c == null ? '—' : String(c))).join('\\t')\n );\n return [b.title, header, ...rows].join('\\n');\n }\n if (b.kind === 'callout') return b.text;\n return '';\n })\n .filter(Boolean)\n .join('\\n\\n');\n}\n\n/**\n * User-message bubble. Wraps long content (including unspaced strings\n * via `wrap-break-word`); when collapsed it caps at 3 lines and fades\n * the last line into the bubble background instead of using a hard\n * ellipsis. A chevron + \"Show more / Show less\" toggle reveals only\n * when the cap actually truncates content.\n */\nfunction UserChip({ text }: { text: string }) {\n const [expanded, setExpanded] = useState(false);\n const [overflowing, setOverflowing] = useState(false);\n const ref = useRef<HTMLDivElement | null>(null);\n\n useLayoutEffect(() => {\n const el = ref.current;\n if (!el || expanded) return;\n setOverflowing(el.scrollHeight > el.clientHeight + 1);\n }, [text, expanded]);\n\n return (\n <div className=\"max-w-[85%] rounded-2xl bg-muted px-4 py-2 text-sm text-foreground\">\n <div className=\"relative\">\n <div\n ref={ref}\n className={cn(\n 'whitespace-pre-wrap wrap-break-word leading-6',\n // 3 lines × leading-6 (24px) = 72px → max-h-18.\n !expanded && 'max-h-18 overflow-hidden'\n )}\n >\n {text}\n </div>\n {!expanded && overflowing && (\n <div\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-x-0 bottom-0 h-6 bg-linear-to-t from-muted to-transparent\"\n />\n )}\n </div>\n {(overflowing || expanded) && (\n <button\n type=\"button\"\n onClick={() => setExpanded((v) => !v)}\n className=\"mt-1 inline-flex items-center gap-1 text-xs font-medium text-muted-foreground hover:text-foreground\"\n >\n {expanded ? (\n <>\n <ChevronUp className=\"size-3.5\" />\n Show less\n </>\n ) : (\n <>\n <ChevronDown className=\"size-3.5\" />\n Show more\n </>\n )}\n </button>\n )}\n </div>\n );\n}\n\n/**\n * Convert stored chat messages into the `useChat` `Message[]` shape\n * plus per-assistant-message hydration maps for blocks, prose, and\n * errors. The two outputs are kept separate because `useChat`'s\n * `Message` type doesn't carry our custom `Block[]` payload — the maps\n * sit alongside `messages` and the renderer joins them by message id.\n */\nfunction storedToUseChat(stored: StoredMessage[]): {\n uiMessages: UIMessage[];\n blocksMap: Record<string, BlockState[]>;\n proseMap: Record<string, string>;\n errorsMap: Record<string, { code: string; message: string }>;\n} {\n const uiMessages: UIMessage[] = [];\n const blocksMap: Record<string, BlockState[]> = {};\n const proseMap: Record<string, string> = {};\n const errorsMap: Record<string, { code: string; message: string }> = {};\n let pendingUser: { id: string; question: string } | null = null;\n\n for (const m of stored) {\n if (m.role === 'user') {\n const id = `user-${m.id}`;\n const question = m.question ?? '';\n uiMessages.push({ id, role: 'user', content: question });\n pendingUser = { id, question };\n continue;\n }\n if (m.role === 'assistant') {\n const id = `assistant-${m.id}`;\n // Reconstruct blocks via sanitiseBlock and reattach prose runs to\n // their matching paragraph_brief entry (mirroring the on-disk\n // shape persisted by the Vercel route's `onFinish`).\n const blocks: BlockState[] = [];\n const stored = (m.blocks ?? []) as Block[];\n stored.forEach((b, i) => {\n const sanitised = sanitiseBlock({ ...(b as Block), index: i } as Block & {\n index: number;\n });\n if (sanitised.kind === 'paragraph_brief') {\n sanitised.prose = m.prose?.[String(i)] ?? '';\n }\n blocks[i] = sanitised;\n });\n\n // Joined prose serves as the message `content`, which the\n // renderer uses as a fallback if no paragraph_brief is present.\n const joinedProse = Object.values(m.prose ?? {})\n .filter(Boolean)\n .join('\\n\\n');\n\n uiMessages.push({\n id,\n role: 'assistant',\n content: joinedProse\n });\n blocksMap[id] = blocks;\n if (joinedProse) proseMap[id] = joinedProse;\n if (m.errorJson) errorsMap[id] = m.errorJson;\n pendingUser = null;\n }\n }\n\n return { uiMessages, blocksMap, proseMap, errorsMap };\n}\n","// @firstlovecenter/ai-chat/ui — public surface\n//\n// Phase 2: two chat shells share the same `AiChatProps` contract — the\n// bespoke SSE shell (`AiChat`) and the Vercel AI SDK shell\n// (`VercelChat`). The host picks one via the `chatInterfaces` registry\n// or `getChatInterface(id)`.\n\n'use client';\n\nimport type { ComponentType } from 'react';\nimport { AiChat } from './ai-chat';\nimport { VercelChat } from './vercel-chat';\nimport type { AiChatProps } from './types';\n\nexport type ChatInterfaceDef = {\n id: 'custom' | 'vercel';\n label: string;\n description: string;\n Component: ComponentType<AiChatProps>;\n};\n\nexport const chatInterfaces: ChatInterfaceDef[] = [\n {\n id: 'custom',\n label: 'Custom',\n description: 'Bespoke SSE chat with structured blocks and prose narrator pass.',\n Component: AiChat\n },\n {\n id: 'vercel',\n label: 'Vercel',\n description: 'Vercel AI SDK chat with native tool loop and data-stream protocol.',\n Component: VercelChat\n }\n];\n\nexport function getChatInterface(id: string): ChatInterfaceDef {\n return chatInterfaces.find((c) => c.id === id) ?? chatInterfaces[0];\n}\n\nexport { AiChat, VercelChat };\nexport { AnswerBlocks, sanitiseBlock, type BlockState } from './answer-blocks';\nexport type { AiChatProps, AiChatSessionSummary } from './types';\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/ui/_shared/cn.ts","../../src/ui/_shared/dropdown-menu.tsx","../../src/ui/_shared/title-editors.tsx","../../src/ui/_shared/chart-card.tsx","../../src/ui/_shared/chart.tsx","../../src/ui/answer-blocks.tsx","../../src/ui/ai-chat.tsx","../../src/ui/vercel-chat.tsx","../../src/ui/index.tsx"],"names":["DropdownMenuPrimitive","jsx","useState","useEffect","jsxs","React","RechartsPrimitive","config","Fragment","useMemo","PieChart","Pie","Cell","Label","BarChart","CartesianGrid","XAxis","YAxis","Bar","LineChart","Line","useRouter","useRef","useLayoutEffect","useCallback","PanelLeftClose","Plus","Link","Pencil","Trash2","Menu","Sparkles","Loader2","ChevronDown","Check","ArrowUp","Copy","RotateCcw","ChevronUp","formatDuration","PROVIDER_LABELS","TEXTAREA_MAX_PX","PROVIDER_DESCRIPTIONS","data","useChat","AnswerView","blocksToPlainText","UserChip","stored"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Minimal class-name combiner. The host uses `clsx + tailwind-merge`;\n * for the package we just filter falsy values and join. Duplicate or\n * conflicting tailwind classes are harmless at runtime — the host can\n * still layer its own `cn` if it cares about deduping.\n */\nexport function cn(...args: unknown[]): string {\n const out: string[] = [];\n for (const a of args) {\n if (!a) continue;\n if (typeof a === 'string') {\n out.push(a);\n } else if (Array.isArray(a)) {\n const inner = cn(...a);\n if (inner) out.push(inner);\n } else if (typeof a === 'object') {\n for (const [k, v] of Object.entries(a as Record<string, unknown>)) {\n if (v) out.push(k);\n }\n }\n }\n return out.join(' ');\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport { DropdownMenu as DropdownMenuPrimitive } from \"radix-ui\"\n\nimport { cn } from \"./cn\"\nimport { CheckIcon, ChevronRightIcon } from \"lucide-react\"\n\nfunction DropdownMenu({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Root>) {\n return <DropdownMenuPrimitive.Root data-slot=\"dropdown-menu\" {...props} />\n}\n\nfunction DropdownMenuPortal({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Portal>) {\n return (\n <DropdownMenuPrimitive.Portal data-slot=\"dropdown-menu-portal\" {...props} />\n )\n}\n\nfunction DropdownMenuTrigger({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Trigger>) {\n return (\n <DropdownMenuPrimitive.Trigger\n data-slot=\"dropdown-menu-trigger\"\n {...props}\n />\n )\n}\n\nfunction DropdownMenuContent({\n className,\n align = \"start\",\n sideOffset = 4,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Content>) {\n return (\n <DropdownMenuPrimitive.Portal>\n <DropdownMenuPrimitive.Content\n data-slot=\"dropdown-menu-content\"\n sideOffset={sideOffset}\n align={align}\n className={cn(\"z-50 max-h-(--radix-dropdown-menu-content-available-height) w-(--radix-dropdown-menu-trigger-width) min-w-32 origin-(--radix-dropdown-menu-content-transform-origin) overflow-x-hidden overflow-y-auto rounded-lg bg-popover p-1 text-popover-foreground shadow-md ring-1 ring-foreground/10 duration-100 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]:overflow-hidden data-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\", className )}\n {...props}\n />\n </DropdownMenuPrimitive.Portal>\n )\n}\n\nfunction DropdownMenuGroup({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Group>) {\n return (\n <DropdownMenuPrimitive.Group data-slot=\"dropdown-menu-group\" {...props} />\n )\n}\n\nfunction DropdownMenuItem({\n className,\n inset,\n variant = \"default\",\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Item> & {\n inset?: boolean\n variant?: \"default\" | \"destructive\"\n}) {\n return (\n <DropdownMenuPrimitive.Item\n data-slot=\"dropdown-menu-item\"\n data-inset={inset}\n data-variant={variant}\n className={cn(\n \"group/dropdown-menu-item relative flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7 data-[variant=destructive]:text-destructive data-[variant=destructive]:focus:bg-destructive/10 data-[variant=destructive]:focus:text-destructive dark:data-[variant=destructive]:focus:bg-destructive/20 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4 data-[variant=destructive]:*:[svg]:text-destructive\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuCheckboxItem({\n className,\n children,\n checked,\n inset,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.CheckboxItem> & {\n inset?: boolean\n}) {\n return (\n <DropdownMenuPrimitive.CheckboxItem\n data-slot=\"dropdown-menu-checkbox-item\"\n data-inset={inset}\n className={cn(\n \"relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n checked={checked}\n {...props}\n >\n <span\n className=\"pointer-events-none absolute right-2 flex items-center justify-center\"\n data-slot=\"dropdown-menu-checkbox-item-indicator\"\n >\n <DropdownMenuPrimitive.ItemIndicator>\n <CheckIcon\n />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.CheckboxItem>\n )\n}\n\nfunction DropdownMenuRadioGroup({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioGroup>) {\n return (\n <DropdownMenuPrimitive.RadioGroup\n data-slot=\"dropdown-menu-radio-group\"\n {...props}\n />\n )\n}\n\nfunction DropdownMenuRadioItem({\n className,\n children,\n inset,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.RadioItem> & {\n inset?: boolean\n}) {\n return (\n <DropdownMenuPrimitive.RadioItem\n data-slot=\"dropdown-menu-radio-item\"\n data-inset={inset}\n className={cn(\n \"relative flex cursor-default items-center gap-1.5 rounded-md py-1 pr-8 pl-1.5 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground focus:**:text-accent-foreground data-inset:pl-7 data-disabled:pointer-events-none data-disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n <span\n className=\"pointer-events-none absolute right-2 flex items-center justify-center\"\n data-slot=\"dropdown-menu-radio-item-indicator\"\n >\n <DropdownMenuPrimitive.ItemIndicator>\n <CheckIcon\n />\n </DropdownMenuPrimitive.ItemIndicator>\n </span>\n {children}\n </DropdownMenuPrimitive.RadioItem>\n )\n}\n\nfunction DropdownMenuLabel({\n className,\n inset,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Label> & {\n inset?: boolean\n}) {\n return (\n <DropdownMenuPrimitive.Label\n data-slot=\"dropdown-menu-label\"\n data-inset={inset}\n className={cn(\n \"px-1.5 py-1 text-xs font-medium text-muted-foreground data-inset:pl-7\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuSeparator({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Separator>) {\n return (\n <DropdownMenuPrimitive.Separator\n data-slot=\"dropdown-menu-separator\"\n className={cn(\"-mx-1 my-1 h-px bg-border\", className)}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuShortcut({\n className,\n ...props\n}: React.ComponentProps<\"span\">) {\n return (\n <span\n data-slot=\"dropdown-menu-shortcut\"\n className={cn(\n \"ml-auto text-xs tracking-widest text-muted-foreground group-focus/dropdown-menu-item:text-accent-foreground\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction DropdownMenuSub({\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.Sub>) {\n return <DropdownMenuPrimitive.Sub data-slot=\"dropdown-menu-sub\" {...props} />\n}\n\nfunction DropdownMenuSubTrigger({\n className,\n inset,\n children,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubTrigger> & {\n inset?: boolean\n}) {\n return (\n <DropdownMenuPrimitive.SubTrigger\n data-slot=\"dropdown-menu-sub-trigger\"\n data-inset={inset}\n className={cn(\n \"flex cursor-default items-center gap-1.5 rounded-md px-1.5 py-1 text-sm outline-hidden select-none focus:bg-accent focus:text-accent-foreground not-data-[variant=destructive]:focus:**:text-accent-foreground data-inset:pl-7 data-open:bg-accent data-open:text-accent-foreground [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n className\n )}\n {...props}\n >\n {children}\n <ChevronRightIcon className=\"ml-auto\" />\n </DropdownMenuPrimitive.SubTrigger>\n )\n}\n\nfunction DropdownMenuSubContent({\n className,\n ...props\n}: React.ComponentProps<typeof DropdownMenuPrimitive.SubContent>) {\n return (\n <DropdownMenuPrimitive.SubContent\n data-slot=\"dropdown-menu-sub-content\"\n className={cn(\"z-50 min-w-[96px] origin-(--radix-dropdown-menu-content-transform-origin) overflow-hidden rounded-lg bg-popover p-1 text-popover-foreground shadow-lg ring-1 ring-foreground/10 duration-100 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-open:animate-in data-open:fade-in-0 data-open:zoom-in-95 data-closed:animate-out data-closed:fade-out-0 data-closed:zoom-out-95\", className )}\n {...props}\n />\n )\n}\n\nexport {\n DropdownMenu,\n DropdownMenuPortal,\n DropdownMenuTrigger,\n DropdownMenuContent,\n DropdownMenuGroup,\n DropdownMenuLabel,\n DropdownMenuItem,\n DropdownMenuCheckboxItem,\n DropdownMenuRadioGroup,\n DropdownMenuRadioItem,\n DropdownMenuSeparator,\n DropdownMenuShortcut,\n DropdownMenuSub,\n DropdownMenuSubTrigger,\n DropdownMenuSubContent,\n}\n","/**\n * Shared inline title editors used by both the custom `AiChat` shell and\n * the Vercel AI SDK `VercelChat` shell. Lifted verbatim from\n * `ai-chat.tsx` so the two chat shells render identical sidebar/header\n * editors without divergence over time.\n */\n'use client';\n\nimport { useEffect, useState } from 'react';\n\n/**\n * Inline editor for a sidebar session row. Renders an autofocused\n * input with the row's current title pre-selected. Enter or blur\n * commits, Escape cancels — the parent decides what to do with the\n * resulting string (PATCH and update sidebar state, in our case).\n */\nexport function SidebarTitleEditor({\n initial,\n onSave,\n onCancel\n}: {\n initial: string;\n onSave: (next: string) => void;\n onCancel: () => void;\n}) {\n const [draft, setDraft] = useState(initial);\n const commit = () => {\n const trimmed = draft.trim();\n if (trimmed && trimmed !== initial) onSave(trimmed);\n else onCancel();\n };\n return (\n <input\n autoFocus\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n onFocus={(e) => e.currentTarget.select()}\n onClick={(e) => e.stopPropagation()}\n onBlur={commit}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n commit();\n } else if (e.key === 'Escape') {\n e.preventDefault();\n onCancel();\n }\n }}\n maxLength={200}\n className=\"w-full rounded-md border border-sidebar-border bg-sidebar-accent/40 px-2 py-1.5 text-sm text-sidebar-foreground focus:outline-none focus:ring-1 focus:ring-ring\"\n />\n );\n}\n\n/**\n * Inline-editable title for the chat header. Click the label to enter\n * edit mode — the input pre-selects the current title so a fresh name\n * just overwrites it. Enter or blur commits via `onSave`, Escape\n * cancels. Mirrors `SidebarTitleEditor` so renaming feels identical\n * whether the user clicks the title in the header or the pencil in\n * the sidebar.\n */\nexport function EditableTitle({\n title,\n onSave\n}: {\n title: string;\n onSave: (next: string) => void;\n}) {\n const [editing, setEditing] = useState(false);\n const [draft, setDraft] = useState(title);\n\n useEffect(() => {\n if (!editing) setDraft(title);\n }, [title, editing]);\n\n if (!editing) {\n return (\n <button\n type=\"button\"\n onClick={() => {\n setDraft(title);\n setEditing(true);\n }}\n className=\"w-64 max-w-full min-w-0 truncate rounded px-2 py-0.5 text-left hover:bg-accent hover:text-foreground\"\n title=\"Click to rename\"\n >\n {title}\n </button>\n );\n }\n\n const commit = () => {\n const trimmed = draft.trim();\n setEditing(false);\n if (trimmed && trimmed !== title) onSave(trimmed);\n };\n\n return (\n <input\n autoFocus\n value={draft}\n onChange={(e) => setDraft(e.target.value)}\n onFocus={(e) => e.currentTarget.select()}\n onBlur={commit}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault();\n commit();\n } else if (e.key === 'Escape') {\n e.preventDefault();\n setEditing(false);\n setDraft(title);\n }\n }}\n className=\"w-64 max-w-full min-w-0 rounded border border-border bg-background px-2 py-0.5 text-sm text-foreground focus:outline-none focus:ring-1 focus:ring-ring\"\n maxLength={200}\n />\n );\n}\n","'use client';\n\nimport type { ReactNode } from 'react';\n\nimport { cn } from './cn';\n\n/**\n * Minimal port of the host's `ChartCard`. The host wraps its shadcn\n * `Card` primitive; we inline an equivalent flex-column with a header\n * and content area so the package doesn't need the full Card family.\n * Tailwind class semantics match (rounded/border/text-card-foreground).\n */\nexport function ChartCard({\n title,\n subtitle,\n children,\n className\n}: {\n title: string;\n subtitle?: string;\n children: ReactNode;\n className?: string;\n}) {\n return (\n <div\n className={cn(\n 'flex flex-col rounded-xl border border-border bg-card text-card-foreground shadow-sm',\n className\n )}\n >\n <div className=\"flex flex-col gap-1.5 p-6\">\n <h3 className=\"font-semibold leading-none tracking-tight\">{title}</h3>\n {subtitle ? (\n <p className=\"text-sm text-muted-foreground\">{subtitle}</p>\n ) : null}\n </div>\n <div className=\"p-6 pt-0\">{children}</div>\n </div>\n );\n}\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as RechartsPrimitive from \"recharts\"\nimport type { TooltipValueType } from \"recharts\"\n\nimport { cn } from \"./cn\"\n\n// Format: { THEME_NAME: CSS_SELECTOR }\nconst THEMES = { light: \"\", dark: \".dark\" } as const\n\nconst INITIAL_DIMENSION = { width: 320, height: 200 } as const\ntype TooltipNameType = number | string\n\nexport type ChartConfig = Record<\n string,\n {\n label?: React.ReactNode\n icon?: React.ComponentType\n } & (\n | { color?: string; theme?: never }\n | { color?: never; theme: Record<keyof typeof THEMES, string> }\n )\n>\n\ntype ChartContextProps = {\n config: ChartConfig\n}\n\nconst ChartContext = React.createContext<ChartContextProps | null>(null)\n\nfunction useChart() {\n const context = React.useContext(ChartContext)\n\n if (!context) {\n throw new Error(\"useChart must be used within a <ChartContainer />\")\n }\n\n return context\n}\n\nfunction ChartContainer({\n id,\n className,\n children,\n config,\n initialDimension = INITIAL_DIMENSION,\n ...props\n}: React.ComponentProps<\"div\"> & {\n config: ChartConfig\n children: React.ComponentProps<\n typeof RechartsPrimitive.ResponsiveContainer\n >[\"children\"]\n initialDimension?: {\n width: number\n height: number\n }\n}) {\n const uniqueId = React.useId()\n const chartId = `chart-${id ?? uniqueId.replace(/:/g, \"\")}`\n\n return (\n <ChartContext.Provider value={{ config }}>\n <div\n data-slot=\"chart\"\n data-chart={chartId}\n className={cn(\n \"flex aspect-video justify-center text-xs [&_.recharts-cartesian-axis-tick_text]:fill-muted-foreground [&_.recharts-cartesian-grid_line[stroke='#ccc']]:stroke-border/50 [&_.recharts-curve.recharts-tooltip-cursor]:stroke-border [&_.recharts-dot[stroke='#fff']]:stroke-transparent [&_.recharts-layer]:outline-hidden [&_.recharts-polar-grid_[stroke='#ccc']]:stroke-border [&_.recharts-radial-bar-background-sector]:fill-muted [&_.recharts-rectangle.recharts-tooltip-cursor]:fill-muted [&_.recharts-reference-line_[stroke='#ccc']]:stroke-border [&_.recharts-sector]:outline-hidden [&_.recharts-sector[stroke='#fff']]:stroke-transparent [&_.recharts-surface]:outline-hidden\",\n className\n )}\n {...props}\n >\n <ChartStyle id={chartId} config={config} />\n <RechartsPrimitive.ResponsiveContainer\n initialDimension={initialDimension}\n >\n {children}\n </RechartsPrimitive.ResponsiveContainer>\n </div>\n </ChartContext.Provider>\n )\n}\n\nconst ChartStyle = ({ id, config }: { id: string; config: ChartConfig }) => {\n const colorConfig = Object.entries(config).filter(\n ([, config]) => config.theme ?? config.color\n )\n\n if (!colorConfig.length) {\n return null\n }\n\n return (\n <style\n dangerouslySetInnerHTML={{\n __html: Object.entries(THEMES)\n .map(\n ([theme, prefix]) => `\n${prefix} [data-chart=${id}] {\n${colorConfig\n .map(([key, itemConfig]) => {\n const color =\n itemConfig.theme?.[theme as keyof typeof itemConfig.theme] ??\n itemConfig.color\n return color ? ` --color-${key}: ${color};` : null\n })\n .join(\"\\n\")}\n}\n`\n )\n .join(\"\\n\"),\n }}\n />\n )\n}\n\nconst ChartTooltip = RechartsPrimitive.Tooltip\n\nfunction ChartTooltipContent({\n active,\n payload,\n className,\n indicator = \"dot\",\n hideLabel = false,\n hideIndicator = false,\n label,\n labelFormatter,\n labelClassName,\n formatter,\n color,\n nameKey,\n labelKey,\n}: React.ComponentProps<typeof RechartsPrimitive.Tooltip> &\n React.ComponentProps<\"div\"> & {\n hideLabel?: boolean\n hideIndicator?: boolean\n indicator?: \"line\" | \"dot\" | \"dashed\"\n nameKey?: string\n labelKey?: string\n } & Omit<\n RechartsPrimitive.DefaultTooltipContentProps<\n TooltipValueType,\n TooltipNameType\n >,\n \"accessibilityLayer\"\n >) {\n const { config } = useChart()\n\n const tooltipLabel = React.useMemo(() => {\n if (hideLabel || !payload?.length) {\n return null\n }\n\n const [item] = payload\n const key = `${labelKey ?? item?.dataKey ?? item?.name ?? \"value\"}`\n const itemConfig = getPayloadConfigFromPayload(config, item, key)\n const value =\n !labelKey && typeof label === \"string\"\n ? (config[label]?.label ?? label)\n : itemConfig?.label\n\n if (labelFormatter) {\n return (\n <div className={cn(\"font-medium\", labelClassName)}>\n {labelFormatter(value, payload)}\n </div>\n )\n }\n\n if (!value) {\n return null\n }\n\n return <div className={cn(\"font-medium\", labelClassName)}>{value}</div>\n }, [\n label,\n labelFormatter,\n payload,\n hideLabel,\n labelClassName,\n config,\n labelKey,\n ])\n\n if (!active || !payload?.length) {\n return null\n }\n\n const nestLabel = payload.length === 1 && indicator !== \"dot\"\n\n return (\n <div\n className={cn(\n \"grid min-w-32 items-start gap-1.5 rounded-lg border border-border/50 bg-background px-2.5 py-1.5 text-xs shadow-xl\",\n className\n )}\n >\n {!nestLabel ? tooltipLabel : null}\n <div className=\"grid gap-1.5\">\n {payload\n .filter((item) => item.type !== \"none\")\n .map((item, index) => {\n const key = `${nameKey ?? item.name ?? item.dataKey ?? \"value\"}`\n const itemConfig = getPayloadConfigFromPayload(config, item, key)\n const indicatorColor = color ?? item.payload?.fill ?? item.color\n\n return (\n <div\n key={index}\n className={cn(\n \"flex w-full flex-wrap items-stretch gap-2 [&>svg]:h-2.5 [&>svg]:w-2.5 [&>svg]:text-muted-foreground\",\n indicator === \"dot\" && \"items-center\"\n )}\n >\n {formatter && item?.value !== undefined && item.name ? (\n formatter(item.value, item.name, item, index, item.payload)\n ) : (\n <>\n {itemConfig?.icon ? (\n <itemConfig.icon />\n ) : (\n !hideIndicator && (\n <div\n className={cn(\n \"shrink-0 rounded-[2px] border-(--color-border) bg-(--color-bg)\",\n {\n \"h-2.5 w-2.5\": indicator === \"dot\",\n \"w-1\": indicator === \"line\",\n \"w-0 border-[1.5px] border-dashed bg-transparent\":\n indicator === \"dashed\",\n \"my-0.5\": nestLabel && indicator === \"dashed\",\n }\n )}\n style={\n {\n \"--color-bg\": indicatorColor,\n \"--color-border\": indicatorColor,\n } as React.CSSProperties\n }\n />\n )\n )}\n <div\n className={cn(\n \"flex flex-1 justify-between leading-none\",\n nestLabel ? \"items-end\" : \"items-center\"\n )}\n >\n <div className=\"grid gap-1.5\">\n {nestLabel ? tooltipLabel : null}\n <span className=\"text-muted-foreground\">\n {itemConfig?.label ?? item.name}\n </span>\n </div>\n {item.value != null && (\n <span className=\"font-mono font-medium text-foreground tabular-nums\">\n {typeof item.value === \"number\"\n ? item.value.toLocaleString()\n : String(item.value)}\n </span>\n )}\n </div>\n </>\n )}\n </div>\n )\n })}\n </div>\n </div>\n )\n}\n\nconst ChartLegend = RechartsPrimitive.Legend\n\nfunction ChartLegendContent({\n className,\n hideIcon = false,\n payload,\n verticalAlign = \"bottom\",\n nameKey,\n}: React.ComponentProps<\"div\"> & {\n hideIcon?: boolean\n nameKey?: string\n} & RechartsPrimitive.DefaultLegendContentProps) {\n const { config } = useChart()\n\n if (!payload?.length) {\n return null\n }\n\n return (\n <div\n className={cn(\n \"flex items-center justify-center gap-4\",\n verticalAlign === \"top\" ? \"pb-3\" : \"pt-3\",\n className\n )}\n >\n {payload\n .filter((item) => item.type !== \"none\")\n .map((item, index) => {\n const key = `${nameKey ?? item.dataKey ?? \"value\"}`\n const itemConfig = getPayloadConfigFromPayload(config, item, key)\n\n return (\n <div\n key={index}\n className={cn(\n \"flex items-center gap-1.5 [&>svg]:h-3 [&>svg]:w-3 [&>svg]:text-muted-foreground\"\n )}\n >\n {itemConfig?.icon && !hideIcon ? (\n <itemConfig.icon />\n ) : (\n <div\n className=\"h-2 w-2 shrink-0 rounded-[2px]\"\n style={{\n backgroundColor: item.color,\n }}\n />\n )}\n {itemConfig?.label}\n </div>\n )\n })}\n </div>\n )\n}\n\nfunction getPayloadConfigFromPayload(\n config: ChartConfig,\n payload: unknown,\n key: string\n) {\n if (typeof payload !== \"object\" || payload === null) {\n return undefined\n }\n\n const payloadPayload =\n \"payload\" in payload &&\n typeof payload.payload === \"object\" &&\n payload.payload !== null\n ? payload.payload\n : undefined\n\n let configLabelKey: string = key\n\n if (\n key in payload &&\n typeof payload[key as keyof typeof payload] === \"string\"\n ) {\n configLabelKey = payload[key as keyof typeof payload] as string\n } else if (\n payloadPayload &&\n key in payloadPayload &&\n typeof payloadPayload[key as keyof typeof payloadPayload] === \"string\"\n ) {\n configLabelKey = payloadPayload[\n key as keyof typeof payloadPayload\n ] as string\n }\n\n return configLabelKey in config ? config[configLabelKey] : config[key]\n}\n\nexport {\n ChartContainer,\n ChartTooltip,\n ChartTooltipContent,\n ChartLegend,\n ChartLegendContent,\n ChartStyle,\n}\n","/**\n * Renders the structured answer of an `/api/agent` turn — the\n * `paragraph_brief | list | chart | table | callout` blocks that come\n * back over the SSE stream. Extracted from the original AskChat so both\n * the AiChat shell at /chat and the legacy renderer can share it\n * (and any visual tweak hits both pages at once).\n */\n'use client';\n\nimport { useMemo } from 'react';\nimport {\n Bar,\n BarChart,\n CartesianGrid,\n Cell,\n Label,\n Line,\n LineChart,\n Pie,\n PieChart,\n XAxis,\n YAxis\n} from 'recharts';\n\nimport { ChartCard } from './_shared/chart-card';\nimport {\n ChartContainer,\n ChartLegend,\n ChartLegendContent,\n ChartTooltip,\n ChartTooltipContent,\n type ChartConfig\n} from './_shared/chart';\nimport type { Block, ChartSpec } from '../server/tools/types';\n\nconst AI_CHART_PALETTE = [\n 'var(--chart-1)',\n 'var(--chart-2)',\n 'var(--chart-3)',\n 'var(--chart-4)',\n 'var(--chart-5)'\n];\n\nfunction aiChartConfig(keys: string[]): ChartConfig {\n const out: ChartConfig = {};\n keys.forEach((key, idx) => {\n out[key] = {\n label: key,\n color: AI_CHART_PALETTE[idx % AI_CHART_PALETTE.length]\n };\n });\n return out;\n}\n\nexport type BlockState =\n | { kind: 'paragraph_brief'; topic: string; key_facts: string[]; prose: string }\n | { kind: 'list'; style: 'bullet' | 'numbered'; items: string[]; title?: string }\n | { kind: 'chart'; title: string; spec: ChartSpec; data: Array<Record<string, unknown>> }\n | { kind: 'table'; title: string; columns: string[]; rows: unknown[][] }\n | { kind: 'callout'; tone: 'info' | 'warn' | 'success'; text: string };\n\nexport function sanitiseBlock(input: Block & { index: number }): BlockState {\n if (input.kind === 'paragraph_brief') {\n return {\n kind: 'paragraph_brief',\n topic: input.topic,\n key_facts: input.key_facts,\n prose: ''\n };\n }\n if (input.kind === 'list') {\n return { kind: 'list', style: input.style, items: input.items, title: input.title };\n }\n if (input.kind === 'chart') {\n return { kind: 'chart', title: input.title, spec: input.spec, data: input.data };\n }\n if (input.kind === 'table') {\n return {\n kind: 'table',\n title: input.title,\n columns: input.columns,\n rows: input.rows\n };\n }\n return { kind: 'callout', tone: input.tone, text: input.text };\n}\n\n/** Treat null / undefined / non-string entries as empty. Stored chats from\n * truncated reasoning-model responses can contain `null` items in\n * `key_facts` / `items`, and we don't want a defensive render to crash on\n * `null.trim()`. */\nfunction isBlankString(v: unknown): boolean {\n return typeof v !== 'string' || !v.trim();\n}\n\n/**\n * True when a block has no user-visible content. We hide these on render\n * so the model serving up an empty `callout` or `paragraph_brief` (e.g.\n * after being forced through a schema-satisfying present() call without\n * real data) doesn't paint a row of empty placeholder boxes for the\n * user. The agent loop tries to salvage these into a synthetic\n * paragraph_brief upstream — this is the defensive fallback.\n *\n * Defensive against malformed historical rows (null entries, missing\n * arrays, non-string values) — hydrating a previously-corrupted session\n * must never throw.\n */\nfunction isBlockEmpty(b: BlockState): boolean {\n if (b.kind === 'paragraph_brief') {\n if (typeof b.prose === 'string' && b.prose.trim()) return false;\n const facts = Array.isArray(b.key_facts) ? b.key_facts : [];\n return facts.length === 0 || facts.every(isBlankString);\n }\n if (b.kind === 'list') {\n const items = Array.isArray(b.items) ? b.items : [];\n return items.length === 0 || items.every(isBlankString);\n }\n if (b.kind === 'callout') return isBlankString(b.text);\n if (b.kind === 'chart') return !Array.isArray(b.data) || b.data.length === 0;\n if (b.kind === 'table') return !Array.isArray(b.rows) || b.rows.length === 0;\n return false;\n}\n\nexport function AnswerBlocks({ blocks }: { blocks: BlockState[] }) {\n const visible = blocks.filter((b) => !isBlockEmpty(b));\n return (\n <div className=\"flex flex-col gap-3\">\n {visible.map((b, i) => (\n <BlockView key={i} block={b} />\n ))}\n </div>\n );\n}\n\nfunction BlockView({ block }: { block: BlockState }) {\n if (block.kind === 'paragraph_brief') {\n return (\n <p className=\"whitespace-pre-wrap text-sm leading-6 text-foreground\">\n {block.prose || (\n <span className=\"text-muted-foreground\">{block.key_facts.join('. ')}…</span>\n )}\n </p>\n );\n }\n if (block.kind === 'list') {\n const Tag = block.style === 'numbered' ? 'ol' : 'ul';\n return (\n <div>\n {block.title && <p className=\"mb-1 text-sm font-medium\">{block.title}</p>}\n <Tag className={block.style === 'numbered' ? 'list-decimal pl-6' : 'list-disc pl-6'}>\n {block.items.map((it, i) => (\n <li key={i} className=\"text-sm leading-6\">\n {it}\n </li>\n ))}\n </Tag>\n </div>\n );\n }\n if (block.kind === 'chart') {\n return <AiChartBlock block={block} />;\n }\n if (block.kind === 'table') {\n return (\n <div className=\"overflow-x-auto rounded border border-border\">\n <p className=\"border-b border-border px-3 py-2 text-sm font-medium\">{block.title}</p>\n <table className=\"min-w-full text-sm\">\n <thead className=\"bg-muted/40\">\n <tr>\n {block.columns.map((c) => (\n <th key={c} className=\"px-3 py-2 text-left font-medium text-muted-foreground\">\n {c}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {block.rows.map((row, i) => (\n <tr key={i} className=\"border-t border-border\">\n {row.map((cell, j) => (\n <td key={j} className=\"px-3 py-2 text-foreground\">\n {cell == null ? '—' : String(cell)}\n </td>\n ))}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n }\n if (block.kind === 'callout') {\n const cls =\n block.tone === 'warn'\n ? 'border-amber-300 dark:border-amber-800 bg-amber-50 dark:bg-amber-950/30 text-amber-900 dark:text-amber-100'\n : block.tone === 'success'\n ? 'border-emerald-300 dark:border-emerald-800 bg-emerald-50 dark:bg-emerald-950/30 text-emerald-900 dark:text-emerald-100'\n : 'border-sky-300 bg-sky-50 text-sky-900';\n return <div className={`rounded border p-3 text-sm ${cls}`}>{block.text}</div>;\n }\n return null;\n}\n\nfunction AiChartBlock({ block }: { block: Extract<BlockState, { kind: 'chart' }> }) {\n const yKeys = Array.isArray(block.spec.y) ? block.spec.y : [block.spec.y];\n if (block.spec.type === 'pie') {\n return <AiPieChart block={block} valueKey={yKeys[0]} />;\n }\n if (block.spec.type === 'bar' || block.spec.type === 'stacked_bar') {\n return <AiBarChart block={block} yKeys={yKeys} stacked={block.spec.type === 'stacked_bar'} />;\n }\n return <AiLineChart block={block} yKeys={yKeys} />;\n}\n\nfunction AiPieChart({\n block,\n valueKey\n}: {\n block: Extract<BlockState, { kind: 'chart' }>;\n valueKey: string;\n}) {\n const config = useMemo(\n () => aiChartConfig(block.data.map((row) => String(row[block.spec.x] ?? ''))),\n [block.data, block.spec.x]\n );\n return (\n <ChartCard title={block.title}>\n <ChartContainer config={config} className=\"h-72 w-full\">\n <PieChart>\n <ChartTooltip content={<ChartTooltipContent hideLabel />} />\n <Pie\n data={block.data}\n dataKey={valueKey}\n nameKey={block.spec.x}\n innerRadius={60}\n strokeWidth={2}\n >\n {block.data.map((row, idx) => {\n const sliceKey = String(row[block.spec.x] ?? '');\n return <Cell key={sliceKey || idx} fill={`var(--color-${sliceKey})`} />;\n })}\n <Label\n content={({ viewBox }) => {\n if (!viewBox || !('cx' in viewBox)) return null;\n return (\n <text\n x={viewBox.cx}\n y={viewBox.cy}\n textAnchor=\"middle\"\n dominantBaseline=\"middle\"\n className=\"fill-foreground text-sm font-medium\"\n >\n {valueKey}\n </text>\n );\n }}\n />\n </Pie>\n <ChartLegend content={<ChartLegendContent nameKey={block.spec.x} />} />\n </PieChart>\n </ChartContainer>\n </ChartCard>\n );\n}\n\nfunction AiBarChart({\n block,\n yKeys,\n stacked\n}: {\n block: Extract<BlockState, { kind: 'chart' }>;\n yKeys: string[];\n stacked: boolean;\n}) {\n const config = useMemo(() => aiChartConfig(yKeys), [yKeys]);\n return (\n <ChartCard title={block.title}>\n <ChartContainer config={config} className=\"h-72 w-full\">\n <BarChart data={block.data} margin={{ left: 12, right: 12, top: 4 }}>\n <CartesianGrid vertical={false} strokeDasharray=\"3 3\" />\n <XAxis dataKey={block.spec.x} tickLine={false} axisLine={false} tickMargin={8} />\n <YAxis tickLine={false} axisLine={false} tickMargin={8} width={64} />\n <ChartTooltip content={<ChartTooltipContent />} />\n <ChartLegend content={<ChartLegendContent />} />\n {yKeys.map((k) => (\n <Bar\n key={k}\n dataKey={k}\n stackId={stacked ? 'stack' : undefined}\n fill={`var(--color-${k})`}\n radius={stacked ? [2, 2, 0, 0] : [4, 4, 0, 0]}\n />\n ))}\n </BarChart>\n </ChartContainer>\n </ChartCard>\n );\n}\n\nfunction AiLineChart({\n block,\n yKeys\n}: {\n block: Extract<BlockState, { kind: 'chart' }>;\n yKeys: string[];\n}) {\n const config = useMemo(() => aiChartConfig(yKeys), [yKeys]);\n return (\n <ChartCard title={block.title}>\n <ChartContainer config={config} className=\"h-72 w-full\">\n <LineChart data={block.data} margin={{ left: 12, right: 12, top: 4 }}>\n <CartesianGrid vertical={false} strokeDasharray=\"3 3\" />\n <XAxis dataKey={block.spec.x} tickLine={false} axisLine={false} tickMargin={8} />\n <YAxis tickLine={false} axisLine={false} tickMargin={8} width={64} />\n <ChartTooltip content={<ChartTooltipContent />} />\n <ChartLegend content={<ChartLegendContent />} />\n {yKeys.map((k) => (\n <Line\n key={k}\n type=\"monotone\"\n dataKey={k}\n stroke={`var(--color-${k})`}\n strokeWidth={2}\n dot={false}\n activeDot={{ r: 4 }}\n />\n ))}\n </LineChart>\n </ChartContainer>\n </ChartCard>\n );\n}\n","/**\n * AiChat — the shared chat shell rendered both at /chat (head\n * pastors / any authed user) and at /admin/ai (super_admin admin\n * surface). One component, one set of pixels: tweaks here propagate to\n * both pages.\n *\n * Layout:\n * ┌── collapsible session sidebar (chat history) ──┬── chat panel ──┐\n * │ + New chat │ empty hero │\n * │ • session 1 │ ─ or ─ │\n * │ • session 2 │ message list │\n * │ • … │ │\n * └────────────────────────────────────────────────┴── input pill ──┘\n *\n * Streaming protocol matches `app/api/agent/route.ts`: `meta`, `block`,\n * `prose`, `error`, `done` SSE frames. Sessions are persisted via\n * `/api/chat/sessions/*`; the agent route writes both the user turn\n * (on POST) and the assistant turn (when it finishes) when the client\n * passes `chatSessionId`.\n */\n'use client';\n\nimport {\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState\n} from 'react';\nimport { useRouter } from 'next/navigation';\nimport Link from 'next/link';\nimport {\n ArrowUp,\n Check,\n ChevronDown,\n ChevronUp,\n Copy,\n Loader2,\n Menu,\n PanelLeftClose,\n Pencil,\n Plus,\n RotateCcw,\n Sparkles,\n Trash2\n} from 'lucide-react';\n\nimport { cn } from './_shared/cn';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger\n} from './_shared/dropdown-menu';\nimport { SidebarTitleEditor, EditableTitle } from './_shared/title-editors';\nimport {\n AnswerBlocks,\n sanitiseBlock,\n type BlockState\n} from './answer-blocks';\nimport type { Block } from '../server/tools/types';\n\ntype NarrativeProvider = 'claude' | 'grok' | 'gemini';\n\ntype AnswerState = {\n question: string;\n blocks: BlockState[];\n done: boolean;\n error?: { code: string; message: string };\n /** ms timestamp when the question was submitted; missing for restored history. */\n startedAt?: number;\n /** Wall-clock ms it took for the agent to mark `done`. Set in the same update that flips `done: true`. Missing for restored history. */\n durationMs?: number;\n};\n\n/** Short human-readable duration: 5s, 45s, 1m, 1m 30s, 12m 5s. */\nfunction formatDuration(ms: number): string {\n if (ms < 0) ms = 0;\n const totalSec = Math.round(ms / 1000);\n if (totalSec < 60) return `${totalSec}s`;\n const m = Math.floor(totalSec / 60);\n const s = totalSec % 60;\n return s === 0 ? `${m}m` : `${m}m ${s}s`;\n}\n\nexport type AiChatSessionSummary = {\n id: string;\n title: string;\n updatedAt: string | null;\n};\n\ntype StoredMessage = {\n id: string;\n role: 'user' | 'assistant';\n question: string | null;\n blocks: Block[] | null;\n prose: Record<string, string> | null;\n errorJson: { code: string; message: string } | null;\n};\n\nexport type AiChatProps = {\n userFirstName: string;\n /** Data scope label shown as a chip beneath the input (eg. \"All countries\"). */\n scopeLabel: string;\n /** User's stored narrative provider, surfaced as the model picker default. */\n initialProvider: NarrativeProvider;\n /**\n * Session to open on mount. The host resolves this from the URL\n * (`/chat/[id]`) so reload/bookmark/multi-tab restore the exact\n * conversation. `null` (or omitted) renders the empty new-chat state.\n */\n initialSessionId?: string | null;\n /**\n * URL prefix the chat is mounted at. Sidebar `<Link>`s and router\n * pushes use this prefix so multiple chat surfaces (e.g. `/chat` and\n * `/admin/ai`) can coexist without yanking users between shells.\n * Defaults to `/chat`.\n */\n basePath?: string;\n};\n\nconst PROVIDER_LABELS: Record<NarrativeProvider, string> = {\n claude: 'Claude',\n grok: 'Grok',\n gemini: 'Gemini'\n};\n\n// Auto-grow cap. The textarea is `leading-6` (24px) with `py-1`\n// (4px top + 4px bottom). 7 visible lines = 7×24 + 8 = 176px; past\n// that, vertical scrolling kicks in inside the textarea.\nconst TEXTAREA_MAX_PX = 176;\n\nconst PROVIDER_DESCRIPTIONS: Record<NarrativeProvider, string> = {\n claude: 'Anthropic Claude on Vertex AI',\n grok: 'xAI Grok on Vertex AI',\n gemini: 'Google Gemini on Vertex AI'\n};\n\nexport function AiChat({\n userFirstName,\n scopeLabel,\n initialProvider,\n initialSessionId = null,\n basePath = '/chat'\n}: AiChatProps) {\n const router = useRouter();\n const [sessions, setSessions] = useState<AiChatSessionSummary[]>([]);\n const [activeSessionId, setActiveSessionId] = useState<string | null>(\n initialSessionId\n );\n const [answers, setAnswers] = useState<AnswerState[]>([]);\n const [pending, setPending] = useState(false);\n const [question, setQuestion] = useState('');\n // Sidebar overlays the chat panel rather than pushing it sideways, so\n // it starts closed; the hamburger in the chat header opens it.\n const [sidebarOpen, setSidebarOpen] = useState(false);\n const [loadingSession, setLoadingSession] = useState(false);\n const [provider, setProvider] = useState<NarrativeProvider>(initialProvider);\n const [providerSaving, setProviderSaving] = useState(false);\n // When non-null, the sidebar row for this session is in inline-edit\n // mode and renders an <input> instead of the static title button.\n const [editingSidebarId, setEditingSidebarId] = useState<string | null>(null);\n const abortRef = useRef<AbortController | null>(null);\n const threadRef = useRef<HTMLDivElement | null>(null);\n const textareaRef = useRef<HTMLTextAreaElement | null>(null);\n // Ref to the most recently submitted answer's container. We snap it\n // to the top of the thread on submit so the AI response gets a fresh\n // viewport below the question, mirroring Claude/ChatGPT.\n const lastAnswerRef = useRef<HTMLDivElement | null>(null);\n const prevAnswersLen = useRef(0);\n\n // Auto-grow the textarea up to TEXTAREA_MAX_LINES (≈7 lines), then\n // start scrolling internally. We measure with scrollHeight after\n // resetting height to 0, mirroring the standard auto-grow pattern.\n useLayoutEffect(() => {\n const el = textareaRef.current;\n if (!el) return;\n el.style.height = '0px';\n const next = Math.min(el.scrollHeight, TEXTAREA_MAX_PX);\n el.style.height = `${next}px`;\n }, [question]);\n\n // Initial session list load (independent of which session is active —\n // the URL is now the source of truth for that, so we just hydrate the\n // sidebar here).\n useEffect(() => {\n let cancelled = false;\n async function load() {\n try {\n const res = await fetch('/api/chat/sessions', { cache: 'no-store' });\n if (!res.ok) return;\n const data = (await res.json()) as { sessions: AiChatSessionSummary[] };\n if (cancelled) return;\n setSessions(data.sessions ?? []);\n } catch {\n // network blip — sidebar will just be empty until next nav.\n }\n }\n void load();\n return () => {\n cancelled = true;\n };\n }, []);\n\n // Hydrate the active session's messages on first mount when the host\n // routed us to /chat/[id]. The URL is authoritative, so we treat\n // `initialSessionId` as the only signal — never auto-open a different\n // session. We deliberately depend only on `initialSessionId` so that\n // navigating between /chat/[a] and /chat/[b] (which remounts the page\n // with a new prop) reloads the right thread.\n useEffect(() => {\n if (initialSessionId == null) {\n setAnswers([]);\n return;\n }\n let cancelled = false;\n async function load(id: string) {\n setLoadingSession(true);\n try {\n const res = await fetch(`/api/chat/sessions/${id}`, { cache: 'no-store' });\n if (cancelled) return;\n if (!res.ok) {\n setAnswers([]);\n return;\n }\n const data = (await res.json()) as { messages: StoredMessage[] };\n if (cancelled) return;\n setAnswers(messagesToAnswers(data.messages ?? []));\n } catch {\n if (!cancelled) setAnswers([]);\n } finally {\n if (!cancelled) setLoadingSession(false);\n }\n }\n void load(initialSessionId);\n return () => {\n cancelled = true;\n };\n }, [initialSessionId]);\n\n // Snap the newly submitted question to the top of the thread when a\n // new answer is appended. We deliberately do NOT auto-scroll on\n // every prose/block update — the user's reading flow stays put as\n // the response streams below the pinned question, and they can\n // scroll up to revisit prior turns. Mirrors Claude / ChatGPT.\n useEffect(() => {\n if (answers.length > prevAnswersLen.current && lastAnswerRef.current) {\n lastAnswerRef.current.scrollIntoView({ behavior: 'smooth', block: 'start' });\n }\n prevAnswersLen.current = answers.length;\n }, [answers.length]);\n\n const refreshSessions = useCallback(async () => {\n try {\n const res = await fetch('/api/chat/sessions', { cache: 'no-store' });\n if (!res.ok) return;\n const data = (await res.json()) as { sessions: AiChatSessionSummary[] };\n setSessions(data.sessions ?? []);\n } catch {\n /* noop */\n }\n }, []);\n\n // Push `${basePath}/<id>` (or `${basePath}`) so reload, bookmarks, and\n // multi-tab restore the exact session the user is viewing. Wrapped so\n // every code path that mutates `activeSessionId` syncs the URL.\n const syncUrl = useCallback(\n (id: string | null) => {\n router.push(id == null ? basePath : `${basePath}/${id}`);\n },\n [router, basePath]\n );\n\n // \"+ New chat\" navigates to ${basePath}?new — the host's basePath\n // route is expected to redirect to the most-recent session by default,\n // and the `?new` hint suppresses that so the user lands on the empty\n // hero. Without this escape hatch, clicking \"+ New chat\" would bounce\n // back to the session you were trying to leave.\n const newChat = useCallback(() => {\n setActiveSessionId(null);\n setAnswers([]);\n setQuestion('');\n router.push(`${basePath}?new`);\n }, [router, basePath]);\n\n const changeProvider = useCallback(\n async (next: NarrativeProvider) => {\n if (next === provider || providerSaving) return;\n setProvider(next);\n setProviderSaving(true);\n try {\n const res = await fetch('/api/settings/me', {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ narrative_provider: next })\n });\n if (!res.ok) {\n // Roll back the optimistic update on failure.\n setProvider((curr) => (curr === next ? provider : curr));\n }\n } catch {\n setProvider((curr) => (curr === next ? provider : curr));\n } finally {\n setProviderSaving(false);\n }\n },\n [provider, providerSaving]\n );\n\n const openSession = useCallback(\n async (id: string) => {\n setLoadingSession(true);\n setActiveSessionId(id);\n syncUrl(id);\n try {\n const res = await fetch(`/api/chat/sessions/${id}`, { cache: 'no-store' });\n if (!res.ok) {\n setAnswers([]);\n return;\n }\n const data = (await res.json()) as { messages: StoredMessage[] };\n setAnswers(messagesToAnswers(data.messages ?? []));\n } catch {\n setAnswers([]);\n } finally {\n setLoadingSession(false);\n }\n },\n [syncUrl]\n );\n\n const persistTitle = useCallback(\n async (id: string, title: string) => {\n const trimmed = title.trim();\n if (!trimmed) return;\n const res = await fetch(`/api/chat/sessions/${id}`, {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ title: trimmed })\n });\n if (res.ok) {\n setSessions((prev) =>\n prev.map((s) => (s.id === id ? { ...s, title: trimmed } : s))\n );\n }\n },\n []\n );\n\n const startSidebarRename = useCallback((id: string) => {\n setEditingSidebarId(id);\n }, []);\n\n const deleteSession = useCallback(\n async (id: string) => {\n if (!window.confirm('Delete this chat? This cannot be undone.')) return;\n const res = await fetch(`/api/chat/sessions/${id}`, { method: 'DELETE' });\n if (!res.ok) return;\n setSessions((prev) => prev.filter((s) => s.id !== id));\n if (activeSessionId === id) {\n setActiveSessionId(null);\n setAnswers([]);\n syncUrl(null);\n }\n },\n [activeSessionId, syncUrl]\n );\n\n const submit = useCallback(\n async (q: string) => {\n const trimmed = q.trim();\n if (!trimmed || pending) return;\n setPending(true);\n setQuestion('');\n\n // Lazily create a session on first submit so empty \"New chat\" rows\n // don't litter the sidebar.\n let sessionId = activeSessionId;\n if (sessionId == null) {\n try {\n const create = await fetch('/api/chat/sessions', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({})\n });\n if (create.ok) {\n const data = (await create.json()) as {\n session: AiChatSessionSummary;\n };\n sessionId = data.session.id;\n setActiveSessionId(sessionId);\n // Pin the URL to the new session so reload restores this thread.\n // Use `window.history.replaceState` (shallow URL update) rather\n // than `router.push` here: a Next.js navigation would unmount\n // this component mid-streaming, dropping the in-flight SSE\n // connection on the floor — the next mount would then\n // re-hydrate from the API before the assistant message\n // finishes persisting, and the user would see an empty thread\n // on reload. ReplaceState updates the address bar without\n // tearing the component down.\n if (typeof window !== 'undefined') {\n window.history.replaceState(null, '', `${basePath}/${sessionId}`);\n }\n setSessions((prev) => [\n { id: data.session.id, title: data.session.title, updatedAt: null },\n ...prev\n ]);\n }\n } catch {\n // Session create failed — proceed without persistence.\n }\n }\n\n setAnswers((prev) => [\n ...prev,\n { question: trimmed, blocks: [], done: false, startedAt: Date.now() }\n ]);\n\n const ac = new AbortController();\n abortRef.current = ac;\n let res: Response;\n try {\n res = await fetch('/api/agent', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n question: trimmed,\n chatSessionId: sessionId\n }),\n signal: ac.signal\n });\n } catch (e) {\n const message = (e as Error).message ?? 'Request failed';\n setAnswers((prev) =>\n updateLast(prev, (a) => ({\n ...a,\n done: true,\n durationMs: a.startedAt != null ? Date.now() - a.startedAt : undefined,\n error: { code: 'NETWORK', message }\n }))\n );\n setPending(false);\n return;\n }\n if (!res.body) {\n setAnswers((prev) =>\n updateLast(prev, (a) => ({\n ...a,\n done: true,\n durationMs: a.startedAt != null ? Date.now() - a.startedAt : undefined,\n error: { code: 'NO_BODY', message: 'No response stream.' }\n }))\n );\n setPending(false);\n return;\n }\n\n const reader = res.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n try {\n while (true) {\n const { value, done } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n const events = buffer.split('\\n\\n');\n buffer = events.pop() ?? '';\n for (const raw of events) {\n // Defensive backstop: if the server's `meta` event arrives\n // (it always does, as the first SSE frame), make sure the\n // client's activeSessionId / URL match the persistent\n // chatSessionId the route resolved. Covers the edge case\n // where lazy-create-on-submit POST'd successfully but the\n // client's local state got out of sync, or where a route\n // hook generated the session without us going through the\n // lazy-create path.\n const meta = parseMetaChatSessionId(raw);\n if (meta != null) {\n setActiveSessionId((prev) => prev ?? meta);\n if (\n typeof window !== 'undefined' &&\n !window.location.pathname.endsWith(`/${meta}`)\n ) {\n window.history.replaceState(\n null,\n '',\n `${basePath}/${meta}`\n );\n }\n }\n handleEvent(raw, setAnswers);\n }\n }\n } catch (e) {\n const message = (e as Error).message ?? 'Stream interrupted';\n setAnswers((prev) =>\n updateLast(prev, (a) => ({\n ...a,\n done: true,\n durationMs: a.startedAt != null ? Date.now() - a.startedAt : undefined,\n error: { code: 'STREAM', message }\n }))\n );\n } finally {\n setPending(false);\n abortRef.current = null;\n // Persisted title may have been auto-generated on the server —\n // refresh sidebar so the new label appears.\n void refreshSessions();\n }\n },\n [activeSessionId, pending, refreshSessions, syncUrl]\n );\n\n const heroVisible = answers.length === 0 && !loadingSession;\n const greeting = useMemo(\n () =>\n `Hi ${userFirstName || 'there'}${\n userFirstName.endsWith('s') ? '' : ''\n },`,\n [userFirstName]\n );\n\n const activeTitle = activeSessionId\n ? sessions.find((s) => s.id === activeSessionId)?.title ?? 'Chat'\n : 'New chat';\n\n return (\n <div className=\"relative flex h-full min-h-0 w-full overflow-hidden rounded-lg border border-border bg-background\">\n {/* Backdrop: click to close. Pointer-events only when open so the\n chat panel underneath stays interactive when the sidebar is\n closed. */}\n <div\n onClick={() => setSidebarOpen(false)}\n aria-hidden=\"true\"\n className={cn(\n 'absolute inset-0 z-10 bg-background/60 backdrop-blur-sm transition-opacity duration-200',\n sidebarOpen\n ? 'opacity-100'\n : 'pointer-events-none opacity-0'\n )}\n />\n\n {/* Overlay session sidebar — slides in from the left, never\n shrinks the chat panel. z-20 so it sits above the backdrop. */}\n <aside\n inert={!sidebarOpen}\n className={cn(\n 'absolute inset-y-0 left-0 z-20 flex w-72 max-w-[85vw] flex-col border-r border-border bg-sidebar text-sidebar-foreground shadow-lg transition-transform duration-200 ease-out',\n sidebarOpen ? 'translate-x-0' : '-translate-x-full'\n )}\n >\n <div className=\"flex items-center gap-2 border-b border-sidebar-border p-2\">\n <button\n type=\"button\"\n onClick={() => setSidebarOpen(false)}\n className=\"inline-flex size-8 items-center justify-center rounded-md text-sidebar-foreground/70 hover:bg-sidebar-accent hover:text-sidebar-foreground\"\n aria-label=\"Close sidebar\"\n >\n <PanelLeftClose className=\"size-4\" />\n </button>\n <button\n type=\"button\"\n onClick={() => {\n newChat();\n setSidebarOpen(false);\n }}\n className=\"ml-auto inline-flex items-center gap-1.5 rounded-full border border-sidebar-border bg-sidebar-accent px-3 py-1.5 text-xs font-medium text-sidebar-accent-foreground hover:bg-sidebar-accent/80\"\n >\n <Plus className=\"size-3.5\" />\n New chat\n </button>\n </div>\n <div className=\"flex-1 overflow-y-auto p-2\">\n {sessions.length === 0 ? (\n <p className=\"px-2 py-3 text-xs text-sidebar-foreground/60\">\n No chats yet. Ask something below to start.\n </p>\n ) : (\n <ul className=\"flex flex-col gap-0.5\">\n {sessions.map((s) => {\n const active = s.id === activeSessionId;\n const editing = s.id === editingSidebarId;\n if (editing) {\n return (\n <li key={s.id} className=\"px-1 py-1\">\n <SidebarTitleEditor\n initial={s.title}\n onCancel={() => setEditingSidebarId(null)}\n onSave={(next) => {\n setEditingSidebarId(null);\n void persistTitle(s.id, next);\n }}\n />\n </li>\n );\n }\n return (\n <li key={s.id} className=\"group relative\">\n <Link\n href={`${basePath}/${s.id}`}\n onClick={() => setSidebarOpen(false)}\n className={cn(\n 'flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm',\n active\n ? 'bg-sidebar-accent text-sidebar-accent-foreground'\n : 'text-sidebar-foreground/80 hover:bg-sidebar-accent/60 hover:text-sidebar-foreground'\n )}\n title={s.title}\n >\n <span className=\"truncate\">{s.title}</span>\n </Link>\n <div className=\"absolute right-1 top-1/2 hidden -translate-y-1/2 items-center gap-0.5 group-hover:flex\">\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n startSidebarRename(s.id);\n }}\n aria-label=\"Rename\"\n className=\"inline-flex size-6 items-center justify-center rounded text-sidebar-foreground/60 hover:bg-sidebar hover:text-sidebar-foreground\"\n >\n <Pencil className=\"size-3\" />\n </button>\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n void deleteSession(s.id);\n }}\n aria-label=\"Delete\"\n className=\"inline-flex size-6 items-center justify-center rounded text-sidebar-foreground/60 hover:bg-sidebar hover:text-destructive\"\n >\n <Trash2 className=\"size-3\" />\n </button>\n </div>\n </li>\n );\n })}\n </ul>\n )}\n </div>\n </aside>\n\n <section className=\"relative flex flex-1 flex-col overflow-hidden\">\n <header className=\"flex items-center gap-2 px-3 py-3 text-sm text-muted-foreground\">\n <button\n type=\"button\"\n onClick={() => setSidebarOpen(true)}\n aria-label=\"Open chat history\"\n className=\"inline-flex size-8 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground\"\n >\n <Menu className=\"size-4\" />\n </button>\n <Sparkles className=\"size-4 text-primary\" />\n {activeSessionId != null ? (\n <EditableTitle\n key={activeSessionId}\n title={activeTitle}\n onSave={(next) => void persistTitle(activeSessionId, next)}\n />\n ) : (\n <span className=\"truncate\">{activeTitle}</span>\n )}\n </header>\n\n <div\n ref={threadRef}\n className=\"min-h-0 flex-1 overflow-y-auto px-4 pb-6 pt-2\"\n >\n {loadingSession ? (\n <div className=\"flex h-full items-center justify-center text-sm text-muted-foreground\">\n <Loader2 className=\"mr-2 size-4 animate-spin\" /> Loading conversation…\n </div>\n ) : heroVisible ? (\n <div className=\"flex h-full flex-col items-center justify-center text-center\">\n <h1 className=\"text-2xl font-medium tracking-tight text-foreground sm:text-3xl\">\n {greeting}\n </h1>\n <p className=\"mt-2 text-2xl font-light tracking-tight text-muted-foreground sm:text-3xl\">\n What's on your mind?\n </p>\n </div>\n ) : (\n <div className=\"mx-auto flex w-full max-w-3xl flex-col gap-6\">\n {answers.map((a, idx) => (\n <AnswerView\n key={idx}\n answer={a}\n onRetry={() => void submit(a.question)}\n forwardRef={idx === answers.length - 1 ? lastAnswerRef : undefined}\n // The last turn reserves enough viewport so the AI\n // response has room to stream below the question\n // without the user needing to scroll. Calc subtracts\n // the input-pill area (~14rem) and a comfort buffer.\n isLast={idx === answers.length - 1}\n />\n ))}\n </div>\n )}\n </div>\n\n <div className=\"shrink-0 px-4 pb-4 pt-2\">\n <form\n className=\"mx-auto w-full max-w-3xl\"\n onSubmit={(e) => {\n e.preventDefault();\n void submit(question);\n }}\n >\n <div className=\"flex flex-col gap-2 rounded-3xl border border-border bg-background px-4 py-3 shadow-sm\">\n <textarea\n ref={textareaRef}\n value={question}\n onChange={(e) => setQuestion(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n void submit(question);\n }\n }}\n placeholder=\"Ask AI...\"\n rows={1}\n disabled={pending}\n style={{ maxHeight: TEXTAREA_MAX_PX }}\n className=\"w-full resize-none overflow-y-auto border-0 bg-transparent py-1 text-sm leading-6 text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-0 disabled:opacity-60\"\n />\n <div className=\"flex items-center justify-between gap-2\">\n <span\n className=\"inline-flex max-w-[60%] items-center gap-1.5 truncate rounded-full border border-border bg-muted/40 px-2.5 py-1 text-xs font-medium text-muted-foreground\"\n title={`Scope: ${scopeLabel}`}\n >\n Scope: <span className=\"truncate text-foreground\">{scopeLabel}</span>\n </span>\n <div className=\"flex items-center gap-2\">\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n className=\"inline-flex items-center gap-1 rounded-full px-2.5 py-1 text-xs font-medium text-muted-foreground hover:bg-accent hover:text-foreground\"\n aria-label=\"Choose model\"\n >\n {PROVIDER_LABELS[provider]}\n <ChevronDown className=\"size-3.5\" />\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-56\">\n {(['claude', 'grok', 'gemini'] as const).map((p) => (\n <DropdownMenuItem\n key={p}\n onSelect={() => void changeProvider(p)}\n className=\"flex items-start gap-2\"\n >\n <Check\n className={cn(\n 'mt-0.5 size-4',\n provider === p ? 'opacity-100' : 'opacity-0'\n )}\n />\n <div className=\"flex flex-col\">\n <span className=\"text-sm font-medium\">\n {PROVIDER_LABELS[p]}\n </span>\n <span className=\"text-xs text-muted-foreground\">\n {PROVIDER_DESCRIPTIONS[p]}\n </span>\n </div>\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n <button\n type=\"submit\"\n disabled={pending || !question.trim()}\n aria-label=\"Send\"\n className=\"inline-flex size-8 shrink-0 items-center justify-center rounded-full bg-primary text-primary-foreground transition-colors enabled:hover:bg-primary/90 disabled:opacity-40\"\n >\n {pending ? (\n <Loader2 className=\"size-4 animate-spin\" />\n ) : (\n <ArrowUp className=\"size-4\" />\n )}\n </button>\n </div>\n </div>\n </div>\n <p className=\"mt-2 text-center text-xs text-muted-foreground\">\n {PROVIDER_LABELS[provider]} is AI and can make mistakes.\n </p>\n </form>\n </div>\n </section>\n </div>\n );\n}\n\nfunction AnswerView({\n answer,\n onRetry,\n forwardRef,\n isLast\n}: {\n answer: AnswerState;\n onRetry: () => void;\n /** Attached to the outer container so the parent can scroll the latest turn into view on submit. */\n forwardRef?: React.RefObject<HTMLDivElement | null>;\n /**\n * The last turn reserves enough viewport that the AI response has\n * room to grow under the pinned question. The parent flex column\n * uses `min-h-[...]` here so a short answer doesn't leave a\n * ridiculous gap, but a long-running response can stream below\n * without the user being autoscrolled.\n */\n isLast?: boolean;\n}) {\n const [copied, setCopied] = useState(false);\n\n const handleCopy = useCallback(async () => {\n // Prefer the structured response; fall back to the error envelope\n // when the turn produced no blocks so the user can still copy the\n // failure (eg. quota error message → paste into an issue).\n const blockText = blocksToPlainText(answer.blocks);\n const text =\n blockText ||\n (answer.error\n ? `${answer.error.code}: ${answer.error.message}`\n : '');\n if (!text) return;\n try {\n await navigator.clipboard.writeText(text);\n setCopied(true);\n window.setTimeout(() => setCopied(false), 1500);\n } catch {\n // Clipboard blocked (insecure context, permission denied) — silent.\n }\n }, [answer.blocks, answer.error]);\n\n const showActions =\n answer.done && (answer.blocks.length > 0 || answer.error != null);\n // While the agent is still computing the first block, drop the\n // nested-column layout entirely and render a single flex row. The\n // normal layout has an empty `AnswerBlocks` wrapper that contributes\n // a 12px flex-gap to the column even when it has no blocks, which\n // throws `items-center` off so the icon and \"Thinking…\" don't align.\n const isThinking =\n !answer.done && answer.blocks.length === 0 && !answer.error;\n\n // Live ticker — re-renders once a second while the agent is thinking\n // so the inline \"(5s)\" counter advances. We force a re-render via a\n // dummy state instead of recomputing elapsed in a useEffect because\n // the elapsed value is derived from `answer.startedAt` (a prop) and\n // `Date.now()` — anything stored in state would just duplicate that.\n const [, forceTick] = useState(0);\n useEffect(() => {\n if (answer.done || answer.startedAt == null) return;\n const id = window.setInterval(() => forceTick((n) => n + 1), 1000);\n return () => window.clearInterval(id);\n }, [answer.done, answer.startedAt]);\n\n // Live elapsed for the thinking state; final stamped duration once done.\n const liveElapsed =\n answer.startedAt != null ? Date.now() - answer.startedAt : null;\n const finalDuration = answer.durationMs;\n\n return (\n <div\n ref={forwardRef}\n // scroll-mt nudges scrollIntoView so the question doesn't kiss\n // the very top of the thread container.\n className={cn(\n 'flex flex-col gap-4 scroll-mt-2',\n // Reserve space below the latest turn so the AI response has a\n // full screen to fill without bouncing the user. Calc subtracts\n // the chat header (~3rem) and the input pill area (~10rem) from\n // the dynamic viewport height.\n isLast && 'min-h-[calc(100dvh-13rem)]'\n )}\n >\n <div className=\"flex justify-end\">\n <UserChip text={answer.question} />\n </div>\n {isThinking ? (\n <div className=\"flex items-center gap-3\">\n <div className=\"flex size-7 shrink-0 items-center justify-center rounded-full bg-primary/10 text-primary\">\n <Sparkles className=\"size-4\" />\n </div>\n <p className=\"flex items-center text-sm text-muted-foreground\">\n <Loader2 className=\"mr-1 inline size-3.5 animate-spin\" />\n Thinking…\n {liveElapsed != null && liveElapsed >= 1000 && (\n <span className=\"ml-2 text-xs tabular-nums\">\n ({formatDuration(liveElapsed)})\n </span>\n )}\n </p>\n </div>\n ) : (\n <div className=\"flex items-start gap-3\">\n <div className=\"mt-0.5 flex size-7 shrink-0 items-center justify-center rounded-full bg-primary/10 text-primary\">\n <Sparkles className=\"size-4\" />\n </div>\n <div className=\"flex min-w-0 flex-1 flex-col gap-3\">\n <AnswerBlocks blocks={answer.blocks} />\n {answer.error && (\n <div className=\"wrap-break-word whitespace-pre-wrap rounded border border-amber-300 bg-amber-50 p-3 text-sm text-amber-900 dark:border-amber-800 dark:bg-amber-950/30 dark:text-amber-100\">\n {answer.error.code}: {answer.error.message}\n </div>\n )}\n {showActions && (\n <div className=\"flex items-center gap-1\">\n {(answer.blocks.length > 0 || answer.error != null) && (\n <button\n type=\"button\"\n onClick={handleCopy}\n aria-label={\n answer.blocks.length === 0 && answer.error\n ? 'Copy error'\n : 'Copy response'\n }\n title={copied ? 'Copied' : 'Copy'}\n className=\"inline-flex size-8 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground\"\n >\n {copied ? (\n <Check className=\"size-4\" />\n ) : (\n <Copy className=\"size-4\" />\n )}\n </button>\n )}\n <button\n type=\"button\"\n onClick={onRetry}\n aria-label=\"Retry\"\n title=\"Retry\"\n className=\"inline-flex size-8 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground\"\n >\n <RotateCcw className=\"size-4\" />\n </button>\n {finalDuration != null && finalDuration >= 1000 && (\n <span\n className=\"ml-1 text-xs text-muted-foreground tabular-nums\"\n title=\"Time taken to generate this response\"\n >\n {formatDuration(finalDuration)}\n </span>\n )}\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n );\n}\n\n/**\n * Flatten an assistant turn's blocks into plain text for the clipboard\n * — paragraph prose, list items, callouts, and a tab-separated table\n * dump. Charts are referenced by title since the visual is what\n * matters there.\n */\nfunction blocksToPlainText(blocks: BlockState[]): string {\n return blocks\n .map((b) => {\n if (b.kind === 'paragraph_brief') {\n return b.prose || b.key_facts.join('. ');\n }\n if (b.kind === 'list') {\n const lines = b.items.map((it, i) =>\n b.style === 'numbered' ? `${i + 1}. ${it}` : `- ${it}`\n );\n return [b.title, ...lines].filter(Boolean).join('\\n');\n }\n if (b.kind === 'chart') {\n return `${b.title} (chart)`;\n }\n if (b.kind === 'table') {\n const header = b.columns.join('\\t');\n const rows = b.rows.map((r) =>\n r.map((c) => (c == null ? '—' : String(c))).join('\\t')\n );\n return [b.title, header, ...rows].join('\\n');\n }\n if (b.kind === 'callout') return b.text;\n return '';\n })\n .filter(Boolean)\n .join('\\n\\n');\n}\n\n/**\n * User-message bubble. Wraps long content (including unspaced strings\n * via `wrap-break-word`); when collapsed it caps at 3 lines and fades\n * the last line into the bubble background instead of using a hard\n * ellipsis. A chevron + \"Show more / Show less\" toggle reveals only\n * when the cap actually truncates content.\n */\nfunction UserChip({ text }: { text: string }) {\n const [expanded, setExpanded] = useState(false);\n const [overflowing, setOverflowing] = useState(false);\n const ref = useRef<HTMLDivElement | null>(null);\n\n useLayoutEffect(() => {\n const el = ref.current;\n if (!el || expanded) return;\n setOverflowing(el.scrollHeight > el.clientHeight + 1);\n }, [text, expanded]);\n\n return (\n <div className=\"max-w-[85%] rounded-2xl bg-muted px-4 py-2 text-sm text-foreground\">\n <div className=\"relative\">\n <div\n ref={ref}\n className={cn(\n 'whitespace-pre-wrap wrap-break-word leading-6',\n // 3 lines × leading-6 (24px) = 72px → max-h-18.\n !expanded && 'max-h-18 overflow-hidden'\n )}\n >\n {text}\n </div>\n {!expanded && overflowing && (\n <div\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-x-0 bottom-0 h-6 bg-linear-to-t from-muted to-transparent\"\n />\n )}\n </div>\n {(overflowing || expanded) && (\n <button\n type=\"button\"\n onClick={() => setExpanded((v) => !v)}\n className=\"mt-1 inline-flex items-center gap-1 text-xs font-medium text-muted-foreground hover:text-foreground\"\n >\n {expanded ? (\n <>\n <ChevronUp className=\"size-3.5\" />\n Show less\n </>\n ) : (\n <>\n <ChevronDown className=\"size-3.5\" />\n Show more\n </>\n )}\n </button>\n )}\n </div>\n );\n}\n\n/**\n * Pull `chatSessionId` out of a `meta` SSE frame. The server emits\n * `event: meta\\ndata: {\"chatSessionId\":\"...\",\"scopeLabel\":\"...\"}`\n * as the very first frame of the stream. Returns `null` for any other\n * event type so the caller can stay in the hot path.\n */\nfunction parseMetaChatSessionId(raw: string): string | null {\n const lines = raw.split('\\n');\n let event = '';\n let dataStr = '';\n for (const line of lines) {\n if (line.startsWith('event: ')) event = line.slice(7).trim();\n else if (line.startsWith('data: ')) dataStr += line.slice(6);\n }\n if (event !== 'meta') return null;\n try {\n const parsed = JSON.parse(dataStr || '{}') as {\n chatSessionId?: unknown;\n };\n return typeof parsed.chatSessionId === 'string' &&\n parsed.chatSessionId.length > 0\n ? parsed.chatSessionId\n : null;\n } catch {\n return null;\n }\n}\n\nfunction handleEvent(\n raw: string,\n setAnswers: React.Dispatch<React.SetStateAction<AnswerState[]>>\n): void {\n const lines = raw.split('\\n');\n let event = '';\n let dataStr = '';\n for (const line of lines) {\n if (line.startsWith('event: ')) event = line.slice(7).trim();\n else if (line.startsWith('data: ')) dataStr += line.slice(6);\n }\n if (!event) return;\n let data: unknown = {};\n try {\n data = JSON.parse(dataStr || '{}');\n } catch {\n return;\n }\n\n if (event === 'block') {\n const blockData = data as Block & { index: number };\n const block = sanitiseBlock(blockData);\n setAnswers((prev) =>\n updateLast(prev, (a) => {\n const blocks = [...a.blocks];\n blocks[blockData.index] = block;\n return { ...a, blocks };\n })\n );\n } else if (event === 'prose') {\n const { block_index, delta } = data as { block_index: number; delta: string };\n setAnswers((prev) =>\n updateLast(prev, (a) => {\n const blocks = [...a.blocks];\n const target = blocks[block_index];\n if (target && target.kind === 'paragraph_brief') {\n blocks[block_index] = { ...target, prose: target.prose + delta };\n }\n return { ...a, blocks };\n })\n );\n } else if (event === 'done') {\n setAnswers((prev) =>\n updateLast(prev, (a) => ({\n ...a,\n done: true,\n durationMs: a.startedAt != null ? Date.now() - a.startedAt : undefined\n }))\n );\n } else if (event === 'error') {\n setAnswers((prev) =>\n updateLast(prev, (a) => ({\n ...a,\n error: data as { code: string; message: string }\n }))\n );\n }\n}\n\nfunction updateLast(\n prev: AnswerState[],\n updater: (a: AnswerState) => AnswerState\n): AnswerState[] {\n if (prev.length === 0) return prev;\n const next = [...prev];\n next[next.length - 1] = updater(next[next.length - 1]);\n return next;\n}\n\nfunction messagesToAnswers(messages: StoredMessage[]): AnswerState[] {\n // Stored messages alternate user → assistant. Pair them into AnswerState.\n const out: AnswerState[] = [];\n let pendingUser: string | null = null;\n for (const m of messages) {\n if (m.role === 'user') {\n pendingUser = m.question ?? '';\n } else if (m.role === 'assistant') {\n const question = pendingUser ?? '';\n pendingUser = null;\n const blocks: BlockState[] = [];\n const stored = (m.blocks ?? []) as Block[];\n stored.forEach((b, i) => {\n const sanitised = sanitiseBlock({ ...(b as Block), index: i } as Block & {\n index: number;\n });\n if (sanitised.kind === 'paragraph_brief') {\n sanitised.prose = m.prose?.[String(i)] ?? '';\n }\n blocks[i] = sanitised;\n });\n out.push({\n question,\n blocks,\n done: true,\n error: m.errorJson ?? undefined\n });\n }\n }\n if (pendingUser !== null) {\n // Trailing user message with no assistant reply (likely interrupted).\n out.push({ question: pendingUser, blocks: [], done: true });\n }\n return out;\n}\n","/**\n * VercelChat — sibling chat shell driven by the Vercel AI SDK\n * (`@ai-sdk/react`'s `useChat`) instead of the bespoke SSE protocol used\n * by `AiChat`. Layout, sidebar, header, thread, and input pill are\n * lifted from `ai-chat.tsx` so the two interfaces render identical\n * pixels — only the streaming wire format differs.\n *\n * Wire shape (matches `routes/agent-vercel.ts`):\n * POST /api/agent/vercel\n * body: { messages, chatSessionId, model }\n * ← Vercel data stream (text deltas + custom data parts)\n *\n * Custom data parts surface in `useChat`'s top-level `data` array as\n * `JSONValue` items. We pick out `{ type: 'block', value: { index, ... } }`\n * entries and feed them through `sanitiseBlock` → `AnswerBlocks`.\n *\n * Hydration: `useChat`'s `setMessages` doesn't repopulate the `data`\n * array, so a session opened from `/api/chat/sessions/[id]` carries its\n * `Block[]` rows via a per-message map (`hydratedBlocks`) instead of\n * `data`. The renderer reads from both — live-streamed blocks come from\n * `data`, hydrated blocks come from the map — so each turn paints\n * identically regardless of origin.\n */\n'use client';\n\nimport {\n useCallback,\n useEffect,\n useLayoutEffect,\n useMemo,\n useRef,\n useState\n} from 'react';\nimport { useRouter } from 'next/navigation';\nimport Link from 'next/link';\nimport {\n ArrowUp,\n Check,\n ChevronDown,\n ChevronUp,\n Copy,\n Loader2,\n Menu,\n PanelLeftClose,\n Pencil,\n Plus,\n RotateCcw,\n Sparkles,\n Trash2\n} from 'lucide-react';\nimport { useChat, type Message as UIMessage } from '@ai-sdk/react';\n\nimport { cn } from './_shared/cn';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger\n} from './_shared/dropdown-menu';\nimport { SidebarTitleEditor, EditableTitle } from './_shared/title-editors';\nimport {\n AnswerBlocks,\n sanitiseBlock,\n type BlockState\n} from './answer-blocks';\nimport type { Block } from '../server/tools/types';\nimport type { AiChatProps, AiChatSessionSummary } from './types';\n\ntype NarrativeProvider = 'claude' | 'grok' | 'gemini';\n\ntype AnswerState = {\n question: string;\n blocks: BlockState[];\n prose: string;\n done: boolean;\n error?: { code: string; message: string };\n /** ms timestamp when the question was submitted; missing for restored history. */\n startedAt?: number;\n /** Wall-clock ms it took for the agent to mark `done`. Set in the same update that flips `done: true`. Missing for restored history. */\n durationMs?: number;\n};\n\n/** Short human-readable duration: 5s, 45s, 1m, 1m 30s, 12m 5s. */\nfunction formatDuration(ms: number): string {\n if (ms < 0) ms = 0;\n const totalSec = Math.round(ms / 1000);\n if (totalSec < 60) return `${totalSec}s`;\n const m = Math.floor(totalSec / 60);\n const s = totalSec % 60;\n return s === 0 ? `${m}m` : `${m}m ${s}s`;\n}\n\ntype StoredMessage = {\n id: string;\n role: 'user' | 'assistant';\n question: string | null;\n blocks: Block[] | null;\n prose: Record<string, string> | null;\n errorJson: { code: string; message: string } | null;\n};\n\nconst PROVIDER_LABELS: Record<NarrativeProvider, string> = {\n claude: 'Claude',\n grok: 'Grok',\n gemini: 'Gemini'\n};\n\n// Auto-grow cap. The textarea is `leading-6` (24px) with `py-1`\n// (4px top + 4px bottom). 7 visible lines = 7×24 + 8 = 176px; past\n// that, vertical scrolling kicks in inside the textarea.\nconst TEXTAREA_MAX_PX = 176;\n\nconst PROVIDER_DESCRIPTIONS: Record<NarrativeProvider, string> = {\n claude: 'Anthropic Claude on Vertex AI',\n grok: 'xAI Grok on Vertex AI',\n gemini: 'Google Gemini on Vertex AI'\n};\n\n/**\n * A single `data` entry from `useChat` representing one of our custom\n * stream parts. `useChat`'s `data` is typed as `JSONValue[] | undefined`\n * — we cast through `unknown` at the boundary and narrow with this\n * helper before reading `type`/`value`.\n */\ntype DataPart =\n | { type: 'meta'; value: { chatSessionId: string | null; scopeLabel?: string } }\n | { type: 'block'; value: Block & { index: number } }\n | { type: 'error'; value: { code: string; message: string } };\n\nfunction asDataPart(v: unknown): DataPart | null {\n if (typeof v !== 'object' || v === null || Array.isArray(v)) return null;\n const t = (v as { type?: unknown }).type;\n if (typeof t !== 'string') return null;\n return v as DataPart;\n}\n\nexport function VercelChat({\n userFirstName,\n scopeLabel,\n initialProvider,\n initialSessionId = null,\n basePath = '/chat'\n}: AiChatProps) {\n const router = useRouter();\n const [sessions, setSessions] = useState<AiChatSessionSummary[]>([]);\n const [activeSessionId, setActiveSessionId] = useState<string | null>(\n initialSessionId\n );\n // Sidebar overlays the chat panel rather than pushing it sideways, so\n // it starts closed; the hamburger in the chat header opens it.\n const [sidebarOpen, setSidebarOpen] = useState(false);\n const [loadingSession, setLoadingSession] = useState(false);\n const [provider, setProvider] = useState<NarrativeProvider>(initialProvider);\n const [providerSaving, setProviderSaving] = useState(false);\n // When non-null, the sidebar row for this session is in inline-edit\n // mode and renders an <input> instead of the static title button.\n const [editingSidebarId, setEditingSidebarId] = useState<string | null>(null);\n // Map of assistant messageId → reconstructed blocks, populated when we\n // hydrate a stored session via `setMessages`. Live-streamed turns\n // bypass this and read blocks from the top-level `data` array.\n const [hydratedBlocks, setHydratedBlocks] = useState<Record<string, BlockState[]>>({});\n // Map of assistant messageId → reconstructed prose, populated alongside\n // `hydratedBlocks` so the same lookup answers both shapes.\n const [hydratedProse, setHydratedProse] = useState<Record<string, string>>({});\n // Map of assistant messageId → stored error envelope, populated for\n // turns that surfaced an error before the agent could `present`.\n const [hydratedErrors, setHydratedErrors] = useState<\n Record<string, { code: string; message: string }>\n >({});\n // Map of user messageId → submission timestamp, used to compute the\n // live \"Thinking… (5s)\" ticker for the in-flight assistant turn.\n const [startedAt, setStartedAt] = useState<Record<string, number>>({});\n\n const threadRef = useRef<HTMLDivElement | null>(null);\n const textareaRef = useRef<HTMLTextAreaElement | null>(null);\n // Ref to the most recently submitted answer's container. We snap it\n // to the top of the thread on submit so the AI response gets a fresh\n // viewport below the question, mirroring Claude/ChatGPT.\n const lastAnswerRef = useRef<HTMLDivElement | null>(null);\n const prevAnswersLen = useRef(0);\n\n // Live mirrors so async callbacks (handleSubmit, prepareRequestBody)\n // always see the freshest values without stale closures.\n const activeSessionIdRef = useRef<string | null>(activeSessionId);\n const providerRef = useRef<NarrativeProvider>(provider);\n useEffect(() => {\n activeSessionIdRef.current = activeSessionId;\n }, [activeSessionId]);\n useEffect(() => {\n providerRef.current = provider;\n }, [provider]);\n\n const refreshSessions = useCallback(async () => {\n try {\n const res = await fetch('/api/chat/sessions', { cache: 'no-store' });\n if (!res.ok) return;\n const data = (await res.json()) as { sessions: AiChatSessionSummary[] };\n setSessions(data.sessions ?? []);\n } catch {\n /* noop */\n }\n }, []);\n\n const {\n messages,\n input,\n handleInputChange,\n handleSubmit,\n status,\n setMessages,\n setInput,\n data\n } = useChat({\n api: '/api/agent/vercel',\n // `body` here is captured at hook init and stale-closes over\n // `activeSessionId`/`provider`. Real per-submit body comes through\n // `experimental_prepareRequestBody` below, which reads from refs.\n experimental_prepareRequestBody: ({ messages: msgs }) => ({\n messages: msgs,\n chatSessionId: activeSessionIdRef.current,\n model: providerRef.current\n }),\n onFinish: () => {\n // Persisted title may have been auto-generated on the server —\n // refresh sidebar so the new label appears.\n void refreshSessions();\n }\n });\n\n // Auto-grow the textarea up to TEXTAREA_MAX_LINES (≈7 lines), then\n // start scrolling internally. We measure with scrollHeight after\n // resetting height to 0, mirroring the standard auto-grow pattern.\n useLayoutEffect(() => {\n const el = textareaRef.current;\n if (!el) return;\n el.style.height = '0px';\n const next = Math.min(el.scrollHeight, TEXTAREA_MAX_PX);\n el.style.height = `${next}px`;\n }, [input]);\n\n // Initial session list load (independent of which session is active —\n // the URL is now the source of truth for that, so we just hydrate the\n // sidebar here).\n useEffect(() => {\n let cancelled = false;\n async function load() {\n try {\n const res = await fetch('/api/chat/sessions', { cache: 'no-store' });\n if (!res.ok) return;\n const json = (await res.json()) as { sessions: AiChatSessionSummary[] };\n if (cancelled) return;\n setSessions(json.sessions ?? []);\n } catch {\n // network blip — sidebar will just be empty until next nav.\n }\n }\n void load();\n return () => {\n cancelled = true;\n };\n }, []);\n\n // Hydrate the active session's messages on first mount when the host\n // routed us to /chat/[id]. The URL is authoritative, so we treat\n // `initialSessionId` as the only signal — never auto-open a different\n // session. Re-runs when the prop changes (navigating between\n // /chat/[a] ↔ /chat/[b] remounts with a new prop).\n useEffect(() => {\n if (initialSessionId == null) {\n setMessages([]);\n setHydratedBlocks({});\n setHydratedProse({});\n setHydratedErrors({});\n return;\n }\n let cancelled = false;\n async function load(id: string) {\n setLoadingSession(true);\n try {\n const res = await fetch(`/api/chat/sessions/${id}`, { cache: 'no-store' });\n if (cancelled) return;\n if (!res.ok) {\n setMessages([]);\n setHydratedBlocks({});\n setHydratedProse({});\n setHydratedErrors({});\n return;\n }\n const json = (await res.json()) as { messages: StoredMessage[] };\n if (cancelled) return;\n const { uiMessages, blocksMap, proseMap, errorsMap } = storedToUseChat(\n json.messages ?? []\n );\n setMessages(uiMessages);\n setHydratedBlocks(blocksMap);\n setHydratedProse(proseMap);\n setHydratedErrors(errorsMap);\n setStartedAt({});\n } catch {\n if (!cancelled) {\n setMessages([]);\n setHydratedBlocks({});\n setHydratedProse({});\n setHydratedErrors({});\n }\n } finally {\n if (!cancelled) setLoadingSession(false);\n }\n }\n void load(initialSessionId);\n return () => {\n cancelled = true;\n };\n }, [initialSessionId, setMessages]);\n\n // Defensive backstop for the `meta` data part. The agent-vercel route\n // emits `{ type: 'meta', value: { chatSessionId, scopeLabel } }` as\n // its first data event; if the lazy-create POST somehow didn't run\n // (or its result didn't reach state), we still want the client's\n // activeSessionId / URL to match the persistent session id.\n useEffect(() => {\n if (!Array.isArray(data)) return;\n for (const raw of data) {\n const part = asDataPart(raw);\n if (!part || part.type !== 'meta') continue;\n const id = part.value.chatSessionId;\n if (!id) continue;\n setActiveSessionId((prev) => prev ?? id);\n if (\n typeof window !== 'undefined' &&\n !window.location.pathname.endsWith(`/${id}`)\n ) {\n window.history.replaceState(null, '', `${basePath}/${id}`);\n }\n break;\n }\n }, [data, basePath]);\n\n // Pair user → assistant messages and attach the right block slice to\n // each assistant turn. Live blocks come from the top-level `data`\n // array; hydrated blocks come from the per-message maps populated in\n // `openSession`. The result is the same `AnswerState[]` shape used by\n // `AiChat` so the rendered markup matches.\n const answers = useMemo<AnswerState[]>(() => {\n // Pull all live block parts from the cumulative `data` array. They\n // arrive in append order; we walk the messages array and assign\n // contiguous block runs to each assistant message that does NOT\n // already have a hydrated entry (since hydration replaces the run).\n const liveBlocks: Array<Block & { index: number }> = [];\n const liveErrors: Array<{ code: string; message: string }> = [];\n if (Array.isArray(data)) {\n for (const raw of data) {\n const part = asDataPart(raw);\n if (!part) continue;\n if (part.type === 'block') liveBlocks.push(part.value);\n else if (part.type === 'error') liveErrors.push(part.value);\n }\n }\n\n // Reduce live blocks to a sparse array indexed by `index`. A second\n // assistant turn would reset the index back to 0, so we track which\n // assistant turn each block run targets by counting assistant\n // messages that lack hydrated blocks.\n const out: AnswerState[] = [];\n let pendingQuestion: string | null = null;\n let liveAssistantSeen = 0;\n // Group live blocks by their assistant-turn ordinal. We assume the\n // server resets `index` back to 0 for each new turn, so a block\n // with `index === 0` after a non-zero index marks a new turn.\n const liveTurns: Array<Array<Block & { index: number }>> = [];\n {\n let current: Array<Block & { index: number }> = [];\n let lastIdx = -1;\n for (const b of liveBlocks) {\n if (b.index <= lastIdx && current.length > 0) {\n liveTurns.push(current);\n current = [];\n }\n current.push(b);\n lastIdx = b.index;\n }\n if (current.length > 0) liveTurns.push(current);\n }\n\n for (const m of messages) {\n if (m.role === 'user') {\n pendingQuestion = m.content;\n continue;\n }\n if (m.role !== 'assistant') continue;\n\n const question = pendingQuestion ?? '';\n pendingQuestion = null;\n\n const hydrated = hydratedBlocks[m.id];\n const hydratedProseStr = hydratedProse[m.id];\n const hydratedError = hydratedErrors[m.id];\n\n let blocks: BlockState[] = [];\n let prose = '';\n let error: { code: string; message: string } | undefined;\n\n if (hydrated != null) {\n // Hydrated assistant turn — blocks/prose/error already mapped\n // out of stored shape; the live data array is irrelevant here.\n blocks = hydrated;\n prose = hydratedProseStr ?? '';\n error = hydratedError;\n } else {\n // Live-streamed assistant turn — splice the next live-turn run\n // into a sparse BlockState[] using sanitiseBlock.\n const run = liveTurns[liveAssistantSeen] ?? [];\n const acc: BlockState[] = [];\n for (const raw of run) {\n acc[raw.index] = sanitiseBlock(raw);\n }\n blocks = acc;\n prose = m.content ?? '';\n error = liveErrors[liveAssistantSeen];\n liveAssistantSeen += 1;\n }\n\n // Attribute streamed prose to the FIRST paragraph_brief block, so\n // the renderer prints it via the existing `paragraph_brief` path\n // and the on-disk shape persisted by the route lines up.\n if (prose) {\n const firstPb = blocks.findIndex((b) => b && b.kind === 'paragraph_brief');\n if (firstPb >= 0) {\n const target = blocks[firstPb];\n if (target.kind === 'paragraph_brief') {\n blocks[firstPb] = { ...target, prose };\n }\n }\n }\n\n const isLive = hydrated == null;\n const turnDone = !isLive || status === 'ready' || status === 'error';\n const startedTs = startedAt[m.id];\n\n out.push({\n question,\n blocks: blocks.filter(Boolean),\n prose,\n done: turnDone,\n error,\n startedAt: startedTs,\n durationMs:\n turnDone && startedTs != null ? Date.now() - startedTs : undefined\n });\n }\n\n // Trailing user message with no assistant reply yet (in flight) —\n // surface it as a thinking turn so the user sees the question\n // pinned and a spinner rendered below.\n if (pendingQuestion != null) {\n const lastUser = [...messages].reverse().find((m) => m.role === 'user');\n const ts = lastUser ? startedAt[lastUser.id] : undefined;\n out.push({\n question: pendingQuestion,\n blocks: [],\n prose: '',\n done: false,\n startedAt: ts\n });\n }\n\n return out;\n }, [messages, data, hydratedBlocks, hydratedProse, hydratedErrors, status, startedAt]);\n\n // Snap the newly submitted question to the top of the thread when a\n // new answer is appended. We deliberately do NOT auto-scroll on\n // every prose/block update — the user's reading flow stays put as\n // the response streams below the pinned question, and they can\n // scroll up to revisit prior turns. Mirrors Claude / ChatGPT.\n useEffect(() => {\n if (answers.length > prevAnswersLen.current && lastAnswerRef.current) {\n lastAnswerRef.current.scrollIntoView({ behavior: 'smooth', block: 'start' });\n }\n prevAnswersLen.current = answers.length;\n }, [answers.length]);\n\n // Push `${basePath}/<id>` (or `${basePath}`) so reload, bookmarks, and\n // multi-tab restore the exact session the user is viewing.\n const syncUrl = useCallback(\n (id: string | null) => {\n router.push(id == null ? basePath : `${basePath}/${id}`);\n },\n [router, basePath]\n );\n\n // \"+ New chat\" navigates to ${basePath}?new — the host's basePath\n // route is expected to redirect to the most-recent session by default,\n // and the `?new` hint suppresses that.\n const newChat = useCallback(() => {\n setActiveSessionId(null);\n setMessages([]);\n setHydratedBlocks({});\n setHydratedProse({});\n setHydratedErrors({});\n setStartedAt({});\n setInput('');\n router.push(`${basePath}?new`);\n }, [setMessages, setInput, router, basePath]);\n\n const changeProvider = useCallback(\n async (next: NarrativeProvider) => {\n if (next === provider || providerSaving) return;\n setProvider(next);\n setProviderSaving(true);\n try {\n const res = await fetch('/api/settings/me', {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ narrative_provider: next })\n });\n if (!res.ok) {\n // Roll back the optimistic update on failure.\n setProvider((curr) => (curr === next ? provider : curr));\n }\n } catch {\n setProvider((curr) => (curr === next ? provider : curr));\n } finally {\n setProviderSaving(false);\n }\n },\n [provider, providerSaving]\n );\n\n const openSession = useCallback(\n async (id: string) => {\n setLoadingSession(true);\n setActiveSessionId(id);\n syncUrl(id);\n try {\n const res = await fetch(`/api/chat/sessions/${id}`, { cache: 'no-store' });\n if (!res.ok) {\n setMessages([]);\n setHydratedBlocks({});\n setHydratedProse({});\n setHydratedErrors({});\n return;\n }\n const json = (await res.json()) as { messages: StoredMessage[] };\n const { uiMessages, blocksMap, proseMap, errorsMap } = storedToUseChat(\n json.messages ?? []\n );\n setMessages(uiMessages);\n setHydratedBlocks(blocksMap);\n setHydratedProse(proseMap);\n setHydratedErrors(errorsMap);\n setStartedAt({});\n } catch {\n setMessages([]);\n setHydratedBlocks({});\n setHydratedProse({});\n setHydratedErrors({});\n } finally {\n setLoadingSession(false);\n }\n },\n [setMessages, syncUrl]\n );\n\n const persistTitle = useCallback(\n async (id: string, title: string) => {\n const trimmed = title.trim();\n if (!trimmed) return;\n const res = await fetch(`/api/chat/sessions/${id}`, {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ title: trimmed })\n });\n if (res.ok) {\n setSessions((prev) =>\n prev.map((s) => (s.id === id ? { ...s, title: trimmed } : s))\n );\n }\n },\n []\n );\n\n const startSidebarRename = useCallback((id: string) => {\n setEditingSidebarId(id);\n }, []);\n\n const deleteSession = useCallback(\n async (id: string) => {\n if (!window.confirm('Delete this chat? This cannot be undone.')) return;\n const res = await fetch(`/api/chat/sessions/${id}`, { method: 'DELETE' });\n if (!res.ok) return;\n setSessions((prev) => prev.filter((s) => s.id !== id));\n if (activeSessionId === id) {\n setActiveSessionId(null);\n setMessages([]);\n setHydratedBlocks({});\n setHydratedProse({});\n setHydratedErrors({});\n syncUrl(null);\n }\n },\n [activeSessionId, setMessages, syncUrl]\n );\n\n // Wraps `useChat`'s handleSubmit so we can lazily create a session on\n // first turn (sidebar would otherwise sprout empty \"New chat\" rows).\n // The form's onSubmit calls `e.preventDefault()` itself; this helper\n // only needs to do the session-create dance and forward to\n // `handleSubmit`. The user message id is generated inside `useChat`\n // and sampled in the `messages` effect below for `startedAt` tracking.\n const submitForm = useCallback(\n async (e: React.FormEvent<HTMLFormElement>) => {\n const trimmed = input.trim();\n if (!trimmed || status !== 'ready') return;\n\n if (activeSessionIdRef.current == null) {\n try {\n const create = await fetch('/api/chat/sessions', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({})\n });\n if (create.ok) {\n const json = (await create.json()) as {\n session: AiChatSessionSummary;\n };\n activeSessionIdRef.current = json.session.id;\n setActiveSessionId(json.session.id);\n // Pin the URL to the new session so reload restores this\n // thread. Use `window.history.replaceState` (shallow URL\n // update) rather than `router.push` here: a Next.js\n // navigation would unmount this component mid-streaming,\n // dropping the in-flight Vercel-AI data stream on the\n // floor — the next mount would then re-hydrate from the\n // API before the assistant message finishes persisting.\n if (typeof window !== 'undefined') {\n window.history.replaceState(\n null,\n '',\n `${basePath}/${json.session.id}`\n );\n }\n setSessions((prev) => [\n { id: json.session.id, title: json.session.title, updatedAt: null },\n ...prev\n ]);\n }\n } catch {\n // Session create failed — proceed without persistence.\n }\n }\n\n handleSubmit(e);\n },\n [input, status, handleSubmit, syncUrl]\n );\n\n // Stamp `startedAt` for any user message we haven't seen yet. This\n // runs on every messages update, but only writes new entries — stable\n // across re-renders so it doesn't cause loops.\n useEffect(() => {\n setStartedAt((prev) => {\n let changed = false;\n const next = { ...prev };\n for (const m of messages) {\n if (m.role === 'user' && next[m.id] == null) {\n next[m.id] = Date.now();\n changed = true;\n }\n if (m.role === 'assistant' && next[m.id] == null) {\n // Reuse the user's startedAt for the immediately-prior user\n // turn so duration tracks the full question→answer span.\n const idx = messages.findIndex((mm) => mm.id === m.id);\n for (let i = idx - 1; i >= 0; i -= 1) {\n const prior = messages[i];\n if (prior.role === 'user' && next[prior.id] != null) {\n next[m.id] = next[prior.id];\n changed = true;\n break;\n }\n }\n }\n }\n return changed ? next : prev;\n });\n }, [messages]);\n\n const heroVisible = answers.length === 0 && !loadingSession;\n const greeting = useMemo(\n () =>\n `Hi ${userFirstName || 'there'}${\n userFirstName.endsWith('s') ? '' : ''\n },`,\n [userFirstName]\n );\n\n const activeTitle = activeSessionId\n ? sessions.find((s) => s.id === activeSessionId)?.title ?? 'Chat'\n : 'New chat';\n\n // Retry resubmits the last user question via setInput + a synthetic\n // submit; the form's submit handler does the lazy-session-create dance.\n const retry = useCallback(\n (q: string) => {\n setInput(q);\n // Defer one tick so `input` is updated before the submit reads it.\n window.setTimeout(() => {\n const form = textareaRef.current?.form;\n if (form) form.requestSubmit();\n }, 0);\n },\n [setInput]\n );\n\n return (\n <div className=\"relative flex h-full min-h-0 w-full overflow-hidden rounded-lg border border-border bg-background\">\n {/* Backdrop: click to close. Pointer-events only when open so the\n chat panel underneath stays interactive when the sidebar is\n closed. */}\n <div\n onClick={() => setSidebarOpen(false)}\n aria-hidden=\"true\"\n className={cn(\n 'absolute inset-0 z-10 bg-background/60 backdrop-blur-sm transition-opacity duration-200',\n sidebarOpen\n ? 'opacity-100'\n : 'pointer-events-none opacity-0'\n )}\n />\n\n {/* Overlay session sidebar — slides in from the left, never\n shrinks the chat panel. z-20 so it sits above the backdrop. */}\n <aside\n inert={!sidebarOpen}\n className={cn(\n 'absolute inset-y-0 left-0 z-20 flex w-72 max-w-[85vw] flex-col border-r border-border bg-sidebar text-sidebar-foreground shadow-lg transition-transform duration-200 ease-out',\n sidebarOpen ? 'translate-x-0' : '-translate-x-full'\n )}\n >\n <div className=\"flex items-center gap-2 border-b border-sidebar-border p-2\">\n <button\n type=\"button\"\n onClick={() => setSidebarOpen(false)}\n className=\"inline-flex size-8 items-center justify-center rounded-md text-sidebar-foreground/70 hover:bg-sidebar-accent hover:text-sidebar-foreground\"\n aria-label=\"Close sidebar\"\n >\n <PanelLeftClose className=\"size-4\" />\n </button>\n <button\n type=\"button\"\n onClick={() => {\n newChat();\n setSidebarOpen(false);\n }}\n className=\"ml-auto inline-flex items-center gap-1.5 rounded-full border border-sidebar-border bg-sidebar-accent px-3 py-1.5 text-xs font-medium text-sidebar-accent-foreground hover:bg-sidebar-accent/80\"\n >\n <Plus className=\"size-3.5\" />\n New chat\n </button>\n </div>\n <div className=\"flex-1 overflow-y-auto p-2\">\n {sessions.length === 0 ? (\n <p className=\"px-2 py-3 text-xs text-sidebar-foreground/60\">\n No chats yet. Ask something below to start.\n </p>\n ) : (\n <ul className=\"flex flex-col gap-0.5\">\n {sessions.map((s) => {\n const active = s.id === activeSessionId;\n const editing = s.id === editingSidebarId;\n if (editing) {\n return (\n <li key={s.id} className=\"px-1 py-1\">\n <SidebarTitleEditor\n initial={s.title}\n onCancel={() => setEditingSidebarId(null)}\n onSave={(next) => {\n setEditingSidebarId(null);\n void persistTitle(s.id, next);\n }}\n />\n </li>\n );\n }\n return (\n <li key={s.id} className=\"group relative\">\n <Link\n href={`${basePath}/${s.id}`}\n onClick={() => setSidebarOpen(false)}\n className={cn(\n 'flex w-full items-center gap-2 rounded-md px-2 py-1.5 text-left text-sm',\n active\n ? 'bg-sidebar-accent text-sidebar-accent-foreground'\n : 'text-sidebar-foreground/80 hover:bg-sidebar-accent/60 hover:text-sidebar-foreground'\n )}\n title={s.title}\n >\n <span className=\"truncate\">{s.title}</span>\n </Link>\n <div className=\"absolute right-1 top-1/2 hidden -translate-y-1/2 items-center gap-0.5 group-hover:flex\">\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n startSidebarRename(s.id);\n }}\n aria-label=\"Rename\"\n className=\"inline-flex size-6 items-center justify-center rounded text-sidebar-foreground/60 hover:bg-sidebar hover:text-sidebar-foreground\"\n >\n <Pencil className=\"size-3\" />\n </button>\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n void deleteSession(s.id);\n }}\n aria-label=\"Delete\"\n className=\"inline-flex size-6 items-center justify-center rounded text-sidebar-foreground/60 hover:bg-sidebar hover:text-destructive\"\n >\n <Trash2 className=\"size-3\" />\n </button>\n </div>\n </li>\n );\n })}\n </ul>\n )}\n </div>\n </aside>\n\n <section className=\"relative flex flex-1 flex-col overflow-hidden\">\n <header className=\"flex items-center gap-2 px-3 py-3 text-sm text-muted-foreground\">\n <button\n type=\"button\"\n onClick={() => setSidebarOpen(true)}\n aria-label=\"Open chat history\"\n className=\"inline-flex size-8 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground\"\n >\n <Menu className=\"size-4\" />\n </button>\n <Sparkles className=\"size-4 text-primary\" />\n {activeSessionId != null ? (\n <EditableTitle\n key={activeSessionId}\n title={activeTitle}\n onSave={(next) => void persistTitle(activeSessionId, next)}\n />\n ) : (\n <span className=\"truncate\">{activeTitle}</span>\n )}\n </header>\n\n <div\n ref={threadRef}\n className=\"min-h-0 flex-1 overflow-y-auto px-4 pb-6 pt-2\"\n >\n {loadingSession ? (\n <div className=\"flex h-full items-center justify-center text-sm text-muted-foreground\">\n <Loader2 className=\"mr-2 size-4 animate-spin\" /> Loading conversation…\n </div>\n ) : heroVisible ? (\n <div className=\"flex h-full flex-col items-center justify-center text-center\">\n <h1 className=\"text-2xl font-medium tracking-tight text-foreground sm:text-3xl\">\n {greeting}\n </h1>\n <p className=\"mt-2 text-2xl font-light tracking-tight text-muted-foreground sm:text-3xl\">\n What's on your mind?\n </p>\n </div>\n ) : (\n <div className=\"mx-auto flex w-full max-w-3xl flex-col gap-6\">\n {answers.map((a, idx) => (\n <AnswerView\n key={idx}\n answer={a}\n onRetry={() => retry(a.question)}\n forwardRef={idx === answers.length - 1 ? lastAnswerRef : undefined}\n // The last turn reserves enough viewport so the AI\n // response has room to stream below the question\n // without the user needing to scroll. Calc subtracts\n // the input-pill area (~14rem) and a comfort buffer.\n isLast={idx === answers.length - 1}\n />\n ))}\n </div>\n )}\n </div>\n\n <div className=\"shrink-0 px-4 pb-4 pt-2\">\n <form\n className=\"mx-auto w-full max-w-3xl\"\n onSubmit={(e) => {\n e.preventDefault();\n void submitForm(e);\n }}\n >\n <div className=\"flex flex-col gap-2 rounded-3xl border border-border bg-background px-4 py-3 shadow-sm\">\n <textarea\n ref={textareaRef}\n value={input}\n onChange={handleInputChange}\n onKeyDown={(e) => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n e.currentTarget.form?.requestSubmit();\n }\n }}\n placeholder=\"Ask AI...\"\n rows={1}\n disabled={status !== 'ready'}\n style={{ maxHeight: TEXTAREA_MAX_PX }}\n className=\"w-full resize-none overflow-y-auto border-0 bg-transparent py-1 text-sm leading-6 text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-0 disabled:opacity-60\"\n />\n <div className=\"flex items-center justify-between gap-2\">\n <span\n className=\"inline-flex max-w-[60%] items-center gap-1.5 truncate rounded-full border border-border bg-muted/40 px-2.5 py-1 text-xs font-medium text-muted-foreground\"\n title={`Scope: ${scopeLabel}`}\n >\n Scope: <span className=\"truncate text-foreground\">{scopeLabel}</span>\n </span>\n <div className=\"flex items-center gap-2\">\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <button\n type=\"button\"\n className=\"inline-flex items-center gap-1 rounded-full px-2.5 py-1 text-xs font-medium text-muted-foreground hover:bg-accent hover:text-foreground\"\n aria-label=\"Choose model\"\n >\n {PROVIDER_LABELS[provider]}\n <ChevronDown className=\"size-3.5\" />\n </button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\" className=\"w-56\">\n {(['claude', 'grok', 'gemini'] as const).map((p) => (\n <DropdownMenuItem\n key={p}\n onSelect={() => void changeProvider(p)}\n className=\"flex items-start gap-2\"\n >\n <Check\n className={cn(\n 'mt-0.5 size-4',\n provider === p ? 'opacity-100' : 'opacity-0'\n )}\n />\n <div className=\"flex flex-col\">\n <span className=\"text-sm font-medium\">\n {PROVIDER_LABELS[p]}\n </span>\n <span className=\"text-xs text-muted-foreground\">\n {PROVIDER_DESCRIPTIONS[p]}\n </span>\n </div>\n </DropdownMenuItem>\n ))}\n </DropdownMenuContent>\n </DropdownMenu>\n <button\n type=\"submit\"\n disabled={status !== 'ready' || !input.trim()}\n aria-label=\"Send\"\n className=\"inline-flex size-8 shrink-0 items-center justify-center rounded-full bg-primary text-primary-foreground transition-colors enabled:hover:bg-primary/90 disabled:opacity-40\"\n >\n {status === 'streaming' || status === 'submitted' ? (\n <Loader2 className=\"size-4 animate-spin\" />\n ) : (\n <ArrowUp className=\"size-4\" />\n )}\n </button>\n </div>\n </div>\n </div>\n <p className=\"mt-2 text-center text-xs text-muted-foreground\">\n {PROVIDER_LABELS[provider]} is AI and can make mistakes.\n </p>\n </form>\n </div>\n </section>\n </div>\n );\n}\n\nfunction AnswerView({\n answer,\n onRetry,\n forwardRef,\n isLast\n}: {\n answer: AnswerState;\n onRetry: () => void;\n /** Attached to the outer container so the parent can scroll the latest turn into view on submit. */\n forwardRef?: React.RefObject<HTMLDivElement | null>;\n /**\n * The last turn reserves enough viewport that the AI response has\n * room to grow under the pinned question. The parent flex column\n * uses `min-h-[...]` here so a short answer doesn't leave a\n * ridiculous gap, but a long-running response can stream below\n * without the user being autoscrolled.\n */\n isLast?: boolean;\n}) {\n const [copied, setCopied] = useState(false);\n\n const handleCopy = useCallback(async () => {\n // Prefer the structured response; fall back to the error envelope\n // when the turn produced no blocks so the user can still copy the\n // failure (eg. quota error message → paste into an issue).\n const blockText = blocksToPlainText(answer.blocks);\n const text =\n blockText ||\n (answer.error\n ? `${answer.error.code}: ${answer.error.message}`\n : '');\n if (!text) return;\n try {\n await navigator.clipboard.writeText(text);\n setCopied(true);\n window.setTimeout(() => setCopied(false), 1500);\n } catch {\n // Clipboard blocked (insecure context, permission denied) — silent.\n }\n }, [answer.blocks, answer.error]);\n\n const showActions =\n answer.done && (answer.blocks.length > 0 || answer.error != null);\n // While the agent is still computing the first block, drop the\n // nested-column layout entirely and render a single flex row. The\n // normal layout has an empty `AnswerBlocks` wrapper that contributes\n // a 12px flex-gap to the column even when it has no blocks, which\n // throws `items-center` off so the icon and \"Thinking…\" don't align.\n const isThinking =\n !answer.done && answer.blocks.length === 0 && !answer.error;\n\n // Live ticker — re-renders once a second while the agent is thinking\n // so the inline \"(5s)\" counter advances. We force a re-render via a\n // dummy state instead of recomputing elapsed in a useEffect because\n // the elapsed value is derived from `answer.startedAt` (a prop) and\n // `Date.now()` — anything stored in state would just duplicate that.\n const [, forceTick] = useState(0);\n useEffect(() => {\n if (answer.done || answer.startedAt == null) return;\n const id = window.setInterval(() => forceTick((n) => n + 1), 1000);\n return () => window.clearInterval(id);\n }, [answer.done, answer.startedAt]);\n\n // Live elapsed for the thinking state; final stamped duration once done.\n const liveElapsed =\n answer.startedAt != null ? Date.now() - answer.startedAt : null;\n const finalDuration = answer.durationMs;\n\n return (\n <div\n ref={forwardRef}\n // scroll-mt nudges scrollIntoView so the question doesn't kiss\n // the very top of the thread container.\n className={cn(\n 'flex flex-col gap-4 scroll-mt-2',\n // Reserve space below the latest turn so the AI response has a\n // full screen to fill without bouncing the user. Calc subtracts\n // the chat header (~3rem) and the input pill area (~10rem) from\n // the dynamic viewport height.\n isLast && 'min-h-[calc(100dvh-13rem)]'\n )}\n >\n <div className=\"flex justify-end\">\n <UserChip text={answer.question} />\n </div>\n {isThinking ? (\n <div className=\"flex items-center gap-3\">\n <div className=\"flex size-7 shrink-0 items-center justify-center rounded-full bg-primary/10 text-primary\">\n <Sparkles className=\"size-4\" />\n </div>\n <p className=\"flex items-center text-sm text-muted-foreground\">\n <Loader2 className=\"mr-1 inline size-3.5 animate-spin\" />\n Thinking…\n {liveElapsed != null && liveElapsed >= 1000 && (\n <span className=\"ml-2 text-xs tabular-nums\">\n ({formatDuration(liveElapsed)})\n </span>\n )}\n </p>\n </div>\n ) : (\n <div className=\"flex items-start gap-3\">\n <div className=\"mt-0.5 flex size-7 shrink-0 items-center justify-center rounded-full bg-primary/10 text-primary\">\n <Sparkles className=\"size-4\" />\n </div>\n <div className=\"flex min-w-0 flex-1 flex-col gap-3\">\n <AnswerBlocks blocks={answer.blocks} />\n {answer.error && (\n <div className=\"wrap-break-word whitespace-pre-wrap rounded border border-amber-300 bg-amber-50 p-3 text-sm text-amber-900 dark:border-amber-800 dark:bg-amber-950/30 dark:text-amber-100\">\n {answer.error.code}: {answer.error.message}\n </div>\n )}\n {showActions && (\n <div className=\"flex items-center gap-1\">\n {(answer.blocks.length > 0 || answer.error != null) && (\n <button\n type=\"button\"\n onClick={handleCopy}\n aria-label={\n answer.blocks.length === 0 && answer.error\n ? 'Copy error'\n : 'Copy response'\n }\n title={copied ? 'Copied' : 'Copy'}\n className=\"inline-flex size-8 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground\"\n >\n {copied ? (\n <Check className=\"size-4\" />\n ) : (\n <Copy className=\"size-4\" />\n )}\n </button>\n )}\n <button\n type=\"button\"\n onClick={onRetry}\n aria-label=\"Retry\"\n title=\"Retry\"\n className=\"inline-flex size-8 items-center justify-center rounded-md text-muted-foreground hover:bg-accent hover:text-foreground\"\n >\n <RotateCcw className=\"size-4\" />\n </button>\n {finalDuration != null && finalDuration >= 1000 && (\n <span\n className=\"ml-1 text-xs text-muted-foreground tabular-nums\"\n title=\"Time taken to generate this response\"\n >\n {formatDuration(finalDuration)}\n </span>\n )}\n </div>\n )}\n </div>\n </div>\n )}\n </div>\n );\n}\n\n/**\n * Flatten an assistant turn's blocks into plain text for the clipboard\n * — paragraph prose, list items, callouts, and a tab-separated table\n * dump. Charts are referenced by title since the visual is what\n * matters there.\n */\nfunction blocksToPlainText(blocks: BlockState[]): string {\n return blocks\n .map((b) => {\n if (b.kind === 'paragraph_brief') {\n return b.prose || b.key_facts.join('. ');\n }\n if (b.kind === 'list') {\n const lines = b.items.map((it, i) =>\n b.style === 'numbered' ? `${i + 1}. ${it}` : `- ${it}`\n );\n return [b.title, ...lines].filter(Boolean).join('\\n');\n }\n if (b.kind === 'chart') {\n return `${b.title} (chart)`;\n }\n if (b.kind === 'table') {\n const header = b.columns.join('\\t');\n const rows = b.rows.map((r) =>\n r.map((c) => (c == null ? '—' : String(c))).join('\\t')\n );\n return [b.title, header, ...rows].join('\\n');\n }\n if (b.kind === 'callout') return b.text;\n return '';\n })\n .filter(Boolean)\n .join('\\n\\n');\n}\n\n/**\n * User-message bubble. Wraps long content (including unspaced strings\n * via `wrap-break-word`); when collapsed it caps at 3 lines and fades\n * the last line into the bubble background instead of using a hard\n * ellipsis. A chevron + \"Show more / Show less\" toggle reveals only\n * when the cap actually truncates content.\n */\nfunction UserChip({ text }: { text: string }) {\n const [expanded, setExpanded] = useState(false);\n const [overflowing, setOverflowing] = useState(false);\n const ref = useRef<HTMLDivElement | null>(null);\n\n useLayoutEffect(() => {\n const el = ref.current;\n if (!el || expanded) return;\n setOverflowing(el.scrollHeight > el.clientHeight + 1);\n }, [text, expanded]);\n\n return (\n <div className=\"max-w-[85%] rounded-2xl bg-muted px-4 py-2 text-sm text-foreground\">\n <div className=\"relative\">\n <div\n ref={ref}\n className={cn(\n 'whitespace-pre-wrap wrap-break-word leading-6',\n // 3 lines × leading-6 (24px) = 72px → max-h-18.\n !expanded && 'max-h-18 overflow-hidden'\n )}\n >\n {text}\n </div>\n {!expanded && overflowing && (\n <div\n aria-hidden=\"true\"\n className=\"pointer-events-none absolute inset-x-0 bottom-0 h-6 bg-linear-to-t from-muted to-transparent\"\n />\n )}\n </div>\n {(overflowing || expanded) && (\n <button\n type=\"button\"\n onClick={() => setExpanded((v) => !v)}\n className=\"mt-1 inline-flex items-center gap-1 text-xs font-medium text-muted-foreground hover:text-foreground\"\n >\n {expanded ? (\n <>\n <ChevronUp className=\"size-3.5\" />\n Show less\n </>\n ) : (\n <>\n <ChevronDown className=\"size-3.5\" />\n Show more\n </>\n )}\n </button>\n )}\n </div>\n );\n}\n\n/**\n * Convert stored chat messages into the `useChat` `Message[]` shape\n * plus per-assistant-message hydration maps for blocks, prose, and\n * errors. The two outputs are kept separate because `useChat`'s\n * `Message` type doesn't carry our custom `Block[]` payload — the maps\n * sit alongside `messages` and the renderer joins them by message id.\n */\nfunction storedToUseChat(stored: StoredMessage[]): {\n uiMessages: UIMessage[];\n blocksMap: Record<string, BlockState[]>;\n proseMap: Record<string, string>;\n errorsMap: Record<string, { code: string; message: string }>;\n} {\n const uiMessages: UIMessage[] = [];\n const blocksMap: Record<string, BlockState[]> = {};\n const proseMap: Record<string, string> = {};\n const errorsMap: Record<string, { code: string; message: string }> = {};\n let pendingUser: { id: string; question: string } | null = null;\n\n for (const m of stored) {\n if (m.role === 'user') {\n const id = `user-${m.id}`;\n const question = m.question ?? '';\n uiMessages.push({ id, role: 'user', content: question });\n pendingUser = { id, question };\n continue;\n }\n if (m.role === 'assistant') {\n const id = `assistant-${m.id}`;\n // Reconstruct blocks via sanitiseBlock and reattach prose runs to\n // their matching paragraph_brief entry (mirroring the on-disk\n // shape persisted by the Vercel route's `onFinish`).\n const blocks: BlockState[] = [];\n const stored = (m.blocks ?? []) as Block[];\n stored.forEach((b, i) => {\n const sanitised = sanitiseBlock({ ...(b as Block), index: i } as Block & {\n index: number;\n });\n if (sanitised.kind === 'paragraph_brief') {\n sanitised.prose = m.prose?.[String(i)] ?? '';\n }\n blocks[i] = sanitised;\n });\n\n // Joined prose serves as the message `content`, which the\n // renderer uses as a fallback if no paragraph_brief is present.\n const joinedProse = Object.values(m.prose ?? {})\n .filter(Boolean)\n .join('\\n\\n');\n\n uiMessages.push({\n id,\n role: 'assistant',\n content: joinedProse\n });\n blocksMap[id] = blocks;\n if (joinedProse) proseMap[id] = joinedProse;\n if (m.errorJson) errorsMap[id] = m.errorJson;\n pendingUser = null;\n }\n }\n\n return { uiMessages, blocksMap, proseMap, errorsMap };\n}\n","// @firstlovecenter/ai-chat/ui — public surface\n//\n// Phase 2: two chat shells share the same `AiChatProps` contract — the\n// bespoke SSE shell (`AiChat`) and the Vercel AI SDK shell\n// (`VercelChat`). The host picks one via the `chatInterfaces` registry\n// or `getChatInterface(id)`.\n\n'use client';\n\nimport type { ComponentType } from 'react';\nimport { AiChat } from './ai-chat';\nimport { VercelChat } from './vercel-chat';\nimport type { AiChatProps } from './types';\n\nexport type ChatInterfaceDef = {\n id: 'custom' | 'vercel';\n label: string;\n description: string;\n Component: ComponentType<AiChatProps>;\n};\n\nexport const chatInterfaces: ChatInterfaceDef[] = [\n {\n id: 'custom',\n label: 'Custom',\n description: 'Bespoke SSE chat with structured blocks and prose narrator pass.',\n Component: AiChat\n },\n {\n id: 'vercel',\n label: 'Vercel',\n description: 'Vercel AI SDK chat with native tool loop and data-stream protocol.',\n Component: VercelChat\n }\n];\n\nexport function getChatInterface(id: string): ChatInterfaceDef {\n return chatInterfaces.find((c) => c.id === id) ?? chatInterfaces[0];\n}\n\nexport { AiChat, VercelChat };\nexport { AnswerBlocks, sanitiseBlock, type BlockState } from './answer-blocks';\nexport type { AiChatProps, AiChatSessionSummary } from './types';\n"]}
|