Provider selection as tabs

This commit is contained in:
Thomas Krijnen
2026-04-03 11:22:43 +02:00
parent 7350ccd25e
commit 918cc65a0d
3 changed files with 77 additions and 12 deletions
+10 -4
View File
@@ -112,13 +112,17 @@ const baseUrlLabelEl = $("baseUrlLabel");
const baseUrlEl = $("baseUrl");
const thinkingIndicatorEl = $("thinkingIndicator");
const modelEl = $("model");
const providerEl = $("provider");
const providerEls = document.querySelectorAll('input[name="provider"]');
const ifcFileEl = $("ifcFile");
const newBtn = $("newModel");
const downloadBtn = $("downloadIfc");
function getProviderValue() {
return document.querySelector('input[name="provider"]:checked')?.value || "openai";
}
function onProviderChange() {
const provider = PROVIDERS[providerEl.value];
const provider = PROVIDERS[getProviderValue()];
apiKeyLabelEl.innerHTML = `${provider.apiKeyLabel}<span class="small">stored in browser memory; only sent to provider servers</span>`;
apiKeyEl.placeholder = provider.apiKeyPlaceholder;
baseUrlRowEl.hidden = !provider.baseUrlDefault;
@@ -133,7 +137,9 @@ function onProviderChange() {
modelEl.innerHTML = provider.models.map(m => `<option value="${m.value}">${m.label}</option>`).join("");
}
providerEl.addEventListener("change", onProviderChange);
for (const providerEl of providerEls) {
providerEl.addEventListener("change", onProviderChange);
}
onProviderChange();
function setBusy(isBusy, reason = "") {
@@ -467,7 +473,7 @@ async function runAgentTurn(userText) {
const apiKey = apiKeyEl.value.trim();
if (!apiKey) throw new Error("Missing API key");
const provider = PROVIDERS[providerEl.value];
const provider = PROVIDERS[getProviderValue()];
const { chat } = provider.api;
const baseURL = provider.baseUrlDefault ? baseUrlEl.value.trim() : undefined;
+18 -6
View File
@@ -14,12 +14,24 @@
<section class="side">
<div class="row">
<label>Provider</label>
<select id="provider" style="width: 100%;">
<option value="openai">OpenAI</option>
<option value="anthropic">Anthropic (Claude)</option>
<option value="gemini">Gemini</option>
<option value="openrouter">OpenRouter</option>
</select>
<div class="provider-tabs" role="radiogroup" aria-label="Provider">
<label class="provider-tab">
<input type="radio" name="provider" value="openai" checked />
<span>OpenAI</span>
</label>
<label class="provider-tab">
<input type="radio" name="provider" value="anthropic" />
<span>Claude</span>
</label>
<label class="provider-tab">
<input type="radio" name="provider" value="gemini" />
<span>Gemini</span>
</label>
<label class="provider-tab">
<input type="radio" name="provider" value="openrouter" />
<span>OpenRouter</span>
</label>
</div>
</div>
<div class="row">
+49 -2
View File
@@ -32,7 +32,7 @@ main {
.side {
border-right: 1px solid #ddd;
padding: 100px 12px 12px 12px;
padding: 12px;
overflow: auto;
background: #f9f9f9;
}
@@ -234,7 +234,54 @@ section > .row > label .small {
}
.side .row {
margin-bottom: 32px;
margin-bottom: 20px;
}
.provider-tabs {
display: flex;
flex-wrap: wrap;
gap: 6px;
background: #00000010;
padding: 6px 0 0 6px;
}
.provider-tab {
position: relative;
display: inline-flex;
}
.provider-tab input {
position: absolute;
opacity: 0;
pointer-events: none;
}
.provider-tab span {
display: inline-flex;
align-items: center;
justify-content: center;
min-height: 38px;
padding: 8px;
border: 1px solid #d0d0d0;
border-radius: 2px 2px 0 0;
background: #e8e8e8;
color: #555;
cursor: pointer;
user-select: none;
transition: background 0.15s, border-color 0.15s, color 0.15s;
font-size: 75%;
}
.provider-tab input:checked + span {
background: #f9f9f9;
border-color: #999;
color: #111;
border-bottom: none;
}
.provider-tab input:focus-visible + span {
outline: 2px solid #666;
outline-offset: 2px;
}
.row button {