diff --git a/desktop/src/lib/llm-service.ts b/desktop/src/lib/llm-service.ts index fc02c80..4c60ce5 100644 --- a/desktop/src/lib/llm-service.ts +++ b/desktop/src/lib/llm-service.ts @@ -16,6 +16,7 @@ import { DEFAULT_MODEL_ID, DEFAULT_OPENAI_BASE_URL } from '../constants/models'; import { createLogger } from './logger'; +import { recordLLMUsage } from './telemetry-collector'; const log = createLogger('LLMService'); @@ -819,7 +820,6 @@ function trackLLMCall( error?: unknown, ): void { try { - const { recordLLMUsage } = require('./telemetry-collector'); recordLLMUsage( response.model || adapter.getProvider(), response.tokensUsed?.input ?? 0, @@ -832,7 +832,7 @@ function trackLLMCall( }, ); } catch (e) { - log.debug('Telemetry recording failed (SSR or unavailable)', { error: e }); + log.debug('Telemetry recording failed', { error: e }); } } diff --git a/desktop/src/store/chat/streamStore.ts b/desktop/src/store/chat/streamStore.ts index c881531..05fd157 100644 --- a/desktop/src/store/chat/streamStore.ts +++ b/desktop/src/store/chat/streamStore.ts @@ -57,7 +57,6 @@ async function tryRecoverFromAuthError(error: string): Promise { const newToken = await saasClient.refreshMutex(); if (newToken) { // Update kernel config with refreshed token → triggers kernel re-init via changed api_key detection - const { useConnectionStore } = await import('../connectionStore'); const { getKernelClient } = await import('../../lib/kernel-client'); const kernelClient = getKernelClient(); const currentConfig = kernelClient.getConfig(); diff --git a/desktop/src/store/connectionStore.ts b/desktop/src/store/connectionStore.ts index 6b4f929..e9fa984 100644 --- a/desktop/src/store/connectionStore.ts +++ b/desktop/src/store/connectionStore.ts @@ -30,6 +30,16 @@ import { useConfigStore } from './configStore'; import { createLogger } from '../lib/logger'; import { secureStorage } from '../lib/secure-storage'; +// 延迟加载 conversationStore 避免循环依赖 +// connect() 是 async 函数,在其中 await import() 是安全的 +let _conversationStore: typeof import('./chat/conversationStore') | null = null; +async function loadConversationStore() { + if (!_conversationStore) { + try { _conversationStore = await import('./chat/conversationStore'); } catch { /* not loaded yet */ } + } + return _conversationStore; +} + const log = createLogger('ConnectionStore'); // === Mode Selection === @@ -492,8 +502,8 @@ export const useConnectionStore = create((set, get) => { // 优先使用 conversationStore 的 currentModel,如果设置了的话 let preferredModel: string | undefined; try { - const { useConversationStore } = require('./chat/conversationStore'); - preferredModel = useConversationStore.getState().currentModel; + const cs = await loadConversationStore(); + preferredModel = cs?.useConversationStore.getState().currentModel; } catch { // conversationStore 可能尚未初始化 } @@ -553,13 +563,9 @@ export const useConnectionStore = create((set, get) => { ); const relayClient = createSaaSRelayGatewayClient(session.saasUrl, () => { // 每次调用时读取 conversationStore 的 currentModel,fallback 到第一个可用模型 - try { - const { useConversationStore } = require('./chat/conversationStore'); - const current = useConversationStore.getState().currentModel; - return (current && validBrowserModelIds.has(current)) ? current : fallbackModelId; - } catch { - return fallbackModelId; - } + // 注意:这里不能用 await(同步回调),但 conversationStore 已在上方 loadConversationStore() 中加载 + const current = _conversationStore?.useConversationStore.getState().currentModel; + return (current && validBrowserModelIds.has(current)) ? current : fallbackModelId; }); set({ diff --git a/desktop/src/store/saasStore.ts b/desktop/src/store/saasStore.ts index 31040ea..1929ea7 100644 --- a/desktop/src/store/saasStore.ts +++ b/desktop/src/store/saasStore.ts @@ -434,7 +434,7 @@ export const useSaaSStore = create((set, get) => { // Clear currentModel so next connection uses fresh model resolution try { - const { useConversationStore } = require('./chat/conversationStore'); + const { useConversationStore } = await import('./chat/conversationStore'); useConversationStore.getState().setCurrentModel(''); } catch { /* non-critical */ }