@memoryrelay/plugin-memoryrelay-ai 0.2.4 โ 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +121 -0
- package/index.ts +88 -19
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,6 +13,7 @@ Long-term memory plugin for OpenClaw agents using [MemoryRelay API](https://api.
|
|
|
13
13
|
- ๐ค **Multi-Agent** โ Isolated memory namespaces per agent
|
|
14
14
|
- ๐ ๏ธ **CLI Tools** โ Manage memories via `openclaw memoryrelay` commands
|
|
15
15
|
- ๐ **Tool Integration** โ Three memory tools for AI agents
|
|
16
|
+
- โ
**Status Reporting** โ Real-time availability and connection status in `openclaw status`
|
|
16
17
|
|
|
17
18
|
## Installation
|
|
18
19
|
|
|
@@ -28,6 +29,61 @@ npm install -g @memoryrelay/plugin-memoryrelay-ai
|
|
|
28
29
|
|
|
29
30
|
## Quick Start
|
|
30
31
|
|
|
32
|
+
### 1. Install the plugin
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
openclaw plugins install @memoryrelay/plugin-memoryrelay-ai
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### 2. Configure API credentials
|
|
39
|
+
|
|
40
|
+
**Option A: Config file** (recommended)
|
|
41
|
+
```bash
|
|
42
|
+
cat ~/.openclaw/openclaw.json | jq '.plugins.entries."plugin-memoryrelay-ai".config = {
|
|
43
|
+
"apiKey": "YOUR_API_KEY",
|
|
44
|
+
"agentId": "YOUR_AGENT_ID",
|
|
45
|
+
"autoRecall": true,
|
|
46
|
+
"autoCapture": false
|
|
47
|
+
}' > /tmp/config.json && \
|
|
48
|
+
mv /tmp/config.json ~/.openclaw/openclaw.json && \
|
|
49
|
+
chmod 600 ~/.openclaw/openclaw.json
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**Option B: Environment variables**
|
|
53
|
+
```bash
|
|
54
|
+
export MEMORYRELAY_API_KEY="YOUR_API_KEY"
|
|
55
|
+
export MEMORYRELAY_AGENT_ID="YOUR_AGENT_ID"
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### 3. Restart the gateway
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
openclaw gateway restart
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### 4. Verify it's working
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
openclaw status
|
|
68
|
+
# When API is reachable (example output):
|
|
69
|
+
# Memory | enabled (plugin plugin-memoryrelay-ai) ยท available
|
|
70
|
+
#
|
|
71
|
+
# When API is down (example output):
|
|
72
|
+
# Memory | enabled (plugin plugin-memoryrelay-ai) ยท unavailable
|
|
73
|
+
# (Note: Exact format depends on your OpenClaw version)
|
|
74
|
+
|
|
75
|
+
# Check plugin-specific status
|
|
76
|
+
openclaw memoryrelay status
|
|
77
|
+
# Shows: API connection, agent ID, endpoint
|
|
78
|
+
|
|
79
|
+
# Check logs
|
|
80
|
+
journalctl -u openclaw-gateway --since '1 minute ago' | grep memory-memoryrelay
|
|
81
|
+
# Example output: "memory-memoryrelay: connected to https://api.memoryrelay.net"
|
|
82
|
+
# (URL will vary if you configured a custom apiUrl)
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Get your API key from [memoryrelay.ai](https://memoryrelay.ai).
|
|
86
|
+
|
|
31
87
|
### 1. Get API Key
|
|
32
88
|
|
|
33
89
|
Sign up at [memoryrelay.io](https://memoryrelay.io) or use the public demo API.
|
|
@@ -152,6 +208,30 @@ memory_forget({ query: "outdated preference" })
|
|
|
152
208
|
|
|
153
209
|
**Returns:** Success confirmation
|
|
154
210
|
|
|
211
|
+
### Status Monitoring
|
|
212
|
+
|
|
213
|
+
The plugin reports its availability and connection status to OpenClaw:
|
|
214
|
+
|
|
215
|
+
```bash
|
|
216
|
+
# Check overall status (shows plugin availability)
|
|
217
|
+
openclaw status
|
|
218
|
+
# Shows: Memory | enabled (plugin plugin-memoryrelay-ai) ยท available
|
|
219
|
+
|
|
220
|
+
# Check plugin-specific status (MemoryRelay custom command)
|
|
221
|
+
openclaw memoryrelay status
|
|
222
|
+
# Shows: API connection, agent ID, endpoint
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
**Status Information Reported:**
|
|
226
|
+
- **Available/Unavailable** โ Whether the plugin can be used
|
|
227
|
+
- **Connected** โ Whether the MemoryRelay API is reachable
|
|
228
|
+
- **Memory Count** โ Total memories stored for this agent (if stats endpoint exists)
|
|
229
|
+
- **Vector Enabled** โ Semantic search capability (always true)
|
|
230
|
+
- **Endpoint** โ API URL being used
|
|
231
|
+
- **Agent ID** โ Current agent identifier
|
|
232
|
+
|
|
233
|
+
When the API is unreachable, status shows "unavailable" with error details.
|
|
234
|
+
|
|
155
235
|
### CLI Commands
|
|
156
236
|
|
|
157
237
|
```bash
|
|
@@ -396,6 +476,47 @@ MIT ยฉ 2026 MemoryRelay
|
|
|
396
476
|
|
|
397
477
|
## Changelog
|
|
398
478
|
|
|
479
|
+
### v0.4.0 (2026-02-13) - Status Reporting
|
|
480
|
+
|
|
481
|
+
**New Features:**
|
|
482
|
+
- โ
Status reporting via `memory.status` gateway RPC method
|
|
483
|
+
- โ
Plugin now reports "available" in `openclaw status` when API is reachable
|
|
484
|
+
- โ
Memory count reporting (via optional `/v1/stats` API endpoint)
|
|
485
|
+
- โ
Vector availability reporting for semantic search
|
|
486
|
+
- โ
Detailed status information: connected state, endpoint, agent ID, memory count
|
|
487
|
+
|
|
488
|
+
**Fixes:**
|
|
489
|
+
- โ
Plugin no longer shows as "unavailable" in `openclaw status` when functional
|
|
490
|
+
- โ
Status accurately reflects API connection state
|
|
491
|
+
|
|
492
|
+
**Technical Improvements:**
|
|
493
|
+
- โ
Extracted constants for maintainability (`DEFAULT_API_URL`, `VALID_HEALTH_STATUSES`)
|
|
494
|
+
- โ
Case-insensitive health status validation
|
|
495
|
+
- โ
Proper type safety with nullish coalescing operators
|
|
496
|
+
- โ
Graceful handling of missing stats endpoint (backwards compatible)
|
|
497
|
+
|
|
498
|
+
**Backwards Compatibility:**
|
|
499
|
+
- Fully compatible with older OpenClaw versions (uses optional chaining)
|
|
500
|
+
- Gracefully handles missing `/v1/stats` endpoint
|
|
501
|
+
|
|
502
|
+
### v0.3.0 (2026-02-13) - Better Installation UX
|
|
503
|
+
|
|
504
|
+
**Improved Installation Experience:**
|
|
505
|
+
- โ
API key can now come from `MEMORYRELAY_API_KEY` env var
|
|
506
|
+
- โ
Agent ID can come from `MEMORYRELAY_AGENT_ID` env var or defaults to "default"
|
|
507
|
+
- โ
Clear error message with setup instructions when config is missing
|
|
508
|
+
- โ
Comprehensive installation guide in README
|
|
509
|
+
- โ
No more silent failures - helpful error messages
|
|
510
|
+
|
|
511
|
+
**Breaking Change:**
|
|
512
|
+
- Debug logging removed (replaced with helpful error messages)
|
|
513
|
+
|
|
514
|
+
**Migration:**
|
|
515
|
+
Works out of the box with env vars, or add config after install:
|
|
516
|
+
```bash
|
|
517
|
+
cat ~/.openclaw/openclaw.json | jq '.plugins.entries."plugin-memoryrelay-ai".config = {"apiKey": "YOUR_KEY", "agentId": "YOUR_AGENT"}' > /tmp/config.json && mv /tmp/config.json ~/.openclaw/openclaw.json
|
|
518
|
+
```
|
|
519
|
+
|
|
399
520
|
### v0.2.4 (2026-02-13)
|
|
400
521
|
|
|
401
522
|
**Debug Logging:**
|
package/index.ts
CHANGED
|
@@ -10,6 +10,13 @@
|
|
|
10
10
|
|
|
11
11
|
import type { OpenClawPluginApi } from "openclaw/plugin-sdk";
|
|
12
12
|
|
|
13
|
+
// ============================================================================
|
|
14
|
+
// Constants
|
|
15
|
+
// ============================================================================
|
|
16
|
+
|
|
17
|
+
const DEFAULT_API_URL = "https://api.memoryrelay.net";
|
|
18
|
+
const VALID_HEALTH_STATUSES = ["ok", "healthy", "up"];
|
|
19
|
+
|
|
13
20
|
// ============================================================================
|
|
14
21
|
// Types
|
|
15
22
|
// ============================================================================
|
|
@@ -48,7 +55,7 @@ class MemoryRelayClient {
|
|
|
48
55
|
constructor(
|
|
49
56
|
private readonly apiKey: string,
|
|
50
57
|
private readonly agentId: string,
|
|
51
|
-
private readonly apiUrl: string =
|
|
58
|
+
private readonly apiUrl: string = DEFAULT_API_URL,
|
|
52
59
|
) {}
|
|
53
60
|
|
|
54
61
|
private async request<T>(
|
|
@@ -124,6 +131,17 @@ class MemoryRelayClient {
|
|
|
124
131
|
async health(): Promise<{ status: string }> {
|
|
125
132
|
return this.request<{ status: string }>("GET", "/v1/health");
|
|
126
133
|
}
|
|
134
|
+
|
|
135
|
+
async stats(): Promise<{ total_memories: number; last_updated?: string }> {
|
|
136
|
+
const response = await this.request<{ data: { total_memories: number; last_updated?: string } }>(
|
|
137
|
+
"GET",
|
|
138
|
+
`/v1/stats?agent_id=${encodeURIComponent(this.agentId)}`,
|
|
139
|
+
);
|
|
140
|
+
return {
|
|
141
|
+
total_memories: response.data?.total_memories ?? 0,
|
|
142
|
+
last_updated: response.data?.last_updated,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
127
145
|
}
|
|
128
146
|
|
|
129
147
|
// ============================================================================
|
|
@@ -159,36 +177,87 @@ export default async function plugin(api: OpenClawPluginApi): Promise<void> {
|
|
|
159
177
|
|
|
160
178
|
const cfg = api.pluginConfig as MemoryRelayConfig | undefined;
|
|
161
179
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
}
|
|
180
|
+
// Try to get config from multiple sources
|
|
181
|
+
const apiKey = cfg?.apiKey || process.env.MEMORYRELAY_API_KEY;
|
|
182
|
+
const agentId = cfg?.agentId || process.env.MEMORYRELAY_AGENT_ID || "default";
|
|
166
183
|
|
|
167
|
-
if (!
|
|
168
|
-
api.logger.error(
|
|
184
|
+
if (!apiKey) {
|
|
185
|
+
api.logger.error(
|
|
186
|
+
"memory-memoryrelay: missing API key. Configure in one of these ways:\n" +
|
|
187
|
+
" 1. Add to config: plugins.entries.\"plugin-memoryrelay-ai\".config.apiKey\n" +
|
|
188
|
+
" 2. Set environment variable: MEMORYRELAY_API_KEY\n" +
|
|
189
|
+
" 3. Run: cat ~/.openclaw/openclaw.json | jq '.plugins.entries.\"plugin-memoryrelay-ai\".config = {\"apiKey\": \"YOUR_KEY\", \"agentId\": \"YOUR_AGENT\"}' > /tmp/config.json && mv /tmp/config.json ~/.openclaw/openclaw.json\n" +
|
|
190
|
+
"Get your API key from: https://memoryrelay.ai"
|
|
191
|
+
);
|
|
169
192
|
return;
|
|
170
193
|
}
|
|
171
194
|
|
|
172
|
-
|
|
173
|
-
api.logger.error(`memory-memoryrelay: missing agentId in config. Config keys: ${Object.keys(cfg).join(', ')}`);
|
|
174
|
-
return;
|
|
175
|
-
}
|
|
195
|
+
api.logger.info(`memory-memoryrelay: using agentId: ${agentId}`);
|
|
176
196
|
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
cfg.agentId,
|
|
180
|
-
cfg.apiUrl || "https://api.memoryrelay.net",
|
|
181
|
-
);
|
|
197
|
+
const apiUrl = cfg?.apiUrl || DEFAULT_API_URL;
|
|
198
|
+
const client = new MemoryRelayClient(apiKey, agentId, apiUrl);
|
|
182
199
|
|
|
183
200
|
// Verify connection on startup
|
|
184
201
|
try {
|
|
185
202
|
await client.health();
|
|
186
|
-
api.logger.info(`memory-memoryrelay: connected to ${
|
|
203
|
+
api.logger.info(`memory-memoryrelay: connected to ${apiUrl}`);
|
|
187
204
|
} catch (err) {
|
|
188
205
|
api.logger.error(`memory-memoryrelay: health check failed: ${String(err)}`);
|
|
189
206
|
return;
|
|
190
207
|
}
|
|
191
208
|
|
|
209
|
+
// ========================================================================
|
|
210
|
+
// Status Reporting (for openclaw status command)
|
|
211
|
+
// ========================================================================
|
|
212
|
+
|
|
213
|
+
// Register gateway RPC method for status probing
|
|
214
|
+
// This allows OpenClaw's status command to query plugin availability
|
|
215
|
+
api.registerGatewayMethod?.("memory.status", async ({ respond }) => {
|
|
216
|
+
try {
|
|
217
|
+
const health = await client.health();
|
|
218
|
+
let memoryCount = 0;
|
|
219
|
+
|
|
220
|
+
// Try to get stats if the endpoint exists
|
|
221
|
+
try {
|
|
222
|
+
const stats = await client.stats();
|
|
223
|
+
memoryCount = stats.total_memories;
|
|
224
|
+
} catch (statsErr) {
|
|
225
|
+
// Stats endpoint may not exist yet - that's okay, just report 0
|
|
226
|
+
api.logger.debug?.(`memory-memoryrelay: stats endpoint unavailable: ${String(statsErr)}`);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Consider API connected if health check succeeds with any recognized status
|
|
230
|
+
const healthStatus = String(health.status).toLowerCase();
|
|
231
|
+
const isConnected = VALID_HEALTH_STATUSES.includes(healthStatus);
|
|
232
|
+
|
|
233
|
+
respond(true, {
|
|
234
|
+
available: true,
|
|
235
|
+
connected: isConnected,
|
|
236
|
+
endpoint: apiUrl,
|
|
237
|
+
memoryCount: memoryCount,
|
|
238
|
+
agentId: agentId,
|
|
239
|
+
// OpenClaw checks status.vector.available for memory plugins
|
|
240
|
+
vector: {
|
|
241
|
+
available: true,
|
|
242
|
+
enabled: true,
|
|
243
|
+
},
|
|
244
|
+
});
|
|
245
|
+
} catch (err) {
|
|
246
|
+
respond(true, {
|
|
247
|
+
available: false,
|
|
248
|
+
connected: false,
|
|
249
|
+
error: String(err),
|
|
250
|
+
endpoint: apiUrl,
|
|
251
|
+
agentId: agentId,
|
|
252
|
+
// Report vector as unavailable when API fails
|
|
253
|
+
vector: {
|
|
254
|
+
available: false,
|
|
255
|
+
enabled: true,
|
|
256
|
+
},
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
|
|
192
261
|
// ========================================================================
|
|
193
262
|
// Tools (using JSON Schema directly)
|
|
194
263
|
// ========================================================================
|
|
@@ -401,8 +470,8 @@ export default async function plugin(api: OpenClawPluginApi): Promise<void> {
|
|
|
401
470
|
try {
|
|
402
471
|
const health = await client.health();
|
|
403
472
|
console.log(`Status: ${health.status}`);
|
|
404
|
-
console.log(`Agent ID: ${
|
|
405
|
-
console.log(`API: ${
|
|
473
|
+
console.log(`Agent ID: ${agentId}`);
|
|
474
|
+
console.log(`API: ${apiUrl}`);
|
|
406
475
|
} catch (err) {
|
|
407
476
|
console.error(`Connection failed: ${String(err)}`);
|
|
408
477
|
}
|
package/openclaw.plugin.json
CHANGED