mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-02 07:04:53 +00:00
Summary:
- Split the lightweight secrets runtime state and auth-store cache from the full secrets runtime.
- Use the startup fast path whenever gateway startup has no SecretRef values, while preserving cleanup and refresh semantics.
- Add regression coverage for startup-only empty auth-store snapshots and update affected gateway/tool tests.
Verification:
- pnpm test src/secrets/runtime.fast-path.test.ts src/secrets/runtime-state.test.ts src/gateway/server-startup-config.secrets.test.ts src/gateway/server-import-boundary.test.ts src/gateway/server-aux-handlers.test.ts src/gateway/server-methods/config.shared-auth.test.ts src/agents/tools/web-tools.enabled-defaults.test.ts src/agents/tools/web-tool-runtime-context.test.ts -- --reporter=verbose
- pnpm build
- pnpm format:check -- src/agents/tools/web-tools.enabled-defaults.test.ts src/secrets/runtime-command-secrets.ts src/secrets/runtime-fast-path.ts src/secrets/runtime.fast-path.test.ts src/agents/auth-profiles/store.ts src/agents/auth-profiles/store-cache.ts src/secrets/runtime-state.ts src/secrets/runtime-state.test.ts src/gateway/server-startup-config.ts
- codex-review --mode branch
- isolated gateway token-auth smoke: openclaw gateway run + openclaw gateway health returned ok: true
- GitHub CI on PR #83031 green; newer Real behavior proof run passed on current SHA f27ed3f7ce.
Co-authored-by: samzong <samzong.lu@gmail.com>
72 lines
2.3 KiB
TypeScript
72 lines
2.3 KiB
TypeScript
import fs from "node:fs";
|
|
import os from "node:os";
|
|
import path from "node:path";
|
|
import { afterEach, describe, expect, it } from "vitest";
|
|
import { resolveAuthStatePath, resolveAuthStorePath } from "../agents/auth-profiles/paths.js";
|
|
import { writeCachedAuthProfileStore } from "../agents/auth-profiles/store-cache.js";
|
|
import { loadAuthProfileStoreForRuntime } from "../agents/auth-profiles/store.js";
|
|
import type { AuthProfileStore } from "../agents/auth-profiles/types.js";
|
|
import { clearSecretsRuntimeSnapshot } from "./runtime-state.js";
|
|
|
|
function authStore(key: string): AuthProfileStore {
|
|
return {
|
|
version: 1,
|
|
profiles: {
|
|
"openai:default": {
|
|
type: "api_key",
|
|
provider: "openai",
|
|
key,
|
|
},
|
|
},
|
|
};
|
|
}
|
|
|
|
describe("secrets runtime state", () => {
|
|
const previousStateDir = process.env.OPENCLAW_STATE_DIR;
|
|
|
|
afterEach(() => {
|
|
clearSecretsRuntimeSnapshot();
|
|
if (previousStateDir === undefined) {
|
|
delete process.env.OPENCLAW_STATE_DIR;
|
|
} else {
|
|
process.env.OPENCLAW_STATE_DIR = previousStateDir;
|
|
}
|
|
});
|
|
|
|
it("clears loaded auth-profile cache without importing the full secrets runtime", () => {
|
|
const root = fs.mkdtempSync(path.join(os.tmpdir(), "openclaw-runtime-state-cache-"));
|
|
process.env.OPENCLAW_STATE_DIR = root;
|
|
const agentDir = path.join(root, "agents", "default", "agent");
|
|
|
|
try {
|
|
fs.mkdirSync(agentDir, { recursive: true });
|
|
const authPath = resolveAuthStorePath(agentDir);
|
|
const statePath = resolveAuthStatePath(agentDir);
|
|
fs.writeFileSync(authPath, `${JSON.stringify(authStore("sk-new"))}\n`);
|
|
const stat = fs.statSync(authPath);
|
|
writeCachedAuthProfileStore({
|
|
authPath,
|
|
authMtimeMs: stat.mtimeMs,
|
|
stateMtimeMs: fs.existsSync(statePath) ? fs.statSync(statePath).mtimeMs : null,
|
|
store: authStore("sk-old"),
|
|
});
|
|
|
|
expect(
|
|
loadAuthProfileStoreForRuntime(agentDir, { syncExternalCli: false }).profiles[
|
|
"openai:default"
|
|
],
|
|
).toMatchObject({ key: "sk-old" });
|
|
|
|
clearSecretsRuntimeSnapshot();
|
|
|
|
expect(
|
|
loadAuthProfileStoreForRuntime(agentDir, { syncExternalCli: false }).profiles[
|
|
"openai:default"
|
|
],
|
|
).toMatchObject({ key: "sk-new" });
|
|
} finally {
|
|
fs.rmSync(root, { recursive: true, force: true });
|
|
}
|
|
});
|
|
});
|