Currently supported: gemini, openai, codestral, ollama.
Adding a new provider requires changes in 7 areas. The examples below use anthropic.
Reference implementations: Before starting, read an existing service —
src/services/openaiService.tsis the best reference for HTTP-based providers. For providers that expose a model listing API (like Gemini), also look atsrc/services/geminiService.tsand theIModelServiceinterface insrc/models/types.ts.
Create a new service file. Use an existing service as a reference (e.g., openaiService.ts for HTTP-based APIs).
Your service must implement the IAIService interface from src/models/types.ts:
import { CommitMessage, ProgressReporter } from '../models/types';
import { BaseAIService } from './baseAIService';
import { ConfigService } from '../utils/configService';
export class AnthropicService {
static async generateCommitMessage(
prompt: string,
progress: ProgressReporter,
attempt: number = 0
): Promise<CommitMessage> {
// 1. Get config values (model, API key, etc.)
// 2. Make API request
// 3. Use BaseAIService.extractAndValidateMessage() to validate response
// 4. Use BaseAIService.handleHttpError() for error handling
// 5. Return { message, model }
}
}Key patterns to follow:
- Use
BaseAIService.handleHttpError()for consistent HTTP error handling - Use
BaseAIService.extractAndValidateMessage()to validate AI responses - Report progress via
progress.report() - Support retry logic via the
attemptparameter - Respect
ConfigService.getApiRequestTimeout()for request timeouts
If your provider supports fetching the list of available models dynamically (like Gemini), implement IModelService in addition to the service class:
import { IModelService } from '../models/types';
export class AnthropicService implements IModelService {
static async getAvailableModels(): Promise<string[]> {
// fetch and return model names from the provider API
}
// ...rest of the service
}This enables the auto model selection mode for your provider.
Import the service and add it to the factory:
import { AnthropicService } from './anthropicService';
export enum AIServiceType {
// ...existing types...
ANTHROPIC = 'anthropic'
}
export class AIServiceFactory {
private static readonly services: Record<AIServiceType, AIServiceClass> = {
// ...existing services...
[AIServiceType.ANTHROPIC]: AnthropicService
};
}Add the provider to the type union and add provider-specific config:
export interface ProjectConfig {
provider?: {
type?: 'gemini' | 'codestral' | 'openai' | 'ollama' | 'anthropic';
};
// ...existing providers...
anthropic?: {
model?: string;
};
}Add getter methods for the new provider's settings:
static getAnthropicModel(): string {
return this.getConfig<string>('anthropic', 'model', 'claude-sonnet-4-6');
}Also add the provider to the validation list in getProvider():
if (!['gemini', 'openai', 'codestral', 'ollama', 'anthropic'].includes(provider)) {Add commands for setting and removing the API key:
- Create or extend files in
src/commands/setApiKeys.ts - Register new commands in
src/commands/index.ts
Add in three places:
a) Provider enum:
"commitSage.provider.type": {
"enum": ["gemini", "openai", "codestral", "ollama", "anthropic"]
}b) Provider settings section:
"commitSage.anthropic.model": {
"type": "string",
"default": "claude-sonnet-4-6",
"description": "Anthropic model to use"
}c) Commands (for API key management):
{
"command": "commitsage.setAnthropicApiKey",
"title": "Commit Sage: Set Anthropic API Key"
},
{
"command": "commitsage.removeAnthropicApiKey",
"title": "Commit Sage: Remove Anthropic API Key"
}Add the new provider to:
- The provider list at the top
- AI Provider Settings section
- Requirements section (if the provider has specific requirements)
After making all changes:
npm run compile— ensure no TypeScript errors.- Open VS Code Settings → CommitSage → confirm the new provider appears in the dropdown.
- Set the API key via Command Palette.
- Select the new provider and generate a commit message.
- Test error handling: use an invalid API key and verify the error message is clear.