Fix OpenClaw Mem0 custom categories payload (#5345)

Co-authored-by: Kartik <kartik.labhshetwar@mem0.ai>
This commit is contained in:
mjzcng
2026-06-12 22:18:53 +08:00
committed by GitHub
parent f48b133101
commit 821152bd14
4 changed files with 94 additions and 4 deletions
+7 -2
View File
@@ -25,7 +25,11 @@ import type {
AddOptions,
SearchOptions,
} from "./types.ts";
import { createProvider, providerToBackend } from "./providers.ts";
import {
createProvider,
customCategoryMapToList,
providerToBackend,
} from "./providers.ts";
import { mem0ConfigSchema } from "./config.ts";
import type { FileConfig } from "./config.ts";
import { createPublicArtifactsProvider } from "./public-artifacts.ts";
@@ -289,7 +293,8 @@ const memoryPlugin = definePluginEntry({
if (runId) opts.run_id = runId;
// Pass customInstructions and customCategories to control what Mem0 extracts
if (cfg.customInstructions) opts.custom_instructions = cfg.customInstructions;
if (cfg.customCategories) opts.custom_categories = cfg.customCategories;
const customCategories = customCategoryMapToList(cfg.customCategories);
if (customCategories) opts.custom_categories = customCategories;
return opts;
}
+10
View File
@@ -13,6 +13,16 @@ import type {
AddResult,
} from "./types.ts";
export function customCategoryMapToList(
categories?: Record<string, string>,
): Array<Record<string, string>> | undefined {
if (!categories || typeof categories !== "object") return undefined;
const items = Object.entries(categories).map(([name, description]) => ({
[name]: description,
}));
return items.length ? items : undefined;
}
// ============================================================================
// Result Normalizers
// ============================================================================
+76 -1
View File
@@ -6,7 +6,11 @@
*/
import { describe, it, expect, vi, beforeEach } from "vitest";
import { providerToBackend } from "../providers.ts";
import {
createProvider,
customCategoryMapToList,
providerToBackend,
} from "../providers.ts";
// ---------------------------------------------------------------------------
// Mock provider factory
@@ -37,6 +41,77 @@ beforeEach(() => {
vi.resetAllMocks();
});
// ---------------------------------------------------------------------------
// customCategoryMapToList
// ---------------------------------------------------------------------------
describe("customCategoryMapToList", () => {
it("converts category maps to the Mem0 SDK list shape", () => {
expect(
customCategoryMapToList({
preference: "User preferences",
work: "Work context",
}),
).toEqual([
{ preference: "User preferences" },
{ work: "Work context" },
]);
});
it("returns undefined for empty or missing category maps", () => {
expect(customCategoryMapToList()).toBeUndefined();
expect(customCategoryMapToList({})).toBeUndefined();
});
});
// ---------------------------------------------------------------------------
// PlatformProvider
// ---------------------------------------------------------------------------
describe("PlatformProvider", () => {
it("passes custom_categories as a list to the Mem0 SDK", async () => {
let addOptions: Record<string, unknown> | undefined;
vi.doMock("mem0ai", () => ({
default: class MockMemoryClient {
async add(_messages: unknown, opts: Record<string, unknown>) {
addOptions = opts;
return { results: [] };
}
},
}));
const provider = createProvider(
{
mode: "platform",
apiKey: "test-key",
userId: "test-user",
autoCapture: true,
autoRecall: true,
customInstructions: "Store durable facts.",
customCategories: {},
searchThreshold: 0.1,
topK: 5,
},
{ resolvePath: (p: string) => p } as any,
);
await provider.add([{ role: "user", content: "Remember this" }], {
user_id: "test-user",
custom_categories: customCategoryMapToList({
preference: "User preferences",
}),
source: "OPENCLAW",
});
expect(addOptions?.customCategories).toEqual([
{ preference: "User preferences" },
]);
vi.doUnmock("mem0ai");
});
});
// ---------------------------------------------------------------------------
// search
// ---------------------------------------------------------------------------
+1 -1
View File
@@ -36,7 +36,7 @@ export interface AddOptions {
user_id: string;
run_id?: string;
custom_instructions?: string;
custom_categories?: Record<string, string>;
custom_categories?: Array<Record<string, string>>;
source?: string;
// Agentic harness additions
infer?: boolean;