nwhitehouse pulls search results out of the activity log and into the answer

When the model returns sources but little prose, the sources now show up as the answer instead of hiding behind a 'completed in steps' toggle.

searchchat-ui

nwhitehouse's fork now treats every result from a legal or web search as a reference card in its own right - a title, where it came from (CourtListener and Federal Register for case law and rulings, plain web for the rest), a date, and a snippet, each linking out to the source. The cards stream in as they're found rather than waiting for the assistant to finish thinking.

The more interesting move is the bug fix behind it. Those cards were being tucked inside a collapsible disclosure, so on multi-source research questions - where the model often hands back citations but thin write-up - the user saw an empty-looking reply unless they manually expanded it. The fix breaks references out into the main conversation, on the candid logic that the sources are the answer when the model under-explains.

So what Worth a look for anyone building a research or search-backed chat tool who wants citations treated as results, not buried in a tool-activity log.

View this fork on GitHub →

Spotted something wrong? Or know the PR text has fresher detail than the writeup above?

Commits in this thread

2 commits from nwhitehouse/mike, oldest first. Source extracted verbatim from the harvested git log.

SHA Subject Author Date
e7f59072 [feat-004] References inline display Nick Whitehouse 2026-05-04 ↗ GitHub
commit body
Surfaces every legal_search and web_search result as a clickable card in
the assistant message, decoupling source-link visibility from Olava's
synthesis. Even when the model under-summarises (which it does because
it's a small reasoning model), the user sees every source and can click
through.

Backend
- chatTools.ts: new ReferenceResult type, accumulated by runToolCalls,
  returned alongside docsRead/docsCreated/etc. legal_search and
  web_search dispatch cases push one ReferenceResult per result and
  emit a "reference_added" SSE event for each (live streaming so cards
  appear as soon as fetched).
- runLLMStream's runTools callback iterates references and pushes
  reference_added events into the assistant message's events array, so
  reloading a chat keeps the cards visible.
- Backend AssistantEvent union extended with reference_added shape.

Frontend
- types.ts: AssistantEvent union extended to mirror the backend shape.
- useAssistantChat.ts: handles reference_added SSE events live.
- AssistantMessage.tsx: new ReferenceBlock card component (title +
  source label + date + snippet, blue dot connector, hover state,
  opens URL in new tab). Dispatch case interleaves cards
  chronologically with content and other tool events.

Same card style works for both legal and web sources - feat-005's
multi-pass orchestrator will produce many of these per turn and they'll
all render with one component.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
3785d7f2 [bug-003] Render references outside the collapsible step wrapper Nick Whitehouse 2026-05-04 ↗ GitHub
commit body
feat-004's reference_added events were getting grouped into the
PreResponseWrapper alongside other tool chatter, which collapses to
"Completed in N steps" by default. References were invisible until the
user expanded the disclosure - which is exactly backwards: references
ARE the answer when Olava under-synthesises (which it does on
multi-source research queries; see Lawyer Tech Misuse Case test where
Olava emitted only "\n\n" three times alongside 11 web references).

Fix: extend the EventGroup discriminated union with a "reference" kind
that breaks the pre-wrapper just like content does. Reference cards
now render inline at top level, never hidden behind a disclosure.

Verified against the chat that motivated the fix - same 11 references
will now render as cards instead of collapsing into "Completed in 5
steps" wrappers. Synthesis quality (Olava emitting empty content) is a
separate problem addressed by feat-005.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

Capture this thread into my fork

Download a single Markdown prompt that tells Claude how to port every commit above into your working tree — adapting paths and structure to match your repo. Run it via claude -p < capture-thread-123.md from inside the repo you want the changes in.

⬇ Download capture-thread-123.md