From fdfad82753aa29e6aaebf05de8a125929a7c38a9 Mon Sep 17 00:00:00 2001 From: SakshiKekre Date: Wed, 13 May 2026 02:01:17 -0700 Subject: [PATCH 1/6] Add "Ask a follow-up" chat drawer on report pages Renders an icon button in ReportActionButtons that opens a Sheet containing an iframe to policyengine-uk-chat. The chat receives the report's scenario as a scenario_context URL param so the assistant knows what report the user is looking at. Opt-in: pass chatScenarioContext to ReportOutputLayout. Without it, no button renders. Defaults to prod chat URL; override with VITE_UK_CHAT_ORIGIN to point at a preview. Co-Authored-By: Claude Opus 4.7 (1M context) --- app/src/components/report/ChatDrawer.tsx | 56 +++++++++++++++++++ .../components/report/ReportActionButtons.tsx | 24 +++++++- .../report-output/ReportOutputLayout.tsx | 16 ++++++ 3 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 app/src/components/report/ChatDrawer.tsx diff --git a/app/src/components/report/ChatDrawer.tsx b/app/src/components/report/ChatDrawer.tsx new file mode 100644 index 000000000..3fdb07b69 --- /dev/null +++ b/app/src/components/report/ChatDrawer.tsx @@ -0,0 +1,56 @@ +/** + * ChatDrawer — slide-out panel that embeds policyengine-uk-chat as an iframe, + * seeded with the report scenario the user is currently viewing. + * + * The chat reads `?scenario_context=` from its URL and forwards it to its + * /chat/message backend, so the assistant knows what the user just saw + * without us having to copy/parse report data into a structured payload. + */ +import { Sheet, SheetContent, SheetHeader, SheetTitle } from '@/components/ui/sheet'; + +interface ChatDrawerProps { + open: boolean; + onOpenChange: (open: boolean) => void; + /** Plain-English summary of the scenario + headline figures. Forwarded + * to the chat as system-prompt context. */ + scenarioContext: string; +} + +const CHAT_ORIGIN = + import.meta.env.VITE_UK_CHAT_ORIGIN || 'https://policyengine-uk-chat.vercel.app'; + +function buildChatUrl(scenarioContext: string): string { + const params = new URLSearchParams({ scenario_context: scenarioContext }); + // model_backend=uk_python so the chat runs against the same Python engine + // app-v2's reports use — needed for chat numbers to be comparable to the + // report numbers the user is looking at. + params.set('model_backend', 'uk_python'); + return `${CHAT_ORIGIN}/?${params.toString()}`; +} + +export function ChatDrawer({ open, onOpenChange, scenarioContext }: ChatDrawerProps) { + return ( + + + + Ask a follow-up + + {open && ( +