Declines self-harm and harm-to-others requests by intent while answering
toxicology; dense + BM25 search fused by RRF over aria_medical_v2 with
rerank-v5.0-fast; transient retries, Judge JSON mode, startup warm-up;
citations show printed page numbers.
Passages are numbered end to end so every claim is cited inline; follow-up
questions are resolved against the conversation; chapter bibliographies and
index pages are dropped before reranking; the answer badge reports how well
grounded an answer is rather than claiming a GRADE certainty. Dependencies
are pinned.
Fix stray markup in answers; report retrieval failures honestly
Two fixes from the recent outage and the rendering reports.
Renderer: thematic breaks (---) printed as a row of hyphens, backslash
escapes printed the backslash (\*All doses...), and <br> emitted inside
table cells printed the tag. All three now render properly, stray inline
tags are dropped while keeping their text, and characters Spectral cannot
draw — subscripts, narrow no-break space, non-breaking hyphen — are folded
to plain equivalents so no tofu boxes land mid-sentence. "eGFR <30" and
existing bold/italic/tables/citations are unaffected.
Backend: a dead vector store reported itself as "failed to reach the
language model", pointing diagnosis at a healthy dependency; it now names
the reference library. An empty retrieval raises instead of handing the
generator an empty context to answer from memory. /api/health probes the
collection and returns 503 unless it is reachable, present and non-empty,
rather than reporting "ok" through a total outage. The dev-only sample
answers can no…
Fix Groq model outage; make provider failures a distinct error state
Groq decommissioned llama-3.3-70b-versatile, which every agent shared via a
single hardcoded get_llm(). Each query returned a 404 that the API then
streamed to the browser as answer prose, so the UI decorated a provider
error with a "MODERATE CERTAINTY" evidence badge and a "grounded reply"
byline.
Model IDs are now centralised in llm/config.py, resolved per role from
ARIA_*_MODEL env vars with live defaults verified against Groq's model list
(generator openai/gpt-oss-120b, everything else openai/gpt-oss-20b). No
Space secrets are required — the defaults work as-is.
Provider failures get their own type and their own SSE `error` event that
carries no confidence, no evidence tier and no citations, and never travels
on the `token` channel the UI renders as an answer. An unreachable guardrail
no longer defaults to "in scope", and a judge that fails or returns
unparseable JSON yields confidence=null, shown as "Not adjudicated", instead
of a placeholder 0.5 on a real gauge.
A startup pref…
UI: replace the landing epigraph with a statement of principle
The opening line recited the pipeline and named the corpus before the reader
had asked anything. It now reads: "Every claim carries its source. Every
answer, its reasoning." The corpus and pipeline still surface per answer, in
the source rail and instrument row.
UI: rebuild the answer view as a chat interface, responsive to mobile
Answers were typeset as a fresh journal article each time — headline, drop cap,
boxed method figure, margin classification, bibliography. The journal identity
stays; the per-answer article furniture goes.
The transcript now scrolls inside one framed sheet with the composer docked at
its foot. The agent pipeline runs as a live thinking strip that folds into a
"Reasoned in 4.2s" receipt; evidence tier, Judge confidence and sources sit in
one instrument row; citations expand their retrieved passage inline.
Same build on mobile: the shell sizes from the visual viewport so the iOS
keyboard lifts the composer, the reply gutter collapses so prose keeps the full
line, and touch targets, type sizes and safe-area insets are handled.