@memoryrelay/plugin-memoryrelay-ai 0.3.0 โ†’ 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
 
@@ -64,11 +65,21 @@ openclaw gateway restart
64
65
 
65
66
  ```bash
66
67
  openclaw status
67
- # Should show: Memory | enabled (plugin plugin-memoryrelay-ai)
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
68
78
 
69
79
  # Check logs
70
80
  journalctl -u openclaw-gateway --since '1 minute ago' | grep memory-memoryrelay
71
- # Should show: "connected to api.memoryrelay.net"
81
+ # Example output: "memory-memoryrelay: connected to https://api.memoryrelay.net"
82
+ # (URL will vary if you configured a custom apiUrl)
72
83
  ```
73
84
 
74
85
  Get your API key from [memoryrelay.ai](https://memoryrelay.ai).
@@ -197,6 +208,30 @@ memory_forget({ query: "outdated preference" })
197
208
 
198
209
  **Returns:** Success confirmation
199
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
+
200
235
  ### CLI Commands
201
236
 
202
237
  ```bash
@@ -441,6 +476,29 @@ MIT ยฉ 2026 MemoryRelay
441
476
 
442
477
  ## Changelog
443
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
+
444
502
  ### v0.3.0 (2026-02-13) - Better Installation UX
445
503
 
446
504
  **Improved Installation Experience:**
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
  // ============================================================================
@@ -176,21 +194,70 @@ export default async function plugin(api: OpenClawPluginApi): Promise<void> {
176
194
 
177
195
  api.logger.info(`memory-memoryrelay: using agentId: ${agentId}`);
178
196
 
179
- const client = new MemoryRelayClient(
180
- apiKey,
181
- agentId,
182
- cfg?.apiUrl || "https://api.memoryrelay.net",
183
- );
197
+ const apiUrl = cfg?.apiUrl || DEFAULT_API_URL;
198
+ const client = new MemoryRelayClient(apiKey, agentId, apiUrl);
184
199
 
185
200
  // Verify connection on startup
186
201
  try {
187
202
  await client.health();
188
- api.logger.info(`memory-memoryrelay: connected to ${cfg.apiUrl || "api.memoryrelay.net"}`);
203
+ api.logger.info(`memory-memoryrelay: connected to ${apiUrl}`);
189
204
  } catch (err) {
190
205
  api.logger.error(`memory-memoryrelay: health check failed: ${String(err)}`);
191
206
  return;
192
207
  }
193
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
+
194
261
  // ========================================================================
195
262
  // Tools (using JSON Schema directly)
196
263
  // ========================================================================
@@ -403,8 +470,8 @@ export default async function plugin(api: OpenClawPluginApi): Promise<void> {
403
470
  try {
404
471
  const health = await client.health();
405
472
  console.log(`Status: ${health.status}`);
406
- console.log(`Agent ID: ${cfg.agentId}`);
407
- console.log(`API: ${cfg.apiUrl || "https://api.memoryrelay.net"}`);
473
+ console.log(`Agent ID: ${agentId}`);
474
+ console.log(`API: ${apiUrl}`);
408
475
  } catch (err) {
409
476
  console.error(`Connection failed: ${String(err)}`);
410
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.3.0",
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.3.0",
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",