refactor: add memory event tools, update SDK types, CLI hooks, and provider config

This commit is contained in:
kartik-mem0
2026-04-06 13:53:42 +05:30
parent 458576dd0c
commit 87157c1fe7
14 changed files with 251 additions and 34 deletions
+6
View File
@@ -1,5 +1,6 @@
import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
import type { Mem0Config, Mem0Provider, AddOptions, SearchOptions } from "../types.ts";
import type { Backend } from "../backend/base.ts";
import { createMemorySearchTool } from "./memory-search.ts";
import { createMemoryAddTool } from "./memory-add.ts";
@@ -7,11 +8,14 @@ import { createMemoryGetTool } from "./memory-get.ts";
import { createMemoryListTool } from "./memory-list.ts";
import { createMemoryUpdateTool } from "./memory-update.ts";
import { createMemoryDeleteTool } from "./memory-delete.ts";
import { createMemoryEventListTool } from "./memory-event-list.ts";
import { createMemoryEventStatusTool } from "./memory-event-status.ts";
export interface ToolDeps {
api: OpenClawPluginApi;
provider: Mem0Provider;
cfg: Mem0Config;
backend?: Backend;
resolveUserId: (opts: { agentId?: string; userId?: string }) => string;
effectiveUserId: (sessionKey?: string) => string;
agentUserId: (id: string) => string;
@@ -31,4 +35,6 @@ export function registerAllTools(deps: ToolDeps): void {
api.registerTool(createMemoryListTool(deps));
api.registerTool(createMemoryUpdateTool(deps));
api.registerTool(createMemoryDeleteTool(deps));
api.registerTool(createMemoryEventListTool(deps));
api.registerTool(createMemoryEventStatusTool(deps));
}
+60
View File
@@ -0,0 +1,60 @@
import { Type } from "@sinclair/typebox";
import type { ToolDeps } from "./index.ts";
export function createMemoryEventListTool(deps: ToolDeps) {
return {
name: "memory_event_list",
label: "Memory Event List",
description:
"List recent background processing events from the Mem0 Platform. Use to check whether memory operations (add, update, delete) were processed successfully.",
parameters: Type.Object({}),
async execute(_toolCallId: string, _params: Record<string, unknown>) {
const start = Date.now();
try {
if (!deps.backend) {
deps.captureToolEvent("memory_event_list", { success: false, latency_ms: 0, error: "not_platform" });
return {
content: [{ type: "text", text: "Event tracking is only available in platform mode." }],
details: { error: "not_platform" },
};
}
const results = await deps.backend.listEvents();
if (!results.length) {
deps.captureToolEvent("memory_event_list", { success: true, latency_ms: Date.now() - start, count: 0 });
return {
content: [{ type: "text", text: "No events found." }],
details: { count: 0 },
};
}
const rows = results.map((ev) => {
const evId = String(ev.id ?? "");
const evType = String(ev.event_type ?? "—");
const status = String(ev.status ?? "—");
const latency =
typeof ev.latency === "number" ? `${Math.round(ev.latency as number)}ms` : "—";
const created = String(ev.created_at ?? "—").slice(0, 19).replace("T", " ");
return { id: evId, type: evType, status, latency, created };
});
const text = rows
.map((r) => `- ${r.id} | ${r.type} | ${r.status} | ${r.latency} | ${r.created}`)
.join("\n");
deps.captureToolEvent("memory_event_list", { success: true, latency_ms: Date.now() - start, count: results.length });
return {
content: [{ type: "text", text: `${results.length} event(s):\n${text}` }],
details: { count: results.length, events: rows },
};
} catch (err) {
deps.captureToolEvent("memory_event_list", { success: false, latency_ms: Date.now() - start, error: String(err) });
return {
content: [{ type: "text", text: `Failed to list events: ${String(err)}` }],
details: { error: String(err) },
};
}
},
};
}
+63
View File
@@ -0,0 +1,63 @@
import { Type } from "@sinclair/typebox";
import type { ToolDeps } from "./index.ts";
export function createMemoryEventStatusTool(deps: ToolDeps) {
return {
name: "memory_event_status",
label: "Memory Event Status",
description:
"Get detailed status of a specific background processing event. Use to verify whether a memory add/update/delete was processed, view latency, and inspect results.",
parameters: Type.Object({
event_id: Type.String({ description: "The event ID to check" }),
}),
async execute(_toolCallId: string, params: Record<string, unknown>) {
const { event_id: eventId } = params as { event_id: string };
const start = Date.now();
try {
if (!deps.backend) {
deps.captureToolEvent("memory_event_status", { success: false, latency_ms: 0, error: "not_platform" });
return {
content: [{ type: "text", text: "Event tracking is only available in platform mode." }],
details: { error: "not_platform" },
};
}
const ev = await deps.backend.getEvent(eventId);
const status = String(ev.status ?? "—");
const evType = String(ev.event_type ?? "—");
const latency =
typeof ev.latency === "number" ? `${Math.round(ev.latency as number)}ms` : "—";
const created = String(ev.created_at ?? "—").slice(0, 19).replace("T", " ");
const updated = String(ev.updated_at ?? "—").slice(0, 19).replace("T", " ");
let text = `Event: ${eventId}\nType: ${evType}\nStatus: ${status}\nLatency: ${latency}\nCreated: ${created}\nUpdated: ${updated}`;
const results = ev.results as Record<string, unknown>[] | undefined;
if (results && Array.isArray(results) && results.length) {
const resultLines = results.map((r) => {
const memId = String(r.id ?? "").slice(0, 8);
const data = r.data as Record<string, unknown> | undefined;
const memory = data?.memory ?? "";
const evName = String(r.event ?? "");
return `- [${evName}] ${memory} (${memId})`;
});
text += `\n\nResults (${results.length}):\n${resultLines.join("\n")}`;
}
deps.captureToolEvent("memory_event_status", { success: true, latency_ms: Date.now() - start });
return {
content: [{ type: "text", text }],
details: { event: ev },
};
} catch (err) {
deps.captureToolEvent("memory_event_status", { success: false, latency_ms: Date.now() - start, error: String(err) });
return {
content: [{ type: "text", text: `Failed to get event: ${String(err)}` }],
details: { error: String(err) },
};
}
},
};
}