Add static model list for Google AI Studio
| @@ -3189,7 +3189,54 @@ | |||
| 3189 | <div> | 3189 | <div> |
| 3190 | <h4 data-i18n="Google Model">Google Model</h4> | 3190 | <h4 data-i18n="Google Model">Google Model</h4> |
| 3191 | <select id="model_google_select"> | 3191 | <select id="model_google_select"> |
| 3192 | <option value="" data-i18n="-- Connect to the API --">-- Connect to the API --</option> | 3192 | <optgroup label="Gemini 2.5"> |
| 3193 | <option value="gemini-2.5-pro-preview-06-05">gemini-2.5-pro-preview-06-05</option> | ||
| 3194 | <option value="gemini-2.5-pro-preview-05-06">gemini-2.5-pro-preview-05-06</option> | ||
| 3195 | <option value="gemini-2.5-pro-preview-03-25">gemini-2.5-pro-preview-03-25</option> | ||
| 3196 | <option value="gemini-2.5-pro-exp-03-25">gemini-2.5-pro-exp-03-25</option> | ||
| 3197 | <option value="gemini-2.5-flash-preview-05-20">gemini-2.5-flash-preview-05-20</option> | ||
| 3198 | <option value="gemini-2.5-flash-preview-04-17">gemini-2.5-flash-preview-04-17</option> | ||
| 3199 | </optgroup> | ||
| 3200 | <optgroup label="Gemini 2.0"> | ||
| 3201 | <option value="gemini-2.0-pro-exp-02-05">gemini-2.0-pro-exp-02-05 → 2.5-pro-exp-03-25</option> | ||
| 3202 | <option value="gemini-2.0-pro-exp">gemini-2.0-pro-exp → 2.5-pro-exp-03-25</option> | ||
| 3203 | <option value="gemini-exp-1206">gemini-exp-1206 → 2.5-pro-exp-03-25</option> | ||
| 3204 | <option value="gemini-2.0-flash-001">gemini-2.0-flash-001</option> | ||
| 3205 | <option value="gemini-2.0-flash-exp-image-generation">gemini-2.0-flash-exp-image-generation</option> | ||
| 3206 | <option value="gemini-2.0-flash-exp">gemini-2.0-flash-exp</option> | ||
| 3207 | <option value="gemini-2.0-flash">gemini-2.0-flash</option> | ||
| 3208 | <option value="gemini-2.0-flash-thinking-exp-01-21">gemini-2.0-flash-thinking-exp-01-21 → 2.5-flash-preview-04-17</option> | ||
| 3209 | <option value="gemini-2.0-flash-thinking-exp-1219">gemini-2.0-flash-thinking-exp-1219 → 2.5-flash-preview-04-17</option> | ||
| 3210 | <option value="gemini-2.0-flash-thinking-exp">gemini-2.0-flash-thinking-exp → 2.5-flash-preview-04-17</option> | ||
| 3211 | <option value="gemini-2.0-flash-lite-001">gemini-2.0-flash-lite-001</option> | ||
| 3212 | <option value="gemini-2.0-flash-lite-preview-02-05">gemini-2.0-flash-lite-preview-02-05</option> | ||
| 3213 | <option value="gemini-2.0-flash-lite-preview">gemini-2.0-flash-lite-preview</option> | ||
| 3214 | </optgroup> | ||
| 3215 | <optgroup label="Gemini 1.5"> | ||
| 3216 | <option value="gemini-1.5-pro-latest">gemini-1.5-pro-latest</option> | ||
| 3217 | <option value="gemini-1.5-pro-002">gemini-1.5-pro-002</option> | ||
| 3218 | <option value="gemini-1.5-pro-001">gemini-1.5-pro-001</option> | ||
| 3219 | <option value="gemini-1.5-pro">gemini-1.5-pro</option> | ||
| 3220 | <option value="gemini-1.5-flash-latest">gemini-1.5-flash-latest</option> | ||
| 3221 | <option value="gemini-1.5-flash-002">gemini-1.5-flash-002</option> | ||
| 3222 | <option value="gemini-1.5-flash-001">gemini-1.5-flash-001</option> | ||
| 3223 | <option value="gemini-1.5-flash">gemini-1.5-flash</option> | ||
| 3224 | <option value="gemini-1.5-flash-8b-001">gemini-1.5-flash-8b-001</option> | ||
| 3225 | <option value="gemini-1.5-flash-8b-exp-0924">gemini-1.5-flash-8b-exp-0924</option> | ||
| 3226 | <option value="gemini-1.5-flash-8b-exp-0827">gemini-1.5-flash-8b-exp-0827</option> | ||
| 3227 | <option value="gemini-1.5-flash-8b">gemini-1.5-flash-8b</option> | ||
| 3228 | </optgroup> | ||
| 3229 | <optgroup label="Gemma"> | ||
| 3230 | <option value="gemma-3n-e4b-it">gemma-3n-e4b-it</option> | ||
| 3231 | <option value="gemma-3-27b-it">gemma-3-27b-it</option> | ||
| 3232 | <option value="gemma-3-12b-it">gemma-3-12b-it</option> | ||
| 3233 | <option value="gemma-3-4b-it">gemma-3-4b-it</option> | ||
| 3234 | <option value="gemma-3-1b-it">gemma-3-1b-it</option> | ||
| 3235 | </optgroup> | ||
| 3236 | <optgroup label="LearnLM"> | ||
| 3237 | <option value="learnlm-2.0-flash-experimental">learnlm-2.0-flash-experimental</option> | ||
| 3238 | </optgroup> | ||
| 3239 | <optgroup id="google_other_models" label="Other"></optgroup> | ||
| 3193 | </select> | 3240 | </select> |
| 3194 | </div> | 3241 | </div> |
| 3195 | </form> | 3242 | </form> |
| @@ -1914,13 +1914,25 @@ function saveModelList(data) { | |||
| 1914 | } | 1914 | } |
| 1915 | 1915 | ||
| 1916 | if (oai_settings.chat_completion_source === chat_completion_sources.MAKERSUITE) { | 1916 | if (oai_settings.chat_completion_source === chat_completion_sources.MAKERSUITE) { |
| 1917 | $('#model_google_select').empty(); | 1917 | // Clear only the "Other" optgroup for dynamic models |
| 1918 | $('#google_other_models').empty(); | ||
| 1919 | |||
| 1920 | // Get static model options that are already in the HTML | ||
| 1921 | const staticModels = []; | ||
| 1922 | $('#model_google_select option').each(function() { | ||
| 1923 | staticModels.push($(this).val()); | ||
| 1924 | }); | ||
| 1925 | |||
| 1926 | // Add dynamic models to the "Other" group | ||
| 1918 | model_list.forEach((model) => { | 1927 | model_list.forEach((model) => { |
| 1919 | $('#model_google_select').append( | 1928 | // Only add if not already in static list |
| 1929 | if (!staticModels.includes(model.id)) { | ||
| 1930 | $('#google_other_models').append( | ||
| 1920 | $('<option>', { | 1931 | $('<option>', { |
| 1921 | value: model.id, | 1932 | value: model.id, |
| 1922 | text: model.id, | 1933 | text: model.id, |
| 1923 | })); | 1934 | })); |
| 1935 | } | ||
| 1924 | }); | 1936 | }); |
| 1925 | 1937 | ||
| 1926 | const selectedModel = model_list.find(model => model.id === oai_settings.google_model); | 1938 | const selectedModel = model_list.find(model => model.id === oai_settings.google_model); |
| @@ -1096,10 +1096,11 @@ router.post('/status', async function (request, response_getstatus_openai) { | |||
| 1096 | // For Google AI Studio, we need to get models from the API | 1096 | // For Google AI Studio, we need to get models from the API |
| 1097 | const api_key_makersuite = request.body.reverse_proxy ? request.body.proxy_password : readSecret(request.user.directories, SECRET_KEYS.MAKERSUITE); | 1097 | const api_key_makersuite = request.body.reverse_proxy ? request.body.proxy_password : readSecret(request.user.directories, SECRET_KEYS.MAKERSUITE); |
| 1098 | const api_url = new URL(request.body.reverse_proxy || API_MAKERSUITE); | 1098 | const api_url = new URL(request.body.reverse_proxy || API_MAKERSUITE); |
| 1099 | let models_url = `${api_url.origin}/v1beta/models?key=${api_key_makersuite}`; | 1099 | const apiVersion = getConfigValue('gemini.apiVersion', 'v1beta'); |
| 1100 | let models_url = `${api_url.origin}/${apiVersion}/models?key=${api_key_makersuite}`; | ||
| 1100 | 1101 | ||
| 1101 | if (!api_key_makersuite && request.body.reverse_proxy) { | 1102 | if (!api_key_makersuite && request.body.reverse_proxy) { |
| 1102 | models_url = `${api_url.origin}/v1beta/models`; // For some special reverse proxy, we can't pass the API key | 1103 | models_url = `${api_url.origin}/${apiVersion}/models`; // For some special reverse proxy, we can't pass the API key |
| 1103 | } else if (!api_key_makersuite && !request.body.reverse_proxy) { | 1104 | } else if (!api_key_makersuite && !request.body.reverse_proxy) { |
| 1104 | console.warn('Google AI Studio API key is missing.'); | 1105 | console.warn('Google AI Studio API key is missing.'); |
| 1105 | return response_getstatus_openai.status(400).send({ error: true }); | 1106 | return response_getstatus_openai.status(400).send({ error: true }); |
| @@ -1114,15 +1115,13 @@ router.post('/status', async function (request, response_getstatus_openai) { | |||
| 1114 | }); | 1115 | }); |
| 1115 | 1116 | ||
| 1116 | if (response.ok) { | 1117 | if (response.ok) { |
| 1118 | /** @type {any} */ | ||
| 1117 | const data = await response.json(); | 1119 | const data = await response.json(); |
| 1118 | // Transform Google AI Studio models to OpenAI format | 1120 | // Transform Google AI Studio models to OpenAI format |
| 1119 | const models = data.models | 1121 | const models = data.models |
| 1120 | ?.filter(model => model.supportedGenerationMethods?.includes('generateContent')) | 1122 | ?.filter(model => model.supportedGenerationMethods?.includes('generateContent')) |
| 1121 | ?.map(model => ({ | 1123 | ?.map(model => ({ |
| 1122 | id: model.name.replace('models/', ''), | 1124 | id: model.name.replace('models/', ''), |
| 1123 | object: 'model', | ||
| 1124 | created: Date.now(), | ||
| 1125 | owned_by: 'google', | ||
| 1126 | })) || []; | 1125 | })) || []; |
| 1127 | 1126 | ||
| 1128 | response_getstatus_openai.send({ data: models }); | 1127 | response_getstatus_openai.send({ data: models }); |