From db148e5f2ee94a931e58ed33ecadac4ce1374059 Mon Sep 17 00:00:00 2001 From: dingguagua996-stack Date: Tue, 24 Mar 2026 19:27:24 +0800 Subject: [PATCH] fix: upgrade LLM request failure logs from debug to warn level When smartExtraction LLM calls fail (timeout, rate limit, network error), the failure was completely silent because log() mapped to api.logger.debug(). Users experienced a 60-90 second hang with no visible output, making it impossible to diagnose LLM connectivity issues. Changes: - Add warnLog parameter to LlmClientConfig for warn-level logging - Use warnLog for request-level failures (timeout, network, rate limit) in both API-key and OAuth client paths - Keep debug-level logging for non-critical issues (empty responses, JSON parse, etc.) - Wire warnLog to api.logger.warn in index.ts Now LLM failures appear as visible warnings in the gateway log: [warn] memory-lancedb-pro: llm-client [extract] request failed for model ... Fixes CortexReach/memory-lancedb-pro#323 --- index.ts | 1 + src/llm-client.ts | 15 +++++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/index.ts b/index.ts index 212dedec..4b37e3d1 100644 --- a/index.ts +++ b/index.ts @@ -1759,6 +1759,7 @@ const memoryLanceDBProPlugin = { oauthPath: llmOauthPath, timeoutMs: llmTimeoutMs, log: (msg: string) => api.logger.debug(msg), + warnLog: (msg: string) => api.logger.warn(msg), }); // Initialize embedding-based noise prototype bank (async, non-blocking) diff --git a/src/llm-client.ts b/src/llm-client.ts index 79182ede..d8ece9ba 100644 --- a/src/llm-client.ts +++ b/src/llm-client.ts @@ -23,6 +23,8 @@ export interface LlmClientConfig { oauthProvider?: string; timeoutMs?: number; log?: (msg: string) => void; + /** Warn-level logger for user-visible failures (timeouts, retries, network errors). */ + warnLog?: (msg: string) => void; } export interface LlmClient { @@ -172,7 +174,7 @@ function createTimeoutSignal(timeoutMs?: number): { signal: AbortSignal; dispose }; } -function createApiKeyClient(config: LlmClientConfig, log: (msg: string) => void): LlmClient { +function createApiKeyClient(config: LlmClientConfig, log: (msg: string) => void, warnLog?: (msg: string) => void): LlmClient { if (!config.apiKey) { throw new Error("LLM api-key mode requires llm.apiKey or embedding.apiKey"); } @@ -249,7 +251,7 @@ function createApiKeyClient(config: LlmClientConfig, log: (msg: string) => void) } catch (err) { lastError = `memory-lancedb-pro: llm-client [${label}] request failed for model ${config.model}: ${err instanceof Error ? err.message : String(err)}`; - log(lastError); + (warnLog ?? log)(lastError); return null; } }, @@ -259,7 +261,7 @@ function createApiKeyClient(config: LlmClientConfig, log: (msg: string) => void) }; } -function createOauthClient(config: LlmClientConfig, log: (msg: string) => void): LlmClient { +function createOauthClient(config: LlmClientConfig, log: (msg: string) => void, warnLog?: (msg: string) => void): LlmClient { if (!config.oauthPath) { throw new Error("LLM oauth mode requires llm.oauthPath"); } @@ -400,7 +402,7 @@ function createOauthClient(config: LlmClientConfig, log: (msg: string) => void): } catch (err) { lastError = `memory-lancedb-pro: llm-client [${label}] OAuth request failed for model ${config.model}: ${err instanceof Error ? err.message : String(err)}`; - log(lastError); + (warnLog ?? log)(lastError); return null; } }, @@ -412,10 +414,11 @@ function createOauthClient(config: LlmClientConfig, log: (msg: string) => void): export function createLlmClient(config: LlmClientConfig): LlmClient { const log = config.log ?? (() => {}); + const warnLog = config.warnLog; if (config.auth === "oauth") { - return createOauthClient(config, log); + return createOauthClient(config, log, warnLog); } - return createApiKeyClient(config, log); + return createApiKeyClient(config, log, warnLog); } export { extractJsonFromResponse, repairCommonJson };