Starter prompt pool
diff --git a/public/js/admin/clinicalAssistant.js b/public/js/admin/clinicalAssistant.js
index 322f03b1..df6441f5 100644
--- a/public/js/admin/clinicalAssistant.js
+++ b/public/js/admin/clinicalAssistant.js
@@ -1,5 +1,52 @@
export function initClinicalAssistantAdmin(adminEscapeHtml) {
let configState = 'idle';
+ const IMAGE_MODEL_FALLBACKS = ['openai-gpt-image-1', 'openai-gpt-image-1-mini', 'openai-gpt-image-1.5', 'openai-dall-e-3'];
+ let savedChatAllowed = [];
+ let savedImageAllowed = [];
+ let chatRoster = [];
+ let imageRoster = [];
+
+ function parseAssistantList(value) {
+ return String(value || '').split(',').map(function(s) { return s.trim(); }).filter(Boolean);
+ }
+ function renderAssistantCheckboxList(containerId, candidates, saved) {
+ var container = document.getElementById(containerId);
+ if (!container) return;
+ var ids = candidates.slice();
+ saved.forEach(function(id) { if (ids.indexOf(id) === -1) ids.push(id); });
+ ids = ids.filter(Boolean).filter(function(id, i, all) { return all.indexOf(id) === i; }).sort();
+ container.innerHTML = '';
+ if (!ids.length) {
+ var empty = document.createElement('p');
+ empty.style.cssText = 'margin:0;font-size:12px;color:var(--g500);';
+ empty.textContent = 'No models available. Add or enable models first.';
+ container.appendChild(empty);
+ return;
+ }
+ ids.forEach(function(id) {
+ var row = document.createElement('label');
+ row.style.cssText = 'display:flex;align-items:center;gap:6px;font-size:12px;padding:2px 0;';
+ var box = document.createElement('input');
+ box.type = 'checkbox';
+ box.value = id;
+ box.checked = saved.indexOf(id) !== -1;
+ var span = document.createElement('span');
+ span.textContent = id;
+ row.appendChild(box);
+ row.appendChild(span);
+ container.appendChild(row);
+ });
+ }
+ function checkedAssistantModels(containerId) {
+ var container = document.getElementById(containerId);
+ if (!container) return [];
+ return Array.prototype.map.call(container.querySelectorAll('input[type="checkbox"]:checked'), function(box) { return box.value; });
+ }
+ function renderAssistantImageModelCheckboxes(models) {
+ imageRoster = (Array.isArray(models) ? models : []).map(function(m) { return m.id; }).concat(IMAGE_MODEL_FALLBACKS, [window._assistantImageModelValue]);
+ renderAssistantCheckboxList('assistant-allowed-image-models', imageRoster, savedImageAllowed);
+ }
+
let imageModelsLoading = false;
document.addEventListener('tabChanged', function(e) {
@@ -80,6 +127,11 @@ export function initClinicalAssistantAdmin(adminEscapeHtml) {
chatSelect.value = savedChatModel;
}
window._assistantImageModelValue = cfg['clinical_assistant.image_model'] || '';
+ savedChatAllowed = parseAssistantList(cfg['clinical_assistant.allowed_models']);
+ savedImageAllowed = parseAssistantList(cfg['clinical_assistant.allowed_image_models']);
+ chatRoster = chatOptions().map(function(o) { return o.value; }).filter(Boolean).concat([cfg['clinical_assistant.chat_model'] || '']);
+ renderAssistantCheckboxList('assistant-allowed-chat-models', chatRoster, savedChatAllowed);
+ renderAssistantImageModelCheckboxes([]);
renderAssistantImageModels([], window._assistantImageModelValue);
setValue('assistant-search-limit', cfg['clinical_assistant.search_limit'] || '8');
setValue('assistant-context-chars', cfg['clinical_assistant.context_chars'] || '1400');
@@ -135,6 +187,7 @@ export function initClinicalAssistantAdmin(adminEscapeHtml) {
.then(function(data) {
if (!data || data.success === false || !Array.isArray(data.models) ||
!data.models.every(function(m) { return m && typeof m.id === 'string' && m.id; })) throw new Error('Invalid image models');
+ renderAssistantImageModelCheckboxes(data.models);
renderAssistantImageModels(data.models, sel.value);
})
.catch(function() {
@@ -304,7 +357,9 @@ export function initClinicalAssistantAdmin(adminEscapeHtml) {
putAssistantConfig('clinical_assistant.chat_model', getValue('assistant-chat-model')),
putAssistantConfig('clinical_assistant.search_limit', getValue('assistant-search-limit') || '8'),
putAssistantConfig('clinical_assistant.context_chars', getValue('assistant-context-chars') || '1400'),
- putAssistantConfig('clinical_assistant.translate_provider', getValue('assistant-translate-provider') || 'libretranslate')
+ putAssistantConfig('clinical_assistant.translate_provider', getValue('assistant-translate-provider') || 'libretranslate'),
+ putAssistantConfig('clinical_assistant.allowed_models', checkedAssistantModels('assistant-allowed-chat-models').join(',')),
+ putAssistantConfig('clinical_assistant.allowed_image_models', checkedAssistantModels('assistant-allowed-image-models').join(','))
]).then(function() {
if (status) status.textContent = '';
showToast('Assistant settings saved', 'success');
@@ -322,6 +377,12 @@ export function initClinicalAssistantAdmin(adminEscapeHtml) {
return data;
});
}
+ function chatOptions() {
+ var chat = document.getElementById('assistant-chat-model');
+ var out = [];
+ if (chat) Array.prototype.forEach.call(chat.options, function(o) { out.push({ value: o.value }); });
+ return out;
+ }
function getValue(id) { var el = document.getElementById(id); return el ? el.value.trim() : ''; }
function setValue(id, value) { var el = document.getElementById(id); if (el) el.value = value; }
const escAssistant = adminEscapeHtml;