241 lines
10 KiB
HTML
241 lines
10 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>AI Assistant</title>
|
|
<link rel="stylesheet" href="style.css">
|
|
</head>
|
|
<body>
|
|
<div id="app">
|
|
<div class="app-header">
|
|
<h3>AI Assistant</h3>
|
|
<button id="openSettings" class="icon-button" title="Open Advanced Settings">⚙️</button>
|
|
</div>
|
|
|
|
<details class="panel-group" open>
|
|
<summary>Session</summary>
|
|
<div class="session-context-section">
|
|
<label for="sessionContextProfile">Session Context:</label>
|
|
<select id="sessionContextProfile"></select>
|
|
<div id="sessionContextHint" class="status-message"></div>
|
|
</div>
|
|
<div class="capture-mode-section">
|
|
<label for="captureModeSelect">Audio Input Mode:</label>
|
|
<select id="captureModeSelect">
|
|
<option value="tab">Tab-only (all speakers in the meeting tab)</option>
|
|
<option value="mic">Mic-only (your voice)</option>
|
|
<option value="mixed">Mixed (tab + mic)</option>
|
|
</select>
|
|
<div class="status-message">Use Tab-only or Mixed if you need other speakers in the meeting.</div>
|
|
</div>
|
|
<div class="session-automation-section">
|
|
<label for="sessionAutomationSelect">Automation Preset:</label>
|
|
<select id="sessionAutomationSelect"></select>
|
|
<div id="sessionAutomationHint" class="status-message"></div>
|
|
</div>
|
|
<button id="toggleListening">Start Listening</button>
|
|
<button id="pauseListening" disabled>Pause Listening</button>
|
|
<details class="session-advanced">
|
|
<summary>Advanced Session Options</summary>
|
|
<div class="active-state-section">
|
|
<label>
|
|
<input type="checkbox" id="autoOpenAssistantWindow">
|
|
Auto-open assistant window after Start Listening
|
|
</label>
|
|
</div>
|
|
<div class="active-state-section">
|
|
<label>
|
|
<input type="checkbox" id="autoStartToggle">
|
|
Auto-start listening on meeting sites
|
|
</label>
|
|
</div>
|
|
<div class="active-state-section">
|
|
<label>
|
|
<input type="checkbox" id="storeSessionToggle" disabled>
|
|
Store this session to memory
|
|
</label>
|
|
<button id="forgetSession" class="danger-btn" disabled>Forget Session</button>
|
|
</div>
|
|
<div class="session-automation-section">
|
|
<button id="runSelectedAutomationNow" type="button">Run Selected Automation Now</button>
|
|
</div>
|
|
</details>
|
|
</details>
|
|
|
|
<details class="panel-group">
|
|
<summary>Assistant Setup</summary>
|
|
<div class="ai-provider-section">
|
|
<label for="aiProvider">AI Provider:</label>
|
|
<select id="aiProvider">
|
|
<option value="openai">OpenAI (GPT)</option>
|
|
<option value="anthropic">Anthropic (Claude)</option>
|
|
<option value="google">Google (Gemini)</option>
|
|
<option value="deepseek">DeepSeek</option>
|
|
<option value="ollama">Ollama (Local)</option>
|
|
</select>
|
|
</div>
|
|
|
|
<div class="model-selection">
|
|
<label for="modelSelect">Model:</label>
|
|
<select id="modelSelect">
|
|
<!-- Options will be populated based on provider selection -->
|
|
</select>
|
|
</div>
|
|
|
|
<div class="stt-settings-section">
|
|
<label for="sttProvider">Speech-to-Text Provider:</label>
|
|
<select id="sttProvider">
|
|
<option value="openai">OpenAI Whisper (recommended for Tab/Mixed)</option>
|
|
<option value="local">Local faster-whisper bridge (self-hosted)</option>
|
|
<option value="browser">Browser SpeechRecognition (mic-oriented)</option>
|
|
</select>
|
|
<label for="sttModel">STT Model:</label>
|
|
<select id="sttModel">
|
|
<option value="whisper-1">whisper-1</option>
|
|
<option value="small">small</option>
|
|
<option value="medium">medium</option>
|
|
<option value="large-v3">large-v3</option>
|
|
</select>
|
|
<label for="sttLanguageMode">Language Mode:</label>
|
|
<select id="sttLanguageMode">
|
|
<option value="auto">Auto-detect (recommended)</option>
|
|
<option value="forced">Force language</option>
|
|
</select>
|
|
<input type="text" id="sttForcedLanguage" placeholder="Forced language code (e.g. en, fr, de, ar)">
|
|
<label for="sttTask">STT Task:</label>
|
|
<select id="sttTask">
|
|
<option value="transcribe">Transcribe</option>
|
|
<option value="translate">Translate to English</option>
|
|
</select>
|
|
<label class="inline-toggle" for="sttVadFilter">
|
|
<input type="checkbox" id="sttVadFilter" checked>
|
|
Enable VAD filter
|
|
</label>
|
|
<label for="sttBeamSize">Beam Size:</label>
|
|
<input type="number" id="sttBeamSize" min="1" max="10" step="1" value="5">
|
|
<input type="url" id="sttEndpointInput" placeholder="Local STT endpoint (e.g. http://localhost:8790/transcribe)">
|
|
<input type="password" id="sttApiKeyInput" placeholder="Enter STT API key">
|
|
<button id="saveSttApiKey" type="button">Save STT API Key</button>
|
|
<button id="testSttConnection" type="button">Test STT Connection</button>
|
|
<div id="sttStatus" class="status-message"></div>
|
|
</div>
|
|
|
|
<div class="api-key-section">
|
|
<input type="password" id="apiKeyInput" placeholder="Enter your API Key here">
|
|
<button id="saveApiKey">Save API Key</button>
|
|
<div id="apiKeyStatus" class="status-message"></div>
|
|
</div>
|
|
|
|
<div class="performance-section">
|
|
<label>
|
|
<input type="checkbox" id="speedModeToggle">
|
|
Optimize for speed (faster, shorter answers)
|
|
</label>
|
|
</div>
|
|
</details>
|
|
|
|
<details class="panel-group">
|
|
<summary>Inputs</summary>
|
|
<div class="mic-monitor-section">
|
|
<h4>Mic Monitor</h4>
|
|
<label for="inputDeviceSelect">Input device:</label>
|
|
<select id="inputDeviceSelect"></select>
|
|
<div id="inputDeviceStatus" class="status-message"></div>
|
|
<div class="mic-level">
|
|
<div class="mic-level-bar" id="micLevelBar"></div>
|
|
</div>
|
|
<button id="startMicMonitor">Enable Mic Monitor</button>
|
|
</div>
|
|
</details>
|
|
|
|
<details class="panel-group">
|
|
<summary>Context</summary>
|
|
<div class="context-section">
|
|
<h4>Context Management</h4>
|
|
<div class="session-context-section">
|
|
<label for="contextProfileSelect">Editing Profile:</label>
|
|
<select id="contextProfileSelect"></select>
|
|
<div id="contextProfileHint" class="status-message"></div>
|
|
</div>
|
|
<details class="profile-manager">
|
|
<summary>Manage Profiles</summary>
|
|
<div class="profile-manager-content">
|
|
<input type="text" id="profileNameInput" placeholder="Profile name (e.g., Interview - Backend)">
|
|
<select id="profileModeSelect">
|
|
<option value="interview">Interview</option>
|
|
<option value="meeting">Meeting</option>
|
|
<option value="standup">Standup</option>
|
|
<option value="custom">Custom</option>
|
|
</select>
|
|
<textarea id="profilePromptInput" placeholder="System prompt for this profile..."></textarea>
|
|
<div class="profile-actions-row">
|
|
<button id="newProfileBtn" type="button">New Profile</button>
|
|
<button id="saveProfileBtn" type="button">Save Profile</button>
|
|
<button id="deleteProfileBtn" type="button" class="danger-btn">Delete Profile</button>
|
|
</div>
|
|
<div id="profileManagerStatus" class="status-message"></div>
|
|
</div>
|
|
</details>
|
|
<div class="context-tabs">
|
|
<button class="tab-button active" data-tab="upload">Upload Files</button>
|
|
<button class="tab-button" data-tab="text">Add Text</button>
|
|
<button class="tab-button" data-tab="manage">Manage (0)</button>
|
|
</div>
|
|
|
|
<div id="uploadTab" class="tab-content active">
|
|
<input type="file" id="contextFileInput" multiple accept=".txt,.pdf,.docx" style="display: none;">
|
|
<button id="uploadContextBtn">Upload CV/Job Description</button>
|
|
<div class="upload-info">Supports: PDF, DOCX, TXT (.doc is not supported)</div>
|
|
</div>
|
|
|
|
<div id="textTab" class="tab-content">
|
|
<textarea id="contextTextInput" placeholder="Paste your CV, job description, or any relevant context here..."></textarea>
|
|
<select id="contextTypeSelect">
|
|
<option value="general">General context</option>
|
|
<option value="system">System prompt</option>
|
|
<option value="cv">CV / Resume</option>
|
|
<option value="job_description">Job description</option>
|
|
</select>
|
|
<input type="text" id="contextTitleInput" placeholder="Context title (e.g., 'My CV', 'Job Description')">
|
|
<button id="addContextBtn">Save Context</button>
|
|
</div>
|
|
|
|
<div id="manageTab" class="tab-content">
|
|
<div id="contextList"></div>
|
|
<button id="clearAllContextBtn" class="danger-btn">Clear All Context</button>
|
|
</div>
|
|
</div>
|
|
</details>
|
|
|
|
<details class="panel-group">
|
|
<summary>Multi-Device</summary>
|
|
<div class="device-section">
|
|
<h4>Remote Listening</h4>
|
|
<div class="device-options">
|
|
<button id="enableRemoteListening">Enable Remote Access</button>
|
|
<div id="remoteStatus" class="status-message"></div>
|
|
<div id="deviceInfo" class="device-info" style="display: none;">
|
|
<div><strong>Access from any device:</strong></div>
|
|
<div class="access-url" id="accessUrl"></div>
|
|
<button id="copyUrlBtn">Copy Link</button>
|
|
<div class="qr-code" id="qrCode"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</details>
|
|
|
|
<details class="panel-group">
|
|
<summary>Permissions</summary>
|
|
<button id="showOverlay" type="button">Show Transcription Overlay</button>
|
|
<button id="requestMicPermission">Request Microphone Permission</button>
|
|
<button id="grantTabAccess">Grant Tab Access</button>
|
|
<div id="overlayStatus" class="status-message"></div>
|
|
<div id="micPermissionStatus" class="status-message"></div>
|
|
<div id="tabAccessStatus" class="status-message"></div>
|
|
</details>
|
|
</div>
|
|
<script src="sidepanel.js"></script>
|
|
</body>
|
|
</html>
|