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
40 changes: 40 additions & 0 deletions .coderabbit.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json
language: "en-US"

reviews:
profile: "assertive"
high_level_summary: true
auto_review:
enabled: true
drafts: false
ignore_title_keywords:
- "wip"
- "draft"
auto_pause_after_reviewed_commits: 0
path_filters:
- "!go.sum"
- "!**/package-lock.json"
- "!**/pnpm-lock.yaml"
- "!**/yarn.lock"
- "!**/*.snap"
- "!**/dist/**"
- "!**/build/**"
- "!**/.vitepress/dist/**"
- "!**/coverage/**"
- "!**/.next/**"
- "!**/site/**"
- "!**/docs/.vitepress/cache/**"
- "!**/*.min.js"
- "!**/*.generated.*"
- "!**/*pb.go"

chat:
auto_reply: true

knowledge_base:
code_guidelines:
enabled: true
filePatterns:
- "CONTRIBUTING.md"
- "README.md"
- "docs/**/*.md"
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -65,3 +65,4 @@ node_modules/
# Plan files
plan.md
.claude/
clients/openclaw/package-lock.json
2 changes: 2 additions & 0 deletions clients/openclaw/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules/
dist/
112 changes: 112 additions & 0 deletions clients/openclaw/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# OpenClaw Membrane Plugin

[OpenClaw](https://github.com/openclaw/openclaw) plugin that bridges to [Membrane](https://github.com/GustyCube/membrane) — giving your AI agents episodic memory.

## What it does

- **Ingests** agent events, tool outputs, and observations into Membrane
- **Searches** episodic memory via the `membrane_search` tool
- **Auto-injects** relevant context before each agent turn
- **Reports** connection status via the `/membrane` command

## Install

```bash
# In your OpenClaw extensions directory
npm install @vainplex/openclaw-membrane
```

Or with [Brainplex](https://www.npmjs.com/package/brainplex):

```bash
npx brainplex init # Auto-detects and configures all plugins
```

## Prerequisites

- A running [Membrane](https://github.com/GustyCube/membrane) instance (the `membraned` daemon)
- OpenClaw v0.10+

## Configuration

In your OpenClaw config (`openclaw.yaml`), under `plugins.entries`:

```yaml
plugins:
entries:
openclaw-membrane:
enabled: true
config:
grpc_endpoint: "localhost:4222"
default_sensitivity: "low"
auto_context: true
context_limit: 5
min_salience: 0.3
context_types: ["episodic", "semantic", "competence"]
```

| Option | Default | Description |
|--------|---------|-------------|
| `grpc_endpoint` | `localhost:4222` | Membrane gRPC address |
| `default_sensitivity` | `low` | Sensitivity for ingested events: `public`, `low`, `medium`, `high`, `hyper` |
| `auto_context` | `true` | Auto-inject memories before each agent turn |
| `context_limit` | `5` | Max memories to inject |
| `min_salience` | `0.3` | Minimum salience score for retrieval |
| `context_types` | `["episodic", "semantic", "competence"]` | Memory types: `episodic`, `working`, `semantic`, `competence`, `plan_graph` |


## Usage

### membrane_search tool

Your agent can search episodic memory:

```javascript
membrane_search("what happened in yesterday's meeting", { limit: 10 })
```

### Auto-context

When `auto_context: true`, the plugin injects relevant memories into the agent's context before each turn. This gives agents awareness of past interactions without explicit tool calls.

### /membrane command

Check connection status:

```text
/membrane
→ Membrane: connected (localhost:4222) | 1,247 records | 3 memory types
```

## Architecture

```text
OpenClaw Agent
├── after_agent_reply ──→ ingestEvent()
├── after_tool_call ────→ ingestToolOutput()
├── before_agent_start ─→ retrieve() → inject context
└── membrane_search ───→ retrieve() → return results
Membrane (gRPC)
┌─────────────┐
│ membraned │
│ SQLCipher │
│ Embeddings │
└─────────────┘
```

## Development

```bash
cd clients/openclaw
npm install
npm run build
npm test
```

## License

MIT — see [LICENSE](../../LICENSE)
51 changes: 51 additions & 0 deletions clients/openclaw/openclaw.plugin.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
{
"id": "openclaw-membrane",
"kind": "memory",
"name": "openclaw-membrane",
"version": "0.4.0",
"description": "Membrane episodic memory bridge — ingest events, search memories, auto-inject context",
"configSchema": {
"type": "object",
"properties": {
"grpc_endpoint": { "type": "string", "default": "localhost:4222" },
"default_sensitivity": { "type": "string", "enum": ["public", "low", "medium", "high", "hyper"], "default": "low" },
"auto_context": { "type": "boolean", "default": true },
"context_limit": { "type": "integer", "minimum": 1, "default": 5 },
"min_salience": { "type": "number", "minimum": 0, "maximum": 1, "default": 0.3 },
"context_types": {
"type": "array",
"items": { "type": "string", "enum": ["episodic", "working", "semantic", "competence", "plan_graph"] },
"default": ["episodic", "semantic", "competence"]
}
},
"additionalProperties": false
},
"hooks": [
"after_agent_reply",
"after_tool_call",
"before_agent_start"
],
"tools": [
{
"name": "membrane_search",
"description": "Search episodic memory in Membrane for relevant context",
"parameters": {
"type": "object",
"properties": {
"query": { "type": "string", "description": "Natural language query to search memories" },
"limit": { "type": "integer", "minimum": 1, "description": "Maximum results to return (default: 5)" },
"memory_types": { "type": "array", "items": { "type": "string", "enum": ["episodic", "working", "semantic", "competence", "plan_graph"] }, "description": "Filter by memory type: episodic, working, semantic, competence, plan_graph" },
"min_salience": { "type": "number", "minimum": 0, "maximum": 1, "description": "Minimum salience score (0-1, default: 0.3)" }
},
"required": ["query"],
"additionalProperties": false
}
}
],
"commands": [
{
"name": "membrane",
"description": "Show Membrane connection status and memory stats"
}
]
}
44 changes: 44 additions & 0 deletions clients/openclaw/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"name": "@vainplex/openclaw-membrane",
"version": "0.4.0",
"description": "Membrane bridge plugin for OpenClaw — episodic memory ingestion, search, and auto-context injection",
"license": "MIT",
"author": "Vainplex <dev@vainplex.de>",
"repository": {
"type": "git",
"url": "https://github.com/GustyCube/membrane.git",
"directory": "clients/openclaw"
},
"homepage": "https://github.com/GustyCube/membrane",
"bugs": {
"url": "https://github.com/GustyCube/membrane/issues"
},
"type": "module",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.js",
"types": "./dist/index.d.ts"
}
},
"files": [
"dist",
"openclaw.plugin.json",
"README.md"
],
"scripts": {
"build": "rm -rf dist && tsc",
"test": "vitest run"
},
"dependencies": {
"@gustycube/membrane": "^0.1.4"
},
"devDependencies": {
"typescript": "^5.7.0",
"vitest": "^3.0.0"
},
"engines": {
"node": ">=20"
}
}
Loading
Loading