Files
shopify-ai-backup/chat/public/admin.html
southseact-3d f5fee2ac4d Remove freePlanModel and opencodeBackupModel settings
Users now use OpenCode Models (Fallback Chain) for model selection.
- Removed Auto Model for Hobby/Free Plan section from admin panel
- Removed OpenCode Ultimate Backup Model section from admin panel
- Updated server to use opencodeModels for free plan users
- Removed backup model fallback logic (opencodeModels chain handles this)
2026-02-19 13:25:54 +00:00

319 lines
13 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Admin Panel</title>
<link rel="stylesheet" href="/styles.css" />
<style>
/* Build page uses a single-column admin layout for clarity */
body[data-page="build"] .admin-grid {
grid-template-columns: none !important;
gap: 12px !important;
}
body[data-page="build"] .admin-grid .admin-card {
width: 100% !important;
}
/* Slightly tighten cards on the build page */
body[data-page="build"] .admin-card { padding: 12px; }
</style>
<!-- PostHog Analytics -->
<script src="/posthog.js"></script>
</head>
<body data-page="build">
<div class="sidebar-overlay"></div>
<div class="app-shell">
<aside class="sidebar">
<div class="brand">
<div class="brand-mark">A</div>
<div>
<div class="brand-title">Admin</div>
<div class="brand-sub">Site management</div>
</div>
<button id="close-sidebar" class="ghost" style="margin-left: auto; display: none;">&times;</button>
</div>
<div class="sidebar-section">
<div class="section-heading">Navigation</div>
<a class="ghost" href="/admin/build">Build models</a>
<a class="ghost" href="/admin/plan">Plan models</a>
<a class="ghost" href="/admin/plans">Plans</a>
<a class="ghost" href="/admin/accounts">Accounts</a>
<a class="ghost" href="/admin/affiliates">Affiliates</a>
<a class="ghost" href="/admin/withdrawals">Withdrawals</a>
<a class="ghost" href="/admin/tracking">Tracking</a>
<a class="ghost" href="/admin/resources">Resources</a>
<a class="ghost" href="/admin/external-testing">External Testing</a>
<a class="ghost" href="/admin/contact-messages">Contact Messages</a>
<a class="ghost" href="/admin/feature-requests">Feature Requests</a>
<a class="ghost" href="/admin/blogs">Blog Management</a>
<a class="ghost" href="/admin/login">Login</a>
</div>
</aside>
<main class="main">
<div class="admin-shell">
<div class="topbar" style="margin-bottom: 12px;">
<button id="menu-toggle">
<span></span><span></span><span></span>
</button>
<div>
<div class="pill">Admin</div>
<div class="title" style="margin-top: 6px;">Model Control</div>
<div class="crumb">Only the configured admin can sign in here.</div>
</div>
<div class="admin-actions">
<button id="admin-refresh" class="ghost">Refresh</button>
<button id="admin-logout" class="primary">Logout</button>
</div>
</div>
<div class="admin-grid">
<!-- OpenCode Models Section -->
<div class="admin-card">
<header>
<h3>Add OpenCode Model</h3>
<div class="pill">OpenCode</div>
</header>
<p style="margin-top:0; color: var(--muted);">These are the models available in OpenCode. They form the fallback chain for build execution. When rate limits are reached or errors occur, the system falls back to the next model in the list.</p>
<form id="opencode-model-form" class="admin-form">
<label>
Select model from OpenCode
<select id="opencode-model-select">
<option value="">-- Select a model --</option>
</select>
</label>
<label>
Display name shown to users
<input id="opencode-model-label" type="text" placeholder="Friendly label (e.g., Claude 3.5 Sonnet)" required />
</label>
<label>
Model tier (for plan limits)
<select id="opencode-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="opencode-model-icon">
<option value="">No icon</option>
</select>
</label>
<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>
</div>
<!-- Public Models Section -->
<div class="admin-card">
<header>
<h3>Add Public Model</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 for selection. This is separate from the OpenCode fallback chain.</p>
<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>
Display name shown to users
<input id="public-model-label" type="text" placeholder="Friendly label (e.g., Claude 3.5 Sonnet)" required />
</label>
<label>
Model tier (for plan limits)
<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;">
<input id="public-model-media" type="checkbox" style="width: auto;" />
<span>Supports image uploads</span>
</label>
<div class="admin-actions">
<button type="submit" class="primary">Add Public Model</button>
</div>
<div class="status-line" id="public-model-status"></div>
</form>
</div>
</div>
<!-- OpenCode Models List with Ordering -->
<div class="admin-card" style="margin-top: 16px;">
<header>
<h3>OpenCode Models (Fallback Chain)</h3>
<div class="pill" id="opencode-models-count">0</div>
</header>
<p class="muted" style="margin-top:0;">Arrange the order of OpenCode models below. When rate limits are reached or errors occur, the system falls back to the next model in this chain. The first model is the primary.</p>
<div id="opencode-models-list" class="admin-list"></div>
</div>
<!-- Public Models List with Ordering -->
<div class="admin-card" style="margin-top: 16px;">
<header>
<h3>Public Models</h3>
<div class="pill" id="public-models-count">0</div>
</header>
<p class="muted" style="margin-top:0;">These models are displayed to users in the builder dropdown. Arrange the order to set their display priority.</p>
<div id="public-models-list" class="admin-list"></div>
</div>
<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>
<div class="pill">Admin</div>
</header>
<p style="margin-top:0; color: var(--muted);">Emergency controls for system management.</p>
<div class="admin-actions" style="flex-direction: column; align-items: flex-start;">
<button id="cancel-all-messages" class="danger">Cancel All Running & Queued Messages</button>
<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>
</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>
<div id="icon-list" class="admin-list"></div>
</div>
</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>
</main>
</div>
<script src="/admin.js"></script>
</body>
</html>