Skip to content

Improve content extraction in auto-capture logic - #1

Open
abelkuruvilla wants to merge 1 commit into
serenichron:masterfrom
abelkuruvilla:patch-1
Open

Improve content extraction in auto-capture logic#1
abelkuruvilla wants to merge 1 commit into
serenichron:masterfrom
abelkuruvilla:patch-1

Conversation

@abelkuruvilla

Copy link
Copy Markdown

OpenClaw sometimes sends content as an array of blocks (e.g. [{ type: "text", text: "..." }]), so .trim() fails.

 OpenClaw sometimes sends content as an array of blocks (e.g. `[{ type: "text", text: "..." }]`), so `.trim()` fails.
@itmmy

itmmy commented Jun 29, 2026

Copy link
Copy Markdown

Local Testing Report & Additional Fix

Thanks for this PR @abelkuruvilla — the msg.content array handling is the right spot.

We deployed this plugin against a self-hosted Mem0 v2 instance (with Qwen3.5-4B LLM + Qwen3-Embedding-4B) and found two issues that need fixing for auto-capture to work end-to-end:

1. Content extraction (this PR — confirmed with improvement suggestion)

The .trim() crash on array content is correct. However, the content blocks follow OpenClaw's message format where text lives under block.text. A more robust approach:

function extractText(content: any): string {
  if (typeof content === "string") return content;
  if (Array.isArray(content)) {
    return content
      .filter((block: any) => block.type === "text")
      .map((block: any) => block.text || "")
      .join("\n");
  }
  return "";
}

This helper should also be applied to the before_agent_start hook where event.prompt may have the same shape.

2. API format mismatch in add() method (new finding — not in this PR)

The add() method currently sends:

{ "content": "...", "user_id": "...", "metadata": { "agent_id": "..." } }

But Mem0 v2 REST API expects:

{ "messages": [{ "role": "user", "content": "..." }], "user_id": "...", "agent_id": "...", "infer": true }

The "messages" field is required per the OpenAPI schema — without it the API returns 422 Unprocessable Entity. The error is caught and silently swallowed, so no memory is ever stored.

The AddResponse interface also needs updating to match Mem0 v2's response shape:

interface AddResponse {
  results: Array<{
    id: string;
    memory: string;
    event: string;
  }>;
}

Testing result

After applying both fixes locally, auto-capture works correctly with infer: true. The Mem0 LLM successfully extracts structured facts from conversation, e.g.:

"User works at 中交资管 (China Communications Construction Asset Management) as a data architect"

Memories are persisted to PostgreSQL via pgvector as expected. Both fixes have been tested end-to-end with auto-recall and auto-capture flows.

Recommendation

Consider merging this PR with the extractText() helper added, and fix the add() API format separately for Mem0 v2 compatibility.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants