@linxiraos/pi-mnemopi 1.1.6 → 1.1.8
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/CHANGELOG.md +8 -0
- package/package.json +5 -5
- package/src/core/beam/helpers.ts +9 -6
- package/src/core/beam/index.ts +1 -1
- package/src/core/beam/recall.ts +8 -4
- package/src/core/entities.ts +2 -0
- package/src/core/patterns.ts +1 -1
- package/src/mcp-tools.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [1.1.8] - 2026-09-04
|
|
6
|
+
|
|
7
|
+
- OMP sync v18.1.2–v18.1.5: memory-backend plumbing aligned with the upstream mnemopi updates.
|
|
8
|
+
|
|
9
|
+
## [1.1.7] - 2026-09-01
|
|
10
|
+
|
|
11
|
+
- 同步上游 OMP v18.0.11(`b8ce33a58911c26bed1d84f0db9a5e2e727c49a2`)。
|
|
12
|
+
|
|
5
13
|
## [1.1.6] - 2026-08-30
|
|
6
14
|
|
|
7
15
|
- 同步上游 OMP v18.0.9(`cc14e04f075d`)。
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@linxiraos/pi-mnemopi",
|
|
4
|
-
"version": "1.1.
|
|
4
|
+
"version": "1.1.8",
|
|
5
5
|
"description": "Local SQLite memory engine for Oh My Pi agents",
|
|
6
6
|
"homepage": "https://linxira-os.github.io/zeta/",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -39,10 +39,10 @@
|
|
|
39
39
|
"fmt": "biome format --write ."
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@linxiraos/pi-ai": "1.1.
|
|
43
|
-
"@linxiraos/pi-catalog": "1.1.
|
|
44
|
-
"@linxiraos/pi-natives": "1.1.
|
|
45
|
-
"@linxiraos/pi-utils": "1.1.
|
|
42
|
+
"@linxiraos/pi-ai": "1.1.8",
|
|
43
|
+
"@linxiraos/pi-catalog": "1.1.8",
|
|
44
|
+
"@linxiraos/pi-natives": "1.1.8",
|
|
45
|
+
"@linxiraos/pi-utils": "1.1.8"
|
|
46
46
|
},
|
|
47
47
|
"peerDependencies": {
|
|
48
48
|
"fastembed": "2.1.0",
|
package/src/core/beam/helpers.ts
CHANGED
|
@@ -270,8 +270,9 @@ export function cjkLikeSearch(
|
|
|
270
270
|
const conditions = cjkChars.map(() => "content LIKE ? ESCAPE '\\'").join(" OR ");
|
|
271
271
|
try {
|
|
272
272
|
const rows = db
|
|
273
|
-
.query(`SELECT ${idColumn}, content FROM ${table} WHERE superseded_by IS NULL AND (
|
|
274
|
-
|
|
273
|
+
.query(`SELECT ${idColumn}, content FROM ${table} WHERE superseded_by IS NULL AND (valid_until IS NULL OR valid_until > ?)
|
|
274
|
+
AND (${conditions}) LIMIT ?`)
|
|
275
|
+
.all(new Date().toISOString(), ...cjkChars.map(ch => `%${ch}%`), k * 5) as Record<string, unknown>[];
|
|
275
276
|
const scored: Array<{ id: string | number; score: number }> = [];
|
|
276
277
|
for (const row of rows) {
|
|
277
278
|
const content = String(row.content ?? "");
|
|
@@ -298,9 +299,10 @@ export function ftsSearch(db: Database, query: string, k = 20): FtsRankResult[]
|
|
|
298
299
|
const rows = db
|
|
299
300
|
.query(`SELECT f.rowid, f.rank FROM fts_episodes f
|
|
300
301
|
WHERE f.fts_episodes MATCH ?
|
|
301
|
-
AND EXISTS (SELECT 1 FROM episodic_memory e WHERE e.rowid = f.rowid AND e.superseded_by IS NULL
|
|
302
|
+
AND EXISTS (SELECT 1 FROM episodic_memory e WHERE e.rowid = f.rowid AND e.superseded_by IS NULL
|
|
303
|
+
AND (e.valid_until IS NULL OR e.valid_until > ?))
|
|
302
304
|
ORDER BY f.rank, f.rowid LIMIT ?`)
|
|
303
|
-
.all(ftsQuery, k) as Record<string, unknown>[];
|
|
305
|
+
.all(ftsQuery, new Date().toISOString(), k) as Record<string, unknown>[];
|
|
304
306
|
if (rows.length === 0 && hasCjk(query)) return cjkLikeSearch(db, query, k, false) as FtsRankResult[];
|
|
305
307
|
return rows.map(row => ({ rowid: Number(row.rowid), rank: Number(row.rank) }));
|
|
306
308
|
} catch {
|
|
@@ -315,9 +317,10 @@ export function ftsSearchWorking(db: Database, query: string, k = 20): WorkingFt
|
|
|
315
317
|
const rows = db
|
|
316
318
|
.query(`SELECT f.id, f.rank FROM fts_working f
|
|
317
319
|
WHERE f.fts_working MATCH ?
|
|
318
|
-
AND EXISTS (SELECT 1 FROM working_memory w WHERE w.id = f.id AND w.superseded_by IS NULL
|
|
320
|
+
AND EXISTS (SELECT 1 FROM working_memory w WHERE w.id = f.id AND w.superseded_by IS NULL
|
|
321
|
+
AND (w.valid_until IS NULL OR w.valid_until > ?))
|
|
319
322
|
ORDER BY f.rank, f.id LIMIT ?`)
|
|
320
|
-
.all(ftsQuery, k) as Record<string, unknown>[];
|
|
323
|
+
.all(ftsQuery, new Date().toISOString(), k) as Record<string, unknown>[];
|
|
321
324
|
if (rows.length === 0 && hasCjk(query)) return cjkLikeSearch(db, query, k, true) as WorkingFtsRankResult[];
|
|
322
325
|
return rows.map(row => ({ id: String(row.id), rank: Number(row.rank) }));
|
|
323
326
|
} catch {
|
package/src/core/beam/index.ts
CHANGED
|
@@ -201,7 +201,7 @@ export class BeamMemory implements BeamMemoryState {
|
|
|
201
201
|
|
|
202
202
|
async flushExtractions(): Promise<void> {
|
|
203
203
|
while (this.pendingExtractions.size > 0) {
|
|
204
|
-
await Promise.allSettled(
|
|
204
|
+
await Promise.allSettled(this.pendingExtractions);
|
|
205
205
|
}
|
|
206
206
|
}
|
|
207
207
|
|
package/src/core/beam/recall.ts
CHANGED
|
@@ -442,6 +442,7 @@ function ftsQuery(query: string, useSynonyms = true): string {
|
|
|
442
442
|
}
|
|
443
443
|
|
|
444
444
|
function placeholders(count: number): string {
|
|
445
|
+
// [suppressed] length preallocation
|
|
445
446
|
return new Array<string>(count).fill("?").join(",");
|
|
446
447
|
}
|
|
447
448
|
|
|
@@ -556,18 +557,20 @@ function ftsRows(
|
|
|
556
557
|
// 0.042ms. EXISTS probes the primary key only for rows MATCH actually produced.
|
|
557
558
|
`SELECT f.id, f.rank FROM fts_working f
|
|
558
559
|
WHERE f.fts_working MATCH ?
|
|
559
|
-
AND EXISTS (SELECT 1 FROM working_memory w WHERE w.id = f.id AND w.superseded_by IS NULL
|
|
560
|
+
AND EXISTS (SELECT 1 FROM working_memory w WHERE w.id = f.id AND w.superseded_by IS NULL
|
|
561
|
+
AND (w.valid_until IS NULL OR w.valid_until > ?))
|
|
560
562
|
ORDER BY f.rank, f.id LIMIT ?`,
|
|
561
|
-
[ftsQuery(query, useSynonyms), limit],
|
|
563
|
+
[ftsQuery(query, useSynonyms), nowIso(), limit],
|
|
562
564
|
);
|
|
563
565
|
}
|
|
564
566
|
return queryAll(
|
|
565
567
|
beam,
|
|
566
568
|
`SELECT f.rowid, f.rank FROM fts_episodes f
|
|
567
569
|
WHERE f.fts_episodes MATCH ?
|
|
568
|
-
AND EXISTS (SELECT 1 FROM episodic_memory e WHERE e.rowid = f.rowid AND e.superseded_by IS NULL
|
|
570
|
+
AND EXISTS (SELECT 1 FROM episodic_memory e WHERE e.rowid = f.rowid AND e.superseded_by IS NULL
|
|
571
|
+
AND (e.valid_until IS NULL OR e.valid_until > ?))
|
|
569
572
|
ORDER BY f.rank, f.rowid LIMIT ?`,
|
|
570
|
-
[ftsQuery(query, useSynonyms), limit],
|
|
573
|
+
[ftsQuery(query, useSynonyms), nowIso(), limit],
|
|
571
574
|
);
|
|
572
575
|
} catch {
|
|
573
576
|
return [];
|
|
@@ -598,6 +601,7 @@ function parseEmbedding(raw: unknown): number[] | null {
|
|
|
598
601
|
try {
|
|
599
602
|
const parsed = JSON.parse(raw) as unknown;
|
|
600
603
|
if (!Array.isArray(parsed)) return null;
|
|
604
|
+
// [suppressed] length preallocation
|
|
601
605
|
const vector = new Array<number>(parsed.length);
|
|
602
606
|
for (let i = 0; i < parsed.length; i += 1) {
|
|
603
607
|
const value = Number(parsed[i]);
|
package/src/core/entities.ts
CHANGED
|
@@ -144,7 +144,9 @@ export function levenshteinDistance(s1: string, s2: string): number {
|
|
|
144
144
|
}
|
|
145
145
|
if (right.length === 0) return left.length;
|
|
146
146
|
|
|
147
|
+
// [suppressed] length preallocation
|
|
147
148
|
let previousRow = new Array<number>(right.length + 1);
|
|
149
|
+
// [suppressed] length preallocation
|
|
148
150
|
let currentRow = new Array<number>(right.length + 1).fill(0);
|
|
149
151
|
for (let i = 0; i <= right.length; i++) previousRow[i] = i;
|
|
150
152
|
|
package/src/core/patterns.ts
CHANGED
|
@@ -203,7 +203,7 @@ export class DetectedPattern {
|
|
|
203
203
|
this.description = init.description;
|
|
204
204
|
this.confidence = init.confidence;
|
|
205
205
|
this.samples = [...(init.samples ?? [])];
|
|
206
|
-
this.metadata = { ...
|
|
206
|
+
this.metadata = { ...init.metadata };
|
|
207
207
|
}
|
|
208
208
|
|
|
209
209
|
toDict(): Record<string, unknown> {
|
package/src/mcp-tools.ts
CHANGED
|
@@ -759,7 +759,7 @@ async function handleSharedRemember(args: ToolArguments): Promise<ToolResult> {
|
|
|
759
759
|
const memoryId = beam.remember(labelled, {
|
|
760
760
|
source: "surface_manual",
|
|
761
761
|
importance: Math.max(0, Math.min(1, numberArg(args, "importance", 0.8))),
|
|
762
|
-
metadata: { ...
|
|
762
|
+
metadata: { ...metadataArg(args), shared_memory: true, surface_kind: kind },
|
|
763
763
|
veracity: stringArg(args, "veracity", "unknown"),
|
|
764
764
|
scope: "global",
|
|
765
765
|
});
|