memorix 1.9.0 → 1.9.1
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 +28 -0
- package/README.md +5 -1
- package/README.zh-CN.md +1 -1
- package/dist/cli/index.js +2508 -1843
- package/dist/index.js +2387 -1722
- package/dist/maintenance-runner.js +1686 -1031
- package/dist/media-audio-runner.js +2185 -1530
- package/dist/media-video-runner.js +2185 -1530
- package/dist/memcode-runtime/CHANGELOG.md +28 -0
- package/dist/sdk.js +2449 -1720
- package/dist/vector-backfill-runner.js +2183 -1528
- package/docs/CONFIGURATION.md +22 -0
- package/docs/DEVELOPMENT.md +2 -2
- package/docs/PERFORMANCE.md +77 -20
- package/docs/README.md +1 -1
- package/package.json +2 -1
- package/plugins/antigravity/memorix/plugin.json +1 -1
- package/plugins/claude/memorix/.claude-plugin/plugin.json +1 -1
- package/plugins/codebuddy/memorix/.codebuddy-plugin/plugin.json +1 -1
- package/plugins/codex/memorix/.codex-plugin/plugin.json +1 -1
- package/plugins/copilot/memorix/plugin.json +1 -1
- package/plugins/gemini/memorix/gemini-extension.json +1 -1
- package/plugins/hermes/memorix/plugin.yaml +1 -1
- package/plugins/omp/memorix/package.json +1 -1
- package/plugins/openclaw/memorix/.codex-plugin/plugin.json +1 -1
- package/plugins/pi/memorix/package.json +1 -1
- package/server.json +2 -2
- package/src/compact/engine.ts +14 -4
- package/src/memory/freshness.ts +7 -4
- package/src/memory/observations.ts +118 -6
- package/src/runtime/vector-backfill-runner.ts +1 -1
- package/src/sdk.ts +13 -6
- package/src/search/semantic-index.ts +340 -0
- package/src/server.ts +1 -1
- package/src/store/obs-store.ts +54 -2
- package/src/store/orama-store.ts +300 -12
- package/src/store/sqlite-db.ts +6 -0
- package/src/store/sqlite-fts.ts +164 -0
- package/src/store/sqlite-store.ts +83 -6
|
@@ -18,6 +18,13 @@
|
|
|
18
18
|
import type { Observation } from '../types.js';
|
|
19
19
|
import type { ObservationStore, StoreTransaction } from './obs-store.js';
|
|
20
20
|
import { getDatabase, closeDatabase } from './sqlite-db.js';
|
|
21
|
+
import {
|
|
22
|
+
isObservationLexicalIndexEnabled,
|
|
23
|
+
rebuildObservationLexicalIndex,
|
|
24
|
+
searchObservationLexically,
|
|
25
|
+
type SqliteLexicalSearchOptions,
|
|
26
|
+
} from './sqlite-fts.js';
|
|
27
|
+
import type { LexicalSearchHit } from './obs-store.js';
|
|
21
28
|
import path from 'node:path';
|
|
22
29
|
import fs from 'node:fs';
|
|
23
30
|
|
|
@@ -126,6 +133,9 @@ export class SqliteBackend implements ObservationStore {
|
|
|
126
133
|
private stmtSelectByProjectStatusNewest: any = null;
|
|
127
134
|
private stmtCountByProject: any = null;
|
|
128
135
|
private stmtCountByProjectStatus: any = null;
|
|
136
|
+
private stmtCountByProjectVisible: any = null;
|
|
137
|
+
private stmtCountByProjectStatusVisible: any = null;
|
|
138
|
+
private stmtCountAll: any = null;
|
|
129
139
|
private stmtSelectByTopicKey: any = null;
|
|
130
140
|
private stmtSelectGeneration: any = null;
|
|
131
141
|
private stmtBumpGeneration: any = null;
|
|
@@ -140,7 +150,7 @@ export class SqliteBackend implements ObservationStore {
|
|
|
140
150
|
|
|
141
151
|
// Prepare statements
|
|
142
152
|
this.stmtInsert = this.db.prepare(`
|
|
143
|
-
INSERT
|
|
153
|
+
INSERT INTO observations
|
|
144
154
|
(id, entityName, type, title, narrative, facts, filesModified, concepts, tokens,
|
|
145
155
|
createdAt, updatedAt, projectId, hasCausalLanguage, topicKey, revisionCount,
|
|
146
156
|
sessionId, status, progress, source, commitHash, relatedCommits, relatedEntities,
|
|
@@ -152,8 +162,39 @@ export class SqliteBackend implements ObservationStore {
|
|
|
152
162
|
@sessionId, @status, @progress, @source, @commitHash, @relatedCommits, @relatedEntities,
|
|
153
163
|
@attachments, @sourceDetail, @valueCategory, @admissionState, @admissionReason, @visibility, @sharedWithAgentIds,
|
|
154
164
|
@createdByAgentId, @writeGeneration)
|
|
165
|
+
ON CONFLICT(id) DO UPDATE SET
|
|
166
|
+
entityName = excluded.entityName,
|
|
167
|
+
type = excluded.type,
|
|
168
|
+
title = excluded.title,
|
|
169
|
+
narrative = excluded.narrative,
|
|
170
|
+
facts = excluded.facts,
|
|
171
|
+
filesModified = excluded.filesModified,
|
|
172
|
+
concepts = excluded.concepts,
|
|
173
|
+
tokens = excluded.tokens,
|
|
174
|
+
createdAt = excluded.createdAt,
|
|
175
|
+
updatedAt = excluded.updatedAt,
|
|
176
|
+
projectId = excluded.projectId,
|
|
177
|
+
hasCausalLanguage = excluded.hasCausalLanguage,
|
|
178
|
+
topicKey = excluded.topicKey,
|
|
179
|
+
revisionCount = excluded.revisionCount,
|
|
180
|
+
sessionId = excluded.sessionId,
|
|
181
|
+
status = excluded.status,
|
|
182
|
+
progress = excluded.progress,
|
|
183
|
+
source = excluded.source,
|
|
184
|
+
commitHash = excluded.commitHash,
|
|
185
|
+
relatedCommits = excluded.relatedCommits,
|
|
186
|
+
relatedEntities = excluded.relatedEntities,
|
|
187
|
+
attachments = excluded.attachments,
|
|
188
|
+
sourceDetail = excluded.sourceDetail,
|
|
189
|
+
valueCategory = excluded.valueCategory,
|
|
190
|
+
admissionState = excluded.admissionState,
|
|
191
|
+
admissionReason = excluded.admissionReason,
|
|
192
|
+
visibility = excluded.visibility,
|
|
193
|
+
sharedWithAgentIds = excluded.sharedWithAgentIds,
|
|
194
|
+
createdByAgentId = excluded.createdByAgentId,
|
|
195
|
+
writeGeneration = excluded.writeGeneration
|
|
155
196
|
`);
|
|
156
|
-
this.stmtUpdate = this.stmtInsert;
|
|
197
|
+
this.stmtUpdate = this.stmtInsert;
|
|
157
198
|
this.stmtSetStatus = this.db.prepare(`UPDATE observations SET status = ? WHERE id = ?`);
|
|
158
199
|
this.stmtSetStatusIfCurrent = this.db.prepare(
|
|
159
200
|
`UPDATE observations SET status = ? WHERE id = ? AND status = ?`,
|
|
@@ -191,6 +232,13 @@ export class SqliteBackend implements ObservationStore {
|
|
|
191
232
|
this.stmtCountByProjectStatus = this.db.prepare(
|
|
192
233
|
`SELECT COUNT(*) AS count FROM observations WHERE projectId = ? AND status = ?`,
|
|
193
234
|
);
|
|
235
|
+
this.stmtCountByProjectVisible = this.db.prepare(
|
|
236
|
+
`SELECT COUNT(*) AS count FROM observations WHERE projectId = ? AND (visibility IS NULL OR visibility = 'project')`,
|
|
237
|
+
);
|
|
238
|
+
this.stmtCountByProjectStatusVisible = this.db.prepare(
|
|
239
|
+
`SELECT COUNT(*) AS count FROM observations WHERE projectId = ? AND status = ? AND (visibility IS NULL OR visibility = 'project')`,
|
|
240
|
+
);
|
|
241
|
+
this.stmtCountAll = this.db.prepare(`SELECT COUNT(*) AS count FROM observations`);
|
|
194
242
|
this.stmtSelectByTopicKey = this.db.prepare(
|
|
195
243
|
`SELECT * FROM observations WHERE projectId = ? AND topicKey = ? ORDER BY id ASC LIMIT 1`,
|
|
196
244
|
);
|
|
@@ -322,10 +370,14 @@ export class SqliteBackend implements ObservationStore {
|
|
|
322
370
|
return this.rawGetById(id);
|
|
323
371
|
}
|
|
324
372
|
|
|
325
|
-
async countByProject(projectId: string, options: { status?: string } = {}): Promise<number> {
|
|
326
|
-
const row = options.
|
|
327
|
-
?
|
|
328
|
-
|
|
373
|
+
async countByProject(projectId: string, options: { status?: string; visibility?: 'project' } = {}): Promise<number> {
|
|
374
|
+
const row = options.visibility === 'project'
|
|
375
|
+
? (options.status
|
|
376
|
+
? this.stmtCountByProjectStatusVisible.get(projectId, options.status)
|
|
377
|
+
: this.stmtCountByProjectVisible.get(projectId))
|
|
378
|
+
: options.status
|
|
379
|
+
? this.stmtCountByProjectStatus.get(projectId, options.status)
|
|
380
|
+
: this.stmtCountByProject.get(projectId);
|
|
329
381
|
return Number(row?.count ?? 0);
|
|
330
382
|
}
|
|
331
383
|
|
|
@@ -333,6 +385,31 @@ export class SqliteBackend implements ObservationStore {
|
|
|
333
385
|
return this.rawLoadIdCounter();
|
|
334
386
|
}
|
|
335
387
|
|
|
388
|
+
async countAll(): Promise<number> {
|
|
389
|
+
return Number(this.stmtCountAll.get()?.count ?? 0);
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
async listProjectIds(): Promise<string[]> {
|
|
393
|
+
return (this.db.prepare('SELECT DISTINCT projectId FROM observations ORDER BY projectId').all() as Array<{ projectId?: string }>)
|
|
394
|
+
.map((row) => row.projectId)
|
|
395
|
+
.filter((projectId): projectId is string => Boolean(projectId));
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
async searchLexical(options: SqliteLexicalSearchOptions): Promise<LexicalSearchHit[]> {
|
|
399
|
+
return searchObservationLexically(this.db, options).map((hit) => ({
|
|
400
|
+
observation: rowToObs(hit.row),
|
|
401
|
+
score: hit.score,
|
|
402
|
+
}));
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
hasLexicalIndex(): boolean {
|
|
406
|
+
return isObservationLexicalIndexEnabled(this.db);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
async rebuildLexicalIndex(): Promise<boolean> {
|
|
410
|
+
return rebuildObservationLexicalIndex(this.db);
|
|
411
|
+
}
|
|
412
|
+
|
|
336
413
|
// ── Public write (each bumps generation) ─────────────────────────
|
|
337
414
|
|
|
338
415
|
async insert(obs: Observation): Promise<void> {
|