fix: remove Model ID field from public models in admin
Public models are now display-only and don't require a Model ID: - Removed Model ID input field from admin.html public models section - Updated admin.js to not require or send Model ID for public models - Updated server API to accept public models without Model ID - Uses display label as the identifier for public models - Only requires Model ID for OpenCode models (which need it for execution) Public models are purely for user-facing display in the builder dropdown, while OpenCode models form the actual execution fallback chain.
This commit is contained in:
@@ -120,10 +120,6 @@
|
|||||||
</header>
|
</header>
|
||||||
<p style="margin-top:0; color: var(--muted);">These models are displayed to users in the builder dropdown for selection. This is separate from the OpenCode fallback chain.</p>
|
<p style="margin-top:0; color: var(--muted);">These models are displayed to users in the builder dropdown for selection. This is separate from the OpenCode fallback chain.</p>
|
||||||
<form id="public-model-form" class="admin-form">
|
<form id="public-model-form" class="admin-form">
|
||||||
<label>
|
|
||||||
Model ID (e.g., claude-3-5-sonnet, gpt-4o)
|
|
||||||
<input id="public-model-name" type="text" placeholder="Enter model ID manually" required />
|
|
||||||
</label>
|
|
||||||
<label>
|
<label>
|
||||||
Display name shown to users
|
Display name shown to users
|
||||||
<input id="public-model-label" type="text" placeholder="Friendly label (e.g., Claude 3.5 Sonnet)" required />
|
<input id="public-model-label" type="text" placeholder="Friendly label (e.g., Claude 3.5 Sonnet)" required />
|
||||||
|
|||||||
@@ -34,7 +34,6 @@
|
|||||||
opencodeModelsCount: document.getElementById('opencode-models-count'),
|
opencodeModelsCount: document.getElementById('opencode-models-count'),
|
||||||
// Public Models (user-facing selection)
|
// Public Models (user-facing selection)
|
||||||
publicModelForm: document.getElementById('public-model-form'),
|
publicModelForm: document.getElementById('public-model-form'),
|
||||||
publicModelName: document.getElementById('public-model-name'),
|
|
||||||
publicModelLabel: document.getElementById('public-model-label'),
|
publicModelLabel: document.getElementById('public-model-label'),
|
||||||
publicModelTier: document.getElementById('public-model-tier'),
|
publicModelTier: document.getElementById('public-model-tier'),
|
||||||
publicModelIcon: document.getElementById('public-model-icon'),
|
publicModelIcon: document.getElementById('public-model-icon'),
|
||||||
@@ -2425,16 +2424,11 @@
|
|||||||
if (el.publicModelForm) {
|
if (el.publicModelForm) {
|
||||||
el.publicModelForm.addEventListener('submit', async (e) => {
|
el.publicModelForm.addEventListener('submit', async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const name = el.publicModelName.value.trim();
|
|
||||||
const label = el.publicModelLabel.value.trim();
|
const label = el.publicModelLabel.value.trim();
|
||||||
const icon = el.publicModelIcon ? el.publicModelIcon.value : '';
|
const icon = el.publicModelIcon ? el.publicModelIcon.value : '';
|
||||||
const tier = el.publicModelTier ? el.publicModelTier.value : 'free';
|
const tier = el.publicModelTier ? el.publicModelTier.value : 'free';
|
||||||
const supportsMedia = el.publicModelMedia ? el.publicModelMedia.checked : false;
|
const supportsMedia = el.publicModelMedia ? el.publicModelMedia.checked : false;
|
||||||
|
|
||||||
if (!name) {
|
|
||||||
setPublicModelStatus('Model ID is required.', true);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!label) {
|
if (!label) {
|
||||||
setPublicModelStatus('Display name is required.', true);
|
setPublicModelStatus('Display name is required.', true);
|
||||||
return;
|
return;
|
||||||
@@ -2446,7 +2440,6 @@
|
|||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
type: 'public',
|
type: 'public',
|
||||||
name,
|
|
||||||
label,
|
label,
|
||||||
icon,
|
icon,
|
||||||
tier,
|
tier,
|
||||||
@@ -2454,7 +2447,6 @@
|
|||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
setPublicModelStatus('Saved');
|
setPublicModelStatus('Saved');
|
||||||
el.publicModelName.value = '';
|
|
||||||
el.publicModelLabel.value = '';
|
el.publicModelLabel.value = '';
|
||||||
await loadConfigured();
|
await loadConfigured();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
@@ -15861,11 +15861,15 @@ async function handleAdminModelUpsert(req, res) {
|
|||||||
if (!session) return;
|
if (!session) return;
|
||||||
try {
|
try {
|
||||||
const body = await parseJsonBody(req);
|
const body = await parseJsonBody(req);
|
||||||
|
const isPublic = body.type === 'public';
|
||||||
|
const isOpencode = body.type === 'opencode';
|
||||||
const modelName = (body.name || body.model || '').trim();
|
const modelName = (body.name || body.model || '').trim();
|
||||||
const label = (body.label || body.displayName || modelName).trim();
|
const label = (body.label || body.displayName || modelName).trim();
|
||||||
const tier = normalizeTier(body.tier);
|
const tier = normalizeTier(body.tier);
|
||||||
|
|
||||||
if (!modelName) return sendJson(res, 400, { error: 'Model name is required' });
|
// For public models, label is required; for opencode, name is required
|
||||||
|
if (isOpencode && !modelName) return sendJson(res, 400, { error: 'Model name is required' });
|
||||||
|
if (isPublic && !label) return sendJson(res, 400, { error: 'Display name is required' });
|
||||||
|
|
||||||
let icon = '';
|
let icon = '';
|
||||||
if (typeof body.icon === 'string' && body.icon.trim()) {
|
if (typeof body.icon === 'string' && body.icon.trim()) {
|
||||||
@@ -15873,9 +15877,11 @@ async function handleAdminModelUpsert(req, res) {
|
|||||||
}
|
}
|
||||||
const supportsMedia = typeof body.supportsMedia === 'boolean' ? body.supportsMedia : false;
|
const supportsMedia = typeof body.supportsMedia === 'boolean' ? body.supportsMedia : false;
|
||||||
|
|
||||||
|
// For public models, use label as the display identifier (no model ID needed)
|
||||||
|
// For opencode models, use the actual model name
|
||||||
const payload = {
|
const payload = {
|
||||||
id: body.id || randomUUID(),
|
id: body.id || randomUUID(),
|
||||||
name: modelName,
|
name: isPublic ? label : modelName,
|
||||||
label: label || modelName,
|
label: label || modelName,
|
||||||
icon,
|
icon,
|
||||||
tier,
|
tier,
|
||||||
|
|||||||
Reference in New Issue
Block a user