fix: update command on docs and logic (#4946)

This commit is contained in:
Kartik
2026-04-23 19:42:28 +05:30
committed by GitHub
parent 34ed122ef3
commit 2549a84e5c
10 changed files with 80 additions and 76 deletions
+24
View File
@@ -4,6 +4,30 @@ description: "Release notes for the OpenClaw plugin and agent harness."
mode: "wide"
---
<Update label="2026-04-23" description="v1.0.10">
**Security:**
- Telemetry `distinct_id` now uses SHA-256 instead of MD5 — prevents rainbow-table reversal of API key hashes
- User email is now SHA-256 hashed before sending as `distinct_id` — no PII in telemetry payloads
- Declared PostHog telemetry endpoint (`us.i.posthog.com`) in `providerEndpoints`
**Fixes:**
- Fixed version-pinned install records preventing plugin updates. `ensureInstallRecord()` now detects semver-pinned specs (e.g. `@mem0/openclaw-mem0@1.0.7`) and rewrites them to `@latest` or `clawhub:` prefix so `openclaw plugins update` resolves to the newest release
- Fixed `searchThreshold` default inconsistency: standardized to `0.3` across docs, README, and manifest
- `PLUGIN_VERSION` now injected at build time via tsup `define` from `package.json` — no more hardcoded version strings
**Manifest Compliance:**
- Removed non-spec fields: `requiredEnvVars`, `dataLocations`, `privacy`, `setup` (with `externalEndpoints`, `providers`, `requiresRuntime`, `postInstallHint`)
- Replaced `setup.externalEndpoints` with spec-compliant `providerEndpoints` using `endpointClass` + `hosts` format
- Env var declarations now rely solely on `providerAuthEnvVars` (already spec-compliant)
**Docs:**
- Fixed `openclaw plugins update` command: uses plugin ID (`openclaw-mem0`), not npm package name (`@mem0/openclaw-mem0`)
- Added update section to README
- Removed redundant "Key Features" and "Conclusion" sections from integration docs
</Update>
<Update label="2026-04-22" description="v1.0.9">
**Security & Compliance:**
+4 -16
View File
@@ -362,11 +362,9 @@ Everything inside `oss` is optional — defaults use OpenAI embeddings (`text-em
### Updating the Plugin
```bash
openclaw plugins update @mem0/openclaw-mem0
openclaw plugins update openclaw-mem0
```
<Note>Use the npm package name (`@mem0/openclaw-mem0`) for plugin management commands, not the plugin ID (`openclaw-mem0`).</Note>
### Checking Plugin Status
```bash
@@ -411,8 +409,9 @@ If the plugin installs but doesn't work:
If `openclaw plugins update` fails:
1. Use the full npm package name: `openclaw plugins update @mem0/openclaw-mem0`
2. If that fails, uninstall and reinstall:
1. Use the plugin ID: `openclaw plugins update openclaw-mem0`
2. Update all plugins at once: `openclaw plugins update --all`
3. If that fails, uninstall and reinstall:
```bash
openclaw plugins uninstall openclaw-mem0
openclaw plugins install @mem0/openclaw-mem0
@@ -476,17 +475,6 @@ export MEM0_TELEMETRY=false
The plugin injects memory-related instructions into the agent's system context via OpenClaw's `prependSystemContext` mechanism. This includes the memory triage protocol and recalled memories. This is the standard OpenClaw plugin SDK pattern for memory backends — no user-facing prompts are modified.
## Key Features
1. **Zero Configuration** — Auto-recall and auto-capture work out of the box with no prompting required
2. **Dual Memory Scopes** — Session-scoped short-term and user-scoped long-term memories
3. **Flexible Backend** — Use Mem0 Cloud for managed service or self-host with open-source mode
4. **Rich Tool Suite** — Eight agent tools for explicit memory operations when needed
## Conclusion
The `@mem0/openclaw-mem0` plugin gives OpenClaw agents persistent memory with minimal setup. Whether using Mem0 Cloud or self-hosting, your agents can now remember user preferences, facts, and context across sessions automatically.
<CardGroup cols={2}>
<Card title="OpenAI Agents SDK" icon="robot" href="/integrations/openai-agents-sdk">
Build agents with OpenAI's SDK and Mem0
+7 -1
View File
@@ -60,6 +60,12 @@ openclaw --version
> **Note:** OpenClaw memory plugins load through an exclusive slot, so install alone does not activate the plugin. You must set `plugins.slots.memory` as shown above.
### Updating the plugin to get the latest features and fixes:
```bash
openclaw plugins update openclaw-mem0
```
### Open-Source (Self-hosted)
No Mem0 key needed. Vectors are stored locally in SQLite at `~/.mem0/vector_store.db` — no external database required.
@@ -257,7 +263,7 @@ openclaw mem0 help --json # discover all comma
| `autoRecall` | `boolean` | `false` | Inject relevant memories before each turn |
| `autoCapture` | `boolean` | `false` | Extract and store facts after each turn |
| `topK` | `number` | `5` | Max memories returned per recall |
| `searchThreshold` | `number` | `0.5` | Minimum similarity score (0-1) |
| `searchThreshold` | `number` | `0.3` | Minimum similarity score (0-1) |
### Platform Mode
+6 -2
View File
@@ -141,10 +141,12 @@ export function ensureInstallRecord(): void {
const entry = full?.plugins?.entries?.[PLUGIN_ID];
const record = full?.plugins?.installs?.[PLUGIN_ID];
const allow = full?.plugins?.allow;
const specPinned = record?.spec && /\d+\.\d+\.\d+/.test(record.spec);
if (
entry?.enabled === true &&
record?.source &&
record?.spec &&
!specPinned &&
Array.isArray(allow) &&
allow.includes(PLUGIN_ID)
) {
@@ -171,8 +173,10 @@ export function ensureInstallRecord(): void {
record.source = "npm";
changed = true;
}
if (!record.spec) {
record.spec = `${NPM_PACKAGE}@latest`;
if (!record.spec || /\d+\.\d+\.\d+/.test(record.spec)) {
record.spec = record.source === "clawhub"
? `clawhub:${NPM_PACKAGE}`
: `${NPM_PACKAGE}@latest`;
changed = true;
}
if (!record.resolvedName) {
+17 -33
View File
@@ -2,7 +2,7 @@
"id": "openclaw-mem0",
"name": "Memory (Mem0)",
"description": "Mem0 memory backend for OpenClaw — platform (mem0.ai cloud) or self-hosted open-source. Auto-recall and auto-capture are opt-in (disabled by default). Supports OpenAI, Anthropic, Ollama (fully local), Qdrant, and PGVector providers.",
"version": "1.0.9",
"version": "1.0.10",
"kind": "memory",
"skills": ["skills"],
"commandAliases": [
@@ -103,8 +103,8 @@
},
"searchThreshold": {
"label": "Search Threshold",
"placeholder": "0.5",
"help": "Minimum similarity score for search results (0-1). Default: 0.5"
"placeholder": "0.3",
"help": "Minimum similarity score for search results (0-1). Default: 0.3"
},
"topK": {
"label": "Top K Results",
@@ -295,34 +295,18 @@
},
"required": []
},
"setup": {
"providers": [
{
"id": "mem0",
"authMethods": ["api-key"],
"envVars": ["MEM0_API_KEY"],
"description": "Platform mode: hosted memory at mem0.ai"
},
{
"id": "openclaw-mem0-oss",
"authMethods": ["api-key", "config"],
"envVars": ["OPENAI_API_KEY", "ANTHROPIC_API_KEY"],
"description": "Open-source mode: self-hosted with chosen LLM/embedder providers. No env vars needed when using Ollama (local)."
}
],
"requiresRuntime": false,
"postInstallHint": "Run 'openclaw mem0 init' to configure mode and credentials",
"externalEndpoints": [
{
"url": "https://api.mem0.ai",
"purpose": "Platform mode API — memory storage and retrieval",
"required": "platform mode only"
},
{
"url": "https://app.mem0.ai",
"purpose": "Account dashboard and API key management",
"required": "platform mode only"
}
]
}
"providerEndpoints": [
{
"endpointClass": "api",
"hosts": ["api.mem0.ai"]
},
{
"endpointClass": "dashboard",
"hosts": ["app.mem0.ai"]
},
{
"endpointClass": "telemetry",
"hosts": ["us.i.posthog.com"]
}
]
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@mem0/openclaw-mem0",
"version": "1.0.9",
"version": "1.0.10",
"type": "module",
"description": "Mem0 memory backend for OpenClaw — platform or self-hosted open-source",
"license": "Apache-2.0",
+12 -18
View File
@@ -11,7 +11,8 @@
import { createHash, randomUUID } from "node:crypto";
import { readPluginAuth, writePluginAuth, getBaseUrl, clearAnonymousTelemetryId } from "./cli/config-file.ts";
export const PLUGIN_VERSION = "1.0.7";
declare const __OPENCLAW_PLUGIN_VERSION__: string;
export const PLUGIN_VERSION: string = __OPENCLAW_PLUGIN_VERSION__;
const POSTHOG_API_KEY = "phc_hgJkUVJFYtmaJqrvf6CYN67TIQ8yhXAkWzUn9AMU4yX";
const POSTHOG_HOST = "https://us.i.posthog.com/i/v0/e/";
@@ -129,18 +130,11 @@ function maybeResolveEmail(apiKey: string): void {
} catch {
/* ignore */
}
// Upgrade any already-queued events from md5(apiKey) to email
const oldId = createHash("md5").update(apiKey).digest("hex");
const oldId = createHash("sha256").update(apiKey).digest("hex");
const newId = createHash("sha256").update(email).digest("hex");
for (const ev of eventQueue) {
if (ev.distinct_id === oldId) {
ev.distinct_id = email;
}
// Also upgrade $identify's distinct_id if present
if (
ev.event === "$identify" &&
ev.distinct_id === oldId
) {
ev.distinct_id = email;
ev.distinct_id = newId;
}
}
}
@@ -176,12 +170,14 @@ function isTelemetryEnabled(): boolean {
function getDistinctId(apiKey?: string): string {
try {
const auth = readPluginAuth();
if (auth.userEmail) return auth.userEmail;
if (auth.userEmail) {
return createHash("sha256").update(auth.userEmail).digest("hex");
}
} catch {
/* ignore */
}
if (apiKey) {
return createHash("md5").update(apiKey).digest("hex");
return createHash("sha256").update(apiKey).digest("hex");
}
return getOrCreateAnonymousId();
}
@@ -262,11 +258,9 @@ export function captureEvent(
try {
const distinctId = getDistinctId(ctx?.apiKey);
// If we resolved to md5(apiKey) instead of email, kick off a background
// /v1/ping/ to resolve and cache the email. The current event ships with
// the hash, but the async resolution upgrades any still-queued events
// (including this one) before the beforeExit flush fires.
if (ctx?.apiKey && distinctId && !distinctId.includes("@") && !distinctId.startsWith("openclaw-anon-")) {
let hasEmail = false;
try { hasEmail = !!readPluginAuth().userEmail; } catch { /* ignore */ }
if (ctx?.apiKey && !hasEmail && !distinctId.startsWith("openclaw-anon-")) {
maybeResolveEmail(ctx.apiKey);
}
+1 -5
View File
@@ -5,7 +5,7 @@ vi.mock("../cli/config-file.ts", () => ({
readPluginAuth: vi.fn().mockReturnValue({}),
}));
import { captureEvent, PLUGIN_VERSION } from "../telemetry.ts";
import { captureEvent } from "../telemetry.ts";
import { readPluginAuth } from "../cli/config-file.ts";
describe("telemetry", () => {
@@ -23,10 +23,6 @@ describe("telemetry", () => {
delete (globalThis as any).__mem0_telemetry_override;
});
it("exports PLUGIN_VERSION", () => {
expect(PLUGIN_VERSION).toBe("1.0.7");
});
it("captureEvent does not throw", () => {
expect(() => captureEvent("test_event")).not.toThrow();
});
+4
View File
@@ -1,4 +1,5 @@
import { defineConfig } from "tsup";
import pkg from "./package.json";
export default defineConfig({
entry: ["index.ts", "fs-safe.ts"],
@@ -8,4 +9,7 @@ export default defineConfig({
sourcemap: true,
clean: true,
external: [/^node:/, /^openclaw\//, "fs", "os", "path", "url", "readline", "module"],
define: {
__OPENCLAW_PLUGIN_VERSION__: JSON.stringify(pkg.version),
},
});
+4
View File
@@ -1,6 +1,10 @@
import { defineConfig } from "vitest/config";
import pkg from "./package.json";
export default defineConfig({
define: {
__OPENCLAW_PLUGIN_VERSION__: JSON.stringify(pkg.version),
},
test: {
alias: {
// OpenClaw SDK modules are resolved from the gateway at runtime.