mirror of
https://gitlab.com/Zer0interrupt/recipe-manager.git
synced 2026-11-01 23:24:11 -05:00
Update default model list from live API discovery and filter out TTS/music/agent models
This commit is contained in:
parent
ca6d9b2db6
commit
454f676499
4 changed files with 31 additions and 24 deletions
|
|
@ -2035,15 +2035,17 @@ function populateModelDropdown(models, selectedModel) {
|
||||||
const select = elements.settingsGeminiModelSelect;
|
const select = elements.settingsGeminiModelSelect;
|
||||||
select.innerHTML = '';
|
select.innerHTML = '';
|
||||||
|
|
||||||
const targetModel = selectedModel || 'gemini-2.0-flash';
|
const targetModel = selectedModel || 'gemini-2.5-flash';
|
||||||
let foundTarget = false;
|
let foundTarget = false;
|
||||||
|
|
||||||
models.forEach(m => {
|
models.forEach(m => {
|
||||||
const opt = document.createElement('option');
|
const opt = document.createElement('option');
|
||||||
opt.value = m.id;
|
opt.value = m.id;
|
||||||
opt.textContent = m.displayName || m.id;
|
opt.textContent = m.displayName || m.id;
|
||||||
if (m.id === 'gemini-2.0-flash') {
|
if (m.id === 'gemini-2.5-flash') {
|
||||||
opt.textContent = `${m.displayName || 'Gemini 2.0 Flash'} (Recommended)`;
|
opt.textContent = `${m.displayName || 'Gemini 2.5 Flash'} (Stable Recommended)`;
|
||||||
|
} else if (m.id === 'gemini-3.8-flash') {
|
||||||
|
opt.textContent = `${m.displayName || 'Gemini 3.8 Flash'} (Newest Flash)`;
|
||||||
}
|
}
|
||||||
if (m.id === targetModel) {
|
if (m.id === targetModel) {
|
||||||
opt.selected = true;
|
opt.selected = true;
|
||||||
|
|
@ -2073,9 +2075,10 @@ async function fetchModelsDirectFromGoogle(key) {
|
||||||
if (!Array.isArray(googleData.models)) {
|
if (!Array.isArray(googleData.models)) {
|
||||||
throw new Error('Unexpected response format from Google API.');
|
throw new Error('Unexpected response format from Google API.');
|
||||||
}
|
}
|
||||||
|
const excludedPatterns = /embedding|aqa|imagen|tts|lyria|banana|-image|robotics|computer-use|deep-research|antigravity|customtools/i;
|
||||||
const models = googleData.models
|
const models = googleData.models
|
||||||
.filter(m => Array.isArray(m.supportedGenerationMethods) && m.supportedGenerationMethods.includes('generateContent'))
|
.filter(m => Array.isArray(m.supportedGenerationMethods) && m.supportedGenerationMethods.includes('generateContent'))
|
||||||
.filter(m => !m.name.includes('embedding') && !m.name.includes('aqa') && !m.name.includes('imagen'))
|
.filter(m => !excludedPatterns.test(m.name) && !excludedPatterns.test(m.displayName || ''))
|
||||||
.map(m => {
|
.map(m => {
|
||||||
const modelId = m.name.replace(/^models\//, '');
|
const modelId = m.name.replace(/^models\//, '');
|
||||||
return {
|
return {
|
||||||
|
|
@ -2090,7 +2093,7 @@ async function fetchModelsDirectFromGoogle(key) {
|
||||||
const bIsFlash = b.id.toLowerCase().includes('flash');
|
const bIsFlash = b.id.toLowerCase().includes('flash');
|
||||||
if (aIsFlash && !bIsFlash) return -1;
|
if (aIsFlash && !bIsFlash) return -1;
|
||||||
if (!aIsFlash && bIsFlash) return 1;
|
if (!aIsFlash && bIsFlash) return 1;
|
||||||
return a.id.localeCompare(b.id);
|
return b.id.localeCompare(a.id);
|
||||||
});
|
});
|
||||||
return models;
|
return models;
|
||||||
}
|
}
|
||||||
|
|
@ -2145,7 +2148,7 @@ async function handleDiscoverModels(showNotice = true) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (models.length > 0) {
|
if (models.length > 0) {
|
||||||
const currentSelected = elements.settingsGeminiModelSelect ? elements.settingsGeminiModelSelect.value : 'gemini-2.0-flash';
|
const currentSelected = elements.settingsGeminiModelSelect ? elements.settingsGeminiModelSelect.value : 'gemini-2.5-flash';
|
||||||
populateModelDropdown(models, currentSelected);
|
populateModelDropdown(models, currentSelected);
|
||||||
if (elements.modelsStatusHint) {
|
if (elements.modelsStatusHint) {
|
||||||
elements.modelsStatusHint.textContent = `Discovered ${models.length} compatible models.`;
|
elements.modelsStatusHint.textContent = `Discovered ${models.length} compatible models.`;
|
||||||
|
|
@ -2211,7 +2214,7 @@ async function openSettingsModal() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (elements.settingsGeminiModelSelect) {
|
if (elements.settingsGeminiModelSelect) {
|
||||||
const savedModel = settings.geminiModel || 'gemini-2.0-flash';
|
const savedModel = (!settings.geminiModel || settings.geminiModel === 'gemini-2.0-flash') ? 'gemini-2.5-flash' : settings.geminiModel;
|
||||||
let exists = false;
|
let exists = false;
|
||||||
for (let i = 0; i < elements.settingsGeminiModelSelect.options.length; i++) {
|
for (let i = 0; i < elements.settingsGeminiModelSelect.options.length; i++) {
|
||||||
if (elements.settingsGeminiModelSelect.options[i].value === savedModel) {
|
if (elements.settingsGeminiModelSelect.options[i].value === savedModel) {
|
||||||
|
|
@ -2243,7 +2246,7 @@ async function handleSaveSettings(e) {
|
||||||
elements.settingsStatusMsg.style.display = 'none';
|
elements.settingsStatusMsg.style.display = 'none';
|
||||||
|
|
||||||
const key = elements.settingsGeminiKeyInput.value.trim();
|
const key = elements.settingsGeminiKeyInput.value.trim();
|
||||||
const model = elements.settingsGeminiModelSelect ? elements.settingsGeminiModelSelect.value : 'gemini-2.0-flash';
|
const model = elements.settingsGeminiModelSelect ? elements.settingsGeminiModelSelect.value : 'gemini-2.5-flash';
|
||||||
const defaultConsolidate = elements.settingsDefaultConsolidate ? elements.settingsDefaultConsolidate.checked : true;
|
const defaultConsolidate = elements.settingsDefaultConsolidate ? elements.settingsDefaultConsolidate.checked : true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
@ -2417,7 +2420,8 @@ async function scanRecipeFile(file) {
|
||||||
}
|
}
|
||||||
const settings = await settingsResponse.json();
|
const settings = await settingsResponse.json();
|
||||||
const apiKey = settings.geminiApiKey ? settings.geminiApiKey.trim() : '';
|
const apiKey = settings.geminiApiKey ? settings.geminiApiKey.trim() : '';
|
||||||
const geminiModel = settings.geminiModel ? settings.geminiModel.trim() : 'gemini-2.0-flash';
|
const rawModel = settings.geminiModel ? settings.geminiModel.trim() : '';
|
||||||
|
const geminiModel = (!rawModel || rawModel === 'gemini-2.0-flash') ? 'gemini-2.5-flash' : rawModel;
|
||||||
const isPlaceholder = apiKey === 'PASTE_YOUR_GEMINI_API_KEY_HERE' || apiKey === '';
|
const isPlaceholder = apiKey === 'PASTE_YOUR_GEMINI_API_KEY_HERE' || apiKey === '';
|
||||||
|
|
||||||
if (!apiKey || isPlaceholder) {
|
if (!apiKey || isPlaceholder) {
|
||||||
|
|
|
||||||
|
|
@ -1036,9 +1036,11 @@
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<select id="settings-gemini-model" style="width: 100%; height: 40px; border-radius: var(--border-radius-md); border: 1px solid var(--border-color); background: var(--bg-card, #1e2430); color: var(--text-main); padding-left: 12px; padding-right: 12px; font-size: 0.85rem; cursor: pointer;">
|
<select id="settings-gemini-model" style="width: 100%; height: 40px; border-radius: var(--border-radius-md); border: 1px solid var(--border-color); background: var(--bg-card, #1e2430); color: var(--text-main); padding-left: 12px; padding-right: 12px; font-size: 0.85rem; cursor: pointer;">
|
||||||
<option value="gemini-2.0-flash">Gemini 2.0 Flash (Recommended)</option>
|
<option value="gemini-2.5-flash">Gemini 2.5 Flash (Stable Recommended)</option>
|
||||||
<option value="gemini-1.5-flash">Gemini 1.5 Flash</option>
|
<option value="gemini-3.8-flash">Gemini 3.8 Flash (Newest Flash)</option>
|
||||||
<option value="gemini-1.5-pro">Gemini 1.5 Pro</option>
|
<option value="gemini-flash-latest">Gemini Flash Latest</option>
|
||||||
|
<option value="gemini-2.5-pro">Gemini 2.5 Pro</option>
|
||||||
|
<option value="gemini-4-argon">Gemini 4 Argon</option>
|
||||||
</select>
|
</select>
|
||||||
<span id="models-status-hint" style="font-size: 0.75rem; color: var(--text-muted); margin-top: 4px; display: block;">Powers both recipe photo scanning and AI text polishing.</span>
|
<span id="models-status-hint" style="font-size: 0.75rem; color: var(--text-muted); margin-top: 4px; display: block;">Powers both recipe photo scanning and AI text polishing.</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
{
|
{
|
||||||
"geminiApiKey": "PASTE_YOUR_GEMINI_API_KEY_HERE",
|
"geminiApiKey": "PASTE_YOUR_GEMINI_API_KEY_HERE",
|
||||||
"geminiModel": "gemini-2.0-flash"
|
"geminiModel": "gemini-2.5-flash"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
23
server.js
23
server.js
|
|
@ -82,7 +82,7 @@ db.prepare(`
|
||||||
db.prepare(`
|
db.prepare(`
|
||||||
CREATE TABLE IF NOT EXISTS settings (
|
CREATE TABLE IF NOT EXISTS settings (
|
||||||
geminiApiKey TEXT DEFAULT '',
|
geminiApiKey TEXT DEFAULT '',
|
||||||
geminiModel TEXT DEFAULT 'gemini-2.0-flash'
|
geminiModel TEXT DEFAULT 'gemini-2.5-flash'
|
||||||
)
|
)
|
||||||
`).run();
|
`).run();
|
||||||
|
|
||||||
|
|
@ -193,16 +193,16 @@ try {
|
||||||
db.prepare("ALTER TABLE backup_history ADD COLUMN userSummary TEXT NOT NULL DEFAULT '[]'").run();
|
db.prepare("ALTER TABLE backup_history ADD COLUMN userSummary TEXT NOT NULL DEFAULT '[]'").run();
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
try {
|
try {
|
||||||
db.prepare("ALTER TABLE settings ADD COLUMN geminiModel TEXT DEFAULT 'gemini-2.0-flash'").run();
|
db.prepare("ALTER TABLE settings ADD COLUMN geminiModel TEXT DEFAULT 'gemini-2.5-flash'").run();
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
try {
|
try {
|
||||||
db.prepare("UPDATE settings SET geminiModel = 'gemini-2.0-flash' WHERE geminiModel IS NULL OR geminiModel = ''").run();
|
db.prepare("UPDATE settings SET geminiModel = 'gemini-2.5-flash' WHERE geminiModel IS NULL OR geminiModel = '' OR geminiModel = 'gemini-2.0-flash'").run();
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
|
|
||||||
// Initialize single settings record if empty
|
// Initialize single settings record if empty
|
||||||
const settingsCount = db.prepare('SELECT COUNT(*) as count FROM settings').get().count;
|
const settingsCount = db.prepare('SELECT COUNT(*) as count FROM settings').get().count;
|
||||||
if (settingsCount === 0) {
|
if (settingsCount === 0) {
|
||||||
db.prepare('INSERT INTO settings (geminiApiKey, geminiModel) VALUES (?, ?)').run('', 'gemini-2.0-flash');
|
db.prepare('INSERT INTO settings (geminiApiKey, geminiModel) VALUES (?, ?)').run('', 'gemini-2.5-flash');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensure default system_admin and admin user profiles exist
|
// Ensure default system_admin and admin user profiles exist
|
||||||
|
|
@ -1587,7 +1587,7 @@ app.post('/api/recipes/ai-polish', requireAuth, async (req, res) => {
|
||||||
|
|
||||||
const settingsRow = db.prepare('SELECT geminiApiKey, geminiModel FROM settings LIMIT 1').get();
|
const settingsRow = db.prepare('SELECT geminiApiKey, geminiModel FROM settings LIMIT 1').get();
|
||||||
const geminiKey = settingsRow?.geminiApiKey?.trim();
|
const geminiKey = settingsRow?.geminiApiKey?.trim();
|
||||||
const geminiModel = settingsRow?.geminiModel?.trim() || 'gemini-2.0-flash';
|
const geminiModel = settingsRow?.geminiModel?.trim() || 'gemini-2.5-flash';
|
||||||
const isPlaceholder = !geminiKey || geminiKey === 'PASTE_YOUR_GEMINI_API_KEY_HERE';
|
const isPlaceholder = !geminiKey || geminiKey === 'PASTE_YOUR_GEMINI_API_KEY_HERE';
|
||||||
|
|
||||||
if (isPlaceholder) {
|
if (isPlaceholder) {
|
||||||
|
|
@ -1654,7 +1654,7 @@ app.get('/api/settings', requireAuth, (req, res) => {
|
||||||
const defaultConsolidateLists = userRow ? userRow.defaultConsolidateLists !== 0 : true;
|
const defaultConsolidateLists = userRow ? userRow.defaultConsolidateLists !== 0 : true;
|
||||||
res.json({
|
res.json({
|
||||||
geminiApiKey: settings ? settings.geminiApiKey : '',
|
geminiApiKey: settings ? settings.geminiApiKey : '',
|
||||||
geminiModel: (settings && settings.geminiModel) ? settings.geminiModel : 'gemini-2.0-flash',
|
geminiModel: (settings && settings.geminiModel) ? settings.geminiModel : 'gemini-2.5-flash',
|
||||||
defaultConsolidateLists
|
defaultConsolidateLists
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
@ -1671,7 +1671,7 @@ app.post('/api/settings', requireAuth, (req, res) => {
|
||||||
db.prepare('UPDATE settings SET geminiApiKey = ?').run(geminiApiKey || '');
|
db.prepare('UPDATE settings SET geminiApiKey = ?').run(geminiApiKey || '');
|
||||||
}
|
}
|
||||||
if (geminiModel !== undefined) {
|
if (geminiModel !== undefined) {
|
||||||
db.prepare('UPDATE settings SET geminiModel = ?').run(geminiModel || 'gemini-2.0-flash');
|
db.prepare('UPDATE settings SET geminiModel = ?').run(geminiModel || 'gemini-2.5-flash');
|
||||||
}
|
}
|
||||||
if (typeof defaultConsolidateLists === 'boolean') {
|
if (typeof defaultConsolidateLists === 'boolean') {
|
||||||
db.prepare('UPDATE users SET defaultConsolidateLists = ? WHERE id = ?').run(defaultConsolidateLists ? 1 : 0, req.user.id);
|
db.prepare('UPDATE users SET defaultConsolidateLists = ? WHERE id = ?').run(defaultConsolidateLists ? 1 : 0, req.user.id);
|
||||||
|
|
@ -1681,7 +1681,7 @@ app.post('/api/settings', requireAuth, (req, res) => {
|
||||||
const userRow = db.prepare('SELECT defaultConsolidateLists FROM users WHERE id = ?').get(req.user.id);
|
const userRow = db.prepare('SELECT defaultConsolidateLists FROM users WHERE id = ?').get(req.user.id);
|
||||||
res.json({
|
res.json({
|
||||||
geminiApiKey: settings ? settings.geminiApiKey : '',
|
geminiApiKey: settings ? settings.geminiApiKey : '',
|
||||||
geminiModel: (settings && settings.geminiModel) ? settings.geminiModel : 'gemini-2.0-flash',
|
geminiModel: (settings && settings.geminiModel) ? settings.geminiModel : 'gemini-2.5-flash',
|
||||||
defaultConsolidateLists: userRow ? userRow.defaultConsolidateLists !== 0 : true
|
defaultConsolidateLists: userRow ? userRow.defaultConsolidateLists !== 0 : true
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
@ -1707,9 +1707,10 @@ app.post('/api/settings/discover-models', requireAuth, async (req, res) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
if (response.data && Array.isArray(response.data.models)) {
|
if (response.data && Array.isArray(response.data.models)) {
|
||||||
|
const excludedPatterns = /embedding|aqa|imagen|tts|lyria|banana|-image|robotics|computer-use|deep-research|antigravity|customtools/i;
|
||||||
const models = response.data.models
|
const models = response.data.models
|
||||||
.filter(m => Array.isArray(m.supportedGenerationMethods) && m.supportedGenerationMethods.includes('generateContent'))
|
.filter(m => Array.isArray(m.supportedGenerationMethods) && m.supportedGenerationMethods.includes('generateContent'))
|
||||||
.filter(m => !m.name.includes('embedding') && !m.name.includes('aqa') && !m.name.includes('imagen'))
|
.filter(m => !excludedPatterns.test(m.name) && !excludedPatterns.test(m.displayName || ''))
|
||||||
.map(m => {
|
.map(m => {
|
||||||
const modelId = m.name.replace(/^models\//, '');
|
const modelId = m.name.replace(/^models\//, '');
|
||||||
return {
|
return {
|
||||||
|
|
@ -1719,13 +1720,13 @@ app.post('/api/settings/discover-models', requireAuth, async (req, res) => {
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
// Sort models: Flash models first, then by ID
|
// Sort models: Flash models first, then Pro, then others
|
||||||
models.sort((a, b) => {
|
models.sort((a, b) => {
|
||||||
const aIsFlash = a.id.toLowerCase().includes('flash');
|
const aIsFlash = a.id.toLowerCase().includes('flash');
|
||||||
const bIsFlash = b.id.toLowerCase().includes('flash');
|
const bIsFlash = b.id.toLowerCase().includes('flash');
|
||||||
if (aIsFlash && !bIsFlash) return -1;
|
if (aIsFlash && !bIsFlash) return -1;
|
||||||
if (!aIsFlash && bIsFlash) return 1;
|
if (!aIsFlash && bIsFlash) return 1;
|
||||||
return a.id.localeCompare(b.id);
|
return b.id.localeCompare(a.id);
|
||||||
});
|
});
|
||||||
|
|
||||||
return res.json({ models });
|
return res.json({ models });
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue