v1.8.4: LLM page — Claude AI as third tab alongside Local/Cloudflare

This commit is contained in:
2026-05-28 19:37:31 +00:00
parent 21610345bd
commit 4d6fea7247
2 changed files with 116 additions and 41 deletions
+42 -41
View File
@@ -588,42 +588,6 @@ curl -X POST https://rag.afaqzaid.com/ingest-url \
</div>
<div id="settings-llm" class="glass rounded-2xl p-6 mt-6"></div>
<div id="settings-r2" class="glass rounded-2xl p-6 mt-6"></div>
<!-- ── Claude AI Section (moved from Claude page) ──────────────────── -->
<div class="glass rounded-2xl p-6 mt-6">
<h3 class="text-primary text-xs font-bold uppercase tracking-widest mb-5 flex items-center gap-2">
<span class="msym text-base">smart_toy</span> Claude AI
</h3>
<!-- Key input -->
<div class="glass rounded-2xl p-6 mb-6">
<h3 class="text-primary text-xs font-bold uppercase tracking-widest mb-5 flex items-center gap-2"><span class="msym text-base">key</span>API Key</h3>
<div class="flex gap-3 mb-3">
<input type="password" id="claude-key-input" placeholder="sk-ant-..."
class="flex-1 bg-surface-high border border-outline-variant rounded-xl px-4 py-3 text-sm text-on-surface outline-none focus:border-primary transition-colors font-mono"/>
<button onclick="toggleClaudeKey()" id="claude-key-toggle" class="glass glass-hover px-4 py-2 rounded-xl text-xs text-on-surface-variant">Show</button>
</div>
<div class="flex items-center gap-3 mb-4">
<div id="claude-status" class="flex items-center gap-2 text-xs text-on-surface-variant">
<span class="w-2 h-2 rounded-full bg-outline-variant inline-block"></span> Not configured
</div>
</div>
<button onclick="saveClaudeKey()" class="bg-primary text-surface font-bold px-6 py-2.5 rounded-xl text-sm hover:shadow-[0_0_20px_rgba(78,222,163,0.4)] transition-all flex items-center gap-2">
<span class="msym text-base">save</span> Save Key
</button>
<p class="text-on-surface-variant text-xs mt-3">Key is stored securely in the database and loaded at runtime. Get yours at <span class="text-primary">console.anthropic.com</span></p>
</div>
<!-- Usage stats -->
<div class="grid grid-cols-2 lg:grid-cols-4 gap-4 mb-6" id="claude-stats"></div>
<!-- Daily usage chart -->
<div class="glass rounded-2xl p-6 mb-6">
<h3 class="text-primary text-xs font-bold uppercase tracking-widest mb-4 flex items-center gap-2"><span class="msym text-base">bar_chart</span>Daily Usage</h3>
<div id="claude-daily-chart"></div>
</div>
<!-- Recent calls -->
<div class="glass rounded-2xl p-6">
<h3 class="text-primary text-xs font-bold uppercase tracking-widest mb-4 flex items-center gap-2"><span class="msym text-base">history</span>Recent Calls</h3>
<div id="claude-usage-list" class="space-y-2"></div>
</div>
</section>
</div>
</section>
@@ -2054,6 +2018,35 @@ async function loadLLMConfig() {
class="flex-1 py-2.5 rounded-xl text-xs font-bold transition-all flex items-center justify-center gap-2 ${isCF ? 'bg-blue-500 text-white' : 'glass glass-hover text-on-surface-variant'}">
<span class="msym text-base">cloud</span> Cloudflare GPU
</button>
<button onclick="llmSetProvider('claude')" id="llm-btn-claude"
class="flex-1 py-2.5 rounded-xl text-xs font-bold transition-all flex items-center justify-center gap-2 ${d.provider==='claude' ? 'bg-purple-600 text-white' : 'glass glass-hover text-on-surface-variant'}">
<span class="msym text-base">smart_toy</span> Claude AI
</button>
</div>
<div id="llm-claude-fields" class="${d.provider==='claude' ? '' : 'hidden'} space-y-3 mb-4">
<div class="glass rounded-xl p-4 text-xs text-on-surface-variant space-y-1 mb-3">
<p class="flex items-center gap-2"><span class="msym text-base text-purple-400">bolt</span>Anthropic Claude — fast, high quality</p>
<p class="flex items-center gap-2"><span class="msym text-base text-primary">all_inclusive</span>claude-sonnet-4 recommended for Arabic</p>
<p class="flex items-center gap-2"><span class="msym text-base text-on-surface-variant">storage</span>API key required — console.anthropic.com</p>
</div>
<div id="claude-key-llm-wrap">
<label class="text-xs text-on-surface-variant block mb-1.5">API Key
<span id="claude-key-llm-status" class="text-emerald-400 text-[10px] ml-2"></span>
</label>
<div class="flex gap-2">
<input id="claude-key-llm-input" type="password" dir="ltr" placeholder="sk-ant-..."
class="flex-1 bg-surface-high border border-outline-variant rounded-xl px-3 py-2 text-xs font-mono outline-none focus:border-primary transition-colors"/>
<button onclick="saveClaudeKey()" class="glass glass-hover px-3 py-2 rounded-xl text-xs text-primary font-bold">Save Key</button>
</div>
</div>
<div>
<label class="text-xs text-on-surface-variant block mb-1.5">Model</label>
<select id="llm-claude-model" class="w-full bg-surface-high border border-outline-variant rounded-xl px-3 py-2 text-xs outline-none focus:border-primary transition-colors">
<option value="claude-sonnet-4-20250514">Claude Sonnet 4 ⭐ (Recommended)</option>
<option value="claude-haiku-4-5-20251001">Claude Haiku 4.5 (Faster)</option>
<option value="claude-opus-4-20250514">Claude Opus 4 (Most Powerful)</option>
</select>
</div>
</div>
<div id="llm-local-info" class="${isLocal ? '' : 'hidden'} glass rounded-xl p-4 mb-4 text-xs text-on-surface-variant space-y-1">
<p class="flex items-center gap-2"><span class="msym text-base text-emerald-400">check_circle</span>Running qwen2:7b on your VPS CPU</p>
@@ -2107,11 +2100,19 @@ async function loadLLMConfig() {
function llmSetProvider(p) {
window._llmProvider = p;
const isLocal = p !== 'cloudflare', isCF = p === 'cloudflare';
document.getElementById('llm-btn-local').className = `flex-1 py-2.5 rounded-xl text-xs font-bold transition-all flex items-center justify-center gap-2 ${isLocal?'bg-primary text-surface':'glass glass-hover text-on-surface-variant'}`;
document.getElementById('llm-btn-cf').className = `flex-1 py-2.5 rounded-xl text-xs font-bold transition-all flex items-center justify-center gap-2 ${isCF?'bg-blue-500 text-white':'glass glass-hover text-on-surface-variant'}`;
document.getElementById('llm-local-info').classList.toggle('hidden', isCF);
document.getElementById('llm-cf-fields').classList.toggle('hidden', isLocal);
const isLocal = p === 'local', isCF = p === 'cloudflare', isClaude = p === 'claude';
const btnLocal = document.getElementById('llm-btn-local');
const btnCF = document.getElementById('llm-btn-cf');
const btnClaude = document.getElementById('llm-btn-claude');
if (btnLocal) btnLocal.className = `flex-1 py-2.5 rounded-xl text-xs font-bold transition-all flex items-center justify-center gap-2 ${isLocal?'bg-primary text-surface':'glass glass-hover text-on-surface-variant'}`;
if (btnCF) btnCF.className = `flex-1 py-2.5 rounded-xl text-xs font-bold transition-all flex items-center justify-center gap-2 ${isCF?'bg-blue-500 text-white':'glass glass-hover text-on-surface-variant'}`;
if (btnClaude) btnClaude.className = `flex-1 py-2.5 rounded-xl text-xs font-bold transition-all flex items-center justify-center gap-2 ${isClaude?'bg-purple-600 text-white':'glass glass-hover text-on-surface-variant'}`;
const localInfo = document.getElementById('llm-local-info');
const cfFields = document.getElementById('llm-cf-fields');
const claudeFields = document.getElementById('llm-claude-fields');
if (localInfo) localInfo.classList.toggle('hidden', !isLocal);
if (cfFields) cfFields.classList.toggle('hidden', !isCF);
if (claudeFields) claudeFields.classList.toggle('hidden', !isClaude);
}
async function saveLLMConfig() {