refactor: update MemoryClient to support snake_case filter keys and separate filters

This commit is contained in:
kartik-mem0
2026-04-14 02:54:21 +05:30
parent de6f9abc6c
commit 133625bbc6
5 changed files with 26 additions and 15 deletions
+15 -4
View File
@@ -257,10 +257,11 @@ export default class MemoryClient {
if (this.telemetryId === "") await this.ping();
const payloadKeys = Object.keys(options || {});
this._captureEvent("get_all", [payloadKeys]);
const { page, pageSize, ...rest } = options ?? {};
const { page, pageSize, filters, ...rest } = options ?? {};
const body: Record<string, any> = {
output_format: "v1.1",
...camelToSnakeKeys(rest),
...(filters && { filters }),
};
let url = `${this.host}/v2/memories/`;
@@ -283,10 +284,12 @@ export default class MemoryClient {
if (this.telemetryId === "") await this.ping();
const payloadKeys = Object.keys(options || {});
this._captureEvent("search", [payloadKeys]);
const { filters, ...rest } = options ?? {};
const payload: Record<string, any> = {
query,
output_format: "v1.1",
...camelToSnakeKeys(options ?? {}),
...camelToSnakeKeys(rest),
...(filters && { filters }),
};
const response = await this._fetchWithErrorHandling(
@@ -612,12 +615,16 @@ export default class MemoryClient {
throw new Error("Missing filters or schema");
}
const { filters, ...rest } = data;
const response = await this._fetchWithErrorHandling(
`${this.host}/v1/exports/`,
{
method: "POST",
headers: this.headers,
body: JSON.stringify(camelToSnakeKeys(data)),
body: JSON.stringify({
...camelToSnakeKeys(rest),
filters,
}),
},
);
@@ -634,12 +641,16 @@ export default class MemoryClient {
throw new Error("Missing memoryExportId or filters");
}
const { filters, ...rest } = data;
const response = await this._fetchWithErrorHandling(
`${this.host}/v1/exports/get/`,
{
method: "POST",
headers: this.headers,
body: JSON.stringify(camelToSnakeKeys(data)),
body: JSON.stringify({
...camelToSnakeKeys(rest),
...(filters && { filters }),
}),
},
);
return response;
@@ -117,7 +117,7 @@ describeIntegration("MemoryClient Integration — CRUD", () => {
describe("get all memories", () => {
test("returns all memories for test user", async () => {
const memories = await client.getAll({
filters: { userId: TEST_USER_ID },
filters: { user_id: TEST_USER_ID },
});
expect(Array.isArray(memories)).toBe(true);
@@ -131,7 +131,7 @@ describeIntegration("MemoryClient Integration — CRUD", () => {
test("returns paginated results with page and page_size", async () => {
const page1 = await client.getAll({
filters: { userId: TEST_USER_ID },
filters: { user_id: TEST_USER_ID },
page: 1,
pageSize: 1,
});
@@ -195,7 +195,7 @@ describeIntegration("MemoryClient Integration — CRUD", () => {
test("getAll for non-existent user returns empty array", async () => {
const memories = await client.getAll({
filters: { userId: `nonexistent-user-${randomUUID()}` },
filters: { user_id: `nonexistent-user-${randomUUID()}` },
});
expect(Array.isArray(memories)).toBe(true);
@@ -64,7 +64,7 @@ export async function waitForMemories(
): Promise<Memory[]> {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
const memories = await withRetry(() =>
client.getAll({ filters: { userId } }),
client.getAll({ filters: { user_id: userId } }),
);
if (Array.isArray(memories) && memories.length >= minCount) {
return memories;
@@ -43,7 +43,7 @@ describeIntegration("MemoryClient Integration — Search & History", () => {
const results = await waitForSearchResults(
client,
"What is my favorite color?",
{ filters: { userId: TEST_USER_ID } },
{ filters: { user_id: TEST_USER_ID } },
);
expect(Array.isArray(results)).toBe(true);
@@ -64,7 +64,7 @@ describeIntegration("MemoryClient Integration — Search & History", () => {
client,
"What do you know about me?",
{
filters: { OR: [{ userId: TEST_USER_ID }] },
filters: { OR: [{ user_id: TEST_USER_ID }] },
},
);
@@ -120,7 +120,7 @@ describeIntegration("MemoryClient Integration — Search & History", () => {
const response = await client.search(
"Tell me about integration test user",
{
filters: { userId: TEST_USER_ID },
filters: { user_id: TEST_USER_ID },
topK: 1,
},
);
@@ -25,7 +25,7 @@ describe("MemoryClient - search()", () => {
const client = new MemoryClient({ apiKey: TEST_API_KEY });
await client.search("What is my name?", {
filters: { userId: "u1" },
filters: { user_id: "u1" },
});
expect(findFetchCall(mock, "/v3/memories/search/", "POST")).toBeDefined();
@@ -41,7 +41,7 @@ describe("MemoryClient - search()", () => {
const client = new MemoryClient({ apiKey: TEST_API_KEY });
await client.search("What is my name?", {
filters: { userId: "u1" },
filters: { user_id: "u1" },
});
const call = findFetchCall(mock, "/v3/memories/search/", "POST");
@@ -57,7 +57,7 @@ describe("MemoryClient - search()", () => {
const mock = setupMockFetch(extra);
const client = new MemoryClient({ apiKey: TEST_API_KEY });
await client.search("test", { filters: { userId: "u1" } });
await client.search("test", { filters: { user_id: "u1" } });
const call = findFetchCall(mock, "/v3/memories/search/", "POST");
expect(getFetchBody(call!).filters).toEqual({ user_id: "u1" });
@@ -106,7 +106,7 @@ describe("MemoryClient - search()", () => {
const client = new MemoryClient({ apiKey: TEST_API_KEY });
const result = await client.search("nonexistent query", {
filters: { userId: "u1" },
filters: { user_id: "u1" },
});
expect(result.results).toHaveLength(0);
});