@memoryrelay/plugin-memoryrelay-ai 0.15.0 → 0.15.2
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 +25 -4
- package/index.ts +35 -6
- package/openclaw.plugin.json +2 -2
- package/package.json +2 -2
- package/src/status-reporter.ts +20 -2
- package/skills/codebase-navigation/SKILL.md +0 -105
- package/skills/release-process/SKILL.md +0 -83
- package/skills/testing-memoryrelay/SKILL.md +0 -87
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ MemoryRelay is designed for engineering teams managing complex, long-running pro
|
|
|
22
22
|
| Multi-agent collaboration | Yes (agent scoping, subagent tracking) | Limited | No |
|
|
23
23
|
| Auto-capture with privacy tiers | Yes (off/conservative/smart/aggressive) | Basic | No |
|
|
24
24
|
| V2 Async Storage | Yes | No | No |
|
|
25
|
-
| Direct commands |
|
|
25
|
+
| Direct commands | 17 | ~5 | 0 |
|
|
26
26
|
| Lifecycle hooks | 13 | 0 | 0 |
|
|
27
27
|
| Tools | 42 | ~10 | 0 |
|
|
28
28
|
|
|
@@ -314,10 +314,31 @@ The plugin registers 14 lifecycle hooks:
|
|
|
314
314
|
|
|
315
315
|
### Skills
|
|
316
316
|
|
|
317
|
-
The plugin ships with
|
|
317
|
+
The plugin ships with 5 skills providing guided workflows on top of the raw tools:
|
|
318
318
|
|
|
319
|
-
-
|
|
320
|
-
-
|
|
319
|
+
- `memory-workflow` — Session lifecycle, storing/retrieving memories
|
|
320
|
+
- `decision-tracking` — ADR management, checking before deciding
|
|
321
|
+
- `pattern-management` — Reusable conventions, search before create
|
|
322
|
+
- `project-orchestration` — Multi-project context loading and impact analysis
|
|
323
|
+
- `entity-and-context` — Knowledge graph, linking entities to memories
|
|
324
|
+
|
|
325
|
+
## Updating
|
|
326
|
+
|
|
327
|
+
To update to the latest version:
|
|
328
|
+
|
|
329
|
+
```bash
|
|
330
|
+
openclaw plugins update plugin-memoryrelay-ai
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
Or from within a conversation, run `/memory-update` to see the exact command.
|
|
334
|
+
|
|
335
|
+
**Important:** The plugin ID is `plugin-memoryrelay-ai` (not `memory-memoryrelay`). Using the wrong ID will fail with "No install record."
|
|
336
|
+
|
|
337
|
+
After updating, restart the gateway:
|
|
338
|
+
|
|
339
|
+
```bash
|
|
340
|
+
openclaw restart
|
|
341
|
+
```
|
|
321
342
|
|
|
322
343
|
## Troubleshooting
|
|
323
344
|
|
package/index.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* OpenClaw Memory Plugin - MemoryRelay
|
|
3
|
-
* Version: 0.
|
|
3
|
+
* Version: 0.15.2
|
|
4
4
|
*
|
|
5
5
|
* Long-term memory with vector search using MemoryRelay API.
|
|
6
6
|
* Provides auto-recall and auto-capture via lifecycle hooks.
|
|
7
7
|
* Includes: memories, entities, agents, sessions, decisions, patterns, projects.
|
|
8
|
+
* New in v0.15.0: V2 async API, context_build with AI-enhanced search modes
|
|
8
9
|
* New in v0.13.0: External session IDs, get-or-create sessions, multi-agent collaboration
|
|
9
10
|
* New in v0.12.7: OpenClaw session context integration for session tracking
|
|
10
11
|
* New in v0.12.0: Smart auto-capture, daily stats, CLI commands, onboarding
|
|
@@ -67,6 +68,7 @@ interface DebugLoggerConfig {
|
|
|
67
68
|
enabled: boolean;
|
|
68
69
|
verbose: boolean;
|
|
69
70
|
maxEntries: number;
|
|
71
|
+
logFile?: string; // Deprecated: File logging removed for security compliance
|
|
70
72
|
}
|
|
71
73
|
|
|
72
74
|
class DebugLogger {
|
|
@@ -709,7 +711,7 @@ class MemoryRelayClient {
|
|
|
709
711
|
headers: {
|
|
710
712
|
"Content-Type": "application/json",
|
|
711
713
|
Authorization: `Bearer ${this.apiKey}`,
|
|
712
|
-
"User-Agent": "openclaw-memory-memoryrelay/0.15.
|
|
714
|
+
"User-Agent": "openclaw-memory-memoryrelay/0.15.2",
|
|
713
715
|
},
|
|
714
716
|
body: body ? JSON.stringify(body) : undefined,
|
|
715
717
|
},
|
|
@@ -1666,7 +1668,7 @@ export default async function plugin(api: OpenClawPluginApi): Promise<void> {
|
|
|
1666
1668
|
}
|
|
1667
1669
|
|
|
1668
1670
|
// ========================================================================
|
|
1669
|
-
// Tools (
|
|
1671
|
+
// Tools (42 total)
|
|
1670
1672
|
// ========================================================================
|
|
1671
1673
|
|
|
1672
1674
|
// --------------------------------------------------------------------------
|
|
@@ -4490,7 +4492,7 @@ export default async function plugin(api: OpenClawPluginApi): Promise<void> {
|
|
|
4490
4492
|
});
|
|
4491
4493
|
|
|
4492
4494
|
api.logger.info?.(
|
|
4493
|
-
`memory-memoryrelay: plugin v0.15.
|
|
4495
|
+
`memory-memoryrelay: plugin v0.15.2 loaded (${Object.values(TOOL_GROUPS).flat().length} tools, autoRecall: ${cfg?.autoRecall}, autoCapture: ${autoCaptureConfig.enabled ? autoCaptureConfig.tier : 'off'}, debug: ${debugEnabled})`,
|
|
4494
4496
|
);
|
|
4495
4497
|
|
|
4496
4498
|
// ========================================================================
|
|
@@ -4551,7 +4553,7 @@ export default async function plugin(api: OpenClawPluginApi): Promise<void> {
|
|
|
4551
4553
|
}
|
|
4552
4554
|
|
|
4553
4555
|
const formatted = logs.map((l) =>
|
|
4554
|
-
`[${new Date(l.timestamp).toISOString()}] ${l.
|
|
4556
|
+
`[${new Date(l.timestamp).toISOString()}] ${l.status.toUpperCase()} ${l.tool ?? "-"}: ${l.method} ${l.path} (${l.duration}ms)${l.error ? ` - ${l.error}` : ""}`
|
|
4555
4557
|
).join("\n");
|
|
4556
4558
|
respond(true, {
|
|
4557
4559
|
logs,
|
|
@@ -4898,7 +4900,7 @@ export default async function plugin(api: OpenClawPluginApi): Promise<void> {
|
|
|
4898
4900
|
}
|
|
4899
4901
|
|
|
4900
4902
|
// ========================================================================
|
|
4901
|
-
// Direct Commands (
|
|
4903
|
+
// Direct Commands (17 total) — bypass LLM, execute immediately
|
|
4902
4904
|
// ========================================================================
|
|
4903
4905
|
|
|
4904
4906
|
// /memory-status — Show full plugin status report
|
|
@@ -5580,6 +5582,33 @@ export default async function plugin(api: OpenClawPluginApi): Promise<void> {
|
|
|
5580
5582
|
},
|
|
5581
5583
|
});
|
|
5582
5584
|
|
|
5585
|
+
// /memory-update — Show update instructions (v0.15.0)
|
|
5586
|
+
api.registerCommand?.({
|
|
5587
|
+
name: "memory-update",
|
|
5588
|
+
description: "Show how to update the MemoryRelay plugin to the latest version",
|
|
5589
|
+
requireAuth: true,
|
|
5590
|
+
handler: async (_ctx) => {
|
|
5591
|
+
const currentVersion = "0.15.2";
|
|
5592
|
+
const lines: string[] = [
|
|
5593
|
+
"MemoryRelay Plugin Update",
|
|
5594
|
+
"━".repeat(50),
|
|
5595
|
+
`Current version: ${currentVersion}`,
|
|
5596
|
+
"",
|
|
5597
|
+
"To update to the latest version, run:",
|
|
5598
|
+
"",
|
|
5599
|
+
" openclaw plugins update plugin-memoryrelay-ai",
|
|
5600
|
+
"",
|
|
5601
|
+
"Then restart the gateway:",
|
|
5602
|
+
"",
|
|
5603
|
+
" openclaw restart",
|
|
5604
|
+
"",
|
|
5605
|
+
"Note: The plugin ID is 'plugin-memoryrelay-ai'",
|
|
5606
|
+
"(not 'memory-memoryrelay').",
|
|
5607
|
+
];
|
|
5608
|
+
return { text: lines.join("\n") };
|
|
5609
|
+
},
|
|
5610
|
+
});
|
|
5611
|
+
|
|
5583
5612
|
// ========================================================================
|
|
5584
5613
|
// Stale Session Cleanup Service (v0.13.0)
|
|
5585
5614
|
// ========================================================================
|
package/openclaw.plugin.json
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
"id": "plugin-memoryrelay-ai",
|
|
3
3
|
"kind": "memory",
|
|
4
4
|
"name": "MemoryRelay AI",
|
|
5
|
-
"description": "MemoryRelay v0.15.
|
|
6
|
-
"version": "0.15.
|
|
5
|
+
"description": "MemoryRelay v0.15.2 - Long-term memory with 42 tools, 17 commands, V2 async, sessions, decisions, patterns & projects (api.memoryrelay.net)",
|
|
6
|
+
"version": "0.15.2",
|
|
7
7
|
"uiHints": {
|
|
8
8
|
"apiKey": {
|
|
9
9
|
"label": "MemoryRelay API Key",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memoryrelay/plugin-memoryrelay-ai",
|
|
3
|
-
"version": "0.15.
|
|
4
|
-
"description": "OpenClaw memory plugin for MemoryRelay API - 42 tools,
|
|
3
|
+
"version": "0.15.2",
|
|
4
|
+
"description": "OpenClaw memory plugin for MemoryRelay API - 42 tools, 17 commands, V2 async, sessions, decisions, patterns, projects & semantic search",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.ts",
|
|
7
7
|
"scripts": {
|
package/src/status-reporter.ts
CHANGED
|
@@ -34,10 +34,25 @@ export interface MemoryStats {
|
|
|
34
34
|
search_count_24h?: number;
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
export type AutoCaptureTier = "off" | "conservative" | "smart" | "aggressive";
|
|
38
|
+
|
|
39
|
+
export interface AutoCaptureConfig {
|
|
40
|
+
enabled: boolean;
|
|
41
|
+
tier: AutoCaptureTier;
|
|
42
|
+
confirmFirst?: number;
|
|
43
|
+
categories?: {
|
|
44
|
+
credentials?: boolean;
|
|
45
|
+
preferences?: boolean;
|
|
46
|
+
technical?: boolean;
|
|
47
|
+
personal?: boolean;
|
|
48
|
+
};
|
|
49
|
+
blocklist?: string[];
|
|
50
|
+
}
|
|
51
|
+
|
|
37
52
|
export interface PluginConfig {
|
|
38
53
|
agentId: string;
|
|
39
54
|
autoRecall: boolean;
|
|
40
|
-
autoCapture:
|
|
55
|
+
autoCapture: AutoCaptureConfig;
|
|
41
56
|
recallLimit: number;
|
|
42
57
|
recallThreshold: number;
|
|
43
58
|
excludeChannels: string[];
|
|
@@ -189,7 +204,10 @@ export class StatusReporter {
|
|
|
189
204
|
? `✓ Enabled (limit: ${report.config.recallLimit}, threshold: ${report.config.recallThreshold})`
|
|
190
205
|
: "✗ Disabled";
|
|
191
206
|
lines.push(` Auto-Recall: ${recallStatus}`);
|
|
192
|
-
|
|
207
|
+
const captureStatus = report.config.autoCapture.enabled
|
|
208
|
+
? `✓ Enabled (tier: ${report.config.autoCapture.tier})`
|
|
209
|
+
: "✗ Disabled";
|
|
210
|
+
lines.push(` Auto-Capture: ${captureStatus}`);
|
|
193
211
|
if (report.config.defaultProject) {
|
|
194
212
|
lines.push(` Default Project: ${report.config.defaultProject}`);
|
|
195
213
|
}
|
|
@@ -1,105 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: codebase-navigation
|
|
3
|
-
description: "Use when navigating the openclaw-plugin codebase for the first time, looking for where a tool is registered, understanding the monolithic index.ts structure, or adding a new tool or hook."
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Codebase Navigation
|
|
7
|
-
|
|
8
|
-
The plugin is a single monolithic `index.ts` (4839 lines) plus a few extracted modules.
|
|
9
|
-
|
|
10
|
-
## index.ts File Map
|
|
11
|
-
|
|
12
|
-
| Lines | Section |
|
|
13
|
-
|-------|---------|
|
|
14
|
-
| 1--14 | Header comments and version info |
|
|
15
|
-
| 16--36 | Imports (plugin SDK, heartbeat, CLI stats, onboarding) |
|
|
16
|
-
| 38--47 | Constants (`DEFAULT_API_URL`, `REQUEST_TIMEOUT_MS`, `MAX_RETRIES`) |
|
|
17
|
-
| 48--121 | `DebugLogger` class (inlined) with `LogEntry`, `DebugLoggerConfig` |
|
|
18
|
-
| 123--404 | `StatusReporter` class (inlined) with `ToolStatus`, `ConnectionStatus`, `MemoryStats` |
|
|
19
|
-
| 406--461 | Types: `AutoCaptureConfig`, `MemoryRelayConfig`, `Memory`, `SearchResult`, `Stats` |
|
|
20
|
-
| 463--648 | Utility functions: `sleep`, `isRetryableError`, `fetchWithTimeout`, auto-capture helpers, `redactSensitive`, `extractRescueContent` |
|
|
21
|
-
| 650--1294 | `MemoryRelayClient` class (API client with retry logic, all endpoints) |
|
|
22
|
-
| 1296--1315 | Pattern detection for auto-capture (`CAPTURE_PATTERNS`, `shouldCapture`) |
|
|
23
|
-
| 1317--1562 | Plugin entry: `export default async function plugin(api)`, config resolution, client init, session cache, `touchSession` |
|
|
24
|
-
| 1564--1613 | `TOOL_GROUPS` map and `isToolEnabled()` |
|
|
25
|
-
| 1615--3747 | 39 tool registrations |
|
|
26
|
-
| 3749--3853 | CLI commands (`memoryrelay status/stats/list/export`) |
|
|
27
|
-
| 3855--4240 | 14 lifecycle hooks (`before_agent_start`, `agent_end`, `session_start`, `session_end`, `before_tool_call`, `after_tool_call`, `before_compaction`, `before_reset`, `message_received`, `message_sending`, `before_message_write`, `subagent_spawned`, `subagent_ended`, `tool_result_persist`) |
|
|
28
|
-
| 4242--4274 | First-run onboarding |
|
|
29
|
-
| 4276--4586 | Gateway methods (`memoryrelay.logs`, `.health`, `.metrics`, `.heartbeat`, `.onboarding`, `.stats`, `.test`) |
|
|
30
|
-
| 4588--4790 | Direct commands: `/memory-status`, `/memory-stats`, `/memory-health`, `/memory-logs`, `/memory-metrics` |
|
|
31
|
-
| 4792--4839 | Stale session cleanup service (`memoryrelay-session-cleanup` via `api.registerService`) |
|
|
32
|
-
|
|
33
|
-
## Tool Registration Pattern
|
|
34
|
-
|
|
35
|
-
Every tool follows this pattern:
|
|
36
|
-
|
|
37
|
-
```typescript
|
|
38
|
-
if (isToolEnabled("tool_name")) {
|
|
39
|
-
api.registerTool((ctx) => ({
|
|
40
|
-
name: "tool_name",
|
|
41
|
-
description: "...",
|
|
42
|
-
parameters: { /* JSON schema */ },
|
|
43
|
-
execute: async (_id, args) => { /* impl */ }
|
|
44
|
-
}), { name: "tool_name" });
|
|
45
|
-
}
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
Tools are numbered 1--39 with comment markers (e.g., `// 1. memory_store`). Search for `// N.` to jump to a specific tool.
|
|
49
|
-
|
|
50
|
-
## TOOL_GROUPS (line 1569)
|
|
51
|
-
|
|
52
|
-
| Group | Count | Tools |
|
|
53
|
-
|-------|-------|-------|
|
|
54
|
-
| memory | 9 | `memory_store`, `memory_recall`, `memory_forget`, `memory_list`, `memory_get`, `memory_update`, `memory_batch_store`, `memory_context`, `memory_promote` |
|
|
55
|
-
| entity | 4 | `entity_create`, `entity_link`, `entity_list`, `entity_graph` |
|
|
56
|
-
| agent | 3 | `agent_list`, `agent_create`, `agent_get` |
|
|
57
|
-
| session | 4 | `session_start`, `session_end`, `session_recall`, `session_list` |
|
|
58
|
-
| decision | 4 | `decision_record`, `decision_list`, `decision_supersede`, `decision_check` |
|
|
59
|
-
| pattern | 4 | `pattern_create`, `pattern_search`, `pattern_adopt`, `pattern_suggest` |
|
|
60
|
-
| project | 10 | `project_register`, `project_list`, `project_info`, `project_add_relationship`, `project_dependencies`, `project_dependents`, `project_related`, `project_impact`, `project_shared_patterns`, `project_context` |
|
|
61
|
-
| health | 1 | `memory_health` |
|
|
62
|
-
|
|
63
|
-
The `enabledTools` config option accepts a comma-separated list of group names (or `"all"`).
|
|
64
|
-
|
|
65
|
-
## Supporting Modules
|
|
66
|
-
|
|
67
|
-
| File | Purpose |
|
|
68
|
-
|------|---------|
|
|
69
|
-
| `src/debug-logger.ts` | `DebugLogger` class (source of the inlined copy) |
|
|
70
|
-
| `src/status-reporter.ts` | `StatusReporter` class (source of the inlined copy) |
|
|
71
|
-
| `src/heartbeat/daily-stats.ts` | Morning/evening summaries, `calculateStats`, `formatStatsForDisplay` |
|
|
72
|
-
| `src/onboarding/first-run.ts` | Onboarding wizard: `checkFirstRun`, `runSimpleOnboarding` |
|
|
73
|
-
| `src/cli/stats-command.ts` | CLI `stats` command handler |
|
|
74
|
-
|
|
75
|
-
## Configuration Fallback Chain
|
|
76
|
-
|
|
77
|
-
```
|
|
78
|
-
Plugin config (openclaw.json) -> Env vars -> Defaults
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
- `apiKey`: `cfg.apiKey` -> `MEMORYRELAY_API_KEY` (required, no default)
|
|
82
|
-
- `agentId`: `cfg.agentId` -> `MEMORYRELAY_AGENT_ID` -> `api.agentName`
|
|
83
|
-
- `apiUrl`: `cfg.apiUrl` -> `MEMORYRELAY_API_URL` -> `https://api.memoryrelay.net`
|
|
84
|
-
|
|
85
|
-
## Key Types
|
|
86
|
-
|
|
87
|
-
| Type | Location | Purpose |
|
|
88
|
-
|------|----------|---------|
|
|
89
|
-
| `Memory` | L442 | Core memory record (`id`, `content`, `agent_id`, `metadata`, `entities`) |
|
|
90
|
-
| `SearchResult` | L453 | Vector search hit (`memory`, `score`) |
|
|
91
|
-
| `Stats` | L458 | Agent statistics (`total_memories`, `last_updated`) |
|
|
92
|
-
| `LogEntry` | L52 | Debug log entry (tool, method, path, duration, status) |
|
|
93
|
-
| `DebugLoggerConfig` | L66 | Logger settings (enabled, verbose, maxEntries) |
|
|
94
|
-
| `ConnectionStatus` | L140 | API connection state (status, endpoint, responseTime) |
|
|
95
|
-
| `ToolStatus` | L127 | Per-group tool health (enabled, available, failed) |
|
|
96
|
-
|
|
97
|
-
## Key Helpers
|
|
98
|
-
|
|
99
|
-
| Function | Location | Purpose |
|
|
100
|
-
|----------|----------|---------|
|
|
101
|
-
| `redactSensitive` | L591 | Replace blocklist patterns with `[REDACTED]` |
|
|
102
|
-
| `extractRescueContent` | L608 | Salvage assistant messages before compaction/reset |
|
|
103
|
-
| `touchSession` | L1444 | Update `lastActivityAt` timestamp in session cache |
|
|
104
|
-
| `isToolEnabled` | L1605 | Check if a tool's group is in the enabled set |
|
|
105
|
-
| `shouldCapture` | L1310 | Test text against `CAPTURE_PATTERNS` for auto-capture |
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: release-process
|
|
3
|
-
description: "Use when bumping the plugin version, preparing a release, updating the CHANGELOG, creating a pre-release audit branch, or triggering the NPM publish workflow."
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Release Process
|
|
7
|
-
|
|
8
|
-
## Semantic Versioning (0.x series)
|
|
9
|
-
|
|
10
|
-
| Bump | When | Example |
|
|
11
|
-
|------|------|---------|
|
|
12
|
-
| **Patch** (0.x.Y) | Bug fixes, version string updates, doc fixes | 0.12.10 → 0.12.11 |
|
|
13
|
-
| **Minor** (0.X.0) | New tools, new features, new config options | 0.12.11 → 0.13.0 |
|
|
14
|
-
| **Major** (X.0.0) | Breaking API changes (not used yet) | 0.13.0 → 1.0.0 |
|
|
15
|
-
|
|
16
|
-
## Version Bump Locations
|
|
17
|
-
|
|
18
|
-
All three files must match the same version string:
|
|
19
|
-
|
|
20
|
-
| File | Field |
|
|
21
|
-
|------|-------|
|
|
22
|
-
| `package.json` | `"version": "X.Y.Z"` |
|
|
23
|
-
| `openclaw.plugin.json` | `"version": "X.Y.Z"` and description string |
|
|
24
|
-
| `index.ts` | Header comment `Version: X.Y.Z` |
|
|
25
|
-
|
|
26
|
-
## CHANGELOG.md Format
|
|
27
|
-
|
|
28
|
-
Follows [Keep a Changelog](https://keepachangelog.com/). Each release entry:
|
|
29
|
-
|
|
30
|
-
```markdown
|
|
31
|
-
## [X.Y.Z] - YYYY-MM-DD
|
|
32
|
-
### Added
|
|
33
|
-
- **Feature Name**: Description
|
|
34
|
-
### Changed
|
|
35
|
-
- Description
|
|
36
|
-
### Fixed
|
|
37
|
-
- **Bug Name**: Description
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
Add a comparison link at the bottom of the file:
|
|
41
|
-
|
|
42
|
-
```
|
|
43
|
-
[X.Y.Z]: https://github.com/memoryrelay/openclaw-plugin/compare/vPREV...vX.Y.Z
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
## Git Commit Conventions
|
|
47
|
-
|
|
48
|
-
| Prefix | Use |
|
|
49
|
-
|--------|-----|
|
|
50
|
-
| `feat:` | New features or tools |
|
|
51
|
-
| `fix:` | Bug fixes |
|
|
52
|
-
| `docs:` | Documentation changes |
|
|
53
|
-
| `chore:` | Maintenance, deps, cleanup |
|
|
54
|
-
|
|
55
|
-
## CI/CD Workflows
|
|
56
|
-
|
|
57
|
-
| File | Trigger | Purpose |
|
|
58
|
-
|------|---------|---------|
|
|
59
|
-
| `.github/workflows/ci.yml` | Push/PR to main | Tests on Node 20.x + 22.x matrix |
|
|
60
|
-
| `.github/workflows/ci-cd.yml` | Push/PR | Full CI/CD pipeline |
|
|
61
|
-
| `.github/workflows/publish.yml` | Manual dispatch | NPM publish with version verification |
|
|
62
|
-
|
|
63
|
-
The publish workflow runs `npm publish --provenance --access public` and requires the `NPM_TOKEN` secret.
|
|
64
|
-
|
|
65
|
-
## Pre-Release Audit Branch
|
|
66
|
-
|
|
67
|
-
For doc review before release, create an audit branch:
|
|
68
|
-
|
|
69
|
-
```
|
|
70
|
-
docs/pre-release-audit-v{version}
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
Example: `docs/pre-release-audit-v0.12.11`. Merge to main once the audit is complete.
|
|
74
|
-
|
|
75
|
-
## Release Checklist
|
|
76
|
-
|
|
77
|
-
1. Update version in all 3 locations (`package.json`, `openclaw.plugin.json`, `index.ts`)
|
|
78
|
-
2. Update `CHANGELOG.md` with new entry and comparison link
|
|
79
|
-
3. Run `npm test` -- all tests must pass
|
|
80
|
-
4. Create audit branch (`docs/pre-release-audit-v{version}`) if doc changes are needed
|
|
81
|
-
5. Merge audit branch to main
|
|
82
|
-
6. Trigger the `publish.yml` workflow manually from GitHub Actions
|
|
83
|
-
7. Verify the published package on NPM
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: testing-memoryrelay
|
|
3
|
-
description: "Use when writing, running, or debugging tests for the MemoryRelay plugin, adding test coverage for new tools or hooks, or investigating test failures."
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Testing MemoryRelay
|
|
7
|
-
|
|
8
|
-
Test runner: **Vitest**. All tests run without a live API.
|
|
9
|
-
|
|
10
|
-
## Commands
|
|
11
|
-
|
|
12
|
-
| Command | Purpose |
|
|
13
|
-
|---------|---------|
|
|
14
|
-
| `npm test` | Run all tests once (`vitest run`) |
|
|
15
|
-
| `npm run test:watch` | Watch mode (`vitest`) |
|
|
16
|
-
| `npm run test:coverage` | Coverage report (`vitest run --coverage`) |
|
|
17
|
-
|
|
18
|
-
## Test Files
|
|
19
|
-
|
|
20
|
-
| File | Scope |
|
|
21
|
-
|------|-------|
|
|
22
|
-
| `index.test.ts` | Integration tests: API client, tools, hooks, retry logic, pattern detection, channel filtering, tool groups, workflow instructions |
|
|
23
|
-
| `src/debug-logger.test.ts` | DebugLogger unit tests: circular buffer, filtering by tool/status, stats, formatting |
|
|
24
|
-
| `src/status-reporter.test.ts` | StatusReporter unit tests: failure tracking, report building, formatting |
|
|
25
|
-
|
|
26
|
-
## Mock Pattern
|
|
27
|
-
|
|
28
|
-
Tests use `MockMemoryRelayClient` -- an in-memory implementation that replaces the real API client:
|
|
29
|
-
|
|
30
|
-
```typescript
|
|
31
|
-
import { describe, test, expect, beforeEach, vi } from "vitest";
|
|
32
|
-
|
|
33
|
-
class MockMemoryRelayClient {
|
|
34
|
-
private memories: Memory[] = [];
|
|
35
|
-
private nextId = 1;
|
|
36
|
-
async store(content, metadata?) { /* push to array, return Memory */ }
|
|
37
|
-
async search(query, limit?, threshold?) { /* keyword .includes() match */ }
|
|
38
|
-
async list(limit?, offset?) { /* .slice() */ }
|
|
39
|
-
async get(id) { /* .find(), throws if missing */ }
|
|
40
|
-
async delete(id) { /* .splice(), throws if missing */ }
|
|
41
|
-
async health() { return { status: "healthy" }; }
|
|
42
|
-
async stats() { return { total_memories: this.memories.length }; }
|
|
43
|
-
}
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
Instantiate fresh per test with `beforeEach(() => { client = new MockMemoryRelayClient("test_key", "test_agent"); })`.
|
|
47
|
-
|
|
48
|
-
## What to Test per Tool
|
|
49
|
-
|
|
50
|
-
| Area | Checks |
|
|
51
|
-
|------|--------|
|
|
52
|
-
| Input validation | Required params present, types correct |
|
|
53
|
-
| Success path | API response formatted correctly, data stored/returned |
|
|
54
|
-
| Error handling | Non-existent IDs throw, empty results return `[]` |
|
|
55
|
-
| Deduplication | `deduplicate=true` prevents near-duplicate storage |
|
|
56
|
-
| Session injection | `session_id` auto-applied from active session |
|
|
57
|
-
| Retry logic | Network errors and 5xx retried; 4xx not retried |
|
|
58
|
-
| Timeouts | 30s timeout via `AbortController` |
|
|
59
|
-
|
|
60
|
-
## Testing Hooks
|
|
61
|
-
|
|
62
|
-
**`before_agent_start`** -- workflow injection and auto-recall:
|
|
63
|
-
|
|
64
|
-
- Verify workflow instructions are built from enabled tool groups
|
|
65
|
-
- Mock `client.search()` to test auto-recall injects context
|
|
66
|
-
- Test channel exclusion skips auto-recall for blocklisted channels
|
|
67
|
-
|
|
68
|
-
**`agent_end`** -- auto-capture:
|
|
69
|
-
|
|
70
|
-
- Test pattern detection (`shouldCapture`) with regex matching
|
|
71
|
-
- Verify length bounds (20-2000 chars)
|
|
72
|
-
- Confirm privacy blocklist rejects passwords, SSNs, API keys
|
|
73
|
-
- Test tier logic: `off`, `conservative`, `smart`, `aggressive`
|
|
74
|
-
|
|
75
|
-
## Testing Gateway Methods
|
|
76
|
-
|
|
77
|
-
| Check | How |
|
|
78
|
-
|-------|-----|
|
|
79
|
-
| Response format | Assert returned object shape matches API contract |
|
|
80
|
-
| Error surfaces | `detail` field extracted (FastAPI format), falls back to `message` |
|
|
81
|
-
| HTTP method | GET with query params for search/check; POST with body for create/link |
|
|
82
|
-
|
|
83
|
-
## Unit Test Patterns
|
|
84
|
-
|
|
85
|
-
**DebugLogger**: Uses `vi.mock("fs")`. Test circular buffer (`maxEntries`), `getRecentLogs(n)`, `getToolLogs(name)`, `getErrorLogs()`, `getStats()`, `clear()`, `formatEntry()`.
|
|
86
|
-
|
|
87
|
-
**StatusReporter**: Instantiate with real `DebugLogger`. Test `recordFailure`/`recordSuccess` toggle, `buildReport` shape, `formatReport`/`formatCompact` output, disconnected status handling.
|