Implement Google AI Studio model list dynamic fetching
| @@ -3189,53 +3189,7 @@ | |||
| 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 | <optgroup label="Gemini 2.5"> | 3192 | <option value="" data-i18n="-- Connect to the API --">-- Connect to the API --</option> |
| 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 | </select> | 3193 | </select> |
| 3240 | </div> | 3194 | </div> |
| 3241 | </form> | 3195 | </form> |
| @@ -1912,6 +1912,24 @@ function saveModelList(data) { | |||
| 1912 | 1912 | ||
| 1913 | $('#model_pollinations_select').val(oai_settings.pollinations_model).trigger('change'); | 1913 | $('#model_pollinations_select').val(oai_settings.pollinations_model).trigger('change'); |
| 1914 | } | 1914 | } |
| 1915 | |||
| 1916 | if (oai_settings.chat_completion_source === chat_completion_sources.MAKERSUITE) { | ||
| 1917 | $('#model_google_select').empty(); | ||
| 1918 | model_list.forEach((model) => { | ||
| 1919 | $('#model_google_select').append( | ||
| 1920 | $('<option>', { | ||
| 1921 | value: model.id, | ||
| 1922 | text: model.id, | ||
| 1923 | })); | ||
| 1924 | }); | ||
| 1925 | |||
| 1926 | const selectedModel = model_list.find(model => model.id === oai_settings.google_model); | ||
| 1927 | if (model_list.length > 0 && (!selectedModel || !oai_settings.google_model)) { | ||
| 1928 | oai_settings.google_model = model_list[0].id; | ||
| 1929 | } | ||
| 1930 | |||
| 1931 | $('#model_google_select').val(oai_settings.google_model).trigger('change'); | ||
| 1932 | } | ||
| 1915 | } | 1933 | } |
| 1916 | 1934 | ||
| 1917 | function appendOpenRouterOptions(model_list, groupModels = false, sort = false) { | 1935 | function appendOpenRouterOptions(model_list, groupModels = false, sort = false) { |
| @@ -3700,7 +3718,6 @@ async function getStatusOpen() { | |||
| 3700 | chat_completion_sources.SCALE, | 3718 | chat_completion_sources.SCALE, |
| 3701 | chat_completion_sources.CLAUDE, | 3719 | chat_completion_sources.CLAUDE, |
| 3702 | chat_completion_sources.AI21, | 3720 | chat_completion_sources.AI21, |
| 3703 | chat_completion_sources.MAKERSUITE, | ||
| 3704 | chat_completion_sources.VERTEXAI, | 3721 | chat_completion_sources.VERTEXAI, |
| 3705 | chat_completion_sources.PERPLEXITY, | 3722 | chat_completion_sources.PERPLEXITY, |
| 3706 | chat_completion_sources.GROQ, | 3723 | chat_completion_sources.GROQ, |
| @@ -1092,6 +1092,50 @@ router.post('/status', async function (request, response_getstatus_openai) { | |||
| 1092 | api_url = 'https://text.pollinations.ai'; | 1092 | api_url = 'https://text.pollinations.ai'; |
| 1093 | api_key_openai = 'NONE'; | 1093 | api_key_openai = 'NONE'; |
| 1094 | headers = {}; | 1094 | headers = {}; |
| 1095 | } else if (request.body.chat_completion_source === CHAT_COMPLETION_SOURCES.MAKERSUITE) { | ||
| 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); | ||
| 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}`; | ||
| 1100 | |||
| 1101 | 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 | } else if (!api_key_makersuite && !request.body.reverse_proxy) { | ||
| 1104 | console.warn('Google AI Studio API key is missing.'); | ||
| 1105 | return response_getstatus_openai.status(400).send({ error: true }); | ||
| 1106 | } | ||
| 1107 | |||
| 1108 | try { | ||
| 1109 | const response = await fetch(models_url, { | ||
| 1110 | method: 'GET', | ||
| 1111 | headers: { | ||
| 1112 | 'Content-Type': 'application/json', | ||
| 1113 | }, | ||
| 1114 | }); | ||
| 1115 | |||
| 1116 | if (response.ok) { | ||
| 1117 | const data = await response.json(); | ||
| 1118 | // Transform Google AI Studio models to OpenAI format | ||
| 1119 | const models = data.models | ||
| 1120 | ?.filter(model => model.supportedGenerationMethods?.includes('generateContent')) | ||
| 1121 | ?.map(model => ({ | ||
| 1122 | id: model.name.replace('models/', ''), | ||
| 1123 | object: 'model', | ||
| 1124 | created: Date.now(), | ||
| 1125 | owned_by: 'google', | ||
| 1126 | })) || []; | ||
| 1127 | |||
| 1128 | response_getstatus_openai.send({ data: models }); | ||
| 1129 | console.info('Available Google AI Studio models:', models.map(m => m.id)); | ||
| 1130 | return; | ||
| 1131 | } else { | ||
| 1132 | console.error('Google AI Studio models endpoint failed:', response.status, response.statusText); | ||
| 1133 | return response_getstatus_openai.send({ error: true, can_bypass: true, data: { data: [] } }); | ||
| 1134 | } | ||
| 1135 | } catch (error) { | ||
| 1136 | console.error('Error fetching Google AI Studio models:', error); | ||
| 1137 | return response_getstatus_openai.send({ error: true, can_bypass: true, data: { data: [] } }); | ||
| 1138 | } | ||
| 1095 | } else { | 1139 | } else { |
| 1096 | console.warn('This chat completion source is not supported yet.'); | 1140 | console.warn('This chat completion source is not supported yet.'); |
| 1097 | return response_getstatus_openai.status(400).send({ error: true }); | 1141 | return response_getstatus_openai.status(400).send({ error: true }); |