Clean up model structure: OpenCode Models, Chain, and Public Models
- Simplified to 3 clear sections: 1. OpenCode Models: OpenCode dropdown + display name + order buttons 2. OpenCode Chain: Fallback chain with add form + order buttons 3. Public Models: Manual entry + order buttons (completely separate) - New state variables: opencodeModels, opencodeChain, publicModels - Clean API endpoints for chain operations - Removed all confusing legacy code and naming
This commit is contained in:
@@ -67,57 +67,71 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="admin-grid">
|
||||
<!-- Provider Models Section (with OpenCode integration) -->
|
||||
<div class="admin-card">
|
||||
<header>
|
||||
<h3>Add Provider Model</h3>
|
||||
<div class="pill">OpenCode</div>
|
||||
</header>
|
||||
<p style="margin-top:0; color: var(--muted);">Add models from OpenCode that will be available to users. These models use the unified provider chain for fallback.</p>
|
||||
<form id="provider-model-form" class="admin-form">
|
||||
<!-- Section 1: OpenCode Models -->
|
||||
<div class="admin-card">
|
||||
<header>
|
||||
<h3>OpenCode Models</h3>
|
||||
<div class="pill">Backend</div>
|
||||
</header>
|
||||
<p style="margin-top:0; color: var(--muted);">Add models from OpenCode. These models process requests and use the OpenCode Chain below for fallback when rate limits are reached.</p>
|
||||
|
||||
<!-- Add Form -->
|
||||
<form id="opencode-model-form" class="admin-form" style="margin-bottom: 24px;">
|
||||
<label>
|
||||
Choose from OpenCode
|
||||
<select id="opencode-model-select"></select>
|
||||
</label>
|
||||
<label>
|
||||
Display name
|
||||
<input id="opencode-model-label" type="text" placeholder="e.g., GPT-4 Turbo" required />
|
||||
</label>
|
||||
<div class="admin-grid" style="grid-template-columns: 1fr 1fr; gap: 12px;">
|
||||
<label>
|
||||
Choose a model from OpenCode
|
||||
<select id="available-models"></select>
|
||||
</label>
|
||||
<label>
|
||||
Display name shown to users
|
||||
<input id="provider-model-label" type="text" placeholder="Friendly label (e.g., Claude 3.5 Sonnet)" required />
|
||||
</label>
|
||||
<label>
|
||||
Model tier (for plan limits)
|
||||
<select id="provider-model-tier">
|
||||
<option value="free">Free (1x multiplier)</option>
|
||||
<option value="plus">Plus (2x multiplier)</option>
|
||||
<option value="pro">Pro (3x multiplier)</option>
|
||||
Tier
|
||||
<select id="opencode-model-tier">
|
||||
<option value="free">Free (1x)</option>
|
||||
<option value="plus">Plus (2x)</option>
|
||||
<option value="pro">Pro (3x)</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
Icon (files in /assets)
|
||||
<select id="provider-model-icon">
|
||||
Icon
|
||||
<select id="opencode-model-icon">
|
||||
<option value="">No icon</option>
|
||||
</select>
|
||||
</label>
|
||||
<label style="display: flex; align-items: center; gap: 8px; margin-top: 8px;">
|
||||
<input id="provider-model-media" type="checkbox" style="width: auto;" />
|
||||
<span>Supports image uploads</span>
|
||||
</label>
|
||||
<div class="admin-actions">
|
||||
<button type="submit" class="primary">Add Provider Model</button>
|
||||
<button type="button" id="reload-available" class="ghost">Reload available models</button>
|
||||
</div>
|
||||
<div class="status-line" id="provider-model-status"></div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<label style="display: flex; align-items: center; gap: 8px; margin-top: 8px;">
|
||||
<input id="opencode-model-media" type="checkbox" style="width: auto;" />
|
||||
<span>Supports image uploads</span>
|
||||
</label>
|
||||
<div class="admin-actions">
|
||||
<button type="submit" class="primary">Add OpenCode Model</button>
|
||||
<button type="button" id="reload-opencode-models" class="ghost">Reload Models</button>
|
||||
</div>
|
||||
<div class="status-line" id="opencode-model-status"></div>
|
||||
</form>
|
||||
|
||||
<!-- Provider Chain Add Section -->
|
||||
<div class="admin-card">
|
||||
<header>
|
||||
<h3>Add to Provider Chain</h3>
|
||||
<div class="pill">Fallback</div>
|
||||
</header>
|
||||
<p style="margin-top:0; color: var(--muted);">Add providers to the unified fallback chain. When rate limits are reached or errors occur, the system automatically falls back to the next provider in this chain.</p>
|
||||
<form id="provider-chain-form" class="admin-form">
|
||||
<!-- List -->
|
||||
<header style="margin-top: 24px; border-top: 1px solid var(--border); padding-top: 16px;">
|
||||
<h3>OpenCode Models List</h3>
|
||||
<div class="pill" id="opencode-models-count">0</div>
|
||||
</header>
|
||||
<p class="muted" style="margin-top:0;">Arrange the order below. This controls which model is primary for OpenCode requests.</p>
|
||||
<div id="opencode-models-list" class="admin-list"></div>
|
||||
</div>
|
||||
|
||||
<!-- Section 2: OpenCode Chain (Fallback) -->
|
||||
<div class="admin-card" style="margin-top: 16px;">
|
||||
<header>
|
||||
<h3>OpenCode Chain</h3>
|
||||
<div class="pill">Fallback</div>
|
||||
</header>
|
||||
<p style="margin-top:0; color: var(--muted);">When rate limits are reached or errors occur, the system falls back through this chain of providers.</p>
|
||||
|
||||
<!-- Add Form -->
|
||||
<form id="chain-form" class="admin-form" style="margin-bottom: 24px;">
|
||||
<div class="admin-grid" style="grid-template-columns: 1fr 2fr; gap: 12px;">
|
||||
<label>
|
||||
Provider
|
||||
<select id="chain-provider">
|
||||
@@ -129,65 +143,66 @@
|
||||
<option value="chutes">Chutes</option>
|
||||
<option value="cerebras">Cerebras</option>
|
||||
<option value="ollama">Ollama</option>
|
||||
<option value="opencode">OpenCode</option>
|
||||
<option value="cohere">Cohere</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
Model Name
|
||||
Model ID
|
||||
<input id="chain-model" type="text" placeholder="e.g., anthropic/claude-3.5-sonnet" required />
|
||||
</label>
|
||||
<div class="admin-actions">
|
||||
<button type="submit" class="primary">Add to Chain</button>
|
||||
</div>
|
||||
<div class="status-line" id="provider-chain-status"></div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="admin-actions">
|
||||
<button type="submit" class="primary">Add to Chain</button>
|
||||
</div>
|
||||
<div class="status-line" id="chain-status"></div>
|
||||
</form>
|
||||
|
||||
<!-- List -->
|
||||
<header style="margin-top: 24px; border-top: 1px solid var(--border); padding-top: 16px;">
|
||||
<h3>Chain Order</h3>
|
||||
<div class="pill" id="chain-count">0</div>
|
||||
</header>
|
||||
<p class="muted" style="margin-top:0;">The system tries providers in this order. Use arrows to reorder.</p>
|
||||
<div id="chain-list" class="admin-list"></div>
|
||||
</div>
|
||||
|
||||
<!-- Provider Chain List with Ordering -->
|
||||
<!-- Section 3: Public Models (Completely Separate) -->
|
||||
<div class="admin-card" style="margin-top: 16px;">
|
||||
<header>
|
||||
<h3>Unified Provider Chain Order</h3>
|
||||
<div class="pill" id="provider-chain-count">0</div>
|
||||
<h3>Public Models</h3>
|
||||
<div class="pill">User-Facing</div>
|
||||
</header>
|
||||
<p class="muted" style="margin-top:0;">Arrange the order of providers below. The system will try each provider in order when rate limits are reached or errors occur. The first provider is the primary.</p>
|
||||
<div id="provider-chain-list" class="admin-list"></div>
|
||||
</div>
|
||||
|
||||
<!-- Public-Facing Models Section -->
|
||||
<div class="admin-card" style="margin-top: 16px;">
|
||||
<header>
|
||||
<h3>Public-Facing Models</h3>
|
||||
<div class="pill">Public</div>
|
||||
</header>
|
||||
<p style="margin-top:0; color: var(--muted);">These models are displayed to users in the builder dropdown. They are separate from the provider models and can be used to create curated model lists for users.</p>
|
||||
<form id="public-model-form" class="admin-form" style="margin-bottom: 16px;">
|
||||
<div class="admin-grid" style="grid-template-columns: 1fr 1fr;">
|
||||
<p style="margin-top:0; color: var(--muted);">These models are displayed to users in the builder dropdown. They are completely separate from OpenCode models.</p>
|
||||
|
||||
<!-- Add Form -->
|
||||
<form id="public-model-form" class="admin-form" style="margin-bottom: 24px;">
|
||||
<div class="admin-grid" style="grid-template-columns: 1fr 1fr; gap: 12px;">
|
||||
<label>
|
||||
Model ID
|
||||
<input id="public-model-name" type="text" placeholder="e.g., custom-model-1" required />
|
||||
<input id="public-model-name" type="text" placeholder="e.g., my-custom-model" required />
|
||||
</label>
|
||||
<label>
|
||||
Display name
|
||||
<input id="public-model-label" type="text" placeholder="Friendly label" required />
|
||||
<input id="public-model-label" type="text" placeholder="e.g., My Custom Model" required />
|
||||
</label>
|
||||
</div>
|
||||
<label>
|
||||
Model tier
|
||||
<select id="public-model-tier">
|
||||
<option value="free">Free (1x multiplier)</option>
|
||||
<option value="plus">Plus (2x multiplier)</option>
|
||||
<option value="pro">Pro (3x multiplier)</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
Icon (files in /assets)
|
||||
<select id="public-model-icon">
|
||||
<option value="">No icon</option>
|
||||
</select>
|
||||
</label>
|
||||
<label style="display: flex; align-items: center; gap: 8px; margin-top: 8px;">
|
||||
<div class="admin-grid" style="grid-template-columns: 1fr 1fr; gap: 12px; margin-top: 12px;">
|
||||
<label>
|
||||
Tier
|
||||
<select id="public-model-tier">
|
||||
<option value="free">Free (1x)</option>
|
||||
<option value="plus">Plus (2x)</option>
|
||||
<option value="pro">Pro (3x)</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
Icon
|
||||
<select id="public-model-icon">
|
||||
<option value="">No icon</option>
|
||||
</select>
|
||||
</label>
|
||||
</div>
|
||||
<label style="display: flex; align-items: center; gap: 8px; margin-top: 12px;">
|
||||
<input id="public-model-media" type="checkbox" style="width: auto;" />
|
||||
<span>Supports image uploads</span>
|
||||
</label>
|
||||
@@ -196,60 +211,18 @@
|
||||
</div>
|
||||
<div class="status-line" id="public-model-status"></div>
|
||||
</form>
|
||||
|
||||
<header style="margin-top: 24px;">
|
||||
|
||||
<!-- List -->
|
||||
<header style="margin-top: 24px; border-top: 1px solid var(--border); padding-top: 16px;">
|
||||
<h3>Public Models List</h3>
|
||||
<div class="pill" id="public-models-count">0</div>
|
||||
</header>
|
||||
<p class="muted" style="margin-top:0;">These are shown to users. Use arrows to reorder.</p>
|
||||
<div id="public-models-list" class="admin-list"></div>
|
||||
</div>
|
||||
|
||||
<!-- Other Admin Sections -->
|
||||
<div class="admin-grid" style="margin-top: 16px;">
|
||||
<!-- Legacy Model Form (hidden but kept for compatibility) -->
|
||||
<div class="admin-card" style="display: none;">
|
||||
<header>
|
||||
<h3>Add / Update Model (Legacy)</h3>
|
||||
<div class="pill">Step 1</div>
|
||||
</header>
|
||||
<form id="model-form" class="admin-form">
|
||||
<label>
|
||||
Choose a model from OpenCode
|
||||
<select id="available-models"></select>
|
||||
</label>
|
||||
<label>
|
||||
Display name shown to users
|
||||
<input id="display-label" type="text" placeholder="Friendly label (e.g. Fast GPT-4)" required />
|
||||
</label>
|
||||
<label>
|
||||
Model tier (for plan limits)
|
||||
<select id="model-tier">
|
||||
<option value="free">Free (1x multiplier)</option>
|
||||
<option value="plus">Plus (2x multiplier)</option>
|
||||
<option value="pro">Pro (3x multiplier)</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
Icon (files in /assets)
|
||||
<select id="icon-select">
|
||||
<option value="">No icon</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
Provider priority (comma separated provider:model)
|
||||
<input id="provider-order" type="text" placeholder="openrouter:anthropic/claude-3.5-sonnet, mistral:mistral-large-latest" />
|
||||
</label>
|
||||
<label style="display: flex; align-items: center; gap: 8px; margin-top: 8px;">
|
||||
<input id="supports-media" type="checkbox" style="width: auto;" />
|
||||
<span>Supports image uploads</span>
|
||||
</label>
|
||||
<div class="admin-actions">
|
||||
<button type="submit" class="primary">Save model</button>
|
||||
<button type="button" id="reload-available" class="ghost">Reload available models</button>
|
||||
</div>
|
||||
<div class="status-line" id="admin-status"></div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="admin-card">
|
||||
<header>
|
||||
<h3>System Actions</h3>
|
||||
@@ -261,136 +234,18 @@
|
||||
<div class="status-line" id="cancel-messages-status"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="admin-card">
|
||||
<header>
|
||||
<h3>Icon Library</h3>
|
||||
<div class="pill">Step 0</div>
|
||||
<div class="pill">Assets</div>
|
||||
</header>
|
||||
<p style="margin-top:0; color: var(--muted);">Upload icon files to <strong>/chat/public/assets</strong> and pick them here. PNG, JPG, SVG, and WEBP are supported.</p>
|
||||
<p style="margin-top:0; color: var(--muted);">Upload icon files to <strong>/chat/public/assets</strong>. PNG, JPG, SVG, and WEBP are supported.</p>
|
||||
<div id="icon-list" class="admin-list"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="admin-card" style="margin-top: 16px;">
|
||||
<header>
|
||||
<h3>OpenCode Ultimate Backup Model</h3>
|
||||
<div class="pill">Fallback</div>
|
||||
</header>
|
||||
<p style="margin-top:0; color: var(--muted);">Configure the ultimate fallback model that will be used when all providers fail. This is the last-resort backup for reliability.</p>
|
||||
<form id="opencode-backup-form" class="admin-form">
|
||||
<label>
|
||||
OpenCode backup model
|
||||
<select id="opencode-backup"></select>
|
||||
</label>
|
||||
<div class="admin-actions">
|
||||
<button type="submit" class="primary">Save backup model</button>
|
||||
</div>
|
||||
<div class="status-line" id="opencode-backup-status"></div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="admin-card" style="margin-top: 16px;">
|
||||
<header>
|
||||
<h3>Auto Model for Hobby/Free Plan</h3>
|
||||
<div class="pill">Free Plan</div>
|
||||
</header>
|
||||
<p style="margin-top:0; color: var(--muted);">Select which model Hobby and Free plan users will automatically use. Paid plan users can select their own models.</p>
|
||||
<form id="auto-model-form" class="admin-form">
|
||||
<label>
|
||||
Model for hobby/free users
|
||||
<select id="auto-model-select">
|
||||
<option value="">Auto (use first configured model)</option>
|
||||
</select>
|
||||
</label>
|
||||
<div class="admin-actions">
|
||||
<button type="submit" class="primary">Save auto model</button>
|
||||
</div>
|
||||
<div class="status-line" id="auto-model-status"></div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="admin-grid" style="margin-top: 16px;">
|
||||
<div class="admin-card">
|
||||
<header>
|
||||
<h3>Provider Limits & Usage</h3>
|
||||
<div class="pill">Rate limits</div>
|
||||
</header>
|
||||
<p style="margin-top:0; color: var(--muted);">Configure token/request limits per provider or per model and monitor current usage.</p>
|
||||
<form id="provider-limit-form" class="admin-form">
|
||||
<label>
|
||||
Provider
|
||||
<select id="limit-provider">
|
||||
<option value="openrouter">OpenRouter</option>
|
||||
<option value="mistral">Mistral</option>
|
||||
<option value="google">Google</option>
|
||||
<option value="groq">Groq</option>
|
||||
<option value="nvidia">NVIDIA</option>
|
||||
<option value="chutes">Chutes</option>
|
||||
<option value="cerebras">Cerebras</option>
|
||||
<option value="ollama">Ollama</option>
|
||||
<option value="opencode">OpenCode</option>
|
||||
<option value="cohere">Cohere</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
Scope
|
||||
<select id="limit-scope">
|
||||
<option value="provider">Per Provider</option>
|
||||
<option value="model">Per Model</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
Model (for per-model limits)
|
||||
<select id="limit-model">
|
||||
<option value="">Any model</option>
|
||||
</select>
|
||||
</label>
|
||||
<label>
|
||||
Tokens per minute
|
||||
<input id="limit-tpm" type="number" min="0" step="1" placeholder="0 = unlimited" />
|
||||
</label>
|
||||
<label>
|
||||
Tokens per hour
|
||||
<input id="limit-tph" type="number" min="0" step="1" placeholder="0 = unlimited" />
|
||||
</label>
|
||||
<label>
|
||||
Tokens per day
|
||||
<input id="limit-tpd" type="number" min="0" step="1" placeholder="0 = unlimited" />
|
||||
</label>
|
||||
<label>
|
||||
Requests per minute
|
||||
<input id="limit-rpm" type="number" min="0" step="1" placeholder="0 = unlimited" />
|
||||
</label>
|
||||
<label>
|
||||
Requests per hour
|
||||
<input id="limit-rph" type="number" min="0" step="1" placeholder="0 = unlimited" />
|
||||
</label>
|
||||
<label>
|
||||
Requests per day
|
||||
<input id="limit-rpd" type="number" min="0" step="1" placeholder="0 = unlimited" />
|
||||
</label>
|
||||
<div class="admin-actions">
|
||||
<button type="submit" class="primary">Save limits</button>
|
||||
</div>
|
||||
<div class="status-line" id="provider-limit-status"></div>
|
||||
</form>
|
||||
<div id="provider-usage" class="admin-list"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Public Models List -->
|
||||
<div class="admin-card" style="margin-top: 16px;">
|
||||
<header>
|
||||
<h3>Public-Facing Models</h3>
|
||||
<div class="pill" id="configured-count">0</div>
|
||||
</header>
|
||||
<p class="muted" style="margin-top:0;">These models are displayed to users in the builder. All models use the unified provider chain above for fallback.</p>
|
||||
<div id="configured-list" class="admin-list"></div>
|
||||
</div>
|
||||
</main>
|
||||
<script src="/admin.js"></script>
|
||||
</div>
|
||||
<script src="/admin.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
3318
chat/public/admin.js
3318
chat/public/admin.js
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user