refactor: drop history subcommand memory_history tool, update platform email mapping, adjust tests

This commit is contained in:
kartik-mem0
2026-04-05 01:32:47 +05:30
parent 6f43487c34
commit 5c14b4c594
4 changed files with 14 additions and 168 deletions
+1 -2
View File
@@ -958,9 +958,8 @@ export function registerCliCommands(
auto_capture: "autoCapture",
top_k: "topK",
mode: "mode",
// Dot notation (matches Python CLI: platform.api_key, defaults.user_id)
"platform.api_key": "apiKey",
"platform.base_url": "baseUrl",
"platform.email": "userEmail",
"defaults.user_id": "userId",
"defaults.org_id": "orgId",
"defaults.project_id": "projectId",
-3
View File
@@ -34,9 +34,6 @@ Identify which memories need action. Use the tools to investigate.
**Search for recent additions:**
Call `memory_search` with a `created_at` filter to find memories added since the last consolidation. These are the most likely to need merging or cleanup.
**Check edit history on suspicious entries:**
If a memory looks like it was updated multiple times or has contradictory content, call `memory_history` on it to understand how it evolved.
**Classify each target into one of these actions:**
- DELETE: contains credentials, expired by TTL, pure noise, raw tool output, standalone timestamps
- MERGE: two or more memories express the same fact in different words, or a series tracks incremental changes to the same entity
+11 -47
View File
@@ -58,6 +58,8 @@ interface MockCommand {
_args: Array<{ name: string; desc: string }>;
command(name: string): MockCommand;
description(desc: string): MockCommand;
configureHelp(opts: any): MockCommand;
hook(event: string, fn: (...args: any[]) => any): MockCommand;
option(flags: string, desc: string, defaultVal?: string): MockCommand;
argument(name: string, desc: string): MockCommand;
action(fn: (...args: any[]) => any): MockCommand;
@@ -80,6 +82,12 @@ function createMockCommand(name: string): MockCommand {
cmd._description = desc;
return cmd;
},
configureHelp(_opts: any) {
return cmd;
},
hook(_event: string, _fn: (...args: any[]) => any) {
return cmd;
},
option(flags: string, desc: string, defaultVal?: string) {
cmd._options.push({ flags, desc, defaultVal });
return cmd;
@@ -284,7 +292,6 @@ describe("registerCliCommands", () => {
expect(names).toContain("list");
expect(names).toContain("update");
expect(names).toContain("delete");
expect(names).toContain("history");
expect(names).toContain("status");
expect(names).toContain("config");
expect(names).toContain("dream");
@@ -321,7 +328,6 @@ describe("registerCliCommands", () => {
expect(writePluginAuth).toHaveBeenCalledWith(
expect.objectContaining({
apiKey: "m0-my-key-1234",
baseUrl: "https://api.mem0.ai",
mode: "platform",
}),
);
@@ -857,48 +863,6 @@ describe("registerCliCommands", () => {
});
});
// ========================================================================
// history subcommand
// ========================================================================
describe("history subcommand", () => {
it("calls provider.history and prints entries as JSON", async () => {
const { mem0, provider } = setup();
const historyCmd = findCommand(mem0, "history")!;
await historyCmd._action!("m1");
expect(provider.history).toHaveBeenCalledWith("m1");
expect(consoleSpy.log).toHaveBeenCalledWith(
expect.stringContaining("UPDATE"),
);
});
it("prints message when no history found", async () => {
const { mem0, provider } = setup();
provider.history.mockResolvedValueOnce([]);
const historyCmd = findCommand(mem0, "history")!;
await historyCmd._action!("m1");
expect(consoleSpy.log).toHaveBeenCalledWith(
"No history found for this memory.",
);
});
it("handles history errors gracefully", async () => {
const { mem0, provider } = setup();
provider.history.mockRejectedValueOnce(new Error("history boom"));
const historyCmd = findCommand(mem0, "history")!;
await historyCmd._action!("m1");
expect(consoleSpy.error).toHaveBeenCalledWith(
expect.stringContaining("History failed"),
);
});
});
// ========================================================================
// status subcommand
// ========================================================================
@@ -965,7 +929,7 @@ describe("registerCliCommands", () => {
expect(allOutput).toContain("Key");
expect(allOutput).toContain("Value");
expect(allOutput).toContain("platform.api_key");
expect(allOutput).toContain("platform.base_url");
expect(allOutput).toContain("platform.email");
expect(allOutput).toContain("defaults.user_id");
expect(allOutput).toContain("Config file:");
});
@@ -1031,9 +995,9 @@ describe("registerCliCommands", () => {
const configCmd = findCommand(mem0, "config")!;
const getCmd = findCommand(configCmd, "get")!;
getCmd._action!("platform.base_url");
getCmd._action!("platform.email");
expect(consoleSpy.log).toHaveBeenCalledWith("https://api.mem0.ai");
expect(consoleSpy.log).toHaveBeenCalledWith("(not set)");
});
});
+2 -116
View File
@@ -15,7 +15,6 @@ import { createMemoryGetTool } from "../tools/memory-get.ts";
import { createMemoryDeleteTool } from "../tools/memory-delete.ts";
import { createMemoryListTool } from "../tools/memory-list.ts";
import { createMemoryUpdateTool } from "../tools/memory-update.ts";
import { createMemoryHistoryTool } from "../tools/memory-history.ts";
// ---------------------------------------------------------------------------
// Mock helper
@@ -80,10 +79,10 @@ function createMockToolDeps(overrides = {}): ToolDeps {
// ---------------------------------------------------------------------------
describe("registerAllTools", () => {
it("calls api.registerTool exactly 7 times", () => {
it("calls api.registerTool exactly 6 times", () => {
const ctx = createMockToolDeps();
registerAllTools(ctx);
expect(ctx.api.registerTool).toHaveBeenCalledTimes(7);
expect(ctx.api.registerTool).toHaveBeenCalledTimes(6);
});
it("registers tools with the correct names", () => {
@@ -103,7 +102,6 @@ describe("registerAllTools", () => {
"memory_list",
"memory_update",
"memory_delete",
"memory_history",
]);
});
@@ -883,115 +881,3 @@ describe("memory_update execute", () => {
});
});
// ---------------------------------------------------------------------------
// memory_history execute
// ---------------------------------------------------------------------------
describe("memory_history execute", () => {
it("returns formatted history", async () => {
const historyEntries = [
{
event: "ADD",
created_at: "2026-01-01T00:00:00Z",
old_memory: null,
new_memory: "Initial memory text",
},
{
event: "UPDATE",
created_at: "2026-01-02T00:00:00Z",
old_memory: "Initial memory text",
new_memory: "Updated memory text",
},
];
const ctx = createMockToolDeps({
provider: {
search: vi.fn(),
add: vi.fn(),
getAll: vi.fn(),
update: vi.fn(),
delete: vi.fn(),
get: vi.fn(),
history: vi.fn().mockResolvedValue(historyEntries),
},
});
const tool = createMemoryHistoryTool(ctx);
const result = await tool.execute("call-1", { memoryId: "mem-abc" });
expect(ctx.provider!.history).toHaveBeenCalledWith("mem-abc");
expect(result.content[0].text).toContain("History for memory mem-abc");
expect(result.content[0].text).toContain("2 entries");
expect(result.content[0].text).toContain("[ADD]");
expect(result.content[0].text).toContain("[UPDATE]");
expect(result.content[0].text).toContain("Initial memory text");
expect(result.content[0].text).toContain("Updated memory text");
expect(result.content[0].text).toContain("Old: (none)");
expect(result.details.count).toBe(2);
expect(result.details.history).toEqual(historyEntries);
});
it("handles empty history", async () => {
const ctx = createMockToolDeps({
provider: {
search: vi.fn(),
add: vi.fn(),
getAll: vi.fn(),
update: vi.fn(),
delete: vi.fn(),
get: vi.fn(),
history: vi.fn().mockResolvedValue([]),
},
});
const tool = createMemoryHistoryTool(ctx);
const result = await tool.execute("call-2", { memoryId: "mem-empty" });
expect(result.content[0].text).toBe(
"No history found for memory mem-empty.",
);
expect(result.details.count).toBe(0);
});
it("handles null history", async () => {
const ctx = createMockToolDeps({
provider: {
search: vi.fn(),
add: vi.fn(),
getAll: vi.fn(),
update: vi.fn(),
delete: vi.fn(),
get: vi.fn(),
history: vi.fn().mockResolvedValue(null),
},
});
const tool = createMemoryHistoryTool(ctx);
const result = await tool.execute("call-3", { memoryId: "mem-null" });
expect(result.content[0].text).toBe(
"No history found for memory mem-null.",
);
expect(result.details.count).toBe(0);
});
it("handles errors gracefully", async () => {
const ctx = createMockToolDeps({
provider: {
search: vi.fn(),
add: vi.fn(),
getAll: vi.fn(),
update: vi.fn(),
delete: vi.fn(),
get: vi.fn(),
history: vi.fn().mockRejectedValue(new Error("history unavailable")),
},
});
const tool = createMemoryHistoryTool(ctx);
const result = await tool.execute("call-4", { memoryId: "mem-err" });
expect(result.content[0].text).toContain("Memory history failed");
expect(result.content[0].text).toContain("history unavailable");
expect(result.details.error).toContain("history unavailable");
});
});