49 lines
3.6 KiB
JavaScript
49 lines
3.6 KiB
JavaScript
// One image-model setting for the whole app: choose from discovered models, applied to both workflows.
|
|
import { imageJson } from '../generatedImages.js';
|
|
let loading = false;
|
|
let loaded = false;
|
|
let select; let budgetClinical; let budgetLearning; let save; let status;
|
|
|
|
async function load() {
|
|
const root = document.getElementById('workflow-image-settings');
|
|
if (!root || loaded || loading) return;
|
|
loading = true;
|
|
try {
|
|
const [settings, models] = await Promise.all([
|
|
imageJson('/api/admin/image-settings'),
|
|
imageJson('/api/admin/config/image-models/discover').catch(() => ({ success: false }))
|
|
]);
|
|
root.textContent = '';
|
|
const form = document.createElement('form');
|
|
const heading = document.createElement('h4'); heading.textContent = 'Image model';
|
|
select = document.createElement('select'); select.className = 'prompt-select';
|
|
select.style.cssText = 'display:block;max-width:100%;font-size:13px;padding:4px 8px;border:1px solid var(--g300);border-radius:6px;';
|
|
const known = new Set([settings.workflows.clinical_assistant.model, settings.workflows.learning_hub.model]);
|
|
const options = [];
|
|
(Array.isArray(models.models) ? models.models : []).forEach(m => { if (m && typeof m.id === 'string' && m.id) { options.push(m.id); known.add(m.id); } });
|
|
const current = settings.workflows.clinical_assistant.model || settings.workflows.learning_hub.model;
|
|
[...new Set([...known])].forEach(id => { const o = document.createElement('option'); o.value = id; o.textContent = id; select.appendChild(o); });
|
|
if (current) select.value = current;
|
|
const label1 = document.createElement('label'); label1.textContent = 'Clinical image input budget (UTF-16 code units) ';
|
|
budgetClinical = document.createElement('input'); budgetClinical.type = 'number'; budgetClinical.min = '1000'; budgetClinical.max = '32000'; budgetClinical.required = true; budgetClinical.value = settings.workflows.clinical_assistant.budget; label1.append(budgetClinical);
|
|
const label2 = document.createElement('label'); label2.textContent = 'Learning image input budget (UTF-16 code units) ';
|
|
budgetLearning = document.createElement('input'); budgetLearning.type = 'number'; budgetLearning.min = '1000'; budgetLearning.max = '32000'; budgetLearning.required = true; budgetLearning.value = settings.workflows.learning_hub.budget; label2.append(budgetLearning);
|
|
save = document.createElement('button'); save.type = 'submit'; save.className = 'btn-sm btn-primary'; save.textContent = 'Save image settings';
|
|
status = document.createElement('p'); status.setAttribute('role', 'status');
|
|
form.append(heading, select, label1, label2, save, status);
|
|
form.onsubmit = async e => {
|
|
e.preventDefault(); if (save.disabled) return; save.disabled = true;
|
|
try {
|
|
// One model chosen once, applied to both workflows.
|
|
for (const workflow of ['clinical_assistant', 'learning_hub']) {
|
|
await imageJson('/api/admin/image-settings/' + workflow, { method: 'PUT', body: JSON.stringify({ model: select.value, budget: Number(workflow === 'clinical_assistant' ? budgetClinical.value : budgetLearning.value) }) });
|
|
}
|
|
status.textContent = 'Saved. New jobs use these settings; existing jobs are unchanged.';
|
|
} catch (error) { status.textContent = error.message + ' Nothing was saved.'; } finally { save.disabled = false; }
|
|
};
|
|
root.append(form);
|
|
loaded = true;
|
|
} catch (_) { /* Next tab entry retries; no drafts are touched. */ }
|
|
finally { loading = false; }
|
|
}
|
|
document.addEventListener('tabChanged', e => { if (e.detail?.tab === 'admin') load(); });
|