Quellcode durchsuchen

further refine settings page, move some provider-specific code to storage layer

alexchenzl vor 5 Monaten
Ursprung
Commit
99f1c2deac

+ 53 - 8
packages/storage/lib/settings/llmProviders.ts

@@ -39,23 +39,20 @@ const storage = createStorage<LLMKeyRecord>(
 );
 
 // Helper function to determine provider type from provider name
-function getProviderTypeByProviderId(providerId: string): ProviderTypeEnum {
+export function getProviderTypeByProviderId(providerId: string): ProviderTypeEnum {
   switch (providerId) {
     case ProviderTypeEnum.OpenAI:
-      return ProviderTypeEnum.OpenAI;
     case ProviderTypeEnum.Anthropic:
-      return ProviderTypeEnum.Anthropic;
     case ProviderTypeEnum.Gemini:
-      return ProviderTypeEnum.Gemini;
     case ProviderTypeEnum.Ollama:
-      return ProviderTypeEnum.Ollama;
+      return providerId;
     default:
       return ProviderTypeEnum.CustomOpenAI;
   }
 }
 
 // Helper function to get display name from provider id
-function getDisplayNameFromProviderId(providerId: string): string {
+export function getDefaultDisplayNameFromProviderId(providerId: string): string {
   switch (providerId) {
     case ProviderTypeEnum.OpenAI:
       return 'OpenAI';
@@ -70,11 +67,59 @@ function getDisplayNameFromProviderId(providerId: string): string {
   }
 }
 
+// Get default configuration for built-in providers
+export function getDefaultProviderConfig(providerId: string): ProviderConfig {
+  switch (providerId) {
+    case ProviderTypeEnum.OpenAI:
+      return {
+        apiKey: '',
+        name: getDefaultDisplayNameFromProviderId(ProviderTypeEnum.OpenAI),
+        type: ProviderTypeEnum.OpenAI,
+        modelNames: [...(llmProviderModelNames[ProviderTypeEnum.OpenAI] || [])],
+        createdAt: Date.now(),
+      };
+    case ProviderTypeEnum.Anthropic:
+      return {
+        apiKey: '',
+        name: getDefaultDisplayNameFromProviderId(ProviderTypeEnum.Anthropic),
+        type: ProviderTypeEnum.Anthropic,
+        modelNames: [...(llmProviderModelNames[ProviderTypeEnum.Anthropic] || [])],
+        createdAt: Date.now(),
+      };
+    case ProviderTypeEnum.Gemini:
+      return {
+        apiKey: '',
+        name: getDefaultDisplayNameFromProviderId(ProviderTypeEnum.Gemini),
+        type: ProviderTypeEnum.Gemini,
+        modelNames: [...(llmProviderModelNames[ProviderTypeEnum.Gemini] || [])],
+        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(),
+      };
+  }
+}
+
 // Helper function to ensure backward compatibility for provider configs
 function ensureBackwardCompatibility(providerId: string, config: ProviderConfig): ProviderConfig {
   const updatedConfig = { ...config };
   if (!updatedConfig.name) {
-    updatedConfig.name = getDisplayNameFromProviderId(providerId);
+    updatedConfig.name = getDefaultDisplayNameFromProviderId(providerId);
   }
   if (!updatedConfig.type) {
     updatedConfig.type = getProviderTypeByProviderId(providerId);
@@ -107,7 +152,7 @@ export const llmProviderStore: LLMProviderStorage = {
     // Ensure backward compatibility by filling in missing fields
     const completeConfig: ProviderConfig = {
       ...config,
-      name: config.name || getDisplayNameFromProviderId(providerId),
+      name: config.name || getDefaultDisplayNameFromProviderId(providerId),
       type: config.type || getProviderTypeByProviderId(providerId),
       modelNames: config.modelNames,
       createdAt: config.createdAt || Date.now(),

+ 25 - 127
pages/options/src/components/ModelSettings.tsx

@@ -8,6 +8,8 @@ import {
   llmProviderModelNames,
   ProviderTypeEnum,
   llmProviderParameters,
+  getDefaultDisplayNameFromProviderId,
+  getDefaultProviderConfig,
 } from '@extension/storage';
 
 interface ModelSettingsProps {
@@ -677,58 +679,9 @@ export const ModelSettings = ({ isDarkMode = false }: ModelSettingsProps) => {
     }, 100);
   };
 
-  const addDefaultProvider = (provider: string) => {
+  const addBuiltInProvider = (provider: string) => {
     // Get the default provider configuration
-    let config: {
-      apiKey: string;
-      name: string;
-      type: ProviderTypeEnum;
-      modelNames: string[];
-      baseUrl?: string;
-      createdAt: number;
-    };
-
-    switch (provider) {
-      case ProviderTypeEnum.OpenAI:
-        config = {
-          apiKey: '',
-          name: 'OpenAI',
-          type: ProviderTypeEnum.OpenAI,
-          modelNames: [...(llmProviderModelNames[ProviderTypeEnum.OpenAI] || [])],
-          createdAt: Date.now(),
-        };
-        break;
-      case ProviderTypeEnum.Anthropic:
-        config = {
-          apiKey: '',
-          name: 'Anthropic',
-          type: ProviderTypeEnum.Anthropic,
-          modelNames: [...(llmProviderModelNames[ProviderTypeEnum.Anthropic] || [])],
-          createdAt: Date.now(),
-        };
-        break;
-      case ProviderTypeEnum.Gemini:
-        config = {
-          apiKey: '',
-          name: 'Gemini',
-          type: ProviderTypeEnum.Gemini,
-          modelNames: [...(llmProviderModelNames[ProviderTypeEnum.Gemini] || [])],
-          createdAt: Date.now(),
-        };
-        break;
-      case ProviderTypeEnum.Ollama:
-        config = {
-          apiKey: 'ollama', // Set default API key for Ollama
-          name: 'Ollama',
-          type: ProviderTypeEnum.Ollama,
-          modelNames: [],
-          baseUrl: 'http://localhost:11434',
-          createdAt: Date.now(),
-        };
-        break;
-      default:
-        return;
-    }
+    const config = getDefaultProviderConfig(provider);
 
     // Add the provider to the state
     setProviders(prev => ({
@@ -809,22 +762,14 @@ export const ModelSettings = ({ isDarkMode = false }: ModelSettingsProps) => {
     // Close the dropdown immediately
     setIsProviderSelectorOpen(false);
 
-    if (providerType === 'custom') {
+    // Handle custom provider
+    if (providerType === ProviderTypeEnum.CustomOpenAI) {
       addCustomProvider();
       return;
     }
 
-    // Handle default providers
-    switch (providerType) {
-      case ProviderTypeEnum.OpenAI:
-      case ProviderTypeEnum.Anthropic:
-      case ProviderTypeEnum.Gemini:
-      case ProviderTypeEnum.Ollama:
-        addDefaultProvider(providerType);
-        break;
-      default:
-        console.error('Unknown provider type:', providerType);
-    }
+    // Handle built-in supported providers
+    addBuiltInProvider(providerType);
   };
 
   const getProviderForModel = (modelName: string): string => {
@@ -1064,7 +1009,7 @@ export const ModelSettings = ({ isDarkMode = false }: ModelSettingsProps) => {
           )}
 
           {/* Add Provider button and dropdown */}
-          <div className="provider-selector-container pt-4 relative">
+          <div className="provider-selector-container relative pt-4">
             <Button
               variant="secondary"
               onClick={() => setIsProviderSelectorOpen(prev => !prev)}
@@ -1084,77 +1029,30 @@ export const ModelSettings = ({ isDarkMode = false }: ModelSettingsProps) => {
                     : 'border-blue-200 bg-white shadow-xl shadow-blue-100/50'
                 }`}>
                 <div className="py-1">
-                  {/* Check if all default providers are already added */}
-                  {(providersFromStorage.has(ProviderTypeEnum.OpenAI) ||
-                    modifiedProviders.has(ProviderTypeEnum.OpenAI)) &&
-                    (providersFromStorage.has(ProviderTypeEnum.Anthropic) ||
-                      modifiedProviders.has(ProviderTypeEnum.Anthropic)) &&
-                    (providersFromStorage.has(ProviderTypeEnum.Gemini) ||
-                      modifiedProviders.has(ProviderTypeEnum.Gemini)) &&
-                    (providersFromStorage.has(ProviderTypeEnum.Ollama) ||
-                      modifiedProviders.has(ProviderTypeEnum.Ollama)) && (
-                      <div
-                        className={`px-4 py-3 text-sm font-medium ${isDarkMode ? 'text-blue-300' : 'text-blue-600'}`}>
-                        All default providers already added. You can still add a custom provider.
-                      </div>
-                    )}
-
-                  {!providersFromStorage.has(ProviderTypeEnum.OpenAI) &&
-                    !modifiedProviders.has(ProviderTypeEnum.OpenAI) && (
-                      <button
-                        type="button"
-                        className={`flex w-full items-center px-4 py-3 text-left text-sm ${
-                          isDarkMode
-                            ? 'text-blue-200 hover:bg-blue-600/30 hover:text-white'
-                            : 'text-blue-700 hover:bg-blue-100 hover:text-blue-800'
-                        } transition-colors duration-150`}
-                        onClick={() => handleProviderSelection(ProviderTypeEnum.OpenAI)}>
-                        <span className="font-medium">OpenAI</span>
-                      </button>
-                    )}
-
-                  {!providersFromStorage.has(ProviderTypeEnum.Anthropic) &&
-                    !modifiedProviders.has(ProviderTypeEnum.Anthropic) && (
-                      <button
-                        type="button"
-                        className={`flex w-full items-center px-4 py-3 text-left text-sm ${
-                          isDarkMode
-                            ? 'text-blue-200 hover:bg-blue-600/30 hover:text-white'
-                            : 'text-blue-700 hover:bg-blue-100 hover:text-blue-800'
-                        } transition-colors duration-150`}
-                        onClick={() => handleProviderSelection(ProviderTypeEnum.Anthropic)}>
-                        <span className="font-medium">Anthropic</span>
-                      </button>
-                    )}
-
-                  {!providersFromStorage.has(ProviderTypeEnum.Gemini) &&
-                    !modifiedProviders.has(ProviderTypeEnum.Gemini) && (
+                  {/* Map through provider types to create buttons */}
+                  {Object.values(ProviderTypeEnum)
+                    // Filter out CustomOpenAI and already added providers
+                    .filter(
+                      type =>
+                        type !== ProviderTypeEnum.CustomOpenAI &&
+                        !providersFromStorage.has(type) &&
+                        !modifiedProviders.has(type),
+                    )
+                    .map(type => (
                       <button
+                        key={type}
                         type="button"
                         className={`flex w-full items-center px-4 py-3 text-left text-sm ${
                           isDarkMode
                             ? 'text-blue-200 hover:bg-blue-600/30 hover:text-white'
                             : 'text-blue-700 hover:bg-blue-100 hover:text-blue-800'
                         } transition-colors duration-150`}
-                        onClick={() => handleProviderSelection(ProviderTypeEnum.Gemini)}>
-                        <span className="font-medium">Gemini</span>
+                        onClick={() => handleProviderSelection(type)}>
+                        <span className="font-medium">{getDefaultDisplayNameFromProviderId(type)}</span>
                       </button>
-                    )}
-
-                  {!providersFromStorage.has(ProviderTypeEnum.Ollama) &&
-                    !modifiedProviders.has(ProviderTypeEnum.Ollama) && (
-                      <button
-                        type="button"
-                        className={`flex w-full items-center px-4 py-3 text-left text-sm ${
-                          isDarkMode
-                            ? 'text-blue-200 hover:bg-blue-600/30 hover:text-white'
-                            : 'text-blue-700 hover:bg-blue-100 hover:text-blue-800'
-                        } transition-colors duration-150`}
-                        onClick={() => handleProviderSelection(ProviderTypeEnum.Ollama)}>
-                        <span className="font-medium">Ollama</span>
-                      </button>
-                    )}
+                    ))}
 
+                  {/* Custom provider button (always shown) */}
                   <button
                     type="button"
                     className={`flex w-full items-center px-4 py-3 text-left text-sm ${
@@ -1162,7 +1060,7 @@ export const ModelSettings = ({ isDarkMode = false }: ModelSettingsProps) => {
                         ? 'text-blue-200 hover:bg-blue-600/30 hover:text-white'
                         : 'text-blue-700 hover:bg-blue-100 hover:text-blue-800'
                     } transition-colors duration-150`}
-                    onClick={() => handleProviderSelection('custom')}>
+                    onClick={() => handleProviderSelection(ProviderTypeEnum.CustomOpenAI)}>
                     <span className="font-medium">Custom OpenAI-compatible</span>
                   </button>
                 </div>