From 6f6ad76a77f7708d7b2a728d11bd1227def43271 Mon Sep 17 00:00:00 2001 From: Mikael Hugo Date: Sun, 10 May 2026 18:25:23 +0200 Subject: [PATCH] feat(memory): load LLM gateway key from auth.json only, not env vars MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Gateway key and URL are now read exclusively from ~/.sf/agent/auth.json under the 'llm-gateway' entry. Removed env var support for the API key (SF_LLM_GATEWAY_KEY, LLM_MUX_API_KEY, etc.) — credentials belong in auth.json alongside all other provider keys, not in the environment. Model/instruction overrides (SF_LLM_GATEWAY_EMBED_MODEL etc.) still read from env vars as they are tuning knobs, not secrets. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../extensions/sf/memory-embeddings.js | 42 ++++++------------- 1 file changed, 12 insertions(+), 30 deletions(-) diff --git a/src/resources/extensions/sf/memory-embeddings.js b/src/resources/extensions/sf/memory-embeddings.js index f1364acfe..c1f0f6034 100644 --- a/src/resources/extensions/sf/memory-embeddings.js +++ b/src/resources/extensions/sf/memory-embeddings.js @@ -22,8 +22,6 @@ import { logWarning } from "./workflow-logger.js"; // ─── Gateway config ────────────────────────────────────────────────────────── const DEFAULT_TIMEOUT_MS = 30_000; -const ENV_KEY = "SF_LLM_GATEWAY_KEY"; -const ENV_URL = "SF_LLM_GATEWAY_URL"; const ENV_EMBED_MODEL = "SF_LLM_GATEWAY_EMBED_MODEL"; const ENV_RERANK_MODEL = "SF_LLM_GATEWAY_RERANK_MODEL"; const ENV_EMBED_QUERY_INSTRUCTION = "SF_LLM_GATEWAY_EMBED_QUERY_INSTRUCTION"; @@ -31,39 +29,23 @@ const DEFAULT_EMBEDDING_MODEL = "Qwen/Qwen3-Embedding-4B"; const DEFAULT_RERANK_MODEL = "Qwen/Qwen3-Reranker-0.6B"; const DEFAULT_QUERY_INSTRUCTION = "Instruct: Retrieve relevant software engineering memories, facts, and project decisions for the given query\nQuery: "; -const KEY_ALIASES = [ - ENV_KEY, - "LLM_GATEWAY_API_KEY", - "LLM_GATEWAY_BEARER_KEY", - "LLM_MUX_API_KEY", -]; -const URL_ALIASES = [ENV_URL, "LLM_GATEWAY_BASE_URL", "LLM_MUX_BASE_URL"]; -function firstEnvEntry(keys) { - for (const key of keys) { - const value = process.env[key]?.trim(); - if (value) return { key, value }; - } - return null; +function firstEnvValue(key) { + return process.env[key]?.trim() || ""; } -function firstEnvValue(keys) { - return firstEnvEntry(keys)?.value ?? ""; -} -/** Read gateway config from env. Returns null when no key is present — opt-in. */ +/** Read gateway config from auth.json only. Returns null when not configured — opt-in. */ export function loadGatewayConfigFromEnv() { - const keyEntry = firstEnvEntry(KEY_ALIASES); - if (!keyEntry) return null; - const urlEntry = firstEnvEntry(URL_ALIASES); - const url = urlEntry?.value || "https://llm-gateway.centralcloud.com/v1"; + const fromAuth = readGatewayFromAuthJson(); + if (!fromAuth) return null; const embeddingModel = - firstEnvValue([ENV_EMBED_MODEL]) || DEFAULT_EMBEDDING_MODEL; - const rerankModel = firstEnvValue([ENV_RERANK_MODEL]) || DEFAULT_RERANK_MODEL; + firstEnvValue(ENV_EMBED_MODEL) || DEFAULT_EMBEDDING_MODEL; + const rerankModel = firstEnvValue(ENV_RERANK_MODEL) || DEFAULT_RERANK_MODEL; const queryInstruction = - firstEnvValue([ENV_EMBED_QUERY_INSTRUCTION]) || DEFAULT_QUERY_INSTRUCTION; + firstEnvValue(ENV_EMBED_QUERY_INSTRUCTION) || DEFAULT_QUERY_INSTRUCTION; return { - url, - apiKey: keyEntry.value, - keySource: keyEntry.key, - urlSource: urlEntry?.key ?? "default", + url: fromAuth.url ?? "https://llm-gateway.centralcloud.com/v1", + apiKey: fromAuth.key, + keySource: "auth.json:llm-gateway", + urlSource: fromAuth.url ? "auth.json:llm-gateway" : "default", embeddingModel, rerankModel, queryInstruction,