@prometheus-ai/memory 0.5.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 +107 -0
- package/dist/types/cli.d.ts +35 -0
- package/dist/types/config.d.ts +77 -0
- package/dist/types/core/aaak.d.ts +55 -0
- package/dist/types/core/annotations.d.ts +75 -0
- package/dist/types/core/banks.d.ts +33 -0
- package/dist/types/core/beam/consolidate.d.ts +32 -0
- package/dist/types/core/beam/helpers.d.ts +76 -0
- package/dist/types/core/beam/index.d.ts +59 -0
- package/dist/types/core/beam/recall.d.ts +32 -0
- package/dist/types/core/beam/schema.d.ts +2 -0
- package/dist/types/core/beam/store.d.ts +35 -0
- package/dist/types/core/beam/types.d.ts +233 -0
- package/dist/types/core/binary-vectors.d.ts +54 -0
- package/dist/types/core/chat-normalize.d.ts +13 -0
- package/dist/types/core/content-sanitizer.d.ts +18 -0
- package/dist/types/core/cost-log.d.ts +13 -0
- package/dist/types/core/embeddings.d.ts +44 -0
- package/dist/types/core/entities.d.ts +7 -0
- package/dist/types/core/episodic-graph.d.ts +89 -0
- package/dist/types/core/extraction/client.d.ts +31 -0
- package/dist/types/core/extraction/diagnostics.d.ts +51 -0
- package/dist/types/core/extraction/prompts.d.ts +2 -0
- package/dist/types/core/extraction.d.ts +6 -0
- package/dist/types/core/index.d.ts +4 -0
- package/dist/types/core/llm-backends.d.ts +21 -0
- package/dist/types/core/local-llm.d.ts +15 -0
- package/dist/types/core/memory.d.ts +160 -0
- package/dist/types/core/migrations/e6-triplestore-split.d.ts +17 -0
- package/dist/types/core/migrations/index.d.ts +1 -0
- package/dist/types/core/mmr.d.ts +8 -0
- package/dist/types/core/orchestrator.d.ts +20 -0
- package/dist/types/core/patterns.d.ts +61 -0
- package/dist/types/core/plugins.d.ts +109 -0
- package/dist/types/core/polyphonic-recall.d.ts +66 -0
- package/dist/types/core/query-cache.d.ts +46 -0
- package/dist/types/core/query-intent.d.ts +20 -0
- package/dist/types/core/recall-diagnostics.d.ts +48 -0
- package/dist/types/core/runtime-options.d.ts +68 -0
- package/dist/types/core/shmr.d.ts +56 -0
- package/dist/types/core/streaming.d.ts +136 -0
- package/dist/types/core/synonyms.d.ts +46 -0
- package/dist/types/core/temporal-parser.d.ts +16 -0
- package/dist/types/core/token-counter.d.ts +8 -0
- package/dist/types/core/triples.d.ts +63 -0
- package/dist/types/core/typed-memory.d.ts +39 -0
- package/dist/types/core/vector-math.d.ts +1 -0
- package/dist/types/core/veracity-consolidation.d.ts +60 -0
- package/dist/types/core/weibull.d.ts +96 -0
- package/dist/types/db.d.ts +16 -0
- package/dist/types/diagnose.d.ts +24 -0
- package/dist/types/dr/index.d.ts +1 -0
- package/dist/types/dr/recovery.d.ts +68 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/mcp-server.d.ts +40 -0
- package/dist/types/mcp-tools.d.ts +484 -0
- package/dist/types/migrations/e6-triplestore-split.d.ts +1 -0
- package/dist/types/migrations/index.d.ts +1 -0
- package/dist/types/types.d.ts +145 -0
- package/dist/types/util/datetime.d.ts +8 -0
- package/dist/types/util/env.d.ts +10 -0
- package/dist/types/util/ids.d.ts +3 -0
- package/dist/types/util/lru.d.ts +12 -0
- package/dist/types/util/regex.d.ts +10 -0
- package/package.json +85 -0
- package/src/cli.ts +398 -0
- package/src/config.ts +326 -0
- package/src/core/aaak.ts +142 -0
- package/src/core/annotations.ts +457 -0
- package/src/core/banks.ts +133 -0
- package/src/core/beam/consolidate.ts +965 -0
- package/src/core/beam/helpers.ts +977 -0
- package/src/core/beam/index.ts +353 -0
- package/src/core/beam/recall.ts +1100 -0
- package/src/core/beam/schema.ts +423 -0
- package/src/core/beam/store.ts +829 -0
- package/src/core/beam/types.ts +268 -0
- package/src/core/binary-vectors.ts +317 -0
- package/src/core/chat-normalize.ts +160 -0
- package/src/core/content-sanitizer.ts +136 -0
- package/src/core/cost-log.ts +103 -0
- package/src/core/embeddings.ts +423 -0
- package/src/core/entities.ts +259 -0
- package/src/core/episodic-graph.ts +708 -0
- package/src/core/extraction/client.ts +162 -0
- package/src/core/extraction/diagnostics.ts +193 -0
- package/src/core/extraction/prompts.ts +31 -0
- package/src/core/extraction.ts +335 -0
- package/src/core/index.ts +30 -0
- package/src/core/llm-backends.ts +51 -0
- package/src/core/local-llm.ts +436 -0
- package/src/core/memory.ts +630 -0
- package/src/core/migrations/e6-triplestore-split.ts +211 -0
- package/src/core/migrations/index.ts +1 -0
- package/src/core/mmr.ts +71 -0
- package/src/core/orchestrator.ts +62 -0
- package/src/core/patterns.ts +484 -0
- package/src/core/plugins.ts +375 -0
- package/src/core/polyphonic-recall.ts +563 -0
- package/src/core/query-cache.ts +354 -0
- package/src/core/query-intent.ts +139 -0
- package/src/core/recall-diagnostics.ts +157 -0
- package/src/core/runtime-options.ts +119 -0
- package/src/core/shmr.ts +460 -0
- package/src/core/streaming.ts +419 -0
- package/src/core/synonyms.ts +197 -0
- package/src/core/temporal-parser.ts +363 -0
- package/src/core/token-counter.ts +30 -0
- package/src/core/triples.ts +454 -0
- package/src/core/typed-memory.ts +407 -0
- package/src/core/vector-math.ts +23 -0
- package/src/core/veracity-consolidation.ts +477 -0
- package/src/core/weibull.ts +124 -0
- package/src/db.ts +128 -0
- package/src/diagnose.ts +174 -0
- package/src/dr/index.ts +1 -0
- package/src/dr/recovery.ts +405 -0
- package/src/index.ts +33 -0
- package/src/mcp-server.ts +155 -0
- package/src/mcp-tools.ts +970 -0
- package/src/migrations/e6-triplestore-split.ts +1 -0
- package/src/migrations/index.ts +1 -0
- package/src/types.ts +157 -0
- package/src/util/datetime.ts +69 -0
- package/src/util/env.ts +65 -0
- package/src/util/ids.ts +19 -0
- package/src/util/lru.ts +48 -0
- package/src/util/regex.ts +165 -0
package/src/mcp-tools.ts
ADDED
|
@@ -0,0 +1,970 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { DEFAULT_DB_FILENAME, dataDir } from "./config";
|
|
4
|
+
import { BankManager } from "./core/banks";
|
|
5
|
+
import { BeamMemory, type RecallOptions } from "./core/beam";
|
|
6
|
+
import { addTriple, queryTriples } from "./core/triples";
|
|
7
|
+
|
|
8
|
+
export type JsonPrimitive = string | number | boolean | null;
|
|
9
|
+
export type JsonValue = JsonPrimitive | JsonValue[] | { [key: string]: JsonValue };
|
|
10
|
+
export type ToolArguments = Record<string, unknown>;
|
|
11
|
+
export type ToolResult = Record<string, unknown>;
|
|
12
|
+
|
|
13
|
+
export interface ToolDefinition {
|
|
14
|
+
readonly name: string;
|
|
15
|
+
readonly description: string;
|
|
16
|
+
readonly inputSchema: {
|
|
17
|
+
readonly type: "object";
|
|
18
|
+
readonly properties: Record<string, unknown>;
|
|
19
|
+
readonly required?: readonly string[];
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const EMPTY_SCHEMA = { type: "object", properties: {} } as const;
|
|
24
|
+
|
|
25
|
+
export const REMEMBER_SCHEMA = {
|
|
26
|
+
type: "object",
|
|
27
|
+
properties: {
|
|
28
|
+
content: { type: "string", description: "The memory content to store." },
|
|
29
|
+
importance: { type: "number", description: "Importance score from 0.0 to 1.0.", default: 0.5 },
|
|
30
|
+
source: { type: "string", description: "Source tag for this memory.", default: "user" },
|
|
31
|
+
scope: {
|
|
32
|
+
type: "string",
|
|
33
|
+
description: "Memory scope: session, global, channel, or a custom scope.",
|
|
34
|
+
default: "session",
|
|
35
|
+
},
|
|
36
|
+
valid_until: { type: "string", description: "Optional expiry date or timestamp." },
|
|
37
|
+
extract_entities: {
|
|
38
|
+
type: "boolean",
|
|
39
|
+
description: "Extract named entities for fuzzy recall.",
|
|
40
|
+
default: false,
|
|
41
|
+
},
|
|
42
|
+
extract: {
|
|
43
|
+
type: "boolean",
|
|
44
|
+
description: "Extract structured facts from content.",
|
|
45
|
+
default: false,
|
|
46
|
+
},
|
|
47
|
+
metadata: { type: "object", description: "Optional key-value metadata.", default: {} },
|
|
48
|
+
veracity: {
|
|
49
|
+
type: "string",
|
|
50
|
+
description: "Confidence label for the memory.",
|
|
51
|
+
default: "unknown",
|
|
52
|
+
},
|
|
53
|
+
author_id: { type: "string", description: "Author identifier for this MCP call." },
|
|
54
|
+
author_type: { type: "string", description: "Author type: human, agent, or system." },
|
|
55
|
+
channel_id: { type: "string", description: "Channel or group this memory belongs to." },
|
|
56
|
+
bank: { type: "string", description: "Memory bank to store in.", default: "default" },
|
|
57
|
+
},
|
|
58
|
+
required: ["content"],
|
|
59
|
+
} as const;
|
|
60
|
+
|
|
61
|
+
export const RECALL_SCHEMA = {
|
|
62
|
+
type: "object",
|
|
63
|
+
properties: {
|
|
64
|
+
query: { type: "string", description: "Natural-language search query." },
|
|
65
|
+
limit: { type: "integer", description: "Maximum results to return.", default: 5 },
|
|
66
|
+
top_k: { type: "integer", description: "Maximum results to return.", default: 5 },
|
|
67
|
+
bank: { type: "string", description: "Memory bank to search.", default: "default" },
|
|
68
|
+
temporal_weight: {
|
|
69
|
+
type: "number",
|
|
70
|
+
description: "Temporal boost weight. 0.0 disables recency boost.",
|
|
71
|
+
default: 0.0,
|
|
72
|
+
},
|
|
73
|
+
query_time: {
|
|
74
|
+
type: "string",
|
|
75
|
+
description: "ISO timestamp to treat as now for temporal scoring.",
|
|
76
|
+
},
|
|
77
|
+
temporal_halflife: {
|
|
78
|
+
type: "number",
|
|
79
|
+
description: "Temporal decay half-life in hours.",
|
|
80
|
+
default: 24,
|
|
81
|
+
},
|
|
82
|
+
vec_weight: { type: "number", description: "Vector similarity weight." },
|
|
83
|
+
fts_weight: { type: "number", description: "Full-text search weight." },
|
|
84
|
+
importance_weight: { type: "number", description: "Importance score weight." },
|
|
85
|
+
author_id: { type: "string", description: "Filter by author identifier." },
|
|
86
|
+
author_type: { type: "string", description: "Filter by author type." },
|
|
87
|
+
channel_id: { type: "string", description: "Filter by channel/group." },
|
|
88
|
+
},
|
|
89
|
+
required: ["query"],
|
|
90
|
+
} as const;
|
|
91
|
+
|
|
92
|
+
export const SHARED_REMEMBER_SCHEMA = {
|
|
93
|
+
type: "object",
|
|
94
|
+
properties: {
|
|
95
|
+
content: { type: "string", description: "Surface memory content to store." },
|
|
96
|
+
kind: {
|
|
97
|
+
type: "string",
|
|
98
|
+
description: "meta | preference | correction | identity",
|
|
99
|
+
default: "meta",
|
|
100
|
+
},
|
|
101
|
+
importance: { type: "number", description: "Importance score from 0.0 to 1.0.", default: 0.8 },
|
|
102
|
+
veracity: { type: "string", description: "Confidence label.", default: "unknown" },
|
|
103
|
+
metadata: { type: "object", description: "Optional metadata object.", default: {} },
|
|
104
|
+
},
|
|
105
|
+
required: ["content"],
|
|
106
|
+
} as const;
|
|
107
|
+
|
|
108
|
+
export const SHARED_RECALL_SCHEMA = {
|
|
109
|
+
type: "object",
|
|
110
|
+
properties: {
|
|
111
|
+
query: { type: "string", description: "Surface memory query." },
|
|
112
|
+
limit: { type: "integer", default: 5 },
|
|
113
|
+
},
|
|
114
|
+
required: ["query"],
|
|
115
|
+
} as const;
|
|
116
|
+
|
|
117
|
+
export const SHARED_FORGET_SCHEMA = {
|
|
118
|
+
type: "object",
|
|
119
|
+
properties: { memory_id: { type: "string", description: "Memory ID to delete." } },
|
|
120
|
+
required: ["memory_id"],
|
|
121
|
+
} as const;
|
|
122
|
+
|
|
123
|
+
export const SLEEP_SCHEMA = {
|
|
124
|
+
type: "object",
|
|
125
|
+
properties: {
|
|
126
|
+
dry_run: {
|
|
127
|
+
type: "boolean",
|
|
128
|
+
description: "Preview consolidation without writes.",
|
|
129
|
+
default: false,
|
|
130
|
+
},
|
|
131
|
+
all_sessions: {
|
|
132
|
+
type: "boolean",
|
|
133
|
+
description: "Consolidate all eligible sessions.",
|
|
134
|
+
default: false,
|
|
135
|
+
},
|
|
136
|
+
bank: { type: "string", description: "Memory bank to consolidate.", default: "default" },
|
|
137
|
+
},
|
|
138
|
+
} as const;
|
|
139
|
+
|
|
140
|
+
export const INVALIDATE_SCHEMA = {
|
|
141
|
+
type: "object",
|
|
142
|
+
properties: {
|
|
143
|
+
memory_id: { type: "string", description: "ID of memory to invalidate." },
|
|
144
|
+
replacement_id: { type: "string", description: "Optional replacement memory ID." },
|
|
145
|
+
bank: { type: "string", default: "default" },
|
|
146
|
+
},
|
|
147
|
+
required: ["memory_id"],
|
|
148
|
+
} as const;
|
|
149
|
+
|
|
150
|
+
export const VALIDATE_SCHEMA = {
|
|
151
|
+
type: "object",
|
|
152
|
+
properties: {
|
|
153
|
+
memory_id: { type: "string", description: "ID of memory to validate." },
|
|
154
|
+
action: { type: "string", enum: ["attest", "update", "invalidate", "delete"] },
|
|
155
|
+
validator: { type: "string", description: "Agent identifier performing validation." },
|
|
156
|
+
new_content: { type: "string", description: "New content for action=update." },
|
|
157
|
+
note: { type: "string", description: "Optional reason or evidence." },
|
|
158
|
+
bank: { type: "string", enum: ["private", "surface"], default: "private" },
|
|
159
|
+
},
|
|
160
|
+
required: ["memory_id", "action"],
|
|
161
|
+
} as const;
|
|
162
|
+
|
|
163
|
+
export const GET_SCHEMA = {
|
|
164
|
+
type: "object",
|
|
165
|
+
properties: {
|
|
166
|
+
memory_id: { type: "string", description: "The memory ID to retrieve." },
|
|
167
|
+
bank: { type: "string", default: "default" },
|
|
168
|
+
},
|
|
169
|
+
required: ["memory_id"],
|
|
170
|
+
} as const;
|
|
171
|
+
|
|
172
|
+
export const TRIPLE_ADD_SCHEMA = {
|
|
173
|
+
type: "object",
|
|
174
|
+
properties: {
|
|
175
|
+
subject: { type: "string" },
|
|
176
|
+
predicate: { type: "string" },
|
|
177
|
+
object: { type: "string" },
|
|
178
|
+
valid_from: { type: "string", description: "ISO date." },
|
|
179
|
+
source: { type: "string", default: "conversation" },
|
|
180
|
+
confidence: { type: "number", default: 1.0 },
|
|
181
|
+
bank: { type: "string", default: "default" },
|
|
182
|
+
},
|
|
183
|
+
required: ["subject", "predicate", "object"],
|
|
184
|
+
} as const;
|
|
185
|
+
|
|
186
|
+
export const TRIPLE_QUERY_SCHEMA = {
|
|
187
|
+
type: "object",
|
|
188
|
+
properties: {
|
|
189
|
+
subject: { type: "string" },
|
|
190
|
+
predicate: { type: "string" },
|
|
191
|
+
object: { type: "string" },
|
|
192
|
+
as_of: { type: "string" },
|
|
193
|
+
bank: { type: "string", default: "default" },
|
|
194
|
+
},
|
|
195
|
+
} as const;
|
|
196
|
+
|
|
197
|
+
export const SCRATCHPAD_WRITE_SCHEMA = {
|
|
198
|
+
type: "object",
|
|
199
|
+
properties: {
|
|
200
|
+
content: { type: "string", description: "Content to write to scratchpad." },
|
|
201
|
+
bank: { type: "string", default: "default" },
|
|
202
|
+
},
|
|
203
|
+
required: ["content"],
|
|
204
|
+
} as const;
|
|
205
|
+
|
|
206
|
+
export const SCRATCHPAD_READ_SCHEMA = {
|
|
207
|
+
type: "object",
|
|
208
|
+
properties: { bank: { type: "string", default: "default" } },
|
|
209
|
+
} as const;
|
|
210
|
+
|
|
211
|
+
export const SCRATCHPAD_CLEAR_SCHEMA = {
|
|
212
|
+
type: "object",
|
|
213
|
+
properties: { bank: { type: "string", default: "default" } },
|
|
214
|
+
} as const;
|
|
215
|
+
|
|
216
|
+
export const EXPORT_SCHEMA = {
|
|
217
|
+
type: "object",
|
|
218
|
+
properties: {
|
|
219
|
+
output_path: { type: "string", description: "File path to write the export JSON." },
|
|
220
|
+
bank: { type: "string", default: "default" },
|
|
221
|
+
},
|
|
222
|
+
required: ["output_path"],
|
|
223
|
+
} as const;
|
|
224
|
+
|
|
225
|
+
export const UPDATE_SCHEMA = {
|
|
226
|
+
type: "object",
|
|
227
|
+
properties: {
|
|
228
|
+
memory_id: { type: "string", description: "ID of the memory to update." },
|
|
229
|
+
content: { type: "string", description: "New content for the memory." },
|
|
230
|
+
importance: { type: "number", description: "New importance score." },
|
|
231
|
+
bank: { type: "string", default: "default" },
|
|
232
|
+
},
|
|
233
|
+
required: ["memory_id", "content"],
|
|
234
|
+
} as const;
|
|
235
|
+
|
|
236
|
+
export const FORGET_SCHEMA = {
|
|
237
|
+
type: "object",
|
|
238
|
+
properties: {
|
|
239
|
+
memory_id: { type: "string", description: "ID of the memory to delete." },
|
|
240
|
+
bank: { type: "string", default: "default" },
|
|
241
|
+
},
|
|
242
|
+
required: ["memory_id"],
|
|
243
|
+
} as const;
|
|
244
|
+
|
|
245
|
+
export const IMPORT_SCHEMA = {
|
|
246
|
+
type: "object",
|
|
247
|
+
properties: {
|
|
248
|
+
input_path: { type: "string", description: "File path to read the export JSON from." },
|
|
249
|
+
force: {
|
|
250
|
+
type: "boolean",
|
|
251
|
+
description: "Overwrite existing records instead of skipping.",
|
|
252
|
+
default: false,
|
|
253
|
+
},
|
|
254
|
+
bank: { type: "string", default: "default" },
|
|
255
|
+
},
|
|
256
|
+
required: ["input_path"],
|
|
257
|
+
} as const;
|
|
258
|
+
|
|
259
|
+
export const GRAPH_QUERY_SCHEMA = {
|
|
260
|
+
type: "object",
|
|
261
|
+
properties: {
|
|
262
|
+
seed_memory_id: { type: "string" },
|
|
263
|
+
max_hops: { type: "integer", default: 2 },
|
|
264
|
+
edge_type: { type: "string" },
|
|
265
|
+
min_weight: { type: "number", default: 0.0 },
|
|
266
|
+
bank: { type: "string", default: "default" },
|
|
267
|
+
},
|
|
268
|
+
required: ["seed_memory_id"],
|
|
269
|
+
} as const;
|
|
270
|
+
|
|
271
|
+
export const GRAPH_LINK_SCHEMA = {
|
|
272
|
+
type: "object",
|
|
273
|
+
properties: {
|
|
274
|
+
source_id: { type: "string" },
|
|
275
|
+
target_id: { type: "string" },
|
|
276
|
+
relationship: { type: "string" },
|
|
277
|
+
weight: { type: "number", default: 0.5 },
|
|
278
|
+
bank: { type: "string", default: "default" },
|
|
279
|
+
},
|
|
280
|
+
required: ["source_id", "target_id", "relationship"],
|
|
281
|
+
} as const;
|
|
282
|
+
|
|
283
|
+
export const TOOLS: readonly ToolDefinition[] = [
|
|
284
|
+
{
|
|
285
|
+
name: "prometheus_memory_remember",
|
|
286
|
+
description: "Store a durable memory in Prometheus Memory.",
|
|
287
|
+
inputSchema: REMEMBER_SCHEMA,
|
|
288
|
+
},
|
|
289
|
+
{
|
|
290
|
+
name: "prometheus_memory_recall",
|
|
291
|
+
description: "Search memories with hybrid scoring.",
|
|
292
|
+
inputSchema: RECALL_SCHEMA,
|
|
293
|
+
},
|
|
294
|
+
{
|
|
295
|
+
name: "prometheus_memory_shared_remember",
|
|
296
|
+
description: "Store compact cross-agent surface memory.",
|
|
297
|
+
inputSchema: SHARED_REMEMBER_SCHEMA,
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
name: "prometheus_memory_shared_recall",
|
|
301
|
+
description: "Search only the shared Prometheus Memory surface DB.",
|
|
302
|
+
inputSchema: SHARED_RECALL_SCHEMA,
|
|
303
|
+
},
|
|
304
|
+
{
|
|
305
|
+
name: "prometheus_memory_shared_forget",
|
|
306
|
+
description: "Delete one shared-surface memory by ID.",
|
|
307
|
+
inputSchema: SHARED_FORGET_SCHEMA,
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
name: "prometheus_memory_shared_stats",
|
|
311
|
+
description: "Return shared surface DB path and counts.",
|
|
312
|
+
inputSchema: EMPTY_SCHEMA,
|
|
313
|
+
},
|
|
314
|
+
{
|
|
315
|
+
name: "prometheus_memory_sleep",
|
|
316
|
+
description: "Run the consolidation sleep cycle.",
|
|
317
|
+
inputSchema: SLEEP_SCHEMA,
|
|
318
|
+
},
|
|
319
|
+
{
|
|
320
|
+
name: "prometheus_memory_stats",
|
|
321
|
+
description: "Return Prometheus Memory statistics.",
|
|
322
|
+
inputSchema: EMPTY_SCHEMA,
|
|
323
|
+
},
|
|
324
|
+
{
|
|
325
|
+
name: "prometheus_memory_invalidate",
|
|
326
|
+
description: "Mark a memory as expired or superseded.",
|
|
327
|
+
inputSchema: INVALIDATE_SCHEMA,
|
|
328
|
+
},
|
|
329
|
+
{
|
|
330
|
+
name: "prometheus_memory_validate",
|
|
331
|
+
description: "Attest, update, invalidate, or delete a memory.",
|
|
332
|
+
inputSchema: VALIDATE_SCHEMA,
|
|
333
|
+
},
|
|
334
|
+
{ name: "prometheus_memory_get", description: "Retrieve one memory by ID.", inputSchema: GET_SCHEMA },
|
|
335
|
+
{
|
|
336
|
+
name: "prometheus_memory_triple_add",
|
|
337
|
+
description: "Add a temporal fact triple.",
|
|
338
|
+
inputSchema: TRIPLE_ADD_SCHEMA,
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
name: "prometheus_memory_triple_query",
|
|
342
|
+
description: "Query temporal fact triples.",
|
|
343
|
+
inputSchema: TRIPLE_QUERY_SCHEMA,
|
|
344
|
+
},
|
|
345
|
+
{
|
|
346
|
+
name: "prometheus_memory_scratchpad_write",
|
|
347
|
+
description: "Write a temporary scratchpad note.",
|
|
348
|
+
inputSchema: SCRATCHPAD_WRITE_SCHEMA,
|
|
349
|
+
},
|
|
350
|
+
{
|
|
351
|
+
name: "prometheus_memory_scratchpad_read",
|
|
352
|
+
description: "Read scratchpad entries.",
|
|
353
|
+
inputSchema: SCRATCHPAD_READ_SCHEMA,
|
|
354
|
+
},
|
|
355
|
+
{
|
|
356
|
+
name: "prometheus_memory_scratchpad_clear",
|
|
357
|
+
description: "Clear scratchpad entries.",
|
|
358
|
+
inputSchema: SCRATCHPAD_CLEAR_SCHEMA,
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
name: "prometheus_memory_export",
|
|
362
|
+
description: "Export Prometheus Memory memories to a JSON file.",
|
|
363
|
+
inputSchema: EXPORT_SCHEMA,
|
|
364
|
+
},
|
|
365
|
+
{
|
|
366
|
+
name: "prometheus_memory_update",
|
|
367
|
+
description: "Update the content or importance of an existing memory.",
|
|
368
|
+
inputSchema: UPDATE_SCHEMA,
|
|
369
|
+
},
|
|
370
|
+
{
|
|
371
|
+
name: "prometheus_memory_forget",
|
|
372
|
+
description: "Permanently delete a memory by ID.",
|
|
373
|
+
inputSchema: FORGET_SCHEMA,
|
|
374
|
+
},
|
|
375
|
+
{
|
|
376
|
+
name: "prometheus_memory_import",
|
|
377
|
+
description: "Import Prometheus Memory memories from a JSON file.",
|
|
378
|
+
inputSchema: IMPORT_SCHEMA,
|
|
379
|
+
},
|
|
380
|
+
{
|
|
381
|
+
name: "prometheus_memory_diagnose",
|
|
382
|
+
description: "Run PII-safe diagnostics on the active Prometheus Memory database.",
|
|
383
|
+
inputSchema: EMPTY_SCHEMA,
|
|
384
|
+
},
|
|
385
|
+
{
|
|
386
|
+
name: "prometheus_memory_graph_query",
|
|
387
|
+
description: "Traverse the memory graph from a seed memory.",
|
|
388
|
+
inputSchema: GRAPH_QUERY_SCHEMA,
|
|
389
|
+
},
|
|
390
|
+
{
|
|
391
|
+
name: "prometheus_memory_graph_link",
|
|
392
|
+
description: "Declare a semantic edge between two memories.",
|
|
393
|
+
inputSchema: GRAPH_LINK_SCHEMA,
|
|
394
|
+
},
|
|
395
|
+
];
|
|
396
|
+
|
|
397
|
+
function stringArg(args: ToolArguments, key: string, fallback = ""): string {
|
|
398
|
+
const value = args[key];
|
|
399
|
+
return typeof value === "string" ? value : fallback;
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
function optionalStringArg(args: ToolArguments, key: string): string | null {
|
|
403
|
+
const value = stringArg(args, key);
|
|
404
|
+
return value.length > 0 ? value : null;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
function numberArg(args: ToolArguments, key: string, fallback: number): number {
|
|
408
|
+
const value = args[key];
|
|
409
|
+
const parsed = typeof value === "number" ? value : typeof value === "string" ? Number(value) : NaN;
|
|
410
|
+
return Number.isFinite(parsed) ? parsed : fallback;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
function booleanArg(args: ToolArguments, key: string, fallback = false): boolean {
|
|
414
|
+
const value = args[key];
|
|
415
|
+
return typeof value === "boolean" ? value : fallback;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
function metadataArg(args: ToolArguments): Record<string, JsonValue> | null {
|
|
419
|
+
const value = args.metadata;
|
|
420
|
+
return value !== null && typeof value === "object" && !Array.isArray(value)
|
|
421
|
+
? (value as Record<string, JsonValue>)
|
|
422
|
+
: null;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
function resolveBank(args: ToolArguments): string {
|
|
426
|
+
return stringArg(args, "bank") || process.env.PROMETHEUS_MEMORY_MCP_BANK || "default";
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
function bankDbPath(bank: string): string {
|
|
430
|
+
return new BankManager(dataDir()).getBankDbPath(bank);
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
function createBeam(args: ToolArguments, bank = resolveBank(args)): BeamMemory {
|
|
434
|
+
const sessionId = process.env.PROMETHEUS_MEMORY_SESSION_ID || `mcp_${bank}`;
|
|
435
|
+
return new BeamMemory({
|
|
436
|
+
sessionId,
|
|
437
|
+
dbPath: bankDbPath(bank),
|
|
438
|
+
authorId: optionalStringArg(args, "author_id") ?? process.env.PROMETHEUS_MEMORY_AUTHOR_ID ?? null,
|
|
439
|
+
authorType: optionalStringArg(args, "author_type") ?? process.env.PROMETHEUS_MEMORY_AUTHOR_TYPE ?? null,
|
|
440
|
+
channelId: optionalStringArg(args, "channel_id") ?? process.env.PROMETHEUS_MEMORY_CHANNEL_ID ?? sessionId,
|
|
441
|
+
});
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
function sharedBeam(): BeamMemory {
|
|
445
|
+
const configured = process.env.PROMETHEUS_MEMORY_SHARED_SURFACE_DB;
|
|
446
|
+
const dbPath = configured && configured.length > 0 ? configured : join(dataDir(), "shared", DEFAULT_DB_FILENAME);
|
|
447
|
+
return new BeamMemory({ sessionId: "mcp_shared_surface", dbPath });
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
async function withBeam<T>(args: ToolArguments, fn: (beam: BeamMemory, bank: string) => T | Promise<T>): Promise<T> {
|
|
451
|
+
const bank = resolveBank(args);
|
|
452
|
+
const beam = createBeam(args, bank);
|
|
453
|
+
try {
|
|
454
|
+
const result = await fn(beam, bank);
|
|
455
|
+
// Drain background fact-extraction and embedding tasks before close so
|
|
456
|
+
// the SQLite handle stays open until in-flight `embed()` writes commit;
|
|
457
|
+
// otherwise the short-lived MCP `remember`/`update`/`sleep` paths race
|
|
458
|
+
// the close and silently drop the new dense-recall rows.
|
|
459
|
+
await beam.flushExtractions();
|
|
460
|
+
return result;
|
|
461
|
+
} finally {
|
|
462
|
+
beam.close();
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
function serialize(value: unknown): unknown {
|
|
466
|
+
if (value instanceof Date) return value.toISOString();
|
|
467
|
+
if (Array.isArray(value)) return value.map(serialize);
|
|
468
|
+
if (value !== null && typeof value === "object") {
|
|
469
|
+
const out: Record<string, unknown> = {};
|
|
470
|
+
for (const key in value) out[key] = serialize((value as Record<string, unknown>)[key]);
|
|
471
|
+
return out;
|
|
472
|
+
}
|
|
473
|
+
return value;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
function cloneRowForBankImport(value: unknown, sessionId: string, channelId: string | null): unknown {
|
|
477
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) return value;
|
|
478
|
+
const row: Record<string, unknown> & { session_id: string; channel_id?: string } = {
|
|
479
|
+
...(value as Record<string, unknown>),
|
|
480
|
+
session_id: sessionId,
|
|
481
|
+
};
|
|
482
|
+
if (channelId !== null) row.channel_id = channelId;
|
|
483
|
+
return row;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
function routeImportToBeamSession(data: Record<string, unknown>, beam: BeamMemory): Record<string, unknown> {
|
|
487
|
+
return {
|
|
488
|
+
...data,
|
|
489
|
+
working_memory: Array.isArray(data.working_memory)
|
|
490
|
+
? data.working_memory.map(row => cloneRowForBankImport(row, beam.sessionId, beam.channelId))
|
|
491
|
+
: data.working_memory,
|
|
492
|
+
episodic_memory: Array.isArray(data.episodic_memory)
|
|
493
|
+
? data.episodic_memory.map(row => cloneRowForBankImport(row, beam.sessionId, beam.channelId))
|
|
494
|
+
: data.episodic_memory,
|
|
495
|
+
scratchpad: Array.isArray(data.scratchpad)
|
|
496
|
+
? data.scratchpad.map(row => cloneRowForBankImport(row, beam.sessionId, null))
|
|
497
|
+
: data.scratchpad,
|
|
498
|
+
consolidation_log: Array.isArray(data.consolidation_log)
|
|
499
|
+
? data.consolidation_log.map(row => cloneRowForBankImport(row, beam.sessionId, null))
|
|
500
|
+
: data.consolidation_log,
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
function required(args: ToolArguments, key: string): string | ToolResult {
|
|
505
|
+
const value = stringArg(args, key).trim();
|
|
506
|
+
return value.length > 0 ? value : { error: `${key} is required` };
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
async function handleRemember(args: ToolArguments): Promise<ToolResult> {
|
|
510
|
+
const content = required(args, "content");
|
|
511
|
+
if (typeof content !== "string") return content;
|
|
512
|
+
return withBeam(args, (beam, bank) => {
|
|
513
|
+
const memoryId = beam.remember(content, {
|
|
514
|
+
source: stringArg(args, "source", "mcp"),
|
|
515
|
+
importance: numberArg(args, "importance", 0.5),
|
|
516
|
+
metadata: metadataArg(args),
|
|
517
|
+
extractEntities: booleanArg(args, "extract_entities"),
|
|
518
|
+
extract: booleanArg(args, "extract"),
|
|
519
|
+
veracity: stringArg(args, "veracity", "unknown"),
|
|
520
|
+
scope: stringArg(args, "scope", "session"),
|
|
521
|
+
});
|
|
522
|
+
return { status: "stored", memory_id: memoryId, bank, content_preview: content.slice(0, 100) };
|
|
523
|
+
});
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
async function handleRecall(args: ToolArguments): Promise<ToolResult> {
|
|
527
|
+
const query = required(args, "query");
|
|
528
|
+
if (typeof query !== "string") return query;
|
|
529
|
+
return withBeam(args, async (beam, bank) => {
|
|
530
|
+
const topK = Math.trunc(numberArg(args, "top_k", numberArg(args, "limit", 5)));
|
|
531
|
+
const options: RecallOptions & Record<string, unknown> = {
|
|
532
|
+
temporalWeight: numberArg(args, "temporal_weight", 0.0),
|
|
533
|
+
queryTime: optionalStringArg(args, "query_time"),
|
|
534
|
+
temporalHalflife: numberArg(args, "temporal_halflife", 24),
|
|
535
|
+
authorId: optionalStringArg(args, "author_id"),
|
|
536
|
+
authorType: optionalStringArg(args, "author_type"),
|
|
537
|
+
channelId: optionalStringArg(args, "channel_id"),
|
|
538
|
+
};
|
|
539
|
+
for (const key of ["vec_weight", "fts_weight", "importance_weight"] as const) {
|
|
540
|
+
if (key in args) options[key.replace(/_([a-z])/g, (_, c: string) => c.toUpperCase())] = args[key];
|
|
541
|
+
}
|
|
542
|
+
const results = (await beam.recall(query, topK, options)).map(row => ({ ...row, bank }));
|
|
543
|
+
return { status: "ok", query, count: results.length, results: serialize(results), bank };
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
async function handleSleep(args: ToolArguments): Promise<ToolResult> {
|
|
548
|
+
return withBeam(args, (beam, bank) => {
|
|
549
|
+
const dryRun = booleanArg(args, "dry_run");
|
|
550
|
+
const allSessions = booleanArg(args, "all_sessions");
|
|
551
|
+
const result = allSessions ? beam.sleepAllSessions(dryRun) : beam.sleep(dryRun);
|
|
552
|
+
return {
|
|
553
|
+
status: "ok",
|
|
554
|
+
dry_run: dryRun,
|
|
555
|
+
all_sessions: allSessions,
|
|
556
|
+
result: serialize(result),
|
|
557
|
+
working: serialize(beam.getWorkingStats()),
|
|
558
|
+
episodic: serialize(beam.getEpisodicStats()),
|
|
559
|
+
bank,
|
|
560
|
+
};
|
|
561
|
+
});
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
async function handleStats(args: ToolArguments): Promise<ToolResult> {
|
|
565
|
+
return withBeam(args, (beam, bank) => ({
|
|
566
|
+
status: "ok",
|
|
567
|
+
provider: "prometheus-memory",
|
|
568
|
+
bank,
|
|
569
|
+
working: serialize(beam.getWorkingStats()),
|
|
570
|
+
episodic: serialize(beam.getEpisodicStats()),
|
|
571
|
+
memoria: serialize(beam.getMemoriaStats()),
|
|
572
|
+
stats: {
|
|
573
|
+
working: serialize(beam.getWorkingStats()),
|
|
574
|
+
episodic: serialize(beam.getEpisodicStats()),
|
|
575
|
+
memoria: serialize(beam.getMemoriaStats()),
|
|
576
|
+
},
|
|
577
|
+
}));
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
async function handleScratchpadWrite(args: ToolArguments): Promise<ToolResult> {
|
|
581
|
+
const content = required(args, "content");
|
|
582
|
+
if (typeof content !== "string") return content;
|
|
583
|
+
return withBeam(args, (beam, bank) => {
|
|
584
|
+
const entryId = beam.scratchpadWrite(content);
|
|
585
|
+
return { status: "written", id: entryId, entry_id: entryId, bank };
|
|
586
|
+
});
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
async function handleScratchpadRead(args: ToolArguments): Promise<ToolResult> {
|
|
590
|
+
return withBeam(args, (beam, bank) => {
|
|
591
|
+
const entries = beam.scratchpadRead();
|
|
592
|
+
return {
|
|
593
|
+
status: "ok",
|
|
594
|
+
entries_count: entries.length,
|
|
595
|
+
count: entries.length,
|
|
596
|
+
entries: serialize(entries),
|
|
597
|
+
bank,
|
|
598
|
+
};
|
|
599
|
+
});
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
async function handleScratchpadClear(args: ToolArguments): Promise<ToolResult> {
|
|
603
|
+
return withBeam(args, (beam, bank) => {
|
|
604
|
+
beam.scratchpadClear();
|
|
605
|
+
return { status: "cleared", bank };
|
|
606
|
+
});
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
async function handleInvalidate(args: ToolArguments): Promise<ToolResult> {
|
|
610
|
+
const memoryId = required(args, "memory_id");
|
|
611
|
+
if (typeof memoryId !== "string") return memoryId;
|
|
612
|
+
return withBeam(args, (beam, bank) => ({
|
|
613
|
+
status: beam.invalidate(memoryId, optionalStringArg(args, "replacement_id")) ? "invalidated" : "not_found",
|
|
614
|
+
memory_id: memoryId,
|
|
615
|
+
bank,
|
|
616
|
+
}));
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
async function handleGet(args: ToolArguments): Promise<ToolResult> {
|
|
620
|
+
const memoryId = required(args, "memory_id");
|
|
621
|
+
if (typeof memoryId !== "string") return memoryId;
|
|
622
|
+
return withBeam(args, (beam, bank) => {
|
|
623
|
+
const memory = beam.get(memoryId);
|
|
624
|
+
return memory === null
|
|
625
|
+
? { status: "not_found", memory_id: memoryId, bank }
|
|
626
|
+
: { status: "ok", memory: serialize(memory), bank };
|
|
627
|
+
});
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
async function handleUpdate(args: ToolArguments): Promise<ToolResult> {
|
|
631
|
+
const memoryId = required(args, "memory_id");
|
|
632
|
+
if (typeof memoryId !== "string") return memoryId;
|
|
633
|
+
return withBeam(args, (beam, bank) => {
|
|
634
|
+
if (!("content" in args) && !("importance" in args)) return { error: "content or importance is required" };
|
|
635
|
+
const content = "content" in args ? stringArg(args, "content") : null;
|
|
636
|
+
if (content !== null && content.trim().length === 0) return { error: "content is required" };
|
|
637
|
+
const importance = "importance" in args ? numberArg(args, "importance", Number.NaN) : null;
|
|
638
|
+
const ok = beam.updateWorking(
|
|
639
|
+
memoryId,
|
|
640
|
+
content,
|
|
641
|
+
importance !== null && Number.isFinite(importance) ? importance : null,
|
|
642
|
+
);
|
|
643
|
+
return { status: ok ? "updated" : "not_found", memory_id: memoryId, bank };
|
|
644
|
+
});
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
async function handleForget(args: ToolArguments): Promise<ToolResult> {
|
|
648
|
+
const memoryId = required(args, "memory_id");
|
|
649
|
+
if (typeof memoryId !== "string") return memoryId;
|
|
650
|
+
return withBeam(args, (beam, bank) => ({
|
|
651
|
+
status: beam.forgetWorking(memoryId) ? "deleted" : "not_found",
|
|
652
|
+
memory_id: memoryId,
|
|
653
|
+
bank,
|
|
654
|
+
}));
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
async function handleTripleAdd(args: ToolArguments): Promise<ToolResult> {
|
|
658
|
+
const subject = required(args, "subject");
|
|
659
|
+
if (typeof subject !== "string") return subject;
|
|
660
|
+
const predicate = required(args, "predicate");
|
|
661
|
+
if (typeof predicate !== "string") return predicate;
|
|
662
|
+
const object = required(args, "object");
|
|
663
|
+
if (typeof object !== "string") return object;
|
|
664
|
+
const bank = resolveBank(args);
|
|
665
|
+
const tripleId = addTriple(subject, predicate, object, {
|
|
666
|
+
dbPath: bankDbPath(bank),
|
|
667
|
+
validFrom: optionalStringArg(args, "valid_from"),
|
|
668
|
+
source: stringArg(args, "source", "conversation"),
|
|
669
|
+
confidence: numberArg(args, "confidence", 1.0),
|
|
670
|
+
});
|
|
671
|
+
return { status: "stored", triple_id: tripleId, store: "triples", bank };
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
async function handleTripleQuery(args: ToolArguments): Promise<ToolResult> {
|
|
675
|
+
const bank = resolveBank(args);
|
|
676
|
+
const results = queryTriples({
|
|
677
|
+
dbPath: bankDbPath(bank),
|
|
678
|
+
subject: optionalStringArg(args, "subject"),
|
|
679
|
+
predicate: optionalStringArg(args, "predicate"),
|
|
680
|
+
object: optionalStringArg(args, "object"),
|
|
681
|
+
asOf: optionalStringArg(args, "as_of"),
|
|
682
|
+
});
|
|
683
|
+
return {
|
|
684
|
+
count: results.length,
|
|
685
|
+
results: serialize(results),
|
|
686
|
+
results_count: results.length,
|
|
687
|
+
store: "triples",
|
|
688
|
+
bank,
|
|
689
|
+
};
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
async function handleExport(args: ToolArguments): Promise<ToolResult> {
|
|
693
|
+
const outputPath = required(args, "output_path");
|
|
694
|
+
if (typeof outputPath !== "string") return outputPath;
|
|
695
|
+
return withBeam(args, (beam, bank) => {
|
|
696
|
+
mkdirSync(dirname(outputPath), { recursive: true });
|
|
697
|
+
const data = beam.exportToDict();
|
|
698
|
+
writeFileSync(outputPath, JSON.stringify(data, null, 2));
|
|
699
|
+
return {
|
|
700
|
+
status: "exported",
|
|
701
|
+
output_path: outputPath,
|
|
702
|
+
bank,
|
|
703
|
+
stats: serialize(beam.getWorkingStats()),
|
|
704
|
+
};
|
|
705
|
+
});
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
async function handleImport(args: ToolArguments): Promise<ToolResult> {
|
|
709
|
+
const inputPath = required(args, "input_path");
|
|
710
|
+
if (typeof inputPath !== "string") return { error: "Either input_path (for file import) is required" };
|
|
711
|
+
if (!existsSync(inputPath)) return { error: `input_path does not exist: ${inputPath}` };
|
|
712
|
+
return withBeam(args, (beam, bank) => {
|
|
713
|
+
const parsed = JSON.parse(readFileSync(inputPath, "utf8")) as Record<string, unknown>;
|
|
714
|
+
const routed = routeImportToBeamSession(parsed, beam);
|
|
715
|
+
const stats = beam.importFromDict(routed, booleanArg(args, "force"));
|
|
716
|
+
return { status: "imported", stats: serialize(stats), bank };
|
|
717
|
+
});
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
function surfaceLabel(content: string, kind: string): string {
|
|
721
|
+
const lower = content.toLowerCase();
|
|
722
|
+
if (
|
|
723
|
+
lower.startsWith("surface meta:") ||
|
|
724
|
+
lower.startsWith("surface preference:") ||
|
|
725
|
+
lower.startsWith("surface correction:") ||
|
|
726
|
+
lower.startsWith("surface identity:")
|
|
727
|
+
)
|
|
728
|
+
return content;
|
|
729
|
+
const label =
|
|
730
|
+
kind === "preference"
|
|
731
|
+
? "Surface preference"
|
|
732
|
+
: kind === "correction"
|
|
733
|
+
? "Surface correction"
|
|
734
|
+
: kind === "identity"
|
|
735
|
+
? "Surface identity"
|
|
736
|
+
: "Surface meta";
|
|
737
|
+
return `${label}: ${content}`;
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
async function withSharedBeam<T>(fn: (beam: BeamMemory) => T | Promise<T>): Promise<T> {
|
|
741
|
+
const beam = sharedBeam();
|
|
742
|
+
try {
|
|
743
|
+
const result = await fn(beam);
|
|
744
|
+
await beam.flushExtractions();
|
|
745
|
+
return result;
|
|
746
|
+
} finally {
|
|
747
|
+
beam.close();
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
async function handleSharedRemember(args: ToolArguments): Promise<ToolResult> {
|
|
752
|
+
const content = required(args, "content");
|
|
753
|
+
if (typeof content !== "string") return content;
|
|
754
|
+
const kind = stringArg(args, "kind", "meta").trim().toLowerCase();
|
|
755
|
+
if (!["meta", "preference", "correction", "identity"].includes(kind))
|
|
756
|
+
return { error: "kind must be one of: meta, preference, correction, identity" };
|
|
757
|
+
return withSharedBeam(beam => {
|
|
758
|
+
const labelled = surfaceLabel(content, kind);
|
|
759
|
+
const memoryId = beam.remember(labelled, {
|
|
760
|
+
source: "surface_manual",
|
|
761
|
+
importance: Math.max(0, Math.min(1, numberArg(args, "importance", 0.8))),
|
|
762
|
+
metadata: { ...(metadataArg(args) ?? {}), shared_memory: true, surface_kind: kind },
|
|
763
|
+
veracity: stringArg(args, "veracity", "unknown"),
|
|
764
|
+
scope: "global",
|
|
765
|
+
});
|
|
766
|
+
return {
|
|
767
|
+
status: "stored_shared",
|
|
768
|
+
memory_id: memoryId,
|
|
769
|
+
kind,
|
|
770
|
+
content_preview: labelled.slice(0, 120),
|
|
771
|
+
};
|
|
772
|
+
});
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
async function handleSharedRecall(args: ToolArguments): Promise<ToolResult> {
|
|
776
|
+
const query = required(args, "query");
|
|
777
|
+
if (typeof query !== "string") return query;
|
|
778
|
+
return withSharedBeam(async beam => {
|
|
779
|
+
const results = (await beam.recall(query, Math.trunc(numberArg(args, "limit", 5)))).map(row => ({
|
|
780
|
+
...row,
|
|
781
|
+
bank: "surface",
|
|
782
|
+
shared_surface: true,
|
|
783
|
+
}));
|
|
784
|
+
return { query, count: results.length, results: serialize(results) };
|
|
785
|
+
});
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
async function handleSharedForget(args: ToolArguments): Promise<ToolResult> {
|
|
789
|
+
const memoryId = required(args, "memory_id");
|
|
790
|
+
if (typeof memoryId !== "string") return memoryId;
|
|
791
|
+
return withSharedBeam(beam => ({
|
|
792
|
+
status: beam.forgetWorking(memoryId) ? "deleted" : "not_found",
|
|
793
|
+
memory_id: memoryId,
|
|
794
|
+
}));
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
async function handleSharedStats(): Promise<ToolResult> {
|
|
798
|
+
return withSharedBeam(beam => ({
|
|
799
|
+
provider: "prometheus_memory_shared",
|
|
800
|
+
working: serialize(beam.getWorkingStats()),
|
|
801
|
+
episodic: serialize(beam.getEpisodicStats()),
|
|
802
|
+
}));
|
|
803
|
+
}
|
|
804
|
+
|
|
805
|
+
async function handleValidate(args: ToolArguments): Promise<ToolResult> {
|
|
806
|
+
const memoryId = required(args, "memory_id");
|
|
807
|
+
if (typeof memoryId !== "string") return memoryId;
|
|
808
|
+
const action = stringArg(args, "action");
|
|
809
|
+
if (!["attest", "update", "invalidate", "delete"].includes(action)) return { error: `unknown action: ${action}` };
|
|
810
|
+
if (action === "update" && !optionalStringArg(args, "new_content"))
|
|
811
|
+
return { error: "new_content is required for action='update'" };
|
|
812
|
+
return withBeam(args, (beam, bank) => {
|
|
813
|
+
const existing = beam.get(memoryId) as { content?: string; author_id?: string | null } | null;
|
|
814
|
+
if (existing === null) return { error: "memory_not_found", memory_id: memoryId, bank };
|
|
815
|
+
let status: string;
|
|
816
|
+
if (action === "delete") status = beam.forgetWorking(memoryId) ? "validation_delete" : "not_found";
|
|
817
|
+
else if (action === "update")
|
|
818
|
+
status = beam.updateWorking(memoryId, stringArg(args, "new_content"), null)
|
|
819
|
+
? "validation_update"
|
|
820
|
+
: "not_found";
|
|
821
|
+
else if (action === "invalidate") status = beam.invalidate(memoryId) ? "validation_invalidate" : "not_found";
|
|
822
|
+
else status = "validation_attest";
|
|
823
|
+
return {
|
|
824
|
+
status,
|
|
825
|
+
memory_id: memoryId,
|
|
826
|
+
bank,
|
|
827
|
+
validator: stringArg(args, "validator", "unknown"),
|
|
828
|
+
author_id: existing.author_id ?? null,
|
|
829
|
+
previous_content: existing.content?.slice(0, 200) ?? null,
|
|
830
|
+
};
|
|
831
|
+
});
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
async function handleDiagnose(args: ToolArguments): Promise<ToolResult> {
|
|
835
|
+
return withBeam(args, (beam, bank) => ({
|
|
836
|
+
status: "ok",
|
|
837
|
+
bank,
|
|
838
|
+
db_path: beam.dbPath ?? null,
|
|
839
|
+
working: serialize(beam.getWorkingStats()),
|
|
840
|
+
episodic: serialize(beam.getEpisodicStats()),
|
|
841
|
+
memoria: serialize(beam.getMemoriaStats()),
|
|
842
|
+
}));
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
interface GraphEdgeInput {
|
|
846
|
+
readonly source: string;
|
|
847
|
+
readonly target: string;
|
|
848
|
+
readonly edgeType: string;
|
|
849
|
+
readonly weight: number;
|
|
850
|
+
readonly timestamp: string;
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
interface GraphQueryApi {
|
|
854
|
+
findRelatedMemories(memoryId: string, depth?: number, edgeType?: string, minWeight?: number): readonly unknown[];
|
|
855
|
+
}
|
|
856
|
+
|
|
857
|
+
interface GraphLinkApi {
|
|
858
|
+
addEdge(edge: GraphEdgeInput): void;
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
function graphQueryApi(beam: BeamMemory): GraphQueryApi | null {
|
|
862
|
+
const graph = beam.episodicGraph;
|
|
863
|
+
if (graph === null || typeof graph !== "object") return null;
|
|
864
|
+
const candidate = graph as { findRelatedMemories?: unknown };
|
|
865
|
+
return typeof candidate.findRelatedMemories === "function" ? (candidate as GraphQueryApi) : null;
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
function graphLinkApi(beam: BeamMemory): GraphLinkApi | null {
|
|
869
|
+
const graph = beam.episodicGraph;
|
|
870
|
+
if (graph === null || typeof graph !== "object") return null;
|
|
871
|
+
const candidate = graph as { addEdge?: unknown };
|
|
872
|
+
return typeof candidate.addEdge === "function" ? (candidate as GraphLinkApi) : null;
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
async function handleGraphQuery(args: ToolArguments): Promise<ToolResult> {
|
|
876
|
+
const seedId = required(args, "seed_memory_id");
|
|
877
|
+
if (typeof seedId !== "string") return seedId;
|
|
878
|
+
const maxHops = Math.max(0, Math.trunc(numberArg(args, "max_hops", 2)));
|
|
879
|
+
const edgeType = stringArg(args, "edge_type");
|
|
880
|
+
const minWeight = numberArg(args, "min_weight", 0);
|
|
881
|
+
return withBeam(args, (beam, bank) => {
|
|
882
|
+
const graph = graphQueryApi(beam);
|
|
883
|
+
if (graph === null) return { error: "Episodic graph not available", seed_memory_id: seedId, bank };
|
|
884
|
+
const related = graph.findRelatedMemories(seedId, maxHops, edgeType, minWeight);
|
|
885
|
+
return {
|
|
886
|
+
status: "ok",
|
|
887
|
+
seed_memory_id: seedId,
|
|
888
|
+
count: related.length,
|
|
889
|
+
results_count: related.length,
|
|
890
|
+
results: serialize(related),
|
|
891
|
+
related_memories: serialize(related),
|
|
892
|
+
bank,
|
|
893
|
+
};
|
|
894
|
+
});
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
async function handleGraphLink(args: ToolArguments): Promise<ToolResult> {
|
|
898
|
+
const sourceId = required(args, "source_id");
|
|
899
|
+
if (typeof sourceId !== "string") return sourceId;
|
|
900
|
+
const targetId = required(args, "target_id");
|
|
901
|
+
if (typeof targetId !== "string") return targetId;
|
|
902
|
+
const relationship = required(args, "relationship");
|
|
903
|
+
if (typeof relationship !== "string") return relationship;
|
|
904
|
+
return withBeam(args, (beam, bank) => {
|
|
905
|
+
const graph = graphLinkApi(beam);
|
|
906
|
+
if (graph === null)
|
|
907
|
+
return {
|
|
908
|
+
error: "Episodic graph not available",
|
|
909
|
+
source_id: sourceId,
|
|
910
|
+
target_id: targetId,
|
|
911
|
+
relationship,
|
|
912
|
+
bank,
|
|
913
|
+
};
|
|
914
|
+
const weight = numberArg(args, "weight", 0.5);
|
|
915
|
+
graph.addEdge({
|
|
916
|
+
source: sourceId,
|
|
917
|
+
target: targetId,
|
|
918
|
+
edgeType: relationship,
|
|
919
|
+
weight,
|
|
920
|
+
timestamp: new Date().toISOString(),
|
|
921
|
+
});
|
|
922
|
+
return {
|
|
923
|
+
status: "linked",
|
|
924
|
+
source_id: sourceId,
|
|
925
|
+
target_id: targetId,
|
|
926
|
+
relationship,
|
|
927
|
+
edge_type: relationship,
|
|
928
|
+
weight,
|
|
929
|
+
bank,
|
|
930
|
+
};
|
|
931
|
+
});
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
type Handler = (args: ToolArguments) => ToolResult | Promise<ToolResult>;
|
|
935
|
+
|
|
936
|
+
const TOOL_HANDLERS: Record<string, Handler> = {
|
|
937
|
+
prometheus_memory_remember: handleRemember,
|
|
938
|
+
prometheus_memory_recall: handleRecall,
|
|
939
|
+
prometheus_memory_shared_remember: handleSharedRemember,
|
|
940
|
+
prometheus_memory_shared_recall: handleSharedRecall,
|
|
941
|
+
prometheus_memory_shared_forget: handleSharedForget,
|
|
942
|
+
prometheus_memory_shared_stats: () => handleSharedStats(),
|
|
943
|
+
prometheus_memory_sleep: handleSleep,
|
|
944
|
+
prometheus_memory_stats: handleStats,
|
|
945
|
+
prometheus_memory_get_stats: handleStats,
|
|
946
|
+
prometheus_memory_invalidate: handleInvalidate,
|
|
947
|
+
prometheus_memory_validate: handleValidate,
|
|
948
|
+
prometheus_memory_get: handleGet,
|
|
949
|
+
prometheus_memory_triple_add: handleTripleAdd,
|
|
950
|
+
prometheus_memory_triple_query: handleTripleQuery,
|
|
951
|
+
prometheus_memory_scratchpad_write: handleScratchpadWrite,
|
|
952
|
+
prometheus_memory_scratchpad_read: handleScratchpadRead,
|
|
953
|
+
prometheus_memory_scratchpad_clear: handleScratchpadClear,
|
|
954
|
+
prometheus_memory_export: handleExport,
|
|
955
|
+
prometheus_memory_update: handleUpdate,
|
|
956
|
+
prometheus_memory_forget: handleForget,
|
|
957
|
+
prometheus_memory_import: handleImport,
|
|
958
|
+
prometheus_memory_diagnose: handleDiagnose,
|
|
959
|
+
prometheus_memory_graph_query: handleGraphQuery,
|
|
960
|
+
prometheus_memory_graph_link: handleGraphLink,
|
|
961
|
+
};
|
|
962
|
+
|
|
963
|
+
export async function handleToolCall(name: string, args: ToolArguments = {}): Promise<ToolResult> {
|
|
964
|
+
const handler = TOOL_HANDLERS[name];
|
|
965
|
+
if (handler === undefined) throw new Error(`Unknown tool: ${name}`);
|
|
966
|
+
return handler(args);
|
|
967
|
+
}
|
|
968
|
+
export function getToolDefinitions(): readonly ToolDefinition[] {
|
|
969
|
+
return TOOLS;
|
|
970
|
+
}
|