From 40dd08a0a6eb2c5e85fc665abfd173bba40e4f92 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Wed, 15 Jul 2026 01:52:20 -0700 Subject: [PATCH] refactor(context-engine): trim internal registry exports (#108179) * refactor(context-engine): trim internal registry exports * chore(deadcode): refresh export baseline --- scripts/deadcode-exports.baseline.mjs | 4 -- .../shared/context-engine-host-compat.test.ts | 2 - src/context-engine/context-engine.test.ts | 60 +++++++------------ src/context-engine/quarantine-health.test.ts | 12 ++-- src/context-engine/registry.test-support.ts | 18 ++++++ src/context-engine/registry.ts | 14 +---- .../server-methods/server-methods.test.ts | 6 +- src/plugins/loader.activation.test-utils.ts | 4 +- src/plugins/loader.registration.test-utils.ts | 5 +- .../status-plugin-health.runtime.test.ts | 4 +- 10 files changed, 58 insertions(+), 71 deletions(-) create mode 100644 src/context-engine/registry.test-support.ts diff --git a/scripts/deadcode-exports.baseline.mjs b/scripts/deadcode-exports.baseline.mjs index 78c46dd3c907..19855c5e2c3a 100644 --- a/scripts/deadcode-exports.baseline.mjs +++ b/scripts/deadcode-exports.baseline.mjs @@ -188,10 +188,6 @@ export const KNIP_UNUSED_EXPORT_BASELINE = [ "src/commitments/runtime.ts: resetCommitmentExtractionRuntimeForTests", "src/commitments/store.ts: loadCommitmentStore", "src/commitments/store.ts: saveCommitmentStore", - "src/context-engine/registry.ts: clearContextEngineRuntimeQuarantine", - "src/context-engine/registry.ts: ContextEngineRegistrationResult", - "src/context-engine/registry.ts: getContextEngineFactory", - "src/context-engine/registry.ts: listContextEngineIds", "src/cron/isolated-agent/delivery-dispatch.ts: getCompletedDirectCronDeliveriesCountForTests", "src/cron/isolated-agent/delivery-dispatch.ts: resetCompletedDirectCronDeliveriesForTests", "src/cron/schedule.ts: clearCronScheduleCacheForTest", diff --git a/src/commands/doctor/shared/context-engine-host-compat.test.ts b/src/commands/doctor/shared/context-engine-host-compat.test.ts index c0199ff09b45..66cc0fb96d84 100644 --- a/src/commands/doctor/shared/context-engine-host-compat.test.ts +++ b/src/commands/doctor/shared/context-engine-host-compat.test.ts @@ -2,7 +2,6 @@ import { describe, expect, it, vi } from "vitest"; import type { OpenClawConfig } from "../../../config/types.openclaw.js"; import { - getContextEngineFactory, getContextEngineRegistration, registerContextEngine, registerContextEngineForOwner, @@ -108,7 +107,6 @@ describe("doctor context-engine host compatibility", () => { factory, lifecycle: "readOnlyDiscovery", }); - expect(getContextEngineFactory(id)).toBeUndefined(); }); it("evaluates native Codex and OpenClaw agent-run hosts", async () => { diff --git a/src/context-engine/context-engine.test.ts b/src/context-engine/context-engine.test.ts index 3b1d82c03791..c26e87ebf6e6 100644 --- a/src/context-engine/context-engine.test.ts +++ b/src/context-engine/context-engine.test.ts @@ -17,18 +17,13 @@ import { registerLegacyContextEngine } from "./legacy.registration.js"; import { registerContextEngine, registerContextEngineForOwner, - clearContextEngineRuntimeQuarantine, - getContextEngineFactory, + getContextEngineRegistration, listContextEngineQuarantines, - listContextEngineIds, resolveContextEngine, resolveContextEngineOwnerPluginId, } from "./registry.js"; -import type { - ContextEngineFactory, - ContextEngineFactoryContext, - ContextEngineRegistrationResult, -} from "./registry.js"; +import type { ContextEngineFactory, ContextEngineFactoryContext } from "./registry.js"; +import { resetContextEngineRuntimeQuarantineForTests } from "./registry.test-support.js"; import type { ContextEngine, ContextEngineInfo, @@ -568,10 +563,7 @@ describe("Engine contract tests", () => { const factory = () => new MockContextEngine(); registerContextEngine("mock", factory); - const resolved = getContextEngineFactory("mock"); - expect(resolved).toBe(factory); - - const engine = await resolved!({}); + const engine = await resolveContextEngine(configWithSlot("mock")); expect(engine).toBeInstanceOf(MockContextEngine); expect(engine.info.id).toBe("mock"); }); @@ -751,19 +743,15 @@ describe("Registry tests", () => { const factory = () => new MockContextEngine(); registerContextEngine("reg-test-2", factory); - const retrieved = getContextEngineFactory("reg-test-2"); - expect(retrieved).toBe(factory); + expect(getContextEngineRegistration("reg-test-2")?.factory).toBe(factory); }); - it("listContextEngineIds() returns all registered ids", () => { - // Ensure at least our test entries exist + it("tracks all registered ids", () => { registerContextEngine("reg-test-a", () => new MockContextEngine()); registerContextEngine("reg-test-b", () => new MockContextEngine()); - const ids = listContextEngineIds(); - expect(ids).toContain("reg-test-a"); - expect(ids).toContain("reg-test-b"); - expect(Array.isArray(ids)).toBe(true); + expect(getContextEngineRegistration("reg-test-a")).toBeDefined(); + expect(getContextEngineRegistration("reg-test-b")).toBeDefined(); }); it("registering the same id with the same owner refreshes the factory", () => { @@ -775,15 +763,15 @@ describe("Registry tests", () => { allowSameOwnerRefresh: true, }), ).toEqual({ ok: true }); - expect(getContextEngineFactory("reg-overwrite")).toBe(factory1); + expect(getContextEngineRegistration("reg-overwrite")?.factory).toBe(factory1); expect( registerContextEngineForOwner("reg-overwrite", factory2, "owner-a", { allowSameOwnerRefresh: true, }), ).toEqual({ ok: true }); - expect(getContextEngineFactory("reg-overwrite")).toBe(factory2); - expect(getContextEngineFactory("reg-overwrite")).not.toBe(factory1); + expect(getContextEngineRegistration("reg-overwrite")?.factory).toBe(factory2); + expect(getContextEngineRegistration("reg-overwrite")?.factory).not.toBe(factory1); }); it("rejects context engine registrations from a different owner", () => { @@ -799,7 +787,7 @@ describe("Registry tests", () => { ok: false, existingOwner: "owner-a", }); - expect(getContextEngineFactory("reg-owner-guard")).toBe(factory1); + expect(getContextEngineRegistration("reg-owner-guard")?.factory).toBe(factory1); }); it("exposes the trusted plugin owner for a resolved registered engine", async () => { @@ -826,14 +814,14 @@ describe("Registry tests", () => { id: string, factory: ContextEngineFactory, opts?: { owner?: string }, - ) => ContextEngineRegistrationResult + ) => ReturnType )("public-owner-guard", () => new MockContextEngine(), { owner: "owner-a" }); expect(spoofAttempt).toEqual({ ok: false, existingOwner: "owner-a", }); - expect(getContextEngineFactory("public-owner-guard")).toBe(ownedFactory); + expect(getContextEngineRegistration("public-owner-guard")?.factory).toBe(ownedFactory); }); it("public registerContextEngine reserves the default legacy id", () => { @@ -842,7 +830,7 @@ describe("Registry tests", () => { id: string, factory: ContextEngineFactory, opts?: { owner?: string }, - ) => ContextEngineRegistrationResult + ) => ReturnType )("legacy", () => new MockContextEngine(), { owner: "core" }); expect(legacyAttempt).toEqual({ @@ -859,7 +847,7 @@ describe("Registry tests", () => { describe("Legacy sessionKey compatibility", () => { beforeEach(() => { registerLegacyContextEngine(); - clearContextEngineRuntimeQuarantine(); + resetContextEngineRuntimeQuarantineForTests(); vi.spyOn(console, "error").mockImplementation(() => {}); }); @@ -1175,7 +1163,7 @@ describe("Factory context passing", () => { describe("Read-only plugin discovery registrations", () => { beforeEach(() => { registerLegacyContextEngine(); - clearContextEngineRuntimeQuarantine(); + resetContextEngineRuntimeQuarantineForTests(); vi.spyOn(console, "warn").mockImplementation(() => {}); }); @@ -1261,7 +1249,7 @@ describe("Read-only plugin discovery registrations", () => { describe("Invalid engine fallback", () => { beforeEach(() => { registerLegacyContextEngine(); - clearContextEngineRuntimeQuarantine(); + resetContextEngineRuntimeQuarantineForTests(); vi.spyOn(console, "error").mockImplementation(() => {}); }); @@ -1902,8 +1890,7 @@ describe("Initialization guard", () => { expect(ensureContextEnginesInitialized()).toBeUndefined(); expect(ensureContextEnginesInitialized()).toBeUndefined(); - const ids = listContextEngineIds(); - expect(ids).toContain("legacy"); + expect(getContextEngineRegistration("legacy")).toBeDefined(); }); }); @@ -1927,8 +1914,7 @@ describe("Bundle chunk isolation (#40096)", () => { const chunks = [ { registerContextEngine, - getContextEngineFactory, - listContextEngineIds, + getContextEngineRegistration, resolveContextEngine, }, dynamicChunk, @@ -1949,8 +1935,7 @@ describe("Bundle chunk isolation (#40096)", () => { }); chunks[0].registerContextEngine(engineId, factory); - expect(chunks[1].getContextEngineFactory(engineId)).toBe(factory); - expect(chunks[1].listContextEngineIds()).toContain(engineId); + expect(chunks[1].getContextEngineRegistration(engineId)?.factory).toBe(factory); const engine = await chunks[1].resolveContextEngine(configWithSlot(engineId)); expect(engine.info.id).toBe(engineId); @@ -1963,9 +1948,8 @@ describe("Bundle chunk isolation (#40096)", () => { ); await Promise.all(registrationTasks); - const allIds = chunks[0].listContextEngineIds(); for (const id of ids) { - expect(allIds).toContain(id); + expect(chunks[0].getContextEngineRegistration(id)).toBeDefined(); } }); }); diff --git a/src/context-engine/quarantine-health.test.ts b/src/context-engine/quarantine-health.test.ts index b899167e847d..8d842ca266ae 100644 --- a/src/context-engine/quarantine-health.test.ts +++ b/src/context-engine/quarantine-health.test.ts @@ -13,11 +13,11 @@ import { recordPersistedContextEngineQuarantine, } from "./quarantine-health.js"; import { - clearContextEngineRuntimeQuarantine, clearContextEnginesForOwner, listContextEngineQuarantines, registerContextEngineForOwner, } from "./registry.js"; +import { resetContextEngineRuntimeQuarantineForTests } from "./registry.test-support.js"; const CONTEXT_ENGINE_QUARANTINE_OWNER_ID = "core:context-engine-quarantine-health"; const CONTEXT_ENGINE_QUARANTINE_NAMESPACE = "runtime-quarantines"; @@ -83,7 +83,7 @@ afterEach(() => { describe("context engine quarantine health", () => { it("lists persisted runtime quarantines when local process state is empty", async () => { await withStateDirEnv("openclaw-context-engine-quarantine-", async () => { - clearContextEngineRuntimeQuarantine(); + resetContextEngineRuntimeQuarantineForTests(); recordPersistedContextEngineQuarantine({ engineId: "lossless-claw", owner: "plugin:lossless-claw", @@ -169,7 +169,7 @@ describe("context engine quarantine health", () => { processStartTime: getProcessStartTime(siblingProcessId), }); - clearContextEngineRuntimeQuarantine(); + resetContextEngineRuntimeQuarantineForTests(); expect(listContextEngineQuarantines()).toEqual([ { @@ -187,7 +187,7 @@ describe("context engine quarantine health", () => { it("drops records from a previous incarnation of this PID", async () => { await withStateDirEnv("openclaw-context-engine-quarantine-incarnation-", async () => { - clearContextEngineRuntimeQuarantine(); + resetContextEngineRuntimeQuarantineForTests(); seedPersistedContextEngineQuarantineForTest({ engineId: "lossless-claw", owner: "plugin:lossless-claw", @@ -206,7 +206,7 @@ describe("context engine quarantine health", () => { async () => { await withStateDirEnv("openclaw-context-engine-quarantine-pid-reuse-", async () => { await withLiveSiblingProcess(async (siblingProcessId) => { - clearContextEngineRuntimeQuarantine(); + resetContextEngineRuntimeQuarantineForTests(); const siblingStartTime = getProcessStartTime(siblingProcessId); seedSiblingQuarantineForTest({ engineId: "lossless-claw", @@ -227,7 +227,7 @@ describe("context engine quarantine health", () => { it("drops sibling records whose process identity cannot be verified", async () => { await withStateDirEnv("openclaw-context-engine-quarantine-unverified-", async () => { await withLiveSiblingProcess(async (siblingProcessId) => { - clearContextEngineRuntimeQuarantine(); + resetContextEngineRuntimeQuarantineForTests(); // A null recorded start time (non-Linux recorder or /proc read failure) // must fail closed instead of trusting bare PID liveness. seedSiblingQuarantineForTest({ diff --git a/src/context-engine/registry.test-support.ts b/src/context-engine/registry.test-support.ts new file mode 100644 index 000000000000..be3ae8383274 --- /dev/null +++ b/src/context-engine/registry.test-support.ts @@ -0,0 +1,18 @@ +import { resolveGlobalSingleton } from "../shared/global-singleton.js"; +import { clearPersistedContextEngineQuarantineForProcess } from "./quarantine-health.js"; + +type ContextEngineRegistryStateForTests = { + engines: Map; + quarantinedEngines: Map; +}; + +const CONTEXT_ENGINE_REGISTRY_STATE = Symbol.for("openclaw.contextEngineRegistryState"); + +export function resetContextEngineRuntimeQuarantineForTests(): void { + const state = resolveGlobalSingleton( + CONTEXT_ENGINE_REGISTRY_STATE, + () => ({ engines: new Map(), quarantinedEngines: new Map() }), + ); + state.quarantinedEngines.clear(); + clearPersistedContextEngineQuarantineForProcess(undefined, process.pid); +} diff --git a/src/context-engine/registry.ts b/src/context-engine/registry.ts index 0aef3ac5d195..3b4798f7496d 100644 --- a/src/context-engine/registry.ts +++ b/src/context-engine/registry.ts @@ -45,7 +45,7 @@ export type ContextEngineFactoryContext = { export type ContextEngineFactory = ( ctx: ContextEngineFactoryContext, ) => ContextEngine | Promise; -export type ContextEngineRegistrationResult = { ok: true } | { ok: false; existingOwner: string }; +type ContextEngineRegistrationResult = { ok: true } | { ok: false; existingOwner: string }; type ContextEngineRegistrationLifecycle = "runtime" | "readOnlyDiscovery"; type ContextEngineRegistration = { factory: ContextEngineFactory; @@ -518,7 +518,7 @@ export function listContextEngineQuarantines(): ContextEngineRuntimeQuarantine[] return quarantines; } -export function clearContextEngineRuntimeQuarantine(engineId?: string): void { +function clearContextEngineRuntimeQuarantine(engineId?: string): void { const quarantinedEngines = getContextEngineRegistryState().quarantinedEngines; if (engineId === undefined) { quarantinedEngines.clear(); @@ -581,14 +581,6 @@ export function registerContextEngine( return registerContextEngineForOwner(id, factory, PUBLIC_CONTEXT_ENGINE_OWNER); } -/** - * Return the factory for a registered engine, or undefined. - */ -export function getContextEngineFactory(id: string): ContextEngineFactory | undefined { - const registration = getContextEngineRegistration(id); - return registration?.lifecycle === "runtime" ? registration.factory : undefined; -} - /** Returns registration metadata so callers can distinguish discovery snapshots from runtime entries. */ export function getContextEngineRegistration(id: string): ContextEngineRegistration | undefined { return getContextEngineRegistryState().engines.get(id); @@ -597,7 +589,7 @@ export function getContextEngineRegistration(id: string): ContextEngineRegistrat /** * List all registered engine ids. */ -export function listContextEngineIds(): string[] { +function listContextEngineIds(): string[] { return [...getContextEngineRegistryState().engines.keys()]; } diff --git a/src/gateway/server-methods/server-methods.test.ts b/src/gateway/server-methods/server-methods.test.ts index e19fd838931c..b2ff6d836654 100644 --- a/src/gateway/server-methods/server-methods.test.ts +++ b/src/gateway/server-methods/server-methods.test.ts @@ -16,11 +16,11 @@ import { HEARTBEAT_PROMPT } from "../../auto-reply/heartbeat.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; import { registerLegacyContextEngine } from "../../context-engine/legacy.registration.js"; import { - clearContextEngineRuntimeQuarantine, clearContextEnginesForOwner, registerContextEngineForOwner, resolveContextEngine, } from "../../context-engine/registry.js"; +import { resetContextEngineRuntimeQuarantineForTests } from "../../context-engine/registry.test-support.js"; import { emitAgentEvent } from "../../infra/agent-events.js"; import { formatZonedTimestamp } from "../../infra/format-time/format-datetime.js"; import { @@ -4864,14 +4864,14 @@ describe("gateway healthHandlers.health cache freshness", () => { pricingState.clearGatewayModelPricingFailures(); registerLegacyContextEngine(); clearContextEnginesForOwner(contextEngineTestOwner); - clearContextEngineRuntimeQuarantine(); + resetContextEngineRuntimeQuarantineForTests(); }); afterEach(() => { pricingState.replaceGatewayModelPricingCache(new Map(), 0); pricingState.clearGatewayModelPricingFailures(); clearContextEnginesForOwner(contextEngineTestOwner); - clearContextEngineRuntimeQuarantine(); + resetContextEngineRuntimeQuarantineForTests(); }); it("refreshes cached health when runtime channel lifecycle has changed", async () => { diff --git a/src/plugins/loader.activation.test-utils.ts b/src/plugins/loader.activation.test-utils.ts index 994ff99b1153..3b980315a36f 100644 --- a/src/plugins/loader.activation.test-utils.ts +++ b/src/plugins/loader.activation.test-utils.ts @@ -2,7 +2,7 @@ import fs from "node:fs"; import path from "node:path"; import { afterAll, afterEach, describe, expect, it } from "vitest"; -import { listContextEngineIds } from "../context-engine/registry.js"; +import { getContextEngineRegistration } from "../context-engine/registry.js"; import { withEnv } from "../test-utils/env.js"; import { getCompactionProvider } from "./compaction-provider.js"; import { writePersistedInstalledPluginIndexInstallRecordsSync } from "./installed-plugin-index-records.js"; @@ -572,7 +572,7 @@ describe("loadOpenClawPlugins", () => { pluginId: "context-engine-malformed", message: "context engine registration missing id", }); - expect(listContextEngineIds()).not.toContain("broken-context"); + expect(getContextEngineRegistration("broken-context")).toBeUndefined(); }, }, { diff --git a/src/plugins/loader.registration.test-utils.ts b/src/plugins/loader.registration.test-utils.ts index 763d275027ed..df4e058de09b 100644 --- a/src/plugins/loader.registration.test-utils.ts +++ b/src/plugins/loader.registration.test-utils.ts @@ -2,7 +2,7 @@ import fs from "node:fs"; import path from "node:path"; import { afterAll, afterEach, describe, expect, it } from "vitest"; -import { getContextEngineFactory, listContextEngineIds } from "../context-engine/registry.js"; +import { getContextEngineRegistration } from "../context-engine/registry.js"; import { clearInternalHooks, createInternalHookEvent, @@ -248,8 +248,7 @@ describe("loadOpenClawPlugins", () => { expect(registry.securityAuditCollectors).toStrictEqual([]); expect(registry.interactiveHandlers).toStrictEqual([]); expect(resolvePluginInteractiveNamespaceMatch("slack", "failme:payload")).toBeNull(); - expect(getContextEngineFactory("failme-context")).toBeUndefined(); - expect(listContextEngineIds()).not.toContain("failme-context"); + expect(getContextEngineRegistration("failme-context")).toBeUndefined(); const event = createInternalHookEvent("gateway", "startup", "gateway:startup"); await triggerInternalHook(event); diff --git a/src/status/status-plugin-health.runtime.test.ts b/src/status/status-plugin-health.runtime.test.ts index a8164e7e6fc5..60c9969aa204 100644 --- a/src/status/status-plugin-health.runtime.test.ts +++ b/src/status/status-plugin-health.runtime.test.ts @@ -4,7 +4,7 @@ import { afterEach, describe, expect, it, vi } from "vitest"; import { recordPersistedRuntimeToolSchemaQuarantine } from "../agents/tool-schema-quarantine-health.js"; import { resolveReadOnlyChannelPluginsForConfig } from "../channels/plugins/read-only.js"; import { recordPersistedContextEngineQuarantine } from "../context-engine/quarantine-health.js"; -import { clearContextEngineRuntimeQuarantine } from "../context-engine/registry.js"; +import { resetContextEngineRuntimeQuarantineForTests } from "../context-engine/registry.test-support.js"; import { createCorePluginStateSyncKeyedStore, resetPluginStateStoreForTests, @@ -67,7 +67,7 @@ function seedPersistedToolQuarantineForTest(record: { describe("runtime plugin health snapshot", () => { it("includes persisted context-engine quarantines", async () => { await withStateDirEnv("openclaw-status-plugin-health-", async () => { - clearContextEngineRuntimeQuarantine(); + resetContextEngineRuntimeQuarantineForTests(); recordPersistedContextEngineQuarantine({ engineId: "lossless-claw", owner: "plugin:lossless-claw",