perf: extract memory adapter registration helper

This commit is contained in:
Peter Steinberger
2026-04-06 22:04:03 +01:00
parent d806682f78
commit 4ae1599ea5
4 changed files with 56 additions and 70 deletions

View File

@@ -0,0 +1,40 @@
import { describe, expect, it } from "vitest";
import { filterUnregisteredMemoryEmbeddingProviderAdapters } from "./provider-adapter-registration.js";
describe("filterUnregisteredMemoryEmbeddingProviderAdapters", () => {
it("keeps builtin adapters that are not already registered", () => {
const adapters = filterUnregisteredMemoryEmbeddingProviderAdapters({
builtinAdapters: [
{ id: "local" },
{ id: "openai" },
{ id: "gemini" },
{ id: "voyage" },
{ id: "mistral" },
],
registeredAdapters: [],
});
expect(adapters.map((adapter) => adapter.id)).toEqual([
"local",
"openai",
"gemini",
"voyage",
"mistral",
]);
});
it("skips builtin adapters that are already registered", () => {
const adapters = filterUnregisteredMemoryEmbeddingProviderAdapters({
builtinAdapters: [
{ id: "local" },
{ id: "openai" },
{ id: "gemini" },
{ id: "voyage" },
{ id: "mistral" },
],
registeredAdapters: [{ id: "local" }, { id: "gemini" }],
});
expect(adapters.map((adapter) => adapter.id)).toEqual(["openai", "voyage", "mistral"]);
});
});

View File

@@ -0,0 +1,11 @@
type AdapterLike = {
id: string;
};
export function filterUnregisteredMemoryEmbeddingProviderAdapters<T extends AdapterLike>(params: {
builtinAdapters: readonly T[];
registeredAdapters: readonly AdapterLike[];
}): T[] {
const existingIds = new Set(params.registeredAdapters.map((adapter) => adapter.id));
return params.builtinAdapters.filter((adapter) => !existingIds.has(adapter.id));
}

View File

@@ -1,63 +0,0 @@
import type { MemoryEmbeddingProviderAdapter } from "openclaw/plugin-sdk/memory-core-host-engine-embeddings";
import { beforeEach, describe, expect, it, vi } from "vitest";
import { registerBuiltInMemoryEmbeddingProviders } from "./provider-adapters.js";
const mocks = vi.hoisted(() => ({
listRegisteredMemoryEmbeddingProviderAdapters: vi.fn<() => MemoryEmbeddingProviderAdapter[]>(
() => [],
),
listMemoryEmbeddingProviders: vi.fn(() => {
throw new Error("fallback capability loading should stay cold during memory-core register");
}),
}));
vi.mock("openclaw/plugin-sdk/memory-core-host-engine-embeddings", async () => {
const actual = await vi.importActual<
typeof import("openclaw/plugin-sdk/memory-core-host-engine-embeddings")
>("openclaw/plugin-sdk/memory-core-host-engine-embeddings");
return {
...actual,
listRegisteredMemoryEmbeddingProviderAdapters:
mocks.listRegisteredMemoryEmbeddingProviderAdapters,
listMemoryEmbeddingProviders: mocks.listMemoryEmbeddingProviders,
};
});
beforeEach(() => {
mocks.listRegisteredMemoryEmbeddingProviderAdapters.mockReset();
mocks.listRegisteredMemoryEmbeddingProviderAdapters.mockReturnValue([]);
mocks.listMemoryEmbeddingProviders.mockClear();
});
describe("registerBuiltInMemoryEmbeddingProviders", () => {
it("uses only already-registered providers when avoiding duplicates", () => {
const ids: string[] = [];
registerBuiltInMemoryEmbeddingProviders({
registerMemoryEmbeddingProvider(adapter) {
ids.push(adapter.id);
},
});
expect(ids).toEqual(["local", "openai", "gemini", "voyage", "mistral"]);
expect(mocks.listRegisteredMemoryEmbeddingProviderAdapters).toHaveBeenCalledTimes(1);
expect(mocks.listMemoryEmbeddingProviders).not.toHaveBeenCalled();
});
it("skips builtin adapters that are already registered in the current load", () => {
mocks.listRegisteredMemoryEmbeddingProviderAdapters.mockReturnValue([
{ id: "local", create: vi.fn() } as MemoryEmbeddingProviderAdapter,
{ id: "gemini", create: vi.fn() } as MemoryEmbeddingProviderAdapter,
]);
const ids: string[] = [];
registerBuiltInMemoryEmbeddingProviders({
registerMemoryEmbeddingProvider(adapter) {
ids.push(adapter.id);
},
});
expect(ids).toEqual(["openai", "voyage", "mistral"]);
expect(mocks.listMemoryEmbeddingProviders).not.toHaveBeenCalled();
});
});

View File

@@ -21,6 +21,7 @@ import {
} from "openclaw/plugin-sdk/memory-core-host-engine-embeddings";
import { resolveUserPath } from "openclaw/plugin-sdk/memory-core-host-engine-foundation";
import { getProviderEnvVars } from "openclaw/plugin-sdk/provider-env-vars";
import { filterUnregisteredMemoryEmbeddingProviderAdapters } from "./provider-adapter-registration.js";
export type BuiltinMemoryEmbeddingProviderDoctorMetadata = {
providerId: string;
@@ -337,13 +338,10 @@ export function registerBuiltInMemoryEmbeddingProviders(register: {
// Only inspect providers already registered in the current load. Falling back
// to capability discovery here can recursively trigger plugin loading while
// memory-core itself is still registering.
const existingIds = new Set(
listRegisteredMemoryEmbeddingProviderAdapters().map((adapter) => adapter.id),
);
for (const adapter of builtinMemoryEmbeddingProviderAdapters) {
if (existingIds.has(adapter.id)) {
continue;
}
for (const adapter of filterUnregisteredMemoryEmbeddingProviderAdapters({
builtinAdapters: builtinMemoryEmbeddingProviderAdapters,
registeredAdapters: listRegisteredMemoryEmbeddingProviderAdapters(),
})) {
register.registerMemoryEmbeddingProvider(adapter);
}
}