Fix OpenClaw Mem0 custom categories payload (#5345)
Co-authored-by: Kartik <kartik.labhshetwar@mem0.ai>
This commit is contained in:
@@ -25,7 +25,11 @@ import type {
|
|||||||
AddOptions,
|
AddOptions,
|
||||||
SearchOptions,
|
SearchOptions,
|
||||||
} from "./types.ts";
|
} from "./types.ts";
|
||||||
import { createProvider, providerToBackend } from "./providers.ts";
|
import {
|
||||||
|
createProvider,
|
||||||
|
customCategoryMapToList,
|
||||||
|
providerToBackend,
|
||||||
|
} from "./providers.ts";
|
||||||
import { mem0ConfigSchema } from "./config.ts";
|
import { mem0ConfigSchema } from "./config.ts";
|
||||||
import type { FileConfig } from "./config.ts";
|
import type { FileConfig } from "./config.ts";
|
||||||
import { createPublicArtifactsProvider } from "./public-artifacts.ts";
|
import { createPublicArtifactsProvider } from "./public-artifacts.ts";
|
||||||
@@ -289,7 +293,8 @@ const memoryPlugin = definePluginEntry({
|
|||||||
if (runId) opts.run_id = runId;
|
if (runId) opts.run_id = runId;
|
||||||
// Pass customInstructions and customCategories to control what Mem0 extracts
|
// Pass customInstructions and customCategories to control what Mem0 extracts
|
||||||
if (cfg.customInstructions) opts.custom_instructions = cfg.customInstructions;
|
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;
|
return opts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,16 @@ import type {
|
|||||||
AddResult,
|
AddResult,
|
||||||
} from "./types.ts";
|
} 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
|
// Result Normalizers
|
||||||
// ============================================================================
|
// ============================================================================
|
||||||
|
|||||||
@@ -6,7 +6,11 @@
|
|||||||
*/
|
*/
|
||||||
import { describe, it, expect, vi, beforeEach } from "vitest";
|
import { describe, it, expect, vi, beforeEach } from "vitest";
|
||||||
|
|
||||||
import { providerToBackend } from "../providers.ts";
|
import {
|
||||||
|
createProvider,
|
||||||
|
customCategoryMapToList,
|
||||||
|
providerToBackend,
|
||||||
|
} from "../providers.ts";
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Mock provider factory
|
// Mock provider factory
|
||||||
@@ -37,6 +41,77 @@ beforeEach(() => {
|
|||||||
vi.resetAllMocks();
|
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
|
// search
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ export interface AddOptions {
|
|||||||
user_id: string;
|
user_id: string;
|
||||||
run_id?: string;
|
run_id?: string;
|
||||||
custom_instructions?: string;
|
custom_instructions?: string;
|
||||||
custom_categories?: Record<string, string>;
|
custom_categories?: Array<Record<string, string>>;
|
||||||
source?: string;
|
source?: string;
|
||||||
// Agentic harness additions
|
// Agentic harness additions
|
||||||
infer?: boolean;
|
infer?: boolean;
|
||||||
|
|||||||
Reference in New Issue
Block a user