Exocore-gateway / src /static /index.html
Johnsteve Costanos
Add DeepSeek Instant/Expert/Vision modes + modelType + image support in /v1
11d39db
Raw
History Blame Contribute Delete
216 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Exocore AI Gateway</title>
<style>
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
:root{
--bg:#0a0a0f;
--surface:#13131a;
--surface2:#1a1a24;
--border:#2a2a3a;
--border2:#3a3a4e;
--text:#e4e4ef;
--text2:#9898b0;
--muted:#68687a;
--blue:#5b8af5;
--blue-bg:rgba(91,138,245,.12);
--green:#4ade80;
--green-bg:rgba(74,222,128,.1);
--orange:#fbbf24;
--orange-bg:rgba(251,191,36,.1);
--red:#f87171;
--red-bg:rgba(248,113,113,.1);
--purple:#a78bfa;
--purple-bg:rgba(167,139,250,.1);
--cyan:#22d3ee;
--cyan-bg:rgba(34,211,238,.1);
--pink:#f472b6;
--indigo:#818cf8;
--indigo-bg:rgba(129,140,248,.12);
--radius:12px;
--radius-sm:8px;
--radius-xs:6px;
}
html{scroll-behavior:smooth}
body{
font-family:-apple-system,BlinkMacSystemFont,'SF Pro Text','Segoe UI',system-ui,sans-serif;
background:var(--bg);
color:var(--text);
min-height:100vh;
line-height:1.5;
-webkit-font-smoothing:antialiased;
}
.layout{display:flex;min-height:100vh}
/* ── Sidebar ── */
aside{
width:220px;min-width:220px;
background:var(--surface);
border-right:1px solid var(--border);
position:sticky;top:0;height:100vh;
overflow-y:auto;padding:20px 12px 24px;
display:flex;flex-direction:column;
}
.logo-wrap{padding:0 8px 18px;border-bottom:1px solid var(--border);margin-bottom:16px}
.logo{display:flex;align-items:center;gap:10px;text-decoration:none}
.logo-icon{
width:32px;height:32px;
background:linear-gradient(135deg,#5b8af5,#a78bfa);
border-radius:8px;
display:flex;align-items:center;justify-content:center;
font-size:16px;font-weight:700;color:#fff;
box-shadow:0 2px 12px rgba(91,138,245,.3);
}
.logo-title{font-size:14px;font-weight:700;color:var(--text);letter-spacing:-.2px}
.logo-sub{font-size:10px;color:var(--muted)}
.nav-group{padding:0 4px;margin-bottom:6px}
.nav-label{
font-size:9px;font-weight:600;color:var(--muted);
letter-spacing:.5px;text-transform:uppercase;
padding:0 8px 6px;
}
.nav-item{
display:flex;align-items:center;gap:8px;
padding:6px 10px;border-radius:6px;
text-decoration:none;font-size:12px;font-weight:500;
color:var(--text2);transition:all .15s;
margin-bottom:1px;cursor:pointer;border:none;background:none;width:100%;text-align:left;font-family:inherit;
}
.nav-item:hover{background:var(--surface2);color:var(--text)}
.nav-item.active{background:var(--blue-bg);color:var(--blue)}
.nav-dot{width:6px;height:6px;border-radius:50%;flex-shrink:0}
.nav-dot.gemini{background:var(--blue)}
.nav-dot.deepseek{background:var(--cyan)}
.nav-dot.qwen{background:var(--purple)}
.nav-dot.kimi{background:var(--pink)}
.nav-dot.claude{background:var(--orange)}
.nav-dot.gpt{background:var(--green)}
.nav-dot.grok{background:var(--red)}
.nav-dot.meta{background:var(--indigo)}
.aside-footer{
margin:auto 8px 0;
padding:8px 10px;
background:var(--surface2);border:1px solid var(--border);
border-radius:var(--radius-xs);font-size:10px;color:var(--muted);line-height:1.5;
}
.aside-footer strong{color:var(--blue)}
/* ── Main ── */
main{flex:1;overflow-x:hidden;display:flex;flex-direction:column}
/* ── Hero ── */
.hero{
background:var(--surface);
border-bottom:1px solid var(--border);
padding:32px 40px 28px;
}
.hero-chip{
display:inline-flex;align-items:center;gap:6px;
background:var(--blue-bg);color:var(--blue);
font-size:10px;font-weight:600;letter-spacing:.3px;
padding:3px 10px;border-radius:20px;margin-bottom:12px;
border:1px solid rgba(91,138,245,.2);
}
h1{
font-size:28px;font-weight:700;letter-spacing:-.6px;
color:var(--text);margin-bottom:8px;line-height:1.2;
}
.hero-desc{font-size:13px;color:var(--muted);max-width:560px;line-height:1.6;margin-bottom:20px}
.base-url-row{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.base-box{
display:inline-flex;align-items:center;gap:10px;
background:var(--surface2);border:1px solid var(--border);
border-radius:var(--radius-sm);padding:7px 12px;
}
.base-label{font-size:10px;font-weight:600;color:var(--muted);text-transform:uppercase;letter-spacing:.4px}
.base-url{font-family:'SF Mono',ui-monospace,monospace;font-size:12px;color:var(--blue);font-weight:500}
.copy-btn{
background:var(--surface2);border:1px solid var(--border);
color:var(--muted);border-radius:5px;padding:3px 8px;
font-size:10px;font-weight:500;cursor:pointer;
transition:all .15s;font-family:inherit;
}
.copy-btn:hover{color:var(--text);border-color:var(--border2)}
.copy-btn.copied{color:var(--green);border-color:var(--green)}
/* ── Provider Tabs ── */
.provider-tabs{
display:flex;gap:0;
background:var(--surface);
border-bottom:1px solid var(--border);
padding:0 40px;overflow-x:auto;
}
.provider-tab{
display:flex;align-items:center;gap:8px;
padding:12px 18px;font-size:13px;font-weight:500;
color:var(--muted);cursor:pointer;
border-bottom:2px solid transparent;
transition:all .15s;white-space:nowrap;background:none;border-top:none;border-left:none;border-right:none;font-family:inherit;
}
.provider-tab:hover{color:var(--text2)}
.provider-tab.active{color:var(--text);border-bottom-color:var(--blue)}
.provider-tab .tab-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}
.provider-tab .tab-dot.gemini{background:var(--blue)}
.provider-tab .tab-dot.deepseek{background:var(--cyan)}
.provider-tab .tab-dot.qwen{background:var(--purple)}
.provider-tab .tab-dot.kimi{background:var(--pink)}
.provider-tab .tab-dot.claude{background:var(--orange)}
.provider-tab .tab-dot.gpt{background:var(--green)}
.provider-tab .tab-dot.grok{background:var(--red)}
.provider-tab .tab-dot.meta{background:var(--indigo)}
.provider-tab .tab-dot.v1{background:var(--green)}
.provider-content{display:none;padding:28px 40px 60px;flex:1}
.provider-content.active{display:block}
/* ── Section ── */
.section{margin-bottom:36px}
.section-eyebrow{
font-size:10px;font-weight:600;color:var(--blue);
letter-spacing:.5px;text-transform:uppercase;margin-bottom:6px;
}
h2{font-size:20px;font-weight:700;letter-spacing:-.3px;color:var(--text);margin-bottom:4px}
.section-desc{font-size:13px;color:var(--muted);line-height:1.7;margin-bottom:16px}
/* ── Endpoint card ── */
.endpoint{
background:var(--surface);border:1px solid var(--border);
border-radius:var(--radius);margin-bottom:12px;
overflow:hidden;transition:border-color .2s;
}
.endpoint:hover{border-color:var(--border2)}
.ep-header{
display:flex;align-items:center;gap:10px;
padding:12px 16px;cursor:pointer;user-select:none;
transition:background .1s;background:none;border:none;width:100%;text-align:left;font-family:inherit;color:inherit;
}
.ep-header:hover{background:var(--surface2)}
.method-badge{
font-family:'SF Mono',ui-monospace,monospace;
font-size:9px;font-weight:700;
padding:2px 8px;border-radius:4px;min-width:52px;text-align:center;
letter-spacing:.3px;flex-shrink:0;
}
.GET{background:var(--green-bg);color:var(--green);border:1px solid rgba(74,222,128,.2)}
.POST{background:var(--orange-bg);color:var(--orange);border:1px solid rgba(251,191,36,.2)}
.DELETE{background:var(--red-bg);color:var(--red);border:1px solid rgba(248,113,113,.2)}
.ep-path{
font-family:'SF Mono',ui-monospace,monospace;
font-size:12px;color:var(--text);font-weight:500;flex:1;
}
.ep-path .q{color:var(--muted)}
.ep-summary{font-size:11px;color:var(--muted);margin-right:6px;flex-shrink:0}
.ep-chevron{color:var(--muted);font-size:10px;transition:transform .2s;flex-shrink:0}
.endpoint.open .ep-chevron{transform:rotate(90deg)}
.ep-body{display:none;border-top:1px solid var(--border)}
.endpoint.open .ep-body{display:block}
.ep-tabs{
display:flex;gap:0;border-bottom:1px solid var(--border);
background:var(--surface2);padding:0 16px;
}
.ep-tab{
padding:8px 12px;font-size:11px;font-weight:500;
color:var(--muted);cursor:pointer;border-bottom:2px solid transparent;
transition:all .15s;white-space:nowrap;background:none;border-top:none;border-left:none;border-right:none;font-family:inherit;
}
.ep-tab.active{color:var(--blue);border-bottom-color:var(--blue)}
.ep-tab:hover:not(.active){color:var(--text)}
.tab-pane{display:none;padding:16px}
.tab-pane.active{display:block}
.tab-pane p{font-size:12px;color:var(--text2);margin-bottom:12px;line-height:1.7}
/* ── Code block ── */
.code-block{
background:#0d0d14;border-radius:var(--radius-xs);
overflow:hidden;border:1px solid rgba(255,255,255,.04);
margin-bottom:10px;
}
.code-block:last-child{margin-bottom:0}
.code-top{
display:flex;align-items:center;justify-content:space-between;
padding:6px 12px;background:rgba(255,255,255,.03);
border-bottom:1px solid rgba(255,255,255,.04);
}
.code-lang{font-size:9px;color:var(--muted);font-weight:600;text-transform:uppercase;letter-spacing:.4px}
.code-copy-btn{
font-size:9px;color:var(--muted);
background:rgba(255,255,255,.06);border:1px solid rgba(255,255,255,.08);
border-radius:4px;padding:2px 7px;cursor:pointer;transition:all .15s;
font-family:inherit;
}
.code-copy-btn:hover{color:var(--text)}
.code-copy-btn.copied{color:var(--green)}
pre{
padding:12px 14px;overflow-x:auto;
font-family:'SF Mono',ui-monospace,monospace;
font-size:11.5px;line-height:1.6;color:#d4d4e0;
white-space:pre;
}
.kw{color:#ff7eb6}
.str{color:#94e2d5}
.num{color:#f38ba8}
.key{color:#89b4fa}
.cmt{color:#6c7086;font-style:italic}
.fn{color:#89dceb}
.url{color:#89dceb}
.val{color:#a6e3a1}
.pu{color:#cba6f7}
/* ── Params table ── */
.table-wrap{overflow-x:auto;margin-bottom:12px;border-radius:var(--radius-xs);border:1px solid var(--border)}
.params-table{width:100%;border-collapse:collapse;font-size:12px}
.params-table th{
text-align:left;padding:7px 10px;
font-size:9px;font-weight:600;color:var(--muted);
letter-spacing:.4px;text-transform:uppercase;
background:var(--surface2);border-bottom:1px solid var(--border);
}
.params-table td{padding:8px 10px;border-bottom:1px solid var(--border);vertical-align:top}
.params-table tr:last-child td{border-bottom:none}
.pname{font-family:'SF Mono',ui-monospace,monospace;color:var(--blue);font-size:11px}
.ptype{font-family:'SF Mono',ui-monospace,monospace;color:var(--purple);font-size:10px}
.req-badge{
display:inline-block;padding:1px 6px;border-radius:3px;font-size:9px;font-weight:600;
}
.req{background:var(--red-bg);color:var(--red)}
.opt{background:var(--surface2);color:var(--muted);border:1px solid var(--border)}
.pdesc{color:var(--text2);line-height:1.5;font-size:11.5px}
.pdesc code{font-size:10px;background:var(--surface2);padding:1px 4px;border-radius:3px}
/* ── Response list ── */
.resp-list{display:flex;flex-direction:column;gap:6px}
.resp-item{display:flex;align-items:flex-start;gap:8px;padding:8px 10px;background:var(--surface2);border:1px solid var(--border);border-radius:var(--radius-xs)}
.resp-code{font-family:'SF Mono',ui-monospace,monospace;font-size:10.5px;font-weight:700;white-space:nowrap;padding:1px 6px;border-radius:3px}
.s2xx{background:var(--green-bg);color:var(--green)}
.s4xx{background:var(--orange-bg);color:var(--orange)}
.s5xx{background:var(--red-bg);color:var(--red)}
.resp-desc{font-size:11.5px;color:var(--text2);line-height:1.5}
.resp-desc code{font-size:10px;background:var(--surface2);padding:1px 4px;border-radius:3px}
/* ── Status grids ── */
.status-grid{
display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:10px;margin-bottom:16px
}
.stat-card{
background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-sm);
padding:14px 16px;transition:border-color .2s;
}
.stat-card:hover{border-color:var(--border2)}
.stat-label{font-size:10px;font-weight:600;color:var(--muted);text-transform:uppercase;letter-spacing:.4px;margin-bottom:4px}
.stat-value{font-size:16px;font-weight:700;color:var(--text);font-family:'SF Mono',ui-monospace,monospace}
.stat-value.ok{color:var(--green)}
.stat-value.nok{color:var(--red)}
.stat-value.warn{color:var(--orange)}
.stat-sub{font-size:10px;color:var(--muted);margin-top:2px}
/* ── Try panel ── */
.try-panel{padding:16px;background:var(--surface2);border-top:1px solid var(--border)}
.try-fields{display:flex;flex-direction:column;gap:8px;margin-bottom:12px}
.try-field{display:flex;flex-direction:column;gap:3px}
.try-label{font-size:10px;font-weight:600;color:var(--muted);letter-spacing:.3px;text-transform:uppercase}
.try-input{
background:var(--surface);border:1px solid var(--border);
border-radius:var(--radius-xs);padding:8px 10px;
font-size:12px;font-family:inherit;color:var(--text);
transition:border-color .15s;outline:none;width:100%;
}
.try-input:focus{border-color:var(--blue);box-shadow:0 0 0 2px rgba(91,138,245,.15)}
textarea.try-input{min-height:60px;resize:vertical;font-family:'SF Mono',ui-monospace,monospace;font-size:11px}
.run-btn{
display:inline-flex;align-items:center;gap:6px;
background:var(--blue);color:#fff;
border:none;border-radius:var(--radius-xs);
padding:8px 16px;font-size:12px;font-weight:600;
cursor:pointer;transition:all .15s;font-family:inherit;
}
.run-btn:hover{background:#4a7be0;box-shadow:0 2px 8px rgba(91,138,245,.3)}
.run-btn:active{transform:translateY(0)}
.run-btn:disabled{background:var(--border2);cursor:not-allowed;box-shadow:none}
.run-btn .spin{animation:spin .7s linear infinite;display:inline-block}
@keyframes spin{to{transform:rotate(360deg)}}
.result-box{margin-top:12px}
.result-header{display:flex;align-items:center;gap:8px;margin-bottom:6px;font-size:11px;font-weight:600;color:var(--muted)}
.status-pill{padding:2px 7px;border-radius:4px;font-size:10px;font-weight:700;font-family:'SF Mono',ui-monospace,monospace}
.status-ok{background:var(--green-bg);color:var(--green)}
.status-err{background:var(--red-bg);color:var(--red)}
.status-warn{background:var(--orange-bg);color:var(--orange)}
.result-pre{
background:#0d0d14;border-radius:var(--radius-xs);
padding:12px 14px;overflow-x:auto;
font-family:'SF Mono',ui-monospace,monospace;
font-size:11.5px;line-height:1.6;color:#d4d4e0;
white-space:pre-wrap;word-break:break-all;
border:1px solid rgba(255,255,255,.04);
max-height:280px;overflow-y:auto;
}
.result-msg-bubble{
background:var(--surface);border:1px solid var(--border);
border-radius:var(--radius-sm);padding:12px 14px;
font-size:13px;color:var(--text);line-height:1.7;
}
.result-meta{display:flex;gap:6px;flex-wrap:wrap;margin-top:8px}
.meta-chip{display:inline-flex;align-items:center;gap:3px;background:var(--surface2);border:1px solid var(--border);border-radius:4px;padding:2px 7px;font-size:10px}
.meta-chip .k{color:var(--muted)}
.meta-chip .v{font-family:'SF Mono',ui-monospace,monospace;color:var(--blue);font-size:9.5px}
details summary{font-size:10px;font-weight:600;color:var(--muted);text-transform:uppercase;letter-spacing:.3px;cursor:pointer;user-select:none;padding:4px 0}
footer{
border-top:1px solid var(--border);background:var(--surface);
padding:14px 40px;display:flex;align-items:center;justify-content:space-between;
font-size:11px;color:var(--muted);margin-top:auto;
}
footer a{color:var(--blue);text-decoration:none}
::-webkit-scrollbar{width:4px;height:4px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{background:var(--border2);border-radius:4px}
@media(max-width:800px){
aside{display:none}
.hero,.provider-content{padding-left:16px;padding-right:16px}
.provider-content{padding-top:20px;padding-bottom:40px}
.provider-tabs{padding:0 16px}
.hero{padding-top:20px;padding-bottom:20px}
h1{font-size:20px;letter-spacing:-.4px}
.hero-desc{font-size:12px}
.ep-summary{display:none}
.ep-path{font-size:11px}
footer{flex-direction:column;gap:4px;padding:12px 16px;text-align:center}
table-wrap .params-table{min-width:440px}
pre{font-size:10.5px}
.try-input{font-size:13px}
.base-url-row{flex-direction:column;align-items:flex-start;gap:6px}
.base-box{width:100%;justify-content:space-between}
.base-url{font-size:10px;word-break:break-all}
.status-grid{grid-template-columns:1fr 1fr}
}
</style>
</head>
<body>
<script>
(function(){
var h = window.location.hostname;
var p = window.location.port;
var proto = window.location.protocol;
var isLocal = h === 'localhost' || h === '127.0.0.1' || h.endsWith('.local');
var base = proto + '//' + h + (p && !((proto==='https:'&&p==='443')||(proto==='http:'&&p==='80')) ? ':'+p : '');
document.addEventListener('DOMContentLoaded', function(){
var el = document.getElementById('baseUrl');
if(el) el.textContent = base;
});
window.__BASE = base;
})();
</script>
<div class="layout">
<aside>
<div class="logo-wrap">
<a class="logo" href="#">
<div class="logo-icon">AI</div>
<div>
<div class="logo-title">Exocore</div>
<div class="logo-sub">AI Gateway</div>
</div>
</a>
</div>
<div class="nav-group">
<div class="nav-label">Providers</div>
<button class="nav-item active" data-provider="gemini" onclick="switchProvider('gemini')"><span class="nav-dot gemini"></span>Gemini</button>
<button class="nav-item" data-provider="deepseek" onclick="switchProvider('deepseek')"><span class="nav-dot deepseek"></span>DeepSeek</button>
<button class="nav-item" data-provider="qwen" onclick="switchProvider('qwen')"><span class="nav-dot qwen"></span>Qwen</button>
<button class="nav-item" data-provider="kimi" onclick="switchProvider('kimi')"><span class="nav-dot kimi"></span>Kimi</button>
<button class="nav-item" data-provider="claude" onclick="switchProvider('claude')"><span class="nav-dot claude"></span>Claude</button>
<button class="nav-item" data-provider="gpt" onclick="switchProvider('gpt')"><span class="nav-dot gpt"></span>GPT</button>
<button class="nav-item" data-provider="grok" onclick="switchProvider('grok')"><span class="nav-dot grok"></span>Grok</button>
<button class="nav-item" data-provider="meta" onclick="switchProvider('meta')"><span class="nav-dot meta"></span>Meta AI</button>
<div class="nav-label" style="margin-top:12px">OpenAI-Compatible</div>
<button class="nav-item" data-provider="v1" onclick="switchProvider('v1')"><span class="nav-dot v1"></span>V1 API</button>
</div>
<div class="aside-footer">v1.0.0 Β· <strong>@exocore/multi</strong></div>
</aside>
<main>
<div class="hero">
<div class="hero-chip">Multi-Provider API Gateway</div>
<h1>Exocore AI Gateway</h1>
<p class="hero-desc">Unified REST API for Gemini, Claude, DeepSeek, Qwen, and Meta AI β€” all behind a single server powered by @exocore/multi.</p>
<div class="base-url-row">
<div class="base-box">
<span class="base-label">Base URL</span>
<span class="base-url" id="baseUrl"></span>
</div>
<button class="copy-btn" id="copyBaseBtn" onclick="copyBase()">Copy</button>
</div>
</div>
<div class="provider-tabs">
<button class="provider-tab active" data-provider="gemini" onclick="switchProvider('gemini')"><span class="tab-dot gemini"></span>Gemini</button>
<button class="provider-tab" data-provider="deepseek" onclick="switchProvider('deepseek')"><span class="tab-dot deepseek"></span>DeepSeek</button>
<button class="provider-tab" data-provider="qwen" onclick="switchProvider('qwen')"><span class="tab-dot qwen"></span>Qwen</button>
<button class="provider-tab" data-provider="kimi" onclick="switchProvider('kimi')"><span class="tab-dot kimi"></span>Kimi</button>
<button class="provider-tab" data-provider="claude" onclick="switchProvider('claude')"><span class="tab-dot claude"></span>Claude</button>
<button class="provider-tab" data-provider="gpt" onclick="switchProvider('gpt')"><span class="tab-dot gpt"></span>GPT</button>
<button class="provider-tab" data-provider="grok" onclick="switchProvider('grok')"><span class="tab-dot grok"></span>Grok</button>
<button class="provider-tab" data-provider="meta" onclick="switchProvider('meta')"><span class="tab-dot meta"></span>Meta AI</button>
<button class="provider-tab" data-provider="v1" onclick="switchProvider('v1')"><span class="tab-dot v1"></span>V1 API</button>
</div>
<!-- ══ GEMINI ══ -->
<div class="provider-content active" id="provider-gemini">
<div class="section-eyebrow">Google Gemini</div>
<h2>Gemini API</h2>
<p class="section-desc">Cookie-based proxy to Google Gemini β€” multi-turn chat, file uploads, and session management.</p>
<div class="status-grid">
<div class="stat-card"><div class="stat-label">Status</div><div class="stat-value" id="gemini-status">β€”</div><div class="stat-sub">last checked</div></div>
<div class="stat-card"><div class="stat-label">Cookies</div><div class="stat-value" id="gemini-cookies">β€”</div><div class="stat-sub">validity</div></div>
<div class="stat-card"><div class="stat-label">Client</div><div class="stat-value" id="gemini-client">β€”</div><div class="stat-sub">initialized</div></div>
</div>
<div class="endpoint open">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/gemini/health</span>
<span class="ep-summary">Server & client status</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs">
<button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button>
<button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button>
</div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block">
<div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div>
<pre><span class="kw">curl</span> <span class="url">"<script>document.write(window.__BASE)</script>/api/gemini/health"</span></pre>
</div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<button class="run-btn" onclick="runGeminiHealth(this)">β–Ά Run</button>
<div class="result-box" id="gemini-health-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/gemini/cookies</span>
<span class="ep-summary">Inspect cookies</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs">
<button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button>
<button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button>
</div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block">
<div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div>
<pre><span class="kw">curl</span> <span class="url">"<script>document.write(window.__BASE)</script>/api/gemini/cookies"</span></pre>
</div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<button class="run-btn" onclick="runGeminiGetCookies(this)">β–Ά Run</button>
<div class="result-box" id="gemini-getcookies-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge POST">POST</span>
<span class="ep-path">/api/gemini/cookies</span>
<span class="ep-summary">Upload cookies</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs">
<button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button>
<button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button>
</div>
<div class="tab-pane active" data-pane="docs">
<p>Replace the cookie jar with a fresh raw cookie string. The server parses, saves, and re-initializes the Gemini client.</p>
<div class="table-wrap">
<table class="params-table">
<thead><tr><th>Field</th><th>Type</th><th>Required</th><th>Description</th></tr></thead>
<tbody>
<tr>
<td><span class="pname">body</span></td>
<td><span class="ptype">string</span></td>
<td><span class="req-badge req">Required</span></td>
<td class="pdesc">Raw cookie string <code>SID=x; HSID=y; ...</code></td>
</tr>
</tbody>
</table>
</div>
<div class="code-block">
<div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div>
<pre><span class="kw">curl</span> -X POST <span class="url">"<script>document.write(window.__BASE)</script>/api/gemini/cookies"</span> \
-H <span class="str">"Content-Type: text/plain"</span> \
--data-raw <span class="str">"SID=abc; HSID=xyz; ..."</span></pre>
</div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields">
<div class="try-field">
<label class="try-label">Cookie string</label>
<textarea class="try-input" id="gemini-cookies-input" placeholder="SID=abc123; HSID=xyz; ..."></textarea>
</div>
</div>
<button class="run-btn" onclick="runGeminiSetCookies(this)">β–Ά Run</button>
<div class="result-box" id="gemini-setcookies-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge DELETE">DELETE</span>
<span class="ep-path">/api/gemini/cookies</span>
<span class="ep-summary">Clear cookies</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs">
<button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button>
<button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button>
</div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block">
<div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div>
<pre><span class="kw">curl</span> -X DELETE <span class="url">"<script>document.write(window.__BASE)</script>/api/gemini/cookies"</span></pre>
</div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<button class="run-btn" style="background:var(--red)" onclick="runGeminiDeleteCookies(this)">β–Ά Run</button>
<div class="result-box" id="gemini-deletecookies-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint" id="chat">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/gemini/chat<span class="q">?ask=&lt;msg&gt;</span></span>
<span class="ep-summary">Send message</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs">
<button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button>
<button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button>
</div>
<div class="tab-pane active" data-pane="docs">
<p>Sends a text prompt to Gemini. Supports multi-turn with <code>cid</code>, <code>rid</code>, <code>rcid</code> params.</p>
<div class="table-wrap">
<table class="params-table">
<thead><tr><th>Param</th><th>Type</th><th>Req</th><th>Description</th></tr></thead>
<tbody>
<tr><td><span class="pname">ask</span></td><td><span class="ptype">string</span></td><td><span class="req-badge req">Required*</span></td><td class="pdesc">Text prompt</td></tr>
<tr><td><span class="pname">upload</span></td><td><span class="ptype">string</span></td><td><span class="req-badge opt">Opt</span></td><td class="pdesc">File URLs to attach</td></tr>
<tr><td><span class="pname">cid</span></td><td><span class="ptype">string</span></td><td><span class="req-badge opt">Opt</span></td><td class="pdesc">Conversation ID</td></tr>
<tr><td><span class="pname">rid</span></td><td><span class="ptype">string</span></td><td><span class="req-badge opt">Opt</span></td><td class="pdesc">Response ID</td></tr>
<tr><td><span class="pname">rcid</span></td><td><span class="ptype">string</span></td><td><span class="req-badge opt">Opt</span></td><td class="pdesc">Candidate ID</td></tr>
<tr><td><span class="pname">model</span></td><td><span class="ptype">string</span></td><td><span class="req-badge opt">Opt</span></td><td class="pdesc"><code>fast</code>, <code>thinking</code>, or <code>pro</code> (default: <code>fast</code>)</td></tr>
<tr><td><span class="pname">tokens</span></td><td><span class="ptype">bool</span></td><td><span class="req-badge opt">Opt</span></td><td class="pdesc">Stream tokens as SSE (<code>true</code>)</td></tr>
<tr><td><span class="pname">delete</span></td><td><span class="ptype">bool</span></td><td><span class="req-badge opt">Opt</span></td><td class="pdesc">Auto-delete conversation after reply</td></tr>
</tbody>
</table>
</div>
<div class="code-block">
<div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div>
<pre><span class="kw">curl</span> <span class="str">"<script>document.write(window.__BASE)</script>/api/gemini/chat?ask=What+is+the+capital+of+France"</span></pre>
</div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields">
<div class="try-field">
<label class="try-label">Message</label>
<input class="try-input" id="gemini-chat-ask" type="text" placeholder="What is the capital of France?" />
</div>
<div class="try-field"><label class="try-label">Model</label><select class="try-input" id="gemini-chat-model"><option value="">Default (fast)</option><option value="fast">Fast</option><option value="thinking">Thinking</option><option value="pro">Pro</option></select></div>
<div class="try-field" style="flex-direction:row;align-items:center;gap:6px"><input type="checkbox" id="gemini-chat-delete" style="accent-color:var(--red)"><label class="try-label" for="gemini-chat-delete" style="cursor:pointer;text-transform:none;font-size:11px">Delete after chat</label></div>
<div class="try-field" style="flex-direction:row;align-items:center;gap:6px"><input type="checkbox" id="gemini-chat-tokens" style="accent-color:var(--green)"><label class="try-label" for="gemini-chat-tokens" style="cursor:pointer;text-transform:none;font-size:11px">Stream tokens</label></div>
<details>
<summary>Multi-turn IDs (optional)</summary>
<div style="display:flex;flex-direction:column;gap:6px;margin-top:8px">
<div class="try-field"><label class="try-label">cid</label><input class="try-input" id="gemini-chat-cid" type="text" placeholder="from previous response" /></div>
<div class="try-field"><label class="try-label">rid</label><input class="try-input" id="gemini-chat-rid" type="text" placeholder="from previous response" /></div>
<div class="try-field"><label class="try-label">rcid</label><input class="try-input" id="gemini-chat-rcid" type="text" placeholder="from previous response" /></div>
</div>
</details>
</div>
<button class="run-btn" onclick="runGeminiChat(this)">β–Ά Run</button>
<div class="result-box" id="gemini-chat-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/gemini/temp/chat<span class="q">?ask=&lt;msg&gt;</span></span>
<span class="ep-summary">No-auth chat</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs">
<button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button>
<button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button>
</div>
<div class="tab-pane active" data-pane="docs">
<p>Truly temporary Gemini chat β€” no cookies, no auth required. Sessions are ephemeral.</p>
<div class="code-block">
<div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div>
<pre><span class="kw">curl</span> <span class="str">"<script>document.write(window.__BASE)</script>/api/gemini/temp/chat?ask=Hello"</span></pre>
</div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields">
<div class="try-field">
<label class="try-label">Message</label>
<input class="try-input" id="gemini-tempchat-ask" type="text" placeholder="Hello" />
</div>
</div>
<button class="run-btn" onclick="runGeminiTempChat(this)">β–Ά Run</button>
<div class="result-box" id="gemini-tempchat-result" style="display:none"></div>
</div>
</div>
</div>
<h2 style="margin-top:24px">Conversations</h2>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/gemini/conversations</span>
<span class="ep-summary">List conversations</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs">
<button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button>
<button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button>
</div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block">
<div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div>
<pre><span class="kw">curl</span> <span class="url">"<script>document.write(window.__BASE)</script>/api/gemini/conversations"</span></pre>
</div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<button class="run-btn" onclick="runGeminiConversations(this)">β–Ά Run</button>
<div class="result-box" id="gemini-conversations-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge DELETE">DELETE</span>
<span class="ep-path">/api/gemini/conversations</span>
<span class="ep-summary">Delete all convos</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs">
<button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button>
<button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button>
</div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block">
<div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div>
<pre><span class="kw">curl</span> -X DELETE <span class="url">"<script>document.write(window.__BASE)</script>/api/gemini/conversations"</span></pre>
</div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<button class="run-btn" style="background:var(--red)" onclick="runGeminiDeleteAllConvos(this)">β–Ά Run</button>
<div class="result-box" id="gemini-deleteall-convos-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge DELETE">DELETE</span>
<span class="ep-path">/api/gemini/conversations/<span class="q">:id</span></span>
<span class="ep-summary">Delete one convo</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs">
<button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button>
<button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button>
</div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block">
<div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div>
<pre><span class="kw">curl</span> -X DELETE <span class="url">"<script>document.write(window.__BASE)</script>/api/gemini/conversations/&lt;id&gt;"</span></pre>
</div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields"><div class="try-field"><label class="try-label">Conversation ID</label><input class="try-input" id="gemini-delete-convo-id" type="text" /></div></div>
<button class="run-btn" style="background:var(--red)" onclick="runGeminiDeleteConvo(this)">β–Ά Run</button>
<div class="result-box" id="gemini-delete-convo-result" style="display:none"></div>
</div>
</div>
</div>
</div>
<!-- ══ DEEPSEEK ══ -->
<div class="provider-content" id="provider-deepseek">
<div class="section-eyebrow">DeepSeek</div>
<h2>DeepSeek API</h2>
<p class="section-desc">Token-based client for DeepSeek chat. Configure via <code>deepseek.json</code> with <code>userToken</code> and <code>hifLeim</code> fields.</p>
<div class="status-grid">
<div class="stat-card"><div class="stat-label">Status</div><div class="stat-value" id="deepseek-status">β€”</div><div class="stat-sub">configured</div></div>
</div>
<div class="endpoint open">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/deepseek/health</span>
<span class="ep-summary">Health check</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="url">"<script>document.write(window.__BASE)</script>/api/deepseek/health"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<button class="run-btn" onclick="runDeepSeekHealth(this)">β–Ά Run</button>
<div class="result-box" id="deepseek-health-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/deepseek/chat<span class="q">?prompt=&lt;msg&gt;</span></span>
<span class="ep-summary">Chat (GET)</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<p>Sends a message to DeepSeek via GET query. Auto-creates session if <code>sessionId</code> omitted.</p>
<div class="table-wrap"><table class="params-table"><thead><tr><th>Param</th><th>Type</th><th>Req</th><th>Description</th></tr></thead><tbody>
<tr><td><span class="pname">prompt</span></td><td><span class="ptype">string</span></td><td><span class="req-badge req">Req</span></td><td class="pdesc">Your message</td></tr>
<tr><td><span class="pname">sessionId</span></td><td><span class="ptype">string</span></td><td><span class="req-badge opt">Opt</span></td><td class="pdesc">Resume existing session</td></tr>
<tr><td><span class="pname">thinkingEnabled</span></td><td><span class="ptype">bool</span></td><td><span class="req-badge opt">Opt</span></td><td class="pdesc">Enable reasoning</td></tr>
<tr><td><span class="pname">searchEnabled</span></td><td><span class="ptype">bool</span></td><td><span class="req-badge opt">Opt</span></td><td class="pdesc">Enable web search</td></tr>
<tr><td><span class="pname">delete</span></td><td><span class="ptype">bool</span></td><td><span class="req-badge opt">Opt</span></td><td class="pdesc">Auto-delete session after reply</td></tr>
<tr><td><span class="pname">tokens</span></td><td><span class="ptype">bool</span></td><td><span class="req-badge opt">Opt</span></td><td class="pdesc">Stream tokens as SSE (<code>true</code>)</td></tr>
</tbody></table></div>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="str">"<script>document.write(window.__BASE)</script>/api/deepseek/chat?prompt=Hello"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields"><div class="try-field"><label class="try-label">Message</label><input class="try-input" id="deepseek-prompt" type="text" placeholder="Hello" /></div>
<div class="try-field" style="flex-direction:row;align-items:center;gap:6px"><input type="checkbox" id="deepseek-chat-delete" style="accent-color:var(--red)"><label class="try-label" for="deepseek-chat-delete" style="cursor:pointer;text-transform:none;font-size:11px">Delete after chat</label></div>
<div class="try-field" style="flex-direction:row;align-items:center;gap:6px"><input type="checkbox" id="deepseek-chat-tokens" style="accent-color:var(--green)"><label class="try-label" for="deepseek-chat-tokens" style="cursor:pointer;text-transform:none;font-size:11px">Stream tokens</label></div></div>
<button class="run-btn" onclick="runDeepSeekChat(this)">β–Ά Run</button>
<div class="result-box" id="deepseek-chat-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge POST">POST</span>
<span class="ep-path">/api/deepseek/chat</span>
<span class="ep-summary">Chat (POST)</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<p>Same as GET but with JSON body.</p>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X POST <span class="url">"<script>document.write(window.__BASE)</script>/api/deepseek/chat"</span> <span class="kw">\</span>
-H <span class="str">"Content-Type: application/json"</span> <span class="kw">\</span>
--data <span class="str">'{"prompt":"Hello"}'</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields"><div class="try-field"><label class="try-label">Message</label><input class="try-input" id="deepseek-chat-post-prompt" type="text" placeholder="Hello" /></div>
<div class="try-field" style="flex-direction:row;align-items:center;gap:6px"><input type="checkbox" id="deepseek-chat-post-tokens" style="accent-color:var(--green)"><label class="try-label" for="deepseek-chat-post-tokens" style="cursor:pointer;text-transform:none;font-size:11px">Stream tokens</label></div></div>
<button class="run-btn" onclick="runDeepSeekChatPost(this)">β–Ά Run</button>
<div class="result-box" id="deepseek-chat-post-result" style="display:none"></div>
</div>
</div>
</div>
<h2 style="margin-top:24px">Sessions</h2>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/deepseek/sessions</span>
<span class="ep-summary">List sessions</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="url">"<script>document.write(window.__BASE)</script>/api/deepseek/sessions?limit=20"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<button class="run-btn" onclick="runDeepSeekSessions(this)">β–Ά Run</button>
<div class="result-box" id="deepseek-sessions-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge POST">POST</span>
<span class="ep-path">/api/deepseek/sessions</span>
<span class="ep-summary">Create session</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X POST <span class="url">"<script>document.write(window.__BASE)</script>/api/deepseek/sessions"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<button class="run-btn" onclick="runDeepSeekCreateSession(this)">β–Ά Run</button>
<div class="result-box" id="deepseek-create-session-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge DELETE">DELETE</span>
<span class="ep-path">/api/deepseek/sessions</span>
<span class="ep-summary">Delete all sessions</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X DELETE <span class="url">"<script>document.write(window.__BASE)</script>/api/deepseek/sessions"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<button class="run-btn" style="background:var(--red)" onclick="runDeepSeekDeleteAllSessions(this)">β–Ά Run</button>
<div class="result-box" id="deepseek-deleteall-sessions-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge DELETE">DELETE</span>
<span class="ep-path">/api/deepseek/sessions/<span class="q">:id</span></span>
<span class="ep-summary">Delete one session</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X DELETE <span class="url">"<script>document.write(window.__BASE)</script>/api/deepseek/sessions/&lt;id&gt;"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields"><div class="try-field"><label class="try-label">Session ID</label><input class="try-input" id="deepseek-delete-session-id" type="text" placeholder="session id" /></div></div>
<button class="run-btn" style="background:var(--red)" onclick="runDeepSeekDeleteSession(this)">β–Ά Run</button>
<div class="result-box" id="deepseek-delete-session-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/deepseek/sessions/<span class="q">:id</span>/messages</span>
<span class="ep-summary">Get messages</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="url">"<script>document.write(window.__BASE)</script>/api/deepseek/sessions/&lt;id&gt;/messages"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields"><div class="try-field"><label class="try-label">Session ID</label><input class="try-input" id="deepseek-messages-session-id" type="text" placeholder="session id" /></div></div>
<button class="run-btn" onclick="runDeepSeekMessages(this)">β–Ά Run</button>
<div class="result-box" id="deepseek-messages-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge POST">POST</span>
<span class="ep-path">/api/deepseek/sessions/<span class="q">:id</span>/chat</span>
<span class="ep-summary">Chat in session</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<p>Send a message to an existing session.</p>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X POST <span class="url">"<script>document.write(window.__BASE)</script>/api/deepseek/sessions/&lt;id&gt;/chat"</span> <span class="kw">\</span>
-H <span class="str">"Content-Type: application/json"</span> <span class="kw">\</span>
--data <span class="str">'{"prompt":"Hello again"}'</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields"><div class="try-field"><label class="try-label">Session ID</label><input class="try-input" id="deepseek-sessionchat-sid" type="text" placeholder="session id" /></div>
<div class="try-field"><label class="try-label">Message</label><input class="try-input" id="deepseek-sessionchat-msg" type="text" placeholder="Hello" /></div></div>
<button class="run-btn" onclick="runDeepSeekSessionChat(this)">β–Ά Run</button>
<div class="result-box" id="deepseek-sessionchat-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge POST">POST</span>
<span class="ep-path">/api/deepseek/sessions/<span class="q">:id</span>/regenerate/<span class="q">:messageId</span></span>
<span class="ep-summary">Regenerate message</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<p>Regenerate an assistant response for a given message.</p>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X POST <span class="url">"<script>document.write(window.__BASE)</script>/api/deepseek/sessions/&lt;id&gt;/regenerate/&lt;msgId&gt;"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields"><div class="try-field"><label class="try-label">Session ID</label><input class="try-input" id="deepseek-reg-session" type="text" /></div>
<div class="try-field"><label class="try-label">Message ID</label><input class="try-input" id="deepseek-reg-msgid" type="text" /></div></div>
<button class="run-btn" onclick="runDeepSeekRegenerate(this)">β–Ά Run</button>
<div class="result-box" id="deepseek-regenerate-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge POST">POST</span>
<span class="ep-path">/api/deepseek/sessions/<span class="q">:id</span>/edit/<span class="q">:messageId</span></span>
<span class="ep-summary">Edit message</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<p>Edit a user message and re-generate the response.</p>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X POST <span class="url">"<script>document.write(window.__BASE)</script>/api/deepseek/sessions/&lt;id&gt;/edit/&lt;msgId&gt;"</span> <span class="kw">\</span>
-H <span class="str">"Content-Type: application/json"</span> <span class="kw">\</span>
--data <span class="str">'{"prompt":"edited text"}'</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields"><div class="try-field"><label class="try-label">Session ID</label><input class="try-input" id="deepseek-edit-session" type="text" /></div>
<div class="try-field"><label class="try-label">Message ID</label><input class="try-input" id="deepseek-edit-msgid" type="text" /></div>
<div class="try-field"><label class="try-label">New prompt</label><input class="try-input" id="deepseek-edit-prompt" type="text" /></div></div>
<button class="run-btn" onclick="runDeepSeekEdit(this)">β–Ά Run</button>
<div class="result-box" id="deepseek-edit-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge POST">POST</span>
<span class="ep-path">/api/deepseek/sessions/<span class="q">:id</span>/continue/<span class="q">:messageId</span></span>
<span class="ep-summary">Continue message</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<p>Continue generating from a partial assistant response.</p>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X POST <span class="url">"<script>document.write(window.__BASE)</script>/api/deepseek/sessions/&lt;id&gt;/continue/&lt;msgId&gt;"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields"><div class="try-field"><label class="try-label">Session ID</label><input class="try-input" id="deepseek-cont-session" type="text" /></div>
<div class="try-field"><label class="try-label">Message ID</label><input class="try-input" id="deepseek-cont-msgid" type="text" /></div></div>
<button class="run-btn" onclick="runDeepSeekContinue(this)">β–Ά Run</button>
<div class="result-box" id="deepseek-continue-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge POST">POST</span>
<span class="ep-path">/api/deepseek/sessions/<span class="q">:id</span>/stop/<span class="q">:messageId</span></span>
<span class="ep-summary">Stop stream</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<p>Stop an in-progress streaming response.</p>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X POST <span class="url">"<script>document.write(window.__BASE)</script>/api/deepseek/sessions/&lt;id&gt;/stop/&lt;msgId&gt;"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields"><div class="try-field"><label class="try-label">Session ID</label><input class="try-input" id="deepseek-stop-session" type="text" /></div>
<div class="try-field"><label class="try-label">Message ID</label><input class="try-input" id="deepseek-stop-msgid" type="text" /></div></div>
<button class="run-btn" onclick="runDeepSeekStop(this)">β–Ά Run</button>
<div class="result-box" id="deepseek-stop-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge PUT">PUT</span>
<span class="ep-path">/api/deepseek/sessions/<span class="q">:id</span>/title</span>
<span class="ep-summary">Update title</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X PUT <span class="url">"<script>document.write(window.__BASE)</script>/api/deepseek/sessions/&lt;id&gt;/title"</span> <span class="kw">\</span>
-H <span class="str">"Content-Type: application/json"</span> <span class="kw">\</span>
--data <span class="str">'{"title":"My Chat"}'</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields"><div class="try-field"><label class="try-label">Session ID</label><input class="try-input" id="deepseek-title-sid" type="text" /></div>
<div class="try-field"><label class="try-label">Title</label><input class="try-input" id="deepseek-title" type="text" placeholder="My Chat" /></div></div>
<button class="run-btn" onclick="runDeepSeekTitle(this)">β–Ά Run</button>
<div class="result-box" id="deepseek-title-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge PUT">PUT</span>
<span class="ep-path">/api/deepseek/sessions/<span class="q">:id</span>/pinned</span>
<span class="ep-summary">Toggle pinned</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X PUT <span class="url">"<script>document.write(window.__BASE)</script>/api/deepseek/sessions/&lt;id&gt;/pinned"</span> <span class="kw">\</span>
-H <span class="str">"Content-Type: application/json"</span> <span class="kw">\</span>
--data <span class="str">'{"pinned":true}'</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields"><div class="try-field"><label class="try-label">Session ID</label><input class="try-input" id="deepseek-pin-sid" type="text" /></div>
<div class="try-field"><label class="try-label">Pinned</label><select class="try-input" id="deepseek-pin-val"><option value="true">True</option><option value="false">False</option></select></div></div>
<button class="run-btn" onclick="runDeepSeekPin(this)">β–Ά Run</button>
<div class="result-box" id="deepseek-pin-result" style="display:none"></div>
</div>
</div>
</div>
<h2 style="margin-top:24px">User &amp; PoW</h2>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/deepseek/user</span>
<span class="ep-summary">Get user info</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="url">"<script>document.write(window.__BASE)</script>/api/deepseek/user"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<button class="run-btn" onclick="runDeepSeekUser(this)">β–Ά Run</button>
<div class="result-box" id="deepseek-user-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/deepseek/pow-challenge</span>
<span class="ep-summary">Get PoW challenge</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<p>Request a PoW challenge for a target endpoint.</p>
<div class="table-wrap"><table class="params-table"><thead><tr><th>Param</th><th>Type</th><th>Req</th><th>Description</th></tr></thead><tbody>
<tr><td><span class="pname">target</span></td><td><span class="ptype">string</span></td><td><span class="req-badge opt">Opt</span></td><td class="pdesc">Default <code>/api/v0/chat/completion</code></td></tr>
</tbody></table></div>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="url">"<script>document.write(window.__BASE)</script>/api/deepseek/pow-challenge"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<button class="run-btn" onclick="runDeepSeekPowChallenge(this)">β–Ά Run</button>
<div class="result-box" id="deepseek-pow-challenge-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge POST">POST</span>
<span class="ep-path">/api/deepseek/pow-solve</span>
<span class="ep-summary">Solve PoW</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<p>Solve a PoW challenge and get the answer.</p>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X POST <span class="url">"<script>document.write(window.__BASE)</script>/api/deepseek/pow-solve"</span> <span class="kw">\</span>
-H <span class="str">"Content-Type: application/json"</span> <span class="kw">\</span>
--data <span class="str">'{"challenge":"...","difficulty":...}'</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<button class="run-btn" onclick="runDeepSeekPowSolve(this)">β–Ά Run</button>
<div class="result-box" id="deepseek-pow-solve-result" style="display:none"></div>
</div>
</div>
</div>
<h2 style="margin-top:24px">Shares</h2>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/deepseek/shares</span>
<span class="ep-summary">List shares</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="url">"<script>document.write(window.__BASE)</script>/api/deepseek/shares"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<button class="run-btn" onclick="runDeepSeekShares(this)">β–Ά Run</button>
<div class="result-box" id="deepseek-shares-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge POST">POST</span>
<span class="ep-path">/api/deepseek/shares</span>
<span class="ep-summary">Create share</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X POST <span class="url">"<script>document.write(window.__BASE)</script>/api/deepseek/shares"</span> <span class="kw">\</span>
-H <span class="str">"Content-Type: application/json"</span> <span class="kw">\</span>
--data <span class="str">'{"sessionId":"...","messageIds":["..."]}'</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields"><div class="try-field"><label class="try-label">Session ID</label><input class="try-input" id="deepseek-share-create-sid" type="text" /></div>
<div class="try-field"><label class="try-label">Message IDs (comma)</label><input class="try-input" id="deepseek-share-create-mids" type="text" placeholder="id1,id2" /></div></div>
<button class="run-btn" onclick="runDeepSeekCreateShare(this)">β–Ά Run</button>
<div class="result-box" id="deepseek-create-share-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge POST">POST</span>
<span class="ep-path">/api/deepseek/shares/fork</span>
<span class="ep-summary">Fork share</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<p>Fork a shared conversation into a new session.</p>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X POST <span class="url">"<script>document.write(window.__BASE)</script>/api/deepseek/shares/fork"</span> <span class="kw">\</span>
-H <span class="str">"Content-Type: application/json"</span> <span class="kw">\</span>
--data <span class="str">'{"shareId":"..."}'</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields"><div class="try-field"><label class="try-label">Share ID</label><input class="try-input" id="deepseek-fork-share-id" type="text" /></div></div>
<button class="run-btn" onclick="runDeepSeekForkShare(this)">β–Ά Run</button>
<div class="result-box" id="deepseek-fork-share-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge DELETE">DELETE</span>
<span class="ep-path">/api/deepseek/shares/<span class="q">:id</span></span>
<span class="ep-summary">Delete share</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X DELETE <span class="url">"<script>document.write(window.__BASE)</script>/api/deepseek/shares/&lt;id&gt;"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields"><div class="try-field"><label class="try-label">Share ID</label><input class="try-input" id="deepseek-delete-share-id" type="text" /></div></div>
<button class="run-btn" style="background:var(--red)" onclick="runDeepSeekDeleteShare(this)">β–Ά Run</button>
<div class="result-box" id="deepseek-delete-share-result" style="display:none"></div>
</div>
</div>
</div>
</div>
<!-- ══ QWEN ══ -->
<div class="provider-content" id="provider-qwen">
<div class="section-eyebrow">Qwen</div>
<h2>Qwen API</h2>
<p class="section-desc">Token-based client for Qwen AI chat. Configure via <code>qwen.json</code> cookies file with a <code>token</code> entry.</p>
<div class="status-grid">
<div class="stat-card"><div class="stat-label">Status</div><div class="stat-value" id="qwen-status">β€”</div><div class="stat-sub">configured</div></div>
</div>
<div class="endpoint open">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/qwen</span>
<span class="ep-summary">API info</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="url">"<script>document.write(window.__BASE)</script>/api/qwen"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<button class="run-btn" onclick="runQwenInfo(this)">β–Ά Run</button>
<div class="result-box" id="qwen-info-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/qwen/health</span>
<span class="ep-summary">Health check</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="url">"<script>document.write(window.__BASE)</script>/api/qwen/health"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<button class="run-btn" onclick="runQwenHealth(this)">β–Ά Run</button>
<div class="result-box" id="qwen-health-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/qwen/ask<span class="q">?prompt=&lt;msg&gt;</span></span>
<span class="ep-summary">Ask Qwen (GET)</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<p>Send a prompt to Qwen via GET. Supports modes: <code>normal</code>, <code>thinking</code>, <code>fast</code>. Use <code>chat_type</code> for features: slides, travel, learn, deep_research, web_dev, search, artifacts.</p>
<div class="table-wrap"><table class="params-table"><thead><tr><th>Param</th><th>Type</th><th>Req</th><th>Description</th></tr></thead><tbody>
<tr><td><span class="pname">prompt</span></td><td><span class="ptype">string</span></td><td><span class="req-badge req">Req</span></td><td class="pdesc">Your message</td></tr>
<tr><td><span class="pname">mode</span></td><td><span class="ptype">string</span></td><td><span class="req-badge opt">Opt</span></td><td class="pdesc"><code>normal</code>, <code>thinking</code>, or <code>fast</code></td></tr>
<tr><td><span class="pname">image_url</span></td><td><span class="ptype">string</span></td><td><span class="req-badge opt">Opt</span></td><td class="pdesc">URL for vision queries</td></tr>
<tr><td><span class="pname">chat_type</span></td><td><span class="ptype">string</span></td><td><span class="req-badge opt">Opt</span></td><td class="pdesc">Feature: slides, travel, deep_research, etc.</td></tr>
<tr><td><span class="pname">model</span></td><td><span class="ptype">string</span></td><td><span class="req-badge opt">Opt</span></td><td class="pdesc">Override model name</td></tr>
<tr><td><span class="pname">delete</span></td><td><span class="ptype">bool</span></td><td><span class="req-badge opt">Opt</span></td><td class="pdesc">Auto-delete all conversations after reply</td></tr>
<tr><td><span class="pname">tokens</span></td><td><span class="ptype">bool</span></td><td><span class="req-badge opt">Opt</span></td><td class="pdesc">Stream tokens as SSE (<code>true</code>)</td></tr>
</tbody></table></div>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="str">"<script>document.write(window.__BASE)</script>/api/qwen/ask?prompt=Hello&mode=fast"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields">
<div class="try-field"><label class="try-label">Message</label><input class="try-input" id="qwen-prompt" type="text" placeholder="Hello" /></div>
<div class="try-field"><label class="try-label">Mode</label><select class="try-input" id="qwen-mode"><option value="normal">Normal</option><option value="thinking">Thinking</option><option value="fast">Fast</option></select></div>
<div class="try-field" style="flex-direction:row;align-items:center;gap:6px"><input type="checkbox" id="qwen-ask-delete" style="accent-color:var(--red)"><label class="try-label" for="qwen-ask-delete" style="cursor:pointer;text-transform:none;font-size:11px">Delete after chat</label></div>
<div class="try-field" style="flex-direction:row;align-items:center;gap:6px"><input type="checkbox" id="qwen-ask-tokens" style="accent-color:var(--green)"><label class="try-label" for="qwen-ask-tokens" style="cursor:pointer;text-transform:none;font-size:11px">Stream tokens</label></div>
</div>
<button class="run-btn" onclick="runQwenAsk(this)">β–Ά Run</button>
<div class="result-box" id="qwen-ask-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge POST">POST</span>
<span class="ep-path">/api/qwen/ask</span>
<span class="ep-summary">Ask Qwen (POST)</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<p>POST version with JSON body. Supports file attachments via <code>file_path</code>.</p>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X POST <span class="url">"<script>document.write(window.__BASE)</script>/api/qwen/ask"</span> <span class="kw">\</span>
-H <span class="str">"Content-Type: application/json"</span> <span class="kw">\</span>
--data <span class="str">'{"prompt":"Hello","mode":"fast","chat_type":"slides"}'</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields"><div class="try-field"><label class="try-label">Message</label><input class="try-input" id="qwen-ask-post-prompt" type="text" placeholder="Hello" /></div>
<div class="try-field"><label class="try-label">Mode</label><select class="try-input" id="qwen-ask-post-mode"><option value="normal">Normal</option><option value="thinking">Thinking</option><option value="fast">Fast</option></select></div>
<div class="try-field" style="flex-direction:row;align-items:center;gap:6px"><input type="checkbox" id="qwen-ask-post-tokens" style="accent-color:var(--green)"><label class="try-label" for="qwen-ask-post-tokens" style="cursor:pointer;text-transform:none;font-size:11px">Stream tokens</label></div></div>
<button class="run-btn" onclick="runQwenAskPost(this)">β–Ά Run</button>
<div class="result-box" id="qwen-ask-post-result" style="display:none"></div>
</div>
</div>
</div>
<h2 style="margin-top:24px">Features</h2>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/qwen/ask<span class="q">?prompt=&lt;msg&gt;&amp;chat_type=slides</span></span>
<span class="ep-summary">Slides</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="str">"<script>document.write(window.__BASE)</script>/api/qwen/ask?prompt=3+slides+about+AI&amp;chat_type=slides"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields"><div class="try-field"><label class="try-label">Message</label><input class="try-input" id="qwen-feature-slides-prompt" type="text" placeholder="3 slides about AI" /></div></div>
<button class="run-btn" onclick="runQwenFeature('slides',this)">β–Ά Run</button>
<div class="result-box" id="qwen-feature-slides-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/qwen/ask<span class="q">?prompt=&lt;msg&gt;&amp;chat_type=travel</span></span>
<span class="ep-summary">Travel</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="str">"<script>document.write(window.__BASE)</script>/api/qwen/ask?prompt=Tokyo+itinerary&amp;chat_type=travel"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields"><div class="try-field"><label class="try-label">Message</label><input class="try-input" id="qwen-feature-travel-prompt" type="text" placeholder="Tokyo itinerary" /></div></div>
<button class="run-btn" onclick="runQwenFeature('travel',this)">β–Ά Run</button>
<div class="result-box" id="qwen-feature-travel-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/qwen/ask<span class="q">?prompt=&lt;msg&gt;&amp;chat_type=learn</span></span>
<span class="ep-summary">Learn</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="str">"<script>document.write(window.__BASE)</script>/api/qwen/ask?prompt=explain+quantum&amp;chat_type=learn"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields"><div class="try-field"><label class="try-label">Message</label><input class="try-input" id="qwen-feature-learn-prompt" type="text" placeholder="explain quantum" /></div></div>
<button class="run-btn" onclick="runQwenFeature('learn',this)">β–Ά Run</button>
<div class="result-box" id="qwen-feature-learn-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/qwen/ask<span class="q">?prompt=&lt;msg&gt;&amp;chat_type=deep_research</span></span>
<span class="ep-summary">Deep Research</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="str">"<script>document.write(window.__BASE)</script>/api/qwen/ask?prompt=climate+change+effects&amp;chat_type=deep_research"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields"><div class="try-field"><label class="try-label">Message</label><input class="try-input" id="qwen-feature-deep_research-prompt" type="text" placeholder="climate change effects" /></div></div>
<button class="run-btn" onclick="runQwenFeature('deep_research',this)">β–Ά Run</button>
<div class="result-box" id="qwen-feature-deep_research-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/qwen/ask<span class="q">?prompt=&lt;msg&gt;&amp;chat_type=web_dev</span></span>
<span class="ep-summary">Web Dev</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="str">"<script>document.write(window.__BASE)</script>/api/qwen/ask?prompt=React+component&amp;chat_type=web_dev"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields"><div class="try-field"><label class="try-label">Message</label><input class="try-input" id="qwen-feature-web_dev-prompt" type="text" placeholder="React component" /></div></div>
<button class="run-btn" onclick="runQwenFeature('web_dev',this)">β–Ά Run</button>
<div class="result-box" id="qwen-feature-web_dev-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/qwen/ask<span class="q">?prompt=&lt;msg&gt;&amp;chat_type=search</span></span>
<span class="ep-summary">Search</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="str">"<script>document.write(window.__BASE)</script>/api/qwen/ask?prompt=latest+tech+news&amp;chat_type=search"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields"><div class="try-field"><label class="try-label">Message</label><input class="try-input" id="qwen-feature-search-prompt" type="text" placeholder="latest tech news" /></div></div>
<button class="run-btn" onclick="runQwenFeature('search',this)">β–Ά Run</button>
<div class="result-box" id="qwen-feature-search-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/qwen/ask<span class="q">?prompt=&lt;msg&gt;&amp;chat_type=artifacts</span></span>
<span class="ep-summary">Artifacts</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="str">"<script>document.write(window.__BASE)</script>/api/qwen/ask?prompt=draw+an+SVG+logo&amp;chat_type=artifacts"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields"><div class="try-field"><label class="try-label">Message</label><input class="try-input" id="qwen-feature-artifacts-prompt" type="text" placeholder="draw an SVG logo" /></div></div>
<button class="run-btn" onclick="runQwenFeature('artifacts',this)">β–Ά Run</button>
<div class="result-box" id="qwen-feature-artifacts-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/qwen/ask<span class="q">?prompt=&lt;msg&gt;&amp;chat_type=tools</span></span>
<span class="ep-summary">Tools</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="str">"<script>document.write(window.__BASE)</script>/api/qwen/ask?prompt=calculator+tool&amp;chat_type=tools"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields"><div class="try-field"><label class="try-label">Message</label><input class="try-input" id="qwen-feature-tools-prompt" type="text" placeholder="calculator tool" /></div></div>
<button class="run-btn" onclick="runQwenFeature('tools',this)">β–Ά Run</button>
<div class="result-box" id="qwen-feature-tools-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/qwen/ask<span class="q">?prompt=&lt;msg&gt;&amp;chat_type=code</span></span>
<span class="ep-summary">Code</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="str">"<script>document.write(window.__BASE)</script>/api/qwen/ask?prompt=Python+fibonacci&amp;chat_type=code"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields"><div class="try-field"><label class="try-label">Message</label><input class="try-input" id="qwen-feature-code-prompt" type="text" placeholder="Python fibonacci" /></div></div>
<button class="run-btn" onclick="runQwenFeature('code',this)">β–Ά Run</button>
<div class="result-box" id="qwen-feature-code-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/qwen/ask<span class="q">?prompt=&lt;msg&gt;&amp;chat_type=drawing</span></span>
<span class="ep-summary">Drawing</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="str">"<script>document.write(window.__BASE)</script>/api/qwen/ask?prompt=design+a+UI+sketch&amp;chat_type=drawing"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields"><div class="try-field"><label class="try-label">Message</label><input class="try-input" id="qwen-feature-drawing-prompt" type="text" placeholder="design a UI sketch" /></div></div>
<button class="run-btn" onclick="runQwenFeature('drawing',this)">β–Ά Run</button>
<div class="result-box" id="qwen-feature-drawing-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/qwen/ask<span class="q">?prompt=&lt;msg&gt;&amp;chat_type=roleplay</span></span>
<span class="ep-summary">Roleplay</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="str">"<script>document.write(window.__BASE)</script>/api/qwen/ask?prompt=you+are+a+detective&amp;chat_type=roleplay"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields"><div class="try-field"><label class="try-label">Message</label><input class="try-input" id="qwen-feature-roleplay-prompt" type="text" placeholder="you are a detective" /></div></div>
<button class="run-btn" onclick="runQwenFeature('roleplay',this)">β–Ά Run</button>
<div class="result-box" id="qwen-feature-roleplay-result" style="display:none"></div>
</div>
</div>
</div>
<h2 style="margin-top:24px">Files &amp; Conversations</h2>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge POST">POST</span>
<span class="ep-path">/api/qwen/upload</span>
<span class="ep-summary">Upload file</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<p>Upload a file as base64 content.</p>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X POST <span class="url">"<script>document.write(window.__BASE)</script>/api/qwen/upload"</span> <span class="kw">\</span>
-H <span class="str">"Content-Type: application/json"</span> <span class="kw">\</span>
--data <span class="str">'{"content":"aGVsbG8=","filename":"hello.txt"}'</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<button class="run-btn" onclick="runQwenUpload(this)">β–Ά Run</button>
<div class="result-box" id="qwen-upload-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/qwen/uploads/<span class="q">:file</span></span>
<span class="ep-summary">Serve uploaded file</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button></div>
<div class="tab-pane active" data-pane="docs">
<p>Retrieve an uploaded file by filename.</p>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="url">"<script>document.write(window.__BASE)</script>/api/qwen/uploads/&lt;filename&gt;"</span></pre></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/qwen/conversations</span>
<span class="ep-summary">List conversations</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="url">"<script>document.write(window.__BASE)</script>/api/qwen/conversations"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<button class="run-btn" onclick="runQwenConversations(this)">β–Ά Run</button>
<div class="result-box" id="qwen-conversations-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge DELETE">DELETE</span>
<span class="ep-path">/api/qwen/conversations</span>
<span class="ep-summary">Delete all convos</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X DELETE <span class="url">"<script>document.write(window.__BASE)</script>/api/qwen/conversations"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<button class="run-btn" style="background:var(--red)" onclick="runQwenDeleteAllConvos(this)">β–Ά Run</button>
<div class="result-box" id="qwen-deleteall-convos-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge DELETE">DELETE</span>
<span class="ep-path">/api/qwen/conversations/<span class="q">:id</span></span>
<span class="ep-summary">Delete one convo</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X DELETE <span class="url">"<script>document.write(window.__BASE)</script>/api/qwen/conversations/&lt;id&gt;"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields"><div class="try-field"><label class="try-label">Conversation ID</label><input class="try-input" id="qwen-delete-convo-id" type="text" /></div></div>
<button class="run-btn" style="background:var(--red)" onclick="runQwenDeleteConvo(this)">β–Ά Run</button>
<div class="result-box" id="qwen-delete-convo-result" style="display:none"></div>
</div>
</div>
</div>
</div>
<!-- ══ KIMI ══ -->
<div class="provider-content" id="provider-kimi">
<div class="section-eyebrow">Kimi</div>
<h2>Kimi API</h2>
<p class="section-desc">Token-based client for Kimi AI chat. Configure via <code>kimi.json</code> cookies file with a <code>kimi-auth</code> cookie entry (JWT token).</p>
<div class="status-grid">
<div class="stat-card"><div class="stat-label">Status</div><div class="stat-value" id="kimi-status">β€”</div><div class="stat-sub">configured</div></div>
</div>
<div class="endpoint open">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/kimi/health</span>
<span class="ep-summary">Health check</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="url">"<script>document.write(window.__BASE)</script>/api/kimi/health"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<button class="run-btn" onclick="runKimiHealth(this)">β–Ά Run</button>
<div class="result-box" id="kimi-health-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/kimi/user</span>
<span class="ep-summary">User info</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="url">"<script>document.write(window.__BASE)</script>/api/kimi/user"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<button class="run-btn" onclick="runKimiUser(this)">β–Ά Run</button>
<div class="result-box" id="kimi-user-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/kimi/models</span>
<span class="ep-summary">List models</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="url">"<script>document.write(window.__BASE)</script>/api/kimi/models"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<button class="run-btn" onclick="runKimiModels(this)">β–Ά Run</button>
<div class="result-box" id="kimi-models-result" style="display:none"></div>
</div>
</div>
</div>
<h2 style="margin-top:24px">Chat</h2>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/kimi/chat<span class="q">?prompt=&lt;msg&gt;</span></span>
<span class="ep-summary">Chat (GET)</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<p>Params: <code>prompt</code> (req), <code>sessionId</code>, <code>thinking</code>, <code>delete</code> (Auto-delete session after reply).</p>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="str">"<script>document.write(window.__BASE)</script>/api/kimi/chat?prompt=Hello"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields"><div class="try-field"><label class="try-label">Message</label><input class="try-input" id="kimi-prompt" type="text" placeholder="Hello" /></div>
<div class="try-field" style="flex-direction:row;align-items:center;gap:6px"><input type="checkbox" id="kimi-chat-delete" style="accent-color:var(--red)"><label class="try-label" for="kimi-chat-delete" style="cursor:pointer;text-transform:none;font-size:11px">Delete after chat</label></div></div>
<button class="run-btn" onclick="runKimiChat(this)">β–Ά Run</button>
<div class="result-box" id="kimi-chat-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge POST">POST</span>
<span class="ep-path">/api/kimi/chat</span>
<span class="ep-summary">Chat (POST)</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button></div>
<div class="tab-pane active" data-pane="docs">
<p>Send message via POST with JSON body.</p>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X POST <span class="url">"<script>document.write(window.__BASE)</script>/api/kimi/chat"</span> <span class="kw">\</span>
-H <span class="str">"Content-Type: application/json"</span> <span class="kw">\</span>
--data <span class="str">'{"prompt":"Hello"}'</span></pre></div>
</div>
</div>
</div>
<h2 style="margin-top:24px">Sessions</h2>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/kimi/sessions</span>
<span class="ep-summary">List sessions</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="url">"<script>document.write(window.__BASE)</script>/api/kimi/sessions"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<button class="run-btn" onclick="runKimiSessions(this)">β–Ά Run</button>
<div class="result-box" id="kimi-sessions-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge POST">POST</span>
<span class="ep-path">/api/kimi/sessions</span>
<span class="ep-summary">Create session</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X POST <span class="url">"<script>document.write(window.__BASE)</script>/api/kimi/sessions"</span> <span class="kw">\</span>
-H <span class="str">"Content-Type: application/json"</span> <span class="kw">\</span>
--data <span class="str">'{"name":"My Chat"}'</span></pre></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/kimi/sessions/<span class="q">:id</span></span>
<span class="ep-summary">Get session</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="url">"<script>document.write(window.__BASE)</script>/api/kimi/sessions/&lt;id&gt;"</span></pre></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/kimi/sessions/<span class="q">:id</span>/messages</span>
<span class="ep-summary">List messages</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="url">"<script>document.write(window.__BASE)</script>/api/kimi/sessions/&lt;id&gt;/messages"</span></pre></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge POST">POST</span>
<span class="ep-path">/api/kimi/chat/<span class="q">:id</span></span>
<span class="ep-summary">Chat in session</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button></div>
<div class="tab-pane active" data-pane="docs">
<p>Send message to an existing session.</p>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X POST <span class="url">"<script>document.write(window.__BASE)</script>/api/kimi/chat/&lt;id&gt;"</span> <span class="kw">\</span>
-H <span class="str">"Content-Type: application/json"</span> <span class="kw">\</span>
--data <span class="str">'{"prompt":"Hello"}'</span></pre></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge PUT">PUT</span>
<span class="ep-path">/api/kimi/sessions/<span class="q">:id</span></span>
<span class="ep-summary">Update session</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X PUT <span class="url">"<script>document.write(window.__BASE)</script>/api/kimi/sessions/&lt;id&gt;"</span> <span class="kw">\</span>
-H <span class="str">"Content-Type: application/json"</span> <span class="kw">\</span>
--data <span class="str">'{"chat":{"name":"New Name"}}'</span></pre></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge DELETE">DELETE</span>
<span class="ep-path">/api/kimi/sessions/<span class="q">:id</span></span>
<span class="ep-summary">Delete session</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X DELETE <span class="url">"<script>document.write(window.__BASE)</script>/api/kimi/sessions/&lt;id&gt;"</span></pre></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge DELETE">DELETE</span>
<span class="ep-path">/api/kimi/sessions</span>
<span class="ep-summary">Delete all sessions</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X DELETE <span class="url">"<script>document.write(window.__BASE)</script>/api/kimi/sessions"</span></pre></div>
</div>
</div>
</div>
<h2 style="margin-top:24px">Kimi+</h2>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/kimi/kimiplus</span>
<span class="ep-summary">List Kimi+</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="url">"<script>document.write(window.__BASE)</script>/api/kimi/kimiplus"</span></pre></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/kimi/kimiplus/<span class="q">:id</span></span>
<span class="ep-summary">Get Kimi+ detail</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="url">"<script>document.write(window.__BASE)</script>/api/kimi/kimiplus/&lt;id&gt;"</span></pre></div>
</div>
</div>
</div>
<h2 style="margin-top:24px">Other</h2>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge POST">POST</span>
<span class="ep-path">/api/kimi/cancel/<span class="q">:chatId</span>/<span class="q">:messageId</span></span>
<span class="ep-summary">Cancel stream</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X POST <span class="url">"<script>document.write(window.__BASE)</script>/api/kimi/cancel/&lt;chatId&gt;/&lt;messageId&gt;"</span></pre></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge POST">POST</span>
<span class="ep-path">/api/kimi/vote/<span class="q">:chatId</span>/<span class="q">:messageId</span></span>
<span class="ep-summary">Vote message</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X POST <span class="url">"<script>document.write(window.__BASE)</script>/api/kimi/vote/&lt;chatId&gt;/&lt;messageId&gt;"</span> <span class="kw">\</span>
-H <span class="str">"Content-Type: application/json"</span> <span class="kw">\</span>
--data <span class="str">'{"voteType":"upvote"}'</span></pre></div>
</div>
</div>
</div>
</div>
<!-- ══ CLAUDE ══ -->
<div class="provider-content" id="provider-claude">
<div class="section-eyebrow">Anthropic Claude</div>
<h2>Claude API</h2>
<p class="section-desc">Free Claude access via <a href="https://puter.com">Puter</a>'s driver API. Configure an <code>auth_token</code> in <code>data/claude.json</code>.</p>
<div class="status-grid">
<div class="stat-card"><div class="stat-label">Status</div><div class="stat-value" id="claude-status">β€”</div><div class="stat-sub">configured</div></div>
</div>
<div class="endpoint open">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/claude/health</span>
<span class="ep-summary">Health check</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="url">"<script>document.write(window.__BASE)</script>/api/claude/health"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<button class="run-btn" onclick="runClaudeHealth(this)">β–Ά Run</button>
<div class="result-box" id="claude-health-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/claude/models</span>
<span class="ep-summary">List models</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="url">"<script>document.write(window.__BASE)</script>/api/claude/models"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<button class="run-btn" onclick="runClaudeModels(this)">β–Ά Run</button>
<div class="result-box" id="claude-models-result" style="display:none"></div>
</div>
</div>
</div>
<h2 style="margin-top:24px">Chat</h2>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/claude/chat<span class="q">?ask=&lt;msg&gt;</span></span>
<span class="ep-summary">Chat (GET)</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<p>Query params: <code>ask</code> (required), <code>model</code> (optional, default: claude-sonnet-4-6).</p>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="str">"<script>document.write(window.__BASE)</script>/api/claude/chat?ask=Hello"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields"><div class="try-field"><label class="try-label">Message</label><input class="try-input" id="claude-prompt" type="text" placeholder="Hello" /></div></div>
<button class="run-btn" onclick="runClaudeChat(this)">β–Ά Run</button>
<div class="result-box" id="claude-chat-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge POST">POST</span>
<span class="ep-path">/api/claude/chat</span>
<span class="ep-summary">Chat (POST)</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button></div>
<div class="tab-pane active" data-pane="docs">
<p>Send messages array with optional streaming. Body: <code>{ messages, model?, stream?, max_tokens? }</code>.</p>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X POST <span class="url">"<script>document.write(window.__BASE)</script>/api/claude/chat"</span> <span class="kw">\</span>
-H <span class="str">"Content-Type: application/json"</span> <span class="kw">\</span>
--data <span class="str">'{"messages":[{"role":"user","content":"Hello"}],"model":"claude-sonnet-4-6"}'</span></pre></div>
</div>
</div>
</div>
<h2 style="margin-top:24px">Available Models</h2>
<div class="model-grid">
<div class="model-chip">claude-sonnet-4-6</div>
<div class="model-chip">claude-opus-4-7</div>
<div class="model-chip">claude-haiku-4-5</div>
<div class="model-chip">claude-opus-4-6</div>
<div class="model-chip">claude-3-sonnet</div>
<div class="model-chip">claude-3-haiku</div>
<div class="model-chip">claude-3-opus</div>
</div>
<h2 style="margin-top:24px">V1 / Anthropic-compatible</h2>
<p class="section-desc">Claude also supports the <code>/v1/messages</code> endpoint with Anthropic-style model names β€” the gateway maps them to Puter driver models automatically.</p>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge POST">POST</span>
<span class="ep-path">/v1/messages</span>
<span class="ep-summary">Anthropic-compatible chat</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button></div>
<div class="tab-pane active" data-pane="docs">
<p>Anthropic Message API format. Model names like <code>claude-sonnet-4-20250514</code>, <code>claude-opus-4-7</code> are mapped automatically.</p>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X POST <span class="url">"<script>document.write(window.__BASE)</script>/v1/messages"</span> <span class="kw">\</span>
-H <span class="str">"Content-Type: application/json"</span> <span class="kw">\</span>
--data <span class="str">'{"model":"claude-sonnet-4-20250514","messages":[{"role":"user","content":"Hello"}],"max_tokens":1024}'</span></pre></div>
</div>
</div>
</div>
</div>
<!-- ══ GPT ══ -->
<div class="provider-content" id="provider-gpt">
<div class="section-eyebrow">OpenAI</div>
<h2>GPT API</h2>
<p class="section-desc">Free GPT access via <a href="https://puter.com">Puter</a>'s driver API. Configure an <code>auth_token</code> in <code>data/gpt.json</code> (can reuse <code>data/claude.json</code> token).</p>
<div class="status-grid">
<div class="stat-card"><div class="stat-label">Status</div><div class="stat-value" id="gpt-status">β€”</div><div class="stat-sub">configured</div></div>
</div>
<div class="endpoint open">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/gpt/health</span>
<span class="ep-summary">Health check</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="url">"<script>document.write(window.__BASE)</script>/api/gpt/health"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<button class="run-btn" onclick="runGptHealth(this)">β–Ά Run</button>
<div class="result-box" id="gpt-health-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/gpt/models</span>
<span class="ep-summary">List models</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="url">"<script>document.write(window.__BASE)</script>/api/gpt/models"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<button class="run-btn" onclick="runGptModels(this)">β–Ά Run</button>
<div class="result-box" id="gpt-models-result" style="display:none"></div>
</div>
</div>
</div>
<h2 style="margin-top:24px">Chat</h2>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/gpt/chat<span class="q">?ask=&lt;msg&gt;</span></span>
<span class="ep-summary">Chat (GET)</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<p>Query params: <code>ask</code> (required), <code>model</code> (optional, default: gpt-4o).</p>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="str">"<script>document.write(window.__BASE)</script>/api/gpt/chat?ask=Hello"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields"><div class="try-field"><label class="try-label">Message</label><input class="try-input" id="gpt-prompt" type="text" placeholder="Hello" /></div></div>
<button class="run-btn" onclick="runGptChat(this)">β–Ά Run</button>
<div class="result-box" id="gpt-chat-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge POST">POST</span>
<span class="ep-path">/api/gpt/chat</span>
<span class="ep-summary">Chat (POST)</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button></div>
<div class="tab-pane active" data-pane="docs">
<p>Send messages array with optional streaming. Body: <code>{ messages, model?, stream?, max_tokens? }</code>.</p>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X POST <span class="url">"<script>document.write(window.__BASE)</script>/api/gpt/chat"</span> <span class="kw">\</span>
-H <span class="str">"Content-Type: application/json"</span> <span class="kw">\</span>
--data <span class="str">'{"messages":[{"role":"user","content":"Hello"}],"model":"gpt-4o"}'</span></pre></div>
</div>
</div>
</div>
<h2 style="margin-top:24px">Available Models</h2>
<div class="model-grid">
<div class="model-chip">gpt-4o</div>
<div class="model-chip">gpt-4o-mini</div>
<div class="model-chip">gpt-4.1</div>
<div class="model-chip">gpt-4.1-mini</div>
<div class="model-chip">gpt-4.1-nano</div>
<div class="model-chip">gpt-4.5-preview</div>
<div class="model-chip">gpt-5-chat-latest</div>
<div class="model-chip">gpt-5.1</div>
<div class="model-chip">gpt-5.1-chat-latest</div>
<div class="model-chip">gpt-5.2-chat-latest</div>
<div class="model-chip">gpt-5.4</div>
<div class="model-chip">gpt-5.4-nano</div>
<div class="model-chip">gpt-5.5</div>
<div class="model-chip">o1</div>
<div class="model-chip">o1-mini</div>
<div class="model-chip">o3-mini</div>
<div class="model-chip">o4-mini</div>
</div>
</div>
<!-- ══ GROK ══ -->
<div class="provider-content" id="provider-grok">
<div class="section-eyebrow">xAI</div>
<h2>Grok API</h2>
<p class="section-desc">Free Grok access via <a href="https://puter.com">Puter</a>'s driver API. Configure an <code>auth_token</code> in <code>data/grok.json</code> (can reuse <code>data/claude.json</code> token).</p>
<div class="status-grid">
<div class="stat-card"><div class="stat-label">Status</div><div class="stat-value" id="grok-status">β€”</div><div class="stat-sub">configured</div></div>
</div>
<div class="endpoint open">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/grok/health</span>
<span class="ep-summary">Health check</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="url">"<script>document.write(window.__BASE)</script>/api/grok/health"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<button class="run-btn" onclick="runGrokHealth(this)">β–Ά Run</button>
<div class="result-box" id="grok-health-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/grok/models</span>
<span class="ep-summary">List models</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="url">"<script>document.write(window.__BASE)</script>/api/grok/models"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<button class="run-btn" onclick="runGrokModels(this)">β–Ά Run</button>
<div class="result-box" id="grok-models-result" style="display:none"></div>
</div>
</div>
</div>
<h2 style="margin-top:24px">Chat</h2>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/grok/chat<span class="q">?ask=&lt;msg&gt;</span></span>
<span class="ep-summary">Chat (GET)</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<p>Query params: <code>ask</code> (required), <code>model</code> (optional, default: grok-3).</p>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="str">"<script>document.write(window.__BASE)</script>/api/grok/chat?ask=Hello"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields"><div class="try-field"><label class="try-label">Message</label><input class="try-input" id="grok-prompt" type="text" placeholder="Hello" /></div></div>
<button class="run-btn" onclick="runGrokChat(this)">β–Ά Run</button>
<div class="result-box" id="grok-chat-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge POST">POST</span>
<span class="ep-path">/api/grok/chat</span>
<span class="ep-summary">Chat (POST)</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button></div>
<div class="tab-pane active" data-pane="docs">
<p>Send messages array with optional streaming. Body: <code>{ messages, model?, stream?, max_tokens? }</code>.</p>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X POST <span class="url">"<script>document.write(window.__BASE)</script>/api/grok/chat"</span> <span class="kw">\</span>
-H <span class="str">"Content-Type: application/json"</span> <span class="kw">\</span>
--data <span class="str">'{"messages":[{"role":"user","content":"Hello"}],"model":"grok-3"}'</span></pre></div>
</div>
</div>
</div>
<h2 style="margin-top:24px">Available Models</h2>
<div class="model-grid">
<div class="model-chip">grok-3</div>
<div class="model-chip">grok-3-fast</div>
<div class="model-chip">grok-3-mini</div>
<div class="model-chip">grok-3-mini-fast</div>
<div class="model-chip">grok-4</div>
<div class="model-chip">grok-4-fast</div>
<div class="model-chip">grok-4-1-fast</div>
<div class="model-chip">grok-4.3</div>
<div class="model-chip">grok-beta</div>
<div class="model-chip">grok-2-vision</div>
</div>
</div>
<!-- ══ META AI ══ -->
<div class="provider-content" id="provider-meta">
<div class="section-eyebrow">Meta</div>
<h2>Meta AI API</h2>
<p class="section-desc">Cookie-based proxy to Meta AI (Llama). Requires <code>ecto_1_sess</code> and <code>datr</code> cookies in <code>data/meta.json</code>.</p>
<div class="status-grid">
<div class="stat-card"><div class="stat-label">Status</div><div class="stat-value" id="meta-status">β€”</div><div class="stat-sub">configured</div></div>
</div>
<div class="endpoint open">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/meta/health</span>
<span class="ep-summary">Health check</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="url">"<script>document.write(window.__BASE)</script>/api/meta/health"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<button class="run-btn" onclick="runMetaHealth(this)">β–Ά Run</button>
<div class="result-box" id="meta-health-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/meta/models</span>
<span class="ep-summary">List models</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="url">"<script>document.write(window.__BASE)</script>/api/meta/models"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<button class="run-btn" onclick="runMetaModels(this)">β–Ά Run</button>
<div class="result-box" id="meta-models-result" style="display:none"></div>
</div>
</div>
</div>
<h2 style="margin-top:24px">Chat</h2>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/meta/chat<span class="q">?ask=&lt;msg&gt;</span></span>
<span class="ep-summary">Chat (GET)</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<p>Query params: <code>ask</code> (required). Optionally <code>delete=true</code> to auto-delete conversation.</p>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="str">"<script>document.write(window.__BASE)</script>/api/meta/chat?ask=Hello"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields"><div class="try-field"><label class="try-label">Message</label><input class="try-input" id="meta-prompt" type="text" placeholder="Hello" /></div>
<div class="try-field" style="flex-direction:row;align-items:center;gap:6px"><input type="checkbox" id="meta-chat-delete" style="accent-color:var(--red)"><label class="try-label" for="meta-chat-delete" style="cursor:pointer;text-transform:none;font-size:11px">Delete after chat</label></div></div>
<button class="run-btn" onclick="runMetaChat(this)">β–Ά Run</button>
<div class="result-box" id="meta-chat-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge POST">POST</span>
<span class="ep-path">/api/meta/chat</span>
<span class="ep-summary">Chat (POST)</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button></div>
<div class="tab-pane active" data-pane="docs">
<p>Send messages array. Body: <code>{ messages, model? }</code>.</p>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X POST <span class="url">"<script>document.write(window.__BASE)</script>/api/meta/chat"</span> <span class="kw">\</span>
-H <span class="str">"Content-Type: application/json"</span> <span class="kw">\</span>
--data <span class="str">'{"messages":[{"role":"user","content":"Hello"}]}'</span></pre></div>
</div>
</div>
</div>
<h2 style="margin-top:24px">Image Generation</h2>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/meta/image<span class="q">?prompt=&lt;desc&gt;</span></span>
<span class="ep-summary">Generate image</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<p>Query params: <code>prompt</code> (required), <code>orientation</code> (optional: VERTICAL, HORIZONTAL, SQUARE).</p>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="str">"<script>document.write(window.__BASE)</script>/api/meta/image?prompt=a+cat&orientation=SQUARE"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields"><div class="try-field"><label class="try-label">Prompt</label><input class="try-input" id="meta-image-prompt" type="text" placeholder="a cat" /></div>
<div class="try-field"><label class="try-label">Orientation</label><select class="try-input" id="meta-image-orientation"><option value="VERTICAL">VERTICAL</option><option value="HORIZONTAL">HORIZONTAL</option><option value="SQUARE">SQUARE</option></select></div></div>
<button class="run-btn" onclick="runMetaImage(this)">β–Ά Run</button>
<div class="result-box" id="meta-image-result" style="display:none"></div>
</div>
</div>
</div>
<h2 style="margin-top:24px">Video Generation</h2>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/api/meta/video<span class="q">?prompt=&lt;desc&gt;</span></span>
<span class="ep-summary">Generate video</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<p>Query params: <code>prompt</code> (required). Video generation is async β€” returns a processing status.</p>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="str">"<script>document.write(window.__BASE)</script>/api/meta/video?prompt=a+cat+playing"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields"><div class="try-field"><label class="try-label">Prompt</label><input class="try-input" id="meta-video-prompt" type="text" placeholder="a cat playing" /></div></div>
<button class="run-btn" onclick="runMetaVideo(this)">β–Ά Run</button>
<div class="result-box" id="meta-video-result" style="display:none"></div>
</div>
</div>
</div>
<h2 style="margin-top:24px">Available Models</h2>
<div class="model-grid">
<div class="model-chip" style="background:var(--indigo-bg);border-color:var(--indigo)">meta-ai</div>
</div>
</div>
<!-- ══ V1 API ══ -->
<div class="provider-content" id="provider-v1">
<div class="section-eyebrow">OpenAI-Compatible</div>
<h2>V1 API</h2>
<p class="section-desc">Unified OpenAI-compatible <code>/v1/chat/completions</code> endpoint that routes to any provider. All models are mapped automatically β€” just set the <code>model</code> field in your request body.</p>
<div class="status-grid">
<div class="stat-card"><div class="stat-label">Endpoint</div><div class="stat-value" style="font-size:13px;word-break:break-all">POST /v1/chat/completions</div><div class="stat-sub">OpenAI-compatible</div></div>
</div>
<h2 style="margin-top:24px">Available Models</h2>
<div class="model-grid" style="margin-bottom:24px">
<div class="model-chip" style="background:var(--blue-bg);border-color:var(--blue)">gemini</div>
<div class="model-chip" style="background:var(--blue-bg);border-color:var(--blue)">gemini-fast</div>
<div class="model-chip" style="background:var(--blue-bg);border-color:var(--blue)">gemini-flash</div>
<div class="model-chip" style="background:var(--blue-bg);border-color:var(--blue)">gemini-thinking</div>
<div class="model-chip" style="background:var(--blue-bg);border-color:var(--blue)">gemini-pro</div>
<div class="model-chip" style="background:var(--cyan-bg);border-color:var(--cyan)">deepseek</div>
<div class="model-chip" style="background:var(--cyan-bg);border-color:var(--cyan)">deepseek-default</div>
<div class="model-chip" style="background:var(--cyan-bg);border-color:var(--cyan)">deepseek-instant</div>
<div class="model-chip" style="background:var(--cyan-bg);border-color:var(--cyan)">deepseek-thinking</div>
<div class="model-chip" style="background:var(--cyan-bg);border-color:var(--cyan)">deepseek-expert</div>
<div class="model-chip" style="background:var(--cyan-bg);border-color:var(--cyan)">deepseek-search</div>
<div class="model-chip" style="background:var(--cyan-bg);border-color:var(--cyan)">deepseek-vision</div>
<div class="model-chip" style="background:var(--purple-bg);border-color:var(--purple)">qwen</div>
<div class="model-chip" style="background:var(--purple-bg);border-color:var(--purple)">qwen-normal</div>
<div class="model-chip" style="background:var(--purple-bg);border-color:var(--purple)">qwen-fast</div>
<div class="model-chip" style="background:var(--purple-bg);border-color:var(--purple)">qwen-thinking</div>
<div class="model-chip" style="background:var(--purple-bg);border-color:var(--purple)">qwen3.7-max</div>
<div class="model-chip" style="background:var(--purple-bg);border-color:var(--purple)">qwen3.7-max-fast</div>
<div class="model-chip" style="background:var(--purple-bg);border-color:var(--purple)">qwen3.7-max-thinking</div>
<div class="model-chip" style="background:var(--purple-bg);border-color:var(--purple)">qwen3.6-plus</div>
<div class="model-chip" style="background:var(--purple-bg);border-color:var(--purple)">qwen3.6-plus-fast</div>
<div class="model-chip" style="background:var(--purple-bg);border-color:var(--purple)">qwen3.6-plus-thinking</div>
<div class="model-chip" style="background:var(--purple-bg);border-color:var(--purple)">qwen3.5-flash</div>
<div class="model-chip" style="background:var(--purple-bg);border-color:var(--purple)">qwen3.5-flash-normal</div>
<div class="model-chip" style="background:var(--purple-bg);border-color:var(--purple)">qwen3.5-flash-thinking</div>
<div class="model-chip" style="background:var(--purple-bg);border-color:var(--purple)">meta</div>
<div class="model-chip" style="background:var(--purple-bg);border-color:var(--purple)">meta-ai</div>
<div class="model-chip" style="background:var(--purple-bg);border-color:var(--purple)">meta-fast</div>
<div class="model-chip" style="background:var(--purple-bg);border-color:var(--purple)">meta-thinking</div>
<div class="model-chip" style="background:var(--pink-bg);border-color:var(--pink)">kimi</div>
<div class="model-chip" style="background:var(--pink-bg);border-color:var(--pink)">kimi-default</div>
<div class="model-chip" style="background:var(--pink-bg);border-color:var(--pink)">kimi-thinking</div>
<div class="model-chip" style="background:var(--orange-bg);border-color:var(--orange)">claude</div>
<div class="model-chip" style="background:var(--orange-bg);border-color:var(--orange)">claude-sonnet</div>
<div class="model-chip" style="background:var(--orange-bg);border-color:var(--orange)">claude-opus</div>
<div class="model-chip" style="background:var(--orange-bg);border-color:var(--orange)">claude-haiku</div>
<div class="model-chip" style="background:var(--orange-bg);border-color:var(--orange)">claude-sonnet-4-6</div>
<div class="model-chip" style="background:var(--orange-bg);border-color:var(--orange)">claude-opus-4-7</div>
<div class="model-chip" style="background:var(--orange-bg);border-color:var(--orange)">claude-haiku-4-5</div>
<div class="model-chip" style="background:var(--green-bg);border-color:var(--green)">gpt-4o</div>
<div class="model-chip" style="background:var(--green-bg);border-color:var(--green)">gpt-4o-mini</div>
<div class="model-chip" style="background:var(--green-bg);border-color:var(--green)">gpt-4.1</div>
<div class="model-chip" style="background:var(--green-bg);border-color:var(--green)">gpt-4.1-mini</div>
<div class="model-chip" style="background:var(--green-bg);border-color:var(--green)">gpt-5-chat-latest</div>
<div class="model-chip" style="background:var(--green-bg);border-color:var(--green)">gpt-5.1</div>
<div class="model-chip" style="background:var(--green-bg);border-color:var(--green)">gpt-5.1-chat-latest</div>
<div class="model-chip" style="background:var(--green-bg);border-color:var(--green)">gpt-5.2-chat-latest</div>
<div class="model-chip" style="background:var(--green-bg);border-color:var(--green)">gpt-5.4</div>
<div class="model-chip" style="background:var(--green-bg);border-color:var(--green)">gpt-5.5</div>
<div class="model-chip" style="background:var(--green-bg);border-color:var(--green)">o1</div>
<div class="model-chip" style="background:var(--green-bg);border-color:var(--green)">o1-mini</div>
<div class="model-chip" style="background:var(--green-bg);border-color:var(--green)">o3-mini</div>
<div class="model-chip" style="background:var(--green-bg);border-color:var(--green)">o4-mini</div>
<div class="model-chip" style="background:var(--red-bg);border-color:var(--red)">grok-3</div>
<div class="model-chip" style="background:var(--red-bg);border-color:var(--red)">grok-3-fast</div>
<div class="model-chip" style="background:var(--red-bg);border-color:var(--red)">grok-3-mini</div>
<div class="model-chip" style="background:var(--red-bg);border-color:var(--red)">grok-4</div>
<div class="model-chip" style="background:var(--red-bg);border-color:var(--red)">grok-4-fast</div>
<div class="model-chip" style="background:var(--red-bg);border-color:var(--red)">grok-4.3</div>
<div class="model-chip" style="background:var(--indigo-bg);border-color:var(--indigo)">meta</div>
<div class="model-chip" style="background:var(--indigo-bg);border-color:var(--indigo)">meta-ai</div>
</div>
<div class="endpoint open">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge POST">POST</span>
<span class="ep-path">/v1/chat/completions</span>
<span class="ep-summary">OpenAI-compatible chat</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<p>Pass any model ID from the list above in the <code>model</code> field. The gateway routes to the correct provider automatically.</p>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X POST <span class="url">"<script>document.write(window.__BASE)</script>/v1/chat/completions"</span> <span class="kw">\</span>
-H <span class="str">"Content-Type: application/json"</span> <span class="kw">\</span>
--data <span class="str">'{"model":"claude-sonnet-4-6","messages":[{"role":"user","content":"Hello"}]}'</span></pre></div>
<p class="section-desc" style="margin-top:12px">Model prefix shorthand: pass the model name as a URL path segment before <code>/v1/messages</code> (e.g. <code>/claude-sonnet/v1/messages</code>).</p>
</div>
<div class="tab-pane try-panel" data-pane="try">
<div class="try-fields">
<div class="try-field"><label class="try-label">Model</label>
<select class="try-input" id="v1-model">
<optgroup label="Gemini">
<option value="gemini">gemini</option>
<option value="gemini-fast">gemini-fast</option>
<option value="gemini-flash">gemini-flash</option>
<option value="gemini-thinking">gemini-thinking</option>
<option value="gemini-pro">gemini-pro</option>
</optgroup>
<optgroup label="DeepSeek">
<option value="deepseek">deepseek</option>
<option value="deepseek-default">deepseek-default</option>
<option value="deepseek-instant">deepseek-instant</option>
<option value="deepseek-thinking">deepseek-thinking</option>
<option value="deepseek-expert">deepseek-expert</option>
<option value="deepseek-search">deepseek-search</option>
<option value="deepseek-vision">deepseek-vision</option>
</optgroup>
<optgroup label="Qwen">
<option value="qwen">qwen</option>
<option value="qwen-fast">qwen-fast</option>
<option value="qwen-thinking">qwen-thinking</option>
<option value="qwen3.7-max">qwen3.7-max</option>
<option value="qwen3.7-max-fast">qwen3.7-max-fast</option>
<option value="qwen3.7-max-thinking">qwen3.7-max-thinking</option>
<option value="qwen3.6-plus">qwen3.6-plus</option>
<option value="qwen3.6-plus-fast">qwen3.6-plus-fast</option>
<option value="qwen3.6-plus-thinking">qwen3.6-plus-thinking</option>
<option value="qwen3.5-flash">qwen3.5-flash</option>
<option value="qwen3.5-flash-normal">qwen3.5-flash-normal</option>
<option value="qwen3.5-flash-thinking">qwen3.5-flash-thinking</option>
</optgroup>
<optgroup label="Kimi">
<option value="kimi">kimi</option>
<option value="kimi-thinking">kimi-thinking</option>
</optgroup>
<optgroup label="Claude">
<option value="claude-sonnet-4-6" selected>claude-sonnet-4-6</option>
<option value="claude-opus-4-7">claude-opus-4-7</option>
<option value="claude-haiku-4-5">claude-haiku-4-5</option>
</optgroup>
<optgroup label="GPT">
<option value="gpt-4o">gpt-4o</option>
<option value="gpt-4o-mini">gpt-4o-mini</option>
<option value="gpt-4.1">gpt-4.1</option>
<option value="gpt-5-chat-latest">gpt-5-chat-latest</option>
<option value="gpt-5.1">gpt-5.1</option>
<option value="o1">o1</option>
<option value="o3-mini">o3-mini</option>
</optgroup>
<optgroup label="Grok">
<option value="grok-3">grok-3</option>
<option value="grok-3-fast">grok-3-fast</option>
<option value="grok-4">grok-4</option>
<option value="grok-4-fast">grok-4-fast</option>
</optgroup>
<optgroup label="Meta AI">
<option value="meta">meta</option>
<option value="meta-ai">meta-ai</option>
<option value="meta-fast">meta-fast</option>
<option value="meta-thinking">meta-thinking</option>
</optgroup>
</select>
</div>
<div class="try-field"><label class="try-label">Message</label><input class="try-input" id="v1-prompt" type="text" placeholder="Hello" /></div>
</div>
<button class="run-btn" onclick="runV1Chat(this)">β–Ά Run</button>
<div class="result-box" id="v1-chat-result" style="display:none"></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge GET">GET</span>
<span class="ep-path">/v1/models</span>
<span class="ep-summary">List all models</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button><button class="ep-tab" onclick="switchTab(this,'try')">β–Ά Try it</button></div>
<div class="tab-pane active" data-pane="docs">
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> <span class="url">"<script>document.write(window.__BASE)</script>/v1/models"</span></pre></div>
</div>
<div class="tab-pane try-panel" data-pane="try">
<button class="run-btn" onclick="runV1Models(this)">β–Ά Run</button>
<div class="result-box" id="v1-models-result" style="display:none"></div>
</div>
</div>
</div>
<h2 style="margin-top:24px">Usage Examples</h2>
<h3 style="color:var(--blue);margin:16px 0 8px">Gemini</h3>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X POST <span class="url">"<script>document.write(window.__BASE)</script>/v1/chat/completions"</span> <span class="kw">\</span>
-H <span class="str">"Content-Type: application/json"</span> <span class="kw">\</span>
--data <span class="str">'{"model":"gemini-thinking","messages":[{"role":"user","content":"What is 2+2?"}]}'</span></pre></div>
<h3 style="color:var(--cyan);margin:16px 0 8px">DeepSeek</h3>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X POST <span class="url">"<script>document.write(window.__BASE)</script>/v1/chat/completions"</span> <span class="kw">\</span>
-H <span class="str">"Content-Type: application/json"</span> <span class="kw">\</span>
--data <span class="str">'{"model":"deepseek-thinking","messages":[{"role":"user","content":"Explain quantum computing"}]}'</span></pre></div>
<h3 style="color:var(--purple);margin:16px 0 8px">Qwen</h3>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X POST <span class="url">"<script>document.write(window.__BASE)</script>/v1/chat/completions"</span> <span class="kw">\</span>
-H <span class="str">"Content-Type: application/json"</span> <span class="kw">\</span>
--data <span class="str">'{"model":"qwen-thinking","messages":[{"role":"user","content":"Write a poem"}]}'</span></pre></div>
<h3 style="color:var(--pink);margin:16px 0 8px">Kimi</h3>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X POST <span class="url">"<script>document.write(window.__BASE)</script>/v1/chat/completions"</span> <span class="kw">\</span>
-H <span class="str">"Content-Type: application/json"</span> <span class="kw">\</span>
--data <span class="str">'{"model":"kimi-thinking","messages":[{"role":"user","content":"Hello"}]}'</span></pre></div>
<h3 style="color:var(--orange);margin:16px 0 8px">Claude</h3>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X POST <span class="url">"<script>document.write(window.__BASE)</script>/v1/chat/completions"</span> <span class="kw">\</span>
-H <span class="str">"Content-Type: application/json"</span> <span class="kw">\</span>
--data <span class="str">'{"model":"claude-opus-4-7","messages":[{"role":"user","content":"Explain relativity"}]}'</span></pre></div>
<h3 style="color:var(--indigo);margin:16px 0 8px">Meta AI</h3>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X POST <span class="url">"<script>document.write(window.__BASE)</script>/v1/chat/completions"</span> <span class="kw">\</span>
-H <span class="str">"Content-Type: application/json"</span> <span class="kw">\</span>
--data <span class="str">'{"model":"meta","messages":[{"role":"user","content":"Hello"}]}'</span></pre></div>
<h3 style="color:var(--green);margin:16px 0 8px">GPT (OpenAI)</h3>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X POST <span class="url">"<script>document.write(window.__BASE)</script>/v1/chat/completions"</span> <span class="kw">\</span>
-H <span class="str">"Content-Type: application/json"</span> <span class="kw">\</span>
--data <span class="str">'{"model":"gpt-4o","messages":[{"role":"user","content":"Hello"}]}'</span></pre></div>
<h3 style="color:var(--red);margin:16px 0 8px">Grok (xAI)</h3>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X POST <span class="url">"<script>document.write(window.__BASE)</script>/v1/chat/completions"</span> <span class="kw">\</span>
-H <span class="str">"Content-Type: application/json"</span> <span class="kw">\</span>
--data <span class="str">'{"model":"grok-4","messages":[{"role":"user","content":"Hello"}]}'</span></pre></div>
<h2 style="margin-top:24px">Anthropic-compatible</h2>
<p class="section-desc">The gateway also supports Anthropic's <code>/v1/messages</code> format with model override via URL path prefix.</p>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge POST">POST</span>
<span class="ep-path">/v1/messages</span>
<span class="ep-summary">Anthropic Messages API</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button></div>
<div class="tab-pane active" data-pane="docs">
<p>Anthropic-style message format. Maps model names like <code>claude-sonnet-4-20250514</code>, <code>claude-opus-4-7</code> etc. automatically.</p>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X POST <span class="url">"<script>document.write(window.__BASE)</script>/v1/messages"</span> <span class="kw">\</span>
-H <span class="str">"Content-Type: application/json"</span> <span class="kw">\</span>
--data <span class="str">'{"model":"claude-sonnet-4-20250514","messages":[{"role":"user","content":"Hello"}],"max_tokens":1024}'</span></pre></div>
</div>
</div>
</div>
<div class="endpoint">
<button class="ep-header" onclick="toggleEp(this)">
<span class="method-badge POST">POST</span>
<span class="ep-path"><span class="q">:model</span>/v1/messages</span>
<span class="ep-summary">Model-prefixed Messages</span>
<span class="ep-chevron">β–Ά</span>
</button>
<div class="ep-body">
<div class="ep-tabs"><button class="ep-tab active" onclick="switchTab(this,'docs')">Docs</button></div>
<div class="tab-pane active" data-pane="docs">
<p>Override the model by prefixing the URL path. Works with any V1 model ID.</p>
<div class="code-block"><div class="code-top"><span class="code-lang">cURL</span><button class="code-copy-btn" onclick="copyCode(this)">Copy</button></div><pre><span class="kw">curl</span> -X POST <span class="url">"<script>document.write(window.__BASE)</script>/claude-sonnet/v1/messages"</span> <span class="kw">\</span>
-H <span class="str">"Content-Type: application/json"</span> <span class="kw">\</span>
--data <span class="str">'{"messages":[{"role":"user","content":"Hello"}],"max_tokens":1024}'</span></pre></div>
</div>
</div>
</div>
</div>
<footer>
<span>Exocore AI Gateway Β· v1.0.0</span>
<span>Built with <a href="#">@exocore/multi</a></span>
</footer>
</main>
</div>
<script>
const BASE = window.__BASE || window.location.origin;
function copyBase() {
navigator.clipboard.writeText(BASE).then(() => {
const btn = document.getElementById('copyBaseBtn');
btn.textContent = 'Copied!'; btn.classList.add('copied');
setTimeout(() => { btn.textContent = 'Copy'; btn.classList.remove('copied'); }, 1600);
});
}
document.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('pre').forEach(pre => {
pre.innerHTML = pre.innerHTML.replaceAll('http://localhost:3000', BASE);
});
checkAllStatus();
});
function switchProvider(name) {
document.querySelectorAll('.provider-tab').forEach(t => t.classList.toggle('active', t.dataset.provider === name));
document.querySelectorAll('.provider-content').forEach(c => c.classList.toggle('active', c.id === 'provider-' + name));
document.querySelectorAll('.nav-item').forEach(n => n.classList.toggle('active', n.dataset.provider === name));
}
function toggleEp(header) {
header.closest('.endpoint').classList.toggle('open');
}
function switchTab(tab, pane) {
const body = tab.closest('.ep-body');
body.querySelectorAll('.ep-tab').forEach(t => t.classList.remove('active'));
body.querySelectorAll('.tab-pane').forEach(p => p.classList.remove('active'));
tab.classList.add('active');
body.querySelector(`[data-pane="${pane}"]`).classList.add('active');
}
function copyCode(btn) {
const pre = btn.closest('.code-block').querySelector('pre');
navigator.clipboard.writeText(pre.innerText).then(() => {
btn.textContent = 'Copied!'; btn.classList.add('copied');
setTimeout(() => { btn.textContent = 'Copy'; btn.classList.remove('copied'); }, 1600);
});
}
function escHtml(s) {
return String(s).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
}
function setLoading(btn, loading) {
if (loading) {
btn.disabled = true;
btn.dataset.orig = btn.innerHTML;
btn.innerHTML = '<span class="spin">⟳</span> Running…';
} else {
btn.disabled = false;
btn.innerHTML = btn.dataset.orig || 'β–Ά Run';
}
}
function showResult(containerId, status, body, opts = {}) {
const box = document.getElementById(containerId);
box.style.display = 'block';
const ok = status >= 200 && status < 300;
const pillClass = ok ? 'status-ok' : status >= 500 ? 'status-err' : 'status-warn';
if (opts.isChat && ok && body.msg) {
box.innerHTML = `
<div class="result-header">
<span class="status-pill ${pillClass}">${status}</span>
<span>Reply</span>
</div>
<div class="result-msg-bubble">${escHtml(body.msg)}</div>
${body.cid ? `<div class="result-meta">
<div class="meta-chip"><span class="k">cid&nbsp;</span><span class="v">${escHtml(body.cid)}</span></div>
<div class="meta-chip"><span class="k">rid&nbsp;</span><span class="v">${escHtml(body.rid)}</span></div>
<div class="meta-chip"><span class="k">rcid</span><span class="v">${escHtml(body.rcid)}</span></div>
</div>` : ''}
`;
} else if (opts.isText) {
box.innerHTML = `
<div class="result-header">
<span class="status-pill ${pillClass}">${status}</span>
<span>${ok ? 'Success' : 'Error'}</span>
</div>
<div class="result-msg-bubble">${escHtml(typeof body === 'string' ? body : JSON.stringify(body))}</div>
`;
} else {
box.innerHTML = `
<div class="result-header">
<span class="status-pill ${pillClass}">${status}</span>
<span>${ok ? 'Success' : 'Error'}</span>
</div>
<div class="result-pre">${escHtml(JSON.stringify(body, null, 2))}</div>
`;
}
}
async function checkAllStatus() {
try {
const r = await fetch(`${BASE}/api/gemini/health`);
const d = await r.json();
const data = d.data || d;
document.getElementById('gemini-status').textContent = data.status || 'β€”';
document.getElementById('gemini-status').className = 'stat-value ok';
document.getElementById('gemini-cookies').textContent = data.cookies_valid ? 'Valid' : 'Expired';
document.getElementById('gemini-cookies').className = 'stat-value ' + (data.cookies_valid ? 'ok' : 'nok');
document.getElementById('gemini-client').textContent = data.client_ready ? 'Ready' : 'Off';
document.getElementById('gemini-client').className = 'stat-value ' + (data.client_ready ? 'ok' : 'nok');
} catch(e) {}
try {
const r = await fetch(`${BASE}/api/gemini/cookies`);
const d = await r.json();
const ck = d.data || d;
const el = document.getElementById('gemini-cookies');
if (ck.valid) { el.textContent = 'Valid'; el.className = 'stat-value ok'; }
else { el.textContent = 'Expired'; el.className = 'stat-value nok'; }
} catch(e) {}
try {
const r = await fetch(`${BASE}/api/deepseek/health`);
const d = await r.json();
const data = d.data || d;
document.getElementById('deepseek-status').textContent = data.configured ? 'Ready' : 'Not configured';
document.getElementById('deepseek-status').className = 'stat-value ' + (data.configured ? 'ok' : 'nok');
} catch(e) {}
try {
const r = await fetch(`${BASE}/api/qwen/health`);
const d = await r.json();
const data = d.data || d;
document.getElementById('qwen-status').textContent = data.configured ? 'Ready' : 'Not configured';
document.getElementById('qwen-status').className = 'stat-value ' + (data.configured ? 'ok' : 'nok');
} catch(e) {}
try {
const r = await fetch(`${BASE}/api/claude/health`);
const d = await r.json();
const data = d.data || d;
document.getElementById('claude-status').textContent = data.configured ? 'Ready' : 'Not configured';
document.getElementById('claude-status').className = 'stat-value ' + (data.configured ? 'ok' : 'nok');
} catch(e) {}
try {
const r = await fetch(`${BASE}/api/gpt/health`);
const d = await r.json();
const data = d.data || d;
document.getElementById('gpt-status').textContent = data.configured ? 'Ready' : 'Not configured';
document.getElementById('gpt-status').className = 'stat-value ' + (data.configured ? 'ok' : 'nok');
} catch(e) {}
try {
const r = await fetch(`${BASE}/api/grok/health`);
const d = await r.json();
const data = d.data || d;
document.getElementById('grok-status').textContent = data.configured ? 'Ready' : 'Not configured';
document.getElementById('grok-status').className = 'stat-value ' + (data.configured ? 'ok' : 'nok');
} catch(e) {}
}
// ── GEMINI ──
async function runGeminiHealth(btn) { setLoading(btn, true); try { const r = await fetch(`${BASE}/api/gemini/health`); showResult('gemini-health-result', r.status, await r.json()); } catch(e) { showResult('gemini-health-result', 0, {error: e.message}); } setLoading(btn, false); }
async function runGeminiGetCookies(btn) { setLoading(btn, true); try { const r = await fetch(`${BASE}/api/gemini/cookies`); showResult('gemini-getcookies-result', r.status, await r.json()); } catch(e) { showResult('gemini-getcookies-result', 0, {error: e.message}); } setLoading(btn, false); }
async function runGeminiSetCookies(btn) {
const raw = document.getElementById('gemini-cookies-input').value.trim();
if (!raw) { alert('Paste cookie string first.'); return; }
setLoading(btn, true);
try {
const r = await fetch(`${BASE}/api/gemini/cookies`, { method:'POST', headers:{'Content-Type':'text/plain'}, body: raw });
showResult('gemini-setcookies-result', r.status, await r.json());
} catch(e) { showResult('gemini-setcookies-result', 0, {error: e.message}); }
setLoading(btn, false);
}
async function runGeminiDeleteCookies(btn) {
if (!confirm('Clear all cookies? Client will disconnect.')) return;
setLoading(btn, true);
try { const r = await fetch(`${BASE}/api/gemini/cookies`, {method:'DELETE'}); showResult('gemini-deletecookies-result', r.status, await r.json()); } catch(e) { showResult('gemini-deletecookies-result', 0, {error: e.message}); }
setLoading(btn, false);
}
async function runGeminiChat(btn) {
const ask = document.getElementById('gemini-chat-ask').value.trim();
const cid = document.getElementById('gemini-chat-cid').value.trim();
const rid = document.getElementById('gemini-chat-rid').value.trim();
const rcid = document.getElementById('gemini-chat-rcid').value.trim();
const model = document.getElementById('gemini-chat-model').value;
if (!ask) { alert('Enter a message.'); return; }
const params = new URLSearchParams();
if (ask) params.set('ask', ask);
if (cid) params.set('cid', cid);
if (rid) params.set('rid', rid);
if (rcid) params.set('rcid', rcid);
if (model) params.set('model', model);
if (document.getElementById('gemini-chat-delete')?.checked) params.set('delete', 'true');
const tokens = document.getElementById('gemini-chat-tokens')?.checked;
setLoading(btn, true);
const box = document.getElementById('gemini-chat-result');
if (tokens) {
box.style.display = 'block';
box.innerHTML = '<div class="result-header"><span class="status-pill status-ok">200</span><span>Streaming</span></div><div class="result-msg-bubble"></div>';
const bubble = box.querySelector('.result-msg-bubble');
try {
const r = await fetch(`${BASE}/api/gemini/chat?${params}&tokens=true`);
const reader = r.body.getReader();
const decoder = new TextDecoder();
let fullText = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
const text = decoder.decode(value, { stream: true });
for (const line of text.split('\n').filter(l => l.startsWith('data: '))) {
try {
const json = JSON.parse(line.slice(6));
if (json.token) { fullText += json.token; bubble.textContent = fullText; }
if (json.error) { bubble.textContent = 'Error: ' + json.error; box.querySelector('.result-header span:last-child').textContent = 'Error'; }
} catch(e) {}
}
}
} catch(e) { bubble.textContent = 'Error: ' + e.message; }
setLoading(btn, false);
return;
}
try {
const r = await fetch(`${BASE}/api/gemini/chat?${params}`);
showResult('gemini-chat-result', r.status, await r.json(), {isChat: true});
} catch(e) { showResult('gemini-chat-result', 0, {error: e.message}); }
setLoading(btn, false);
}
async function runGeminiTempChat(btn) {
const ask = document.getElementById('gemini-tempchat-ask').value.trim() || 'Hello';
setLoading(btn, true);
try {
const r = await fetch(`${BASE}/api/gemini/temp/chat?ask=${encodeURIComponent(ask)}`);
showResult('gemini-tempchat-result', r.status, await r.json(), {isText: true});
} catch(e) { showResult('gemini-tempchat-result', 0, {error: e.message}); }
setLoading(btn, false);
}
async function runGeminiConversations(btn) {
setLoading(btn, true);
try {
const r = await fetch(`${BASE}/api/gemini/conversations`);
const data = await r.json();
const convs = data.data?.conversations || data.conversations || [];
const box = document.getElementById('gemini-conversations-result');
box.style.display = 'block';
if (!r.ok) {
box.innerHTML = `<div class="result-header"><span class="status-pill status-err">${r.status}</span><span>Error</span></div><div class="result-pre">${escHtml(JSON.stringify(data, null, 2))}</div>`;
} else if (!convs.length) {
box.innerHTML = `<div class="result-header"><span class="status-pill status-ok">${r.status}</span><span>No conversations</span></div><div class="result-msg-bubble" style="color:var(--muted)">No conversations found.</div>`;
} else {
let html = `<div class="result-header"><span class="status-pill status-ok">${r.status}</span><span>${convs.length} conversations</span></div><div style="display:flex;flex-direction:column;gap:4px;margin-top:8px">`;
for (const c of convs) {
const title = c.title || c.id || '(untitled)';
html += `<div style="display:flex;align-items:center;gap:6px;background:var(--surface2);border:1px solid var(--border);border-radius:6px;padding:6px 10px">
<span style="flex:1;font-size:12px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap">${escHtml(title)}</span>
<code style="font-size:10px;color:var(--muted);font-family:monospace">${escHtml(c.id)}</code>
<button onclick="runGeminiDeleteSingle(this,'${escHtml(c.id)}')" style="background:var(--red-bg);color:var(--red);border:1px solid rgba(248,113,113,.2);border-radius:4px;padding:2px 8px;font-size:10px;cursor:pointer;font-family:inherit;white-space:nowrap">Delete</button>
</div>`;
}
html += '</div>';
box.innerHTML = html;
}
} catch(e) { showResult('gemini-conversations-result', 0, {error: e.message}); }
setLoading(btn, false);
}
async function runGeminiDeleteSingle(btn, id) {
if (!confirm(`Delete conversation "${id}"?`)) return;
btn.disabled = true; btn.textContent = '…';
try {
const r = await fetch(`${BASE}/api/gemini/conversations/${encodeURIComponent(id)}`, {method:'DELETE'});
const data = await r.json();
btn.textContent = r.ok ? 'Deleted' : 'Error';
btn.style.color = r.ok ? 'var(--green)' : 'var(--orange)';
} catch(e) { btn.textContent = 'Error'; btn.style.color = 'var(--red)'; }
}
async function runGeminiDeleteAllConvos(btn) {
if (!confirm('Delete ALL Gemini conversations?')) return;
setLoading(btn, true); try { const r = await fetch(`${BASE}/api/gemini/conversations`, {method:'DELETE'}); showResult('gemini-deleteall-convos-result', r.status, await r.json()); } catch(e) { showResult('gemini-deleteall-convos-result', 0, {error: e.message}); } setLoading(btn, false);
}
async function runGeminiDeleteConvo(btn) {
const id = document.getElementById('gemini-delete-convo-id').value.trim();
if (!id) { alert('Enter a conversation ID.'); return; }
setLoading(btn, true); try { const r = await fetch(`${BASE}/api/gemini/conversations/${encodeURIComponent(id)}`, {method:'DELETE'}); showResult('gemini-delete-convo-result', r.status, await r.json()); } catch(e) { showResult('gemini-delete-convo-result', 0, {error: e.message}); } setLoading(btn, false);
}
// ── DEEPSEEK ──
async function runDeepSeekHealth(btn) { setLoading(btn, true); try { const r = await fetch(`${BASE}/api/deepseek/health`); showResult('deepseek-health-result', r.status, await r.json()); } catch(e) { showResult('deepseek-health-result', 0, {error: e.message}); } setLoading(btn, false); }
async function runDeepSeekChat(btn) {
const prompt = document.getElementById('deepseek-prompt').value.trim() || 'Hello';
const del = document.getElementById('deepseek-chat-delete')?.checked ? 'true' : '';
const tokens = document.getElementById('deepseek-chat-tokens')?.checked;
setLoading(btn, true);
const box = document.getElementById('deepseek-chat-result');
if (tokens) {
box.style.display = 'block';
box.innerHTML = '<div class="result-header"><span class="status-pill status-ok">200</span><span>Streaming</span></div><div class="result-msg-bubble"></div>';
const bubble = box.querySelector('.result-msg-bubble');
try {
const r = await fetch(`${BASE}/api/deepseek/chat?prompt=${encodeURIComponent(prompt)}&tokens=true${del ? '&delete=true' : ''}`);
const reader = r.body.getReader();
const decoder = new TextDecoder();
let fullText = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
const text = decoder.decode(value, { stream: true });
for (const line of text.split('\n').filter(l => l.startsWith('data: '))) {
try {
const json = JSON.parse(line.slice(6));
if (json.token) { fullText += json.token; bubble.textContent = fullText; }
if (json.error) { bubble.textContent = 'Error: ' + json.error; box.querySelector('.result-header span:last-child').textContent = 'Error'; }
} catch(e) {}
}
}
} catch(e) { bubble.textContent = 'Error: ' + e.message; }
setLoading(btn, false);
return;
}
try {
const r = await fetch(`${BASE}/api/deepseek/chat?prompt=${encodeURIComponent(prompt)}${del ? '&delete=true' : ''}`);
const data = await r.json();
const text = data.data?.response || data.response || data;
showResult('deepseek-chat-result', r.status, text, {isText: true});
} catch(e) { showResult('deepseek-chat-result', 0, {error: e.message}); }
setLoading(btn, false);
}
async function runDeepSeekChatPost(btn) {
const prompt = document.getElementById('deepseek-chat-post-prompt').value.trim() || 'Hello';
const tokens = document.getElementById('deepseek-chat-post-tokens')?.checked;
setLoading(btn, true);
const box = document.getElementById('deepseek-chat-post-result');
if (tokens) {
box.style.display = 'block';
box.innerHTML = '<div class="result-header"><span class="status-pill status-ok">200</span><span>Streaming</span></div><div class="result-msg-bubble"></div>';
const bubble = box.querySelector('.result-msg-bubble');
try {
const r = await fetch(`${BASE}/api/deepseek/chat`, { method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify({prompt, tokens:true}) });
const reader = r.body.getReader();
const decoder = new TextDecoder();
let fullText = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
const text = decoder.decode(value, { stream: true });
for (const line of text.split('\n').filter(l => l.startsWith('data: '))) {
try {
const json = JSON.parse(line.slice(6));
if (json.token) { fullText += json.token; bubble.textContent = fullText; }
if (json.error) { bubble.textContent = 'Error: ' + json.error; box.querySelector('.result-header span:last-child').textContent = 'Error'; }
} catch(e) {}
}
}
} catch(e) { bubble.textContent = 'Error: ' + e.message; }
setLoading(btn, false);
return;
}
try {
const r = await fetch(`${BASE}/api/deepseek/chat`, { method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify({prompt}) });
const data = await r.json();
const text = data.data?.response || data;
showResult('deepseek-chat-post-result', r.status, text, {isText: true});
} catch(e) { showResult('deepseek-chat-post-result', 0, {error: e.message}); }
setLoading(btn, false);
}
async function runDeepSeekSessions(btn) { setLoading(btn, true); try { const r = await fetch(`${BASE}/api/deepseek/sessions`); showResult('deepseek-sessions-result', r.status, await r.json()); } catch(e) { showResult('deepseek-sessions-result', 0, {error: e.message}); } setLoading(btn, false); }
async function runDeepSeekCreateSession(btn) { setLoading(btn, true); try { const r = await fetch(`${BASE}/api/deepseek/sessions`, {method:'POST'}); showResult('deepseek-create-session-result', r.status, await r.json()); } catch(e) { showResult('deepseek-create-session-result', 0, {error: e.message}); } setLoading(btn, false); }
async function runDeepSeekDeleteAllSessions(btn) {
if (!confirm('Delete ALL DeepSeek sessions?')) return;
setLoading(btn, true); try { const r = await fetch(`${BASE}/api/deepseek/sessions`, {method:'DELETE'}); showResult('deepseek-deleteall-sessions-result', r.status, await r.json()); } catch(e) { showResult('deepseek-deleteall-sessions-result', 0, {error: e.message}); } setLoading(btn, false);
}
async function runDeepSeekDeleteSession(btn) {
const id = document.getElementById('deepseek-delete-session-id').value.trim();
if (!id) { alert('Enter a session ID.'); return; }
if (!confirm('Delete this session?')) return;
setLoading(btn, true); try { const r = await fetch(`${BASE}/api/deepseek/sessions/${encodeURIComponent(id)}`, {method:'DELETE'}); showResult('deepseek-delete-session-result', r.status, await r.json()); } catch(e) { showResult('deepseek-delete-session-result', 0, {error: e.message}); } setLoading(btn, false);
}
async function runDeepSeekMessages(btn) {
const id = document.getElementById('deepseek-messages-session-id').value.trim();
if (!id) { alert('Enter a session ID.'); return; }
setLoading(btn, true); try { const r = await fetch(`${BASE}/api/deepseek/sessions/${encodeURIComponent(id)}/messages`); showResult('deepseek-messages-result', r.status, await r.json()); } catch(e) { showResult('deepseek-messages-result', 0, {error: e.message}); } setLoading(btn, false);
}
async function runDeepSeekSessionChat(btn) {
const sid = document.getElementById('deepseek-sessionchat-sid').value.trim();
const msg = document.getElementById('deepseek-sessionchat-msg').value.trim() || 'Hello';
if (!sid) { alert('Enter a session ID.'); return; }
setLoading(btn, true); try { const r = await fetch(`${BASE}/api/deepseek/sessions/${encodeURIComponent(sid)}/chat`, { method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify({prompt:msg}) }); const data = await r.json(); showResult('deepseek-sessionchat-result', r.status, data, {isText: true}); } catch(e) { showResult('deepseek-sessionchat-result', 0, {error: e.message}); } setLoading(btn, false);
}
async function runDeepSeekRegenerate(btn) {
const sid = document.getElementById('deepseek-reg-session').value.trim();
const mid = document.getElementById('deepseek-reg-msgid').value.trim();
if (!sid || !mid) { alert('Enter session ID and message ID.'); return; }
setLoading(btn, true); try { const r = await fetch(`${BASE}/api/deepseek/sessions/${encodeURIComponent(sid)}/regenerate/${encodeURIComponent(mid)}`, {method:'POST'}); showResult('deepseek-regenerate-result', r.status, await r.json()); } catch(e) { showResult('deepseek-regenerate-result', 0, {error: e.message}); } setLoading(btn, false);
}
async function runDeepSeekEdit(btn) {
const sid = document.getElementById('deepseek-edit-session').value.trim();
const mid = document.getElementById('deepseek-edit-msgid').value.trim();
const prompt = document.getElementById('deepseek-edit-prompt').value.trim() || 'edited';
if (!sid || !mid) { alert('Enter session ID and message ID.'); return; }
setLoading(btn, true); try { const r = await fetch(`${BASE}/api/deepseek/sessions/${encodeURIComponent(sid)}/edit/${encodeURIComponent(mid)}`, {method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify({prompt}) }); showResult('deepseek-edit-result', r.status, await r.json()); } catch(e) { showResult('deepseek-edit-result', 0, {error: e.message}); } setLoading(btn, false);
}
async function runDeepSeekContinue(btn) {
const sid = document.getElementById('deepseek-cont-session').value.trim();
const mid = document.getElementById('deepseek-cont-msgid').value.trim();
if (!sid || !mid) { alert('Enter session ID and message ID.'); return; }
setLoading(btn, true); try { const r = await fetch(`${BASE}/api/deepseek/sessions/${encodeURIComponent(sid)}/continue/${encodeURIComponent(mid)}`, {method:'POST'}); showResult('deepseek-continue-result', r.status, await r.json()); } catch(e) { showResult('deepseek-continue-result', 0, {error: e.message}); } setLoading(btn, false);
}
async function runDeepSeekStop(btn) {
const sid = document.getElementById('deepseek-stop-session').value.trim();
const mid = document.getElementById('deepseek-stop-msgid').value.trim();
if (!sid || !mid) { alert('Enter session ID and message ID.'); return; }
setLoading(btn, true); try { const r = await fetch(`${BASE}/api/deepseek/sessions/${encodeURIComponent(sid)}/stop/${encodeURIComponent(mid)}`, {method:'POST'}); showResult('deepseek-stop-result', r.status, await r.json()); } catch(e) { showResult('deepseek-stop-result', 0, {error: e.message}); } setLoading(btn, false);
}
async function runDeepSeekTitle(btn) {
const sid = document.getElementById('deepseek-title-sid').value.trim();
const title = document.getElementById('deepseek-title').value.trim() || 'My Chat';
if (!sid) { alert('Enter a session ID.'); return; }
setLoading(btn, true); try { const r = await fetch(`${BASE}/api/deepseek/sessions/${encodeURIComponent(sid)}/title`, {method:'PUT', headers:{'Content-Type':'application/json'}, body:JSON.stringify({title}) }); showResult('deepseek-title-result', r.status, await r.json()); } catch(e) { showResult('deepseek-title-result', 0, {error: e.message}); } setLoading(btn, false);
}
async function runDeepSeekPin(btn) {
const sid = document.getElementById('deepseek-pin-sid').value.trim();
const pinned = document.getElementById('deepseek-pin-val').value === 'true';
if (!sid) { alert('Enter a session ID.'); return; }
setLoading(btn, true); try { const r = await fetch(`${BASE}/api/deepseek/sessions/${encodeURIComponent(sid)}/pinned`, {method:'PUT', headers:{'Content-Type':'application/json'}, body:JSON.stringify({pinned}) }); showResult('deepseek-pin-result', r.status, await r.json()); } catch(e) { showResult('deepseek-pin-result', 0, {error: e.message}); } setLoading(btn, false);
}
async function runDeepSeekUser(btn) { setLoading(btn, true); try { const r = await fetch(`${BASE}/api/deepseek/user`); showResult('deepseek-user-result', r.status, await r.json()); } catch(e) { showResult('deepseek-user-result', 0, {error: e.message}); } setLoading(btn, false); }
async function runDeepSeekPowChallenge(btn) { setLoading(btn, true); try { const r = await fetch(`${BASE}/api/deepseek/pow-challenge`); showResult('deepseek-pow-challenge-result', r.status, await r.json()); } catch(e) { showResult('deepseek-pow-challenge-result', 0, {error: e.message}); } setLoading(btn, false); }
async function runDeepSeekPowSolve(btn) {
setLoading(btn, true); try { const r = await fetch(`${BASE}/api/deepseek/pow-solve`, {method:'POST', headers:{'Content-Type':'application/json'}, body:'{}' }); showResult('deepseek-pow-solve-result', r.status, await r.json()); } catch(e) { showResult('deepseek-pow-solve-result', 0, {error: e.message}); } setLoading(btn, false);
}
async function runDeepSeekShares(btn) { setLoading(btn, true); try { const r = await fetch(`${BASE}/api/deepseek/shares`); showResult('deepseek-shares-result', r.status, await r.json()); } catch(e) { showResult('deepseek-shares-result', 0, {error: e.message}); } setLoading(btn, false); }
async function runDeepSeekCreateShare(btn) {
const sid = document.getElementById('deepseek-share-create-sid').value.trim();
const mids = document.getElementById('deepseek-share-create-mids').value.trim();
if (!sid || !mids) { alert('Enter session ID and message IDs.'); return; }
setLoading(btn, true); try { const r = await fetch(`${BASE}/api/deepseek/shares`, {method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify({sessionId:sid, messageIds:mids.split(',').map(s=>s.trim())}) }); showResult('deepseek-create-share-result', r.status, await r.json()); } catch(e) { showResult('deepseek-create-share-result', 0, {error: e.message}); } setLoading(btn, false);
}
async function runDeepSeekForkShare(btn) {
const shareId = document.getElementById('deepseek-fork-share-id').value.trim();
if (!shareId) { alert('Enter a share ID.'); return; }
setLoading(btn, true); try { const r = await fetch(`${BASE}/api/deepseek/shares/fork`, {method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify({shareId}) }); showResult('deepseek-fork-share-result', r.status, await r.json()); } catch(e) { showResult('deepseek-fork-share-result', 0, {error: e.message}); } setLoading(btn, false);
}
async function runDeepSeekDeleteShare(btn) {
const id = document.getElementById('deepseek-delete-share-id').value.trim();
if (!id) { alert('Enter a share ID.'); return; }
if (!confirm('Delete this share?')) return;
setLoading(btn, true); try { const r = await fetch(`${BASE}/api/deepseek/shares/${encodeURIComponent(id)}`, {method:'DELETE'}); showResult('deepseek-delete-share-result', r.status, await r.json()); } catch(e) { showResult('deepseek-delete-share-result', 0, {error: e.message}); } setLoading(btn, false);
}
// ── QWEN ──
async function runQwenHealth(btn) { setLoading(btn, true); try { const r = await fetch(`${BASE}/api/qwen/health`); showResult('qwen-health-result', r.status, await r.json()); } catch(e) { showResult('qwen-health-result', 0, {error: e.message}); } setLoading(btn, false); }
async function runQwenInfo(btn) { setLoading(btn, true); try { const r = await fetch(`${BASE}/api/qwen`); showResult('qwen-info-result', r.status, await r.json()); } catch(e) { showResult('qwen-info-result', 0, {error: e.message}); } setLoading(btn, false); }
async function runQwenAsk(btn) {
const prompt = document.getElementById('qwen-prompt').value.trim() || 'Hello';
const mode = document.getElementById('qwen-mode').value;
const del = document.getElementById('qwen-ask-delete')?.checked ? 'true' : '';
const tokens = document.getElementById('qwen-ask-tokens')?.checked;
setLoading(btn, true);
const box = document.getElementById('qwen-ask-result');
if (tokens) {
box.style.display = 'block';
box.innerHTML = '<div class="result-header"><span class="status-pill status-ok">200</span><span>Streaming</span></div><div class="result-msg-bubble"></div>';
const bubble = box.querySelector('.result-msg-bubble');
try {
const r = await fetch(`${BASE}/api/qwen/ask?prompt=${encodeURIComponent(prompt)}&mode=${mode}&tokens=true${del ? '&delete=true' : ''}`);
const reader = r.body.getReader();
const decoder = new TextDecoder();
let fullText = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
const text = decoder.decode(value, { stream: true });
for (const line of text.split('\n').filter(l => l.startsWith('data: '))) {
try {
const json = JSON.parse(line.slice(6));
if (json.token) { fullText += json.token; bubble.textContent = fullText; }
if (json.error) { bubble.textContent = 'Error: ' + json.error; box.querySelector('.result-header span:last-child').textContent = 'Error'; }
} catch(e) {}
}
}
} catch(e) { bubble.textContent = 'Error: ' + e.message; }
setLoading(btn, false);
return;
}
try {
const r = await fetch(`${BASE}/api/qwen/ask?prompt=${encodeURIComponent(prompt)}&mode=${mode}${del ? '&delete=true' : ''}`);
const data = await r.json();
showResult('qwen-ask-result', r.status, data, {isText: true});
} catch(e) { showResult('qwen-ask-result', 0, {error: e.message}); }
setLoading(btn, false);
}
async function runQwenAskPost(btn) {
const prompt = document.getElementById('qwen-ask-post-prompt').value.trim() || 'Hello';
const mode = document.getElementById('qwen-ask-post-mode').value;
const tokens = document.getElementById('qwen-ask-post-tokens')?.checked;
setLoading(btn, true);
const box = document.getElementById('qwen-ask-post-result');
if (tokens) {
box.style.display = 'block';
box.innerHTML = '<div class="result-header"><span class="status-pill status-ok">200</span><span>Streaming</span></div><div class="result-msg-bubble"></div>';
const bubble = box.querySelector('.result-msg-bubble');
try {
const r = await fetch(`${BASE}/api/qwen/ask`, { method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify({prompt, mode, tokens:true}) });
const reader = r.body.getReader();
const decoder = new TextDecoder();
let fullText = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
const text = decoder.decode(value, { stream: true });
for (const line of text.split('\n').filter(l => l.startsWith('data: '))) {
try {
const json = JSON.parse(line.slice(6));
if (json.token) { fullText += json.token; bubble.textContent = fullText; }
if (json.error) { bubble.textContent = 'Error: ' + json.error; box.querySelector('.result-header span:last-child').textContent = 'Error'; }
} catch(e) {}
}
}
} catch(e) { bubble.textContent = 'Error: ' + e.message; }
setLoading(btn, false);
return;
}
try {
const r = await fetch(`${BASE}/api/qwen/ask`, { method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify({prompt, mode}) });
const data = await r.json();
showResult('qwen-ask-post-result', r.status, data, {isText: true});
} catch(e) { showResult('qwen-ask-post-result', 0, {error: e.message}); }
setLoading(btn, false);
}
async function runQwenFeature(feature, btn) {
const prompt = document.getElementById(`qwen-feature-${feature}-prompt`).value.trim() || 'hello';
setLoading(btn, true);
try {
const r = await fetch(`${BASE}/api/qwen/ask?prompt=${encodeURIComponent(prompt)}&chat_type=${feature}`);
const data = await r.json();
showResult(`qwen-feature-${feature}-result`, r.status, data, {isText: true});
} catch(e) { showResult(`qwen-feature-${feature}-result`, 0, {error: e.message}); }
setLoading(btn, false);
}
async function runQwenUpload(btn) {
setLoading(btn, true);
try {
const content = btoa('hello world');
const r = await fetch(`${BASE}/api/qwen/upload`, { method:'POST', headers:{'Content-Type':'application/json'}, body:JSON.stringify({content, filename:'test.txt'}) });
showResult('qwen-upload-result', r.status, await r.json());
} catch(e) { showResult('qwen-upload-result', 0, {error: e.message}); }
setLoading(btn, false);
}
async function runQwenConversations(btn) { setLoading(btn, true); try { const r = await fetch(`${BASE}/api/qwen/conversations`); showResult('qwen-conversations-result', r.status, await r.json()); } catch(e) { showResult('qwen-conversations-result', 0, {error: e.message}); } setLoading(btn, false); }
async function runQwenDeleteAllConvos(btn) {
if (!confirm('Delete ALL Qwen conversations?')) return;
setLoading(btn, true); try { const r = await fetch(`${BASE}/api/qwen/conversations`, {method:'DELETE'}); showResult('qwen-deleteall-convos-result', r.status, await r.json()); } catch(e) { showResult('qwen-deleteall-convos-result', 0, {error: e.message}); } setLoading(btn, false);
}
async function runQwenDeleteConvo(btn) {
const id = document.getElementById('qwen-delete-convo-id').value.trim();
if (!id) { alert('Enter a conversation ID.'); return; }
setLoading(btn, true); try { const r = await fetch(`${BASE}/api/qwen/conversations/${encodeURIComponent(id)}`, {method:'DELETE'}); showResult('qwen-delete-convo-result', r.status, await r.json()); } catch(e) { showResult('qwen-delete-convo-result', 0, {error: e.message}); } setLoading(btn, false);
}
// ── KIMI ──
async function runKimiHealth(btn) { setLoading(btn, true); try { const r = await fetch(`${BASE}/api/kimi/health`); showResult('kimi-health-result', r.status, await r.json()); } catch(e) { showResult('kimi-health-result', 0, {error: e.message}); } setLoading(btn, false); }
async function runKimiUser(btn) { setLoading(btn, true); try { const r = await fetch(`${BASE}/api/kimi/user`); showResult('kimi-user-result', r.status, await r.json()); } catch(e) { showResult('kimi-user-result', 0, {error: e.message}); } setLoading(btn, false); }
async function runKimiModels(btn) { setLoading(btn, true); try { const r = await fetch(`${BASE}/api/kimi/models`); showResult('kimi-models-result', r.status, await r.json()); } catch(e) { showResult('kimi-models-result', 0, {error: e.message}); } setLoading(btn, false); }
async function runKimiSessions(btn) { setLoading(btn, true); try { const r = await fetch(`${BASE}/api/kimi/sessions`); showResult('kimi-sessions-result', r.status, await r.json()); } catch(e) { showResult('kimi-sessions-result', 0, {error: e.message}); } setLoading(btn, false); }
async function runKimiChat(btn) {
const prompt = document.getElementById('kimi-prompt').value.trim() || 'Hello';
const del = document.getElementById('kimi-chat-delete')?.checked ? 'true' : '';
setLoading(btn, true);
try {
const r = await fetch(`${BASE}/api/kimi/chat?prompt=${encodeURIComponent(prompt)}${del ? '&delete=true' : ''}`);
const data = await r.json();
const text = data.data?.response || data.response || data;
showResult('kimi-chat-result', r.status, text, {isText: true});
} catch(e) { showResult('kimi-chat-result', 0, {error: e.message}); }
setLoading(btn, false);
}
// ── CLAUDE ──
async function runClaudeHealth(btn) { setLoading(btn, true); try { const r = await fetch(`${BASE}/api/claude/health`); showResult('claude-health-result', r.status, await r.json()); } catch(e) { showResult('claude-health-result', 0, {error: e.message}); } setLoading(btn, false); }
async function runClaudeModels(btn) { setLoading(btn, true); try { const r = await fetch(`${BASE}/api/claude/models`); showResult('claude-models-result', r.status, await r.json()); } catch(e) { showResult('claude-models-result', 0, {error: e.message}); } setLoading(btn, false); }
async function runClaudeChat(btn) {
const prompt = document.getElementById('claude-prompt').value.trim() || 'Hello';
setLoading(btn, true);
try {
const r = await fetch(`${BASE}/api/claude/chat?ask=${encodeURIComponent(prompt)}`);
const data = await r.json();
const text = data.response || data.data?.response || data;
showResult('claude-chat-result', r.status, text, {isText: true});
} catch(e) { showResult('claude-chat-result', 0, {error: e.message}); }
setLoading(btn, false);
}
// ── GPT ──
async function runGptHealth(btn) { setLoading(btn, true); try { const r = await fetch(`${BASE}/api/gpt/health`); showResult('gpt-health-result', r.status, await r.json()); } catch(e) { showResult('gpt-health-result', 0, {error: e.message}); } setLoading(btn, false); }
async function runGptModels(btn) { setLoading(btn, true); try { const r = await fetch(`${BASE}/api/gpt/models`); showResult('gpt-models-result', r.status, await r.json()); } catch(e) { showResult('gpt-models-result', 0, {error: e.message}); } setLoading(btn, false); }
async function runGptChat(btn) {
const prompt = document.getElementById('gpt-prompt').value.trim() || 'Hello';
setLoading(btn, true);
try {
const r = await fetch(`${BASE}/api/gpt/chat?ask=${encodeURIComponent(prompt)}`);
const data = await r.json();
const text = data.response || data.data?.response || data;
showResult('gpt-chat-result', r.status, text, {isText: true});
} catch(e) { showResult('gpt-chat-result', 0, {error: e.message}); }
setLoading(btn, false);
}
// ── GROK ──
async function runGrokHealth(btn) { setLoading(btn, true); try { const r = await fetch(`${BASE}/api/grok/health`); showResult('grok-health-result', r.status, await r.json()); } catch(e) { showResult('grok-health-result', 0, {error: e.message}); } setLoading(btn, false); }
async function runGrokModels(btn) { setLoading(btn, true); try { const r = await fetch(`${BASE}/api/grok/models`); showResult('grok-models-result', r.status, await r.json()); } catch(e) { showResult('grok-models-result', 0, {error: e.message}); } setLoading(btn, false); }
async function runGrokChat(btn) {
const prompt = document.getElementById('grok-prompt').value.trim() || 'Hello';
setLoading(btn, true);
try {
const r = await fetch(`${BASE}/api/grok/chat?ask=${encodeURIComponent(prompt)}`);
const data = await r.json();
const text = data.response || data.data?.response || data;
showResult('grok-chat-result', r.status, text, {isText: true});
} catch(e) { showResult('grok-chat-result', 0, {error: e.message}); }
setLoading(btn, false);
}
// ── META AI ──
async function runMetaHealth(btn) { setLoading(btn, true); try { const r = await fetch(`${BASE}/api/meta/health`); showResult('meta-health-result', r.status, await r.json()); } catch(e) { showResult('meta-health-result', 0, {error: e.message}); } setLoading(btn, false); }
async function runMetaModels(btn) { setLoading(btn, true); try { const r = await fetch(`${BASE}/api/meta/models`); showResult('meta-models-result', r.status, await r.json()); } catch(e) { showResult('meta-models-result', 0, {error: e.message}); } setLoading(btn, false); }
async function runMetaChat(btn) {
const prompt = document.getElementById('meta-prompt').value.trim() || 'Hello';
const del = document.getElementById('meta-chat-delete')?.checked ? 'true' : '';
setLoading(btn, true);
try {
const r = await fetch(`${BASE}/api/meta/chat?ask=${encodeURIComponent(prompt)}${del ? '&delete=true' : ''}`);
const data = await r.json();
const text = data.data?.response || data.response || data;
showResult('meta-chat-result', r.status, text, {isText: true});
} catch(e) { showResult('meta-chat-result', 0, {error: e.message}); }
setLoading(btn, false);
}
async function runMetaImage(btn) {
const prompt = document.getElementById('meta-image-prompt').value.trim() || 'a cat';
const orientation = document.getElementById('meta-image-orientation').value;
setLoading(btn, true); try { const r = await fetch(`${BASE}/api/meta/image?prompt=${encodeURIComponent(prompt)}&orientation=${orientation}`); showResult('meta-image-result', r.status, await r.json()); } catch(e) { showResult('meta-image-result', 0, {error: e.message}); } setLoading(btn, false);
}
async function runMetaVideo(btn) {
const prompt = document.getElementById('meta-video-prompt').value.trim() || 'a cat playing';
setLoading(btn, true); try { const r = await fetch(`${BASE}/api/meta/video?prompt=${encodeURIComponent(prompt)}`); showResult('meta-video-result', r.status, await r.json()); } catch(e) { showResult('meta-video-result', 0, {error: e.message}); } setLoading(btn, false);
}
// ── V1 API ──
async function runV1Chat(btn) {
const model = document.getElementById('v1-model').value;
const prompt = document.getElementById('v1-prompt').value.trim() || 'Hello';
setLoading(btn, true);
try {
const r = await fetch(`${BASE}/v1/chat/completions`, {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({model, messages: [{role: 'user', content: prompt}]}),
});
const data = await r.json();
const text = data.choices?.[0]?.message?.content || data;
showResult('v1-chat-result', r.status, text, {isText: true});
} catch(e) { showResult('v1-chat-result', 0, {error: e.message}); }
setLoading(btn, false);
}
async function runV1Models(btn) { setLoading(btn, true); try { const r = await fetch(`${BASE}/v1/models`); showResult('v1-models-result', r.status, await r.json()); } catch(e) { showResult('v1-models-result', 0, {error: e.message}); } setLoading(btn, false); }
document.addEventListener('keydown', e => {
if (e.key === 'Enter' && e.target.closest('.try-panel')) {
const btn = e.target.closest('.try-panel').querySelector('.run-btn');
if (btn) btn.click();
}
});
</script>
</body>
</html>