| import fs from "node:fs/promises"; |
| import path from "node:path"; |
| import { describe, expect, it, vi } from "vitest"; |
| import { withTempHome } from "./test-helpers.js"; |
|
|
| describe("config pruning defaults", () => { |
| it("does not enable contextPruning by default", async () => { |
| const prevApiKey = process.env.ANTHROPIC_API_KEY; |
| const prevOauthToken = process.env.ANTHROPIC_OAUTH_TOKEN; |
| process.env.ANTHROPIC_API_KEY = ""; |
| process.env.ANTHROPIC_OAUTH_TOKEN = ""; |
| await withTempHome(async (home) => { |
| const configDir = path.join(home, ".openclaw"); |
| await fs.mkdir(configDir, { recursive: true }); |
| await fs.writeFile( |
| path.join(configDir, "openclaw.json"), |
| JSON.stringify({ agents: { defaults: {} } }, null, 2), |
| "utf-8", |
| ); |
|
|
| vi.resetModules(); |
| const { loadConfig } = await import("./config.js"); |
| const cfg = loadConfig(); |
|
|
| expect(cfg.agents?.defaults?.contextPruning?.mode).toBeUndefined(); |
| }); |
| if (prevApiKey === undefined) { |
| delete process.env.ANTHROPIC_API_KEY; |
| } else { |
| process.env.ANTHROPIC_API_KEY = prevApiKey; |
| } |
| if (prevOauthToken === undefined) { |
| delete process.env.ANTHROPIC_OAUTH_TOKEN; |
| } else { |
| process.env.ANTHROPIC_OAUTH_TOKEN = prevOauthToken; |
| } |
| }); |
|
|
| it("enables cache-ttl pruning + 1h heartbeat for Anthropic OAuth", async () => { |
| await withTempHome(async (home) => { |
| const configDir = path.join(home, ".openclaw"); |
| await fs.mkdir(configDir, { recursive: true }); |
| await fs.writeFile( |
| path.join(configDir, "openclaw.json"), |
| JSON.stringify( |
| { |
| auth: { |
| profiles: { |
| "anthropic:me": { provider: "anthropic", mode: "oauth", email: "me@example.com" }, |
| }, |
| }, |
| agents: { defaults: {} }, |
| }, |
| null, |
| 2, |
| ), |
| "utf-8", |
| ); |
|
|
| vi.resetModules(); |
| const { loadConfig } = await import("./config.js"); |
| const cfg = loadConfig(); |
|
|
| expect(cfg.agents?.defaults?.contextPruning?.mode).toBe("cache-ttl"); |
| expect(cfg.agents?.defaults?.contextPruning?.ttl).toBe("1h"); |
| expect(cfg.agents?.defaults?.heartbeat?.every).toBe("1h"); |
| }); |
| }); |
|
|
| it("enables cache-ttl pruning + 1h cache TTL for Anthropic API keys", async () => { |
| await withTempHome(async (home) => { |
| const configDir = path.join(home, ".openclaw"); |
| await fs.mkdir(configDir, { recursive: true }); |
| await fs.writeFile( |
| path.join(configDir, "openclaw.json"), |
| JSON.stringify( |
| { |
| auth: { |
| profiles: { |
| "anthropic:api": { provider: "anthropic", mode: "api_key" }, |
| }, |
| }, |
| agents: { |
| defaults: { |
| model: { primary: "anthropic/claude-opus-4-5" }, |
| }, |
| }, |
| }, |
| null, |
| 2, |
| ), |
| "utf-8", |
| ); |
|
|
| vi.resetModules(); |
| const { loadConfig } = await import("./config.js"); |
| const cfg = loadConfig(); |
|
|
| expect(cfg.agents?.defaults?.contextPruning?.mode).toBe("cache-ttl"); |
| expect(cfg.agents?.defaults?.contextPruning?.ttl).toBe("1h"); |
| expect(cfg.agents?.defaults?.heartbeat?.every).toBe("30m"); |
| expect( |
| cfg.agents?.defaults?.models?.["anthropic/claude-opus-4-5"]?.params?.cacheControlTtl, |
| ).toBe("1h"); |
| }); |
| }); |
|
|
| it("does not override explicit contextPruning mode", async () => { |
| await withTempHome(async (home) => { |
| const configDir = path.join(home, ".openclaw"); |
| await fs.mkdir(configDir, { recursive: true }); |
| await fs.writeFile( |
| path.join(configDir, "openclaw.json"), |
| JSON.stringify({ agents: { defaults: { contextPruning: { mode: "off" } } } }, null, 2), |
| "utf-8", |
| ); |
|
|
| vi.resetModules(); |
| const { loadConfig } = await import("./config.js"); |
| const cfg = loadConfig(); |
|
|
| expect(cfg.agents?.defaults?.contextPruning?.mode).toBe("off"); |
| }); |
| }); |
| }); |
|
|