File size: 10,598 Bytes
1dbc34b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 | # Claude Compatible Providers System
This document describes the implementation of Claude Compatible Providers, allowing users to configure alternative API endpoints that expose Claude-compatible models to the application.
## Overview
Claude Compatible Providers allow Automaker to work with third-party API endpoints that implement Claude's API protocol. This enables:
- **Cost savings**: Use providers like z.AI GLM or MiniMax at lower costs
- **Alternative models**: Access models like GLM-4.7 or MiniMax M2.1 through familiar interfaces
- **Flexibility**: Configure per-phase model selection to optimize for speed vs quality
- **Project overrides**: Use different providers for different projects
## Architecture
### Type Definitions
#### ClaudeCompatibleProvider
```typescript
export interface ClaudeCompatibleProvider {
id: string; // Unique identifier (UUID)
name: string; // Display name (e.g., "z.AI GLM")
baseUrl: string; // API endpoint URL
providerType?: string; // Provider type for icon/grouping (e.g., 'glm', 'minimax', 'openrouter')
apiKeySource?: ApiKeySource; // 'inline' | 'env' | 'credentials'
apiKey?: string; // API key (when apiKeySource = 'inline')
useAuthToken?: boolean; // Use ANTHROPIC_AUTH_TOKEN header
timeoutMs?: number; // Request timeout in milliseconds
disableNonessentialTraffic?: boolean; // Minimize non-essential API calls
enabled?: boolean; // Whether provider is active (default: true)
models?: ProviderModel[]; // Models exposed by this provider
}
```
#### ProviderModel
```typescript
export interface ProviderModel {
id: string; // Model ID sent to API (e.g., "GLM-4.7")
displayName: string; // Display name in UI (e.g., "GLM 4.7")
mapsToClaudeModel?: ClaudeModelAlias; // Which Claude tier this replaces ('haiku' | 'sonnet' | 'opus')
capabilities?: {
supportsVision?: boolean; // Whether model supports image inputs
supportsThinking?: boolean; // Whether model supports extended thinking
maxThinkingLevel?: ThinkingLevel; // Maximum thinking level if supported
};
}
```
#### PhaseModelEntry
Phase model configuration now supports provider models:
```typescript
export interface PhaseModelEntry {
providerId?: string; // Provider ID (undefined = native Claude)
model: string; // Model ID or alias
thinkingLevel?: ThinkingLevel; // 'none' | 'low' | 'medium' | 'high'
}
```
### Provider Templates
Available provider templates in `CLAUDE_PROVIDER_TEMPLATES`:
| Template | Provider Type | Base URL | Description |
| ---------------- | ------------- | ------------------------------------ | ----------------------------- |
| Direct Anthropic | anthropic | `https://api.anthropic.com` | Standard Anthropic API |
| OpenRouter | openrouter | `https://openrouter.ai/api` | Access Claude and 300+ models |
| z.AI GLM | glm | `https://api.z.ai/api/anthropic` | GLM models at lower cost |
| MiniMax | minimax | `https://api.minimax.io/anthropic` | MiniMax M2.1 model |
| MiniMax (China) | minimax | `https://api.minimaxi.com/anthropic` | MiniMax for China region |
### Model Mappings
Each provider model specifies which Claude model tier it maps to via `mapsToClaudeModel`:
**z.AI GLM:**
- `GLM-4.5-Air` β haiku
- `GLM-4.7` β sonnet, opus
**MiniMax:**
- `MiniMax-M2.1` β haiku, sonnet, opus
**OpenRouter:**
- `anthropic/claude-3.5-haiku` β haiku
- `anthropic/claude-3.5-sonnet` β sonnet
- `anthropic/claude-3-opus` β opus
## Server-Side Implementation
### API Key Resolution
The `buildEnv()` function in `claude-provider.ts` resolves API keys based on `apiKeySource`:
```typescript
function buildEnv(
providerConfig?: ClaudeCompatibleProvider,
credentials?: Credentials
): Record<string, string | undefined> {
if (providerConfig) {
let apiKey: string | undefined;
const source = providerConfig.apiKeySource ?? 'inline';
switch (source) {
case 'inline':
apiKey = providerConfig.apiKey;
break;
case 'env':
apiKey = process.env.ANTHROPIC_API_KEY;
break;
case 'credentials':
apiKey = credentials?.apiKeys?.anthropic;
break;
}
// ... build environment with resolved key
}
}
```
### Provider Lookup
The `getProviderByModelId()` helper resolves provider configuration from model IDs:
```typescript
export async function getProviderByModelId(
modelId: string,
settingsService: SettingsService,
logPrefix?: string
): Promise<{
provider?: ClaudeCompatibleProvider;
resolvedModel?: string;
credentials?: Credentials;
}>;
```
This is used by all routes that call the Claude SDK to:
1. Check if the model ID belongs to a provider
2. Get the provider configuration (baseUrl, auth, etc.)
3. Resolve the `mapsToClaudeModel` for the SDK
### Phase Model Resolution
The `getPhaseModelWithOverrides()` helper gets effective phase model config:
```typescript
export async function getPhaseModelWithOverrides(
phaseKey: PhaseModelKey,
settingsService: SettingsService,
projectPath?: string,
logPrefix?: string
): Promise<{
model: string;
thinkingLevel?: ThinkingLevel;
providerId?: string;
providerConfig?: ClaudeCompatibleProvider;
credentials?: Credentials;
}>;
```
This handles:
1. Project-level overrides (if projectPath provided)
2. Global phase model settings
3. Default fallback models
## UI Implementation
### Model Selection Dropdowns
Phase model selectors (`PhaseModelSelector`) display:
1. **Claude Models** - Native Claude models (Haiku, Sonnet, Opus)
2. **Provider Sections** - Each enabled provider as a separate group:
- Section header: `{provider.name} (via Claude)`
- Models with their mapped Claude tiers: "Maps to Haiku, Sonnet, Opus"
- Thinking level submenu for models that support it
### Provider Icons
Icons are determined by `providerType`:
- `glm` β Z logo
- `minimax` β MiniMax logo
- `openrouter` β OpenRouter logo
- Generic β OpenRouter as fallback
### Bulk Replace
The "Bulk Replace" feature allows switching all phase models to a provider at once:
1. Select a provider from the dropdown
2. Preview shows which models will be assigned:
- haiku phases β provider's haiku-mapped model
- sonnet phases β provider's sonnet-mapped model
- opus phases β provider's opus-mapped model
3. Apply replaces all phase model configurations
The Bulk Replace button only appears when at least one provider is enabled.
## Project-Level Overrides
Projects can override global phase model settings via `phaseModelOverrides`:
```typescript
interface Project {
// ...
phaseModelOverrides?: PhaseModelConfig; // Per-phase overrides
}
```
### Storage
Project overrides are stored in `.automaker/settings.json`:
```json
{
"phaseModelOverrides": {
"enhancementModel": {
"providerId": "provider-uuid",
"model": "GLM-4.5-Air",
"thinkingLevel": "none"
}
}
}
```
### Resolution Priority
1. Project override for specific phase (if set)
2. Global phase model setting
3. Default model for phase
## Migration
### v5 β v6 Migration
The system migrated from `claudeApiProfiles` to `claudeCompatibleProviders`:
```typescript
// Old: modelMappings object
{
modelMappings: {
haiku: 'GLM-4.5-Air',
sonnet: 'GLM-4.7',
opus: 'GLM-4.7'
}
}
// New: models array with mapsToClaudeModel
{
models: [
{ id: 'GLM-4.5-Air', displayName: 'GLM 4.5 Air', mapsToClaudeModel: 'haiku' },
{ id: 'GLM-4.7', displayName: 'GLM 4.7', mapsToClaudeModel: 'sonnet' },
{ id: 'GLM-4.7', displayName: 'GLM 4.7', mapsToClaudeModel: 'opus' },
]
}
```
The migration is automatic and preserves existing provider configurations.
## Files Changed
### Types
| File | Changes |
| ---------------------------- | -------------------------------------------------------------------- |
| `libs/types/src/settings.ts` | `ClaudeCompatibleProvider`, `ProviderModel`, `PhaseModelEntry` types |
| `libs/types/src/provider.ts` | `ExecuteOptions.claudeCompatibleProvider` field |
| `libs/types/src/index.ts` | Exports for new types |
### Server
| File | Changes |
| ---------------------------------------------- | -------------------------------------------------------- |
| `apps/server/src/providers/claude-provider.ts` | Provider config handling, buildEnv updates |
| `apps/server/src/lib/settings-helpers.ts` | `getProviderByModelId()`, `getPhaseModelWithOverrides()` |
| `apps/server/src/services/settings-service.ts` | v5βv6 migration |
| `apps/server/src/routes/**/*.ts` | Provider lookup for all SDK calls |
### UI
| File | Changes |
| -------------------------------------------------- | ----------------------------------------- |
| `apps/ui/src/.../phase-model-selector.tsx` | Provider model rendering, thinking levels |
| `apps/ui/src/.../bulk-replace-dialog.tsx` | Bulk replace feature |
| `apps/ui/src/.../api-profiles-section.tsx` | Provider management UI |
| `apps/ui/src/components/ui/provider-icon.tsx` | Provider-specific icons |
| `apps/ui/src/hooks/use-project-settings-loader.ts` | Load phaseModelOverrides |
## Testing
```bash
# Build and run
npm run build:packages
npm run dev:web
# Run server tests
npm run test:server
```
### Test Cases
1. **Provider setup**: Add z.AI GLM provider with inline API key
2. **Model selection**: Select GLM-4.7 for a phase, verify it appears in dropdown
3. **Thinking levels**: Select thinking level for provider model
4. **Bulk replace**: Switch all phases to a provider at once
5. **Project override**: Set per-project model override, verify it persists
6. **Provider deletion**: Delete all providers, verify empty state persists
## Future Enhancements
Potential improvements:
1. **Provider validation**: Test API connection before saving
2. **Usage tracking**: Show which phases use which provider
3. **Cost estimation**: Display estimated costs per provider
4. **Model capabilities**: Auto-detect supported features from provider
|