Explorar o código

Refine logging and copy latest hook

Lukas Goldschmidt hai 1 mes
pai
achega
b627bee1d2
Modificáronse 2 ficheiros con 59 adicións e 40 borrados
  1. 1 1
      README.md
  2. 58 39
      hook/handler.ts

+ 1 - 1
README.md

@@ -67,7 +67,7 @@ All options are read from environment variables (prefixed `MEM0_`) or a JSON fil
 
 ## Testing & troubleshooting
 
-- Logs are prefixed with `[mem0-...]` (e.g., `[mem0-auto-capture]`, `[mem0-auto-recall]`, `[mem0-stt]`). If something silently fails, check `/tmp/openclaw/...` logs for those tags.
+- Logs flow through a single helper and now print as `[mem0] <tag> {...}` (e.g., `[mem0] auto-recall-query`, `[mem0] auto-capture`, `[mem0] auto-recall-injection`). Filter on the `tag` to track capture/recall steps in `/tmp/openclaw/...` logs.
 - Use `openclaw hooks simulate message` (or your own integration tests) to feed the hook a fake event and watch the HTTP calls.
 - If the hook can’t reach Mem0, the recall/capture branches simply log errors and continue; the agent still runs but without those enhancements.
 

+ 58 - 39
hook/handler.ts

@@ -63,6 +63,20 @@ function loadPluginCfg() {
   };
 }
 
+// ---------------------------------------------------------------------------
+// Logging helpers
+// ---------------------------------------------------------------------------
+type LogLevel = "log" | "warn" | "error";
+
+function logHook(tag: string, detail: Record<string, unknown>, level: LogLevel = "log") {
+  const payload = { tag, ...detail };
+  try {
+    console[level](`[mem0] ${tag}`, JSON.stringify(payload));
+  } catch {
+    console[level](`[mem0] ${tag}`, payload);
+  }
+}
+
 // ---------------------------------------------------------------------------
 // Types
 // ---------------------------------------------------------------------------
@@ -251,7 +265,7 @@ async function mem0SearchMemories(
     const res = await fetch(`${baseUrl}/memories/search`, {
       method: "POST",
       headers: { "Content-Type": "application/json" },
-      body: JSON.stringify({ query, userId }),
+      body: JSON.stringify({ query, userId, limit }),
     });
     if (!res.ok) {
       console.error(`[mem0-recall] /memories/search returned ${res.status}`);
@@ -275,7 +289,7 @@ async function mem0SearchKnowledge(
     const res = await fetch(`${baseUrl}/knowledge/search`, {
       method: "POST",
       headers: { "Content-Type": "application/json" },
-      body: JSON.stringify({ query, userId: knowledgeUserId }),
+      body: JSON.stringify({ query, userId: knowledgeUserId, limit }),
     });
     if (!res.ok) {
       console.error(`[mem0-recall] /knowledge/search returned ${res.status}`);
@@ -395,24 +409,17 @@ const CAPTURE_DEDUP_MS = 60_000;
 // Main handler
 // ---------------------------------------------------------------------------
 export default async function handler(event: HookEvent) {
-  console.log(
-    "[mem0-FIRE]",
-    JSON.stringify(
-      {
-        type: event.type,
-        action: event.action,
-        sessionKey: event.sessionKey,
-        contextKeys: Object.keys(event.context || {}),
-        content: event.context?.content?.slice(0, 80),
-        messagesLen: event.messages?.length,
-      },
-      null,
-      2
-    )
-  );
+  logHook("fire", {
+    type: event.type,
+    action: event.action,
+    sessionKey: event.sessionKey,
+    contextKeys: Object.keys(event.context || {}),
+    content: event.context?.content?.slice(0, 80),
+    messagesLen: event.messages?.length,
+  });
 
   if (event.type !== "message") {
-    console.log("[mem0-FIRE] bailed: type is not message, got:", event.type);
+    logHook("fire-bail", { type: event.type, sessionKey: event.sessionKey }, "warn");
     return;
   }
 
@@ -480,7 +487,11 @@ export default async function handler(event: HookEvent) {
 
     const { baseUrl, recallLimit, rerankThreshold } = pluginCfg;
 
-    console.log("[mem0-auto-recall] query:", text.slice(0, 120));
+    logHook("auto-recall-query", {
+      sessionKey: event.sessionKey,
+      userId,
+      query: text.slice(0, 120),
+    });
 
     const personalResults = await mem0SearchMemories(
       baseUrl,
@@ -489,9 +500,10 @@ export default async function handler(event: HookEvent) {
       recallLimit
     );
 
-    console.log("[mem0-auto-recall]", {
+    logHook("auto-recall-result", {
+      sessionKey: event.sessionKey,
       userId,
-      personalCount: personalResults?.length ?? "error",
+      personalCount: personalResults?.length ?? 0,
       threshold: rerankThreshold,
     });
 
@@ -501,10 +513,20 @@ export default async function handler(event: HookEvent) {
       rerankThreshold
     );
 
-    if (!injectionBlock) return; // nothing passed the threshold from either endpoint
+    if (!injectionBlock) {
+      logHook("auto-recall-injection-skip", {
+        sessionKey: event.sessionKey,
+        userId,
+      });
+      return; // nothing passed the threshold from either endpoint
+    }
 
     event.context.bodyForAgent = `${text}\n\n${injectionBlock}`;
-    console.log("[mem0-injected-prompt]\n" + event.context.bodyForAgent);
+    logHook("auto-recall-injection", {
+      sessionKey: event.sessionKey,
+      userId,
+      snippet: injectionBlock.slice(0, 200),
+    });
   };
 
   // ── received: capture ────────────────────────────────────────────────────
@@ -544,29 +566,26 @@ export default async function handler(event: HookEvent) {
     const hash = simpleHash(JSON.stringify(captureMessages));
     const lastCapture = recentlyCaptured.get(hash);
     if (lastCapture && Date.now() - lastCapture < CAPTURE_DEDUP_MS) {
-      console.log("[mem0-auto-capture] skipped duplicate");
+      logHook("auto-capture-duplicate", {
+        sessionKey: event.sessionKey,
+        userId,
+      });
       return;
     }
     recentlyCaptured.set(hash, Date.now());
 
     try {
+      const captureDetail: Record<string, unknown> = {
+        sessionKey: event.sessionKey,
+        userId,
+        captureTrigger,
+        hasAssistantMessage: !!assistantMessage,
+        messageCount: captureMessages.length,
+      };
       if (pluginCfg.debugCapture) {
-        console.log("[mem0-auto-capture]", {
-          sessionKey: event.sessionKey,
-          userId,
-          captureTrigger,
-          hasAssistantMessage: !!assistantMessage,
-          messages: captureMessages,
-        });
-      } else {
-        console.log("[mem0-auto-capture]", {
-          sessionKey: event.sessionKey,
-          userId,
-          captureTrigger,
-          hasAssistantMessage: !!assistantMessage,
-          messageCount: captureMessages.length,
-        });
+        captureDetail.messages = captureMessages;
       }
+      logHook("auto-capture", captureDetail);
       await fetch(`${pluginCfg.baseUrl}/memories`, {
         method: "POST",
         headers: { "Content-Type": "application/json" },