mirror of
				https://github.com/TriliumNext/Notes.git
				synced 2025-10-31 13:01:31 +08:00 
			
		
		
		
	feat(llm): have OpenAI provider not require API keys (for endpoints like LM Studio)
This commit is contained in:
		
							parent
							
								
									c26b74495c
								
							
						
					
					
						commit
						85cfc8fbd4
					
				| @ -44,7 +44,7 @@ export async function validateEmbeddingProviders(validationWarning: HTMLElement) | |||||||
|                 // Check OpenAI configuration
 |                 // Check OpenAI configuration
 | ||||||
|                 const apiKey = options.get('openaiApiKey'); |                 const apiKey = options.get('openaiApiKey'); | ||||||
|                 if (!apiKey) { |                 if (!apiKey) { | ||||||
|                     configIssues.push(`OpenAI API key is missing`); |                     configIssues.push(`OpenAI API key is missing (optional for OpenAI-compatible endpoints)`); | ||||||
|                 } |                 } | ||||||
|             } else if (provider === 'anthropic') { |             } else if (provider === 'anthropic') { | ||||||
|                 // Check Anthropic configuration
 |                 // Check Anthropic configuration
 | ||||||
|  | |||||||
| @ -66,12 +66,13 @@ async function listModels(req: Request, res: Response) { | |||||||
|         const apiKey = await options.getOption('openaiApiKey'); |         const apiKey = await options.getOption('openaiApiKey'); | ||||||
| 
 | 
 | ||||||
|         if (!apiKey) { |         if (!apiKey) { | ||||||
|             throw new Error('OpenAI API key is not configured'); |             // Log warning but don't throw - some OpenAI-compatible endpoints don't require API keys
 | ||||||
|  |             log.info('OpenAI API key is not configured when listing models. This may cause issues with official OpenAI endpoints.'); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // Initialize OpenAI client with the API key and base URL
 |         // Initialize OpenAI client with the API key (or empty string) and base URL
 | ||||||
|         const openai = new OpenAI({ |         const openai = new OpenAI({ | ||||||
|             apiKey, |             apiKey: apiKey || '', // Default to empty string if no API key
 | ||||||
|             baseURL: openaiBaseUrl |             baseURL: openaiBaseUrl | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -14,7 +14,9 @@ export class OpenAIService extends BaseAIService { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     override isAvailable(): boolean { |     override isAvailable(): boolean { | ||||||
|         return super.isAvailable() && !!options.getOption('openaiApiKey'); |         // Make API key optional to support OpenAI-compatible endpoints that don't require authentication
 | ||||||
|  |         // The provider is considered available as long as the parent checks pass
 | ||||||
|  |         return super.isAvailable(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private getClient(apiKey: string, baseUrl?: string): OpenAI { |     private getClient(apiKey: string, baseUrl?: string): OpenAI { | ||||||
| @ -29,7 +31,7 @@ export class OpenAIService extends BaseAIService { | |||||||
| 
 | 
 | ||||||
|     async generateChatCompletion(messages: Message[], opts: ChatCompletionOptions = {}): Promise<ChatResponse> { |     async generateChatCompletion(messages: Message[], opts: ChatCompletionOptions = {}): Promise<ChatResponse> { | ||||||
|         if (!this.isAvailable()) { |         if (!this.isAvailable()) { | ||||||
|             throw new Error('OpenAI service is not available. Check API key and AI settings.'); |             throw new Error('OpenAI service is not available. Check AI settings.'); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // Get provider-specific options from the central provider manager
 |         // Get provider-specific options from the central provider manager
 | ||||||
|  | |||||||
| @ -152,23 +152,30 @@ export async function createProvidersFromCurrentOptions(): Promise<EmbeddingProv | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // Create OpenAI provider if API key is configured
 |         // Create OpenAI provider even without API key (for OpenAI-compatible endpoints)
 | ||||||
|         const openaiApiKey = await options.getOption('openaiApiKey'); |         const openaiApiKey = await options.getOption('openaiApiKey'); | ||||||
|         if (openaiApiKey) { |         const openaiBaseUrl = await options.getOption('openaiBaseUrl'); | ||||||
|             const openaiModel = await options.getOption('openaiEmbeddingModel') || 'text-embedding-3-small'; | 
 | ||||||
|             const openaiBaseUrl = await options.getOption('openaiBaseUrl') || 'https://api.openai.com/v1'; |         // Only create OpenAI provider if base URL is set or API key is provided
 | ||||||
|  |         if (openaiApiKey || openaiBaseUrl) { | ||||||
|  |             const openaiModel = await options.getOption('openaiEmbeddingModel') | ||||||
|  |             const finalBaseUrl = openaiBaseUrl || 'https://api.openai.com/v1'; | ||||||
|  | 
 | ||||||
|  |             if (!openaiApiKey) { | ||||||
|  |                 log.info('Creating OpenAI embedding provider without API key. This may cause issues with official OpenAI endpoints.'); | ||||||
|  |             } | ||||||
| 
 | 
 | ||||||
|             const openaiProvider = new OpenAIEmbeddingProvider({ |             const openaiProvider = new OpenAIEmbeddingProvider({ | ||||||
|                 model: openaiModel, |                 model: openaiModel, | ||||||
|                 dimension: 1536, |                 dimension: 1536, | ||||||
|                 type: 'float32', |                 type: 'float32', | ||||||
|                 apiKey: openaiApiKey, |                 apiKey: openaiApiKey || '', // Default to empty string
 | ||||||
|                 baseUrl: openaiBaseUrl |                 baseUrl: finalBaseUrl | ||||||
|             }); |             }); | ||||||
| 
 | 
 | ||||||
|             registerEmbeddingProvider(openaiProvider); |             registerEmbeddingProvider(openaiProvider); | ||||||
|             result.push(openaiProvider); |             result.push(openaiProvider); | ||||||
|             log.info(`Created OpenAI provider on-demand: ${openaiModel}`); |             log.info(`Created OpenAI provider on-demand: ${openaiModel} at ${finalBaseUrl}`); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // Create Voyage provider if API key is configured
 |         // Create Voyage provider if API key is configured
 | ||||||
| @ -352,7 +359,8 @@ export function getOpenAIOptions( | |||||||
|     try { |     try { | ||||||
|         const apiKey = options.getOption('openaiApiKey'); |         const apiKey = options.getOption('openaiApiKey'); | ||||||
|         if (!apiKey) { |         if (!apiKey) { | ||||||
|             throw new Error('OpenAI API key is not configured'); |             // Log warning but don't throw - some OpenAI-compatible endpoints don't require API keys
 | ||||||
|  |             log.info('OpenAI API key is not configured. This may cause issues with official OpenAI endpoints.'); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         const baseUrl = options.getOption('openaiBaseUrl') || PROVIDER_CONSTANTS.OPENAI.BASE_URL; |         const baseUrl = options.getOption('openaiBaseUrl') || PROVIDER_CONSTANTS.OPENAI.BASE_URL; | ||||||
| @ -377,7 +385,7 @@ export function getOpenAIOptions( | |||||||
| 
 | 
 | ||||||
|         return { |         return { | ||||||
|             // Connection settings
 |             // Connection settings
 | ||||||
|             apiKey, |             apiKey: apiKey || '', // Default to empty string if no API key
 | ||||||
|             baseUrl, |             baseUrl, | ||||||
| 
 | 
 | ||||||
|             // Provider metadata
 |             // Provider metadata
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 perf3ct
						perf3ct