Overhaul extraction pipeline with new TradeItem model, conversation flow, and dedicated extraction endpoint. Add sidebar navigation with NavMenu component and landing page. Introduce few-shot prompting service and tests. Add prompt settings and email upload specs. Update OpenSpec tooling with improved export-spec and extract-feature commands. Archive completed changes and export full specs. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
64 lines
4.1 KiB
Markdown
64 lines
4.1 KiB
Markdown
## Context
|
|
|
|
The extraction endpoint (`POST /api/chat/extract`) and few-shot prompting infrastructure exist on the backend. The client needs a way to trigger extraction by uploading email files and then handle the multi-turn extraction conversation (disambiguation, result presentation).
|
|
|
|
The current Chat.razor has a text input with send button and Enter key handling. The extraction flow adds a new input modality (file drop) and conversation mode tracking.
|
|
|
|
## Goals / Non-Goals
|
|
|
|
**Goals:**
|
|
- Enable email file upload via drag-and-drop and file picker
|
|
- Route uploaded emails to the extraction endpoint
|
|
- Support disambiguation follow-up within the same conversation
|
|
- Present extraction results clearly in the chat stream
|
|
|
|
**Non-Goals:**
|
|
- .msg file parsing (MVP accepts .html only — users save emails as HTML first)
|
|
- Structured result UI (tables, editable fields) — the agent streams formatted text/markdown
|
|
- Offline/batch extraction of multiple emails
|
|
- Email preview or parsing on the client before sending to the API
|
|
|
|
## Decisions
|
|
|
|
### 1. Drag-and-drop on the message area, not a separate upload zone
|
|
|
|
**Decision:** The entire chat message area (`.message-list`) acts as the drop target, with visual feedback when a file is dragged over.
|
|
|
|
**Why:** Drag-and-drop onto the conversation area is the natural gesture — it mirrors how you'd "give" a document to someone in a chat. A separate upload widget adds visual clutter.
|
|
|
|
**Alternative considered:** Dedicated upload zone above the input area. Rejected — takes permanent screen space for an occasional action.
|
|
|
|
### 2. HTML files only for MVP
|
|
|
|
**Decision:** Accept `.html` files only. Do not support `.msg` parsing in this change.
|
|
|
|
**Why:** .msg is a proprietary Microsoft format requiring either a server-side library (like MsgReader) or a JS parser. HTML is what Outlook "Save As" produces and is trivially read via the File API. Supporting .msg can be a follow-up change.
|
|
|
|
### 3. Conversation mode tracking with `_isExtractionMode`
|
|
|
|
**Decision:** Add a boolean `_isExtractionMode` flag to Chat.razor. When an email is uploaded, set it to `true`. All subsequent `SendMessage()` calls route to the extraction endpoint (passing the original email HTML + growing message list). "New Chat" resets to `false`.
|
|
|
|
**Why:** After initial extraction, the user needs to reply to disambiguation questions. Those replies must go to the extraction endpoint with full context, not the general chat endpoint. The mode flag is the simplest routing mechanism.
|
|
|
|
**Alternative considered:** Separate extraction page/component. Rejected — breaks the conversational flow and duplicates the chat UI.
|
|
|
|
### 4. File reading via Blazor JS interop
|
|
|
|
**Decision:** Use `InputFile` component or JavaScript interop with the File API to read the dropped file's text content. Send the HTML string to the extraction endpoint.
|
|
|
|
**Why:** Blazor WASM has `InputFile` for file picker but drag-and-drop requires JS interop for the `drop` event. We need both: `InputFile` for the button, JS interop for drag-and-drop.
|
|
|
|
### 5. Agent streams results as markdown, no special result UI
|
|
|
|
**Decision:** The extraction agent's response (including the final JSON table) streams as markdown rendered by the existing rich text display. No special result component.
|
|
|
|
**Why:** The rich text rendering already handles tables, code blocks, and formatted output. The agent naturally presents results as a markdown table. A structured result component adds complexity without clear UX benefit at this stage.
|
|
|
|
## Risks / Trade-offs
|
|
|
|
**[Large email files]** → HTML emails with embedded images can be large. Mitigation: the API receives the HTML string only — embedded images are base64 in the HTML and the LLM will ignore them. If size becomes an issue, strip image tags client-side before sending.
|
|
|
|
**[Mode confusion]** → User may not realize they're in extraction mode. Mitigation: show a visual indicator (e.g., chip or banner) when `_isExtractionMode` is true, and include "New Chat" to reset.
|
|
|
|
**[Drop event handling in Blazor]** → Blazor's built-in event handling for drag-and-drop is limited. Mitigation: use a small JS interop function for the drop handler that reads the file and calls back into .NET.
|