fix(memory): add missing readGatewayFromAuthJson to source + update tests
The function and node:fs/os/path imports were dropped from the source during editing. Added them back. Updated memory-embeddings-llm-gateway test to cover auth.json-only behavior (no env var aliases). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
parent
6f6ad76a77
commit
5c2e3eec24
2 changed files with 77 additions and 60 deletions
|
|
@ -12,6 +12,9 @@
|
|||
// When no gateway is configured (or the worker is offline), all three
|
||||
// pipeline stages soft-degrade and `getRelevantMemoriesRanked` falls back
|
||||
// to static (confidence × hit_count) ranking.
|
||||
import { existsSync, readFileSync } from "node:fs";
|
||||
import { homedir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import {
|
||||
_getAdapter,
|
||||
deleteMemoryEmbedding,
|
||||
|
|
@ -20,6 +23,20 @@ import {
|
|||
} from "./sf-db.js";
|
||||
import { logWarning } from "./workflow-logger.js";
|
||||
|
||||
/** Read the llm-gateway entry from ~/.sf/agent/auth.json if present. */
|
||||
function readGatewayFromAuthJson() {
|
||||
try {
|
||||
const authPath = join(homedir(), ".sf", "agent", "auth.json");
|
||||
if (!existsSync(authPath)) return null;
|
||||
const data = JSON.parse(readFileSync(authPath, "utf8"));
|
||||
const entry = data["llm-gateway"];
|
||||
if (!entry?.key) return null;
|
||||
return { key: entry.key, url: entry.url || null };
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Gateway config ──────────────────────────────────────────────────────────
|
||||
const DEFAULT_TIMEOUT_MS = 30_000;
|
||||
const ENV_EMBED_MODEL = "SF_LLM_GATEWAY_EMBED_MODEL";
|
||||
|
|
|
|||
|
|
@ -1,74 +1,74 @@
|
|||
import assert from "node:assert/strict";
|
||||
import { afterEach, test } from "vitest";
|
||||
import { mkdirSync, mkdtempSync, writeFileSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { afterEach, beforeEach, test } from "vitest";
|
||||
|
||||
import { loadGatewayConfigFromEnv } from "../memory-embeddings-llm-gateway.js";
|
||||
import { loadGatewayConfigFromEnv } from "../memory-embeddings.js";
|
||||
|
||||
const KEYS = [
|
||||
"SF_LLM_GATEWAY_KEY",
|
||||
"SF_LLM_GATEWAY_URL",
|
||||
const ENV_KEYS = [
|
||||
"SF_LLM_GATEWAY_EMBED_MODEL",
|
||||
"SF_LLM_GATEWAY_RERANK_MODEL",
|
||||
"LLM_GATEWAY_API_KEY",
|
||||
"LLM_GATEWAY_BEARER_KEY",
|
||||
"LLM_GATEWAY_BASE_URL",
|
||||
"LLM_MUX_API_KEY",
|
||||
"LLM_MUX_BASE_URL",
|
||||
"SF_LLM_GATEWAY_EMBED_QUERY_INSTRUCTION",
|
||||
];
|
||||
|
||||
function withCleanGatewayEnv(fn) {
|
||||
const original = Object.fromEntries(
|
||||
KEYS.map((key) => [key, process.env[key]]),
|
||||
);
|
||||
for (const key of KEYS) delete process.env[key];
|
||||
afterEach(() => {
|
||||
for (const key of KEYS) {
|
||||
if (original[key] === undefined) delete process.env[key];
|
||||
else process.env[key] = original[key];
|
||||
}
|
||||
});
|
||||
fn();
|
||||
let originalHome;
|
||||
let tmpHome;
|
||||
|
||||
beforeEach(() => {
|
||||
originalHome = process.env.HOME;
|
||||
tmpHome = mkdtempSync(join(tmpdir(), "sf-test-"));
|
||||
mkdirSync(join(tmpHome, ".sf", "agent"), { recursive: true });
|
||||
process.env.HOME = tmpHome;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
process.env.HOME = originalHome;
|
||||
for (const key of ENV_KEYS) delete process.env[key];
|
||||
});
|
||||
|
||||
function writeAuthJson(entry) {
|
||||
const authPath = join(tmpHome, ".sf", "agent", "auth.json");
|
||||
writeFileSync(authPath, JSON.stringify({ "llm-gateway": entry }));
|
||||
}
|
||||
|
||||
test("loadGatewayConfigFromEnv accepts SF-prefixed configuration", () => {
|
||||
withCleanGatewayEnv(() => {
|
||||
process.env.SF_LLM_GATEWAY_KEY = "sf-key";
|
||||
process.env.SF_LLM_GATEWAY_URL = "https://example.test/v1";
|
||||
process.env.SF_LLM_GATEWAY_EMBED_MODEL = "embed-model";
|
||||
process.env.SF_LLM_GATEWAY_RERANK_MODEL = "rerank-model";
|
||||
|
||||
assert.deepEqual(loadGatewayConfigFromEnv(), {
|
||||
url: "https://example.test/v1",
|
||||
apiKey: "sf-key",
|
||||
keySource: "SF_LLM_GATEWAY_KEY",
|
||||
urlSource: "SF_LLM_GATEWAY_URL",
|
||||
embeddingModel: "embed-model",
|
||||
rerankModel: "rerank-model",
|
||||
queryInstruction:
|
||||
"Instruct: Retrieve relevant software engineering memories, facts, and project decisions for the given query\nQuery: ",
|
||||
});
|
||||
});
|
||||
test("loadGatewayConfigFromEnv returns null when auth.json has no llm-gateway entry", () => {
|
||||
const authPath = join(tmpHome, ".sf", "agent", "auth.json");
|
||||
writeFileSync(authPath, JSON.stringify({}));
|
||||
assert.equal(loadGatewayConfigFromEnv(), null);
|
||||
});
|
||||
|
||||
test("loadGatewayConfigFromEnv accepts llm-gateway shell aliases", () => {
|
||||
withCleanGatewayEnv(() => {
|
||||
process.env.LLM_GATEWAY_BEARER_KEY = "gateway-key";
|
||||
process.env.LLM_GATEWAY_BASE_URL = "https://llm-gateway.test/v1";
|
||||
|
||||
assert.deepEqual(loadGatewayConfigFromEnv(), {
|
||||
url: "https://llm-gateway.test/v1",
|
||||
apiKey: "gateway-key",
|
||||
keySource: "LLM_GATEWAY_BEARER_KEY",
|
||||
urlSource: "LLM_GATEWAY_BASE_URL",
|
||||
embeddingModel: "Qwen/Qwen3-Embedding-4B",
|
||||
rerankModel: "Qwen/Qwen3-Reranker-0.6B",
|
||||
queryInstruction:
|
||||
"Instruct: Retrieve relevant software engineering memories, facts, and project decisions for the given query\nQuery: ",
|
||||
});
|
||||
});
|
||||
test("loadGatewayConfigFromEnv returns null when auth.json does not exist", () => {
|
||||
assert.equal(loadGatewayConfigFromEnv(), null);
|
||||
});
|
||||
|
||||
test("loadGatewayConfigFromEnv returns null without any gateway key", () => {
|
||||
withCleanGatewayEnv(() => {
|
||||
assert.equal(loadGatewayConfigFromEnv(), null);
|
||||
});
|
||||
test("loadGatewayConfigFromEnv reads key and url from auth.json", () => {
|
||||
writeAuthJson({ key: "auth-key", url: "https://example.test/v1", type: "api_key" });
|
||||
|
||||
const cfg = loadGatewayConfigFromEnv();
|
||||
assert.equal(cfg.apiKey, "auth-key");
|
||||
assert.equal(cfg.url, "https://example.test/v1");
|
||||
assert.equal(cfg.keySource, "auth.json:llm-gateway");
|
||||
assert.equal(cfg.urlSource, "auth.json:llm-gateway");
|
||||
assert.equal(cfg.embeddingModel, "Qwen/Qwen3-Embedding-4B");
|
||||
assert.equal(cfg.rerankModel, "Qwen/Qwen3-Reranker-0.6B");
|
||||
});
|
||||
|
||||
test("loadGatewayConfigFromEnv uses default url when auth.json has no url", () => {
|
||||
writeAuthJson({ key: "auth-key", type: "api_key" });
|
||||
|
||||
const cfg = loadGatewayConfigFromEnv();
|
||||
assert.equal(cfg.url, "https://llm-gateway.centralcloud.com/v1");
|
||||
assert.equal(cfg.urlSource, "default");
|
||||
});
|
||||
|
||||
test("loadGatewayConfigFromEnv respects model env var overrides", () => {
|
||||
writeAuthJson({ key: "auth-key", type: "api_key" });
|
||||
process.env.SF_LLM_GATEWAY_EMBED_MODEL = "custom-embed";
|
||||
process.env.SF_LLM_GATEWAY_RERANK_MODEL = "custom-rerank";
|
||||
|
||||
const cfg = loadGatewayConfigFromEnv();
|
||||
assert.equal(cfg.embeddingModel, "custom-embed");
|
||||
assert.equal(cfg.rerankModel, "custom-rerank");
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue