chore: added a plan to add mistral as an option for models

This commit is contained in:
2026-02-28 20:22:30 +01:00
parent 15e8d1398a
commit 1fc2003260

149
MISTRAL_PLAN.md Normal file
View File

@@ -0,0 +1,149 @@
# Plan: Add Mistral AI as Alternative Chat Provider
## Context
bDS currently routes all AI chat through the OpenCode Zen gateway (`opencode.ai/zen/v1/...`) with two code paths: Anthropic Messages API and OpenAI-compatible. The user wants Mistral AI added as a direct alternative provider with frontier models that support chat completion, tool use, and vision. Mistral's API is OpenAI-compatible (`api.mistral.ai/v1/chat/completions`), making integration straightforward.
## Target Models
- **Mistral Large 3** (`mistral-large-2512`) - frontier, vision, tools, 40k ctx
- **Mistral Medium 3.1** (`mistral-medium-2508`) - frontier, vision, tools, 40k ctx
- **Mistral Small 3.2** (`mistral-small-2506`) - vision, tools, 128k ctx
## Files to Modify
### 1. `src/main/engine/OpenCodeManager.ts` - Core provider logic
**A. Add Mistral constants** (near lines 23-25)
- `MISTRAL_API_URL = 'https://api.mistral.ai/v1/chat/completions'`
- `MISTRAL_MODELS_URL = 'https://api.mistral.ai/v1/models'`
**B. Add Mistral models to `MODEL_DISPLAY_NAMES`** (lines 28-69)
```
'mistral-large-2512': 'Mistral Large 3'
'mistral-medium-2508': 'Mistral Medium 3.1'
'mistral-small-2506': 'Mistral Small 3.2'
```
**C. Update `detectProvider()`** (lines 1839-1845)
- Add: `if (id.startsWith('mistral') || id.startsWith('ministral')) return 'mistral';`
**D. Add Mistral API key storage**
- New field: `private mistralApiKey: string = ''`
- New methods: `setMistralApiKey()`, `getMistralApiKey()`, `validateMistralApiKey()`
- Load on init from settings key `'mistral_api_key'`
**E. Add Mistral request path in `sendMessage()`**
- Route `provider === 'mistral'` to new `sendMistralRequest()` method
- Similar to OpenAI path but:
- URL: `MISTRAL_API_URL` (direct, not through OpenCode gateway)
- Auth: `Authorization: Bearer ${this.mistralApiKey}`
- No `tool_choice: "required"` — use `"any"` for Mistral's equivalent
- Context budget: 35,000 tokens (vs 150k for OpenCode) for 40k-ctx models, 120k for Small 3.2
**F. Vision format for Mistral**
- In `view_image` tool result handling: use `image_url` format with base64 data URI
- Format: `{ type: 'image_url', image_url: { url: 'data:image/webp;base64,...' } }`
- Same as OpenAI path (Mistral is compatible here)
**G. Update `getAvailableModels()`**
- When Mistral key is set, include Mistral models in returned list
- Add `provider` field to model entries so UI can group them
**H. Update `analyzeMediaImage()`** (lines 2066-2192)
- Support Mistral models for image metadata analysis (title/alt/caption generation)
- When a Mistral model is selected, use Mistral vision format (`image_url` with base64 data URI)
- Route to `api.mistral.ai` with Mistral API key
### 2. `src/main/engine/ChatEngine.ts` - Settings persistence
**A. Add Mistral key helpers**
- `getMistralApiKey()` - read from settings table
- `setMistralApiKey(key)` - persist to settings table
- Settings key: `'mistral_api_key'`
### 3. `src/main/ipc/chatHandlers.ts` - IPC bridge
**A. Add Mistral-specific handlers**
- `chat:setMistralApiKey` - validate + persist Mistral key
- `chat:getMistralApiKey` - return masked key
- `chat:validateMistralApiKey` - test key against Mistral API
**B. Update `chat:getAvailableModels`**
- Include Mistral models when Mistral key is configured
- Return provider info per model
**C. Update `chat:checkReady`**
- Report readiness for both providers independently
### 4. `src/main/shared/electronApi.ts` - Type definitions
**A. Extend `ChatModel` interface**
- Add `provider: 'opencode' | 'mistral'` field (already optional, ensure populated)
**B. Add Mistral IPC methods to `ElectronAPI.chat`**
- `setMistralApiKey(key: string)`
- `getMistralApiKey()`
- `validateMistralApiKey(key: string)`
### 5. `src/renderer/components/SettingsView.tsx` - UI settings
**A. Add Mistral API key section**
- Separate input field for Mistral API key (below OpenCode key)
- Same pattern: masked display, change button, validation on save
**B. Update model selector**
- Group models by provider in dropdown (optgroup: "OpenCode Zen", "Mistral AI")
- Show provider badge next to selected model
### 6. `src/renderer/components/ChatPanel/ChatPanel.tsx` - Chat UI
**A. Update model selector in chat**
- Group by provider in dropdown
- Only show models for configured providers
### 7. Preload/IPC registration
**A. `src/main/ipc/handlers.ts` or preload**
- Register new Mistral IPC channels
- Expose in preload bridge
### 8. MCP Server - `src/main/engine/MCPServer.ts`
- No changes needed — MCP server exposes tools for external AI agents to call; no bDS-side AI runs during MCP requests
## Implementation Order
1. Tests first (per AGENTS.md)
2. Types (`electronApi.ts`)
3. Engine (`OpenCodeManager.ts` — constants, detection, key storage, request path)
4. Persistence (`ChatEngine.ts` — settings helpers)
5. IPC (`chatHandlers.ts` — new handlers)
6. UI (`SettingsView.tsx`, `ChatPanel.tsx` — key input, model grouping)
7. Build verification
## Key Differences to Handle
| Aspect | OpenCode/OpenAI | Mistral |
|--------|----------------|---------|
| Base URL | `opencode.ai/zen/v1/...` | `api.mistral.ai/v1/...` |
| Auth header | `Bearer ${openCodeKey}` | `Bearer ${mistralKey}` |
| Tool choice forced | `"required"` | `"any"` |
| Parallel tools | not set | `parallel_tool_calls: true` |
| Context budget | 150k tokens | 35k (Large/Medium), 120k (Small) |
| Vision format | `image_url` block | `image_url` block (same) |
| Streaming | SSE deltas | SSE deltas (same) |
## Verification
1. Run `npm test` — all existing + new tests pass
2. Run `npm run build` — clean build
3. Manual: set Mistral API key in Settings, verify validation
4. Manual: select Mistral Large 3, send chat message, verify response streams
5. Manual: use `view_image` tool in chat with Mistral model, verify vision works
6. Manual: verify tool calling works (search_posts, list_posts, etc.)
7. Manual: verify OpenCode models still work unchanged
## Resolved Decisions
1. **`analyzeMediaImage()`** — Mistral models will be usable for image metadata analysis
2. **MCP server** — N/A; MCP server only exposes tools, no bDS-side AI runs during MCP requests
3. **Model dropdown grouping** — Use `<optgroup>` labels ("OpenCode Zen", "Mistral AI")