refactor(plugin-sdk): inject memory local service per call

This commit is contained in:
Vincent Koc
2026-07-12 06:33:57 +08:00
committed by Vincent Koc
parent eae846e3e5
commit c1e70b9a7f
5 changed files with 77 additions and 31 deletions
-1
View File
@@ -17,7 +17,6 @@ export { checkQmdBinaryAvailability } from "openclaw/plugin-sdk/memory-core-host
export { hasConfiguredMemorySecretInput } from "openclaw/plugin-sdk/memory-core-host-secret";
export { auditDreamingArtifacts, repairDreamingArtifacts } from "./src/dreaming-repair.js";
export { configureMemoryCoreDreamingState } from "./src/dreaming-state.js";
export { configureMemoryCoreEmbeddingLocalService } from "./src/memory/embedding-local-service.js";
export {
auditShortTermPromotionArtifacts,
loadShortTermPromotionDreamingStats,
@@ -4,7 +4,6 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
const loadBundledPluginPublicSurfaceModuleSync = vi.hoisted(() => vi.fn());
const configureMemoryCoreEmbeddingLocalServiceImpl = vi.hoisted(() => vi.fn());
const configureMemoryCoreDreamingStateImpl = vi.hoisted(() => vi.fn());
const createEmbeddingProviderImpl = vi.hoisted(() => vi.fn());
const removeGroundedShortTermCandidatesImpl = vi.hoisted(() => vi.fn());
@@ -25,7 +24,6 @@ vi.mock("./facade-loader.js", async () => {
describe("plugin-sdk memory-core bundled runtime", () => {
beforeEach(() => {
configureMemoryCoreEmbeddingLocalServiceImpl.mockReset();
configureMemoryCoreDreamingStateImpl.mockReset();
createEmbeddingProviderImpl.mockReset().mockResolvedValue({ provider: { id: "openai" } });
removeGroundedShortTermCandidatesImpl.mockReset().mockResolvedValue({ removed: 1 });
@@ -40,7 +38,6 @@ describe("plugin-sdk memory-core bundled runtime", () => {
.mockImplementation(({ artifactBasename }) => {
if (artifactBasename === "runtime-api.js") {
return {
configureMemoryCoreEmbeddingLocalService: configureMemoryCoreEmbeddingLocalServiceImpl,
configureMemoryCoreDreamingState: configureMemoryCoreDreamingStateImpl,
createEmbeddingProvider: createEmbeddingProviderImpl,
removeGroundedShortTermCandidates: removeGroundedShortTermCandidatesImpl,
@@ -71,7 +68,9 @@ describe("plugin-sdk memory-core bundled runtime", () => {
artifactBasename: "runtime-api.js",
});
expect(configureMemoryCoreDreamingStateImpl).toHaveBeenCalledWith(expect.any(Function));
expect(configureMemoryCoreEmbeddingLocalServiceImpl).toHaveBeenCalledWith(expect.any(Function));
expect(createEmbeddingProviderImpl).toHaveBeenCalledWith({
acquireLocalService: expect.any(Function),
});
});
it("delegates doctor and embedding helpers through the bundled public surfaces", async () => {
+11 -10
View File
@@ -21,9 +21,6 @@ type EmbeddingProviderResult = {
};
type RuntimeFacadeModule = {
configureMemoryCoreEmbeddingLocalService: (
acquireLocalService: ReturnType<typeof createConfiguredProviderLocalServiceAcquirer>,
) => void;
configureMemoryCoreDreamingState: (
openKeyedStore: <T>(options: OpenKeyedStoreOptions) => PluginStateKeyedStore<T>,
) => void;
@@ -237,17 +234,21 @@ function loadRuntimeFacadeModule(): RuntimeFacadeModule {
module.configureMemoryCoreDreamingState(<T>(options: OpenKeyedStoreOptions) =>
createPluginStateKeyedStore<T>("memory-core", options),
);
module.configureMemoryCoreEmbeddingLocalService(
createConfiguredProviderLocalServiceAcquirer(getRuntimeConfig),
);
return module;
}
const acquireLocalService = createConfiguredProviderLocalServiceAcquirer(getRuntimeConfig);
/** Create a memory embedding provider with built-in fallback metadata. */
export const createEmbeddingProvider: RuntimeFacadeModule["createEmbeddingProvider"] = ((...args) =>
loadRuntimeFacadeModule().createEmbeddingProvider(
...args,
)) as RuntimeFacadeModule["createEmbeddingProvider"];
export const createEmbeddingProvider: RuntimeFacadeModule["createEmbeddingProvider"] = ((
options,
) => {
const createOptions = {
...options,
acquireLocalService,
};
return loadRuntimeFacadeModule().createEmbeddingProvider(createOptions);
}) as RuntimeFacadeModule["createEmbeddingProvider"];
/** Remove short-term recall candidates already grounded into durable memory. */
export const removeGroundedShortTermCandidates: RuntimeFacadeModule["removeGroundedShortTermCandidates"] =
@@ -1,10 +1,34 @@
/**
* Tests memory core engine runtime facade behavior.
*/
import { describe, expect, it } from "vitest";
import { beforeEach, describe, expect, it, vi } from "vitest";
import type { ShortTermAuditIssue } from "./memory-core-engine-runtime.js";
const loadActivatedBundledPluginPublicSurfaceModuleSync = vi.hoisted(() => vi.fn());
const getMemorySearchManagerImpl = vi.hoisted(() => vi.fn(async () => ({ manager: null })));
const getMemoryIndexManagerImpl = vi.hoisted(() => vi.fn(async () => null));
vi.mock("./facade-runtime.js", async () => {
const actual = await vi.importActual<typeof import("./facade-runtime.js")>("./facade-runtime.js");
return {
...actual,
loadActivatedBundledPluginPublicSurfaceModuleSync,
};
});
describe("memory-core engine runtime SDK facade", () => {
beforeEach(() => {
getMemorySearchManagerImpl.mockClear();
getMemoryIndexManagerImpl.mockClear();
loadActivatedBundledPluginPublicSurfaceModuleSync.mockReset().mockReturnValue({
configureMemoryCoreDreamingState: vi.fn(),
getMemorySearchManager: getMemorySearchManagerImpl,
MemoryIndexManager: {
get: getMemoryIndexManagerImpl,
},
});
});
it("exposes the short-term recall overflow audit code", () => {
const issue = {
severity: "warn",
@@ -15,4 +39,23 @@ describe("memory-core engine runtime SDK facade", () => {
expect(issue.code).toBe("recall-store-over-limit");
});
it("injects local-service acquisition into manager facade calls", async () => {
const runtime = await import("./memory-core-engine-runtime.js");
const params = { cfg: {}, agentId: "main" } as never;
await runtime.getMemorySearchManager(params);
await runtime.MemoryIndexManager.get(params);
expect(getMemorySearchManagerImpl).toHaveBeenCalledWith({
cfg: {},
agentId: "main",
acquireLocalService: expect.any(Function),
});
expect(getMemoryIndexManagerImpl).toHaveBeenCalledWith({
cfg: {},
agentId: "main",
acquireLocalService: expect.any(Function),
});
});
});
+19 -15
View File
@@ -6,10 +6,7 @@ import { createConfiguredProviderLocalServiceAcquirer } from "../agents/provider
import { getRuntimeConfig } from "../config/config.js";
import type { OpenClawConfig } from "../config/types.js";
import { createPluginStateKeyedStore } from "../plugin-state/plugin-state-store.js";
import {
createLazyFacadeObjectValue,
loadActivatedBundledPluginPublicSurfaceModuleSync,
} from "./facade-runtime.js";
import { loadActivatedBundledPluginPublicSurfaceModuleSync } from "./facade-runtime.js";
import type { MemorySearchManager } from "./memory-core-host-engine-storage.js";
import type { OpenKeyedStoreOptions, PluginStateKeyedStore } from "./plugin-state-runtime.js";
@@ -114,9 +111,6 @@ type MemoryIndexManagerFacade = {
};
type FacadeModule = {
configureMemoryCoreEmbeddingLocalService: (
acquireLocalService: ReturnType<typeof createConfiguredProviderLocalServiceAcquirer>,
) => void;
configureMemoryCoreDreamingState: (
openKeyedStore: <T>(options: OpenKeyedStoreOptions) => PluginStateKeyedStore<T>,
) => void;
@@ -161,11 +155,10 @@ function loadFacadeModule(): FacadeModule {
module.configureMemoryCoreDreamingState(<T>(options: OpenKeyedStoreOptions) =>
createPluginStateKeyedStore<T>("memory-core", options),
);
module.configureMemoryCoreEmbeddingLocalService(
createConfiguredProviderLocalServiceAcquirer(getRuntimeConfig),
);
return module;
}
const acquireLocalService = createConfiguredProviderLocalServiceAcquirer(getRuntimeConfig);
/** Audit short-term promotion artifacts in an agent workspace. */
export const auditShortTermPromotionArtifacts: FacadeModule["auditShortTermPromotionArtifacts"] = ((
...args
@@ -183,8 +176,13 @@ export const getBuiltinMemoryEmbeddingProviderDoctorMetadata: FacadeModule["getB
...args,
)) as FacadeModule["getBuiltinMemoryEmbeddingProviderDoctorMetadata"];
/** Resolve the active memory search manager and any runtime availability error. */
export const getMemorySearchManager: FacadeModule["getMemorySearchManager"] = ((...args) =>
loadFacadeModule()["getMemorySearchManager"](...args)) as FacadeModule["getMemorySearchManager"];
export const getMemorySearchManager: FacadeModule["getMemorySearchManager"] = ((params) => {
const managerParams = {
...params,
acquireLocalService,
};
return loadFacadeModule()["getMemorySearchManager"](managerParams);
}) as FacadeModule["getMemorySearchManager"];
/** List built-in memory embedding providers eligible for automatic selection. */
export const listBuiltinAutoSelectMemoryEmbeddingProviderDoctorMetadata: FacadeModule["listBuiltinAutoSelectMemoryEmbeddingProviderDoctorMetadata"] =
((...args) =>
@@ -192,9 +190,15 @@ export const listBuiltinAutoSelectMemoryEmbeddingProviderDoctorMetadata: FacadeM
...args,
)) as FacadeModule["listBuiltinAutoSelectMemoryEmbeddingProviderDoctorMetadata"];
/** Lazy memory index manager facade used by status and runtime callers. */
export const MemoryIndexManager: FacadeModule["MemoryIndexManager"] = createLazyFacadeObjectValue(
() => loadFacadeModule()["MemoryIndexManager"] as object,
) as FacadeModule["MemoryIndexManager"];
export const MemoryIndexManager: FacadeModule["MemoryIndexManager"] = {
async get(params) {
const managerParams = {
...params,
acquireLocalService,
};
return await loadFacadeModule()["MemoryIndexManager"].get(managerParams);
},
};
/** Repair invalid recall-store entries and stale short-term promotion locks. */
export const repairShortTermPromotionArtifacts: FacadeModule["repairShortTermPromotionArtifacts"] =
((...args) =>