150 lines
6.6 KiB
JavaScript
150 lines
6.6 KiB
JavaScript
/**
|
|
* PR-A Baseline Test 12: Active Memory Plugin
|
|
* Verifies: active-memory plugin exists, loads, has hook mechanism
|
|
* Freezes: active-memory plugin contract
|
|
*/
|
|
|
|
import { describe, it } from "node:test";
|
|
import assert from "node:assert";
|
|
import { existsSync, readFileSync, readdirSync } from "node:fs";
|
|
import { homedir } from "node:os";
|
|
import { join } from "node:path";
|
|
|
|
const OPENCLAW_HOME = "/opt/homebrew/lib/node_modules/openclaw";
|
|
const ACTIVE_MEM_DIR = join(OPENCLAW_HOME, "dist", "extensions", "active-memory");
|
|
const MEMORY_CORE_DIR = join(OPENCLAW_HOME, "dist", "extensions", "memory-core");
|
|
|
|
describe("test-12: Active Memory Plugin Baseline", () => {
|
|
it("12.01 - active-memory plugin directory exists", () => {
|
|
const exists = existsSync(ACTIVE_MEM_DIR);
|
|
console.log("[BASELINE] active-memory dir:", ACTIVE_MEM_DIR);
|
|
console.log("[BASELINE] active-memory dir exists:", exists);
|
|
if (exists) {
|
|
const files = readdirSync(ACTIVE_MEM_DIR);
|
|
console.log("[BASELINE] active-memory files:", files.join(", "));
|
|
}
|
|
assert.ok(exists, "active-memory plugin directory must exist");
|
|
});
|
|
|
|
it("12.02 - active-memory plugin.json has contracts", () => {
|
|
const pluginPath = join(ACTIVE_MEM_DIR, "openclaw.plugin.json");
|
|
if (existsSync(pluginPath)) {
|
|
const plugin = JSON.parse(readFileSync(pluginPath, "utf8"));
|
|
console.log("[BASELINE] active-memory plugin id:", plugin.id);
|
|
console.log("[BASELINE] active-memory onStartup:", plugin.activation?.onStartup);
|
|
console.log("[BASELINE] active-memory name:", plugin.name);
|
|
|
|
// Check config schema keys
|
|
if (plugin.configSchema?.properties) {
|
|
const keys = Object.keys(plugin.configSchema.properties);
|
|
console.log("[BASELINE] active-memory config keys:", keys.join(", "));
|
|
console.log("[BASELINE] active-memory config key count:", keys.length);
|
|
|
|
// Key config fields that must exist
|
|
assert.ok(keys.includes("enabled"), "must have 'enabled' config");
|
|
assert.ok(keys.includes("timeoutMs"), "must have 'timeoutMs' config");
|
|
assert.ok(keys.includes("queryMode"), "must have 'queryMode' config");
|
|
}
|
|
} else {
|
|
console.log("[BASELINE] active-memory plugin.json not found");
|
|
}
|
|
assert.ok(true, "baseline frozen: plugin contract");
|
|
});
|
|
|
|
it("12.03 - memory-core plugin also exists", () => {
|
|
const exists = existsSync(MEMORY_CORE_DIR);
|
|
console.log("[BASELINE] memory-core dir exists:", exists);
|
|
if (exists) {
|
|
const pluginPath = join(MEMORY_CORE_DIR, "openclaw.plugin.json");
|
|
if (existsSync(pluginPath)) {
|
|
const plugin = JSON.parse(readFileSync(pluginPath, "utf8"));
|
|
console.log("[BASELINE] memory-core plugin id:", plugin.id);
|
|
console.log("[BASELINE] memory-core kind:", plugin.kind);
|
|
console.log("[BASELINE] memory-core contracts:",
|
|
JSON.stringify(plugin.contracts));
|
|
console.log("[BASELINE] memory-core has dreaming:",
|
|
!!plugin.configSchema?.properties?.dreaming);
|
|
|
|
// Tool contracts are critical
|
|
const tools = plugin.contracts?.tools || [];
|
|
console.log("[BASELINE] memory-core tools:", tools.join(", "));
|
|
assert.ok(tools.includes("memory_search"), "must register memory_search");
|
|
assert.ok(tools.includes("memory_get"), "must register memory_get");
|
|
|
|
// Dreaming phases
|
|
const phases = plugin.configSchema?.properties?.dreaming?.properties?.phases?.properties;
|
|
if (phases) {
|
|
const phaseNames = Object.keys(phases);
|
|
console.log("[BASELINE] dreaming phases:", phaseNames.join(", "));
|
|
// Freeze: current phase count (light, deep, rem = 3)
|
|
console.log("[BASELINE] dreaming phase count:", phaseNames.length);
|
|
}
|
|
}
|
|
}
|
|
assert.ok(exists, "memory-core plugin directory must exist");
|
|
});
|
|
|
|
it("12.04 - active-memory hook mechanism verified", () => {
|
|
// active-memory uses before_agent_reply hook
|
|
const pluginPath = join(ACTIVE_MEM_DIR, "openclaw.plugin.json");
|
|
if (existsSync(pluginPath)) {
|
|
const plugin = JSON.parse(readFileSync(pluginPath, "utf8"));
|
|
// Check if hook is declared in plugin metadata
|
|
const hasHooks = plugin.hooks !== undefined ||
|
|
plugin.activation?.onStartup === true;
|
|
console.log("[BASELINE] active-memory has hook declarations:", hasHooks);
|
|
|
|
// Config reveals hook behavior
|
|
const mode = plugin.configSchema?.properties?.queryMode;
|
|
if (mode) {
|
|
console.log("[BASELINE] queryMode options:", mode.enum?.join(", ") || "unknown");
|
|
}
|
|
}
|
|
|
|
// Check that the actual code module loads
|
|
const indexJs = join(ACTIVE_MEM_DIR, "index.js");
|
|
if (existsSync(indexJs)) {
|
|
const size = readFileSync(indexJs, "utf8").length;
|
|
console.log("[BASELINE] active-memory index.js size:", size);
|
|
assert.ok(size > 100, "active-memory code must be substantial");
|
|
}
|
|
|
|
assert.ok(true, "baseline frozen: active-memory hook mechanism");
|
|
});
|
|
|
|
it("12.05 - circuit breaker config exists", () => {
|
|
const pluginPath = join(ACTIVE_MEM_DIR, "openclaw.plugin.json");
|
|
if (existsSync(pluginPath)) {
|
|
const plugin = JSON.parse(readFileSync(pluginPath, "utf8"));
|
|
const props = plugin.configSchema?.properties || {};
|
|
const hasCircuitBreaker =
|
|
props.circuitBreakerMaxTimeouts !== undefined &&
|
|
props.circuitBreakerCooldownMs !== undefined;
|
|
console.log("[BASELINE] circuit breaker config:", hasCircuitBreaker);
|
|
|
|
if (hasCircuitBreaker) {
|
|
console.log("[BASELINE] circuitBreakerMaxTimeouts min:",
|
|
props.circuitBreakerMaxTimeouts.minimum);
|
|
console.log("[BASELINE] circuitBreakerCooldownMs min:",
|
|
props.circuitBreakerCooldownMs.minimum);
|
|
}
|
|
}
|
|
assert.ok(true, "baseline frozen: circuit breaker config");
|
|
});
|
|
|
|
it("12.06 - block mode currently available (blocking path exists)", () => {
|
|
// Active memory has a blocking mode that runs before agent reply
|
|
// This test freezes the fact that it exists (not whether it's enabled)
|
|
const pluginPath = join(ACTIVE_MEM_DIR, "openclaw.plugin.json");
|
|
if (existsSync(pluginPath)) {
|
|
const plugin = JSON.parse(readFileSync(pluginPath, "utf8"));
|
|
const promptStyle = plugin.configSchema?.properties?.promptStyle;
|
|
if (promptStyle) {
|
|
console.log("[BASELINE] promptStyle options:", promptStyle.enum?.join(", "));
|
|
assert.ok(promptStyle.enum.length >= 4, "must have multiple prompt styles");
|
|
}
|
|
}
|
|
assert.ok(true, "baseline frozen: active memory blocking behavior exists");
|
|
});
|
|
});
|