SPB Git

spb/vquant Public MIT

VibeQuant — AI-powered institutional-grade financial intelligence platform.

TypeScript 84.3% Python 11.7% JavaScript 1.6% CSS 1.5% HTML 0.7%
8.4 KB · 211 lines html
Raw Blame History
1<!DOCTYPE html>2<!--3  =============================================================================4   VibeQuant (vquant) — AI-Powered Financial Intelligence Platform5  -----------------------------------------------------------------------------6   File:      desktop/setup.html78   Author:    Simon-Pierre Boucher9   Contact:   contact@spboucher.ai10   Website:   https://www.spboucher.ai11   Demo:      https://www.vquant.ai12   License:   MIT (see LICENSE)1314   Copyright © 2026 Simon-Pierre Boucher. All rights reserved.15  =============================================================================16-->1718<html lang="fr">19<head>20  <meta charset="UTF-8">21  <meta name="viewport" content="width=device-width, initial-scale=1.0">22  <title>VQuant — Configuration</title>23  <link rel="stylesheet" href="setup.css">24</head>25<body>26  <div class="drag-region"></div>2728  <div class="container">29    <div class="header">30      <div class="logo">31        <svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">32          <path d="m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z"/>33          <path d="M5 3v4"/><path d="M19 17v4"/><path d="M3 5h4"/><path d="M17 19h4"/>34        </svg>35      </div>36      <h1>VQuant</h1>37      <p class="subtitle">Financial Intelligence Platform</p>38    </div>3940    <div class="description">41      <p>Configurez vos cles API pour demarrer. Les cles requises sont necessaires pour utiliser VQuant.</p>42    </div>4344    <form id="setup-form">45      <div class="section">46        <h2>47          <span class="badge required">Requises</span>48          Cles API principales49        </h2>5051        <div class="field">52          <label for="anthropic">Anthropic (Claude AI)</label>53          <input type="password" id="anthropic" placeholder="sk-ant-api03-..." autocomplete="off" spellcheck="false" />54          <span class="hint">Obtenez votre cle sur <a href="#" onclick="openLink('https://console.anthropic.com/')">console.anthropic.com</a></span>55        </div>5657        <div class="field">58          <label for="fmp">Financial Modeling Prep</label>59          <input type="password" id="fmp" placeholder="Votre cle FMP..." autocomplete="off" spellcheck="false" />60          <span class="hint">Obtenez votre cle sur <a href="#" onclick="openLink('https://financialmodelingprep.com/developer')">financialmodelingprep.com</a></span>61        </div>62      </div>6364      <div class="section">65        <h2>66          <span class="badge optional">Optionnelles</span>67          Recherche web & extras68        </h2>6970        <div class="collapsible" id="optional-toggle">71          <button type="button" class="collapsible-btn" onclick="toggleOptional()">72            <span>Afficher les cles optionnelles</span>73            <svg class="chevron" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="m6 9 6 6 6-6"/></svg>74          </button>75        </div>7677        <div class="optional-fields" id="optional-fields" style="display: none;">78          <div class="field">79            <label for="tavily">Tavily (Recherche web)</label>80            <input type="password" id="tavily" placeholder="tvly-..." autocomplete="off" spellcheck="false" />81          </div>82          <div class="field">83            <label for="firecrawl">Firecrawl (Web scraping)</label>84            <input type="password" id="firecrawl" placeholder="fc-..." autocomplete="off" spellcheck="false" />85          </div>86          <div class="field">87            <label for="exa">Exa (Recherche semantique)</label>88            <input type="password" id="exa" placeholder="Votre cle Exa..." autocomplete="off" spellcheck="false" />89          </div>90          <div class="field">91            <label for="serpapi">SerpAPI (Google Search)</label>92            <input type="password" id="serpapi" placeholder="Votre cle SerpAPI..." autocomplete="off" spellcheck="false" />93          </div>94          <div class="field">95            <label for="elevenlabs">ElevenLabs (Speech-to-text)</label>96            <input type="password" id="elevenlabs" placeholder="Votre cle ElevenLabs..." autocomplete="off" spellcheck="false" />97          </div>98        </div>99      </div>100101      <div id="error-message" class="error" style="display: none;"></div>102103      <div id="loading-state" class="loading" style="display: none;">104        <div class="spinner"></div>105        <span>Demarrage du serveur VQuant...</span>106      </div>107108      <button type="submit" id="submit-btn" class="submit-btn">109        Demarrer VQuant110      </button>111    </form>112113    <div class="footer">114      <span>VQuant Desktop</span>115      <span id="version"></span>116    </div>117  </div>118119  <script>120    function openLink(url) {121      if (window.vquant) {122        window.vquant.openExternal(url);123      }124    }125126    function toggleOptional() {127      const fields = document.getElementById('optional-fields');128      const btn = document.querySelector('.collapsible-btn span');129      const chevron = document.querySelector('.chevron');130      if (fields.style.display === 'none') {131        fields.style.display = 'block';132        btn.textContent = 'Masquer les cles optionnelles';133        chevron.style.transform = 'rotate(180deg)';134      } else {135        fields.style.display = 'none';136        btn.textContent = 'Afficher les cles optionnelles';137        chevron.style.transform = 'rotate(0deg)';138      }139    }140141    async function init() {142      if (!window.vquant) return;143144      const version = await window.vquant.getAppVersion();145      document.getElementById('version').textContent = `v${version}`;146147      const keys = await window.vquant.getApiKeys();148      if (keys.ANTHROPIC_API_KEY) document.getElementById('anthropic').value = keys.ANTHROPIC_API_KEY;149      if (keys.FMP_API_KEY) document.getElementById('fmp').value = keys.FMP_API_KEY;150      if (keys.TAVILY_API_KEY) document.getElementById('tavily').value = keys.TAVILY_API_KEY;151      if (keys.FIRECRAWL_API_KEY) document.getElementById('firecrawl').value = keys.FIRECRAWL_API_KEY;152      if (keys.EXA_API_KEY) document.getElementById('exa').value = keys.EXA_API_KEY;153      if (keys.SERPAPI_API_KEY) document.getElementById('serpapi').value = keys.SERPAPI_API_KEY;154      if (keys.ELEVENLABS_API_KEY) document.getElementById('elevenlabs').value = keys.ELEVENLABS_API_KEY;155156      const theme = await window.vquant.getTheme();157      document.body.setAttribute('data-theme', theme);158159      window.vquant.onSetupStatus((status) => {160        if (status === 'starting-server') {161          document.getElementById('loading-state').style.display = 'flex';162          document.getElementById('submit-btn').disabled = true;163        }164      });165    }166167    document.getElementById('setup-form').addEventListener('submit', async (e) => {168      e.preventDefault();169170      const anthropic = document.getElementById('anthropic').value.trim();171      const fmp = document.getElementById('fmp').value.trim();172173      if (!anthropic || !fmp) {174        const error = document.getElementById('error-message');175        error.textContent = 'Les cles Anthropic et FMP sont requises.';176        error.style.display = 'block';177        return;178      }179180      document.getElementById('error-message').style.display = 'none';181      document.getElementById('loading-state').style.display = 'flex';182      document.getElementById('submit-btn').disabled = true;183      document.getElementById('submit-btn').textContent = 'Demarrage...';184185      const keys = {186        ANTHROPIC_API_KEY: anthropic,187        FMP_API_KEY: fmp,188        TAVILY_API_KEY: document.getElementById('tavily').value.trim(),189        FIRECRAWL_API_KEY: document.getElementById('firecrawl').value.trim(),190        EXA_API_KEY: document.getElementById('exa').value.trim(),191        SERPAPI_API_KEY: document.getElementById('serpapi').value.trim(),192        ELEVENLABS_API_KEY: document.getElementById('elevenlabs').value.trim(),193      };194195      const result = await window.vquant.saveApiKeys(keys);196197      if (!result.success) {198        document.getElementById('loading-state').style.display = 'none';199        document.getElementById('submit-btn').disabled = false;200        document.getElementById('submit-btn').textContent = 'Demarrer VQuant';201        const error = document.getElementById('error-message');202        error.textContent = `Erreur: ${result.error}`;203        error.style.display = 'block';204      }205    });206207    init();208  </script>209</body>210</html>211