mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-01-31 20:03:37 +00:00
- Added CursorProvider to the ProviderFactory for handling cursor-* models. - Updated getProviderNameForModel method to determine the appropriate provider based on model identifiers. - Enhanced getAllProviders method to return both ClaudeProvider and CursorProvider. - Updated documentation to reflect the completion of the Provider Factory integration phase.
6.2 KiB
6.2 KiB
Phase 3: Provider Factory Integration
Status: completed
Dependencies: Phase 2 (Provider)
Estimated Effort: Small (routing logic only)
Objective
Integrate CursorProvider into the ProviderFactory so models are automatically routed to the correct provider.
Tasks
Task 3.1: Update Provider Factory
Status: completed
File: apps/server/src/providers/provider-factory.ts
Add Cursor provider import and routing:
import { CursorProvider } from './cursor-provider';
import { CURSOR_MODEL_MAP } from '@automaker/types';
export class ProviderFactory {
/**
* Determine which provider to use for a given model
*/
static getProviderNameForModel(model: string): 'claude' | 'cursor' {
const lowerModel = model.toLowerCase();
// Check for explicit cursor prefix
if (lowerModel.startsWith('cursor-')) {
return 'cursor';
}
// Check if it's a known Cursor model ID
const cursorModelId = lowerModel.replace('cursor-', '');
if (cursorModelId in CURSOR_MODEL_MAP) {
return 'cursor';
}
// Check for Cursor-specific patterns
if (
lowerModel === 'auto' ||
lowerModel.includes('gpt-') ||
lowerModel.includes('gemini-') ||
lowerModel === 'o3-mini'
) {
// These could be Cursor models, but we default to Claude
// unless explicitly prefixed with cursor-
}
// Check for Claude model patterns
if (
lowerModel.startsWith('claude-') ||
['opus', 'sonnet', 'haiku'].some((n) => lowerModel.includes(n))
) {
return 'claude';
}
// Default to Claude
return 'claude';
}
/**
* Get a provider instance for the given model
*/
static getProviderForModel(model: string, config?: ProviderConfig): BaseProvider {
const providerName = this.getProviderNameForModel(model);
if (providerName === 'cursor') {
return new CursorProvider(config);
}
return new ClaudeProvider(config);
}
/**
* Get all registered providers
*/
static getAllProviders(): BaseProvider[] {
return [new ClaudeProvider(), new CursorProvider()];
}
/**
* Get a provider by name
*/
static getProviderByName(name: string): BaseProvider | null {
const lowerName = name.toLowerCase();
switch (lowerName) {
case 'claude':
return new ClaudeProvider();
case 'cursor':
return new CursorProvider();
default:
return null;
}
}
/**
* Check installation status of all providers
*/
static async checkAllProviders(): Promise<Record<string, InstallationStatus>> {
const providers = this.getAllProviders();
const statuses: Record<string, InstallationStatus> = {};
await Promise.all(
providers.map(async (provider) => {
const status = await provider.detectInstallation();
statuses[provider.getName()] = status;
})
);
return statuses;
}
/**
* Get all available models from all providers
*/
static getAllAvailableModels(): ModelDefinition[] {
const providers = this.getAllProviders();
return providers.flatMap((p) => p.getAvailableModels());
}
}
Task 3.2: Export CursorProvider
Status: completed
File: apps/server/src/providers/index.ts
Add export:
export { CursorProvider, CursorErrorCode, CursorError } from './cursor-provider';
export { CursorConfigManager } from './cursor-config-manager';
Verification
Test 1: Model Routing
import { ProviderFactory } from './apps/server/src/providers/provider-factory';
// Cursor models
console.assert(ProviderFactory.getProviderNameForModel('cursor-auto') === 'cursor');
console.assert(ProviderFactory.getProviderNameForModel('cursor-gpt-4o') === 'cursor');
console.assert(ProviderFactory.getProviderNameForModel('cursor-claude-sonnet-4') === 'cursor');
// Claude models (default)
console.assert(ProviderFactory.getProviderNameForModel('claude-sonnet-4') === 'claude');
console.assert(ProviderFactory.getProviderNameForModel('opus') === 'claude');
console.assert(ProviderFactory.getProviderNameForModel('sonnet') === 'claude');
console.assert(ProviderFactory.getProviderNameForModel('haiku') === 'claude');
// Unknown models default to Claude
console.assert(ProviderFactory.getProviderNameForModel('unknown-model') === 'claude');
console.log('All routing tests passed!');
Test 2: Provider Instantiation
import { ProviderFactory } from './apps/server/src/providers/provider-factory';
const cursorProvider = ProviderFactory.getProviderForModel('cursor-auto');
console.assert(cursorProvider.getName() === 'cursor');
const claudeProvider = ProviderFactory.getProviderForModel('sonnet');
console.assert(claudeProvider.getName() === 'claude');
console.log('Provider instantiation tests passed!');
Test 3: All Providers Check
import { ProviderFactory } from './apps/server/src/providers/provider-factory';
const statuses = await ProviderFactory.checkAllProviders();
console.log('Provider statuses:', statuses);
// Should have both 'claude' and 'cursor' keys
const allModels = ProviderFactory.getAllAvailableModels();
console.log('Total models:', allModels.length);
// Should include models from both providers
Verification Checklist
Before marking this phase complete:
- ProviderFactory routes
cursor-*models to CursorProvider - ProviderFactory routes Claude models to ClaudeProvider
getAllProviders()returns both providersgetProviderByName('cursor')returns CursorProvidercheckAllProviders()returns status for both providersgetAllAvailableModels()includes Cursor models- Existing Claude routing not broken
Files Changed
| File | Action | Description |
|---|---|---|
apps/server/src/providers/provider-factory.ts |
Modify | Add Cursor routing |
apps/server/src/providers/index.ts |
Modify | Export CursorProvider |
Notes
- Model routing uses prefix matching for explicit
cursor-models - Unknown models default to Claude for backward compatibility
- The factory is stateless - new provider instances created per call