117 lines
5.8 KiB
HTML
117 lines
5.8 KiB
HTML
<!doctype html>
|
|
<html lang="pt-BR">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<title>API Gemini & Conexão · Carinha</title>
|
|
<link rel="stylesheet" href="/dashboard.css">
|
|
<script src="/dashboard.js" defer></script>
|
|
</head>
|
|
<body>
|
|
<div style="display:flex;justify-content:space-between;align-items:flex-start;flex-wrap:wrap;gap:16px;margin-bottom:12px">
|
|
<div>
|
|
<h1>API Gemini & Conexão IA</h1>
|
|
<p style="margin:4px 0 0">Configure o modelo do Google Gemini que dá inteligência ao diálogo e cria novas expressões.</p>
|
|
</div>
|
|
<div>
|
|
<span class="badge" id="apiBadge">Verificando…</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="split" style="margin-top:16px">
|
|
<!-- Formulário do Gemini -->
|
|
<section class="card">
|
|
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:14px">
|
|
<h2>
|
|
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="var(--ciano)" stroke-width="2"><circle cx="12" cy="12" r="10"/><path d="M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20"/><path d="M2 12h20"/></svg>
|
|
Google Gemini Cloud
|
|
</h2>
|
|
<span class="badge" style="font-size:11px">Seguro · api-privada.json</span>
|
|
</div>
|
|
|
|
<form id="apiForm">
|
|
<!-- Model Presets -->
|
|
<label for="apiModelSelect">Modelos recomendados:</label>
|
|
<select id="apiModelSelect" style="margin-bottom:12px">
|
|
<option value="gemini-2.5-flash">gemini-2.5-flash · Rápido, expressivo & moderno (Recomendado)</option>
|
|
<option value="gemini-1.5-flash">gemini-1.5-flash · Alta velocidade e respostas curtas</option>
|
|
<option value="gemini-2.0-flash">gemini-2.0-flash · Nova arquitetura multimodal</option>
|
|
<option value="gemini-1.5-pro">gemini-1.5-pro · Raciocínio profundo e criatividade</option>
|
|
<option value="custom">Outro (digitar manualmente abaixo)</option>
|
|
</select>
|
|
|
|
<label for="apiModel">Identificador do Modelo</label>
|
|
<input id="apiModel" required maxlength="100" placeholder="gemini-flash-lite-latest">
|
|
|
|
<label for="apiKey">Chave de API Gemini (Google AI Studio)</label>
|
|
<input id="apiKey" type="password" autocomplete="new-password" maxlength="250" placeholder="Insira nova chave ou deixe vazio para manter a atual">
|
|
|
|
<p style="font-size:12.5px;color:var(--fraco);margin-top:-6px">
|
|
🔒 Por segurança, o campo de chave nunca exibe o valor salvo no servidor. Ele é mantido exclusivamente no arquivo privado local do Orange Pi.
|
|
</p>
|
|
|
|
<div class="actions" style="margin-top:20px">
|
|
<button class="primary" id="apiSave" type="submit">💾 Salvar Configuração</button>
|
|
<button type="button" id="apiTest">⚡ Testar Conexão Agora</button>
|
|
</div>
|
|
</form>
|
|
|
|
<p id="apiState" role="status" aria-live="polite" style="margin-top:16px;font-size:13.5px;color:var(--ciano);min-height:24px"></p>
|
|
</section>
|
|
|
|
<!-- Instruções e Informações do Sistema -->
|
|
<section class="card" style="display:flex;flex-direction:column;justify-content:space-between">
|
|
<div>
|
|
<h2>
|
|
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="var(--ciano)" stroke-width="2"><path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z"/></svg>
|
|
Arquitetura Híbrida de IA
|
|
</h2>
|
|
<p>O Carinha combina processamento em nuvem com inteligência embarcada no robô:</p>
|
|
|
|
<div style="display:flex;flex-direction:column;gap:12px;margin:16px 0">
|
|
<div style="background:rgba(12,22,36,0.6);border:1px solid var(--borda);border-radius:var(--raio-md);padding:12px">
|
|
<strong style="color:var(--ciano);display:block;margin-bottom:4px">☁️ Google Gemini (Nuvem)</strong>
|
|
<small style="color:var(--texto-medio);font-size:13px">Gera as respostas de conversação natural, recupera lembranças e desenha novas figurinhas SVG em tempo real.</small>
|
|
</div>
|
|
|
|
<div style="background:rgba(12,22,36,0.6);border:1px solid var(--borda);border-radius:var(--raio-md);padding:12px">
|
|
<strong style="color:#34d399;display:block;margin-bottom:4px">📱 Qwen / Local (Galaxy S10)</strong>
|
|
<small style="color:var(--texto-medio);font-size:13px">Disponível no app do celular para quando estiver offline, garantindo que o Carinha continue reagindo aos sensores.</small>
|
|
</div>
|
|
</div>
|
|
|
|
<p style="font-size:13px">Você pode alternar entre os motores a qualquer momento na tela <a href="/conversa">Conversar</a>.</p>
|
|
</div>
|
|
|
|
<details style="margin-top:16px">
|
|
<summary>Informações do Servidor Local</summary>
|
|
<p id="apiServer" style="font-family:'JetBrains Mono',monospace;font-size:12px;color:var(--ciano);margin-top:8px"></p>
|
|
<p style="font-size:12px;color:var(--fraco)">Orange Pi Zero 3 operando na rede interna.</p>
|
|
</details>
|
|
</section>
|
|
</div>
|
|
|
|
<script src="/api-painel.js" defer></script>
|
|
<script>
|
|
// Sincroniza o select de modelos com o input de modelo
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
const sel = document.getElementById('apiModelSelect');
|
|
const input = document.getElementById('apiModel');
|
|
if (sel && input) {
|
|
sel.onchange = () => {
|
|
if (sel.value !== 'custom') {
|
|
input.value = sel.value;
|
|
}
|
|
};
|
|
input.addEventListener('input', () => {
|
|
let matched = false;
|
|
for (let opt of sel.options) {
|
|
if (opt.value === input.value) { opt.selected = true; matched = true; break; }
|
|
}
|
|
if (!matched) sel.value = 'custom';
|
|
});
|
|
}
|
|
});
|
|
</script>
|
|
</body>
|
|
</html> |