@memoryrelay/plugin-memoryrelay-ai 0.8.4 → 0.8.6
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/index.ts +11 -9
- package/openclaw.plugin.json +2 -2
- package/package.json +3 -2
- package/src/debug-logger.test.ts +0 -233
- package/src/status-reporter.test.ts +0 -230
package/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* OpenClaw Memory Plugin - MemoryRelay
|
|
3
|
-
* Version: 0.8.
|
|
3
|
+
* Version: 0.8.6 (OpenClaw Security Compliance)
|
|
4
4
|
*
|
|
5
5
|
* Long-term memory with vector search using MemoryRelay API.
|
|
6
6
|
* Provides auto-recall and auto-capture via lifecycle hooks.
|
|
@@ -9,6 +9,11 @@
|
|
|
9
9
|
* API: https://api.memoryrelay.net
|
|
10
10
|
* Docs: https://memoryrelay.ai
|
|
11
11
|
*
|
|
12
|
+
* ENHANCEMENTS (v0.8.6):
|
|
13
|
+
* - Removed fs.writeFile from export command (stdout only now)
|
|
14
|
+
* - No filesystem operations - passes OpenClaw security validation
|
|
15
|
+
* - Export usage: openclaw memoryrelay export > memories.json
|
|
16
|
+
*
|
|
12
17
|
* ENHANCEMENTS (v0.8.4):
|
|
13
18
|
* - Removed file logging feature to pass OpenClaw security validation
|
|
14
19
|
* - All debug logs now in-memory only (circular buffer)
|
|
@@ -858,7 +863,7 @@ export default async function plugin(api: OpenClawPluginApi): Promise<void> {
|
|
|
858
863
|
const verboseEnabled = cfg?.verbose || false;
|
|
859
864
|
const maxLogEntries = cfg?.maxLogEntries || 100;
|
|
860
865
|
|
|
861
|
-
// Note: logFile is deprecated in v0.8.
|
|
866
|
+
// Note: logFile is deprecated in v0.8.6 (removed for OpenClaw security compliance)
|
|
862
867
|
// All debug logs are in-memory only. Use gateway methods to access logs.
|
|
863
868
|
|
|
864
869
|
let debugLogger: DebugLogger | undefined;
|
|
@@ -3209,15 +3214,12 @@ export default async function plugin(api: OpenClawPluginApi): Promise<void> {
|
|
|
3209
3214
|
|
|
3210
3215
|
mem
|
|
3211
3216
|
.command("export")
|
|
3212
|
-
.description("Export all memories to JSON
|
|
3213
|
-
.
|
|
3214
|
-
.action(async (opts) => {
|
|
3217
|
+
.description("Export all memories to JSON (outputs to stdout)")
|
|
3218
|
+
.action(async () => {
|
|
3215
3219
|
try {
|
|
3216
|
-
console.log("Exporting memories...");
|
|
3217
3220
|
const memories = await client.export();
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
console.log(`Exported ${memories.length} memories to ${opts.output}`);
|
|
3221
|
+
console.log(JSON.stringify(memories, null, 2));
|
|
3222
|
+
console.error(`\n# Exported ${memories.length} memories. Redirect stdout to save: memoryrelay export > memories.json`);
|
|
3221
3223
|
} catch (err) {
|
|
3222
3224
|
console.error(`Export failed: ${String(err)}`);
|
|
3223
3225
|
}
|
package/openclaw.plugin.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"kind": "memory",
|
|
4
4
|
"name": "MemoryRelay AI",
|
|
5
5
|
"description": "AI memory service with sessions, decisions, patterns & projects (api.memoryrelay.net)",
|
|
6
|
-
"version": "0.8.
|
|
6
|
+
"version": "0.8.6",
|
|
7
7
|
"uiHints": {
|
|
8
8
|
"apiKey": {
|
|
9
9
|
"label": "MemoryRelay API Key",
|
|
@@ -113,7 +113,7 @@
|
|
|
113
113
|
},
|
|
114
114
|
"logFile": {
|
|
115
115
|
"type": "string",
|
|
116
|
-
"description": "DEPRECATED (v0.8.
|
|
116
|
+
"description": "DEPRECATED (v0.8.6): File logging removed for OpenClaw security compliance. This option is ignored. Use gateway methods to access in-memory logs (coming in v0.9.0)."
|
|
117
117
|
},
|
|
118
118
|
"maxLogEntries": {
|
|
119
119
|
"type": "number",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memoryrelay/plugin-memoryrelay-ai",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.6",
|
|
4
4
|
"description": "OpenClaw memory plugin for MemoryRelay API - sessions, decisions, patterns, projects & semantic search",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.ts",
|
|
@@ -51,7 +51,8 @@
|
|
|
51
51
|
},
|
|
52
52
|
"files": [
|
|
53
53
|
"index.ts",
|
|
54
|
-
"src
|
|
54
|
+
"src/*.ts",
|
|
55
|
+
"!src/*.test.ts",
|
|
55
56
|
"bin/",
|
|
56
57
|
"openclaw.plugin.json",
|
|
57
58
|
"README.md",
|
package/src/debug-logger.test.ts
DELETED
|
@@ -1,233 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* DebugLogger Tests (Corrected)
|
|
3
|
-
*
|
|
4
|
-
* Tests matching actual implementation
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { describe, test, expect, beforeEach, vi } from "vitest";
|
|
8
|
-
import { DebugLogger, type LogEntry } from "./debug-logger";
|
|
9
|
-
import * as fs from "fs";
|
|
10
|
-
|
|
11
|
-
vi.mock("fs");
|
|
12
|
-
|
|
13
|
-
describe("DebugLogger", () => {
|
|
14
|
-
let logger: DebugLogger;
|
|
15
|
-
|
|
16
|
-
beforeEach(() => {
|
|
17
|
-
vi.clearAllMocks();
|
|
18
|
-
logger = new DebugLogger({
|
|
19
|
-
enabled: true,
|
|
20
|
-
verbose: false,
|
|
21
|
-
maxEntries: 5,
|
|
22
|
-
});
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
test("logs are stored when enabled", () => {
|
|
26
|
-
logger.log({
|
|
27
|
-
timestamp: new Date().toISOString(),
|
|
28
|
-
tool: "memory_store",
|
|
29
|
-
method: "POST",
|
|
30
|
-
path: "/v1/memories",
|
|
31
|
-
duration: 142,
|
|
32
|
-
status: "success",
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
const logs = logger.getAllLogs();
|
|
36
|
-
expect(logs).toHaveLength(1);
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
test("logs are not stored when disabled", () => {
|
|
40
|
-
const disabledLogger = new DebugLogger({
|
|
41
|
-
enabled: false,
|
|
42
|
-
verbose: false,
|
|
43
|
-
maxEntries: 5,
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
disabledLogger.log({
|
|
47
|
-
timestamp: new Date().toISOString(),
|
|
48
|
-
tool: "memory_store",
|
|
49
|
-
method: "POST",
|
|
50
|
-
path: "/v1/memories",
|
|
51
|
-
duration: 142,
|
|
52
|
-
status: "success",
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
const logs = disabledLogger.getAllLogs();
|
|
56
|
-
expect(logs).toHaveLength(0);
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
test("respects circular buffer limit (FIFO)", () => {
|
|
60
|
-
for (let i = 0; i < 10; i++) {
|
|
61
|
-
logger.log({
|
|
62
|
-
timestamp: new Date(Date.now() + i).toISOString(),
|
|
63
|
-
tool: `tool_${i}`,
|
|
64
|
-
method: "GET",
|
|
65
|
-
path: `/test/${i}`,
|
|
66
|
-
duration: 100,
|
|
67
|
-
status: "success",
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const logs = logger.getAllLogs();
|
|
72
|
-
expect(logs).toHaveLength(5); // maxEntries = 5
|
|
73
|
-
expect(logs[0].tool).toBe("tool_5"); // Oldest kept
|
|
74
|
-
expect(logs[4].tool).toBe("tool_9"); // Newest
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
test("getRecentLogs returns last N entries", () => {
|
|
78
|
-
for (let i = 0; i < 3; i++) {
|
|
79
|
-
logger.log({
|
|
80
|
-
timestamp: new Date(Date.now() + i).toISOString(),
|
|
81
|
-
tool: `tool_${i}`,
|
|
82
|
-
method: "GET",
|
|
83
|
-
path: `/test/${i}`,
|
|
84
|
-
duration: 100,
|
|
85
|
-
status: "success",
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const logs = logger.getRecentLogs(2);
|
|
90
|
-
expect(logs).toHaveLength(2);
|
|
91
|
-
expect(logs[0].tool).toBe("tool_1"); // Second-to-last
|
|
92
|
-
expect(logs[1].tool).toBe("tool_2"); // Last
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
test("getToolLogs filters by tool name", () => {
|
|
96
|
-
logger.log({
|
|
97
|
-
timestamp: new Date().toISOString(),
|
|
98
|
-
tool: "memory_store",
|
|
99
|
-
method: "POST",
|
|
100
|
-
path: "/v1/memories",
|
|
101
|
-
duration: 142,
|
|
102
|
-
status: "success",
|
|
103
|
-
});
|
|
104
|
-
logger.log({
|
|
105
|
-
timestamp: new Date().toISOString(),
|
|
106
|
-
tool: "memory_recall",
|
|
107
|
-
method: "POST",
|
|
108
|
-
path: "/v1/memories/search",
|
|
109
|
-
duration: 78,
|
|
110
|
-
status: "success",
|
|
111
|
-
});
|
|
112
|
-
logger.log({
|
|
113
|
-
timestamp: new Date().toISOString(),
|
|
114
|
-
tool: "memory_store",
|
|
115
|
-
method: "POST",
|
|
116
|
-
path: "/v1/memories",
|
|
117
|
-
duration: 156,
|
|
118
|
-
status: "error",
|
|
119
|
-
error: "500",
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
const logs = logger.getToolLogs("memory_store", 10);
|
|
123
|
-
expect(logs).toHaveLength(2);
|
|
124
|
-
expect(logs.every(l => l.tool === "memory_store")).toBe(true);
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
test("getErrorLogs filters by error status", () => {
|
|
128
|
-
logger.log({
|
|
129
|
-
timestamp: new Date().toISOString(),
|
|
130
|
-
tool: "memory_store",
|
|
131
|
-
method: "POST",
|
|
132
|
-
path: "/v1/memories",
|
|
133
|
-
duration: 142,
|
|
134
|
-
status: "success",
|
|
135
|
-
});
|
|
136
|
-
logger.log({
|
|
137
|
-
timestamp: new Date().toISOString(),
|
|
138
|
-
tool: "memory_recall",
|
|
139
|
-
method: "POST",
|
|
140
|
-
path: "/v1/memories/search",
|
|
141
|
-
duration: 78,
|
|
142
|
-
status: "error",
|
|
143
|
-
error: "404",
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
const logs = logger.getErrorLogs(10);
|
|
147
|
-
expect(logs).toHaveLength(1);
|
|
148
|
-
expect(logs[0].status).toBe("error");
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
test("getStats calculates correctly", () => {
|
|
152
|
-
logger.log({
|
|
153
|
-
timestamp: new Date().toISOString(),
|
|
154
|
-
tool: "memory_store",
|
|
155
|
-
method: "POST",
|
|
156
|
-
path: "/v1/memories",
|
|
157
|
-
duration: 100,
|
|
158
|
-
status: "success",
|
|
159
|
-
});
|
|
160
|
-
logger.log({
|
|
161
|
-
timestamp: new Date().toISOString(),
|
|
162
|
-
tool: "memory_recall",
|
|
163
|
-
method: "POST",
|
|
164
|
-
path: "/v1/memories/search",
|
|
165
|
-
duration: 200,
|
|
166
|
-
status: "success",
|
|
167
|
-
});
|
|
168
|
-
logger.log({
|
|
169
|
-
timestamp: new Date().toISOString(),
|
|
170
|
-
tool: "memory_store",
|
|
171
|
-
method: "POST",
|
|
172
|
-
path: "/v1/memories",
|
|
173
|
-
duration: 150,
|
|
174
|
-
status: "error",
|
|
175
|
-
error: "500",
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
const stats = logger.getStats();
|
|
179
|
-
expect(stats.total).toBe(3);
|
|
180
|
-
expect(stats.successful).toBe(2);
|
|
181
|
-
expect(stats.failed).toBe(1);
|
|
182
|
-
expect(stats.avgDuration).toBe(150); // (100+200+150)/3 = 150
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
test("clear() empties logs", () => {
|
|
186
|
-
logger.log({
|
|
187
|
-
timestamp: new Date().toISOString(),
|
|
188
|
-
tool: "memory_store",
|
|
189
|
-
method: "POST",
|
|
190
|
-
path: "/v1/memories",
|
|
191
|
-
duration: 142,
|
|
192
|
-
status: "success",
|
|
193
|
-
});
|
|
194
|
-
|
|
195
|
-
logger.clear();
|
|
196
|
-
const logs = logger.getAllLogs();
|
|
197
|
-
expect(logs).toHaveLength(0);
|
|
198
|
-
});
|
|
199
|
-
|
|
200
|
-
test("formatEntry creates human-readable output", () => {
|
|
201
|
-
const entry: LogEntry = {
|
|
202
|
-
timestamp: new Date().toISOString(),
|
|
203
|
-
tool: "memory_store",
|
|
204
|
-
method: "POST",
|
|
205
|
-
path: "/v1/memories",
|
|
206
|
-
duration: 142,
|
|
207
|
-
status: "success",
|
|
208
|
-
};
|
|
209
|
-
|
|
210
|
-
const formatted = DebugLogger.formatEntry(entry);
|
|
211
|
-
expect(formatted).toContain("memory_store");
|
|
212
|
-
expect(formatted).toContain("142ms");
|
|
213
|
-
expect(formatted).toContain("✓");
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
test("formatEntry shows error", () => {
|
|
217
|
-
const entry: LogEntry = {
|
|
218
|
-
timestamp: new Date().toISOString(),
|
|
219
|
-
tool: "memory_store",
|
|
220
|
-
method: "POST",
|
|
221
|
-
path: "/v1/memories",
|
|
222
|
-
duration: 156,
|
|
223
|
-
status: "error",
|
|
224
|
-
error: "500 Internal Server Error",
|
|
225
|
-
};
|
|
226
|
-
|
|
227
|
-
const formatted = DebugLogger.formatEntry(entry);
|
|
228
|
-
expect(formatted).toContain("memory_store");
|
|
229
|
-
expect(formatted).toContain("156ms");
|
|
230
|
-
expect(formatted).toContain("✗");
|
|
231
|
-
expect(formatted).toContain("500 Internal Server Error");
|
|
232
|
-
});
|
|
233
|
-
});
|
|
@@ -1,230 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* StatusReporter Tests (Simplified)
|
|
3
|
-
*
|
|
4
|
-
* Tests matching actual implementation
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { describe, test, expect, beforeEach } from "vitest";
|
|
8
|
-
import { StatusReporter, type ConnectionStatus, type PluginConfig, type MemoryStats } from "./status-reporter";
|
|
9
|
-
import { DebugLogger } from "./debug-logger";
|
|
10
|
-
|
|
11
|
-
describe("StatusReporter", () => {
|
|
12
|
-
let reporter: StatusReporter;
|
|
13
|
-
let debugLogger: DebugLogger;
|
|
14
|
-
let mockConnection: ConnectionStatus;
|
|
15
|
-
let mockConfig: PluginConfig;
|
|
16
|
-
let mockStats: MemoryStats;
|
|
17
|
-
|
|
18
|
-
beforeEach(() => {
|
|
19
|
-
debugLogger = new DebugLogger({
|
|
20
|
-
enabled: true,
|
|
21
|
-
verbose: false,
|
|
22
|
-
maxEntries: 100,
|
|
23
|
-
});
|
|
24
|
-
reporter = new StatusReporter(debugLogger);
|
|
25
|
-
|
|
26
|
-
mockConnection = {
|
|
27
|
-
status: "connected",
|
|
28
|
-
endpoint: "https://api.memoryrelay.net",
|
|
29
|
-
lastCheck: new Date().toISOString(),
|
|
30
|
-
responseTime: 45,
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
mockConfig = {
|
|
34
|
-
agentId: "test-agent",
|
|
35
|
-
autoRecall: true,
|
|
36
|
-
autoCapture: false,
|
|
37
|
-
recallLimit: 5,
|
|
38
|
-
recallThreshold: 0.3,
|
|
39
|
-
excludeChannels: [],
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
mockStats = {
|
|
43
|
-
total_memories: 100,
|
|
44
|
-
};
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
test("records and clears tool failures", () => {
|
|
48
|
-
reporter.recordFailure("memory_store", "500 Error");
|
|
49
|
-
let issues = reporter.getIssues();
|
|
50
|
-
expect(issues).toHaveLength(1);
|
|
51
|
-
expect(issues[0].tool).toBe("memory_store");
|
|
52
|
-
|
|
53
|
-
reporter.recordSuccess("memory_store");
|
|
54
|
-
issues = reporter.getIssues();
|
|
55
|
-
expect(issues).toHaveLength(0);
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
test("buildReport creates status report", () => {
|
|
59
|
-
const toolGroups = {
|
|
60
|
-
"Core Memory": ["memory_store", "memory_recall"],
|
|
61
|
-
"Projects": ["project_list"],
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
const report = reporter.buildReport(
|
|
65
|
-
mockConnection,
|
|
66
|
-
mockConfig,
|
|
67
|
-
mockStats,
|
|
68
|
-
toolGroups,
|
|
69
|
-
);
|
|
70
|
-
|
|
71
|
-
expect(report.connection).toEqual(mockConnection);
|
|
72
|
-
expect(report.config).toEqual(mockConfig);
|
|
73
|
-
expect(report.stats).toEqual(mockStats);
|
|
74
|
-
expect(report.tools["Core Memory"]).toBeDefined();
|
|
75
|
-
expect(report.tools["Projects"]).toBeDefined();
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
test("buildReport includes tool status from debug logs", () => {
|
|
79
|
-
debugLogger.log({
|
|
80
|
-
timestamp: new Date().toISOString(),
|
|
81
|
-
tool: "memory_store",
|
|
82
|
-
method: "POST",
|
|
83
|
-
path: "/v1/memories",
|
|
84
|
-
duration: 142,
|
|
85
|
-
status: "success",
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
const toolGroups = {
|
|
89
|
-
"Core Memory": ["memory_store"],
|
|
90
|
-
};
|
|
91
|
-
|
|
92
|
-
const report = reporter.buildReport(
|
|
93
|
-
mockConnection,
|
|
94
|
-
mockConfig,
|
|
95
|
-
mockStats,
|
|
96
|
-
toolGroups,
|
|
97
|
-
);
|
|
98
|
-
|
|
99
|
-
const memoryTools = report.tools["Core Memory"];
|
|
100
|
-
expect(memoryTools.available).toBe(1);
|
|
101
|
-
expect(memoryTools.failed).toBe(0);
|
|
102
|
-
expect(memoryTools.tools[0].status).toBe("working");
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
test("buildReport shows failed tools", () => {
|
|
106
|
-
debugLogger.log({
|
|
107
|
-
timestamp: new Date().toISOString(),
|
|
108
|
-
tool: "memory_store",
|
|
109
|
-
method: "POST",
|
|
110
|
-
path: "/v1/memories",
|
|
111
|
-
duration: 156,
|
|
112
|
-
status: "error",
|
|
113
|
-
error: "500 Internal Server Error",
|
|
114
|
-
});
|
|
115
|
-
|
|
116
|
-
const toolGroups = {
|
|
117
|
-
"Core Memory": ["memory_store"],
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
const report = reporter.buildReport(
|
|
121
|
-
mockConnection,
|
|
122
|
-
mockConfig,
|
|
123
|
-
mockStats,
|
|
124
|
-
toolGroups,
|
|
125
|
-
);
|
|
126
|
-
|
|
127
|
-
const memoryTools = report.tools["Core Memory"];
|
|
128
|
-
expect(memoryTools.available).toBe(0);
|
|
129
|
-
expect(memoryTools.failed).toBe(1);
|
|
130
|
-
expect(memoryTools.tools[0].status).toBe("error");
|
|
131
|
-
expect(memoryTools.tools[0].error).toBe("500 Internal Server Error");
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
test("buildReport includes recent calls", () => {
|
|
135
|
-
debugLogger.log({
|
|
136
|
-
timestamp: new Date().toISOString(),
|
|
137
|
-
tool: "memory_store",
|
|
138
|
-
method: "POST",
|
|
139
|
-
path: "/v1/memories",
|
|
140
|
-
duration: 142,
|
|
141
|
-
status: "success",
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
const toolGroups = {
|
|
145
|
-
"Core Memory": ["memory_store"],
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
const report = reporter.buildReport(
|
|
149
|
-
mockConnection,
|
|
150
|
-
mockConfig,
|
|
151
|
-
mockStats,
|
|
152
|
-
toolGroups,
|
|
153
|
-
);
|
|
154
|
-
|
|
155
|
-
expect(report.recentCalls).toHaveLength(1);
|
|
156
|
-
expect(report.recentCalls[0].tool).toBe("memory_store");
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
test("formatReport creates human-readable output", () => {
|
|
160
|
-
const toolGroups = {
|
|
161
|
-
"Core Memory": ["memory_store", "memory_recall"],
|
|
162
|
-
};
|
|
163
|
-
|
|
164
|
-
const report = reporter.buildReport(
|
|
165
|
-
mockConnection,
|
|
166
|
-
mockConfig,
|
|
167
|
-
mockStats,
|
|
168
|
-
toolGroups,
|
|
169
|
-
);
|
|
170
|
-
|
|
171
|
-
const formatted = StatusReporter.formatReport(report);
|
|
172
|
-
expect(formatted).toContain("MemoryRelay Plugin Status");
|
|
173
|
-
expect(formatted).toContain("connected");
|
|
174
|
-
expect(formatted).toContain("Core Memory");
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
test("formatCompact creates brief output", () => {
|
|
178
|
-
const toolGroups = {
|
|
179
|
-
"Core Memory": ["memory_store"],
|
|
180
|
-
};
|
|
181
|
-
|
|
182
|
-
const report = reporter.buildReport(
|
|
183
|
-
mockConnection,
|
|
184
|
-
mockConfig,
|
|
185
|
-
mockStats,
|
|
186
|
-
toolGroups,
|
|
187
|
-
);
|
|
188
|
-
|
|
189
|
-
const compact = StatusReporter.formatCompact(report);
|
|
190
|
-
expect(compact).toContain("connected");
|
|
191
|
-
expect(compact.length).toBeLessThan(200); // Should be brief
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
test("handles disconnected status", () => {
|
|
195
|
-
mockConnection.status = "disconnected";
|
|
196
|
-
|
|
197
|
-
const toolGroups = {
|
|
198
|
-
"Core Memory": ["memory_store"],
|
|
199
|
-
};
|
|
200
|
-
|
|
201
|
-
const report = reporter.buildReport(
|
|
202
|
-
mockConnection,
|
|
203
|
-
mockConfig,
|
|
204
|
-
mockStats,
|
|
205
|
-
toolGroups,
|
|
206
|
-
);
|
|
207
|
-
|
|
208
|
-
expect(report.connection.status).toBe("disconnected");
|
|
209
|
-
const formatted = StatusReporter.formatReport(report);
|
|
210
|
-
expect(formatted).toContain("disconnected");
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
test("includes issues in report", () => {
|
|
214
|
-
reporter.recordFailure("memory_batch_store", "500 Error");
|
|
215
|
-
|
|
216
|
-
const toolGroups = {
|
|
217
|
-
"Core Memory": ["memory_batch_store"],
|
|
218
|
-
};
|
|
219
|
-
|
|
220
|
-
const report = reporter.buildReport(
|
|
221
|
-
mockConnection,
|
|
222
|
-
mockConfig,
|
|
223
|
-
mockStats,
|
|
224
|
-
toolGroups,
|
|
225
|
-
);
|
|
226
|
-
|
|
227
|
-
expect(report.issues).toHaveLength(1);
|
|
228
|
-
expect(report.issues[0].tool).toBe("memory_batch_store");
|
|
229
|
-
});
|
|
230
|
-
});
|