mr-memory 2.18.3 ā 2.19.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/index.ts +55 -0
- package/package.json +1 -1
- package/upload.ts +6 -3
package/index.ts
CHANGED
|
@@ -872,6 +872,61 @@ const memoryRouterPlugin = {
|
|
|
872
872
|
await runUpload({ memoryKey, endpoint, targetPath, stateDir, workspacePath, hasWorkspaceFlag: !!opts.workspace, hasBrainFlag: !!opts.brain, embeddings });
|
|
873
873
|
});
|
|
874
874
|
|
|
875
|
+
mr.command("search")
|
|
876
|
+
.description("Search memories in vault")
|
|
877
|
+
.argument("<query>", "Search query")
|
|
878
|
+
.option("-n, --limit <number>", "Number of results", "5")
|
|
879
|
+
.action(async (query: string, opts: { limit: string }) => {
|
|
880
|
+
if (!memoryKey) { console.error("Not configured. Run: openclaw mr <key>"); return; }
|
|
881
|
+
const limit = parseInt(opts.limit, 10) || 5;
|
|
882
|
+
try {
|
|
883
|
+
const res = await fetch(`${endpoint}/v1/memory/search`, {
|
|
884
|
+
method: "POST",
|
|
885
|
+
headers: {
|
|
886
|
+
Authorization: `Bearer ${memoryKey}`,
|
|
887
|
+
"Content-Type": "application/json",
|
|
888
|
+
},
|
|
889
|
+
body: JSON.stringify({ query, limit }),
|
|
890
|
+
});
|
|
891
|
+
if (!res.ok) {
|
|
892
|
+
const err = await res.json() as { error?: string };
|
|
893
|
+
console.error(`Search failed: ${err.error || `HTTP ${res.status}`}`);
|
|
894
|
+
return;
|
|
895
|
+
}
|
|
896
|
+
const data = await res.json() as {
|
|
897
|
+
totalMemories: number;
|
|
898
|
+
tokenCount: number;
|
|
899
|
+
memories: Array<{
|
|
900
|
+
content: string;
|
|
901
|
+
score: number;
|
|
902
|
+
window: string;
|
|
903
|
+
timestampHuman: string;
|
|
904
|
+
role: string;
|
|
905
|
+
}>;
|
|
906
|
+
};
|
|
907
|
+
if (data.totalMemories === 0) {
|
|
908
|
+
console.log("No results found.");
|
|
909
|
+
return;
|
|
910
|
+
}
|
|
911
|
+
const modelLabel = embeddings ? ` (${embeddings})` : " (bge)";
|
|
912
|
+
console.log(`\nš ${data.totalMemories} results for "${query}"${modelLabel}\n`);
|
|
913
|
+
for (let i = 0; i < data.memories.length; i++) {
|
|
914
|
+
const m = data.memories[i];
|
|
915
|
+
const score = (m.score * 100).toFixed(1);
|
|
916
|
+
const date = new Date(m.timestampHuman).toLocaleDateString("en-US", {
|
|
917
|
+
month: "short", day: "numeric", year: "numeric",
|
|
918
|
+
});
|
|
919
|
+
const windowIcon = m.window === "immediate" ? "ā”" : m.window === "short" ? "š„" : m.window === "long" ? "š§ " : "š";
|
|
920
|
+
const preview = m.content.replace(/\n/g, " ").slice(0, 200);
|
|
921
|
+
console.log(` ${i + 1}. ${windowIcon} ${score}% | ${m.role} | ${date}`);
|
|
922
|
+
console.log(` ${preview}${m.content.length > 200 ? "..." : ""}\n`);
|
|
923
|
+
}
|
|
924
|
+
console.log(` Tokens: ${data.tokenCount}`);
|
|
925
|
+
} catch (err) {
|
|
926
|
+
console.error(`Failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
927
|
+
}
|
|
928
|
+
});
|
|
929
|
+
|
|
875
930
|
mr.command("delete")
|
|
876
931
|
.description("Clear all memories from vault")
|
|
877
932
|
.action(async () => {
|
package/package.json
CHANGED
package/upload.ts
CHANGED
|
@@ -143,7 +143,8 @@ type MemoryLine = {
|
|
|
143
143
|
const MAX_ITEM_CHARS = 8000;
|
|
144
144
|
const TARGET_CHUNK_CHARS = 4000;
|
|
145
145
|
const MAX_BATCH_BYTES = 2_000_000;
|
|
146
|
-
const
|
|
146
|
+
const MAX_BATCH_COUNT_DEFAULT = 100;
|
|
147
|
+
const MAX_BATCH_COUNT_QWEN = 25;
|
|
147
148
|
const BATCH_SLEEP_MS = 150;
|
|
148
149
|
const MAX_HTTP_RETRIES = 3;
|
|
149
150
|
|
|
@@ -430,14 +431,16 @@ export async function runUpload(params: {
|
|
|
430
431
|
return;
|
|
431
432
|
}
|
|
432
433
|
|
|
433
|
-
// Batch
|
|
434
|
+
// Batch ā smaller batches for Qwen (4096-dim vectors are 4x heavier)
|
|
435
|
+
const isQwen = embeddings && ['qwen', 'qwen3', 'qwen3-8b', 'qwen3-embedding', 'qwen3-embedding-8b'].includes(embeddings.toLowerCase());
|
|
436
|
+
const maxBatchCount = isQwen ? MAX_BATCH_COUNT_QWEN : MAX_BATCH_COUNT_DEFAULT;
|
|
434
437
|
const batches: MemoryLine[][] = [];
|
|
435
438
|
let currentBatch: MemoryLine[] = [];
|
|
436
439
|
let currentBytes = 0;
|
|
437
440
|
|
|
438
441
|
for (const line of allLines) {
|
|
439
442
|
const lineBytes = JSON.stringify(line).length + 1;
|
|
440
|
-
if (currentBytes + lineBytes > MAX_BATCH_BYTES || currentBatch.length >=
|
|
443
|
+
if (currentBytes + lineBytes > MAX_BATCH_BYTES || currentBatch.length >= maxBatchCount) {
|
|
441
444
|
if (currentBatch.length > 0) batches.push(currentBatch);
|
|
442
445
|
currentBatch = [line];
|
|
443
446
|
currentBytes = lineBytes;
|