Persist agent/secrets settings with masked secrets and runner hot-reload; add maintenance windows, maintpage binary, and zero-downtime listener handoff.
83 lines
2.7 KiB
JavaScript
83 lines
2.7 KiB
JavaScript
/**
|
|
* Unit tests for runner applyReload helper (extracted inline via dynamic import of module pieces).
|
|
* We test TavilyKeyPool rebuild + masking semantics used by /admin/reload.
|
|
*/
|
|
import assert from "node:assert/strict";
|
|
import { TavilyKeyPool } from "../extensions/tavily-search.mjs";
|
|
import { mkdtempSync, readFileSync, rmSync } from "node:fs";
|
|
import { tmpdir } from "node:os";
|
|
import { join } from "node:path";
|
|
import { writeFileSync, mkdirSync } from "node:fs";
|
|
|
|
function applyReloadLike(body, { piDir, runtime }) {
|
|
const minimax = body.minimax || {};
|
|
const endpoint = (minimax.endpoint || runtime.endpoint || "https://api.minimaxi.com/v1").trim();
|
|
const apiToken = String(minimax.apiKey || "").trim();
|
|
const modelId = (minimax.modelId || body.piModel || runtime.model || "MiniMax-M3").trim();
|
|
let rawApiType = (minimax.apiType || runtime.apiType || "openai-compatible").trim();
|
|
let apiType = rawApiType;
|
|
if (rawApiType === "openai-compatible" || rawApiType === "openai") {
|
|
apiType = "openai-completions";
|
|
}
|
|
mkdirSync(join(piDir, "extensions"), { recursive: true });
|
|
const models = {
|
|
providers: {
|
|
minimax: {
|
|
name: "MiniMax",
|
|
baseUrl: endpoint,
|
|
api: apiType,
|
|
apiKey: apiToken,
|
|
models: [{ id: modelId, name: modelId }],
|
|
},
|
|
},
|
|
};
|
|
writeFileSync(join(piDir, "models.json"), JSON.stringify(models, null, 2) + "\n");
|
|
let pool = runtime.pool;
|
|
if (Array.isArray(body.tavilyKeys)) {
|
|
pool = new TavilyKeyPool(body.tavilyKeys);
|
|
}
|
|
return {
|
|
ok: true,
|
|
endpoint,
|
|
model_id: modelId,
|
|
api: apiType,
|
|
has_token: Boolean(apiToken),
|
|
tavily: { active: pool.size() > 0, keys_count: pool.size() },
|
|
pool,
|
|
};
|
|
}
|
|
|
|
const dir = mkdtempSync(join(tmpdir(), "pi-reload-"));
|
|
try {
|
|
const result = applyReloadLike(
|
|
{
|
|
minimax: {
|
|
endpoint: "https://example.test/v1",
|
|
apiKey: "sk-test-key",
|
|
modelId: "MiniMax-M2.7-highspeed",
|
|
apiType: "openai-compatible",
|
|
},
|
|
tavilyKeys: ["tvly-a", "tvly-b"],
|
|
},
|
|
{
|
|
piDir: dir,
|
|
runtime: {
|
|
endpoint: "https://old",
|
|
model: "old",
|
|
apiType: "openai-compatible",
|
|
pool: new TavilyKeyPool([]),
|
|
},
|
|
},
|
|
);
|
|
assert.equal(result.ok, true);
|
|
assert.equal(result.model_id, "MiniMax-M2.7-highspeed");
|
|
assert.equal(result.api, "openai-completions");
|
|
assert.equal(result.tavily.keys_count, 2);
|
|
const models = JSON.parse(readFileSync(join(dir, "models.json"), "utf8"));
|
|
assert.equal(models.providers.minimax.apiKey, "sk-test-key");
|
|
assert.equal(models.providers.minimax.baseUrl, "https://example.test/v1");
|
|
console.log("reload.test.mjs PASS");
|
|
} finally {
|
|
rmSync(dir, { recursive: true, force: true });
|
|
}
|