Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
# Supermemory Plugin for Clawdbot
# Supermemory Plugin for OpenClaw (previously Clawdbot)

<img width="1200" height="628" alt="Announcement-3 (2)" src="https://github.com/user-attachments/assets/caa5acaa-8246-4172-af3a-9cfed2a452c1" />



Long-term memory for Clawdbot. Automatically remembers conversations, recalls relevant context, and builds a persistent user profile — all powered by [Supermemory](https://supermemory.ai) cloud. No local infrastructure required.
Long-term memory for OpenClaw. Automatically remembers conversations, recalls relevant context, and builds a persistent user profile — all powered by [Supermemory](https://supermemory.ai) cloud. No local infrastructure required.

## Install

```bash
clawdbot plugins install @supermemoryai/clawdbot-supermemory
openclaw plugins install @supermemory/openclaw-supermemory
```

Restart Clawdbot after installing.
Restart OpenClaw after installing.

## Configuration

Expand All @@ -21,19 +21,19 @@ The only required value is your Supermemory API key. Get one at [console.superme
Set it as an environment variable:

```bash
export SUPERMEMORY_CLAWDBOT_API_KEY="sm_..."
export SUPERMEMORY_OPENCLAW_API_KEY="sm_..."
```

Or configure it directly in `clawdbot.json`:
Or configure it directly in `openclaw.json`:

```json5
{
"plugins": {
"entries": {
"clawdbot-supermemory": {
"openclaw-supermemory": {
"enabled": true,
"config": {
"apiKey": "${SUPERMEMORY_CLAWDBOT_API_KEY}"
"apiKey": "${SUPERMEMORY_OPENCLAW_API_KEY}"
}
}
}
Expand All @@ -45,7 +45,7 @@ Or configure it directly in `clawdbot.json`:

| Key | Type | Default | Description |
|-----|------|---------|-------------|
| `containerTag` | `string` | `clawdbot_{hostname}` | Memory namespace. All channels share this tag. |
| `containerTag` | `string` | `openclaw_{hostname}` | Memory namespace. All channels share this tag. |
| `autoRecall` | `boolean` | `true` | Inject relevant memories before every AI turn. |
| `autoCapture` | `boolean` | `true` | Automatically store conversation content after every turn. |
| `maxRecallResults` | `number` | `10` | Max memories injected into context per turn. |
Expand Down Expand Up @@ -83,7 +83,7 @@ The AI can use these tools autonomously during conversations:
## CLI Commands

```bash
clawdbot supermemory search <query> # Search memories
clawdbot supermemory profile # View user profile
clawdbot supermemory wipe # Delete all memories (destructive, requires confirmation)
openclaw supermemory search <query> # Search memories
openclaw supermemory profile # View user profile
openclaw supermemory wipe # Delete all memories (destructive, requires confirmation)
```
6 changes: 3 additions & 3 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions commands/cli.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import type { ClawdbotPluginApi } from "clawdbot/plugin-sdk"
import type { OpenClawPluginApi } from "openclaw/plugin-sdk"
import type { SupermemoryClient } from "../client.ts"
import type { SupermemoryConfig } from "../config.ts"
import { log } from "../logger.ts"

export function registerCli(
api: ClawdbotPluginApi,
api: OpenClawPluginApi,
client: SupermemoryClient,
_cfg: SupermemoryConfig,
): void {
api.registerCli(
// biome-ignore lint/suspicious/noExplicitAny: clawdbot SDK does not ship types
// biome-ignore lint/suspicious/noExplicitAny: openclaw SDK does not ship types
({ program }: { program: any }) => {
const cmd = program
.command("supermemory")
Expand Down
6 changes: 3 additions & 3 deletions commands/slash.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import type { ClawdbotPluginApi } from "clawdbot/plugin-sdk"
import type { OpenClawPluginApi } from "openclaw/plugin-sdk"
import type { SupermemoryClient } from "../client.ts"
import type { SupermemoryConfig } from "../config.ts"
import { log } from "../logger.ts"
import { buildDocumentId, detectCategory } from "../memory.ts"

export function registerCommands(
api: ClawdbotPluginApi,
api: OpenClawPluginApi,
client: SupermemoryClient,
_cfg: SupermemoryConfig,
getSessionKey: () => string | undefined,
Expand All @@ -28,7 +28,7 @@ export function registerCommands(
const sk = getSessionKey()
await client.addMemory(
text,
{ type: category, source: "clawdbot_command" },
{ type: category, source: "openclaw_command" },
sk ? buildDocumentId(sk) : undefined,
)

Expand Down
6 changes: 3 additions & 3 deletions config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ function sanitizeTag(raw: string): string {
}

function defaultContainerTag(): string {
return sanitizeTag(`clawdbot_${hostname()}`)
return sanitizeTag(`openclaw_${hostname()}`)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Changing the default containerTag from clawdbot_{hostname} to openclaw_{hostname} will cause users on the default configuration to silently lose access to their existing memories after upgrading.
Severity: HIGH

Suggested Fix

To prevent silent data loss for existing users, implement a fallback mechanism. The application should first check for memories using the new openclaw_{hostname} tag, and if none are found, it should then check for the old clawdbot_{hostname} tag. This would provide backward compatibility during the transition period. Alternatively, add a prominent warning to users upon upgrade, informing them of the change and guiding them to manually configure their containerTag if they wish to access old memories.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.

Location: config.ts#L56

Potential issue: The default value for `containerTag` has been changed from
`clawdbot_{hostname}` to `openclaw_{hostname}`. Since the container tag acts as a
namespace for all memory operations, this change will cause existing users who rely on
the default configuration to silently lose access to all their previously stored
memories upon upgrading. The application will not crash or show any warnings; it will
simply connect to a new, empty memory namespace, effectively resulting in unintentional
data loss for this subset of users.

Did we get this right? 👍 / 👎 to inform future reviews.

}

export function parseConfig(raw: unknown): SupermemoryConfig {
Expand All @@ -69,11 +69,11 @@ export function parseConfig(raw: unknown): SupermemoryConfig {
const apiKey =
typeof cfg.apiKey === "string" && cfg.apiKey.length > 0
? resolveEnvVars(cfg.apiKey)
: process.env.SUPERMEMORY_CLAWDBOT_API_KEY
: process.env.SUPERMEMORY_OPENCLAW_API_KEY

if (!apiKey) {
throw new Error(
"supermemory: apiKey is required (set in plugin config or SUPERMEMORY_CLAWDBOT_API_KEY env var)",
"supermemory: apiKey is required (set in plugin config or SUPERMEMORY_OPENCLAW_API_KEY env var)",
)
}

Expand Down
2 changes: 1 addition & 1 deletion hooks/capture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export function buildCaptureHandler(
try {
await client.addMemory(
content,
{ source: "clawdbot", timestamp: new Date().toISOString() },
{ source: "openclaw", timestamp: new Date().toISOString() },
customId,
)
} catch (err) {
Expand Down
10 changes: 5 additions & 5 deletions index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ClawdbotPluginApi } from "clawdbot/plugin-sdk"
import type { OpenClawPluginApi } from "openclaw/plugin-sdk"
import { SupermemoryClient } from "./client.ts"
import { registerCli } from "./commands/cli.ts"
import { registerCommands } from "./commands/slash.ts"
Expand All @@ -12,13 +12,13 @@ import { registerSearchTool } from "./tools/search.ts"
import { registerStoreTool } from "./tools/store.ts"

export default {
id: "clawdbot-supermemory",
id: "openclaw-supermemory",
name: "Supermemory",
description: "Clawdbot powered by Supermemory plugin",
description: "OpenClaw powered by Supermemory plugin",
kind: "memory" as const,
configSchema: supermemoryConfigSchema,

register(api: ClawdbotPluginApi) {
register(api: OpenClawPluginApi) {
const cfg = parseConfig(api.pluginConfig)

initLogger(api.logger, cfg.debug)
Expand Down Expand Up @@ -52,7 +52,7 @@ export default {
registerCli(api, client, cfg)

api.registerService({
id: "clawdbot-supermemory",
id: "openclaw-supermemory",
start: () => {
api.logger.info("supermemory: connected")
},
Expand Down
8 changes: 4 additions & 4 deletions clawdbot.plugin.json → openclaw.plugin.json
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
{
"id": "clawdbot-supermemory",
"id": "openclaw-supermemory",
"kind": "memory",
"uiHints": {
"apiKey": {
"label": "Supermemory API Key",
"sensitive": true,
"placeholder": "sm_...",
"help": "Your API key from console.supermemory.ai (or use ${SUPERMEMORY_CLAWDBOT_API_KEY})"
"help": "Your API key from console.supermemory.ai (or use ${SUPERMEMORY_OPENCLAW_API_KEY})"
},
"containerTag": {
"label": "Container Tag",
"placeholder": "clawdbot_myhostname",
"help": "Memory namespace. Default: clawdbot_{hostname}. All channels share this.",
"placeholder": "openclaw_myhostname",
"help": "Memory namespace. Default: openclaw_{hostname}. All channels share this.",
"advanced": true
},
"autoRecall": {
Expand Down
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"name": "@supermemory/clawdbot-supermemory",
"version": "1.0.0",
"name": "@supermemory/openclaw-supermemory",
"version": "1.0.1",
"type": "module",
"description": "Clawdbot Supermemory memory plugin",
"description": "OpenClaw Supermemory memory plugin",
"license": "MIT",
"dependencies": {
"supermemory": "^4.0.0",
Expand All @@ -15,9 +15,9 @@
"build:lib": "esbuild lib/validate.ts --bundle --minify --format=esm --platform=node --target=es2022 --external:node:crypto --outfile=lib/validate.js"
},
"peerDependencies": {
"clawdbot": ">=2026.1.24"
"openclaw": ">=2026.1.29"
},
"clawdbot": {
"openclaw": {
"extensions": [
"./index.ts"
]
Expand Down
4 changes: 2 additions & 2 deletions tools/forget.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Type } from "@sinclair/typebox"
import type { ClawdbotPluginApi } from "clawdbot/plugin-sdk"
import type { OpenClawPluginApi } from "openclaw/plugin-sdk"
import type { SupermemoryClient } from "../client.ts"
import type { SupermemoryConfig } from "../config.ts"
import { log } from "../logger.ts"

export function registerForgetTool(
api: ClawdbotPluginApi,
api: OpenClawPluginApi,
client: SupermemoryClient,
_cfg: SupermemoryConfig,
): void {
Expand Down
4 changes: 2 additions & 2 deletions tools/profile.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Type } from "@sinclair/typebox"
import type { ClawdbotPluginApi } from "clawdbot/plugin-sdk"
import type { OpenClawPluginApi } from "openclaw/plugin-sdk"
import type { SupermemoryClient } from "../client.ts"
import type { SupermemoryConfig } from "../config.ts"
import { log } from "../logger.ts"

export function registerProfileTool(
api: ClawdbotPluginApi,
api: OpenClawPluginApi,
client: SupermemoryClient,
_cfg: SupermemoryConfig,
): void {
Expand Down
4 changes: 2 additions & 2 deletions tools/search.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { Type } from "@sinclair/typebox"
import type { ClawdbotPluginApi } from "clawdbot/plugin-sdk"
import type { OpenClawPluginApi } from "openclaw/plugin-sdk"
import type { SupermemoryClient } from "../client.ts"
import type { SupermemoryConfig } from "../config.ts"
import { log } from "../logger.ts"

export function registerSearchTool(
api: ClawdbotPluginApi,
api: OpenClawPluginApi,
client: SupermemoryClient,
_cfg: SupermemoryConfig,
): void {
Expand Down
8 changes: 4 additions & 4 deletions tools/store.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Type } from "@sinclair/typebox"
import type { ClawdbotPluginApi } from "clawdbot/plugin-sdk"
import { stringEnum } from "clawdbot/plugin-sdk"
import type { OpenClawPluginApi } from "openclaw/plugin-sdk"
import { stringEnum } from "openclaw/plugin-sdk"
import type { SupermemoryClient } from "../client.ts"
import type { SupermemoryConfig } from "../config.ts"
import { log } from "../logger.ts"
Expand All @@ -11,7 +11,7 @@ import {
} from "../memory.ts"

export function registerStoreTool(
api: ClawdbotPluginApi,
api: OpenClawPluginApi,
client: SupermemoryClient,
_cfg: SupermemoryConfig,
getSessionKey: () => string | undefined,
Expand All @@ -37,7 +37,7 @@ export function registerStoreTool(

await client.addMemory(
params.text,
{ type: category, source: "clawdbot_tool" },
{ type: category, source: "openclaw_tool" },
customId,
)

Expand Down
16 changes: 8 additions & 8 deletions types/clawdbot.d.ts → types/openclaw.d.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
declare module "clawdbot/plugin-sdk" {
export interface ClawdbotPluginApi {
declare module "openclaw/plugin-sdk" {
export interface OpenClawPluginApi {
pluginConfig: unknown
logger: {
info: (msg: string) => void
warn: (msg: string) => void
error: (msg: string, ...args: unknown[]) => void
debug: (msg: string) => void
}
// biome-ignore lint/suspicious/noExplicitAny: clawdbot SDK does not ship types
// biome-ignore lint/suspicious/noExplicitAny: openclaw SDK does not ship types
registerTool(tool: any, options: any): void
// biome-ignore lint/suspicious/noExplicitAny: clawdbot SDK does not ship types
// biome-ignore lint/suspicious/noExplicitAny: openclaw SDK does not ship types
registerCommand(command: any): void
// biome-ignore lint/suspicious/noExplicitAny: clawdbot SDK does not ship types
// biome-ignore lint/suspicious/noExplicitAny: openclaw SDK does not ship types
registerCli(handler: any, options?: any): void
// biome-ignore lint/suspicious/noExplicitAny: clawdbot SDK does not ship types
// biome-ignore lint/suspicious/noExplicitAny: openclaw SDK does not ship types
registerService(service: any): void
// biome-ignore lint/suspicious/noExplicitAny: clawdbot SDK does not ship types
// biome-ignore lint/suspicious/noExplicitAny: openclaw SDK does not ship types
on(event: string, handler: (...args: any[]) => any): void
}

// biome-ignore lint/suspicious/noExplicitAny: clawdbot SDK does not ship types
// biome-ignore lint/suspicious/noExplicitAny: openclaw SDK does not ship types
export function stringEnum(values: readonly string[]): any
}