123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198 |
- import { StorageEnum } from '../base/enums';
- import { createStorage } from '../base/base';
- import type { BaseStorage } from '../base/types';
- import { type AgentNameEnum, llmProviderModelNames, llmProviderParameters, ProviderTypeEnum } from './types';
- // Interface for a single provider configuration
- export interface ProviderConfig {
- name?: string; // Display name in the options
- type?: ProviderTypeEnum; // Help to decide which LangChain ChatModel package to use
- apiKey: string; // Must be provided, but may be empty for local models
- baseUrl?: string; // Optional base URL if provided
- modelNames?: string[]; // Chosen model names, if not provided use hardcoded names from llmProviderModelNames
- createdAt?: number; // Timestamp in milliseconds when the provider was created
- }
- // Interface for storing multiple LLM provider configurations
- // The key is the provider id, which is the same as the provider type for built-in providers, but is custom for custom providers
- export interface LLMKeyRecord {
- providers: Record<string, ProviderConfig>;
- }
- export type LLMProviderStorage = BaseStorage<LLMKeyRecord> & {
- setProvider: (providerId: string, config: ProviderConfig) => Promise<void>;
- getProvider: (providerId: string) => Promise<ProviderConfig | undefined>;
- removeProvider: (providerId: string) => Promise<void>;
- hasProvider: (providerId: string) => Promise<boolean>;
- getAllProviders: () => Promise<Record<string, ProviderConfig>>;
- };
- // Storage for LLM provider configurations
- // use "llm-api-keys" as the key for the storage, for backward compatibility
- const storage = createStorage<LLMKeyRecord>(
- 'llm-api-keys',
- { providers: {} },
- {
- storageEnum: StorageEnum.Local,
- liveUpdate: true,
- },
- );
- // Helper function to determine provider type from provider name
- // Make sure to update this function if you add a new provider type
- export function getProviderTypeByProviderId(providerId: string): ProviderTypeEnum {
- switch (providerId) {
- case ProviderTypeEnum.OpenAI:
- case ProviderTypeEnum.Anthropic:
- case ProviderTypeEnum.Gemini:
- case ProviderTypeEnum.Grok:
- case ProviderTypeEnum.Ollama:
- return providerId;
- default:
- return ProviderTypeEnum.CustomOpenAI;
- }
- }
- // Helper function to get display name from provider id
- // Make sure to update this function if you add a new provider type
- export function getDefaultDisplayNameFromProviderId(providerId: string): string {
- switch (providerId) {
- case ProviderTypeEnum.OpenAI:
- return 'OpenAI';
- case ProviderTypeEnum.Anthropic:
- return 'Anthropic';
- case ProviderTypeEnum.Gemini:
- return 'Gemini';
- case ProviderTypeEnum.Grok:
- return 'Grok';
- case ProviderTypeEnum.Ollama:
- return 'Ollama';
- default:
- return providerId; // Use the provider id as display name for custom providers by default
- }
- }
- // Get default configuration for built-in providers
- // Make sure to update this function if you add a new provider type
- export function getDefaultProviderConfig(providerId: string): ProviderConfig {
- switch (providerId) {
- case ProviderTypeEnum.OpenAI:
- case ProviderTypeEnum.Anthropic:
- case ProviderTypeEnum.Gemini:
- case ProviderTypeEnum.Grok:
- return {
- apiKey: '',
- name: getDefaultDisplayNameFromProviderId(providerId),
- type: providerId,
- modelNames: [...(llmProviderModelNames[providerId] || [])],
- createdAt: Date.now(),
- };
- case ProviderTypeEnum.Ollama:
- return {
- apiKey: 'ollama', // Set default API key for Ollama
- name: getDefaultDisplayNameFromProviderId(ProviderTypeEnum.Ollama),
- type: ProviderTypeEnum.Ollama,
- modelNames: [],
- baseUrl: 'http://localhost:11434',
- createdAt: Date.now(),
- };
- default:
- return {
- apiKey: '',
- name: getDefaultDisplayNameFromProviderId(providerId),
- type: ProviderTypeEnum.CustomOpenAI,
- baseUrl: '',
- modelNames: [],
- createdAt: Date.now(),
- };
- }
- }
- export function getDefaultAgentModelParams(providerId: string, agentName: AgentNameEnum): Record<string, number> {
- const newParameters = llmProviderParameters[providerId as keyof typeof llmProviderParameters]?.[agentName] || {
- temperature: 0.1,
- topP: 0.1,
- };
- return newParameters;
- }
- // Helper function to ensure backward compatibility for provider configs
- function ensureBackwardCompatibility(providerId: string, config: ProviderConfig): ProviderConfig {
- const updatedConfig = { ...config };
- if (!updatedConfig.name) {
- updatedConfig.name = getDefaultDisplayNameFromProviderId(providerId);
- }
- if (!updatedConfig.type) {
- updatedConfig.type = getProviderTypeByProviderId(providerId);
- }
- if (!updatedConfig.modelNames) {
- updatedConfig.modelNames = llmProviderModelNames[providerId as keyof typeof llmProviderModelNames] || [];
- }
- if (!updatedConfig.createdAt) {
- // if createdAt is not set, set it to "03/04/2025" for backward compatibility
- updatedConfig.createdAt = new Date('03/04/2025').getTime();
- }
- return updatedConfig;
- }
- export const llmProviderStore: LLMProviderStorage = {
- ...storage,
- async setProvider(providerId: string, config: ProviderConfig) {
- if (!providerId) {
- throw new Error('Provider id cannot be empty');
- }
- if (config.apiKey === undefined) {
- throw new Error('API key must be provided (can be empty for local models)');
- }
- if (!config.modelNames) {
- throw new Error('Model names must be provided');
- }
- // Ensure backward compatibility by filling in missing fields
- const completeConfig: ProviderConfig = {
- ...config,
- name: config.name || getDefaultDisplayNameFromProviderId(providerId),
- type: config.type || getProviderTypeByProviderId(providerId),
- modelNames: config.modelNames,
- createdAt: config.createdAt || Date.now(),
- };
- const current = (await storage.get()) || { providers: {} };
- await storage.set({
- providers: {
- ...current.providers,
- [providerId]: completeConfig,
- },
- });
- },
- async getProvider(providerId: string) {
- const data = (await storage.get()) || { providers: {} };
- const config = data.providers[providerId];
- return config ? ensureBackwardCompatibility(providerId, config) : undefined;
- },
- async removeProvider(providerId: string) {
- const current = (await storage.get()) || { providers: {} };
- const newProviders = { ...current.providers };
- delete newProviders[providerId];
- await storage.set({ providers: newProviders });
- },
- async hasProvider(providerId: string) {
- const data = (await storage.get()) || { providers: {} };
- return providerId in data.providers;
- },
- async getAllProviders() {
- const data = await storage.get();
- const providers = { ...data.providers };
- // Add backward compatibility for all providers
- for (const [providerId, config] of Object.entries(providers)) {
- providers[providerId] = ensureBackwardCompatibility(providerId, config);
- }
- return providers;
- },
- };
|