shieldcortex 3.0.3 → 3.1.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 +5 -2
- package/dashboard/.next/standalone/dashboard/.next/BUILD_ID +1 -1
- package/dashboard/.next/standalone/dashboard/.next/build-manifest.json +2 -2
- package/dashboard/.next/standalone/dashboard/.next/prerender-manifest.json +3 -3
- package/dashboard/.next/standalone/dashboard/.next/required-server-files.json +4 -4
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.rsc +3 -3
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_full.segment.rsc +3 -3
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_index.segment.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/page/react-loadable-manifest.json +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/dashboard_3051539d._.js +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/pages/404.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/pages/500.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/server-reference-manifest.js +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/server-reference-manifest.json +1 -1
- package/dashboard/.next/standalone/dashboard/.next/static/chunks/0a69eb25d08447ee.js +1 -0
- package/dashboard/.next/standalone/dashboard/.next/static/chunks/9232a2d99b47b21f.js +3 -0
- package/dashboard/.next/standalone/dashboard/.next/static/chunks/97537d3db46c8467.css +3 -0
- package/dashboard/.next/standalone/dashboard/.next/static/chunks/aa6e9b8a52353969.js +9 -0
- package/dashboard/.next/standalone/dashboard/node_modules/@img/sharp-darwin-arm64/lib/sharp-darwin-arm64.node +0 -0
- package/dashboard/.next/standalone/{node_modules/@img/sharp-linux-x64 → dashboard/node_modules/@img/sharp-darwin-arm64}/package.json +7 -13
- package/dashboard/.next/standalone/dashboard/node_modules/@img/{sharp-libvips-linux-x64 → sharp-libvips-darwin-arm64}/README.md +2 -2
- package/dashboard/.next/standalone/dashboard/node_modules/@img/{sharp-libvips-linux-x64 → sharp-libvips-darwin-arm64}/lib/glib-2.0/include/glibconfig.h +8 -9
- package/dashboard/.next/standalone/dashboard/node_modules/@img/{sharp-libvips-linux-x64/lib/libvips-cpp.so.8.17.3 → sharp-libvips-darwin-arm64/lib/libvips-cpp.8.17.3.dylib} +0 -0
- package/dashboard/.next/standalone/dashboard/node_modules/@img/{sharp-libvips-linux-x64 → sharp-libvips-darwin-arm64}/package.json +5 -11
- package/dashboard/.next/standalone/dashboard/server.js +1 -1
- package/dashboard/.next/standalone/{dashboard/node_modules/@img/sharp-linux-x64 → node_modules/@img/sharp-darwin-arm64}/package.json +7 -13
- package/dashboard/.next/standalone/node_modules/@img/{sharp-libvips-linux-x64 → sharp-libvips-darwin-arm64}/package.json +5 -11
- package/dist/api/routes/admin.d.ts +12 -0
- package/dist/api/routes/admin.js +502 -0
- package/dist/api/routes/graph.d.ts +4 -0
- package/dist/api/routes/graph.js +333 -0
- package/dist/api/routes/incidents.d.ts +2 -0
- package/dist/api/routes/incidents.js +32 -0
- package/dist/api/routes/memories.d.ts +4 -0
- package/dist/api/routes/memories.js +659 -0
- package/dist/api/routes/recall.d.ts +4 -0
- package/dist/api/routes/recall.js +36 -0
- package/dist/api/routes/system.d.ts +9 -0
- package/dist/api/routes/system.js +266 -0
- package/dist/api/visualization-server.js +31 -1913
- package/dist/cloud/cli.d.ts +1 -0
- package/dist/cloud/cli.js +40 -0
- package/dist/cloud/config.d.ts +10 -0
- package/dist/cloud/config.js +54 -0
- package/dist/cloud/graph-sync.d.ts +45 -0
- package/dist/cloud/graph-sync.js +257 -0
- package/dist/cloud/memory-sync.d.ts +36 -0
- package/dist/cloud/memory-sync.js +183 -0
- package/dist/cloud/sync-queue.d.ts +24 -0
- package/dist/cloud/sync-queue.js +126 -7
- package/dist/database/init.js +24 -0
- package/dist/graph/backfill.js +3 -5
- package/dist/graph/resolve.d.ts +10 -0
- package/dist/graph/resolve.js +63 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +61 -4
- package/dist/memory/search.d.ts +37 -0
- package/dist/memory/search.js +143 -0
- package/dist/memory/store.js +47 -171
- package/dist/memory/types.d.ts +2 -0
- package/dist/service/install.d.ts +1 -0
- package/dist/service/install.js +43 -1
- package/dist/tools/recall.d.ts +1 -1
- package/hooks/openclaw/cortex-memory/handler.ts +5 -141
- package/hooks/openclaw/cortex-memory/runtime.mjs +129 -0
- package/package.json +8 -4
- package/plugins/openclaw/dist/index.js +5 -39
- package/scripts/run-jest.mjs +25 -1
- package/dashboard/.next/standalone/dashboard/.next/static/chunks/be6970da20a17c0b.js +0 -9
- package/dashboard/.next/standalone/dashboard/.next/static/chunks/e63d2228780629dd.css +0 -3
- package/dashboard/.next/standalone/dashboard/.next/static/chunks/f69fd1c5e71fbbfd.js +0 -1
- package/dashboard/.next/standalone/dashboard/.next/static/chunks/fa5217550a8ab9a6.js +0 -3
- package/dashboard/.next/standalone/dashboard/node_modules/@img/sharp-libvips-linuxmusl-x64/README.md +0 -46
- package/dashboard/.next/standalone/dashboard/node_modules/@img/sharp-libvips-linuxmusl-x64/lib/glib-2.0/include/glibconfig.h +0 -221
- package/dashboard/.next/standalone/dashboard/node_modules/@img/sharp-libvips-linuxmusl-x64/lib/index.js +0 -1
- package/dashboard/.next/standalone/dashboard/node_modules/@img/sharp-libvips-linuxmusl-x64/lib/libvips-cpp.so.8.17.3 +0 -0
- package/dashboard/.next/standalone/dashboard/node_modules/@img/sharp-libvips-linuxmusl-x64/package.json +0 -42
- package/dashboard/.next/standalone/dashboard/node_modules/@img/sharp-libvips-linuxmusl-x64/versions.json +0 -30
- package/dashboard/.next/standalone/dashboard/node_modules/@img/sharp-linux-x64/lib/sharp-linux-x64.node +0 -0
- package/dashboard/.next/standalone/dashboard/node_modules/@img/sharp-linuxmusl-x64/lib/sharp-linuxmusl-x64.node +0 -0
- package/dashboard/.next/standalone/dashboard/node_modules/@img/sharp-linuxmusl-x64/package.json +0 -46
- package/dashboard/.next/standalone/dashboard/node_modules/typescript/lib/_tsc.js +0 -133818
- package/dashboard/.next/standalone/dashboard/node_modules/typescript/lib/_tsserver.js +0 -659
- package/dashboard/.next/standalone/dashboard/node_modules/typescript/lib/_typingsInstaller.js +0 -222
- package/dashboard/.next/standalone/dashboard/node_modules/typescript/lib/cs/diagnosticMessages.generated.json +0 -2122
- package/dashboard/.next/standalone/dashboard/node_modules/typescript/lib/de/diagnosticMessages.generated.json +0 -2122
- package/dashboard/.next/standalone/dashboard/node_modules/typescript/lib/es/diagnosticMessages.generated.json +0 -2122
- package/dashboard/.next/standalone/dashboard/node_modules/typescript/lib/fr/diagnosticMessages.generated.json +0 -2122
- package/dashboard/.next/standalone/dashboard/node_modules/typescript/lib/it/diagnosticMessages.generated.json +0 -2122
- package/dashboard/.next/standalone/dashboard/node_modules/typescript/lib/ja/diagnosticMessages.generated.json +0 -2122
- package/dashboard/.next/standalone/dashboard/node_modules/typescript/lib/ko/diagnosticMessages.generated.json +0 -2122
- package/dashboard/.next/standalone/dashboard/node_modules/typescript/lib/pl/diagnosticMessages.generated.json +0 -2122
- package/dashboard/.next/standalone/dashboard/node_modules/typescript/lib/pt-br/diagnosticMessages.generated.json +0 -2122
- package/dashboard/.next/standalone/dashboard/node_modules/typescript/lib/ru/diagnosticMessages.generated.json +0 -2122
- package/dashboard/.next/standalone/dashboard/node_modules/typescript/lib/tr/diagnosticMessages.generated.json +0 -2122
- package/dashboard/.next/standalone/dashboard/node_modules/typescript/lib/tsc.js +0 -8
- package/dashboard/.next/standalone/dashboard/node_modules/typescript/lib/tsserver.js +0 -8
- package/dashboard/.next/standalone/dashboard/node_modules/typescript/lib/tsserverlibrary.js +0 -21
- package/dashboard/.next/standalone/dashboard/node_modules/typescript/lib/typesMap.json +0 -497
- package/dashboard/.next/standalone/dashboard/node_modules/typescript/lib/typescript.js +0 -200276
- package/dashboard/.next/standalone/dashboard/node_modules/typescript/lib/typingsInstaller.js +0 -8
- package/dashboard/.next/standalone/dashboard/node_modules/typescript/lib/watchGuard.js +0 -53
- package/dashboard/.next/standalone/dashboard/node_modules/typescript/lib/zh-cn/diagnosticMessages.generated.json +0 -2122
- package/dashboard/.next/standalone/dashboard/node_modules/typescript/lib/zh-tw/diagnosticMessages.generated.json +0 -2122
- package/dashboard/.next/standalone/dashboard/node_modules/typescript/package.json +0 -120
- package/dashboard/.next/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64/package.json +0 -42
- package/dashboard/.next/standalone/node_modules/@img/sharp-linuxmusl-x64/package.json +0 -46
- package/scripts/start-dashboard.sh +0 -41
- package/scripts/stop-dashboard.sh +0 -21
- /package/dashboard/.next/standalone/dashboard/.next/static/{THy6JENQ0c1sq6jQhvIDp → RnvqrTXo_jN8SuMdaNcIj}/_buildManifest.js +0 -0
- /package/dashboard/.next/standalone/dashboard/.next/static/{THy6JENQ0c1sq6jQhvIDp → RnvqrTXo_jN8SuMdaNcIj}/_clientMiddlewareManifest.json +0 -0
- /package/dashboard/.next/standalone/dashboard/.next/static/{THy6JENQ0c1sq6jQhvIDp → RnvqrTXo_jN8SuMdaNcIj}/_ssgManifest.js +0 -0
- /package/dashboard/.next/standalone/dashboard/node_modules/@img/{sharp-libvips-linux-x64 → sharp-libvips-darwin-arm64}/lib/index.js +0 -0
- /package/dashboard/.next/standalone/dashboard/node_modules/@img/{sharp-libvips-linux-x64 → sharp-libvips-darwin-arm64}/versions.json +0 -0
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
* Supports both audit metadata sync and quarantine content sync payloads.
|
|
6
6
|
* Uses SQLite sync_queue table with exponential backoff.
|
|
7
7
|
*/
|
|
8
|
+
import type { SyncedMemoryRecord } from './memory-sync.js';
|
|
9
|
+
import type { GraphSyncEnvelope } from './graph-sync.js';
|
|
8
10
|
export interface SyncEntry {
|
|
9
11
|
source_type: string;
|
|
10
12
|
source_identifier: string;
|
|
@@ -37,6 +39,15 @@ export interface QueueStats {
|
|
|
37
39
|
pending: number;
|
|
38
40
|
failed: number;
|
|
39
41
|
synced: number;
|
|
42
|
+
byKind: Record<'audit' | 'quarantine' | 'memory' | 'graph' | 'unknown', {
|
|
43
|
+
pending: number;
|
|
44
|
+
failed: number;
|
|
45
|
+
synced: number;
|
|
46
|
+
}>;
|
|
47
|
+
oldestPendingAt: string | null;
|
|
48
|
+
nextRetryAt: string | null;
|
|
49
|
+
lastError: string | null;
|
|
50
|
+
lastErrorKind: 'audit' | 'quarantine' | 'memory' | 'graph' | 'unknown' | null;
|
|
40
51
|
}
|
|
41
52
|
export interface SyncQueueResult {
|
|
42
53
|
processed: number;
|
|
@@ -44,6 +55,9 @@ export interface SyncQueueResult {
|
|
|
44
55
|
failed: number;
|
|
45
56
|
permanentlyFailed: number;
|
|
46
57
|
}
|
|
58
|
+
export interface ReconcileQueueResult {
|
|
59
|
+
removed: number;
|
|
60
|
+
}
|
|
47
61
|
/**
|
|
48
62
|
* Enqueue a failed sync entry for later retry.
|
|
49
63
|
* INSERT into sync_queue with exponential backoff schedule.
|
|
@@ -53,6 +67,11 @@ export declare function enqueueFailedSync(entry: SyncEntry): void;
|
|
|
53
67
|
* Enqueue a failed quarantine sync entry for later retry.
|
|
54
68
|
*/
|
|
55
69
|
export declare function enqueueFailedQuarantineSync(entry: QuarantineSyncEntry): void;
|
|
70
|
+
/**
|
|
71
|
+
* Enqueue a failed memory sync entry for later retry.
|
|
72
|
+
*/
|
|
73
|
+
export declare function enqueueFailedMemorySync(entry: SyncedMemoryRecord): void;
|
|
74
|
+
export declare function enqueueFailedGraphSync(entry: GraphSyncEnvelope): void;
|
|
56
75
|
/**
|
|
57
76
|
* Process pending items in the retry queue.
|
|
58
77
|
* SELECT pending WHERE next_retry_at <= now, retry each (up to 10 per tick).
|
|
@@ -63,6 +82,11 @@ export declare function processRetryQueue(): Promise<SyncQueueResult>;
|
|
|
63
82
|
* Get queue statistics by status.
|
|
64
83
|
*/
|
|
65
84
|
export declare function getQueueStats(): QueueStats;
|
|
85
|
+
export declare function reconcileSyncQueue(options?: {
|
|
86
|
+
kinds?: Array<'memory' | 'graph' | 'audit' | 'quarantine'>;
|
|
87
|
+
statuses?: Array<'pending' | 'failed'>;
|
|
88
|
+
maxCreatedAt?: string | null;
|
|
89
|
+
}): ReconcileQueueResult;
|
|
66
90
|
/**
|
|
67
91
|
* Purge old entries from the queue.
|
|
68
92
|
* DELETE WHERE created_at < 7 days ago.
|
package/dist/cloud/sync-queue.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* Uses SQLite sync_queue table with exponential backoff.
|
|
7
7
|
*/
|
|
8
8
|
import { getDatabase } from '../database/init.js';
|
|
9
|
-
import { getCloudConfig, updateLastSyncAt } from './config.js';
|
|
9
|
+
import { getCloudConfig, getDeviceId, getDeviceName, updateLastSyncAt } from './config.js';
|
|
10
10
|
/**
|
|
11
11
|
* Enqueue a failed sync entry for later retry.
|
|
12
12
|
* INSERT into sync_queue with exponential backoff schedule.
|
|
@@ -20,6 +20,23 @@ export function enqueueFailedSync(entry) {
|
|
|
20
20
|
export function enqueueFailedQuarantineSync(entry) {
|
|
21
21
|
enqueuePayload({ kind: 'quarantine', entry });
|
|
22
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* Enqueue a failed memory sync entry for later retry.
|
|
25
|
+
*/
|
|
26
|
+
export function enqueueFailedMemorySync(entry) {
|
|
27
|
+
enqueuePayload({
|
|
28
|
+
kind: 'memory',
|
|
29
|
+
entry: {
|
|
30
|
+
record: entry,
|
|
31
|
+
device_id: getDeviceId(),
|
|
32
|
+
device_name: getDeviceName(),
|
|
33
|
+
platform: `${process.platform}/${process.arch}`,
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
export function enqueueFailedGraphSync(entry) {
|
|
38
|
+
enqueuePayload({ kind: 'graph', entry });
|
|
39
|
+
}
|
|
23
40
|
function enqueuePayload(payload) {
|
|
24
41
|
const db = getDatabase();
|
|
25
42
|
const payloadJson = JSON.stringify(payload);
|
|
@@ -60,6 +77,35 @@ function buildRetryRequest(payloadText) {
|
|
|
60
77
|
body: JSON.stringify(payload.entry),
|
|
61
78
|
};
|
|
62
79
|
}
|
|
80
|
+
if (parsed &&
|
|
81
|
+
typeof parsed === 'object' &&
|
|
82
|
+
!Array.isArray(parsed) &&
|
|
83
|
+
'kind' in parsed &&
|
|
84
|
+
parsed.kind === 'memory') {
|
|
85
|
+
const payload = parsed;
|
|
86
|
+
return {
|
|
87
|
+
path: '/v1/sync/memories',
|
|
88
|
+
body: JSON.stringify({
|
|
89
|
+
device: {
|
|
90
|
+
device_id: payload.entry.device_id,
|
|
91
|
+
device_name: payload.entry.device_name,
|
|
92
|
+
platform: payload.entry.platform,
|
|
93
|
+
},
|
|
94
|
+
memories: [payload.entry.record],
|
|
95
|
+
}),
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
if (parsed &&
|
|
99
|
+
typeof parsed === 'object' &&
|
|
100
|
+
!Array.isArray(parsed) &&
|
|
101
|
+
'kind' in parsed &&
|
|
102
|
+
parsed.kind === 'graph') {
|
|
103
|
+
const payload = parsed;
|
|
104
|
+
return {
|
|
105
|
+
path: '/v1/sync/graph',
|
|
106
|
+
body: JSON.stringify(payload.entry),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
63
109
|
throw new Error('Unsupported sync queue payload');
|
|
64
110
|
}
|
|
65
111
|
/**
|
|
@@ -167,21 +213,94 @@ export async function processRetryQueue() {
|
|
|
167
213
|
export function getQueueStats() {
|
|
168
214
|
const db = getDatabase();
|
|
169
215
|
const rows = db.prepare(`
|
|
170
|
-
SELECT status,
|
|
216
|
+
SELECT id, payload, status, next_retry_at, last_error, created_at
|
|
171
217
|
FROM sync_queue
|
|
172
|
-
GROUP BY status
|
|
173
218
|
`).all();
|
|
174
|
-
const stats = {
|
|
219
|
+
const stats = {
|
|
220
|
+
pending: 0,
|
|
221
|
+
failed: 0,
|
|
222
|
+
synced: 0,
|
|
223
|
+
byKind: {
|
|
224
|
+
audit: { pending: 0, failed: 0, synced: 0 },
|
|
225
|
+
quarantine: { pending: 0, failed: 0, synced: 0 },
|
|
226
|
+
memory: { pending: 0, failed: 0, synced: 0 },
|
|
227
|
+
graph: { pending: 0, failed: 0, synced: 0 },
|
|
228
|
+
unknown: { pending: 0, failed: 0, synced: 0 },
|
|
229
|
+
},
|
|
230
|
+
oldestPendingAt: null,
|
|
231
|
+
nextRetryAt: null,
|
|
232
|
+
lastError: null,
|
|
233
|
+
lastErrorKind: null,
|
|
234
|
+
};
|
|
235
|
+
let newestErrorRowId = -1;
|
|
175
236
|
for (const row of rows) {
|
|
237
|
+
const kind = getPayloadKind(row.payload);
|
|
176
238
|
if (row.status === 'pending')
|
|
177
|
-
stats.pending
|
|
239
|
+
stats.pending++;
|
|
178
240
|
else if (row.status === 'failed')
|
|
179
|
-
stats.failed
|
|
241
|
+
stats.failed++;
|
|
180
242
|
else if (row.status === 'synced')
|
|
181
|
-
stats.synced
|
|
243
|
+
stats.synced++;
|
|
244
|
+
if (row.status === 'pending' || row.status === 'failed' || row.status === 'synced') {
|
|
245
|
+
stats.byKind[kind][row.status]++;
|
|
246
|
+
}
|
|
247
|
+
if (row.status === 'pending' && row.created_at) {
|
|
248
|
+
if (!stats.oldestPendingAt || row.created_at < stats.oldestPendingAt) {
|
|
249
|
+
stats.oldestPendingAt = row.created_at;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
if (row.status === 'pending' && row.next_retry_at) {
|
|
253
|
+
if (!stats.nextRetryAt || row.next_retry_at < stats.nextRetryAt) {
|
|
254
|
+
stats.nextRetryAt = row.next_retry_at;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
if (row.last_error && row.id > newestErrorRowId) {
|
|
258
|
+
newestErrorRowId = row.id;
|
|
259
|
+
stats.lastError = row.last_error;
|
|
260
|
+
stats.lastErrorKind = kind;
|
|
261
|
+
}
|
|
182
262
|
}
|
|
183
263
|
return stats;
|
|
184
264
|
}
|
|
265
|
+
export function reconcileSyncQueue(options = {}) {
|
|
266
|
+
const db = getDatabase();
|
|
267
|
+
const kinds = options.kinds ?? ['memory', 'graph'];
|
|
268
|
+
const statuses = options.statuses ?? ['pending', 'failed'];
|
|
269
|
+
if (kinds.length === 0 || statuses.length === 0) {
|
|
270
|
+
return { removed: 0 };
|
|
271
|
+
}
|
|
272
|
+
const kindPlaceholders = kinds.map(() => '?').join(', ');
|
|
273
|
+
const statusPlaceholders = statuses.map(() => '?').join(', ');
|
|
274
|
+
const params = [...statuses, ...kinds];
|
|
275
|
+
let sqlText = `
|
|
276
|
+
DELETE FROM sync_queue
|
|
277
|
+
WHERE status IN (${statusPlaceholders})
|
|
278
|
+
AND json_extract(payload, '$.kind') IN (${kindPlaceholders})
|
|
279
|
+
`;
|
|
280
|
+
if (options.maxCreatedAt) {
|
|
281
|
+
sqlText += ' AND created_at <= ?';
|
|
282
|
+
params.push(options.maxCreatedAt);
|
|
283
|
+
}
|
|
284
|
+
const result = db.prepare(sqlText).run(...params);
|
|
285
|
+
return { removed: Number(result.changes ?? 0) };
|
|
286
|
+
}
|
|
287
|
+
function getPayloadKind(payloadText) {
|
|
288
|
+
try {
|
|
289
|
+
const parsed = JSON.parse(payloadText);
|
|
290
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed) && 'kind' in parsed) {
|
|
291
|
+
const kind = parsed.kind;
|
|
292
|
+
if (kind === 'audit' || kind === 'quarantine' || kind === 'memory' || kind === 'graph')
|
|
293
|
+
return kind;
|
|
294
|
+
}
|
|
295
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
296
|
+
return 'audit';
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
catch {
|
|
300
|
+
// ignore malformed payloads
|
|
301
|
+
}
|
|
302
|
+
return 'unknown';
|
|
303
|
+
}
|
|
185
304
|
/**
|
|
186
305
|
* Purge old entries from the queue.
|
|
187
306
|
* DELETE WHERE created_at < 7 days ago.
|
package/dist/database/init.js
CHANGED
|
@@ -7,6 +7,7 @@ import { dirname, join } from 'path';
|
|
|
7
7
|
import { homedir } from 'os';
|
|
8
8
|
import { fileURLToPath } from 'url';
|
|
9
9
|
import { execSync } from 'child_process';
|
|
10
|
+
import { randomUUID } from 'crypto';
|
|
10
11
|
const _currentFile = fileURLToPath(import.meta.url);
|
|
11
12
|
const _currentDir = dirname(_currentFile);
|
|
12
13
|
let db = null;
|
|
@@ -260,6 +261,25 @@ function runMigrations(database) {
|
|
|
260
261
|
if (!columnNames.has('source')) {
|
|
261
262
|
database.exec("ALTER TABLE memories ADD COLUMN source TEXT DEFAULT 'user:direct'");
|
|
262
263
|
}
|
|
264
|
+
if (!columnNames.has('uuid')) {
|
|
265
|
+
database.exec("ALTER TABLE memories ADD COLUMN uuid TEXT");
|
|
266
|
+
}
|
|
267
|
+
if (!columnNames.has('updated_at')) {
|
|
268
|
+
database.exec('ALTER TABLE memories ADD COLUMN updated_at TIMESTAMP');
|
|
269
|
+
}
|
|
270
|
+
try {
|
|
271
|
+
const rowsWithoutUuid = database.prepare('SELECT id FROM memories WHERE uuid IS NULL OR uuid = ?').all('');
|
|
272
|
+
const setUuid = database.prepare('UPDATE memories SET uuid = ? WHERE id = ?');
|
|
273
|
+
for (const row of rowsWithoutUuid) {
|
|
274
|
+
setUuid.run(randomUUID(), row.id);
|
|
275
|
+
}
|
|
276
|
+
database.exec('UPDATE memories SET updated_at = COALESCE(updated_at, created_at, CURRENT_TIMESTAMP) WHERE updated_at IS NULL');
|
|
277
|
+
database.exec('CREATE UNIQUE INDEX IF NOT EXISTS idx_memories_uuid ON memories(uuid)');
|
|
278
|
+
database.exec('CREATE INDEX IF NOT EXISTS idx_memories_updated ON memories(updated_at DESC)');
|
|
279
|
+
}
|
|
280
|
+
catch {
|
|
281
|
+
// Safe to ignore on partially migrated databases
|
|
282
|
+
}
|
|
263
283
|
// Migration: Defence tables (defence_audit, quarantine, fragmentation_entities)
|
|
264
284
|
try {
|
|
265
285
|
database.exec(`
|
|
@@ -673,6 +693,7 @@ function getInlineSchema() {
|
|
|
673
693
|
return `
|
|
674
694
|
CREATE TABLE IF NOT EXISTS memories (
|
|
675
695
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
696
|
+
uuid TEXT NOT NULL UNIQUE,
|
|
676
697
|
type TEXT NOT NULL CHECK(type IN ('short_term', 'long_term', 'episodic')),
|
|
677
698
|
category TEXT NOT NULL DEFAULT 'note',
|
|
678
699
|
title TEXT NOT NULL,
|
|
@@ -684,6 +705,7 @@ function getInlineSchema() {
|
|
|
684
705
|
access_count INTEGER DEFAULT 0,
|
|
685
706
|
last_accessed TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
686
707
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
708
|
+
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
687
709
|
metadata TEXT DEFAULT '{}',
|
|
688
710
|
embedding BLOB,
|
|
689
711
|
scope TEXT DEFAULT 'project',
|
|
@@ -721,11 +743,13 @@ function getInlineSchema() {
|
|
|
721
743
|
END;
|
|
722
744
|
|
|
723
745
|
CREATE INDEX IF NOT EXISTS idx_memories_type ON memories(type);
|
|
746
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_memories_uuid ON memories(uuid);
|
|
724
747
|
CREATE INDEX IF NOT EXISTS idx_memories_project ON memories(project);
|
|
725
748
|
CREATE INDEX IF NOT EXISTS idx_memories_category ON memories(category);
|
|
726
749
|
CREATE INDEX IF NOT EXISTS idx_memories_salience ON memories(salience DESC);
|
|
727
750
|
CREATE INDEX IF NOT EXISTS idx_memories_decayed_score ON memories(decayed_score DESC);
|
|
728
751
|
CREATE INDEX IF NOT EXISTS idx_memories_last_accessed ON memories(last_accessed DESC);
|
|
752
|
+
CREATE INDEX IF NOT EXISTS idx_memories_updated ON memories(updated_at DESC);
|
|
729
753
|
|
|
730
754
|
CREATE TABLE IF NOT EXISTS sessions (
|
|
731
755
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
package/dist/graph/backfill.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { getDatabase } from '../database/init.js';
|
|
2
2
|
import { extractFromMemory } from './extract.js';
|
|
3
|
-
import {
|
|
3
|
+
import { replaceMemoryGraph } from './resolve.js';
|
|
4
4
|
/** Bump this when extract.ts logic changes to force re-extraction */
|
|
5
|
-
const EXTRACTION_VERSION =
|
|
5
|
+
const EXTRACTION_VERSION = 3;
|
|
6
6
|
export function backfillGraph(options) {
|
|
7
7
|
const db = getDatabase();
|
|
8
8
|
const force = options?.force ?? false;
|
|
@@ -32,9 +32,7 @@ export function backfillGraph(options) {
|
|
|
32
32
|
for (const mem of memories) {
|
|
33
33
|
try {
|
|
34
34
|
const extraction = extractFromMemory(mem.title, mem.content, mem.category);
|
|
35
|
-
|
|
36
|
-
processExtractionResult(extraction, mem.id);
|
|
37
|
-
}
|
|
35
|
+
replaceMemoryGraph(mem.id, extraction);
|
|
38
36
|
// Mark this memory as extracted at the current version
|
|
39
37
|
if (updateVersion) {
|
|
40
38
|
updateVersion.run(EXTRACTION_VERSION, mem.id);
|
package/dist/graph/resolve.d.ts
CHANGED
|
@@ -2,4 +2,14 @@ import type { EntityType, ExtractionResult } from './extract.js';
|
|
|
2
2
|
export declare function levenshtein(a: string, b: string): number;
|
|
3
3
|
export declare function resolveEntity(name: string, type: EntityType): number;
|
|
4
4
|
export declare function mergeEntities(keepId: number, removeId: number): void;
|
|
5
|
+
export declare function removeMemoryGraph(memoryId: number): {
|
|
6
|
+
removedEntityLinks: number;
|
|
7
|
+
removedTriples: number;
|
|
8
|
+
orphanEntitiesPruned: number;
|
|
9
|
+
};
|
|
10
|
+
export declare function replaceMemoryGraph(memoryId: number, result: ExtractionResult): {
|
|
11
|
+
removedEntityLinks: number;
|
|
12
|
+
removedTriples: number;
|
|
13
|
+
orphanEntitiesPruned: number;
|
|
14
|
+
};
|
|
5
15
|
export declare function processExtractionResult(result: ExtractionResult, memoryId: number): void;
|
package/dist/graph/resolve.js
CHANGED
|
@@ -93,7 +93,7 @@ export function mergeEntities(keepId, removeId) {
|
|
|
93
93
|
db.prepare('DELETE FROM entities WHERE id = ?').run(removeId);
|
|
94
94
|
})();
|
|
95
95
|
}
|
|
96
|
-
|
|
96
|
+
function applyExtractionResult(result, memoryId) {
|
|
97
97
|
const db = getDatabase();
|
|
98
98
|
const nameToId = new Map();
|
|
99
99
|
// 1. Resolve all entities
|
|
@@ -123,3 +123,65 @@ export function processExtractionResult(result, memoryId) {
|
|
|
123
123
|
updateCount.run(id);
|
|
124
124
|
}
|
|
125
125
|
}
|
|
126
|
+
function pruneOrphanEntities(candidateIds) {
|
|
127
|
+
if (candidateIds.length === 0)
|
|
128
|
+
return 0;
|
|
129
|
+
const db = getDatabase();
|
|
130
|
+
const placeholders = candidateIds.map(() => '?').join(', ');
|
|
131
|
+
const orphanRows = db.prepare(`
|
|
132
|
+
SELECT e.id
|
|
133
|
+
FROM entities e
|
|
134
|
+
WHERE e.id IN (${placeholders})
|
|
135
|
+
AND NOT EXISTS (SELECT 1 FROM memory_entities me WHERE me.entity_id = e.id)
|
|
136
|
+
AND NOT EXISTS (SELECT 1 FROM triples t WHERE t.subject_id = e.id OR t.object_id = e.id)
|
|
137
|
+
`).all(...candidateIds);
|
|
138
|
+
if (orphanRows.length === 0)
|
|
139
|
+
return 0;
|
|
140
|
+
const orphanIds = orphanRows.map((row) => row.id);
|
|
141
|
+
const orphanPlaceholders = orphanIds.map(() => '?').join(', ');
|
|
142
|
+
db.prepare(`DELETE FROM entities WHERE id IN (${orphanPlaceholders})`).run(...orphanIds);
|
|
143
|
+
return orphanIds.length;
|
|
144
|
+
}
|
|
145
|
+
function clearMemoryGraphSlice(memoryId) {
|
|
146
|
+
const db = getDatabase();
|
|
147
|
+
const linkedEntityRows = db.prepare(`
|
|
148
|
+
SELECT DISTINCT entity_id
|
|
149
|
+
FROM memory_entities
|
|
150
|
+
WHERE memory_id = ?
|
|
151
|
+
`).all(memoryId);
|
|
152
|
+
const linkedEntityIds = linkedEntityRows.map((row) => row.entity_id);
|
|
153
|
+
const removedTriples = Number(db.prepare('DELETE FROM triples WHERE source_memory_id = ?').run(memoryId).changes ?? 0);
|
|
154
|
+
const removedEntityLinks = Number(db.prepare('DELETE FROM memory_entities WHERE memory_id = ?').run(memoryId).changes ?? 0);
|
|
155
|
+
if (linkedEntityIds.length > 0) {
|
|
156
|
+
const placeholders = linkedEntityIds.map(() => '?').join(', ');
|
|
157
|
+
db.prepare(`
|
|
158
|
+
UPDATE entities
|
|
159
|
+
SET memory_count = CASE WHEN memory_count > 0 THEN memory_count - 1 ELSE 0 END
|
|
160
|
+
WHERE id IN (${placeholders})
|
|
161
|
+
`).run(...linkedEntityIds);
|
|
162
|
+
}
|
|
163
|
+
const orphanEntitiesPruned = pruneOrphanEntities(linkedEntityIds);
|
|
164
|
+
return {
|
|
165
|
+
removedEntityLinks,
|
|
166
|
+
removedTriples,
|
|
167
|
+
orphanEntitiesPruned,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
export function removeMemoryGraph(memoryId) {
|
|
171
|
+
const db = getDatabase();
|
|
172
|
+
return db.transaction(() => clearMemoryGraphSlice(memoryId))();
|
|
173
|
+
}
|
|
174
|
+
export function replaceMemoryGraph(memoryId, result) {
|
|
175
|
+
const db = getDatabase();
|
|
176
|
+
return db.transaction(() => {
|
|
177
|
+
const cleared = clearMemoryGraphSlice(memoryId);
|
|
178
|
+
if (result.entities.length > 0) {
|
|
179
|
+
applyExtractionResult(result, memoryId);
|
|
180
|
+
}
|
|
181
|
+
return cleared;
|
|
182
|
+
})();
|
|
183
|
+
}
|
|
184
|
+
export function processExtractionResult(result, memoryId) {
|
|
185
|
+
const db = getDatabase();
|
|
186
|
+
db.transaction(() => applyExtractionResult(result, memoryId))();
|
|
187
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
* shieldcortex hook session-start # Run session-start hook (for settings.json)
|
|
26
26
|
* shieldcortex hook session-end # Run session-end hook (for settings.json)
|
|
27
27
|
* shieldcortex service install # Auto-start dashboard on login
|
|
28
|
+
* shieldcortex service repair # Rebuild auto-start service with current install path
|
|
28
29
|
* shieldcortex service uninstall # Remove auto-start
|
|
29
30
|
* shieldcortex service status # Check service status
|
|
30
31
|
* shieldcortex openclaw install # Install OpenClaw hook
|
|
@@ -32,6 +33,7 @@
|
|
|
32
33
|
* shieldcortex openclaw status # Check OpenClaw hook status
|
|
33
34
|
* shieldcortex config --openclaw-auto-memory true # Enable OpenClaw auto-memory extraction
|
|
34
35
|
* shieldcortex config --openclaw-auto-memory false # Disable OpenClaw auto-memory extraction
|
|
36
|
+
* shieldcortex cloud sync --full # Backfill local memories + graph to ShieldCortex Cloud
|
|
35
37
|
* shieldcortex copilot install # Configure MCP server for VS Code + Cursor
|
|
36
38
|
* shieldcortex copilot uninstall # Remove MCP server configuration
|
|
37
39
|
* shieldcortex copilot status # Check MCP server configuration
|
package/dist/index.js
CHANGED
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
* shieldcortex hook session-start # Run session-start hook (for settings.json)
|
|
26
26
|
* shieldcortex hook session-end # Run session-end hook (for settings.json)
|
|
27
27
|
* shieldcortex service install # Auto-start dashboard on login
|
|
28
|
+
* shieldcortex service repair # Rebuild auto-start service with current install path
|
|
28
29
|
* shieldcortex service uninstall # Remove auto-start
|
|
29
30
|
* shieldcortex service status # Check service status
|
|
30
31
|
* shieldcortex openclaw install # Install OpenClaw hook
|
|
@@ -32,6 +33,7 @@
|
|
|
32
33
|
* shieldcortex openclaw status # Check OpenClaw hook status
|
|
33
34
|
* shieldcortex config --openclaw-auto-memory true # Enable OpenClaw auto-memory extraction
|
|
34
35
|
* shieldcortex config --openclaw-auto-memory false # Disable OpenClaw auto-memory extraction
|
|
36
|
+
* shieldcortex cloud sync --full # Backfill local memories + graph to ShieldCortex Cloud
|
|
35
37
|
* shieldcortex copilot install # Configure MCP server for VS Code + Cursor
|
|
36
38
|
* shieldcortex copilot uninstall # Remove MCP server configuration
|
|
37
39
|
* shieldcortex copilot status # Check MCP server configuration
|
|
@@ -47,6 +49,7 @@
|
|
|
47
49
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
48
50
|
import { spawn } from 'child_process';
|
|
49
51
|
import { fileURLToPath } from 'url';
|
|
52
|
+
import http from 'http';
|
|
50
53
|
import path from 'path';
|
|
51
54
|
import fs from 'fs';
|
|
52
55
|
import { createServer } from './server.js';
|
|
@@ -295,6 +298,25 @@ function startDashboard() {
|
|
|
295
298
|
});
|
|
296
299
|
return dashboard;
|
|
297
300
|
}
|
|
301
|
+
function checkLocalHttp(url, expectedStatus = [200], timeoutMs = 1200) {
|
|
302
|
+
return new Promise((resolve) => {
|
|
303
|
+
const req = http.get(url, { timeout: timeoutMs }, (res) => {
|
|
304
|
+
res.resume();
|
|
305
|
+
resolve(Boolean(res.statusCode && expectedStatus.includes(res.statusCode)));
|
|
306
|
+
});
|
|
307
|
+
req.on('timeout', () => {
|
|
308
|
+
req.destroy();
|
|
309
|
+
resolve(false);
|
|
310
|
+
});
|
|
311
|
+
req.on('error', () => resolve(false));
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
async function isLocalApiRunning() {
|
|
315
|
+
return checkLocalHttp('http://127.0.0.1:3001/api/health');
|
|
316
|
+
}
|
|
317
|
+
async function isLocalDashboardRunning() {
|
|
318
|
+
return checkLocalHttp('http://127.0.0.1:3030', [200, 307, 308]);
|
|
319
|
+
}
|
|
298
320
|
/**
|
|
299
321
|
* Main entry point
|
|
300
322
|
*/
|
|
@@ -321,6 +343,7 @@ ${bold}COMMANDS${reset}
|
|
|
321
343
|
${cyan}doctor${reset} Diagnose installation issues
|
|
322
344
|
${cyan}quickstart${reset} [target] Detect the fastest setup path
|
|
323
345
|
${cyan}config${reset} [options] Configure cloud sync and settings
|
|
346
|
+
${cyan}cloud${reset} sync --full Backfill local memories + graph to ShieldCortex Cloud
|
|
324
347
|
${cyan}license${reset} <action> Manage licence key (activate, status, deactivate)
|
|
325
348
|
${cyan}iron-dome${reset} <action> Manage behaviour protection layer
|
|
326
349
|
${cyan}audit${reset} [options] Run a full security audit
|
|
@@ -343,6 +366,7 @@ ${bold}EXAMPLES${reset}
|
|
|
343
366
|
shieldcortex dashboard
|
|
344
367
|
shieldcortex license activate sc_pro_...
|
|
345
368
|
shieldcortex config --cloud-enable --cloud-api-key <key>
|
|
369
|
+
shieldcortex cloud sync --full
|
|
346
370
|
|
|
347
371
|
${bold}DOCS${reset}
|
|
348
372
|
https://shieldcortex.ai/docs
|
|
@@ -423,6 +447,12 @@ ${bold}DOCS${reset}
|
|
|
423
447
|
handleCloudConfig(process.argv.slice(3));
|
|
424
448
|
return;
|
|
425
449
|
}
|
|
450
|
+
// Handle "cloud" subcommand
|
|
451
|
+
if (process.argv[2] === 'cloud') {
|
|
452
|
+
const { handleCloudCommand } = await import('./cloud/cli.js');
|
|
453
|
+
await handleCloudCommand(process.argv.slice(3));
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
426
456
|
// Handle "status" subcommand
|
|
427
457
|
if (process.argv[2] === 'status') {
|
|
428
458
|
const { handleStatusCommand } = await import('./setup/status.js');
|
|
@@ -602,7 +632,7 @@ ${bold}DOCS${reset}
|
|
|
602
632
|
const knownCommands = new Set([
|
|
603
633
|
'doctor', 'quickstart', 'setup', 'install', 'migrate', 'uninstall', 'hook',
|
|
604
634
|
'openclaw', 'clawdbot', 'copilot', 'service', 'config', 'status',
|
|
605
|
-
'graph', 'license', 'licence', 'audit', 'iron-dome', 'scan',
|
|
635
|
+
'graph', 'license', 'licence', 'audit', 'iron-dome', 'scan', 'cloud',
|
|
606
636
|
'scan-skill', 'scan-skills', 'dashboard', 'api',
|
|
607
637
|
]);
|
|
608
638
|
const arg = process.argv[2];
|
|
@@ -615,14 +645,36 @@ ${bold}DOCS${reset}
|
|
|
615
645
|
let dashboardProcess = null;
|
|
616
646
|
if (mode === 'api') {
|
|
617
647
|
// API mode only - for dashboard visualization
|
|
648
|
+
if (await isLocalApiRunning()) {
|
|
649
|
+
console.log('ShieldCortex API is already running at http://localhost:3001');
|
|
650
|
+
return;
|
|
651
|
+
}
|
|
618
652
|
console.log('Starting ShieldCortex in API mode...');
|
|
619
653
|
startVisualizationServer(dbPath);
|
|
620
654
|
}
|
|
621
655
|
else if (mode === 'dashboard') {
|
|
622
656
|
// Dashboard mode - API + Next.js dashboard
|
|
623
657
|
console.log('Starting ShieldCortex with Dashboard...');
|
|
624
|
-
|
|
625
|
-
|
|
658
|
+
const apiRunning = await isLocalApiRunning();
|
|
659
|
+
const dashboardRunning = await isLocalDashboardRunning();
|
|
660
|
+
if (apiRunning && dashboardRunning) {
|
|
661
|
+
console.log('ShieldCortex dashboard is already running.');
|
|
662
|
+
console.log('Dashboard: http://localhost:3030');
|
|
663
|
+
console.log('API: http://localhost:3001');
|
|
664
|
+
return;
|
|
665
|
+
}
|
|
666
|
+
if (!apiRunning) {
|
|
667
|
+
startVisualizationServer(dbPath);
|
|
668
|
+
}
|
|
669
|
+
else {
|
|
670
|
+
console.log('Reusing existing local ShieldCortex API on http://localhost:3001');
|
|
671
|
+
}
|
|
672
|
+
if (!dashboardRunning) {
|
|
673
|
+
dashboardProcess = startDashboard();
|
|
674
|
+
}
|
|
675
|
+
else {
|
|
676
|
+
console.log('Dashboard UI is already running on http://localhost:3030');
|
|
677
|
+
}
|
|
626
678
|
// Kill dashboard child process on any exit (prevents orphans)
|
|
627
679
|
const killDashboard = () => {
|
|
628
680
|
if (dashboardProcess && !dashboardProcess.killed) {
|
|
@@ -648,7 +700,12 @@ ${bold}DOCS${reset}
|
|
|
648
700
|
else if (mode === 'both') {
|
|
649
701
|
// Both modes - API in background, MCP in foreground
|
|
650
702
|
console.log('Starting ShieldCortex in both modes...');
|
|
651
|
-
|
|
703
|
+
if (!(await isLocalApiRunning())) {
|
|
704
|
+
startVisualizationServer(dbPath);
|
|
705
|
+
}
|
|
706
|
+
else {
|
|
707
|
+
console.log('Reusing existing local ShieldCortex API on http://localhost:3001');
|
|
708
|
+
}
|
|
652
709
|
await startMcpServer(dbPath);
|
|
653
710
|
}
|
|
654
711
|
else {
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type Database from 'better-sqlite3';
|
|
2
|
+
import { Memory, MemoryCategory, MemoryConfig, SearchResult } from './types.js';
|
|
3
|
+
export interface SearchExecutionOptions {
|
|
4
|
+
enableSideEffects: boolean;
|
|
5
|
+
includeExplanation: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface SearchScoringContext {
|
|
8
|
+
db: Database.Database;
|
|
9
|
+
config: MemoryConfig;
|
|
10
|
+
detectedCategory: MemoryCategory | null;
|
|
11
|
+
queryTags: string[];
|
|
12
|
+
vectorResults: Map<number, number>;
|
|
13
|
+
query: string;
|
|
14
|
+
}
|
|
15
|
+
export interface SearchScoreValues {
|
|
16
|
+
ftsScore: number;
|
|
17
|
+
vectorSimilarity: number;
|
|
18
|
+
vectorBoost: number;
|
|
19
|
+
decayedScore: number;
|
|
20
|
+
priorityBoost: number;
|
|
21
|
+
recencyBoost: number;
|
|
22
|
+
categoryBoost: number;
|
|
23
|
+
linkBoost: number;
|
|
24
|
+
tagBoost: number;
|
|
25
|
+
activationBoost: number;
|
|
26
|
+
finalScore: number;
|
|
27
|
+
}
|
|
28
|
+
export type MemoryRowConverter = (row: Record<string, unknown>) => Memory;
|
|
29
|
+
export declare function detectQueryCategory(query: string): MemoryCategory | null;
|
|
30
|
+
export declare function calculateLinkBoost(memoryId: number, db: Database.Database): number;
|
|
31
|
+
export declare function calculateTagScore(queryTags: string[], memoryTags: string[]): number;
|
|
32
|
+
export declare function extractQueryTags(query: string): string[];
|
|
33
|
+
export declare function vectorSearch(db: Database.Database, rowToMemory: MemoryRowConverter, queryEmbedding: Float32Array, limit: number, project?: string, includeGlobal?: boolean): Array<{
|
|
34
|
+
memory: Memory;
|
|
35
|
+
similarity: number;
|
|
36
|
+
}>;
|
|
37
|
+
export declare function buildSearchExplanation(memory: Memory, context: SearchScoringContext, values: SearchScoreValues): SearchResult['explanation'];
|