dropthejase makes Louis think out loud

A run of streaming-interface work that lets users watch the assistant reason in real time and cleans up the small visual glitches that came with it.

chat-ui

dropthejase has been polishing how the chat actually feels to use. The headline change: the assistant now streams its reasoning as it works, with a live "thinking" indicator and expandable blocks that show the model's chain of thought before it answers. For anyone using a legal assistant on a real matter, seeing the reasoning unfold builds trust in a way a bare answer never does.

The rest is the unglamorous craft that separates a demo from a product. Tool actions no longer flicker or pop back open as a response finishes, edit cards vanish cleanly once you accept or reject them, and a shared message view now powers both the main chat and project pages so they behave identically. There's also a small fix so short or unclear prompts get a sensible chat title instead of a cryptic one.

So what Anyone evaluating Louis as a day-to-day legal assistant should care: this is the work that makes the interface feel reliable rather than experimental.

View this fork on GitHub →

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

Commits in this thread

17 commits from dropthejase/louis, oldest first. Source extracted verbatim from the harvested git log.

SHA Subject Author Date
2b301415 fix(sidebar): always navigate to /assistant after chat delete Jason Lee 2026-05-12 ↗ GitHub
37c8b1d5 fix(chat): fallback to dated title when LLM returns unhelpful generate-title response; update FEATURE-PARITY Jason Lee 2026-05-12 ↗ GitHub
51d7f384 fix(AssistantChatPage): remove 2s timeout redirect for empty messages Jason Lee 2026-05-12 ↗ GitHub
Page now shows loading state indefinitely; API returns error if chat
truly doesn't exist rather than silently redirecting.
acba2e4f fix(edit-document): align annotation field names with MikeEditAnnotation type Jason Lee 2026-05-12 ↗ GitHub
Rename id→edit_id, del_id→del_w_id, ins_id→ins_w_id so EditCard
accept/reject URLs resolve correctly instead of hitting /edits/undefined/accept.
3206edf0 fix(agent): resolve read_document spinner stuck forever Jason Lee 2026-05-12 ↗ GitHub
commit body
doc_read_start emits real filename; afterToolCallEvent was emitting
filename from result.filename which is always empty (read_document
returns plain text not JSON). Now looks up filename from docIndex
using the tool input doc_id, matching what the start event used.
256b41ba feat(frontend): cycle thinking phrases randomly in ReasoningBlock and ThinkingBlock Jason Lee 2026-05-12 ↗ GitHub
7eca5fd2 feat(agents): enable extended thinking, disable printer, add reasoning SSE events and stream logging Jason Lee 2026-05-12 ↗ GitHub
ee1668eb fix(frontend): collapse tool card immediately when trailing content event is still streaming Jason Lee 2026-05-13 ↗ GitHub
cbd9640d refactor(frontend): extract MessageList shared component for chat message rendering Jason Lee 2026-05-13 ↗ GitHub
commit body
Both ChatView and ProjectChatPage now use MessageList. Edit resolution state
(resolvedEditStatuses, reloadingEditIds) lives in MessageList - ProjectChatPage
no longer has a no-op handleEditResolved stub, so Accept/Reject cards now
collapse correctly in Project Chat.
f99b111a fix(frontend): widen MessageList ref types to accept null Jason Lee 2026-05-13 ↗ GitHub
9afbe9d4 fix(frontend): collapse edit cards on resolve; fix tool card bleed in Project Chat Jason Lee 2026-05-13 ↗ GitHub
commit body
- EditCard returns null when resolved (accepted or rejected)
- EditCardsSection auto-collapses via useEffect when all pending edits resolve
- ProjectChatPage defers getProject refetch to after stream completes to
  prevent mid-stream setProject re-renders that pop tool cards back open
95ff93fc fix(frontend): remove unreachable Accepted/Rejected button labels after early return Jason Lee 2026-05-13 ↗ GitHub
dc7aa1d1 feat(frontend): extract MessageList component; fix edit card collapse and tool card bleed Jason Lee 2026-05-13 ↗ GitHub
af49112e fix(frontend): derive PreResponseWrapper isOpen from props during streaming to eliminate tool card bleed Jason Lee 2026-05-13 ↗ GitHub
4dd0b8a7 fix(frontend): use context deleteChat in ProjectChatPage so sidebar updates immediately on chat deletion Jason Lee 2026-05-13 ↗ GitHub
f757bc84 fix(streaming): prevent tool_call_start from splitting mid-sentence content blocks Jason Lee 2026-05-15 ↗ GitHub
commit body
Two bugs caused the tool-use accordion to appear mid-sentence:
1. tool_call_start incorrectly called pushEvent(), which finalized the
   in-flight content block prematurely before the text was complete.
2. finalizeStreamingContent() only checked the last event; after fix 1
   the last event is the tool_call_start placeholder, so the streaming
   content block (second-to-last) was never committed and the drip text
   was lost.

Fix 1: tool_call_start bypasses pushEvent() and appends the placeholder
directly, leaving the content block open.
Fix 2: finalizeStreamingContent() scans backwards through the event array
to find the streaming content block regardless of its position.
e25bfd80 Merge feature/fix-tool-call-streaming into development Jason Lee 2026-05-15 ↗ GitHub
Fixes tool-use accordion appearing mid-sentence during streaming responses.

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-346.md from inside the repo you want the changes in.

⬇ Download capture-thread-346.md