feat(memory): load LLM gateway key from auth.json only, not env vars

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>
This commit is contained in:
Mikael Hugo 2026-05-10 18:25:23 +02:00
parent a77e1551d2
commit 6f6ad76a77

View file

@ -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,