From 094cf15a43c1f147bd7324e53d2e6f9453c77d21 Mon Sep 17 00:00:00 2001 From: Mahesh Sanikommu Date: Thu, 7 May 2026 16:32:05 -0700 Subject: [PATCH 1/2] fix: plugin packaging and status capture --- .github/workflows/publish.yml | 2 +- client.ts | 15 ++++++++++++--- commands/slash.ts | 7 ++++++- package.json | 14 +++++++++++--- tools/store.ts | 13 ++++++++++++- 5 files changed, 42 insertions(+), 9 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 93ebcca..509494c 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -58,7 +58,7 @@ jobs: - name: Build if: steps.version-check.outputs.changed == 'true' - run: bun run build:lib + run: bun run build:plugin - name: Publish if: steps.version-check.outputs.changed == 'true' diff --git a/client.ts b/client.ts index fbb71a4..f2050b2 100644 --- a/client.ts +++ b/client.ts @@ -58,7 +58,7 @@ export class SupermemoryClient { customId?: string, containerTag?: string, entityContext?: string, - ): Promise<{ id: string }> { + ): Promise<{ id: string; status: string }> { const cleaned = sanitizeContent(content) const tag = containerTag ?? this.containerTag @@ -81,8 +81,17 @@ export class SupermemoryClient { ...(clampedCtx && { entityContext: clampedCtx }), }) - log.debugResponse("add", { id: result.id }) - return { id: result.id } + log.debugResponse("add", { id: result.id, status: result.status }) + + if (result.status === "failed") { + log.warn( + `add returned status="failed" for id=${result.id}` + + (customId ? ` customId=${customId}` : "") + + ` (contentLength=${cleaned.length}, containerTag=${tag})`, + ) + } + + return { id: result.id, status: result.status } } async search( diff --git a/commands/slash.ts b/commands/slash.ts index ff7e74f..a7df83b 100644 --- a/commands/slash.ts +++ b/commands/slash.ts @@ -52,7 +52,7 @@ export function registerCommands( try { const category = detectCategory(text) const sk = getSessionKey() - await client.addMemory( + const { status } = await client.addMemory( text, { type: category, source: "openclaw_command" }, sk ? buildDocumentId(sk) : undefined, @@ -61,6 +61,11 @@ export function registerCommands( ) const preview = text.length > 60 ? `${text.slice(0, 60)}…` : text + if (status === "failed") { + return { + text: `Memory store failed (server returned status="failed") for: "${preview}"`, + } + } return { text: `Remembered: "${preview}"` } } catch (err) { log.error("/remember failed", err) diff --git a/package.json b/package.json index 4e1dcbc..895c256 100644 --- a/package.json +++ b/package.json @@ -1,9 +1,15 @@ { "name": "@supermemory/openclaw-supermemory", - "version": "2.1.11", + "version": "2.1.12", "type": "module", "description": "OpenClaw Supermemory memory plugin", "license": "MIT", + "files": [ + "dist", + "openclaw.plugin.json", + "README.md", + "types" + ], "dependencies": { "supermemory": "^4.0.0", "@sinclair/typebox": "0.34.47" @@ -12,14 +18,16 @@ "check-types": "tsc --noEmit", "lint": "bunx @biomejs/biome ci .", "lint:fix": "bunx @biomejs/biome check --write .", - "build:lib": "esbuild lib/validate.ts --bundle --minify --format=esm --platform=node --target=es2022 --external:node:crypto --outfile=lib/validate.js" + "build:plugin": "esbuild index.ts --bundle --format=esm --platform=node --target=es2022 --external:openclaw --external:openclaw/* --external:supermemory --external:@sinclair/typebox --outfile=dist/index.js", + "build": "bun run build:plugin", + "prepack": "bun run build" }, "peerDependencies": { "openclaw": ">=2026.2.17" }, "openclaw": { "extensions": [ - "./index.ts" + "./dist/index.js" ] }, "repository": { diff --git a/tools/store.ts b/tools/store.ts index 4c688ae..75eaf20 100644 --- a/tools/store.ts +++ b/tools/store.ts @@ -44,7 +44,7 @@ export function registerStoreTool( `store tool: category="${category}" customId="${customId}" containerTag="${params.containerTag ?? "default"}"`, ) - await client.addMemory( + const { status } = await client.addMemory( params.text, { type: category, source: "openclaw_tool" }, customId, @@ -55,6 +55,17 @@ export function registerStoreTool( const preview = params.text.length > 80 ? `${params.text.slice(0, 80)}…` : params.text + if (status === "failed") { + return { + content: [ + { + type: "text" as const, + text: `Memory store failed (server returned status="failed") for: "${preview}"`, + }, + ], + } + } + return { content: [{ type: "text" as const, text: `Stored: "${preview}"` }], } From 40b2f47037af012d277afc544de014d05ff5a3b8 Mon Sep 17 00:00:00 2001 From: Mahesh Sanikommu Date: Fri, 22 May 2026 13:57:54 -0700 Subject: [PATCH 2/2] feat: sm_source attribution and kebab tool names Stamp openclaw source on API calls, register kebab tool aliases, add sm_capture_mode on store. Bump to 2.1.13. --- client.ts | 20 +++++++++++++++++--- index.ts | 4 ++++ package.json | 2 +- tools/forget.ts | 5 +++-- tools/profile.ts | 5 +++-- tools/search.ts | 5 +++-- tools/store.ts | 7 ++++--- 7 files changed, 35 insertions(+), 13 deletions(-) diff --git a/client.ts b/client.ts index f2050b2..4ea93c4 100644 --- a/client.ts +++ b/client.ts @@ -47,7 +47,12 @@ export class SupermemoryClient { log.warn(`container tag warning: ${tagCheck.reason}`) } - this.client = new Supermemory({ apiKey }) + // `x-sm-source` is read by mono's API to attribute searches and + // writes to the OpenClaw plugin in PostHog / `document.source`. + this.client = new Supermemory({ + apiKey, + defaultHeaders: { "x-sm-source": "openclaw" }, + }) this.containerTag = containerTag log.info(`initialized (container: ${containerTag})`) } @@ -62,10 +67,19 @@ export class SupermemoryClient { const cleaned = sanitizeContent(content) const tag = containerTag ?? this.containerTag + // Always stamp `sm_source` so mono's `document.source` column attributes + // these writes to the OpenClaw plugin. Existing callers can still pass + // extra metadata (e.g. `source: "openclaw_tool"`) and it is preserved + // underneath the canonical `sm_source` key. + const mergedMetadata: Record = { + sm_source: "openclaw", + ...(metadata ?? {}), + } + log.debugRequest("add", { contentLength: cleaned.length, customId, - metadata, + metadata: mergedMetadata, containerTag: tag, }) @@ -76,7 +90,7 @@ export class SupermemoryClient { const result = await this.client.add({ content: cleaned, containerTag: tag, - ...(metadata && { metadata }), + metadata: mergedMetadata, ...(customId && { customId }), ...(clampedCtx && { entityContext: clampedCtx }), }) diff --git a/index.ts b/index.ts index d7e79e7..5594502 100644 --- a/index.ts +++ b/index.ts @@ -77,6 +77,10 @@ export default { registerStoreTool(api, client, cfg, getSessionKey) registerForgetTool(api, client, cfg) registerProfileTool(api, client, cfg) + registerSearchTool(api, client, cfg, "supermemory-search") + registerStoreTool(api, client, cfg, getSessionKey, "supermemory-save") + registerForgetTool(api, client, cfg, "supermemory-forget") + registerProfileTool(api, client, cfg, "supermemory-profile") if (cfg.autoRecall) { api.on("before_prompt_build", buildRecallHandler(client, cfg)) diff --git a/package.json b/package.json index 895c256..25f4e4d 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@supermemory/openclaw-supermemory", - "version": "2.1.12", + "version": "2.1.13", "type": "module", "description": "OpenClaw Supermemory memory plugin", "license": "MIT", diff --git a/tools/forget.ts b/tools/forget.ts index 6225bc1..23064e3 100644 --- a/tools/forget.ts +++ b/tools/forget.ts @@ -8,10 +8,11 @@ export function registerForgetTool( api: OpenClawPluginApi, client: SupermemoryClient, _cfg: SupermemoryConfig, + toolName = "supermemory_forget", ): void { api.registerTool( { - name: "supermemory_forget", + name: toolName, label: "Memory Forget", description: "Forget/delete a specific memory. Searches for the closest match and removes it.", @@ -66,6 +67,6 @@ export function registerForgetTool( } }, }, - { name: "supermemory_forget" }, + { name: toolName }, ) } diff --git a/tools/profile.ts b/tools/profile.ts index 8d5f00d..68f230c 100644 --- a/tools/profile.ts +++ b/tools/profile.ts @@ -8,10 +8,11 @@ export function registerProfileTool( api: OpenClawPluginApi, client: SupermemoryClient, _cfg: SupermemoryConfig, + toolName = "supermemory_profile", ): void { api.registerTool( { - name: "supermemory_profile", + name: toolName, label: "User Profile", description: "Get a summary of what is known about the user — stable preferences and recent context.", @@ -77,6 +78,6 @@ export function registerProfileTool( } }, }, - { name: "supermemory_profile" }, + { name: toolName }, ) } diff --git a/tools/search.ts b/tools/search.ts index 5cdfce3..92fad28 100644 --- a/tools/search.ts +++ b/tools/search.ts @@ -8,10 +8,11 @@ export function registerSearchTool( api: OpenClawPluginApi, client: SupermemoryClient, _cfg: SupermemoryConfig, + toolName = "supermemory_search", ): void { api.registerTool( { - name: "supermemory_search", + name: toolName, label: "Memory Search", description: "Search through long-term memories for relevant information.", @@ -77,6 +78,6 @@ export function registerSearchTool( } }, }, - { name: "supermemory_search" }, + { name: toolName }, ) } diff --git a/tools/store.ts b/tools/store.ts index 75eaf20..03b8d7b 100644 --- a/tools/store.ts +++ b/tools/store.ts @@ -14,10 +14,11 @@ export function registerStoreTool( client: SupermemoryClient, cfg: SupermemoryConfig, getSessionKey: () => string | undefined, + toolName = "supermemory_store", ): void { api.registerTool( { - name: "supermemory_store", + name: toolName, label: "Memory Store", description: "Save important information to long-term memory.", parameters: Type.Object({ @@ -46,7 +47,7 @@ export function registerStoreTool( const { status } = await client.addMemory( params.text, - { type: category, source: "openclaw_tool" }, + { type: category, sm_capture_mode: "tool" }, customId, params.containerTag, cfg.entityContext, @@ -71,6 +72,6 @@ export function registerStoreTool( } }, }, - { name: "supermemory_store" }, + { name: toolName }, ) }