[feat-002] Legal database search with Files and Sources picker
Adds a `legal_search` tool that fans out across four open US legal databases
(CourtListener, GovInfo, Federal Register, eCFR), gated by a new "Files and
Sources" picker on the chat input. Hard gate: when no sources are selected,
the tool isn't in the schema at all.
Backend
- backend/src/lib/legalSearch.ts (new): TS port of work___'s
legal_search_service.py. Promise.allSettled fan-out, 12s per-source
timeouts, graceful degradation when an API key is missing or a source
errors. Includes formatLegalResultsForModel() that produces markdown
links so the model can cite inline.
- chatTools.ts: new LEGAL_TOOLS array (kept separate from always-on TOOLS
so it can be conditionally appended). Dispatch case in runToolCalls
defensively clamps the model's `sources` arg to the user's selection.
runLLMStream takes new `sources?: { legal?: string[] }` param;
conditionally appends LEGAL_TOOLS and a system-prompt line restricting
the model's `sources` arg to the user's selection.
- routes/chat.ts: reads `sources` from request body, passes through.
- .env.example: documents COURTLISTENER_API_TOKEN, GOVINFO_API_KEY (FR +
eCFR are open APIs, no auth).
Frontend
- AddDocButton.tsx → FilesAndSourcesButton.tsx (rename + extend). Trigger
label "Files and sources"; count = attached files + selected sources.
Sectioned popover: existing Upload / Browse + new "US Legal Sources"
section with 4 checkboxes (Court Opinions, Federal Legislation, Federal
Register, Regulations CFR). Default off. Architected so future sections
(Knowledge Base, Integrations, EU/UK Law) drop in without rework.
- ChatInput.tsx: tracks selectedLegalSources, passes to button, includes
in submitted MikeMessage's `sources` field, resets to [] after submit
(per-message-only - no chat-level persistence in v1).
- MikeMessage.sources (transient field, not persisted in history).
- useAssistantChat.ts + mikeApi.streamChat: thread `sources` through to
POST /chat body.
- Renamed prop `hideAddDocButton` → `hideFilesAndSourcesButton`; one
caller updated (project chat page).
Smoke-tested both open APIs (Federal Register + eCFR) end-to-end against
real endpoints - both return real results in <1.5s.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| Repository | nwhitehouse/mike |
|---|---|
| Author | Nick Whitehouse <nick.whitehouse@mccarthyfinch.com> |
| Authored | |
| Parents | 6d2aac9e |
| Stats | 11 files changed , +575 , -30 |
| Part of | Legal database search tool + Files-and-Sources picker |
Capture this commit into my fork
Download a Markdown prompt that tells Claude how to port this
exact commit into your working tree. Run it via
claude -p < capture-commit-6a4ea15e.md
from inside the repo you want the change in.