## 1. Example Folder Structure - [x] 1.1 Create directory structure: `examples/extraction/few-shot/` and `examples/extraction/evaluation/` - [x] 1.2 Add placeholder example `01/` with `input.html` (sample email HTML) and `output.json` (sample ExtractionResult JSON matching TradeItem schema). Use realistic but anonymized data. - [x] 1.3 Add placeholder example `02/` with a different email pattern (e.g., single swap, different currency) - [x] 1.4 Add placeholder example `03/` with an edge case (e.g., breakclause = "Y", or unusual counterparty name) ## 2. Instruction Template - [x] 2.1 Create `examples/extraction/instruction-template.txt` with the fixed extraction system prompt: task description, TradeItem schema definition (all 7 fields with types), mapping rules (date parsing, leg flattening, currency symbol → ISO code, breakclause default), and expected JSON output format ## 3. FewShotService - [x] 3.1 Create `FewShotService.cs` in the API project — constructor loads instruction template and all few-shot examples from disk, assembles a ChatHistory prefix (system message + alternating user/assistant turns) - [x] 3.2 Add `CloneWithEmail(string emailHtml)` method that clones the cached ChatHistory prefix and appends the email as a user message - [x] 3.3 Add `CloneWithEmailAndMessages(string emailHtml, List messages)` method for follow-up disambiguation requests — clones prefix, appends email, appends follow-up messages - [x] 3.4 Register `FewShotService` as singleton in `Program.cs` - [x] 3.5 Add `Examples:FewShotPath` configuration in `appsettings.json` pointing to the examples folder ## 4. ExtractionRequest DTO - [x] 4.1 Create `ExtractionRequest.cs` in Shared/Models with `EmailHtml` (string, required) and `Messages` (List, optional) ## 5. Extraction Endpoint - [x] 5.1 Add `Extract` action to `ChatController` (or new `ExtractionController`) — `POST /api/chat/extract` accepting `ExtractionRequest` - [x] 5.2 In the Extract action: get ChatHistory from `FewShotService.CloneWithEmail()` or `CloneWithEmailAndMessages()` based on whether Messages are present - [x] 5.3 Import extraction-specific plugins only (not general chat plugins) - [x] 5.4 Stream response via SSE using the same format as the existing chat endpoint - [x] 5.5 Update `ChatApiClient` on the client side — add `SendExtractionStreamingAsync(ExtractionRequest request)` method mirroring the existing streaming pattern ## 6. Build and Verify - [x] 6.1 Build the solution (`dotnet build`) and confirm no compilation errors - [x] 6.2 Run all tests (`dotnet test`) and confirm they pass - [x] 6.3 Add unit test for `FewShotService` — verify it loads examples and assembles correct ChatHistory structure (message count, roles, ordering)