141 lines
3.1 KiB
TypeScript
141 lines
3.1 KiB
TypeScript
import type { BaseChatModel } from '@langchain/core/language_models/chat_models';
|
|
import { ChatAnthropic } from '@langchain/anthropic';
|
|
import type { FastifyBaseLogger } from 'fastify';
|
|
|
|
/**
|
|
* Supported LLM providers
|
|
*/
|
|
export enum LLMProvider {
|
|
ANTHROPIC = 'anthropic',
|
|
}
|
|
|
|
/**
|
|
* Model configuration
|
|
*/
|
|
export interface ModelConfig {
|
|
provider: LLMProvider;
|
|
model: string;
|
|
temperature?: number;
|
|
maxTokens?: number;
|
|
}
|
|
|
|
/**
|
|
* License tier model configuration
|
|
*/
|
|
export interface LicenseTierModels {
|
|
default: string;
|
|
cost_optimized: string;
|
|
complex: string;
|
|
allowed_models?: string[];
|
|
blocked_models?: string[];
|
|
}
|
|
|
|
/**
|
|
* License models configuration
|
|
*/
|
|
export interface LicenseModelsConfig {
|
|
free: LicenseTierModels;
|
|
pro: LicenseTierModels;
|
|
enterprise: LicenseTierModels;
|
|
}
|
|
|
|
/**
|
|
* Provider configuration with API keys
|
|
*/
|
|
export interface ProviderConfig {
|
|
anthropicApiKey?: string;
|
|
defaultModel?: ModelConfig;
|
|
licenseModels?: LicenseModelsConfig;
|
|
}
|
|
|
|
/**
|
|
* LLM Provider factory
|
|
* Creates model instances with unified interface across providers
|
|
*/
|
|
export class LLMProviderFactory {
|
|
private config: ProviderConfig;
|
|
private logger: FastifyBaseLogger;
|
|
|
|
constructor(config: ProviderConfig, logger: FastifyBaseLogger) {
|
|
this.config = config;
|
|
this.logger = logger;
|
|
}
|
|
|
|
/**
|
|
* Create a chat model instance
|
|
*/
|
|
createModel(modelConfig: ModelConfig): BaseChatModel {
|
|
this.logger.debug(
|
|
{ provider: modelConfig.provider, model: modelConfig.model },
|
|
'Creating LLM model'
|
|
);
|
|
|
|
switch (modelConfig.provider) {
|
|
case LLMProvider.ANTHROPIC:
|
|
return this.createAnthropicModel(modelConfig);
|
|
|
|
default:
|
|
throw new Error(`Unsupported provider: ${modelConfig.provider}`);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Create Anthropic Claude model
|
|
*/
|
|
private createAnthropicModel(config: ModelConfig): ChatAnthropic {
|
|
if (!this.config.anthropicApiKey) {
|
|
throw new Error('Anthropic API key not configured');
|
|
}
|
|
|
|
return new ChatAnthropic({
|
|
model: config.model,
|
|
temperature: config.temperature ?? 0.7,
|
|
maxTokens: config.maxTokens ?? 4096,
|
|
anthropicApiKey: this.config.anthropicApiKey,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Get default model based on environment
|
|
*/
|
|
getDefaultModel(): ModelConfig {
|
|
if (this.config.defaultModel) {
|
|
return this.config.defaultModel;
|
|
}
|
|
|
|
if (!this.config.anthropicApiKey) {
|
|
throw new Error('Anthropic API key not configured');
|
|
}
|
|
|
|
return {
|
|
provider: LLMProvider.ANTHROPIC,
|
|
model: 'claude-sonnet-4-6',
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Get license models configuration
|
|
*/
|
|
getLicenseModelsConfig(): LicenseModelsConfig | undefined {
|
|
return this.config.licenseModels;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Predefined model configurations
|
|
*/
|
|
export const MODELS = {
|
|
CLAUDE_SONNET: {
|
|
provider: LLMProvider.ANTHROPIC,
|
|
model: 'claude-sonnet-4-6',
|
|
},
|
|
CLAUDE_HAIKU: {
|
|
provider: LLMProvider.ANTHROPIC,
|
|
model: 'claude-haiku-4-5-20251001',
|
|
},
|
|
CLAUDE_OPUS: {
|
|
provider: LLMProvider.ANTHROPIC,
|
|
model: 'claude-opus-4-6',
|
|
},
|
|
} as const satisfies Record<string, ModelConfig>;
|