feat(ui): redesign voice cockpit with clinical companion drawer, Svelte 5 migration, and Gemini 3.8 voice
- Re-architect VoiceSession into full-bleed studio cockpit with overlay slide-over companion drawer - Eliminate width squishing defect on LiveInsightPanel and add native dark/light theme support - Integrate authentic Google Gemini 3.8 Flash TTS with Fenrir persona and fallback audio pipeline - Implement comprehensive Playwright E2E visual regression suite across Desktop, iPad, and iPhone (21 tests, 45 snapshots) - Migrate core application to Svelte 5 runes (, , ) with reactive stores - Maintain .NET 8 Azure Functions serverless endpoints and clean build hygiene
This commit is contained in:
1 parent
c82b112624
commit
1feea40684
148 files changed
+11230
-1706
No files matched your search
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* API Configuration & Key Resolution Service
|
||||
*
|
||||
* Provides unified, hierarchical access to OpenRouter API credentials,
|
||||
* supporting browser LocalStorage overrides and environment variables.
|
||||
*/
|
||||
|
||||
import { UserSettings } from '../types';
|
||||
|
||||
const SETTINGS_KEY = 'cognitive-clarity-settings';
|
||||
|
||||
export const DEFAULT_OPENROUTER_MODEL = 'google/gemini-3.8-flash';
|
||||
export const DEFAULT_SUPERVISOR_MODEL = 'google/gemini-3.8-flash';
|
||||
|
||||
export function getStoredUserSettings(): Partial<UserSettings> {
|
||||
try {
|
||||
if (typeof localStorage === 'undefined') {
|
||||
return {};
|
||||
}
|
||||
const saved = localStorage.getItem(SETTINGS_KEY);
|
||||
return saved ? JSON.parse(saved) : {};
|
||||
} catch (e) {
|
||||
console.error("Failed to read user settings from localStorage", e);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the effective OpenRouter API Key.
|
||||
* Precedence:
|
||||
* 1. Explicit argument
|
||||
* 2. UserSettings in LocalStorage
|
||||
* 3. Vite environment variable (VITE_OPENROUTER_API_KEY)
|
||||
* 4. Node process environment variable (OPENROUTER_API_KEY)
|
||||
*/
|
||||
export function getOpenRouterApiKey(customKey?: string): string {
|
||||
if (customKey !== undefined) {
|
||||
return customKey.trim();
|
||||
}
|
||||
|
||||
const stored = getStoredUserSettings();
|
||||
if (stored.openRouterApiKey && stored.openRouterApiKey.trim().length > 0) {
|
||||
return stored.openRouterApiKey.trim();
|
||||
}
|
||||
|
||||
if (typeof process !== 'undefined' && process.env?.OPENROUTER_API_KEY !== undefined) {
|
||||
return process.env.OPENROUTER_API_KEY.trim();
|
||||
}
|
||||
|
||||
if (typeof import.meta !== 'undefined' && import.meta.env?.VITE_OPENROUTER_API_KEY) {
|
||||
return (import.meta.env.VITE_OPENROUTER_API_KEY as string).trim();
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a valid OpenRouter API Key is configured.
|
||||
*/
|
||||
export function hasOpenRouterApiKey(): boolean {
|
||||
return getOpenRouterApiKey().length > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the effective Google Gemini API Key.
|
||||
* Precedence:
|
||||
* 1. Explicit argument
|
||||
* 2. UserSettings in LocalStorage (geminiApiKey)
|
||||
* 3. Node process environment variable (GEMINI_API_KEY / API_KEY / VITE_GEMINI_API_KEY)
|
||||
* 4. Vite environment variable (VITE_GEMINI_API_KEY)
|
||||
*/
|
||||
export function getGeminiApiKey(customKey?: string): string {
|
||||
if (customKey !== undefined) {
|
||||
return customKey.trim();
|
||||
}
|
||||
|
||||
const stored = getStoredUserSettings();
|
||||
if (stored.geminiApiKey && stored.geminiApiKey.trim().length > 0) {
|
||||
return stored.geminiApiKey.trim();
|
||||
}
|
||||
|
||||
if (typeof process !== 'undefined') {
|
||||
if (process.env?.GEMINI_API_KEY !== undefined) return process.env.GEMINI_API_KEY.trim();
|
||||
if (process.env?.API_KEY !== undefined) return process.env.API_KEY.trim();
|
||||
if (process.env?.VITE_GEMINI_API_KEY !== undefined) return process.env.VITE_GEMINI_API_KEY.trim();
|
||||
}
|
||||
|
||||
if (typeof import.meta !== 'undefined' && import.meta.env?.VITE_GEMINI_API_KEY) {
|
||||
return (import.meta.env.VITE_GEMINI_API_KEY as string).trim();
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a valid Google Gemini API Key is configured.
|
||||
*/
|
||||
export function hasGeminiApiKey(): boolean {
|
||||
return getGeminiApiKey().length > 0;
|
||||
}
|
||||
Reference in new issue
Block a user