Steps to Add a New LLM
Suppose you want to add support for DeepSeek. According to the current architecture, you should follow these steps:
Step 1: Define Constants
Add the new provider identifier in src/utils/common.js:
javascript
export const MODEL_PROTOCOL_PREFIX = {
// ... existing content
DEEPSEEK: 'deepseek', // New protocol prefix
}
export const MODEL_PROVIDER = {
// ... existing content
DEEPSEEK_CUSTOM: 'deepseek-custom', // New provider identifier
}Step 2: Create Provider Core Implementation
Create deepseek-core.js in the src/providers/deepseek/ directory:
javascript
// src/providers/deepseek/deepseek-core.js
import axios from 'axios';
export class DeepSeekApiService {
constructor(config) {
this.apiKey = config.DEEPSEEK_API_KEY;
this.baseUrl = config.DEEPSEEK_BASE_URL || 'https://api.deepseek.com/v1';
this.axiosInstance = axios.create({
baseURL: this.baseUrl,
headers: {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json'
}
});
}
async generateContent(model, requestBody) {
const response = await this.axiosInstance.post('/chat/completions', requestBody);
return response.data;
}
async *generateContentStream(model, requestBody) {
// Implement streaming logic...
}
}Step 3: Register Provider Adapter
Create an adapter class in src/providers/adapter.js and call the registerAdapter function:
javascript
// src/providers/adapter.js
import { DeepSeekApiService } from './deepseek/deepseek-core.js';
export class DeepSeekApiServiceAdapter extends ApiServiceAdapter {
constructor(config) {
super();
this.service = new DeepSeekApiService(config);
}
// Implement generateContent, generateContentStream, listModels, refreshToken, etc...
}
// Call registration at the bottom of the file
registerAdapter(MODEL_PROVIDER.DEEPSEEK_CUSTOM, DeepSeekApiServiceAdapter);Step 4: Create Protocol Converter
Create DeepSeekConverter.js in src/converters/strategies/:
javascript
// src/converters/strategies/DeepSeekConverter.js
import { BaseConverter } from '../BaseConverter.js';
import { MODEL_PROTOCOL_PREFIX } from '../../utils/common.js';
export class DeepSeekConverter extends BaseConverter {
// Override toOpenAIRequest, toClaudeRequest, etc., for format conversion
}And register it in src/converters/register-converters.js:
javascript
import { DeepSeekConverter } from './strategies/DeepSeekConverter.js';
// ...
ConverterFactory.registerConverter(MODEL_PROTOCOL_PREFIX.DEEPSEEK, DeepSeekConverter);Step 5: Configure Provider Strategy
Import the new strategy in src/utils/provider-strategies.js and add it to the switch block in the factory:
javascript
// src/utils/provider-strategies.js
import { DeepSeekStrategy } from '../providers/deepseek/deepseek-strategy.js';
class ProviderStrategyFactory {
static getStrategy(providerProtocol) {
switch (providerProtocol) {
// ... existing content
case MODEL_PROTOCOL_PREFIX.DEEPSEEK:
return new DeepSeekStrategy();
default:
throw new Error(`Unsupported provider protocol: ${providerProtocol}`);
}
}
}Step 6: (Optional) Configure Model List
Add supported DeepSeek model names to the PROVIDER_MODELS object in src/providers/provider-models.js for selection in the Web UI.
Summary
This layered design ensures:
- Core: Handles API details (URL, Auth).
- Adapter: Unifies the internal service interface.
- Converter: Manages cross-protocol data transformation.
- Strategy: Handles request-time logic (like system prompt injection).