chore: added a plan to add mistral as an option for models
This commit is contained in:
149
MISTRAL_PLAN.md
Normal file
149
MISTRAL_PLAN.md
Normal 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")
|
||||||
Reference in New Issue
Block a user