memento-mcp 0.3.6 → 0.3.7
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/package.json +1 -1
- package/scripts/memento-stop-recall.sh +7 -4
- package/src/index.js +66 -0
- package/src/storage/hosted.js +13 -0
package/package.json
CHANGED
|
@@ -143,9 +143,11 @@ if [ -z "$SAAS_COUNT" ] || [ "$SAAS_COUNT" = "0" ]; then
|
|
|
143
143
|
"$TOAST" memento "✓ ${EXTRACTED_COUNT} memories stored" &>/dev/null
|
|
144
144
|
else
|
|
145
145
|
"$TOAST" memento "✓ No memories matched" &>/dev/null
|
|
146
|
-
exit 0
|
|
147
146
|
fi
|
|
148
|
-
|
|
147
|
+
exit 0
|
|
148
|
+
fi
|
|
149
|
+
|
|
150
|
+
if [ "$SAAS_COUNT" != "0" ]; then
|
|
149
151
|
if [ -n "$EXTRACTED_COUNT" ] && [ "$EXTRACTED_COUNT" != "0" ]; then
|
|
150
152
|
"$TOAST" memento "✓ ${SAAS_COUNT} recalled, ${EXTRACTED_COUNT} stored" &>/dev/null
|
|
151
153
|
else
|
|
@@ -159,11 +161,12 @@ if [ -n "$EXTRACTED_COUNT" ] && [ "$EXTRACTED_COUNT" != "0" ]; then
|
|
|
159
161
|
SUMMARY="${SUMMARY}, ${EXTRACTED_COUNT} memories stored"
|
|
160
162
|
fi
|
|
161
163
|
|
|
162
|
-
# Block the Stop so
|
|
164
|
+
# Block the Stop so recalled memories are injected into context.
|
|
165
|
+
# If no memories are relevant, respond with <...> to signal active silence.
|
|
163
166
|
REASON="${SUMMARY} surfaced from your last response.
|
|
164
167
|
${SAAS_DETAIL}
|
|
165
168
|
|
|
166
|
-
You have absorbed these memories into context. If any recalled memory is stale, wrong, or overlaps with others — update, delete, or consolidate it now. Otherwise continue naturally."
|
|
169
|
+
You have absorbed these memories into context. If any recalled memory is stale, wrong, or overlaps with others — update, delete, or consolidate it now. Otherwise respond with <...> to continue naturally."
|
|
167
170
|
|
|
168
171
|
python3 -c "
|
|
169
172
|
import json, sys
|
package/src/index.js
CHANGED
|
@@ -433,6 +433,72 @@ This is reconsolidation — like how the brain rebuilds memories on recall. Freq
|
|
|
433
433
|
}
|
|
434
434
|
);
|
|
435
435
|
|
|
436
|
+
// ---------------------------------------------------------------------------
|
|
437
|
+
// Tool: memento_extract
|
|
438
|
+
// ---------------------------------------------------------------------------
|
|
439
|
+
|
|
440
|
+
server.tool(
|
|
441
|
+
"memento_extract",
|
|
442
|
+
`Extract memories from a conversation transcript or the conversation buffer using LLM. Use this to manually trigger memory extraction — e.g., to flush the buffer before ending a session, or to extract from a pasted transcript.
|
|
443
|
+
|
|
444
|
+
Two modes:
|
|
445
|
+
- "distill" (default): Full extraction — facts, decisions, instructions, observations. Up to 20 memories.
|
|
446
|
+
- "seeds": Relational/experiential texture — preferences, emotions, sensory details. Up to 3 memories.
|
|
447
|
+
|
|
448
|
+
If no transcript is provided, reads from the conversation buffer (auto-populated by the context hook). Buffer is cleared after extraction unless keep_buffer is true.`,
|
|
449
|
+
{
|
|
450
|
+
transcript: z.string().optional().describe("Raw conversation text. If omitted, reads from the conversation buffer."),
|
|
451
|
+
mode: z.enum(["distill", "seeds"]).optional().describe("Extraction mode (default: distill)"),
|
|
452
|
+
max_memories: z.number().optional().describe("Override max memories to extract"),
|
|
453
|
+
keep_buffer: z.boolean().optional().describe("If true, don't clear the buffer after reading it"),
|
|
454
|
+
},
|
|
455
|
+
async ({ transcript, mode, max_memories, keep_buffer }) => {
|
|
456
|
+
const result = await storage.extractMemories(null, {
|
|
457
|
+
transcript,
|
|
458
|
+
mode,
|
|
459
|
+
max_memories,
|
|
460
|
+
keep_buffer,
|
|
461
|
+
});
|
|
462
|
+
|
|
463
|
+
if (result.error && !result.stored) {
|
|
464
|
+
return {
|
|
465
|
+
content: [{ type: "text", text: `Error: ${result.error}` }],
|
|
466
|
+
isError: true,
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
if (result.error) {
|
|
471
|
+
// Partial success — extraction ran but had issues
|
|
472
|
+
const summary = result.stored?.length > 0
|
|
473
|
+
? result.stored.map((m) => `- **${m.id}** (${m.type}): ${m.content}`).join("\n")
|
|
474
|
+
: "No memories extracted.";
|
|
475
|
+
return {
|
|
476
|
+
content: [{
|
|
477
|
+
type: "text",
|
|
478
|
+
text: `Extraction completed with warning: ${result.error}\n\n${summary}`,
|
|
479
|
+
}],
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
if (!result.stored || result.stored.length === 0) {
|
|
484
|
+
return {
|
|
485
|
+
content: [{
|
|
486
|
+
type: "text",
|
|
487
|
+
text: `No novel memories found (mode: ${result.mode || mode || "distill"}, source: ${result.source || "unknown"}).`,
|
|
488
|
+
}],
|
|
489
|
+
};
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
const summary = result.stored.map((m) => `- **${m.id}** (${m.type}): ${m.content}`).join("\n");
|
|
493
|
+
return {
|
|
494
|
+
content: [{
|
|
495
|
+
type: "text",
|
|
496
|
+
text: `Extracted ${result.count} memor${result.count === 1 ? "y" : "ies"} (mode: ${result.mode}, source: ${result.source}):\n\n${summary}`,
|
|
497
|
+
}],
|
|
498
|
+
};
|
|
499
|
+
}
|
|
500
|
+
);
|
|
501
|
+
|
|
436
502
|
// ---------------------------------------------------------------------------
|
|
437
503
|
// Tool: memento_skip_add
|
|
438
504
|
// ---------------------------------------------------------------------------
|
package/src/storage/hosted.js
CHANGED
|
@@ -261,6 +261,19 @@ export class HostedStorageAdapter extends StorageInterface {
|
|
|
261
261
|
return res;
|
|
262
262
|
}
|
|
263
263
|
|
|
264
|
+
async extractMemories(_wsPath, { transcript, mode, max_memories, source_tag, keep_buffer }) {
|
|
265
|
+
const body = {};
|
|
266
|
+
if (transcript) body.transcript = transcript;
|
|
267
|
+
if (mode) body.mode = mode;
|
|
268
|
+
if (max_memories) body.max_memories = max_memories;
|
|
269
|
+
if (source_tag) body.source_tag = source_tag;
|
|
270
|
+
if (keep_buffer !== undefined) body.keep_buffer = keep_buffer;
|
|
271
|
+
|
|
272
|
+
const res = await this._fetchJson("POST", "/v1/extract", body);
|
|
273
|
+
if (res.error && !res.stored) return { error: res.error };
|
|
274
|
+
return res;
|
|
275
|
+
}
|
|
276
|
+
|
|
264
277
|
async getIdentity(_wsPath) {
|
|
265
278
|
const { text, isError } = await this._fetch("GET", "/v1/identity");
|
|
266
279
|
if (isError) return { error: text };
|