@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 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 = "https://api.memoryrelay.net",
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
- if (!cfg) {
163
- api.logger.error("memory-memoryrelay: pluginConfig is null or undefined");
164
- return;
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 (!cfg.apiKey) {
168
- api.logger.error(`memory-memoryrelay: missing apiKey in config. Config keys: ${Object.keys(cfg).join(', ')}`);
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
- if (!cfg.agentId) {
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 client = new MemoryRelayClient(
178
- cfg.apiKey,
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 ${cfg.apiUrl || "api.memoryrelay.net"}`);
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: ${cfg.agentId}`);
405
- console.log(`API: ${cfg.apiUrl || "https://api.memoryrelay.net"}`);
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
  }
@@ -3,7 +3,7 @@
3
3
  "kind": "memory",
4
4
  "name": "MemoryRelay AI",
5
5
  "description": "AI memory service using MemoryRelay API (api.memoryrelay.net)",
6
- "version": "0.2.4",
6
+ "version": "0.4.0",
7
7
  "uiHints": {
8
8
  "apiKey": {
9
9
  "label": "MemoryRelay API Key",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@memoryrelay/plugin-memoryrelay-ai",
3
- "version": "0.2.4",
3
+ "version": "0.4.0",
4
4
  "description": "OpenClaw memory plugin for MemoryRelay API - long-term memory with semantic search",
5
5
  "type": "module",
6
6
  "main": "index.ts",