// Separate from the existing clinical model form; loading never replaces a draft. import { imageJson } from '../generatedImages.js'; let loading = false; async function load() { const root = document.getElementById('workflow-image-settings'); if (!root || root.children.length || loading) return; loading = true; try { const data = await imageJson('/api/admin/image-settings'); for (const workflow of ['clinical_assistant', 'learning_hub']) { const form = document.createElement('form'); const heading = document.createElement('h4'); heading.textContent = workflow === 'learning_hub' ? 'Learning Hub image model and budget' : 'Clinical Assistant image budget'; const help = document.createElement('p'); help.textContent = 'Budget: full original request + tool description + workflow/output/layout instructions + selected preceding context, in UTF-16 code units. Default 32,000; allowed 1,000–32,000. Conservative allowance, not an average or computed model token limit. Mandatory overflow is rejected; only whole recent context turns are included. Original chats and drafts are never truncated.'; const label = document.createElement('label'); label.textContent = 'Image input budget (UTF-16 code units) '; const budget = document.createElement('input'); budget.type = 'number'; budget.min = '1000'; budget.max = '32000'; budget.step = '1'; budget.required = true; budget.value = data.workflows[workflow].budget; label.append(budget); form.append(heading, help, label); let model; if (workflow === 'learning_hub') { const ml = document.createElement('label'); ml.textContent = 'Learning image model ID (configured LiteLLM gateway only) '; model = document.createElement('input'); model.required = true; model.value = data.workflows[workflow].model; model.maxLength = 200; ml.append(model); form.append(ml); } const save = document.createElement('button'); save.type = 'submit'; save.textContent = 'Save image settings'; const status = document.createElement('p'); status.setAttribute('role', 'status'); form.append(save, status); form.onsubmit = async e => { e.preventDefault(); if (save.disabled) return; save.disabled = true; try { await imageJson('/api/admin/image-settings/' + workflow, { method: 'PUT', body: JSON.stringify({ budget: Number(budget.value), ...(model ? { model: model.value } : {}) }) }); status.textContent = 'Saved. New jobs snapshot these settings; existing jobs are unchanged.'; } catch (error) { status.textContent = error.message + ' Draft preserved.'; } finally { save.disabled = false; } }; root.append(form); } } catch (_) { /* Next tab entry retries, without touching prompt drafts. */ } finally { loading = false; } } document.addEventListener('tabChanged', e => { if (e.detail?.tab === 'admin') load(); });