- 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
101 lines
3.0 KiB
TypeScript
101 lines
3.0 KiB
TypeScript
/**
|
|
* 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;
|
|
}
|