Parent epic: #1288
When the LLM triggers a content warning (e.g. asking how to do gain-of-function research on SARS-CoV-2), the app shows "The analysis assistant is currently unavailable. Please try again later." with a retry. Changing the subject works fine.
There's no content-refusal handling today: a provider content warning surfaces as an exception and is mapped to a generic error (assistant.py:91-96 → 503/500), which the frontend renders as the catch-all unavailable/retry message (useAssistantChat.ts:175).
Instead, detect content-policy refusals and respond with a polite message that the topic is outside BRC Analytics' domain, pointing the user to how to use the assistant — without the "unavailable"/retry framing.
Acceptance criteria
- A content-policy refusal yields a polite in-conversation message explaining the topic is out of scope and how to use BRC Analytics — not an "unavailable"/retry error.
- Normal conversation continues afterward (the refusal doesn't break the session).
Parent epic: #1288
When the LLM triggers a content warning (e.g. asking how to do gain-of-function research on SARS-CoV-2), the app shows "The analysis assistant is currently unavailable. Please try again later." with a retry. Changing the subject works fine.
There's no content-refusal handling today: a provider content warning surfaces as an exception and is mapped to a generic error (
assistant.py:91-96→ 503/500), which the frontend renders as the catch-all unavailable/retry message (useAssistantChat.ts:175).Instead, detect content-policy refusals and respond with a polite message that the topic is outside BRC Analytics' domain, pointing the user to how to use the assistant — without the "unavailable"/retry framing.
Acceptance criteria