@remnic/core 9.3.762 → 9.3.764
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/dist/access-admin-ops-surface.d.ts +2 -2
- package/dist/access-admin-ops-surface.js +5 -5
- package/dist/access-boundary.d.ts +2 -2
- package/dist/access-boundary.js +6 -6
- package/dist/access-cli.js +26 -26
- package/dist/access-http.d.ts +2 -2
- package/dist/access-http.js +10 -10
- package/dist/access-identity-continuity-surface.d.ts +1 -1
- package/dist/access-identity-continuity-surface.js +5 -5
- package/dist/access-lcm-surface.d.ts +2 -2
- package/dist/access-lcm-surface.js +5 -5
- package/dist/access-mcp.d.ts +2 -2
- package/dist/access-mcp.js +9 -9
- package/dist/access-observe-write-surface.d.ts +2 -2
- package/dist/access-observe-write-surface.js +5 -5
- package/dist/access-operations-batch.js +7 -7
- package/dist/access-operations.d.ts +2 -2
- package/dist/access-operations.js +8 -8
- package/dist/access-recall-surface.d.ts +2 -2
- package/dist/access-recall-surface.js +5 -5
- package/dist/{access-service-CaWJP_f6.d.ts → access-service-CAoJ4qN8.d.ts} +1 -1
- package/dist/access-service.d.ts +2 -2
- package/dist/access-service.js +5 -5
- package/dist/access-surface-catalog.d.ts +2 -2
- package/dist/bootstrap.d.ts +1 -1
- package/dist/briefing.js +3 -3
- package/dist/causal-consolidation.js +4 -4
- package/dist/{chunk-OQ6F3WBX.js → chunk-2RLECZ6J.js} +2 -2
- package/dist/{chunk-DB647OZ4.js → chunk-2V6CTSSA.js} +13 -13
- package/dist/{chunk-2KYXXMTE.js → chunk-422OELQ3.js} +4 -4
- package/dist/{chunk-DPZ5GJMD.js → chunk-5JF4DIKZ.js} +2 -2
- package/dist/{chunk-ZTBH2OHD.js → chunk-AS2NRB45.js} +2 -2
- package/dist/{chunk-JU6BKZHX.js → chunk-CGLRKKMF.js} +3 -3
- package/dist/{chunk-HDFS6RWQ.js → chunk-CVINPTKG.js} +2 -2
- package/dist/{chunk-P7W4CDX6.js → chunk-DTTVX6EO.js} +11 -3
- package/dist/chunk-DTTVX6EO.js.map +1 -0
- package/dist/{chunk-HDYFNXVO.js → chunk-IVFIYAIP.js} +2 -2
- package/dist/{chunk-QPFO54VC.js → chunk-KXG7HHIQ.js} +2 -2
- package/dist/{chunk-ESDBHQY6.js → chunk-N3QDLE2N.js} +5 -5
- package/dist/{chunk-4HYJETVO.js → chunk-N4ZA2I7M.js} +2 -2
- package/dist/{chunk-TEKTCF2V.js → chunk-NDXJJKT2.js} +2 -2
- package/dist/{chunk-2PGB63VU.js → chunk-NFWTMM2M.js} +2 -2
- package/dist/{chunk-PNFN7SIN.js → chunk-OX272PBW.js} +2 -2
- package/dist/{chunk-WAIMHMO3.js → chunk-P6ZZ4GX4.js} +3 -3
- package/dist/{chunk-HMUEAKSD.js → chunk-QPTP6SKC.js} +2 -2
- package/dist/{chunk-VHYFY3JI.js → chunk-R3K4CXPR.js} +2 -2
- package/dist/{chunk-EDC7RZCW.js → chunk-RIOJRLJ6.js} +25 -55
- package/dist/chunk-RIOJRLJ6.js.map +1 -0
- package/dist/{chunk-TIWRP5NW.js → chunk-RJCQPRLB.js} +4 -4
- package/dist/{chunk-IIURIWJG.js → chunk-SFNQDXXL.js} +9 -5
- package/dist/chunk-SFNQDXXL.js.map +1 -0
- package/dist/{chunk-MB5RSUW6.js → chunk-SXN3LCUT.js} +114 -28
- package/dist/chunk-SXN3LCUT.js.map +1 -0
- package/dist/{chunk-LAJIXABF.js → chunk-UQEE4H6Z.js} +12 -12
- package/dist/chunk-UQEE4H6Z.js.map +1 -0
- package/dist/{chunk-ES3GAMSQ.js → chunk-VKHZFF5P.js} +2 -2
- package/dist/{chunk-KZWUJC7Y.js → chunk-X7HTU4HO.js} +2 -2
- package/dist/{chunk-QWIE43BS.js → chunk-YDYC6PIS.js} +2 -2
- package/dist/{cli-CvWpIbMD.d.ts → cli-WRmxvfc_.d.ts} +2 -2
- package/dist/cli.d.ts +3 -3
- package/dist/cli.js +20 -20
- package/dist/compounding/engine.js +3 -3
- package/dist/connectors/codex-materialize-runner.js +3 -3
- package/dist/connectors/index.js +3 -3
- package/dist/entity-retrieval.js +3 -3
- package/dist/explicit-capture.d.ts +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +26 -26
- package/dist/maintenance/memory-governance.js +3 -3
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +3 -3
- package/dist/maintenance/rebuild-memory-projection.js +4 -4
- package/dist/mcp-memory-inspector-app.d.ts +2 -2
- package/dist/memory-projection-store.d.ts +6 -2
- package/dist/memory-projection-store.js +9 -3
- package/dist/namespaces/migrate.js +4 -4
- package/dist/namespaces/storage.js +3 -3
- package/dist/operator-toolkit.js +7 -7
- package/dist/orchestration/maintenance.js +5 -5
- package/dist/{orchestrator-C04Q4Zao.d.ts → orchestrator-Y9wyG4jK.d.ts} +102 -15
- package/dist/orchestrator.d.ts +1 -1
- package/dist/orchestrator.js +26 -26
- package/dist/{purge-6ATBGT77.js → purge-IHRX4Z7X.js} +7 -1
- package/dist/purge-IHRX4Z7X.js.map +1 -0
- package/dist/semantic-consolidation.js +4 -4
- package/dist/semantic-rule-promotion.js +3 -3
- package/dist/semantic-rule-verifier.js +3 -3
- package/dist/storage.js +2 -2
- package/dist/verified-recall.js +3 -3
- package/package.json +2 -2
- package/src/access-service.ts +7 -7
- package/src/maintenance/purge.test.ts +76 -0
- package/src/maintenance/purge.ts +3 -0
- package/src/maintenance/rebuild-memory-projection.ts +5 -1
- package/src/memory-projection-store.ts +143 -35
- package/src/orchestration/recall-introspection.ts +3 -12
- package/src/orchestrator.ts +9 -57
- package/src/storage.ts +8 -8
- package/dist/chunk-EDC7RZCW.js.map +0 -1
- package/dist/chunk-IIURIWJG.js.map +0 -1
- package/dist/chunk-LAJIXABF.js.map +0 -1
- package/dist/chunk-MB5RSUW6.js.map +0 -1
- package/dist/chunk-P7W4CDX6.js.map +0 -1
- package/dist/purge-6ATBGT77.js.map +0 -1
- /package/dist/{chunk-OQ6F3WBX.js.map → chunk-2RLECZ6J.js.map} +0 -0
- /package/dist/{chunk-DB647OZ4.js.map → chunk-2V6CTSSA.js.map} +0 -0
- /package/dist/{chunk-2KYXXMTE.js.map → chunk-422OELQ3.js.map} +0 -0
- /package/dist/{chunk-DPZ5GJMD.js.map → chunk-5JF4DIKZ.js.map} +0 -0
- /package/dist/{chunk-ZTBH2OHD.js.map → chunk-AS2NRB45.js.map} +0 -0
- /package/dist/{chunk-JU6BKZHX.js.map → chunk-CGLRKKMF.js.map} +0 -0
- /package/dist/{chunk-HDFS6RWQ.js.map → chunk-CVINPTKG.js.map} +0 -0
- /package/dist/{chunk-HDYFNXVO.js.map → chunk-IVFIYAIP.js.map} +0 -0
- /package/dist/{chunk-QPFO54VC.js.map → chunk-KXG7HHIQ.js.map} +0 -0
- /package/dist/{chunk-ESDBHQY6.js.map → chunk-N3QDLE2N.js.map} +0 -0
- /package/dist/{chunk-4HYJETVO.js.map → chunk-N4ZA2I7M.js.map} +0 -0
- /package/dist/{chunk-TEKTCF2V.js.map → chunk-NDXJJKT2.js.map} +0 -0
- /package/dist/{chunk-2PGB63VU.js.map → chunk-NFWTMM2M.js.map} +0 -0
- /package/dist/{chunk-PNFN7SIN.js.map → chunk-OX272PBW.js.map} +0 -0
- /package/dist/{chunk-WAIMHMO3.js.map → chunk-P6ZZ4GX4.js.map} +0 -0
- /package/dist/{chunk-HMUEAKSD.js.map → chunk-QPTP6SKC.js.map} +0 -0
- /package/dist/{chunk-VHYFY3JI.js.map → chunk-R3K4CXPR.js.map} +0 -0
- /package/dist/{chunk-TIWRP5NW.js.map → chunk-RJCQPRLB.js.map} +0 -0
- /package/dist/{chunk-ES3GAMSQ.js.map → chunk-VKHZFF5P.js.map} +0 -0
- /package/dist/{chunk-KZWUJC7Y.js.map → chunk-X7HTU4HO.js.map} +0 -0
- /package/dist/{chunk-QWIE43BS.js.map → chunk-YDYC6PIS.js.map} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remnic/core",
|
|
3
|
-
"version": "9.3.
|
|
3
|
+
"version": "9.3.764",
|
|
4
4
|
"description": "Framework-agnostic Remnic memory engine — orchestrator, storage, extraction, search, trust zones",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -3000,7 +3000,7 @@
|
|
|
3000
3000
|
"core"
|
|
3001
3001
|
],
|
|
3002
3002
|
"peerDependencies": {
|
|
3003
|
-
"@remnic/coding-graph": "^9.3.
|
|
3003
|
+
"@remnic/coding-graph": "^9.3.764"
|
|
3004
3004
|
},
|
|
3005
3005
|
"peerDependenciesMeta": {
|
|
3006
3006
|
"@remnic/coding-graph": {
|
package/src/access-service.ts
CHANGED
|
@@ -2121,8 +2121,8 @@ export class EngramAccessService {
|
|
|
2121
2121
|
if (!includeDebug) return undefined;
|
|
2122
2122
|
if (!sessionKey?.trim()) return undefined;
|
|
2123
2123
|
const [intent, graph] = await Promise.all([
|
|
2124
|
-
this.orchestrator.getLastIntentSnapshot(namespace),
|
|
2125
|
-
this.orchestrator.getLastGraphRecallSnapshot(namespace),
|
|
2124
|
+
this.orchestrator.recallIntrospection.getLastIntentSnapshot(namespace),
|
|
2125
|
+
this.orchestrator.recallIntrospection.getLastGraphRecallSnapshot(namespace),
|
|
2126
2126
|
]);
|
|
2127
2127
|
return snapshot || intent || graph
|
|
2128
2128
|
? {
|
|
@@ -2831,8 +2831,8 @@ export class EngramAccessService {
|
|
|
2831
2831
|
})();
|
|
2832
2832
|
if (!namespace) return { found: false };
|
|
2833
2833
|
const [intent, graph] = await Promise.all([
|
|
2834
|
-
this.orchestrator.getLastIntentSnapshot(namespace),
|
|
2835
|
-
this.orchestrator.getLastGraphRecallSnapshot(namespace),
|
|
2834
|
+
this.orchestrator.recallIntrospection.getLastIntentSnapshot(namespace),
|
|
2835
|
+
this.orchestrator.recallIntrospection.getLastGraphRecallSnapshot(namespace),
|
|
2836
2836
|
]);
|
|
2837
2837
|
if (!readableSnapshot && !intent && !graph) return { found: false };
|
|
2838
2838
|
return { found: true, snapshot: readableSnapshot ?? undefined, intent, graph };
|
|
@@ -4817,17 +4817,17 @@ export class EngramAccessService {
|
|
|
4817
4817
|
}
|
|
4818
4818
|
|
|
4819
4819
|
async intentDebug(namespace?: string): Promise<unknown> {
|
|
4820
|
-
const snapshot = await this.orchestrator.getLastIntentSnapshot(namespace);
|
|
4820
|
+
const snapshot = await this.orchestrator.recallIntrospection.getLastIntentSnapshot(namespace);
|
|
4821
4821
|
return snapshot ?? { message: "No intent debug snapshot available" };
|
|
4822
4822
|
}
|
|
4823
4823
|
|
|
4824
4824
|
async qmdDebug(namespace?: string): Promise<unknown> {
|
|
4825
|
-
const snapshot = await this.orchestrator.getLastQmdRecallSnapshot(namespace);
|
|
4825
|
+
const snapshot = await this.orchestrator.recallIntrospection.getLastQmdRecallSnapshot(namespace);
|
|
4826
4826
|
return snapshot ?? { message: "No QMD debug snapshot available" };
|
|
4827
4827
|
}
|
|
4828
4828
|
|
|
4829
4829
|
async graphExplainLastRecall(namespace?: string): Promise<unknown> {
|
|
4830
|
-
const explanation = await this.orchestrator.explainLastGraphRecall({ namespace });
|
|
4830
|
+
const explanation = await this.orchestrator.recallIntrospection.explainLastGraphRecall({ namespace });
|
|
4831
4831
|
return { explanation };
|
|
4832
4832
|
}
|
|
4833
4833
|
|
|
@@ -5,6 +5,9 @@ import path from "node:path";
|
|
|
5
5
|
import test from "node:test";
|
|
6
6
|
|
|
7
7
|
import { purgeMemories } from "./purge.js";
|
|
8
|
+
import { rebuildMemoryProjection } from "./rebuild-memory-projection.js";
|
|
9
|
+
import { readProjectedMemoryBrowse } from "../memory-projection-store.js";
|
|
10
|
+
import { StorageManager } from "../storage.js";
|
|
8
11
|
import type { MemoryFile } from "../types.js";
|
|
9
12
|
|
|
10
13
|
test("purgeMemories records audit errors without blocking hard delete", async () => {
|
|
@@ -54,6 +57,79 @@ test("purgeMemories records audit errors without blocking hard delete", async ()
|
|
|
54
57
|
}
|
|
55
58
|
});
|
|
56
59
|
|
|
60
|
+
test("purgeMemories invalidates projection rows for hard-deleted memories", async () => {
|
|
61
|
+
const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-purge-projection-"));
|
|
62
|
+
try {
|
|
63
|
+
const storage = new StorageManager(dir);
|
|
64
|
+
const { id } = await storage.writeMemory("fact", "purge projection target", {
|
|
65
|
+
source: "test",
|
|
66
|
+
});
|
|
67
|
+
const memory = await storage.getMemoryById(id);
|
|
68
|
+
assert.ok(memory);
|
|
69
|
+
await rebuildMemoryProjection({ memoryDir: dir, dryRun: false });
|
|
70
|
+
assert.equal(readProjectedMemoryBrowse(dir, { limit: 5, offset: 0 })?.total, 1);
|
|
71
|
+
|
|
72
|
+
const result = await purgeMemories({
|
|
73
|
+
storage,
|
|
74
|
+
olderThanMs: 1,
|
|
75
|
+
tier: "all",
|
|
76
|
+
dryRun: false,
|
|
77
|
+
now: () => new Date(Date.now() + 86_400_000),
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
assert.equal(result.purgedCount, 1);
|
|
81
|
+
assert.equal(readProjectedMemoryBrowse(dir, { limit: 5, offset: 0 })?.total, 0);
|
|
82
|
+
} finally {
|
|
83
|
+
await rm(dir, { recursive: true, force: true });
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
test("purgeMemories invalidates projection rows for already-absent files but not failed deletes, and dry-run never mutates", async () => {
|
|
88
|
+
const dir = await mkdtemp(path.join(os.tmpdir(), "remnic-purge-projection-branches-"));
|
|
89
|
+
try {
|
|
90
|
+
// Real projection with two rows; candidates come from a mock storage so the
|
|
91
|
+
// unlink outcomes are deterministic: one path is already absent (ENOENT),
|
|
92
|
+
// the other is a non-empty directory (unlink fails, not ENOENT).
|
|
93
|
+
const realStorage = new StorageManager(dir);
|
|
94
|
+
const first = await realStorage.writeMemory("fact", "purge branch enoent", { source: "test" });
|
|
95
|
+
const second = await realStorage.writeMemory("fact", "purge branch failure", { source: "test" });
|
|
96
|
+
await rebuildMemoryProjection({ memoryDir: dir, dryRun: false });
|
|
97
|
+
assert.equal(readProjectedMemoryBrowse(dir, { limit: 5, offset: 0 })?.total, 2);
|
|
98
|
+
|
|
99
|
+
const firstMemory = await realStorage.getMemoryById(first.id);
|
|
100
|
+
const secondMemory = await realStorage.getMemoryById(second.id);
|
|
101
|
+
assert.ok(firstMemory && secondMemory);
|
|
102
|
+
await rm(firstMemory.path);
|
|
103
|
+
await rm(secondMemory.path);
|
|
104
|
+
await mkdir(secondMemory.path);
|
|
105
|
+
await writeFile(path.join(secondMemory.path, "block.txt"), "x", "utf8");
|
|
106
|
+
|
|
107
|
+
const mockStorage = {
|
|
108
|
+
dir,
|
|
109
|
+
readAllMemories: async () => [firstMemory, secondMemory],
|
|
110
|
+
readAllColdMemories: async () => [],
|
|
111
|
+
readArchivedMemories: async () => [],
|
|
112
|
+
};
|
|
113
|
+
const future = () => new Date(Date.now() + 86_400_000);
|
|
114
|
+
|
|
115
|
+
// Dry-run: no projection mutation.
|
|
116
|
+
await purgeMemories({ storage: mockStorage as never, olderThanMs: 1, tier: "all", dryRun: true, now: future });
|
|
117
|
+
assert.equal(readProjectedMemoryBrowse(dir, { limit: 5, offset: 0 })?.total, 2);
|
|
118
|
+
|
|
119
|
+
const result = await purgeMemories({ storage: mockStorage as never, olderThanMs: 1, tier: "all", dryRun: false, now: future });
|
|
120
|
+
|
|
121
|
+
assert.equal(result.alreadyAbsentCount, 1);
|
|
122
|
+
assert.equal(result.purgedCount, 0);
|
|
123
|
+
assert.equal(result.errors.filter((e) => e.id === second.id).length, 1);
|
|
124
|
+
const page = readProjectedMemoryBrowse(dir, { limit: 5, offset: 0 });
|
|
125
|
+
assert.ok(page);
|
|
126
|
+
// ENOENT row invalidated; failed-delete row keeps its projection entry.
|
|
127
|
+
assert.equal(page.total, 1);
|
|
128
|
+
} finally {
|
|
129
|
+
await rm(dir, { recursive: true, force: true });
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
|
|
57
133
|
async function fileExists(filePath: string): Promise<boolean> {
|
|
58
134
|
try {
|
|
59
135
|
await access(filePath);
|
package/src/maintenance/purge.ts
CHANGED
|
@@ -23,6 +23,7 @@ import path from "node:path";
|
|
|
23
23
|
import { appendFile, mkdir, unlink } from "node:fs/promises";
|
|
24
24
|
import type { StorageManager } from "../storage.js";
|
|
25
25
|
import type { MemoryFile } from "../types.js";
|
|
26
|
+
import { markProjectedMemoryPathInvalid } from "../memory-projection-store.js";
|
|
26
27
|
import type { SearchBackend } from "../search/port.js";
|
|
27
28
|
|
|
28
29
|
export type PurgeTierFilter = "cold" | "all";
|
|
@@ -236,12 +237,14 @@ export async function purgeMemories(
|
|
|
236
237
|
await unlink(candidate.path);
|
|
237
238
|
actuallyPurged.push(candidate);
|
|
238
239
|
addCollectionForCandidate(candidate);
|
|
240
|
+
markProjectedMemoryPathInvalid(storage.dir, candidate.id);
|
|
239
241
|
} catch (err) {
|
|
240
242
|
const message = err instanceof Error ? err.message : String(err);
|
|
241
243
|
// ENOENT is fine — already gone
|
|
242
244
|
if (hasErrorCode(err, "ENOENT")) {
|
|
243
245
|
alreadyAbsent.push(candidate);
|
|
244
246
|
addCollectionForCandidate(candidate);
|
|
247
|
+
markProjectedMemoryPathInvalid(storage.dir, candidate.id);
|
|
245
248
|
} else {
|
|
246
249
|
errors.push({ id: candidate.id, path: candidate.path, error: message });
|
|
247
250
|
}
|
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
import {
|
|
25
25
|
getMemoryProjectionPath,
|
|
26
26
|
initializeMemoryProjectionDb,
|
|
27
|
+
isProjectedMemoryPathValid,
|
|
27
28
|
type ProjectedEntityMentionRow,
|
|
28
29
|
type MemoryProjectionGovernanceAppliedActionRow,
|
|
29
30
|
type MemoryProjectionGovernanceReviewQueueRow,
|
|
@@ -794,6 +795,7 @@ function writeProjectionDb(
|
|
|
794
795
|
usedLifecycleLedger: boolean,
|
|
795
796
|
): void {
|
|
796
797
|
const db = openBetterSqlite3(dbPath);
|
|
798
|
+
const memoryDir = path.dirname(path.dirname(dbPath));
|
|
797
799
|
try {
|
|
798
800
|
initializeMemoryProjectionDb(db);
|
|
799
801
|
|
|
@@ -810,6 +812,7 @@ function writeProjectionDb(
|
|
|
810
812
|
status,
|
|
811
813
|
lifecycle_state,
|
|
812
814
|
path_rel,
|
|
815
|
+
path_valid,
|
|
813
816
|
created_at,
|
|
814
817
|
updated_at,
|
|
815
818
|
archived_at,
|
|
@@ -823,7 +826,7 @@ function writeProjectionDb(
|
|
|
823
826
|
last_accessed,
|
|
824
827
|
tags_json,
|
|
825
828
|
preview_text
|
|
826
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
829
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
827
830
|
`);
|
|
828
831
|
|
|
829
832
|
const insertTimeline = db.prepare(`
|
|
@@ -921,6 +924,7 @@ function writeProjectionDb(
|
|
|
921
924
|
row.status,
|
|
922
925
|
row.lifecycleState ?? null,
|
|
923
926
|
row.pathRel,
|
|
927
|
+
isProjectedMemoryPathValid(memoryDir, row.pathRel) ? 1 : 0,
|
|
924
928
|
row.created,
|
|
925
929
|
row.updated,
|
|
926
930
|
row.archivedAt ?? null,
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
type BetterSqlite3Database,
|
|
18
18
|
} from "./runtime/better-sqlite.js";
|
|
19
19
|
|
|
20
|
-
export const MEMORY_PROJECTION_SCHEMA_VERSION =
|
|
20
|
+
export const MEMORY_PROJECTION_SCHEMA_VERSION = 3;
|
|
21
21
|
|
|
22
22
|
export interface ProjectedMemoryBrowseOptions {
|
|
23
23
|
query?: string;
|
|
@@ -153,11 +153,13 @@ function migrateProjectionSchemaIfNeeded(memoryDir: string): void {
|
|
|
153
153
|
export function memoryCurrentSelectExpressions(db: BetterSqlite3Database): {
|
|
154
154
|
tagsJson: string;
|
|
155
155
|
previewText: string;
|
|
156
|
+
hasPathValid: boolean;
|
|
156
157
|
} {
|
|
157
158
|
const columns = listTableColumns(db, "memory_current");
|
|
158
159
|
return {
|
|
159
160
|
tagsJson: columns.has("tags_json") ? "tags_json" : `'[]' AS tags_json`,
|
|
160
161
|
previewText: columns.has("preview_text") ? "preview_text" : `'' AS preview_text`,
|
|
162
|
+
hasPathValid: columns.has("path_valid"),
|
|
161
163
|
};
|
|
162
164
|
}
|
|
163
165
|
|
|
@@ -174,6 +176,7 @@ export function initializeMemoryProjectionDb(db: BetterSqlite3Database): void {
|
|
|
174
176
|
status TEXT NOT NULL,
|
|
175
177
|
lifecycle_state TEXT,
|
|
176
178
|
path_rel TEXT NOT NULL,
|
|
179
|
+
path_valid INTEGER NOT NULL DEFAULT 0 CHECK (path_valid IN (0, 1)),
|
|
177
180
|
created_at TEXT NOT NULL,
|
|
178
181
|
updated_at TEXT NOT NULL,
|
|
179
182
|
archived_at TEXT,
|
|
@@ -195,8 +198,6 @@ export function initializeMemoryProjectionDb(db: BetterSqlite3Database): void {
|
|
|
195
198
|
CREATE INDEX IF NOT EXISTS idx_memory_current_category
|
|
196
199
|
ON memory_current(category);
|
|
197
200
|
|
|
198
|
-
CREATE INDEX IF NOT EXISTS idx_memory_current_updated
|
|
199
|
-
ON memory_current(updated_at DESC);
|
|
200
201
|
|
|
201
202
|
CREATE TABLE IF NOT EXISTS memory_timeline (
|
|
202
203
|
event_id TEXT PRIMARY KEY,
|
|
@@ -297,6 +298,18 @@ export function initializeMemoryProjectionDb(db: BetterSqlite3Database): void {
|
|
|
297
298
|
`);
|
|
298
299
|
|
|
299
300
|
migrateMemoryCurrentTable(db);
|
|
301
|
+
if (listTableColumns(db, "memory_current").has("path_valid")) {
|
|
302
|
+
db.exec(`
|
|
303
|
+
CREATE INDEX IF NOT EXISTS idx_memory_current_browse_updated_desc
|
|
304
|
+
ON memory_current(path_valid, updated_at DESC, created_at DESC, memory_id ASC);
|
|
305
|
+
CREATE INDEX IF NOT EXISTS idx_memory_current_browse_updated_asc
|
|
306
|
+
ON memory_current(path_valid, updated_at ASC, created_at ASC, memory_id ASC);
|
|
307
|
+
CREATE INDEX IF NOT EXISTS idx_memory_current_browse_created_desc
|
|
308
|
+
ON memory_current(path_valid, created_at DESC, updated_at DESC, memory_id ASC);
|
|
309
|
+
CREATE INDEX IF NOT EXISTS idx_memory_current_browse_created_asc
|
|
310
|
+
ON memory_current(path_valid, created_at ASC, updated_at ASC, memory_id ASC);
|
|
311
|
+
`);
|
|
312
|
+
}
|
|
300
313
|
db.prepare("INSERT OR REPLACE INTO meta(key, value) VALUES (?, ?)")
|
|
301
314
|
.run("schemaVersion", String(MEMORY_PROJECTION_SCHEMA_VERSION));
|
|
302
315
|
}
|
|
@@ -309,6 +322,42 @@ function openProjectionReadonly(memoryDir: string): BetterSqlite3Database | null
|
|
|
309
322
|
return null;
|
|
310
323
|
}
|
|
311
324
|
}
|
|
325
|
+
function updateProjectionBestEffort(
|
|
326
|
+
memoryDir: string,
|
|
327
|
+
sql: string,
|
|
328
|
+
params: unknown[],
|
|
329
|
+
): void {
|
|
330
|
+
let db: BetterSqlite3Database | null = null;
|
|
331
|
+
try {
|
|
332
|
+
db = openBetterSqlite3(getMemoryProjectionPath(memoryDir), { fileMustExist: true });
|
|
333
|
+
db.prepare(sql).run(...params);
|
|
334
|
+
} catch {
|
|
335
|
+
// Projection updates must never block the canonical filesystem mutation.
|
|
336
|
+
} finally {
|
|
337
|
+
db?.close();
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
export function markProjectedMemoryPathInvalid(memoryDir: string, memoryId: string): void {
|
|
342
|
+
updateProjectionBestEffort(
|
|
343
|
+
memoryDir,
|
|
344
|
+
"UPDATE memory_current SET path_valid = 0 WHERE memory_id = ?",
|
|
345
|
+
[memoryId],
|
|
346
|
+
);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
export function updateProjectedMemoryPath(
|
|
350
|
+
memoryDir: string,
|
|
351
|
+
memoryId: string,
|
|
352
|
+
pathRel: string,
|
|
353
|
+
): void {
|
|
354
|
+
const pathValid = isProjectedMemoryPathValid(memoryDir, pathRel) ? 1 : 0;
|
|
355
|
+
updateProjectionBestEffort(
|
|
356
|
+
memoryDir,
|
|
357
|
+
"UPDATE memory_current SET path_rel = ?, path_valid = ? WHERE memory_id = ?",
|
|
358
|
+
[pathRel, pathValid, memoryId],
|
|
359
|
+
);
|
|
360
|
+
}
|
|
312
361
|
|
|
313
362
|
function withProjectionReadonly<T>(
|
|
314
363
|
memoryDir: string,
|
|
@@ -363,7 +412,11 @@ function isPathInsideRoot(candidatePath: string, rootPath: string): boolean {
|
|
|
363
412
|
return relative === "" || (!relative.startsWith("..") && !path.isAbsolute(relative));
|
|
364
413
|
}
|
|
365
414
|
|
|
366
|
-
function resolveProjectedMemoryPath(
|
|
415
|
+
function resolveProjectedMemoryPath(
|
|
416
|
+
memoryDir: string,
|
|
417
|
+
pathRel: string,
|
|
418
|
+
requireExisting = false,
|
|
419
|
+
): string | null {
|
|
367
420
|
if (path.isAbsolute(pathRel)) return null;
|
|
368
421
|
const root = resolveMemoryDirRoot(memoryDir);
|
|
369
422
|
const candidate = path.resolve(root, pathRel);
|
|
@@ -372,14 +425,21 @@ function resolveProjectedMemoryPath(memoryDir: string, pathRel: string): string
|
|
|
372
425
|
const realCandidate = fs.realpathSync(candidate);
|
|
373
426
|
if (!isPathInsideRoot(realCandidate, root)) return null;
|
|
374
427
|
} catch {
|
|
428
|
+
if (requireExisting) return null;
|
|
375
429
|
// Missing files are handled by callers. Still keep the lexical guard above.
|
|
376
430
|
}
|
|
377
431
|
return candidate;
|
|
378
432
|
}
|
|
379
433
|
|
|
434
|
+
export function isProjectedMemoryPathValid(memoryDir: string, pathRel: string): boolean {
|
|
435
|
+
return resolveProjectedMemoryPath(memoryDir, pathRel) !== null;
|
|
436
|
+
}
|
|
437
|
+
|
|
380
438
|
function projectedBrowseRowFromCurrentRow(
|
|
381
439
|
memoryDir: string,
|
|
382
440
|
row: Record<string, unknown>,
|
|
441
|
+
resolvedFilePath?: string,
|
|
442
|
+
requireExisting = false,
|
|
383
443
|
): ProjectedMemoryBrowseRow | null {
|
|
384
444
|
if (
|
|
385
445
|
typeof row.memory_id !== "string" ||
|
|
@@ -389,7 +449,7 @@ function projectedBrowseRowFromCurrentRow(
|
|
|
389
449
|
) {
|
|
390
450
|
return null;
|
|
391
451
|
}
|
|
392
|
-
const filePath = resolveProjectedMemoryPath(memoryDir, row.path_rel);
|
|
452
|
+
const filePath = resolvedFilePath ?? resolveProjectedMemoryPath(memoryDir, row.path_rel, requireExisting);
|
|
393
453
|
if (!filePath) return null;
|
|
394
454
|
return {
|
|
395
455
|
id: row.memory_id,
|
|
@@ -613,8 +673,15 @@ export function readProjectedMemoryBrowse(
|
|
|
613
673
|
const whereSql = whereClauses.length > 0 ? `WHERE ${whereClauses.join(" AND ")}` : "";
|
|
614
674
|
|
|
615
675
|
if (normalizedQuery) {
|
|
616
|
-
//
|
|
617
|
-
|
|
676
|
+
// Full-content search still examines every eligible row so totals and
|
|
677
|
+
// matches stay exact, but iteration keeps memory use proportional to the page.
|
|
678
|
+
const queryWhereClauses = currentSelect.hasPathValid
|
|
679
|
+
? [...whereClauses, ...projectedBrowsePathSqlClauses(), "path_valid = 1"]
|
|
680
|
+
: whereClauses;
|
|
681
|
+
const queryWhereSql = queryWhereClauses.length > 0
|
|
682
|
+
? `WHERE ${queryWhereClauses.join(" AND ")}`
|
|
683
|
+
: "";
|
|
684
|
+
const rows = db
|
|
618
685
|
.prepare(`
|
|
619
686
|
SELECT
|
|
620
687
|
memory_id,
|
|
@@ -627,47 +694,88 @@ export function readProjectedMemoryBrowse(
|
|
|
627
694
|
${currentSelect.tagsJson},
|
|
628
695
|
${currentSelect.previewText}
|
|
629
696
|
FROM memory_current
|
|
630
|
-
${
|
|
697
|
+
${queryWhereSql}
|
|
631
698
|
ORDER BY ${orderBySql}
|
|
632
699
|
`)
|
|
633
|
-
.
|
|
700
|
+
.iterate(...params) as Iterable<Record<string, unknown>>;
|
|
701
|
+
const pageRows: ProjectedMemoryBrowseRow[] = [];
|
|
702
|
+
let total = 0;
|
|
634
703
|
|
|
635
|
-
const
|
|
636
|
-
if (typeof row.memory_id !== "string" || typeof row.path_rel !== "string")
|
|
637
|
-
const filePath = resolveProjectedMemoryPath(
|
|
638
|
-
|
|
639
|
-
|
|
704
|
+
for (const row of rows) {
|
|
705
|
+
if (typeof row.memory_id !== "string" || typeof row.path_rel !== "string") continue;
|
|
706
|
+
const filePath = resolveProjectedMemoryPath(
|
|
707
|
+
memoryDir,
|
|
708
|
+
row.path_rel,
|
|
709
|
+
currentSelect.hasPathValid,
|
|
710
|
+
);
|
|
711
|
+
if (!filePath) continue;
|
|
640
712
|
const preview = typeof row.preview_text === "string" ? row.preview_text.toLowerCase() : "";
|
|
641
713
|
const category = typeof row.category === "string" ? row.category.toLowerCase() : "";
|
|
642
714
|
const entityRef = typeof row.entity_ref === "string" ? row.entity_ref.toLowerCase() : "";
|
|
643
715
|
const tags = typeof row.tags_json === "string" ? row.tags_json.toLowerCase() : "";
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
716
|
+
let matches = preview.includes(normalizedQuery) || category.includes(normalizedQuery) ||
|
|
717
|
+
entityRef.includes(normalizedQuery) || tags.includes(normalizedQuery);
|
|
718
|
+
if (!matches) {
|
|
719
|
+
try {
|
|
720
|
+
matches = fs.readFileSync(filePath, "utf-8").toLowerCase().includes(normalizedQuery);
|
|
721
|
+
} catch {
|
|
722
|
+
matches = false;
|
|
723
|
+
}
|
|
647
724
|
}
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
const
|
|
651
|
-
|
|
652
|
-
} catch {
|
|
653
|
-
return false;
|
|
725
|
+
if (!matches) continue;
|
|
726
|
+
if (total >= options.offset && pageRows.length < options.limit) {
|
|
727
|
+
const browseRow = projectedBrowseRowFromCurrentRow(memoryDir, row, filePath);
|
|
728
|
+
if (browseRow) pageRows.push(browseRow);
|
|
654
729
|
}
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
return {
|
|
659
|
-
total: filtered.length,
|
|
660
|
-
memories: pageRows
|
|
661
|
-
.map((row) => projectedBrowseRowFromCurrentRow(memoryDir, row))
|
|
662
|
-
.filter((row): row is ProjectedMemoryBrowseRow => row !== null),
|
|
663
|
-
};
|
|
730
|
+
total += 1;
|
|
731
|
+
}
|
|
732
|
+
|
|
733
|
+
return { total, memories: pageRows };
|
|
664
734
|
}
|
|
665
735
|
|
|
666
|
-
// No query: push lexical path safety into SQL, then count through the same
|
|
667
|
-
// realpath-aware row parser used for returned rows so symlink escapes do not
|
|
668
|
-
// inflate totals.
|
|
669
736
|
const browseWhereClauses = [...whereClauses, ...projectedBrowsePathSqlClauses()];
|
|
737
|
+
if (currentSelect.hasPathValid) {
|
|
738
|
+
browseWhereClauses.push("path_valid = 1");
|
|
739
|
+
}
|
|
670
740
|
const browseWhereSql = `WHERE ${browseWhereClauses.join(" AND ")}`;
|
|
741
|
+
|
|
742
|
+
if (currentSelect.hasPathValid) {
|
|
743
|
+
const rows = db
|
|
744
|
+
.prepare(`
|
|
745
|
+
SELECT
|
|
746
|
+
memory_id,
|
|
747
|
+
path_rel,
|
|
748
|
+
category,
|
|
749
|
+
status,
|
|
750
|
+
created_at,
|
|
751
|
+
updated_at,
|
|
752
|
+
entity_ref,
|
|
753
|
+
${currentSelect.tagsJson},
|
|
754
|
+
${currentSelect.previewText}
|
|
755
|
+
FROM memory_current
|
|
756
|
+
${browseWhereSql}
|
|
757
|
+
ORDER BY ${orderBySql}
|
|
758
|
+
`)
|
|
759
|
+
.iterate(...params) as Iterable<Record<string, unknown>>;
|
|
760
|
+
const pageRows: ProjectedMemoryBrowseRow[] = [];
|
|
761
|
+
let validRowsSeen = 0;
|
|
762
|
+
for (const row of rows) {
|
|
763
|
+
const browseRow = projectedBrowseRowFromCurrentRow(memoryDir, row, undefined, true);
|
|
764
|
+
if (!browseRow) continue;
|
|
765
|
+
if (validRowsSeen >= options.offset) {
|
|
766
|
+
pageRows.push(browseRow);
|
|
767
|
+
if (pageRows.length >= options.limit) break;
|
|
768
|
+
}
|
|
769
|
+
validRowsSeen += 1;
|
|
770
|
+
}
|
|
771
|
+
const totalRow = db
|
|
772
|
+
.prepare(`SELECT COUNT(*) AS total FROM memory_current ${browseWhereSql}`)
|
|
773
|
+
.get(...params) as { total: number };
|
|
774
|
+
return { total: totalRow.total, memories: pageRows };
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
// Legacy projections have no materialized path validity. Preserve the
|
|
778
|
+
// realpath-aware full scan rather than trusting rows from an older writer.
|
|
671
779
|
const pageRows: ProjectedMemoryBrowseRow[] = [];
|
|
672
780
|
const fetchSize = Math.max(options.limit * 2, 50);
|
|
673
781
|
let validRowsSeen = 0;
|
|
@@ -54,15 +54,6 @@ export interface RecallIntrospectionDeps {
|
|
|
54
54
|
effectiveCronRecallInstructionHeavyTokenCap(): number;
|
|
55
55
|
readonly faithfulnessCounters: FaithfulnessGateCounters;
|
|
56
56
|
getCodingContextForSession(sessionKey: string | undefined): CodingContext | null;
|
|
57
|
-
getLastGraphRecallSnapshot(
|
|
58
|
-
namespace?: string,
|
|
59
|
-
): Promise<GraphRecallSnapshot | null>;
|
|
60
|
-
getLastIntentSnapshot(
|
|
61
|
-
namespace?: string,
|
|
62
|
-
): Promise<IntentDebugSnapshot | null>;
|
|
63
|
-
getLastQmdRecallSnapshot(
|
|
64
|
-
namespace?: string,
|
|
65
|
-
): Promise<QmdRecallSnapshot | null>;
|
|
66
57
|
getStorage(namespace?: string): Promise<StorageManager>;
|
|
67
58
|
readonly graphRecallCoordinator: GraphRecallCoordinator;
|
|
68
59
|
readonly lastRecall: LastRecallStore;
|
|
@@ -299,7 +290,7 @@ export class RecallIntrospectionCoordinator {
|
|
|
299
290
|
namespace?: string;
|
|
300
291
|
maxExpanded?: number;
|
|
301
292
|
}): Promise<string> {
|
|
302
|
-
const snapshot = await this.
|
|
293
|
+
const snapshot = await this.getLastGraphRecallSnapshot(options?.namespace);
|
|
303
294
|
if (!snapshot) return "No graph-recall snapshot found yet.";
|
|
304
295
|
const maxExpanded = Math.max(1, Math.min(50, options?.maxExpanded ?? 10));
|
|
305
296
|
const expanded = snapshot.expanded.slice(0, maxExpanded);
|
|
@@ -353,7 +344,7 @@ export class RecallIntrospectionCoordinator {
|
|
|
353
344
|
}
|
|
354
345
|
|
|
355
346
|
async explainLastIntent(options?: { namespace?: string }): Promise<string> {
|
|
356
|
-
const snapshot = await this.
|
|
347
|
+
const snapshot = await this.getLastIntentSnapshot(options?.namespace);
|
|
357
348
|
if (!snapshot) return "No intent-debug snapshot found yet.";
|
|
358
349
|
return [
|
|
359
350
|
"## Last Intent Debug",
|
|
@@ -375,7 +366,7 @@ export class RecallIntrospectionCoordinator {
|
|
|
375
366
|
namespace?: string;
|
|
376
367
|
maxResults?: number;
|
|
377
368
|
}): Promise<string> {
|
|
378
|
-
const snapshot = await this.
|
|
369
|
+
const snapshot = await this.getLastQmdRecallSnapshot(options?.namespace);
|
|
379
370
|
if (!snapshot) return "No QMD recall snapshot found yet.";
|
|
380
371
|
const maxResults = Math.max(1, Math.min(25, options?.maxResults ?? 10));
|
|
381
372
|
const shown = snapshot.results.slice(0, maxResults);
|
package/src/orchestrator.ts
CHANGED
|
@@ -611,7 +611,7 @@ export class Orchestrator {
|
|
|
611
611
|
}
|
|
612
612
|
|
|
613
613
|
getConsoleFaithfulnessDistribution(): FaithfulnessGateCounters | undefined {
|
|
614
|
-
return this.
|
|
614
|
+
return this.recallIntrospection.getConsoleFaithfulnessDistribution(
|
|
615
615
|
);
|
|
616
616
|
}
|
|
617
617
|
readonly modelRegistry: ModelRegistry;
|
|
@@ -2158,54 +2158,6 @@ export class Orchestrator {
|
|
|
2158
2158
|
}
|
|
2159
2159
|
}
|
|
2160
2160
|
|
|
2161
|
-
async getLastGraphRecallSnapshot(
|
|
2162
|
-
namespace?: string,
|
|
2163
|
-
): Promise<GraphRecallSnapshot | null> {
|
|
2164
|
-
return this.recallIntrospectionCoordinator.getLastGraphRecallSnapshot(
|
|
2165
|
-
namespace,
|
|
2166
|
-
);
|
|
2167
|
-
}
|
|
2168
|
-
|
|
2169
|
-
async getLastIntentSnapshot(
|
|
2170
|
-
namespace?: string,
|
|
2171
|
-
): Promise<IntentDebugSnapshot | null> {
|
|
2172
|
-
return this.recallIntrospectionCoordinator.getLastIntentSnapshot(
|
|
2173
|
-
namespace,
|
|
2174
|
-
);
|
|
2175
|
-
}
|
|
2176
|
-
|
|
2177
|
-
async getLastQmdRecallSnapshot(
|
|
2178
|
-
namespace?: string,
|
|
2179
|
-
): Promise<QmdRecallSnapshot | null> {
|
|
2180
|
-
return this.recallIntrospectionCoordinator.getLastQmdRecallSnapshot(
|
|
2181
|
-
namespace,
|
|
2182
|
-
);
|
|
2183
|
-
}
|
|
2184
|
-
|
|
2185
|
-
async explainLastGraphRecall(options?: {
|
|
2186
|
-
namespace?: string;
|
|
2187
|
-
maxExpanded?: number;
|
|
2188
|
-
}): Promise<string> {
|
|
2189
|
-
return this.recallIntrospectionCoordinator.explainLastGraphRecall(
|
|
2190
|
-
options,
|
|
2191
|
-
);
|
|
2192
|
-
}
|
|
2193
|
-
|
|
2194
|
-
async explainLastIntent(options?: { namespace?: string }): Promise<string> {
|
|
2195
|
-
return this.recallIntrospectionCoordinator.explainLastIntent(
|
|
2196
|
-
options,
|
|
2197
|
-
);
|
|
2198
|
-
}
|
|
2199
|
-
|
|
2200
|
-
async explainLastQmdRecall(options?: {
|
|
2201
|
-
namespace?: string;
|
|
2202
|
-
maxResults?: number;
|
|
2203
|
-
}): Promise<string> {
|
|
2204
|
-
return this.recallIntrospectionCoordinator.explainLastQmdRecall(
|
|
2205
|
-
options,
|
|
2206
|
-
);
|
|
2207
|
-
}
|
|
2208
|
-
|
|
2209
2161
|
private async searchConversationRecallResults(
|
|
2210
2162
|
retrievalQuery: string,
|
|
2211
2163
|
topK: number,
|
|
@@ -2341,7 +2293,7 @@ export class Orchestrator {
|
|
|
2341
2293
|
async waitForDirectAnswerObservationIdle(
|
|
2342
2294
|
timeoutMs: number = 60_000,
|
|
2343
2295
|
): Promise<boolean> {
|
|
2344
|
-
return this.
|
|
2296
|
+
return this.recallIntrospection.waitForDirectAnswerObservationIdle(
|
|
2345
2297
|
timeoutMs,
|
|
2346
2298
|
);
|
|
2347
2299
|
}
|
|
@@ -2354,7 +2306,7 @@ export class Orchestrator {
|
|
|
2354
2306
|
caps: CapabilitySet,
|
|
2355
2307
|
namespacesEnabled: boolean,
|
|
2356
2308
|
): void {
|
|
2357
|
-
return this.
|
|
2309
|
+
return this.recallIntrospection.enqueueDirectAnswerObservation(
|
|
2358
2310
|
prompt,
|
|
2359
2311
|
sessionKey,
|
|
2360
2312
|
namespaceOverride,
|
|
@@ -2374,7 +2326,7 @@ export class Orchestrator {
|
|
|
2374
2326
|
caps: CapabilitySet,
|
|
2375
2327
|
_parentAbortSignal?: AbortSignal,
|
|
2376
2328
|
): Promise<void> {
|
|
2377
|
-
return this.
|
|
2329
|
+
return this.recallIntrospection.annotateDirectAnswerTier(
|
|
2378
2330
|
prompt,
|
|
2379
2331
|
sessionKey,
|
|
2380
2332
|
namespaces,
|
|
@@ -2540,7 +2492,7 @@ export class Orchestrator {
|
|
|
2540
2492
|
finalResults?: GraphRecallRankedResult[];
|
|
2541
2493
|
shadowComparison?: GraphRecallShadowComparison;
|
|
2542
2494
|
}): Promise<void> {
|
|
2543
|
-
return this.
|
|
2495
|
+
return this.recallIntrospection.recordLastGraphRecallSnapshot(
|
|
2544
2496
|
options,
|
|
2545
2497
|
);
|
|
2546
2498
|
}
|
|
@@ -2548,7 +2500,7 @@ export class Orchestrator {
|
|
|
2548
2500
|
storage: StorageManager;
|
|
2549
2501
|
snapshot: IntentDebugSnapshot;
|
|
2550
2502
|
}): Promise<void> {
|
|
2551
|
-
return this.
|
|
2503
|
+
return this.recallIntrospection.recordLastIntentSnapshot(
|
|
2552
2504
|
options,
|
|
2553
2505
|
);
|
|
2554
2506
|
}
|
|
@@ -2557,7 +2509,7 @@ export class Orchestrator {
|
|
|
2557
2509
|
storage: StorageManager;
|
|
2558
2510
|
snapshot: QmdRecallSnapshot;
|
|
2559
2511
|
}): Promise<void> {
|
|
2560
|
-
return this.
|
|
2512
|
+
return this.recallIntrospection.recordLastQmdRecallSnapshot(
|
|
2561
2513
|
options,
|
|
2562
2514
|
);
|
|
2563
2515
|
}
|
|
@@ -2566,7 +2518,7 @@ export class Orchestrator {
|
|
|
2566
2518
|
namespace: string;
|
|
2567
2519
|
snapshot: IntentDebugSnapshot;
|
|
2568
2520
|
}): Promise<void> {
|
|
2569
|
-
return this.
|
|
2521
|
+
return this.recallIntrospection.recordLastIntentSnapshotForNamespace(
|
|
2570
2522
|
options,
|
|
2571
2523
|
);
|
|
2572
2524
|
}
|
|
@@ -2746,7 +2698,7 @@ export class Orchestrator {
|
|
|
2746
2698
|
*/
|
|
2747
2699
|
private _recallIntrospectionCoordinator: RecallIntrospectionCoordinator | undefined;
|
|
2748
2700
|
|
|
2749
|
-
|
|
2701
|
+
get recallIntrospection(): RecallIntrospectionCoordinator {
|
|
2750
2702
|
if (!this._recallIntrospectionCoordinator) {
|
|
2751
2703
|
this._recallIntrospectionCoordinator = new RecallIntrospectionCoordinator(
|
|
2752
2704
|
selfDeps<ConstructorParameters<typeof RecallIntrospectionCoordinator>[0]>(this),
|