diff --git a/desktop/src/App.tsx b/desktop/src/App.tsx index df43321..f4e2b35 100644 --- a/desktop/src/App.tsx +++ b/desktop/src/App.tsx @@ -261,63 +261,65 @@ function App() { // Non-critical, continue without heartbeat } - // Step 5: Restore embedding config to Rust backend - try { - // Migrate plaintext embedding apiKey to secure storage if present + // Step 5: Restore embedding config to Rust backend (Tauri-only) + if (isTauriRuntime()) { try { - const embStored = localStorage.getItem('zclaw-embedding-config'); - if (embStored) { - const embParsed = JSON.parse(embStored); - if (embParsed.apiKey && embParsed.apiKey.trim()) { - const { saveEmbeddingApiKey } = await import('./lib/embedding-client'); - const { secureStorage } = await import('./lib/secure-storage'); - // Only migrate if not already in secure storage - const existing = await secureStorage.get('zclaw-secure-embedding-apikey'); - if (!existing) { - await saveEmbeddingApiKey(embParsed.apiKey); + // Migrate plaintext embedding apiKey to secure storage if present + try { + const embStored = localStorage.getItem('zclaw-embedding-config'); + if (embStored) { + const embParsed = JSON.parse(embStored); + if (embParsed.apiKey && embParsed.apiKey.trim()) { + const { saveEmbeddingApiKey } = await import('./lib/embedding-client'); + const { secureStorage } = await import('./lib/secure-storage'); + // Only migrate if not already in secure storage + const existing = await secureStorage.get('zclaw-secure-embedding-apikey'); + if (!existing) { + await saveEmbeddingApiKey(embParsed.apiKey); + } + // Strip apiKey from localStorage + const { apiKey: _, ...stripped } = embParsed; + localStorage.setItem('zclaw-embedding-config', JSON.stringify(stripped)); } - // Strip apiKey from localStorage - const { apiKey: _, ...stripped } = embParsed; - localStorage.setItem('zclaw-embedding-config', JSON.stringify(stripped)); } + } catch { /* migration failure is non-critical */ } + + const embConfig = loadEmbeddingConfig(); + const embApiKey = await loadEmbeddingApiKey(); + if (embConfig.enabled && embConfig.provider !== 'local' && embApiKey) { + setBootstrapStatus('Restoring embedding configuration...'); + await invoke('viking_configure_embedding', { + provider: embConfig.provider, + apiKey: embApiKey, + model: embConfig.model || undefined, + endpoint: embConfig.endpoint || undefined, + }); + log.debug('Embedding configuration restored to backend'); } - } catch { /* migration failure is non-critical */ } - - const embConfig = loadEmbeddingConfig(); - const embApiKey = await loadEmbeddingApiKey(); - if (embConfig.enabled && embConfig.provider !== 'local' && embApiKey) { - setBootstrapStatus('Restoring embedding configuration...'); - await invoke('viking_configure_embedding', { - provider: embConfig.provider, - apiKey: embApiKey, - model: embConfig.model || undefined, - endpoint: embConfig.endpoint || undefined, - }); - log.debug('Embedding configuration restored to backend'); + } catch (embErr) { + log.warn('Failed to restore embedding config:', embErr); + // Non-critical, semantic search will fall back to TF-IDF } - } catch (embErr) { - log.warn('Failed to restore embedding config:', embErr); - // Non-critical, semantic search will fall back to TF-IDF - } - // Step 5b: Configure summary driver using active LLM (for L0/L1 generation) - try { - const { getDefaultModelConfigAsync, migrateModelApiKeysToSecureStorage } = await import('./store/connectionStore'); - // Migrate any plaintext API keys to secure storage (idempotent) - await migrateModelApiKeysToSecureStorage(); - const modelConfig = await getDefaultModelConfigAsync(); - if (modelConfig && modelConfig.apiKey && modelConfig.baseUrl) { - setBootstrapStatus('Configuring summary driver...'); - await invoke('viking_configure_summary_driver', { - endpoint: modelConfig.baseUrl, - apiKey: modelConfig.apiKey, - model: modelConfig.model || undefined, - }); - log.debug('Summary driver configured with active LLM'); + // Step 5b: Configure summary driver using active LLM (for L0/L1 generation) + try { + const { getDefaultModelConfigAsync, migrateModelApiKeysToSecureStorage } = await import('./store/connectionStore'); + // Migrate any plaintext API keys to secure storage (idempotent) + await migrateModelApiKeysToSecureStorage(); + const modelConfig = await getDefaultModelConfigAsync(); + if (modelConfig && modelConfig.apiKey && modelConfig.baseUrl) { + setBootstrapStatus('Configuring summary driver...'); + await invoke('viking_configure_summary_driver', { + endpoint: modelConfig.baseUrl, + apiKey: modelConfig.apiKey, + model: modelConfig.model || undefined, + }); + log.debug('Summary driver configured with active LLM'); + } + } catch (sumErr) { + log.warn('Failed to configure summary driver:', sumErr); + // Non-critical, summaries won't be auto-generated } - } catch (sumErr) { - log.warn('Failed to configure summary driver:', sumErr); - // Non-critical, summaries won't be auto-generated } // Step 6: Bootstrap complete diff --git a/desktop/src/store/saasStore.ts b/desktop/src/store/saasStore.ts index 3be4bfa..0c49766 100644 --- a/desktop/src/store/saasStore.ts +++ b/desktop/src/store/saasStore.ts @@ -542,7 +542,7 @@ export const useSaaSStore = create((set, get) => { const kernelConfigs = result.configs.filter( (c) => kernelCategories.includes(c.category) && c.value !== null ); - if (kernelConfigs.length > 0) { + if (kernelConfigs.length > 0 && typeof window !== 'undefined' && '__TAURI_INTERNALS__' in window) { try { const { invoke } = await import('@tauri-apps/api/core'); await invoke('kernel_apply_saas_config', {