@iworkforces/tracelattice 2.1.1 → 2.2.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 +20 -3
- package/dist/contracts/PersistenceBackend.d.ts +10 -1
- package/dist/contracts/PersistenceBackend.d.ts.map +1 -1
- package/dist/contracts/calibrator.d.ts +9 -6
- package/dist/contracts/calibrator.d.ts.map +1 -1
- package/dist/contracts/interfaces.d.ts +6 -0
- package/dist/contracts/interfaces.d.ts.map +1 -1
- package/dist/contracts/persistence-work.d.ts +13 -1
- package/dist/contracts/persistence-work.d.ts.map +1 -1
- package/dist/contracts/strategy.d.ts +14 -9
- package/dist/contracts/strategy.d.ts.map +1 -1
- package/dist/core/DurableThoughtIdentityIndex.d.ts +35 -0
- package/dist/core/DurableThoughtIdentityIndex.d.ts.map +1 -0
- package/dist/core/DurableThoughtIdentityIndex.js +94 -0
- package/dist/core/DurableThoughtIdentityIndex.js.map +1 -0
- package/dist/core/HistoryManager.d.ts +5 -0
- package/dist/core/HistoryManager.d.ts.map +1 -1
- package/dist/core/HistoryManager.js +37 -4
- package/dist/core/HistoryManager.js.map +1 -1
- package/dist/core/IHistoryManager.d.ts +2 -0
- package/dist/core/IHistoryManager.d.ts.map +1 -1
- package/dist/core/PersistenceBuffer.d.ts +7 -1
- package/dist/core/PersistenceBuffer.d.ts.map +1 -1
- package/dist/core/PersistenceBuffer.js +13 -1
- package/dist/core/PersistenceBuffer.js.map +1 -1
- package/dist/core/PersistenceRestore.d.ts.map +1 -1
- package/dist/core/PersistenceRestore.js +11 -3
- package/dist/core/PersistenceRestore.js.map +1 -1
- package/dist/core/PersistenceWorkQueue.d.ts +13 -1
- package/dist/core/PersistenceWorkQueue.d.ts.map +1 -1
- package/dist/core/PersistenceWorkQueue.js +86 -11
- package/dist/core/PersistenceWorkQueue.js.map +1 -1
- package/dist/core/PersistenceWriter.d.ts.map +1 -1
- package/dist/core/PersistenceWriter.js +3 -0
- package/dist/core/PersistenceWriter.js.map +1 -1
- package/dist/core/ThoughtEvaluator.d.ts +7 -4
- package/dist/core/ThoughtEvaluator.d.ts.map +1 -1
- package/dist/core/ThoughtEvaluator.js +15 -7
- package/dist/core/ThoughtEvaluator.js.map +1 -1
- package/dist/core/ThoughtProcessor.d.ts.map +1 -1
- package/dist/core/ThoughtProcessor.js +19 -7
- package/dist/core/ThoughtProcessor.js.map +1 -1
- package/dist/core/ThoughtReferenceIndex.d.ts +4 -0
- package/dist/core/ThoughtReferenceIndex.d.ts.map +1 -1
- package/dist/core/ThoughtReferenceIndex.js +28 -1
- package/dist/core/ThoughtReferenceIndex.js.map +1 -1
- package/dist/core/VerificationOutcomeAdmission.d.ts +8 -1
- package/dist/core/VerificationOutcomeAdmission.d.ts.map +1 -1
- package/dist/core/VerificationOutcomeAdmission.js.map +1 -1
- package/dist/core/VerificationTargetRestore.d.ts +5 -0
- package/dist/core/VerificationTargetRestore.d.ts.map +1 -0
- package/dist/core/VerificationTargetRestore.js +61 -0
- package/dist/core/VerificationTargetRestore.js.map +1 -0
- package/dist/core/evaluator/Aggregator.d.ts +2 -1
- package/dist/core/evaluator/Aggregator.d.ts.map +1 -1
- package/dist/core/evaluator/Aggregator.js +4 -12
- package/dist/core/evaluator/Aggregator.js.map +1 -1
- package/dist/core/evaluator/Calibrator.d.ts +13 -9
- package/dist/core/evaluator/Calibrator.d.ts.map +1 -1
- package/dist/core/evaluator/Calibrator.js +25 -11
- package/dist/core/evaluator/Calibrator.js.map +1 -1
- package/dist/core/evaluator/PatternDetector.d.ts +2 -1
- package/dist/core/evaluator/PatternDetector.d.ts.map +1 -1
- package/dist/core/evaluator/PatternDetector.js +13 -12
- package/dist/core/evaluator/PatternDetector.js.map +1 -1
- package/dist/core/evaluator/SignalComputer.d.ts +3 -2
- package/dist/core/evaluator/SignalComputer.d.ts.map +1 -1
- package/dist/core/evaluator/SignalComputer.js +4 -9
- package/dist/core/evaluator/SignalComputer.js.map +1 -1
- package/dist/core/evaluator/VerificationLinks.d.ts +19 -0
- package/dist/core/evaluator/VerificationLinks.d.ts.map +1 -0
- package/dist/core/evaluator/VerificationLinks.js +113 -0
- package/dist/core/evaluator/VerificationLinks.js.map +1 -0
- package/dist/core/evaluator/calibration-math.d.ts +12 -2
- package/dist/core/evaluator/calibration-math.d.ts.map +1 -1
- package/dist/core/evaluator/calibration-math.js +11 -2
- package/dist/core/evaluator/calibration-math.js.map +1 -1
- package/dist/core/graph/EdgeEmitter.d.ts.map +1 -1
- package/dist/core/graph/EdgeEmitter.js +2 -1
- package/dist/core/graph/EdgeEmitter.js.map +1 -1
- package/dist/core/graph/GraphView.d.ts +5 -5
- package/dist/core/graph/GraphView.d.ts.map +1 -1
- package/dist/core/graph/GraphView.js +11 -11
- package/dist/core/graph/GraphView.js.map +1 -1
- package/dist/core/reasoning/ActiveEvidenceProjection.d.ts +20 -0
- package/dist/core/reasoning/ActiveEvidenceProjection.d.ts.map +1 -0
- package/dist/core/reasoning/ActiveEvidenceProjection.js +100 -0
- package/dist/core/reasoning/ActiveEvidenceProjection.js.map +1 -0
- package/dist/core/reasoning/strategies/TreeOfThoughtStrategy.d.ts +5 -4
- package/dist/core/reasoning/strategies/TreeOfThoughtStrategy.d.ts.map +1 -1
- package/dist/core/reasoning/strategies/TreeOfThoughtStrategy.js +24 -14
- package/dist/core/reasoning/strategies/TreeOfThoughtStrategy.js.map +1 -1
- package/dist/lib.d.ts.map +1 -1
- package/dist/lib.js +3 -1
- package/dist/lib.js.map +1 -1
- package/dist/persistence/BacktrackPersistence.d.ts +13 -0
- package/dist/persistence/BacktrackPersistence.d.ts.map +1 -0
- package/dist/persistence/BacktrackPersistence.js +90 -0
- package/dist/persistence/BacktrackPersistence.js.map +1 -0
- package/dist/persistence/FilePersistence.d.ts +2 -1
- package/dist/persistence/FilePersistence.d.ts.map +1 -1
- package/dist/persistence/FilePersistence.js +28 -0
- package/dist/persistence/FilePersistence.js.map +1 -1
- package/dist/persistence/FileSnapshotV2.d.ts +2 -0
- package/dist/persistence/FileSnapshotV2.d.ts.map +1 -1
- package/dist/persistence/FileSnapshotV2.js +6 -2
- package/dist/persistence/FileSnapshotV2.js.map +1 -1
- package/dist/persistence/MemoryPersistence.d.ts +2 -1
- package/dist/persistence/MemoryPersistence.d.ts.map +1 -1
- package/dist/persistence/MemoryPersistence.js +21 -1
- package/dist/persistence/MemoryPersistence.js.map +1 -1
- package/dist/persistence/PersistenceCodec.d.ts.map +1 -1
- package/dist/persistence/PersistenceCodec.js +5 -0
- package/dist/persistence/PersistenceCodec.js.map +1 -1
- package/dist/persistence/PersistenceErrors.d.ts +1 -1
- package/dist/persistence/PersistenceErrors.d.ts.map +1 -1
- package/dist/persistence/PersistenceErrors.js.map +1 -1
- package/dist/persistence/PersistenceScope.d.ts +1 -1
- package/dist/persistence/PersistenceScope.d.ts.map +1 -1
- package/dist/persistence/PersistenceScope.js.map +1 -1
- package/dist/persistence/SqlitePersistence.d.ts +2 -1
- package/dist/persistence/SqlitePersistence.d.ts.map +1 -1
- package/dist/persistence/SqlitePersistence.js +18 -0
- package/dist/persistence/SqlitePersistence.js.map +1 -1
- package/dist/registry/BaseRegistry.d.ts +10 -2
- package/dist/registry/BaseRegistry.d.ts.map +1 -1
- package/dist/registry/BaseRegistry.js +128 -81
- package/dist/registry/BaseRegistry.js.map +1 -1
- package/package.json +4 -3
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { isDeepStrictEqual } from "node:util";
|
|
2
|
+
import { PersistenceCompatibilityError } from "../errors.js";
|
|
3
|
+
import { assertBranchScope, assertPersistableThoughtCollections, assertThoughtScope } from "./PersistenceScope.js";
|
|
4
|
+
function cloneThoughts(thoughts) {
|
|
5
|
+
return [
|
|
6
|
+
...structuredClone(thoughts)
|
|
7
|
+
];
|
|
8
|
+
}
|
|
9
|
+
function collections(sessionId, history, branches) {
|
|
10
|
+
return [
|
|
11
|
+
{
|
|
12
|
+
sessionId,
|
|
13
|
+
thoughts: history
|
|
14
|
+
},
|
|
15
|
+
...branches.map((branch)=>({
|
|
16
|
+
sessionId,
|
|
17
|
+
thoughts: branch.thoughts
|
|
18
|
+
}))
|
|
19
|
+
];
|
|
20
|
+
}
|
|
21
|
+
function retractCopies(thoughts, targetThoughtId) {
|
|
22
|
+
return thoughts.map((thought)=>thought.id === targetThoughtId ? {
|
|
23
|
+
...thought,
|
|
24
|
+
retracted: true
|
|
25
|
+
} : thought);
|
|
26
|
+
}
|
|
27
|
+
function stageBacktrackPersistence(sessionId, history, branches, thought, targetThoughtId, maxHistorySize) {
|
|
28
|
+
assertThoughtScope('saveBacktrackForSession', sessionId, thought);
|
|
29
|
+
if ('backtrack' !== thought.thought_type) throw new PersistenceCompatibilityError(`${sessionId}/thoughts`, 'saveBacktrackForSession requires a backtrack thought');
|
|
30
|
+
if (0 === targetThoughtId.length) throw new PersistenceCompatibilityError(`${sessionId}/thoughts`, 'backtrack target thought id must not be empty');
|
|
31
|
+
const stagedHistory = cloneThoughts(history);
|
|
32
|
+
const stagedBranches = branches.map((branch)=>({
|
|
33
|
+
branchId: branch.branchId,
|
|
34
|
+
thoughts: cloneThoughts(branch.thoughts)
|
|
35
|
+
}));
|
|
36
|
+
assertPersistableThoughtCollections(collections(sessionId, stagedHistory, stagedBranches), `${sessionId}/backtrack`);
|
|
37
|
+
const correctedHistory = [
|
|
38
|
+
...retractCopies(stagedHistory, targetThoughtId),
|
|
39
|
+
structuredClone(thought)
|
|
40
|
+
];
|
|
41
|
+
const retainedHistory = maxHistorySize > 0 ? correctedHistory.slice(-maxHistorySize) : correctedHistory;
|
|
42
|
+
const correctedBranches = stagedBranches.map((branch)=>({
|
|
43
|
+
branchId: branch.branchId,
|
|
44
|
+
thoughts: retractCopies(branch.thoughts, targetThoughtId)
|
|
45
|
+
}));
|
|
46
|
+
for (const branch of correctedBranches)assertBranchScope('saveBranchForSession', sessionId, branch.branchId, branch.thoughts);
|
|
47
|
+
assertPersistableThoughtCollections(collections(sessionId, retainedHistory, correctedBranches), `${sessionId}/backtrack`);
|
|
48
|
+
return {
|
|
49
|
+
history: retainedHistory,
|
|
50
|
+
branches: correctedBranches
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function repairRetainedBacktracks(sessionId, history, branches) {
|
|
54
|
+
let repairedHistory = cloneThoughts(history);
|
|
55
|
+
let repairedBranches = branches.map((branch)=>({
|
|
56
|
+
branchId: branch.branchId,
|
|
57
|
+
thoughts: cloneThoughts(branch.thoughts)
|
|
58
|
+
}));
|
|
59
|
+
const allThoughts = ()=>[
|
|
60
|
+
...repairedHistory,
|
|
61
|
+
...repairedBranches.flatMap((branch)=>branch.thoughts)
|
|
62
|
+
];
|
|
63
|
+
const backtracks = new Map();
|
|
64
|
+
for (const thought of allThoughts())if (void 0 !== thought.id && 'backtrack' === thought.thought_type) {
|
|
65
|
+
const existing = backtracks.get(thought.id);
|
|
66
|
+
if (void 0 === existing || isDeepStrictEqual(existing, thought)) backtracks.set(thought.id, thought);
|
|
67
|
+
}
|
|
68
|
+
for (const backtrack of backtracks.values()){
|
|
69
|
+
if (void 0 === backtrack.backtrack_target) continue;
|
|
70
|
+
const targetIds = new Set();
|
|
71
|
+
for (const candidate of allThoughts())if (void 0 !== candidate.id && candidate.id !== backtrack.id && candidate.thought_number === backtrack.backtrack_target) targetIds.add(candidate.id);
|
|
72
|
+
if (0 === targetIds.size) continue;
|
|
73
|
+
if (targetIds.size > 1) throw new PersistenceCompatibilityError(`restore:${sessionId}`, `ambiguous retained backtrack target ${backtrack.backtrack_target}`);
|
|
74
|
+
const targetThoughtId = targetIds.values().next().value;
|
|
75
|
+
if (void 0 !== targetThoughtId) {
|
|
76
|
+
repairedHistory = retractCopies(repairedHistory, targetThoughtId);
|
|
77
|
+
repairedBranches = repairedBranches.map((branch)=>({
|
|
78
|
+
branchId: branch.branchId,
|
|
79
|
+
thoughts: retractCopies(branch.thoughts, targetThoughtId)
|
|
80
|
+
}));
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
return {
|
|
84
|
+
history: repairedHistory,
|
|
85
|
+
branches: repairedBranches
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
export { repairRetainedBacktracks, stageBacktrackPersistence };
|
|
89
|
+
|
|
90
|
+
//# sourceMappingURL=BacktrackPersistence.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persistence/BacktrackPersistence.js","sources":["../../src/persistence/BacktrackPersistence.ts"],"sourcesContent":["import { isDeepStrictEqual } from 'node:util';\nimport type { BranchId, SessionId, ThoughtId } from '../contracts/ids.js';\nimport type { ThoughtData } from '../core/thought.js';\nimport { PersistenceCompatibilityError } from '../errors.js';\nimport {\n\tassertBranchScope,\n\tassertPersistableThoughtCollections,\n\tassertThoughtScope,\n\ttype PersistedThoughtCollection,\n} from './PersistenceScope.js';\n\nexport type PersistedBranchSnapshot = {\n\treadonly branchId: BranchId;\n\treadonly thoughts: readonly ThoughtData[];\n};\n\nexport type StagedThoughtState = {\n\treadonly history: readonly ThoughtData[];\n\treadonly branches: readonly PersistedBranchSnapshot[];\n};\n\nfunction cloneThoughts(thoughts: readonly ThoughtData[]): ThoughtData[] {\n\treturn [...structuredClone(thoughts)];\n}\n\nfunction collections(\n\tsessionId: SessionId,\n\thistory: readonly ThoughtData[],\n\tbranches: readonly PersistedBranchSnapshot[]\n): PersistedThoughtCollection[] {\n\treturn [\n\t\t{ sessionId, thoughts: history },\n\t\t...branches.map((branch) => ({ sessionId, thoughts: branch.thoughts })),\n\t];\n}\n\nfunction retractCopies(\n\tthoughts: readonly ThoughtData[],\n\ttargetThoughtId: ThoughtId\n): ThoughtData[] {\n\treturn thoughts.map((thought) =>\n\t\tthought.id === targetThoughtId ? { ...thought, retracted: true } : thought\n\t);\n}\n\nexport function stageBacktrackPersistence(\n\tsessionId: SessionId,\n\thistory: readonly ThoughtData[],\n\tbranches: readonly PersistedBranchSnapshot[],\n\tthought: ThoughtData,\n\ttargetThoughtId: ThoughtId,\n\tmaxHistorySize: number\n): StagedThoughtState {\n\tassertThoughtScope('saveBacktrackForSession', sessionId, thought);\n\tif (thought.thought_type !== 'backtrack') {\n\t\tthrow new PersistenceCompatibilityError(\n\t\t\t`${sessionId}/thoughts`,\n\t\t\t'saveBacktrackForSession requires a backtrack thought'\n\t\t);\n\t}\n\tif (targetThoughtId.length === 0) {\n\t\tthrow new PersistenceCompatibilityError(\n\t\t\t`${sessionId}/thoughts`,\n\t\t\t'backtrack target thought id must not be empty'\n\t\t);\n\t}\n\n\tconst stagedHistory = cloneThoughts(history);\n\tconst stagedBranches = branches.map((branch) => ({\n\t\tbranchId: branch.branchId,\n\t\tthoughts: cloneThoughts(branch.thoughts),\n\t}));\n\tassertPersistableThoughtCollections(\n\t\tcollections(sessionId, stagedHistory, stagedBranches),\n\t\t`${sessionId}/backtrack`\n\t);\n\n\tconst correctedHistory = [\n\t\t...retractCopies(stagedHistory, targetThoughtId),\n\t\tstructuredClone(thought),\n\t];\n\tconst retainedHistory =\n\t\tmaxHistorySize > 0 ? correctedHistory.slice(-maxHistorySize) : correctedHistory;\n\tconst correctedBranches = stagedBranches.map((branch) => ({\n\t\tbranchId: branch.branchId,\n\t\tthoughts: retractCopies(branch.thoughts, targetThoughtId),\n\t}));\n\tfor (const branch of correctedBranches) {\n\t\tassertBranchScope('saveBranchForSession', sessionId, branch.branchId, branch.thoughts);\n\t}\n\tassertPersistableThoughtCollections(\n\t\tcollections(sessionId, retainedHistory, correctedBranches),\n\t\t`${sessionId}/backtrack`\n\t);\n\treturn { history: retainedHistory, branches: correctedBranches };\n}\n\nexport function repairRetainedBacktracks(\n\tsessionId: SessionId,\n\thistory: readonly ThoughtData[],\n\tbranches: readonly PersistedBranchSnapshot[]\n): StagedThoughtState {\n\tlet repairedHistory = cloneThoughts(history);\n\tlet repairedBranches = branches.map((branch) => ({\n\t\tbranchId: branch.branchId,\n\t\tthoughts: cloneThoughts(branch.thoughts),\n\t}));\n\tconst allThoughts = (): readonly ThoughtData[] => [\n\t\t...repairedHistory,\n\t\t...repairedBranches.flatMap((branch) => branch.thoughts),\n\t];\n\tconst backtracks = new Map<string, ThoughtData>();\n\tfor (const thought of allThoughts()) {\n\t\tif (thought.id !== undefined && thought.thought_type === 'backtrack') {\n\t\t\tconst existing = backtracks.get(thought.id);\n\t\t\tif (existing === undefined || isDeepStrictEqual(existing, thought)) {\n\t\t\t\tbacktracks.set(thought.id, thought);\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (const backtrack of backtracks.values()) {\n\t\tif (backtrack.backtrack_target === undefined) continue;\n\t\tconst targetIds = new Set<ThoughtId>();\n\t\tfor (const candidate of allThoughts()) {\n\t\t\tif (\n\t\t\t\tcandidate.id !== undefined &&\n\t\t\t\tcandidate.id !== backtrack.id &&\n\t\t\t\tcandidate.thought_number === backtrack.backtrack_target\n\t\t\t) {\n\t\t\t\ttargetIds.add(candidate.id);\n\t\t\t}\n\t\t}\n\t\tif (targetIds.size === 0) continue;\n\t\tif (targetIds.size > 1) {\n\t\t\tthrow new PersistenceCompatibilityError(\n\t\t\t\t`restore:${sessionId}`,\n\t\t\t\t`ambiguous retained backtrack target ${backtrack.backtrack_target}`\n\t\t\t);\n\t\t}\n\t\tconst targetThoughtId = targetIds.values().next().value;\n\t\tif (targetThoughtId === undefined) continue;\n\t\trepairedHistory = retractCopies(repairedHistory, targetThoughtId);\n\t\trepairedBranches = repairedBranches.map((branch) => ({\n\t\t\tbranchId: branch.branchId,\n\t\t\tthoughts: retractCopies(branch.thoughts, targetThoughtId),\n\t\t}));\n\t}\n\n\treturn { history: repairedHistory, branches: repairedBranches };\n}\n"],"names":["cloneThoughts","thoughts","structuredClone","collections","sessionId","history","branches","branch","retractCopies","targetThoughtId","thought","stageBacktrackPersistence","maxHistorySize","assertThoughtScope","PersistenceCompatibilityError","stagedHistory","stagedBranches","assertPersistableThoughtCollections","correctedHistory","retainedHistory","correctedBranches","assertBranchScope","repairRetainedBacktracks","repairedHistory","repairedBranches","allThoughts","backtracks","Map","undefined","existing","isDeepStrictEqual","backtrack","targetIds","Set","candidate"],"mappings":";;;AAqBA,SAASA,cAAcC,QAAgC;IACtD,OAAO;WAAIC,gBAAgBD;KAAU;AACtC;AAEA,SAASE,YACRC,SAAoB,EACpBC,OAA+B,EAC/BC,QAA4C;IAE5C,OAAO;QACN;YAAEF;YAAW,UAAUC;QAAQ;WAC5BC,SAAS,GAAG,CAAC,CAACC,SAAY;gBAAEH;gBAAW,UAAUG,OAAO,QAAQ;YAAC;KACpE;AACF;AAEA,SAASC,cACRP,QAAgC,EAChCQ,eAA0B;IAE1B,OAAOR,SAAS,GAAG,CAAC,CAACS,UACpBA,QAAQ,EAAE,KAAKD,kBAAkB;YAAE,GAAGC,OAAO;YAAE,WAAW;QAAK,IAAIA;AAErE;AAEO,SAASC,0BACfP,SAAoB,EACpBC,OAA+B,EAC/BC,QAA4C,EAC5CI,OAAoB,EACpBD,eAA0B,EAC1BG,cAAsB;IAEtBC,mBAAmB,2BAA2BT,WAAWM;IACzD,IAAIA,AAAyB,gBAAzBA,QAAQ,YAAY,EACvB,MAAM,IAAII,8BACT,GAAGV,UAAU,SAAS,CAAC,EACvB;IAGF,IAAIK,AAA2B,MAA3BA,gBAAgB,MAAM,EACzB,MAAM,IAAIK,8BACT,GAAGV,UAAU,SAAS,CAAC,EACvB;IAIF,MAAMW,gBAAgBf,cAAcK;IACpC,MAAMW,iBAAiBV,SAAS,GAAG,CAAC,CAACC,SAAY;YAChD,UAAUA,OAAO,QAAQ;YACzB,UAAUP,cAAcO,OAAO,QAAQ;QACxC;IACAU,oCACCd,YAAYC,WAAWW,eAAeC,iBACtC,GAAGZ,UAAU,UAAU,CAAC;IAGzB,MAAMc,mBAAmB;WACrBV,cAAcO,eAAeN;QAChCP,gBAAgBQ;KAChB;IACD,MAAMS,kBACLP,iBAAiB,IAAIM,iBAAiB,KAAK,CAAC,CAACN,kBAAkBM;IAChE,MAAME,oBAAoBJ,eAAe,GAAG,CAAC,CAACT,SAAY;YACzD,UAAUA,OAAO,QAAQ;YACzB,UAAUC,cAAcD,OAAO,QAAQ,EAAEE;QAC1C;IACA,KAAK,MAAMF,UAAUa,kBACpBC,kBAAkB,wBAAwBjB,WAAWG,OAAO,QAAQ,EAAEA,OAAO,QAAQ;IAEtFU,oCACCd,YAAYC,WAAWe,iBAAiBC,oBACxC,GAAGhB,UAAU,UAAU,CAAC;IAEzB,OAAO;QAAE,SAASe;QAAiB,UAAUC;IAAkB;AAChE;AAEO,SAASE,yBACflB,SAAoB,EACpBC,OAA+B,EAC/BC,QAA4C;IAE5C,IAAIiB,kBAAkBvB,cAAcK;IACpC,IAAImB,mBAAmBlB,SAAS,GAAG,CAAC,CAACC,SAAY;YAChD,UAAUA,OAAO,QAAQ;YACzB,UAAUP,cAAcO,OAAO,QAAQ;QACxC;IACA,MAAMkB,cAAc,IAA8B;eAC9CF;eACAC,iBAAiB,OAAO,CAAC,CAACjB,SAAWA,OAAO,QAAQ;SACvD;IACD,MAAMmB,aAAa,IAAIC;IACvB,KAAK,MAAMjB,WAAWe,cACrB,IAAIf,AAAekB,WAAflB,QAAQ,EAAE,IAAkBA,AAAyB,gBAAzBA,QAAQ,YAAY,EAAkB;QACrE,MAAMmB,WAAWH,WAAW,GAAG,CAAChB,QAAQ,EAAE;QAC1C,IAAImB,AAAaD,WAAbC,YAA0BC,kBAAkBD,UAAUnB,UACzDgB,WAAW,GAAG,CAAChB,QAAQ,EAAE,EAAEA;IAE7B;IAGD,KAAK,MAAMqB,aAAaL,WAAW,MAAM,GAAI;QAC5C,IAAIK,AAA+BH,WAA/BG,UAAU,gBAAgB,EAAgB;QAC9C,MAAMC,YAAY,IAAIC;QACtB,KAAK,MAAMC,aAAaT,cACvB,IACCS,AAAiBN,WAAjBM,UAAU,EAAE,IACZA,UAAU,EAAE,KAAKH,UAAU,EAAE,IAC7BG,UAAU,cAAc,KAAKH,UAAU,gBAAgB,EAEvDC,UAAU,GAAG,CAACE,UAAU,EAAE;QAG5B,IAAIF,AAAmB,MAAnBA,UAAU,IAAI,EAAQ;QAC1B,IAAIA,UAAU,IAAI,GAAG,GACpB,MAAM,IAAIlB,8BACT,CAAC,QAAQ,EAAEV,WAAW,EACtB,CAAC,oCAAoC,EAAE2B,UAAU,gBAAgB,EAAE;QAGrE,MAAMtB,kBAAkBuB,UAAU,MAAM,GAAG,IAAI,GAAG,KAAK;QACvD,IAAIvB,AAAoBmB,WAApBnB;YACJc,kBAAkBf,cAAce,iBAAiBd;YACjDe,mBAAmBA,iBAAiB,GAAG,CAAC,CAACjB,SAAY;oBACpD,UAAUA,OAAO,QAAQ;oBACzB,UAAUC,cAAcD,OAAO,QAAQ,EAAEE;gBAC1C;;IACD;IAEA,OAAO;QAAE,SAASc;QAAiB,UAAUC;IAAiB;AAC/D"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { IMetrics } from '../contracts/interfaces.js';
|
|
2
2
|
import type { PersistenceConfig, PersistenceBackend } from '../contracts/PersistenceBackend.js';
|
|
3
|
-
import { type BranchId, type SessionId } from '../contracts/ids.js';
|
|
3
|
+
import { type BranchId, type SessionId, type ThoughtId } from '../contracts/ids.js';
|
|
4
4
|
import type { Summary } from '../core/compression/Summary.js';
|
|
5
5
|
import type { Edge } from '../core/graph/Edge.js';
|
|
6
6
|
import type { ThoughtData } from '../core/thought.js';
|
|
@@ -18,6 +18,7 @@ export declare class FilePersistence implements PersistenceBackend {
|
|
|
18
18
|
constructor(options?: FilePersistenceOptions);
|
|
19
19
|
static create(options?: FilePersistenceOptions): Promise<FilePersistence>;
|
|
20
20
|
saveThoughtForSession(sessionId: SessionId, thought: ThoughtData): Promise<void>;
|
|
21
|
+
saveBacktrackForSession(sessionId: SessionId, thought: ThoughtData, targetThoughtId: ThoughtId): Promise<void>;
|
|
21
22
|
private _saveThought;
|
|
22
23
|
loadHistoryForSession(sessionId: SessionId): Promise<ThoughtData[]>;
|
|
23
24
|
saveBranchForSession(sessionId: SessionId, branchId: BranchId, thoughts: readonly ThoughtData[]): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FilePersistence.d.ts","sourceRoot":"","sources":["../../src/persistence/FilePersistence.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"FilePersistence.d.ts","sourceRoot":"","sources":["../../src/persistence/FilePersistence.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAChG,OAAO,EAAe,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AACjG,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAUtD,OAAO,EAAqC,KAAK,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAY/F,KAAK,sBAAsB,GAAG,WAAW,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC,GAAG;IACzE,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,gBAAgB,CAAC,EAAE,oBAAoB,CAAC;CACjD,CAAC;AAIF,qBAAa,eAAgB,YAAW,kBAAkB;IACzD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAU;IAC3C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAuB;IAChD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAa;gBAEzB,OAAO,CAAC,EAAE,sBAAsB;WAWxB,MAAM,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,OAAO,CAAC,eAAe,CAAC;IAYzE,qBAAqB,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAMhF,uBAAuB,CACnC,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,WAAW,EACpB,eAAe,EAAE,SAAS,GACxB,OAAO,CAAC,IAAI,CAAC;YA+BF,YAAY;IA2Bb,qBAAqB,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAQnE,oBAAoB,CAChC,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,SAAS,WAAW,EAAE,GAC9B,OAAO,CAAC,IAAI,CAAC;YAOF,WAAW;IAwCZ,sBAAsB,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAY/E,oBAAoB,CAChC,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,QAAQ,GAChB,OAAO,CAAC,WAAW,EAAE,GAAG,SAAS,CAAC;IAYxB,sBAAsB,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAWjE,YAAY,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAIpC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAIzB,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAWjD,SAAS,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAYtE,SAAS,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAOhD,aAAa,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAcjF,aAAa,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAQvD,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;IAUjC,UAAU,IAAI,MAAM;IAId,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;YAIrB,KAAK;YAQL,OAAO;YAaP,aAAa;YAYb,QAAQ;CAUtB"}
|
|
@@ -5,6 +5,7 @@ import { join } from "node:path";
|
|
|
5
5
|
import { asSessionId } from "../contracts/ids.js";
|
|
6
6
|
import { PersistenceCompatibilityError } from "../errors.js";
|
|
7
7
|
import { EMPTY_FILE_SNAPSHOT_V2, parseFileSnapshotV2, serializeFileSnapshotV2, sessionsInSnapshot } from "./FileSnapshotV2.js";
|
|
8
|
+
import { stageBacktrackPersistence } from "./BacktrackPersistence.js";
|
|
8
9
|
import { FILE_WRITER_LOCK_NAME, FileWriter } from "./FileWriter.js";
|
|
9
10
|
import { assertBranchScope, assertEdgeScopes, assertPersistableThoughtCollections, assertPersistableThoughts, assertSummaryScopes, assertThoughtScope, compareCodePoint, parsePersistenceBranchId } from "./PersistenceScope.js";
|
|
10
11
|
const SNAPSHOT_NAME = 'snapshot.json';
|
|
@@ -38,6 +39,33 @@ class FilePersistence {
|
|
|
38
39
|
assertThoughtScope('saveThoughtForSession', validatedSessionId, thought);
|
|
39
40
|
await this._saveThought(validatedSessionId, thought);
|
|
40
41
|
}
|
|
42
|
+
async saveBacktrackForSession(sessionId, thought, targetThoughtId) {
|
|
43
|
+
const validatedSessionId = asSessionId(sessionId);
|
|
44
|
+
await this._mutate('save_backtrack', (snapshot)=>{
|
|
45
|
+
const staged = stageBacktrackPersistence(validatedSessionId, snapshot.thoughts.find((record)=>record.sessionId === validatedSessionId)?.thoughts ?? [], snapshot.branches.filter((record)=>record.sessionId === validatedSessionId).map((record)=>({
|
|
46
|
+
branchId: record.branchId,
|
|
47
|
+
thoughts: record.thoughts
|
|
48
|
+
})), thought, targetThoughtId, this._maxHistorySize);
|
|
49
|
+
return {
|
|
50
|
+
...snapshot,
|
|
51
|
+
thoughts: [
|
|
52
|
+
...snapshot.thoughts.filter((record)=>record.sessionId !== validatedSessionId),
|
|
53
|
+
{
|
|
54
|
+
sessionId: validatedSessionId,
|
|
55
|
+
thoughts: staged.history
|
|
56
|
+
}
|
|
57
|
+
],
|
|
58
|
+
branches: [
|
|
59
|
+
...snapshot.branches.filter((record)=>record.sessionId !== validatedSessionId),
|
|
60
|
+
...staged.branches.map((branch)=>({
|
|
61
|
+
sessionId: validatedSessionId,
|
|
62
|
+
branchId: branch.branchId,
|
|
63
|
+
thoughts: branch.thoughts
|
|
64
|
+
}))
|
|
65
|
+
]
|
|
66
|
+
};
|
|
67
|
+
});
|
|
68
|
+
}
|
|
41
69
|
async _saveThought(sessionId, thought) {
|
|
42
70
|
assertPersistableThoughts([
|
|
43
71
|
thought
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"persistence/FilePersistence.js","sources":["../../src/persistence/FilePersistence.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { readFile, readdir } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport type { IMetrics } from '../contracts/interfaces.js';\nimport type {\n\tPersistenceConfig,\n\tPersistenceBackend,\n} from '../contracts/PersistenceBackend.js';\nimport { asSessionId, type BranchId, type SessionId } from '../contracts/ids.js';\nimport type { Summary } from '../core/compression/Summary.js';\nimport type { Edge } from '../core/graph/Edge.js';\nimport type { ThoughtData } from '../core/thought.js';\nimport { PersistenceCompatibilityError } from '../errors.js';\nimport {\n\tEMPTY_FILE_SNAPSHOT_V2,\n\tparseFileSnapshotV2,\n\tserializeFileSnapshotV2,\n\tsessionsInSnapshot,\n} from './FileSnapshotV2.js';\nimport type { FileSnapshotV2 } from './FileSnapshotTypes.js';\nimport {\n\tFILE_WRITER_LOCK_NAME,\n\tFileWriter,\n\ttype FileWriterOperations,\n} from './FileWriter.js';\nimport {\n\tassertBranchScope,\n\tassertEdgeScopes,\n\tassertPersistableThoughtCollections,\n\tassertPersistableThoughts,\n\tassertSummaryScopes,\n\tassertThoughtScope,\n\tcompareCodePoint,\n\tparsePersistenceBranchId,\n} from './PersistenceScope.js';\n\ntype FilePersistenceOptions = NonNullable<PersistenceConfig['options']> & {\n\treadonly metrics?: IMetrics;\n\treadonly writerOperations?: FileWriterOperations;\n};\n\nconst SNAPSHOT_NAME = 'snapshot.json';\n\nexport class FilePersistence implements PersistenceBackend {\n\tprivate readonly _dataDir: string;\n\tprivate readonly _maxHistorySize: number;\n\tprivate readonly _persistBranches: boolean;\n\tprivate readonly _metrics: IMetrics | undefined;\n\tprivate readonly _writer: FileWriter;\n\n\tconstructor(options?: FilePersistenceOptions) {\n\t\tconst defaultDataDir = existsSync('.claude/data')\n\t\t\t? '.claude/data'\n\t\t\t: join(homedir(), '.claude/data');\n\t\tthis._dataDir = options?.dataDir ?? defaultDataDir;\n\t\tthis._maxHistorySize = options?.maxHistorySize ?? 10000;\n\t\tthis._persistBranches = options?.persistBranches ?? true;\n\t\tthis._metrics = options?.metrics;\n\t\tthis._writer = new FileWriter(this._dataDir, options?.writerOperations);\n\t}\n\n\tpublic static async create(options?: FilePersistenceOptions): Promise<FilePersistence> {\n\t\tconst persistence = new FilePersistence(options);\n\t\ttry {\n\t\t\tawait persistence._writer.ready();\n\t\t\tawait persistence._writer.run(async (dataDir) => await persistence._loadSnapshot(dataDir));\n\t\t\treturn persistence;\n\t\t} catch (error) {\n\t\t\tawait persistence.close();\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tpublic async saveThoughtForSession(sessionId: SessionId, thought: ThoughtData): Promise<void> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tassertThoughtScope('saveThoughtForSession', validatedSessionId, thought);\n\t\tawait this._saveThought(validatedSessionId, thought);\n\t}\n\n\tprivate async _saveThought(sessionId: SessionId, thought: ThoughtData): Promise<void> {\n\t\tassertPersistableThoughts([thought], `${sessionId}/thoughts`);\n\t\tawait this._mutate('save_thought', (snapshot) => {\n\t\t\tconst current =\n\t\t\t\tsnapshot.thoughts.find((record) => record.sessionId === sessionId)?.thoughts ?? [];\n\t\t\tconst prospective = [...current, thought];\n\t\t\tassertPersistableThoughtCollections(\n\t\t\t\t[\n\t\t\t\t\t{ sessionId, thoughts: prospective },\n\t\t\t\t\t...snapshot.branches\n\t\t\t\t\t\t.filter((record) => record.sessionId === sessionId)\n\t\t\t\t\t\t.map((record) => ({ sessionId, thoughts: record.thoughts })),\n\t\t\t\t],\n\t\t\t\t`${sessionId}/thoughts`\n\t\t\t);\n\t\t\tconst retained =\n\t\t\t\tthis._maxHistorySize > 0 ? prospective.slice(-this._maxHistorySize) : prospective;\n\t\t\treturn {\n\t\t\t\t...snapshot,\n\t\t\t\tthoughts: [\n\t\t\t\t\t...snapshot.thoughts.filter((record) => record.sessionId !== sessionId),\n\t\t\t\t\t{ sessionId, thoughts: retained },\n\t\t\t\t],\n\t\t\t};\n\t\t});\n\t}\n\n\tpublic async loadHistoryForSession(sessionId: SessionId): Promise<ThoughtData[]> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\treturn await this._read('load_history', (snapshot) => [\n\t\t\t...(snapshot.thoughts.find((record) => record.sessionId === validatedSessionId)?.thoughts ??\n\t\t\t\t[]),\n\t\t]);\n\t}\n\n\tpublic async saveBranchForSession(\n\t\tsessionId: SessionId,\n\t\tbranchId: BranchId,\n\t\tthoughts: readonly ThoughtData[]\n\t): Promise<void> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tconst validatedBranchId = parsePersistenceBranchId(branchId, `${validatedSessionId}/branches`);\n\t\tassertBranchScope('saveBranchForSession', validatedSessionId, validatedBranchId, thoughts);\n\t\tawait this._saveBranch(validatedSessionId, validatedBranchId, thoughts);\n\t}\n\n\tprivate async _saveBranch(\n\t\tsessionId: SessionId,\n\t\tbranchId: BranchId,\n\t\tthoughts: readonly ThoughtData[]\n\t): Promise<void> {\n\t\tassertPersistableThoughtCollections(\n\t\t\t[{ sessionId, thoughts }],\n\t\t\t`${sessionId}/branches/${branchId}`\n\t\t);\n\t\tif (!this._persistBranches) {\n\t\t\tawait this._writer.run(async (dataDir) => {\n\t\t\t\tconst snapshot = await this._loadSnapshot(dataDir);\n\t\t\t\tassertPersistableThoughtCollections(\n\t\t\t\t\t[\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsessionId,\n\t\t\t\t\t\t\tthoughts:\n\t\t\t\t\t\t\t\tsnapshot.thoughts.find((record) => record.sessionId === sessionId)?.thoughts ?? [],\n\t\t\t\t\t\t},\n\t\t\t\t\t\t...snapshot.branches\n\t\t\t\t\t\t\t.filter((record) => record.sessionId === sessionId)\n\t\t\t\t\t\t\t.map((record) => ({ sessionId, thoughts: record.thoughts })),\n\t\t\t\t\t\t{ sessionId, thoughts },\n\t\t\t\t\t],\n\t\t\t\t\t`${sessionId}/branches/${branchId}`\n\t\t\t\t);\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tawait this._mutate('save_branch', (snapshot) => ({\n\t\t\t...snapshot,\n\t\t\tbranches: [\n\t\t\t\t...snapshot.branches.filter(\n\t\t\t\t\t(record) => record.sessionId !== sessionId || record.branchId !== branchId\n\t\t\t\t),\n\t\t\t\t{ sessionId, branchId, thoughts: [...thoughts] },\n\t\t\t],\n\t\t}));\n\t}\n\n\tpublic async deleteBranchForSession(sessionId: SessionId, branchId: BranchId): Promise<void> {\n\t\tif (!this._persistBranches) return;\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tconst validatedBranchId = parsePersistenceBranchId(branchId, `${validatedSessionId}/branches`);\n\t\tawait this._mutate('delete_branch', (snapshot) => ({\n\t\t\t...snapshot,\n\t\t\tbranches: snapshot.branches.filter(\n\t\t\t\t(record) => record.sessionId !== validatedSessionId || record.branchId !== validatedBranchId\n\t\t\t),\n\t\t}));\n\t}\n\n\tpublic async loadBranchForSession(\n\t\tsessionId: SessionId,\n\t\tbranchId: BranchId\n\t): Promise<ThoughtData[] | undefined> {\n\t\tif (!this._persistBranches) return undefined;\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tconst validatedBranchId = parsePersistenceBranchId(branchId, `${validatedSessionId}/branches`);\n\t\treturn await this._read('load_branch', (snapshot) => {\n\t\t\tconst thoughts = snapshot.branches.find(\n\t\t\t\t(record) => record.sessionId === validatedSessionId && record.branchId === validatedBranchId\n\t\t\t)?.thoughts;\n\t\t\treturn thoughts === undefined ? undefined : [...thoughts];\n\t\t});\n\t}\n\n\tpublic async listBranchesForSession(sessionId: SessionId): Promise<BranchId[]> {\n\t\tif (!this._persistBranches) return [];\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\treturn await this._read('list_branches', (snapshot) =>\n\t\t\tsnapshot.branches\n\t\t\t\t.filter((record) => record.sessionId === validatedSessionId)\n\t\t\t\t.map((record) => record.branchId)\n\t\t\t\t.sort(compareCodePoint)\n\t\t);\n\t}\n\n\tpublic async listSessions(): Promise<SessionId[]> {\n\t\treturn await this._read('list_sessions', sessionsInSnapshot);\n\t}\n\n\tpublic async clearAll(): Promise<void> {\n\t\tawait this._mutate('clear_all', () => EMPTY_FILE_SNAPSHOT_V2);\n\t}\n\n\tpublic async clearSession(sessionId: SessionId): Promise<void> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tawait this._mutate('clear_session', (snapshot) => ({\n\t\t\tversion: 2,\n\t\t\tthoughts: snapshot.thoughts.filter((record) => record.sessionId !== validatedSessionId),\n\t\t\tbranches: snapshot.branches.filter((record) => record.sessionId !== validatedSessionId),\n\t\t\tedges: snapshot.edges.filter((record) => record.sessionId !== validatedSessionId),\n\t\t\tsummaries: snapshot.summaries.filter((record) => record.sessionId !== validatedSessionId),\n\t\t}));\n\t}\n\n\tpublic async saveEdges(sessionId: SessionId, edges: readonly Edge[]): Promise<void> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tassertEdgeScopes(validatedSessionId, edges);\n\t\tawait this._mutate('save_edges', (snapshot) => ({\n\t\t\t...snapshot,\n\t\t\tedges: [\n\t\t\t\t...snapshot.edges.filter((record) => record.sessionId !== validatedSessionId),\n\t\t\t\t...(edges.length === 0 ? [] : [{ sessionId: validatedSessionId, edges: [...edges] }]),\n\t\t\t],\n\t\t}));\n\t}\n\n\tpublic async loadEdges(sessionId: SessionId): Promise<Edge[]> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\treturn await this._read('load_edges', (snapshot) => [\n\t\t\t...(snapshot.edges.find((record) => record.sessionId === validatedSessionId)?.edges ?? []),\n\t\t]);\n\t}\n\n\tpublic async saveSummaries(sessionId: SessionId, summaries: readonly Summary[]): Promise<void> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tassertSummaryScopes(validatedSessionId, summaries);\n\t\tawait this._mutate('save_summaries', (snapshot) => ({\n\t\t\t...snapshot,\n\t\t\tsummaries: [\n\t\t\t\t...snapshot.summaries.filter((record) => record.sessionId !== validatedSessionId),\n\t\t\t\t...(summaries.length === 0\n\t\t\t\t\t? []\n\t\t\t\t\t: [{ sessionId: validatedSessionId, summaries: [...summaries] }]),\n\t\t\t],\n\t\t}));\n\t}\n\n\tpublic async loadSummaries(sessionId: SessionId): Promise<Summary[]> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\treturn await this._read('load_summaries', (snapshot) => [\n\t\t\t...(snapshot.summaries.find((record) => record.sessionId === validatedSessionId)?.summaries ??\n\t\t\t\t[]),\n\t\t]);\n\t}\n\n\tpublic async healthy(): Promise<boolean> {\n\t\ttry {\n\t\t\tawait this._writer.run(async (dataDir) => await this._loadSnapshot(dataDir));\n\t\t\treturn true;\n\t\t} catch (error) {\n\t\t\tif (error instanceof Error) return false;\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tpublic getDataDir(): string {\n\t\treturn this._dataDir;\n\t}\n\n\tpublic async close(): Promise<void> {\n\t\tawait this._writer.close();\n\t}\n\n\tprivate async _read<T>(operation: string, select: (snapshot: FileSnapshotV2) => T): Promise<T> {\n\t\treturn await this._measure(\n\t\t\toperation,\n\t\t\tasync () =>\n\t\t\t\tawait this._writer.run(async (dataDir) => select(await this._loadSnapshot(dataDir)))\n\t\t);\n\t}\n\n\tprivate async _mutate(\n\t\toperation: string,\n\t\tmutate: (snapshot: FileSnapshotV2) => FileSnapshotV2\n\t): Promise<void> {\n\t\tawait this._measure(operation, async () => {\n\t\t\tawait this._writer.run(async (dataDir) => {\n\t\t\t\tconst snapshotPath = join(dataDir, SNAPSHOT_NAME);\n\t\t\t\tconst updated = mutate(await this._loadSnapshot(dataDir));\n\t\t\t\tawait this._writer.publish(snapshotPath, serializeFileSnapshotV2(updated, snapshotPath));\n\t\t\t});\n\t\t});\n\t}\n\n\tprivate async _loadSnapshot(dataDir: string): Promise<FileSnapshotV2> {\n\t\tconst snapshotPath = join(dataDir, SNAPSHOT_NAME);\n\t\tconst layoutEntries = (await readdir(dataDir)).filter(\n\t\t\t(entry) => entry !== FILE_WRITER_LOCK_NAME\n\t\t);\n\t\tif (layoutEntries.length === 0) return EMPTY_FILE_SNAPSHOT_V2;\n\t\tif (layoutEntries.length !== 1 || layoutEntries[0] !== SNAPSHOT_NAME) {\n\t\t\tthrow new PersistenceCompatibilityError(\n\t\t\t\tdataDir,\n\t\t\t\t'directory does not match File v2 layout'\n\t\t\t);\n\t\t}\n\t\treturn parseFileSnapshotV2(await readFile(snapshotPath, 'utf-8'), snapshotPath);\n\t}\n\n\tprivate async _measure<T>(operation: string, action: () => Promise<T>): Promise<T> {\n\t\tconst startTime = Date.now();\n\t\ttry {\n\t\t\treturn await action();\n\t\t} finally {\n\t\t\tthis._metrics?.histogram('persistence_op_duration_seconds', (Date.now() - startTime) / 1000, {\n\t\t\t\toperation,\n\t\t\t});\n\t\t}\n\t}\n}\n"],"names":["SNAPSHOT_NAME","FilePersistence","options","defaultDataDir","existsSync","join","homedir","FileWriter","persistence","dataDir","error","sessionId","thought","validatedSessionId","asSessionId","assertThoughtScope","assertPersistableThoughts","snapshot","current","record","prospective","assertPersistableThoughtCollections","retained","branchId","thoughts","validatedBranchId","parsePersistenceBranchId","assertBranchScope","undefined","compareCodePoint","sessionsInSnapshot","EMPTY_FILE_SNAPSHOT_V2","edges","assertEdgeScopes","summaries","assertSummaryScopes","Error","operation","select","mutate","snapshotPath","updated","serializeFileSnapshotV2","layoutEntries","readdir","entry","FILE_WRITER_LOCK_NAME","PersistenceCompatibilityError","parseFileSnapshotV2","readFile","action","startTime","Date"],"mappings":";;;;;;;;;AA0CA,MAAMA,gBAAgB;AAEf,MAAMC;IACK,SAAiB;IACjB,gBAAwB;IACxB,iBAA0B;IAC1B,SAA+B;IAC/B,QAAoB;IAErC,YAAYC,OAAgC,CAAE;QAC7C,MAAMC,iBAAiBC,WAAW,kBAC/B,iBACAC,KAAKC,WAAW;QACnB,IAAI,CAAC,QAAQ,GAAGJ,SAAS,WAAWC;QACpC,IAAI,CAAC,eAAe,GAAGD,SAAS,kBAAkB;QAClD,IAAI,CAAC,gBAAgB,GAAGA,SAAS,mBAAmB;QACpD,IAAI,CAAC,QAAQ,GAAGA,SAAS;QACzB,IAAI,CAAC,OAAO,GAAG,IAAIK,WAAW,IAAI,CAAC,QAAQ,EAAEL,SAAS;IACvD;IAEA,aAAoB,OAAOA,OAAgC,EAA4B;QACtF,MAAMM,cAAc,IAAIP,gBAAgBC;QACxC,IAAI;YACH,MAAMM,YAAY,OAAO,CAAC,KAAK;YAC/B,MAAMA,YAAY,OAAO,CAAC,GAAG,CAAC,OAAOC,UAAY,MAAMD,YAAY,aAAa,CAACC;YACjF,OAAOD;QACR,EAAE,OAAOE,OAAO;YACf,MAAMF,YAAY,KAAK;YACvB,MAAME;QACP;IACD;IAEA,MAAa,sBAAsBC,SAAoB,EAAEC,OAAoB,EAAiB;QAC7F,MAAMC,qBAAqBC,YAAYH;QACvCI,mBAAmB,yBAAyBF,oBAAoBD;QAChE,MAAM,IAAI,CAAC,YAAY,CAACC,oBAAoBD;IAC7C;IAEA,MAAc,aAAaD,SAAoB,EAAEC,OAAoB,EAAiB;QACrFI,0BAA0B;YAACJ;SAAQ,EAAE,GAAGD,UAAU,SAAS,CAAC;QAC5D,MAAM,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAACM;YACnC,MAAMC,UACLD,SAAS,QAAQ,CAAC,IAAI,CAAC,CAACE,SAAWA,OAAO,SAAS,KAAKR,YAAY,YAAY,EAAE;YACnF,MAAMS,cAAc;mBAAIF;gBAASN;aAAQ;YACzCS,oCACC;gBACC;oBAAEV;oBAAW,UAAUS;gBAAY;mBAChCH,SAAS,QAAQ,CAClB,MAAM,CAAC,CAACE,SAAWA,OAAO,SAAS,KAAKR,WACxC,GAAG,CAAC,CAACQ,SAAY;wBAAER;wBAAW,UAAUQ,OAAO,QAAQ;oBAAC;aAC1D,EACD,GAAGR,UAAU,SAAS,CAAC;YAExB,MAAMW,WACL,IAAI,CAAC,eAAe,GAAG,IAAIF,YAAY,KAAK,CAAC,CAAC,IAAI,CAAC,eAAe,IAAIA;YACvE,OAAO;gBACN,GAAGH,QAAQ;gBACX,UAAU;uBACNA,SAAS,QAAQ,CAAC,MAAM,CAAC,CAACE,SAAWA,OAAO,SAAS,KAAKR;oBAC7D;wBAAEA;wBAAW,UAAUW;oBAAS;iBAChC;YACF;QACD;IACD;IAEA,MAAa,sBAAsBX,SAAoB,EAA0B;QAChF,MAAME,qBAAqBC,YAAYH;QACvC,OAAO,MAAM,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAACM,WAAa;mBACjDA,SAAS,QAAQ,CAAC,IAAI,CAAC,CAACE,SAAWA,OAAO,SAAS,KAAKN,qBAAqB,YAChF,EAAE;aACH;IACF;IAEA,MAAa,qBACZF,SAAoB,EACpBY,QAAkB,EAClBC,QAAgC,EAChB;QAChB,MAAMX,qBAAqBC,YAAYH;QACvC,MAAMc,oBAAoBC,yBAAyBH,UAAU,GAAGV,mBAAmB,SAAS,CAAC;QAC7Fc,kBAAkB,wBAAwBd,oBAAoBY,mBAAmBD;QACjF,MAAM,IAAI,CAAC,WAAW,CAACX,oBAAoBY,mBAAmBD;IAC/D;IAEA,MAAc,YACbb,SAAoB,EACpBY,QAAkB,EAClBC,QAAgC,EAChB;QAChBH,oCACC;YAAC;gBAAEV;gBAAWa;YAAS;SAAE,EACzB,GAAGb,UAAU,UAAU,EAAEY,UAAU;QAEpC,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,YAC3B,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAOd;YAC7B,MAAMQ,WAAW,MAAM,IAAI,CAAC,aAAa,CAACR;YAC1CY,oCACC;gBACC;oBACCV;oBACA,UACCM,SAAS,QAAQ,CAAC,IAAI,CAAC,CAACE,SAAWA,OAAO,SAAS,KAAKR,YAAY,YAAY,EAAE;gBACpF;mBACGM,SAAS,QAAQ,CAClB,MAAM,CAAC,CAACE,SAAWA,OAAO,SAAS,KAAKR,WACxC,GAAG,CAAC,CAACQ,SAAY;wBAAER;wBAAW,UAAUQ,OAAO,QAAQ;oBAAC;gBAC1D;oBAAER;oBAAWa;gBAAS;aACtB,EACD,GAAGb,UAAU,UAAU,EAAEY,UAAU;QAErC;QAGD,MAAM,IAAI,CAAC,OAAO,CAAC,eAAe,CAACN,WAAc;gBAChD,GAAGA,QAAQ;gBACX,UAAU;uBACNA,SAAS,QAAQ,CAAC,MAAM,CAC1B,CAACE,SAAWA,OAAO,SAAS,KAAKR,aAAaQ,OAAO,QAAQ,KAAKI;oBAEnE;wBAAEZ;wBAAWY;wBAAU,UAAU;+BAAIC;yBAAS;oBAAC;iBAC/C;YACF;IACD;IAEA,MAAa,uBAAuBb,SAAoB,EAAEY,QAAkB,EAAiB;QAC5F,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;QAC5B,MAAMV,qBAAqBC,YAAYH;QACvC,MAAMc,oBAAoBC,yBAAyBH,UAAU,GAAGV,mBAAmB,SAAS,CAAC;QAC7F,MAAM,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAACI,WAAc;gBAClD,GAAGA,QAAQ;gBACX,UAAUA,SAAS,QAAQ,CAAC,MAAM,CACjC,CAACE,SAAWA,OAAO,SAAS,KAAKN,sBAAsBM,OAAO,QAAQ,KAAKM;YAE7E;IACD;IAEA,MAAa,qBACZd,SAAoB,EACpBY,QAAkB,EACmB;QACrC,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE;QAC5B,MAAMV,qBAAqBC,YAAYH;QACvC,MAAMc,oBAAoBC,yBAAyBH,UAAU,GAAGV,mBAAmB,SAAS,CAAC;QAC7F,OAAO,MAAM,IAAI,CAAC,KAAK,CAAC,eAAe,CAACI;YACvC,MAAMO,WAAWP,SAAS,QAAQ,CAAC,IAAI,CACtC,CAACE,SAAWA,OAAO,SAAS,KAAKN,sBAAsBM,OAAO,QAAQ,KAAKM,oBACzE;YACH,OAAOD,AAAaI,WAAbJ,WAAyBI,SAAY;mBAAIJ;aAAS;QAC1D;IACD;IAEA,MAAa,uBAAuBb,SAAoB,EAAuB;QAC9E,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,OAAO,EAAE;QACrC,MAAME,qBAAqBC,YAAYH;QACvC,OAAO,MAAM,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAACM,WACzCA,SAAS,QAAQ,CACf,MAAM,CAAC,CAACE,SAAWA,OAAO,SAAS,KAAKN,oBACxC,GAAG,CAAC,CAACM,SAAWA,OAAO,QAAQ,EAC/B,IAAI,CAACU;IAET;IAEA,MAAa,eAAqC;QACjD,OAAO,MAAM,IAAI,CAAC,KAAK,CAAC,iBAAiBC;IAC1C;IAEA,MAAa,WAA0B;QACtC,MAAM,IAAI,CAAC,OAAO,CAAC,aAAa,IAAMC;IACvC;IAEA,MAAa,aAAapB,SAAoB,EAAiB;QAC9D,MAAME,qBAAqBC,YAAYH;QACvC,MAAM,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAACM,WAAc;gBAClD,SAAS;gBACT,UAAUA,SAAS,QAAQ,CAAC,MAAM,CAAC,CAACE,SAAWA,OAAO,SAAS,KAAKN;gBACpE,UAAUI,SAAS,QAAQ,CAAC,MAAM,CAAC,CAACE,SAAWA,OAAO,SAAS,KAAKN;gBACpE,OAAOI,SAAS,KAAK,CAAC,MAAM,CAAC,CAACE,SAAWA,OAAO,SAAS,KAAKN;gBAC9D,WAAWI,SAAS,SAAS,CAAC,MAAM,CAAC,CAACE,SAAWA,OAAO,SAAS,KAAKN;YACvE;IACD;IAEA,MAAa,UAAUF,SAAoB,EAAEqB,KAAsB,EAAiB;QACnF,MAAMnB,qBAAqBC,YAAYH;QACvCsB,iBAAiBpB,oBAAoBmB;QACrC,MAAM,IAAI,CAAC,OAAO,CAAC,cAAc,CAACf,WAAc;gBAC/C,GAAGA,QAAQ;gBACX,OAAO;uBACHA,SAAS,KAAK,CAAC,MAAM,CAAC,CAACE,SAAWA,OAAO,SAAS,KAAKN;uBACtDmB,AAAiB,MAAjBA,MAAM,MAAM,GAAS,EAAE,GAAG;wBAAC;4BAAE,WAAWnB;4BAAoB,OAAO;mCAAImB;6BAAM;wBAAC;qBAAE;iBACpF;YACF;IACD;IAEA,MAAa,UAAUrB,SAAoB,EAAmB;QAC7D,MAAME,qBAAqBC,YAAYH;QACvC,OAAO,MAAM,IAAI,CAAC,KAAK,CAAC,cAAc,CAACM,WAAa;mBAC/CA,SAAS,KAAK,CAAC,IAAI,CAAC,CAACE,SAAWA,OAAO,SAAS,KAAKN,qBAAqB,SAAS,EAAE;aACzF;IACF;IAEA,MAAa,cAAcF,SAAoB,EAAEuB,SAA6B,EAAiB;QAC9F,MAAMrB,qBAAqBC,YAAYH;QACvCwB,oBAAoBtB,oBAAoBqB;QACxC,MAAM,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAACjB,WAAc;gBACnD,GAAGA,QAAQ;gBACX,WAAW;uBACPA,SAAS,SAAS,CAAC,MAAM,CAAC,CAACE,SAAWA,OAAO,SAAS,KAAKN;uBAC1DqB,AAAqB,MAArBA,UAAU,MAAM,GACjB,EAAE,GACF;wBAAC;4BAAE,WAAWrB;4BAAoB,WAAW;mCAAIqB;6BAAU;wBAAC;qBAAE;iBACjE;YACF;IACD;IAEA,MAAa,cAAcvB,SAAoB,EAAsB;QACpE,MAAME,qBAAqBC,YAAYH;QACvC,OAAO,MAAM,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAACM,WAAa;mBACnDA,SAAS,SAAS,CAAC,IAAI,CAAC,CAACE,SAAWA,OAAO,SAAS,KAAKN,qBAAqB,aACjF,EAAE;aACH;IACF;IAEA,MAAa,UAA4B;QACxC,IAAI;YACH,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAOJ,UAAY,MAAM,IAAI,CAAC,aAAa,CAACA;YACnE,OAAO;QACR,EAAE,OAAOC,OAAO;YACf,IAAIA,iBAAiB0B,OAAO,OAAO;YACnC,MAAM1B;QACP;IACD;IAEO,aAAqB;QAC3B,OAAO,IAAI,CAAC,QAAQ;IACrB;IAEA,MAAa,QAAuB;QACnC,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK;IACzB;IAEA,MAAc,MAAS2B,SAAiB,EAAEC,MAAuC,EAAc;QAC9F,OAAO,MAAM,IAAI,CAAC,QAAQ,CACzBD,WACA,UACC,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO5B,UAAY6B,OAAO,MAAM,IAAI,CAAC,aAAa,CAAC7B;IAE7E;IAEA,MAAc,QACb4B,SAAiB,EACjBE,MAAoD,EACpC;QAChB,MAAM,IAAI,CAAC,QAAQ,CAACF,WAAW;YAC9B,MAAM,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO5B;gBAC7B,MAAM+B,eAAenC,KAAKI,SAAST;gBACnC,MAAMyC,UAAUF,OAAO,MAAM,IAAI,CAAC,aAAa,CAAC9B;gBAChD,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC+B,cAAcE,wBAAwBD,SAASD;YAC3E;QACD;IACD;IAEA,MAAc,cAAc/B,OAAe,EAA2B;QACrE,MAAM+B,eAAenC,KAAKI,SAAST;QACnC,MAAM2C,gBAAiB,OAAMC,QAAQnC,QAAO,EAAG,MAAM,CACpD,CAACoC,QAAUA,UAAUC;QAEtB,IAAIH,AAAyB,MAAzBA,cAAc,MAAM,EAAQ,OAAOZ;QACvC,IAAIY,AAAyB,MAAzBA,cAAc,MAAM,IAAUA,aAAa,CAAC,EAAE,KAAK3C,eACtD,MAAM,IAAI+C,8BACTtC,SACA;QAGF,OAAOuC,oBAAoB,MAAMC,SAAST,cAAc,UAAUA;IACnE;IAEA,MAAc,SAAYH,SAAiB,EAAEa,MAAwB,EAAc;QAClF,MAAMC,YAAYC,KAAK,GAAG;QAC1B,IAAI;YACH,OAAO,MAAMF;QACd,SAAU;YACT,IAAI,CAAC,QAAQ,EAAE,UAAU,mCAAoCE,AAAAA,CAAAA,KAAK,GAAG,KAAKD,SAAQ,IAAK,MAAM;gBAC5Fd;YACD;QACD;IACD;AACD"}
|
|
1
|
+
{"version":3,"file":"persistence/FilePersistence.js","sources":["../../src/persistence/FilePersistence.ts"],"sourcesContent":["import { existsSync } from 'node:fs';\nimport { readFile, readdir } from 'node:fs/promises';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport type { IMetrics } from '../contracts/interfaces.js';\nimport type { PersistenceConfig, PersistenceBackend } from '../contracts/PersistenceBackend.js';\nimport { asSessionId, type BranchId, type SessionId, type ThoughtId } from '../contracts/ids.js';\nimport type { Summary } from '../core/compression/Summary.js';\nimport type { Edge } from '../core/graph/Edge.js';\nimport type { ThoughtData } from '../core/thought.js';\nimport { PersistenceCompatibilityError } from '../errors.js';\nimport {\n\tEMPTY_FILE_SNAPSHOT_V2,\n\tparseFileSnapshotV2,\n\tserializeFileSnapshotV2,\n\tsessionsInSnapshot,\n} from './FileSnapshotV2.js';\nimport type { FileSnapshotV2 } from './FileSnapshotTypes.js';\nimport { stageBacktrackPersistence } from './BacktrackPersistence.js';\nimport { FILE_WRITER_LOCK_NAME, FileWriter, type FileWriterOperations } from './FileWriter.js';\nimport {\n\tassertBranchScope,\n\tassertEdgeScopes,\n\tassertPersistableThoughtCollections,\n\tassertPersistableThoughts,\n\tassertSummaryScopes,\n\tassertThoughtScope,\n\tcompareCodePoint,\n\tparsePersistenceBranchId,\n} from './PersistenceScope.js';\n\ntype FilePersistenceOptions = NonNullable<PersistenceConfig['options']> & {\n\treadonly metrics?: IMetrics;\n\treadonly writerOperations?: FileWriterOperations;\n};\n\nconst SNAPSHOT_NAME = 'snapshot.json';\n\nexport class FilePersistence implements PersistenceBackend {\n\tprivate readonly _dataDir: string;\n\tprivate readonly _maxHistorySize: number;\n\tprivate readonly _persistBranches: boolean;\n\tprivate readonly _metrics: IMetrics | undefined;\n\tprivate readonly _writer: FileWriter;\n\n\tconstructor(options?: FilePersistenceOptions) {\n\t\tconst defaultDataDir = existsSync('.claude/data')\n\t\t\t? '.claude/data'\n\t\t\t: join(homedir(), '.claude/data');\n\t\tthis._dataDir = options?.dataDir ?? defaultDataDir;\n\t\tthis._maxHistorySize = options?.maxHistorySize ?? 10000;\n\t\tthis._persistBranches = options?.persistBranches ?? true;\n\t\tthis._metrics = options?.metrics;\n\t\tthis._writer = new FileWriter(this._dataDir, options?.writerOperations);\n\t}\n\n\tpublic static async create(options?: FilePersistenceOptions): Promise<FilePersistence> {\n\t\tconst persistence = new FilePersistence(options);\n\t\ttry {\n\t\t\tawait persistence._writer.ready();\n\t\t\tawait persistence._writer.run(async (dataDir) => await persistence._loadSnapshot(dataDir));\n\t\t\treturn persistence;\n\t\t} catch (error) {\n\t\t\tawait persistence.close();\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tpublic async saveThoughtForSession(sessionId: SessionId, thought: ThoughtData): Promise<void> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tassertThoughtScope('saveThoughtForSession', validatedSessionId, thought);\n\t\tawait this._saveThought(validatedSessionId, thought);\n\t}\n\n\tpublic async saveBacktrackForSession(\n\t\tsessionId: SessionId,\n\t\tthought: ThoughtData,\n\t\ttargetThoughtId: ThoughtId\n\t): Promise<void> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tawait this._mutate('save_backtrack', (snapshot) => {\n\t\t\tconst staged = stageBacktrackPersistence(\n\t\t\t\tvalidatedSessionId,\n\t\t\t\tsnapshot.thoughts.find((record) => record.sessionId === validatedSessionId)?.thoughts ?? [],\n\t\t\t\tsnapshot.branches\n\t\t\t\t\t.filter((record) => record.sessionId === validatedSessionId)\n\t\t\t\t\t.map((record) => ({ branchId: record.branchId, thoughts: record.thoughts })),\n\t\t\t\tthought,\n\t\t\t\ttargetThoughtId,\n\t\t\t\tthis._maxHistorySize\n\t\t\t);\n\t\t\treturn {\n\t\t\t\t...snapshot,\n\t\t\t\tthoughts: [\n\t\t\t\t\t...snapshot.thoughts.filter((record) => record.sessionId !== validatedSessionId),\n\t\t\t\t\t{ sessionId: validatedSessionId, thoughts: staged.history },\n\t\t\t\t],\n\t\t\t\tbranches: [\n\t\t\t\t\t...snapshot.branches.filter((record) => record.sessionId !== validatedSessionId),\n\t\t\t\t\t...staged.branches.map((branch) => ({\n\t\t\t\t\t\tsessionId: validatedSessionId,\n\t\t\t\t\t\tbranchId: branch.branchId,\n\t\t\t\t\t\tthoughts: branch.thoughts,\n\t\t\t\t\t})),\n\t\t\t\t],\n\t\t\t};\n\t\t});\n\t}\n\n\tprivate async _saveThought(sessionId: SessionId, thought: ThoughtData): Promise<void> {\n\t\tassertPersistableThoughts([thought], `${sessionId}/thoughts`);\n\t\tawait this._mutate('save_thought', (snapshot) => {\n\t\t\tconst current =\n\t\t\t\tsnapshot.thoughts.find((record) => record.sessionId === sessionId)?.thoughts ?? [];\n\t\t\tconst prospective = [...current, thought];\n\t\t\tassertPersistableThoughtCollections(\n\t\t\t\t[\n\t\t\t\t\t{ sessionId, thoughts: prospective },\n\t\t\t\t\t...snapshot.branches\n\t\t\t\t\t\t.filter((record) => record.sessionId === sessionId)\n\t\t\t\t\t\t.map((record) => ({ sessionId, thoughts: record.thoughts })),\n\t\t\t\t],\n\t\t\t\t`${sessionId}/thoughts`\n\t\t\t);\n\t\t\tconst retained =\n\t\t\t\tthis._maxHistorySize > 0 ? prospective.slice(-this._maxHistorySize) : prospective;\n\t\t\treturn {\n\t\t\t\t...snapshot,\n\t\t\t\tthoughts: [\n\t\t\t\t\t...snapshot.thoughts.filter((record) => record.sessionId !== sessionId),\n\t\t\t\t\t{ sessionId, thoughts: retained },\n\t\t\t\t],\n\t\t\t};\n\t\t});\n\t}\n\n\tpublic async loadHistoryForSession(sessionId: SessionId): Promise<ThoughtData[]> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\treturn await this._read('load_history', (snapshot) => [\n\t\t\t...(snapshot.thoughts.find((record) => record.sessionId === validatedSessionId)?.thoughts ??\n\t\t\t\t[]),\n\t\t]);\n\t}\n\n\tpublic async saveBranchForSession(\n\t\tsessionId: SessionId,\n\t\tbranchId: BranchId,\n\t\tthoughts: readonly ThoughtData[]\n\t): Promise<void> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tconst validatedBranchId = parsePersistenceBranchId(branchId, `${validatedSessionId}/branches`);\n\t\tassertBranchScope('saveBranchForSession', validatedSessionId, validatedBranchId, thoughts);\n\t\tawait this._saveBranch(validatedSessionId, validatedBranchId, thoughts);\n\t}\n\n\tprivate async _saveBranch(\n\t\tsessionId: SessionId,\n\t\tbranchId: BranchId,\n\t\tthoughts: readonly ThoughtData[]\n\t): Promise<void> {\n\t\tassertPersistableThoughtCollections(\n\t\t\t[{ sessionId, thoughts }],\n\t\t\t`${sessionId}/branches/${branchId}`\n\t\t);\n\t\tif (!this._persistBranches) {\n\t\t\tawait this._writer.run(async (dataDir) => {\n\t\t\t\tconst snapshot = await this._loadSnapshot(dataDir);\n\t\t\t\tassertPersistableThoughtCollections(\n\t\t\t\t\t[\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tsessionId,\n\t\t\t\t\t\t\tthoughts:\n\t\t\t\t\t\t\t\tsnapshot.thoughts.find((record) => record.sessionId === sessionId)?.thoughts ?? [],\n\t\t\t\t\t\t},\n\t\t\t\t\t\t...snapshot.branches\n\t\t\t\t\t\t\t.filter((record) => record.sessionId === sessionId)\n\t\t\t\t\t\t\t.map((record) => ({ sessionId, thoughts: record.thoughts })),\n\t\t\t\t\t\t{ sessionId, thoughts },\n\t\t\t\t\t],\n\t\t\t\t\t`${sessionId}/branches/${branchId}`\n\t\t\t\t);\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tawait this._mutate('save_branch', (snapshot) => ({\n\t\t\t...snapshot,\n\t\t\tbranches: [\n\t\t\t\t...snapshot.branches.filter(\n\t\t\t\t\t(record) => record.sessionId !== sessionId || record.branchId !== branchId\n\t\t\t\t),\n\t\t\t\t{ sessionId, branchId, thoughts: [...thoughts] },\n\t\t\t],\n\t\t}));\n\t}\n\n\tpublic async deleteBranchForSession(sessionId: SessionId, branchId: BranchId): Promise<void> {\n\t\tif (!this._persistBranches) return;\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tconst validatedBranchId = parsePersistenceBranchId(branchId, `${validatedSessionId}/branches`);\n\t\tawait this._mutate('delete_branch', (snapshot) => ({\n\t\t\t...snapshot,\n\t\t\tbranches: snapshot.branches.filter(\n\t\t\t\t(record) => record.sessionId !== validatedSessionId || record.branchId !== validatedBranchId\n\t\t\t),\n\t\t}));\n\t}\n\n\tpublic async loadBranchForSession(\n\t\tsessionId: SessionId,\n\t\tbranchId: BranchId\n\t): Promise<ThoughtData[] | undefined> {\n\t\tif (!this._persistBranches) return undefined;\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tconst validatedBranchId = parsePersistenceBranchId(branchId, `${validatedSessionId}/branches`);\n\t\treturn await this._read('load_branch', (snapshot) => {\n\t\t\tconst thoughts = snapshot.branches.find(\n\t\t\t\t(record) => record.sessionId === validatedSessionId && record.branchId === validatedBranchId\n\t\t\t)?.thoughts;\n\t\t\treturn thoughts === undefined ? undefined : [...thoughts];\n\t\t});\n\t}\n\n\tpublic async listBranchesForSession(sessionId: SessionId): Promise<BranchId[]> {\n\t\tif (!this._persistBranches) return [];\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\treturn await this._read('list_branches', (snapshot) =>\n\t\t\tsnapshot.branches\n\t\t\t\t.filter((record) => record.sessionId === validatedSessionId)\n\t\t\t\t.map((record) => record.branchId)\n\t\t\t\t.sort(compareCodePoint)\n\t\t);\n\t}\n\n\tpublic async listSessions(): Promise<SessionId[]> {\n\t\treturn await this._read('list_sessions', sessionsInSnapshot);\n\t}\n\n\tpublic async clearAll(): Promise<void> {\n\t\tawait this._mutate('clear_all', () => EMPTY_FILE_SNAPSHOT_V2);\n\t}\n\n\tpublic async clearSession(sessionId: SessionId): Promise<void> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tawait this._mutate('clear_session', (snapshot) => ({\n\t\t\tversion: 2,\n\t\t\tthoughts: snapshot.thoughts.filter((record) => record.sessionId !== validatedSessionId),\n\t\t\tbranches: snapshot.branches.filter((record) => record.sessionId !== validatedSessionId),\n\t\t\tedges: snapshot.edges.filter((record) => record.sessionId !== validatedSessionId),\n\t\t\tsummaries: snapshot.summaries.filter((record) => record.sessionId !== validatedSessionId),\n\t\t}));\n\t}\n\n\tpublic async saveEdges(sessionId: SessionId, edges: readonly Edge[]): Promise<void> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tassertEdgeScopes(validatedSessionId, edges);\n\t\tawait this._mutate('save_edges', (snapshot) => ({\n\t\t\t...snapshot,\n\t\t\tedges: [\n\t\t\t\t...snapshot.edges.filter((record) => record.sessionId !== validatedSessionId),\n\t\t\t\t...(edges.length === 0 ? [] : [{ sessionId: validatedSessionId, edges: [...edges] }]),\n\t\t\t],\n\t\t}));\n\t}\n\n\tpublic async loadEdges(sessionId: SessionId): Promise<Edge[]> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\treturn await this._read('load_edges', (snapshot) => [\n\t\t\t...(snapshot.edges.find((record) => record.sessionId === validatedSessionId)?.edges ?? []),\n\t\t]);\n\t}\n\n\tpublic async saveSummaries(sessionId: SessionId, summaries: readonly Summary[]): Promise<void> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tassertSummaryScopes(validatedSessionId, summaries);\n\t\tawait this._mutate('save_summaries', (snapshot) => ({\n\t\t\t...snapshot,\n\t\t\tsummaries: [\n\t\t\t\t...snapshot.summaries.filter((record) => record.sessionId !== validatedSessionId),\n\t\t\t\t...(summaries.length === 0\n\t\t\t\t\t? []\n\t\t\t\t\t: [{ sessionId: validatedSessionId, summaries: [...summaries] }]),\n\t\t\t],\n\t\t}));\n\t}\n\n\tpublic async loadSummaries(sessionId: SessionId): Promise<Summary[]> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\treturn await this._read('load_summaries', (snapshot) => [\n\t\t\t...(snapshot.summaries.find((record) => record.sessionId === validatedSessionId)?.summaries ??\n\t\t\t\t[]),\n\t\t]);\n\t}\n\n\tpublic async healthy(): Promise<boolean> {\n\t\ttry {\n\t\t\tawait this._writer.run(async (dataDir) => await this._loadSnapshot(dataDir));\n\t\t\treturn true;\n\t\t} catch (error) {\n\t\t\tif (error instanceof Error) return false;\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tpublic getDataDir(): string {\n\t\treturn this._dataDir;\n\t}\n\n\tpublic async close(): Promise<void> {\n\t\tawait this._writer.close();\n\t}\n\n\tprivate async _read<T>(operation: string, select: (snapshot: FileSnapshotV2) => T): Promise<T> {\n\t\treturn await this._measure(\n\t\t\toperation,\n\t\t\tasync () =>\n\t\t\t\tawait this._writer.run(async (dataDir) => select(await this._loadSnapshot(dataDir)))\n\t\t);\n\t}\n\n\tprivate async _mutate(\n\t\toperation: string,\n\t\tmutate: (snapshot: FileSnapshotV2) => FileSnapshotV2\n\t): Promise<void> {\n\t\tawait this._measure(operation, async () => {\n\t\t\tawait this._writer.run(async (dataDir) => {\n\t\t\t\tconst snapshotPath = join(dataDir, SNAPSHOT_NAME);\n\t\t\t\tconst updated = mutate(await this._loadSnapshot(dataDir));\n\t\t\t\tawait this._writer.publish(snapshotPath, serializeFileSnapshotV2(updated, snapshotPath));\n\t\t\t});\n\t\t});\n\t}\n\n\tprivate async _loadSnapshot(dataDir: string): Promise<FileSnapshotV2> {\n\t\tconst snapshotPath = join(dataDir, SNAPSHOT_NAME);\n\t\tconst layoutEntries = (await readdir(dataDir)).filter(\n\t\t\t(entry) => entry !== FILE_WRITER_LOCK_NAME\n\t\t);\n\t\tif (layoutEntries.length === 0) return EMPTY_FILE_SNAPSHOT_V2;\n\t\tif (layoutEntries.length !== 1 || layoutEntries[0] !== SNAPSHOT_NAME) {\n\t\t\tthrow new PersistenceCompatibilityError(dataDir, 'directory does not match File v2 layout');\n\t\t}\n\t\treturn parseFileSnapshotV2(await readFile(snapshotPath, 'utf-8'), snapshotPath);\n\t}\n\n\tprivate async _measure<T>(operation: string, action: () => Promise<T>): Promise<T> {\n\t\tconst startTime = Date.now();\n\t\ttry {\n\t\t\treturn await action();\n\t\t} finally {\n\t\t\tthis._metrics?.histogram('persistence_op_duration_seconds', (Date.now() - startTime) / 1000, {\n\t\t\t\toperation,\n\t\t\t});\n\t\t}\n\t}\n}\n"],"names":["SNAPSHOT_NAME","FilePersistence","options","defaultDataDir","existsSync","join","homedir","FileWriter","persistence","dataDir","error","sessionId","thought","validatedSessionId","asSessionId","assertThoughtScope","targetThoughtId","snapshot","staged","stageBacktrackPersistence","record","branch","assertPersistableThoughts","current","prospective","assertPersistableThoughtCollections","retained","branchId","thoughts","validatedBranchId","parsePersistenceBranchId","assertBranchScope","undefined","compareCodePoint","sessionsInSnapshot","EMPTY_FILE_SNAPSHOT_V2","edges","assertEdgeScopes","summaries","assertSummaryScopes","Error","operation","select","mutate","snapshotPath","updated","serializeFileSnapshotV2","layoutEntries","readdir","entry","FILE_WRITER_LOCK_NAME","PersistenceCompatibilityError","parseFileSnapshotV2","readFile","action","startTime","Date"],"mappings":"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"}
|
|
@@ -7,6 +7,7 @@ export declare const FileSnapshotV2Schema: v.StrictObjectSchema<{
|
|
|
7
7
|
readonly thoughts: v.ArraySchema<v.StrictObjectSchema<{
|
|
8
8
|
readonly sessionId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, undefined>]>;
|
|
9
9
|
readonly thoughts: v.ArraySchema<v.ObjectSchema<{
|
|
10
|
+
readonly retracted: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
|
|
10
11
|
readonly available_mcp_tools: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.StringSchema<undefined>, undefined>, v.DescriptionAction<string[], "Array of MCP tool names available for use (e.g., [\"mcp-omnisearch\", \"mcp-turso-cloud\"])">]>, undefined>;
|
|
11
12
|
readonly available_skills: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.StringSchema<undefined>, undefined>, v.DescriptionAction<string[], "Array of skill names available for use (e.g., [\"commit\", \"review-pr\", \"pdf\"])">]>, undefined>;
|
|
12
13
|
readonly thought: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.DescriptionAction<string, "Your current thinking step">]>;
|
|
@@ -176,6 +177,7 @@ export declare const FileSnapshotV2Schema: v.StrictObjectSchema<{
|
|
|
176
177
|
readonly sessionId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, undefined>]>;
|
|
177
178
|
readonly branchId: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.RegexAction<string, undefined>]>;
|
|
178
179
|
readonly thoughts: v.ArraySchema<v.ObjectSchema<{
|
|
180
|
+
readonly retracted: v.OptionalSchema<v.BooleanSchema<undefined>, undefined>;
|
|
179
181
|
readonly available_mcp_tools: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.StringSchema<undefined>, undefined>, v.DescriptionAction<string[], "Array of MCP tool names available for use (e.g., [\"mcp-omnisearch\", \"mcp-turso-cloud\"])">]>, undefined>;
|
|
180
182
|
readonly available_skills: v.OptionalSchema<v.SchemaWithPipe<readonly [v.ArraySchema<v.StringSchema<undefined>, undefined>, v.DescriptionAction<string[], "Array of skill names available for use (e.g., [\"commit\", \"review-pr\", \"pdf\"])">]>, undefined>;
|
|
181
183
|
readonly thought: v.SchemaWithPipe<readonly [v.StringSchema<undefined>, v.DescriptionAction<string, "Your current thinking step">]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileSnapshotV2.d.ts","sourceRoot":"","sources":["../../src/persistence/FileSnapshotV2.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAC7B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAGrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAItD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"FileSnapshotV2.d.ts","sourceRoot":"","sources":["../../src/persistence/FileSnapshotV2.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAC;AAC7B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAGrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAItD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAgC7D,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aAM/B,CAAC;AAEH,eAAO,MAAM,sBAAsB,EAAE,cAMpC,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,cAAc,CAmCvF;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAuB5F;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,cAAc,GAAG,SAAS,EAAE,CAWxE;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,WAAW,GAAG,SAAS,CAEjE"}
|
|
@@ -8,14 +8,18 @@ import { validateFileSnapshotV2 } from "./FileSnapshotValidation.js";
|
|
|
8
8
|
import * as __rspack_external_valibot from "valibot";
|
|
9
9
|
const SessionIdStringSchema = __rspack_external_valibot.pipe(__rspack_external_valibot.string(), __rspack_external_valibot.regex(/^[A-Za-z0-9_-]{1,100}$/));
|
|
10
10
|
const BranchIdStringSchema = __rspack_external_valibot.pipe(__rspack_external_valibot.string(), __rspack_external_valibot.regex(/^[A-Za-z0-9_-]{1,50}$/));
|
|
11
|
+
const PersistedThoughtV2Schema = __rspack_external_valibot.object({
|
|
12
|
+
...SequentialThinkingSchema.entries,
|
|
13
|
+
retracted: __rspack_external_valibot.optional(__rspack_external_valibot.boolean())
|
|
14
|
+
});
|
|
11
15
|
const ThoughtSessionV2Schema = __rspack_external_valibot.strictObject({
|
|
12
16
|
sessionId: SessionIdStringSchema,
|
|
13
|
-
thoughts: __rspack_external_valibot.array(
|
|
17
|
+
thoughts: __rspack_external_valibot.array(PersistedThoughtV2Schema)
|
|
14
18
|
});
|
|
15
19
|
const BranchRecordV2Schema = __rspack_external_valibot.strictObject({
|
|
16
20
|
sessionId: SessionIdStringSchema,
|
|
17
21
|
branchId: BranchIdStringSchema,
|
|
18
|
-
thoughts: __rspack_external_valibot.array(
|
|
22
|
+
thoughts: __rspack_external_valibot.array(PersistedThoughtV2Schema)
|
|
19
23
|
});
|
|
20
24
|
const EdgeSessionV2Schema = __rspack_external_valibot.strictObject({
|
|
21
25
|
sessionId: SessionIdStringSchema,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"persistence/FileSnapshotV2.js","sources":["../../src/persistence/FileSnapshotV2.ts"],"sourcesContent":["import * as v from 'valibot';\nimport type { SessionId } from '../contracts/ids.js';\nimport { asSessionId } from '../contracts/ids.js';\nimport { SummarySchema } from '../core/compression/Summary.js';\nimport type { ThoughtData } from '../core/thought.js';\nimport { PersistenceCompatibilityError, PersistenceCorruptionError } from '../errors.js';\nimport { EdgeSchema, SequentialThinkingSchema } from '../schema.js';\nimport { parseEdge, parseSummary, parseThoughtData } from './PersistenceCodec.js';\nimport type { FileSnapshotV2 } from './FileSnapshotTypes.js';\nimport {\n\tcompareCodePoint,\n\tcompareCreatedThenId,\n\tparsePersistenceBranchId,\n} from './PersistenceScope.js';\nimport { validateFileSnapshotV2 } from './FileSnapshotValidation.js';\n\nconst SessionIdStringSchema = v.pipe(v.string(), v.regex(/^[A-Za-z0-9_-]{1,100}$/));\nconst BranchIdStringSchema = v.pipe(v.string(), v.regex(/^[A-Za-z0-9_-]{1,50}$/));\nconst ThoughtSessionV2Schema = v.strictObject({\n\tsessionId: SessionIdStringSchema,\n\tthoughts: v.array(
|
|
1
|
+
{"version":3,"file":"persistence/FileSnapshotV2.js","sources":["../../src/persistence/FileSnapshotV2.ts"],"sourcesContent":["import * as v from 'valibot';\nimport type { SessionId } from '../contracts/ids.js';\nimport { asSessionId } from '../contracts/ids.js';\nimport { SummarySchema } from '../core/compression/Summary.js';\nimport type { ThoughtData } from '../core/thought.js';\nimport { PersistenceCompatibilityError, PersistenceCorruptionError } from '../errors.js';\nimport { EdgeSchema, SequentialThinkingSchema } from '../schema.js';\nimport { parseEdge, parseSummary, parseThoughtData } from './PersistenceCodec.js';\nimport type { FileSnapshotV2 } from './FileSnapshotTypes.js';\nimport {\n\tcompareCodePoint,\n\tcompareCreatedThenId,\n\tparsePersistenceBranchId,\n} from './PersistenceScope.js';\nimport { validateFileSnapshotV2 } from './FileSnapshotValidation.js';\n\nconst SessionIdStringSchema = v.pipe(v.string(), v.regex(/^[A-Za-z0-9_-]{1,100}$/));\nconst BranchIdStringSchema = v.pipe(v.string(), v.regex(/^[A-Za-z0-9_-]{1,50}$/));\nconst PersistedThoughtV2Schema = v.object({\n\t...SequentialThinkingSchema.entries,\n\tretracted: v.optional(v.boolean()),\n});\nconst ThoughtSessionV2Schema = v.strictObject({\n\tsessionId: SessionIdStringSchema,\n\tthoughts: v.array(PersistedThoughtV2Schema),\n});\nconst BranchRecordV2Schema = v.strictObject({\n\tsessionId: SessionIdStringSchema,\n\tbranchId: BranchIdStringSchema,\n\tthoughts: v.array(PersistedThoughtV2Schema),\n});\nconst EdgeSessionV2Schema = v.strictObject({\n\tsessionId: SessionIdStringSchema,\n\tedges: v.array(EdgeSchema),\n});\nconst SummarySessionV2Schema = v.strictObject({\n\tsessionId: SessionIdStringSchema,\n\tsummaries: v.array(SummarySchema),\n});\n\nexport const FileSnapshotV2Schema = v.strictObject({\n\tversion: v.literal(2),\n\tthoughts: v.array(ThoughtSessionV2Schema),\n\tbranches: v.array(BranchRecordV2Schema),\n\tedges: v.array(EdgeSessionV2Schema),\n\tsummaries: v.array(SummarySessionV2Schema),\n});\n\nexport const EMPTY_FILE_SNAPSHOT_V2: FileSnapshotV2 = {\n\tversion: 2,\n\tthoughts: [],\n\tbranches: [],\n\tedges: [],\n\tsummaries: [],\n};\n\nexport function parseFileSnapshotV2(content: string, sourcePath: string): FileSnapshotV2 {\n\tlet raw: unknown;\n\ttry {\n\t\traw = JSON.parse(content);\n\t} catch (error) {\n\t\tthrow new PersistenceCorruptionError(sourcePath, error);\n\t}\n\ttry {\n\t\tconst parsed = v.parse(FileSnapshotV2Schema, raw);\n\t\tconst snapshot: FileSnapshotV2 = {\n\t\t\tversion: 2,\n\t\t\tthoughts: parsed.thoughts.map((record) => ({\n\t\t\t\tsessionId: asSessionId(record.sessionId),\n\t\t\t\tthoughts: record.thoughts.map((thought) => parseThoughtData(thought, sourcePath)),\n\t\t\t})),\n\t\t\tbranches: parsed.branches.map((record) => ({\n\t\t\t\tsessionId: asSessionId(record.sessionId),\n\t\t\t\tbranchId: parsePersistenceBranchId(record.branchId, sourcePath),\n\t\t\t\tthoughts: record.thoughts.map((thought) => parseThoughtData(thought, sourcePath)),\n\t\t\t})),\n\t\t\tedges: parsed.edges.map((record) => ({\n\t\t\t\tsessionId: asSessionId(record.sessionId),\n\t\t\t\tedges: record.edges.map(parseEdge),\n\t\t\t})),\n\t\t\tsummaries: parsed.summaries.map((record) => ({\n\t\t\t\tsessionId: asSessionId(record.sessionId),\n\t\t\t\tsummaries: record.summaries.map((summary) => parseSummary(summary, sourcePath)),\n\t\t\t})),\n\t\t};\n\t\tvalidateFileSnapshotV2(snapshot, sourcePath);\n\t\treturn snapshot;\n\t} catch (error) {\n\t\tif (error instanceof PersistenceCompatibilityError) throw error;\n\t\tthrow new PersistenceCompatibilityError(sourcePath, 'document does not match File v2', error);\n\t}\n}\n\nexport function serializeFileSnapshotV2(snapshot: FileSnapshotV2, sourcePath: string): string {\n\tconst canonical: FileSnapshotV2 = {\n\t\tversion: 2,\n\t\tthoughts: [...snapshot.thoughts].sort((left, right) =>\n\t\t\tcompareCodePoint(left.sessionId, right.sessionId)\n\t\t),\n\t\tbranches: [...snapshot.branches].sort(\n\t\t\t(left, right) =>\n\t\t\t\tcompareCodePoint(left.sessionId, right.sessionId) ||\n\t\t\t\tcompareCodePoint(left.branchId, right.branchId)\n\t\t),\n\t\tedges: [...snapshot.edges]\n\t\t\t.sort((left, right) => compareCodePoint(left.sessionId, right.sessionId))\n\t\t\t.map((record) => ({ ...record, edges: [...record.edges].sort(compareCreatedThenId) })),\n\t\tsummaries: [...snapshot.summaries]\n\t\t\t.sort((left, right) => compareCodePoint(left.sessionId, right.sessionId))\n\t\t\t.map((record) => ({\n\t\t\t\t...record,\n\t\t\t\tsummaries: [...record.summaries].sort(compareCreatedThenId),\n\t\t\t})),\n\t};\n\tvalidateFileSnapshotV2(canonical, sourcePath);\n\treturn `${JSON.stringify(canonical, null, 2)}\\n`;\n}\n\nexport function sessionsInSnapshot(snapshot: FileSnapshotV2): SessionId[] {\n\tconst sessions = new Set<SessionId>();\n\tfor (const records of [\n\t\tsnapshot.thoughts,\n\t\tsnapshot.branches,\n\t\tsnapshot.edges,\n\t\tsnapshot.summaries,\n\t]) {\n\t\tfor (const record of records) sessions.add(record.sessionId);\n\t}\n\treturn [...sessions].sort(compareCodePoint);\n}\n\nexport function sessionForThought(thought: ThoughtData): SessionId {\n\treturn asSessionId(thought.session_id);\n}\n"],"names":["SessionIdStringSchema","v","BranchIdStringSchema","PersistedThoughtV2Schema","SequentialThinkingSchema","ThoughtSessionV2Schema","BranchRecordV2Schema","EdgeSessionV2Schema","EdgeSchema","SummarySessionV2Schema","SummarySchema","FileSnapshotV2Schema","EMPTY_FILE_SNAPSHOT_V2","parseFileSnapshotV2","content","sourcePath","raw","JSON","error","PersistenceCorruptionError","parsed","snapshot","record","asSessionId","thought","parseThoughtData","parsePersistenceBranchId","parseEdge","summary","parseSummary","validateFileSnapshotV2","PersistenceCompatibilityError","serializeFileSnapshotV2","canonical","left","right","compareCodePoint","compareCreatedThenId","sessionsInSnapshot","sessions","Set","records","sessionForThought"],"mappings":"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"}
|
|
@@ -2,7 +2,7 @@ import type { ThoughtData } from '../core/thought.js';
|
|
|
2
2
|
import type { Edge } from '../core/graph/Edge.js';
|
|
3
3
|
import type { Summary } from '../core/compression/Summary.js';
|
|
4
4
|
import type { PersistenceBackend } from '../contracts/PersistenceBackend.js';
|
|
5
|
-
import { type BranchId, type SessionId } from '../contracts/ids.js';
|
|
5
|
+
import { type BranchId, type SessionId, type ThoughtId } from '../contracts/ids.js';
|
|
6
6
|
export interface MemoryPersistenceOptions {
|
|
7
7
|
maxSize?: number;
|
|
8
8
|
maxHistorySize?: number;
|
|
@@ -17,6 +17,7 @@ export declare class MemoryPersistence implements PersistenceBackend {
|
|
|
17
17
|
private readonly _persistBranches;
|
|
18
18
|
constructor(options?: MemoryPersistenceOptions);
|
|
19
19
|
saveThoughtForSession(sessionId: SessionId, thought: ThoughtData): Promise<void>;
|
|
20
|
+
saveBacktrackForSession(sessionId: SessionId, thought: ThoughtData, targetThoughtId: ThoughtId): Promise<void>;
|
|
20
21
|
loadHistoryForSession(sessionId: SessionId): Promise<ThoughtData[]>;
|
|
21
22
|
saveBranchForSession(sessionId: SessionId, branchId: BranchId, thoughts: readonly ThoughtData[]): Promise<void>;
|
|
22
23
|
deleteBranchForSession(sessionId: SessionId, branchId: BranchId): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MemoryPersistence.d.ts","sourceRoot":"","sources":["../../src/persistence/MemoryPersistence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,OAAO,EAAe,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"MemoryPersistence.d.ts","sourceRoot":"","sources":["../../src/persistence/MemoryPersistence.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,OAAO,EAAe,KAAK,QAAQ,EAAE,KAAK,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAejG,MAAM,WAAW,wBAAwB;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,qBAAa,iBAAkB,YAAW,kBAAkB;IAC3D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAuC;IAClE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsD;IAChF,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgC;IACvD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAmC;IAC9D,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAqB;IAC9C,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAU;gBAE/B,OAAO,GAAE,wBAA6B;IAOrC,qBAAqB,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBhF,uBAAuB,CACnC,SAAS,EAAE,SAAS,EACpB,OAAO,EAAE,WAAW,EACpB,eAAe,EAAE,SAAS,GACxB,OAAO,CAAC,IAAI,CAAC;IAoBH,qBAAqB,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAInE,oBAAoB,CAChC,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,SAAS,WAAW,EAAE,GAC9B,OAAO,CAAC,IAAI,CAAC;IAuBH,sBAAsB,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAU/E,oBAAoB,CAChC,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,QAAQ,GAChB,OAAO,CAAC,WAAW,EAAE,GAAG,SAAS,CAAC;IAQxB,sBAAsB,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC;IAKjE,YAAY,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;IAQpC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC;IAI3B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAOzB,YAAY,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC;IAQjD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAEtB,SAAS,CAAC,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE,SAAS,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAQtE,SAAS,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAIhD,aAAa,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAQjF,aAAa,CAAC,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;CAGpE"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { asSessionId } from "../contracts/ids.js";
|
|
2
|
+
import { stageBacktrackPersistence } from "./BacktrackPersistence.js";
|
|
2
3
|
import { assertBranchScope, assertEdgeScopes, assertPersistableThoughtCollections, assertSummaryScopes, assertThoughtScope, assertUniqueRecordIds, compareCodePoint, compareCreatedThenId, parsePersistenceBranchId } from "./PersistenceScope.js";
|
|
3
4
|
class MemoryPersistence {
|
|
4
5
|
_histories = new Map();
|
|
@@ -9,7 +10,7 @@ class MemoryPersistence {
|
|
|
9
10
|
_persistBranches;
|
|
10
11
|
constructor(options = {}){
|
|
11
12
|
const configuredSize = options.maxHistorySize ?? options.maxSize;
|
|
12
|
-
this._maxSize = void 0
|
|
13
|
+
this._maxSize = void 0 === configuredSize ? 10000 : configuredSize > 0 ? configuredSize : void 0;
|
|
13
14
|
this._persistBranches = options.persistBranches ?? true;
|
|
14
15
|
}
|
|
15
16
|
async saveThoughtForSession(sessionId, thought) {
|
|
@@ -32,6 +33,25 @@ class MemoryPersistence {
|
|
|
32
33
|
assertPersistableThoughtCollections(collections, `${validatedSessionId}/thoughts`);
|
|
33
34
|
this._histories.set(validatedSessionId, void 0 === this._maxSize ? history : history.slice(-this._maxSize));
|
|
34
35
|
}
|
|
36
|
+
async saveBacktrackForSession(sessionId, thought, targetThoughtId) {
|
|
37
|
+
const validatedSessionId = asSessionId(sessionId);
|
|
38
|
+
const branches = this._branches.get(validatedSessionId) ?? new Map();
|
|
39
|
+
const staged = stageBacktrackPersistence(validatedSessionId, this._histories.get(validatedSessionId) ?? [], [
|
|
40
|
+
...branches
|
|
41
|
+
].map(([branchId, thoughts])=>({
|
|
42
|
+
branchId,
|
|
43
|
+
thoughts
|
|
44
|
+
})), thought, targetThoughtId, this._maxSize ?? 0);
|
|
45
|
+
this._histories.set(validatedSessionId, [
|
|
46
|
+
...staged.history
|
|
47
|
+
]);
|
|
48
|
+
if (this._persistBranches) this._branches.set(validatedSessionId, new Map(staged.branches.map((branch)=>[
|
|
49
|
+
branch.branchId,
|
|
50
|
+
[
|
|
51
|
+
...branch.thoughts
|
|
52
|
+
]
|
|
53
|
+
])));
|
|
54
|
+
}
|
|
35
55
|
async loadHistoryForSession(sessionId) {
|
|
36
56
|
return [
|
|
37
57
|
...this._histories.get(asSessionId(sessionId)) ?? []
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"persistence/MemoryPersistence.js","sources":["../../src/persistence/MemoryPersistence.ts"],"sourcesContent":["import type { ThoughtData } from '../core/thought.js';\nimport type { Edge } from '../core/graph/Edge.js';\nimport type { Summary } from '../core/compression/Summary.js';\nimport type { PersistenceBackend } from '../contracts/PersistenceBackend.js';\nimport { asSessionId, type BranchId, type SessionId } from '../contracts/ids.js';\nimport {\n\tassertBranchScope,\n\tassertEdgeScopes,\n\tassertPersistableThoughtCollections,\n\tassertSummaryScopes,\n\tassertThoughtScope,\n\tassertUniqueRecordIds,\n\tcompareCodePoint,\n\tcompareCreatedThenId,\n\tparsePersistenceBranchId,\n\ttype PersistedThoughtCollection,\n} from './PersistenceScope.js';\n\nexport interface MemoryPersistenceOptions {\n\tmaxSize?: number;\n\tmaxHistorySize?: number;\n\tpersistBranches?: boolean;\n}\n\nexport class MemoryPersistence implements PersistenceBackend {\n\tprivate readonly _histories = new Map<SessionId, ThoughtData[]>();\n\tprivate readonly _branches = new Map<SessionId, Map<BranchId, ThoughtData[]>>();\n\tprivate readonly _edges = new Map<SessionId, Edge[]>();\n\tprivate readonly _summaries = new Map<SessionId, Summary[]>();\n\tprivate readonly _maxSize: number | undefined;\n\tprivate readonly _persistBranches: boolean;\n\n\tconstructor(options: MemoryPersistenceOptions = {}) {\n\t\tconst configuredSize = options.maxHistorySize ?? options.maxSize;\n\t\tthis._maxSize = configuredSize !== undefined && configuredSize > 0 ? configuredSize : undefined;\n\t\tthis._persistBranches = options.persistBranches ?? true;\n\t}\n\n\tpublic async saveThoughtForSession(sessionId: SessionId, thought: ThoughtData): Promise<void> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tassertThoughtScope('saveThoughtForSession', validatedSessionId, thought);\n\t\tconst history = [...(this._histories.get(validatedSessionId) ?? []), thought];\n\t\tconst collections: PersistedThoughtCollection[] = [\n\t\t\t{ sessionId: validatedSessionId, thoughts: history },\n\t\t];\n\t\tfor (const branch of this._branches.get(validatedSessionId)?.values() ?? []) {\n\t\t\tcollections.push({ sessionId: validatedSessionId, thoughts: branch });\n\t\t}\n\t\tassertPersistableThoughtCollections(collections, `${validatedSessionId}/thoughts`);\n\t\tthis._histories.set(\n\t\t\tvalidatedSessionId,\n\t\t\tthis._maxSize === undefined ? history : history.slice(-this._maxSize)\n\t\t);\n\t}\n\n\tpublic async loadHistoryForSession(sessionId: SessionId): Promise<ThoughtData[]> {\n\t\treturn [...(this._histories.get(asSessionId(sessionId)) ?? [])];\n\t}\n\n\tpublic async saveBranchForSession(\n\t\tsessionId: SessionId,\n\t\tbranchId: BranchId,\n\t\tthoughts: readonly ThoughtData[]\n\t): Promise<void> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tconst validatedBranchId = parsePersistenceBranchId(branchId, `${validatedSessionId}/branches`);\n\t\tassertBranchScope('saveBranchForSession', validatedSessionId, validatedBranchId, thoughts);\n\t\tconst branches = new Map(this._branches.get(validatedSessionId) ?? []);\n\t\tbranches.set(validatedBranchId, [...thoughts]);\n\t\tconst collections: PersistedThoughtCollection[] = [\n\t\t\t{\n\t\t\t\tsessionId: validatedSessionId,\n\t\t\t\tthoughts: this._histories.get(validatedSessionId) ?? [],\n\t\t\t},\n\t\t];\n\t\tfor (const branch of branches.values()) {\n\t\t\tcollections.push({ sessionId: validatedSessionId, thoughts: branch });\n\t\t}\n\t\tassertPersistableThoughtCollections(\n\t\t\tcollections,\n\t\t\t`${validatedSessionId}/branches/${validatedBranchId}`\n\t\t);\n\t\tif (!this._persistBranches) return;\n\t\tthis._branches.set(validatedSessionId, branches);\n\t}\n\n\tpublic async deleteBranchForSession(sessionId: SessionId, branchId: BranchId): Promise<void> {\n\t\tif (!this._persistBranches) return;\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tconst validatedBranchId = parsePersistenceBranchId(branchId, `${validatedSessionId}/branches`);\n\t\tconst branches = this._branches.get(validatedSessionId);\n\t\tif (branches === undefined) return;\n\t\tbranches.delete(validatedBranchId);\n\t\tif (branches.size === 0) this._branches.delete(validatedSessionId);\n\t}\n\n\tpublic async loadBranchForSession(\n\t\tsessionId: SessionId,\n\t\tbranchId: BranchId\n\t): Promise<ThoughtData[] | undefined> {\n\t\tif (!this._persistBranches) return undefined;\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tconst validatedBranchId = parsePersistenceBranchId(branchId, `${validatedSessionId}/branches`);\n\t\tconst branch = this._branches.get(validatedSessionId)?.get(validatedBranchId);\n\t\treturn branch === undefined ? undefined : [...branch];\n\t}\n\n\tpublic async listBranchesForSession(sessionId: SessionId): Promise<BranchId[]> {\n\t\tif (!this._persistBranches) return [];\n\t\treturn [...(this._branches.get(asSessionId(sessionId))?.keys() ?? [])].sort(compareCodePoint);\n\t}\n\n\tpublic async listSessions(): Promise<SessionId[]> {\n\t\tconst sessions = new Set<SessionId>();\n\t\tfor (const namespace of [this._histories, this._branches, this._edges, this._summaries]) {\n\t\t\tfor (const sessionId of namespace.keys()) sessions.add(sessionId);\n\t\t}\n\t\treturn [...sessions].sort(compareCodePoint);\n\t}\n\n\tpublic async healthy(): Promise<boolean> {\n\t\treturn true;\n\t}\n\n\tpublic async clearAll(): Promise<void> {\n\t\tthis._histories.clear();\n\t\tthis._branches.clear();\n\t\tthis._edges.clear();\n\t\tthis._summaries.clear();\n\t}\n\n\tpublic async clearSession(sessionId: SessionId): Promise<void> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tthis._histories.delete(validatedSessionId);\n\t\tthis._branches.delete(validatedSessionId);\n\t\tthis._edges.delete(validatedSessionId);\n\t\tthis._summaries.delete(validatedSessionId);\n\t}\n\n\tpublic async close(): Promise<void> {}\n\n\tpublic async saveEdges(sessionId: SessionId, edges: readonly Edge[]): Promise<void> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tassertEdgeScopes(validatedSessionId, edges);\n\t\tassertUniqueRecordIds(edges, `${validatedSessionId}/edges`, 'edge');\n\t\tif (edges.length === 0) this._edges.delete(validatedSessionId);\n\t\telse this._edges.set(validatedSessionId, [...edges].sort(compareCreatedThenId));\n\t}\n\n\tpublic async loadEdges(sessionId: SessionId): Promise<Edge[]> {\n\t\treturn [...(this._edges.get(asSessionId(sessionId)) ?? [])].sort(compareCreatedThenId);\n\t}\n\n\tpublic async saveSummaries(sessionId: SessionId, summaries: readonly Summary[]): Promise<void> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tassertSummaryScopes(validatedSessionId, summaries);\n\t\tassertUniqueRecordIds(summaries, `${validatedSessionId}/summaries`, 'summary');\n\t\tif (summaries.length === 0) this._summaries.delete(validatedSessionId);\n\t\telse this._summaries.set(validatedSessionId, [...summaries].sort(compareCreatedThenId));\n\t}\n\n\tpublic async loadSummaries(sessionId: SessionId): Promise<Summary[]> {\n\t\treturn [...(this._summaries.get(asSessionId(sessionId)) ?? [])].sort(compareCreatedThenId);\n\t}\n\n}\n"],"names":["MemoryPersistence","Map","options","configuredSize","undefined","sessionId","thought","validatedSessionId","asSessionId","assertThoughtScope","history","collections","branch","assertPersistableThoughtCollections","branchId","thoughts","validatedBranchId","parsePersistenceBranchId","assertBranchScope","branches","compareCodePoint","sessions","Set","namespace","edges","assertEdgeScopes","assertUniqueRecordIds","compareCreatedThenId","summaries","assertSummaryScopes"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"persistence/MemoryPersistence.js","sources":["../../src/persistence/MemoryPersistence.ts"],"sourcesContent":["import type { ThoughtData } from '../core/thought.js';\nimport type { Edge } from '../core/graph/Edge.js';\nimport type { Summary } from '../core/compression/Summary.js';\nimport type { PersistenceBackend } from '../contracts/PersistenceBackend.js';\nimport { asSessionId, type BranchId, type SessionId, type ThoughtId } from '../contracts/ids.js';\nimport { stageBacktrackPersistence } from './BacktrackPersistence.js';\nimport {\n\tassertBranchScope,\n\tassertEdgeScopes,\n\tassertPersistableThoughtCollections,\n\tassertSummaryScopes,\n\tassertThoughtScope,\n\tassertUniqueRecordIds,\n\tcompareCodePoint,\n\tcompareCreatedThenId,\n\tparsePersistenceBranchId,\n\ttype PersistedThoughtCollection,\n} from './PersistenceScope.js';\n\nexport interface MemoryPersistenceOptions {\n\tmaxSize?: number;\n\tmaxHistorySize?: number;\n\tpersistBranches?: boolean;\n}\n\nexport class MemoryPersistence implements PersistenceBackend {\n\tprivate readonly _histories = new Map<SessionId, ThoughtData[]>();\n\tprivate readonly _branches = new Map<SessionId, Map<BranchId, ThoughtData[]>>();\n\tprivate readonly _edges = new Map<SessionId, Edge[]>();\n\tprivate readonly _summaries = new Map<SessionId, Summary[]>();\n\tprivate readonly _maxSize: number | undefined;\n\tprivate readonly _persistBranches: boolean;\n\n\tconstructor(options: MemoryPersistenceOptions = {}) {\n\t\tconst configuredSize = options.maxHistorySize ?? options.maxSize;\n\t\tthis._maxSize =\n\t\t\tconfiguredSize === undefined ? 10_000 : configuredSize > 0 ? configuredSize : undefined;\n\t\tthis._persistBranches = options.persistBranches ?? true;\n\t}\n\n\tpublic async saveThoughtForSession(sessionId: SessionId, thought: ThoughtData): Promise<void> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tassertThoughtScope('saveThoughtForSession', validatedSessionId, thought);\n\t\tconst history = [...(this._histories.get(validatedSessionId) ?? []), thought];\n\t\tconst collections: PersistedThoughtCollection[] = [\n\t\t\t{ sessionId: validatedSessionId, thoughts: history },\n\t\t];\n\t\tfor (const branch of this._branches.get(validatedSessionId)?.values() ?? []) {\n\t\t\tcollections.push({ sessionId: validatedSessionId, thoughts: branch });\n\t\t}\n\t\tassertPersistableThoughtCollections(collections, `${validatedSessionId}/thoughts`);\n\t\tthis._histories.set(\n\t\t\tvalidatedSessionId,\n\t\t\tthis._maxSize === undefined ? history : history.slice(-this._maxSize)\n\t\t);\n\t}\n\n\tpublic async saveBacktrackForSession(\n\t\tsessionId: SessionId,\n\t\tthought: ThoughtData,\n\t\ttargetThoughtId: ThoughtId\n\t): Promise<void> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tconst branches = this._branches.get(validatedSessionId) ?? new Map();\n\t\tconst staged = stageBacktrackPersistence(\n\t\t\tvalidatedSessionId,\n\t\t\tthis._histories.get(validatedSessionId) ?? [],\n\t\t\t[...branches].map(([branchId, thoughts]) => ({ branchId, thoughts })),\n\t\t\tthought,\n\t\t\ttargetThoughtId,\n\t\t\tthis._maxSize ?? 0\n\t\t);\n\t\tthis._histories.set(validatedSessionId, [...staged.history]);\n\t\tif (this._persistBranches) {\n\t\t\tthis._branches.set(\n\t\t\t\tvalidatedSessionId,\n\t\t\t\tnew Map(staged.branches.map((branch) => [branch.branchId, [...branch.thoughts]]))\n\t\t\t);\n\t\t}\n\t}\n\n\tpublic async loadHistoryForSession(sessionId: SessionId): Promise<ThoughtData[]> {\n\t\treturn [...(this._histories.get(asSessionId(sessionId)) ?? [])];\n\t}\n\n\tpublic async saveBranchForSession(\n\t\tsessionId: SessionId,\n\t\tbranchId: BranchId,\n\t\tthoughts: readonly ThoughtData[]\n\t): Promise<void> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tconst validatedBranchId = parsePersistenceBranchId(branchId, `${validatedSessionId}/branches`);\n\t\tassertBranchScope('saveBranchForSession', validatedSessionId, validatedBranchId, thoughts);\n\t\tconst branches = new Map(this._branches.get(validatedSessionId) ?? []);\n\t\tbranches.set(validatedBranchId, [...thoughts]);\n\t\tconst collections: PersistedThoughtCollection[] = [\n\t\t\t{\n\t\t\t\tsessionId: validatedSessionId,\n\t\t\t\tthoughts: this._histories.get(validatedSessionId) ?? [],\n\t\t\t},\n\t\t];\n\t\tfor (const branch of branches.values()) {\n\t\t\tcollections.push({ sessionId: validatedSessionId, thoughts: branch });\n\t\t}\n\t\tassertPersistableThoughtCollections(\n\t\t\tcollections,\n\t\t\t`${validatedSessionId}/branches/${validatedBranchId}`\n\t\t);\n\t\tif (!this._persistBranches) return;\n\t\tthis._branches.set(validatedSessionId, branches);\n\t}\n\n\tpublic async deleteBranchForSession(sessionId: SessionId, branchId: BranchId): Promise<void> {\n\t\tif (!this._persistBranches) return;\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tconst validatedBranchId = parsePersistenceBranchId(branchId, `${validatedSessionId}/branches`);\n\t\tconst branches = this._branches.get(validatedSessionId);\n\t\tif (branches === undefined) return;\n\t\tbranches.delete(validatedBranchId);\n\t\tif (branches.size === 0) this._branches.delete(validatedSessionId);\n\t}\n\n\tpublic async loadBranchForSession(\n\t\tsessionId: SessionId,\n\t\tbranchId: BranchId\n\t): Promise<ThoughtData[] | undefined> {\n\t\tif (!this._persistBranches) return undefined;\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tconst validatedBranchId = parsePersistenceBranchId(branchId, `${validatedSessionId}/branches`);\n\t\tconst branch = this._branches.get(validatedSessionId)?.get(validatedBranchId);\n\t\treturn branch === undefined ? undefined : [...branch];\n\t}\n\n\tpublic async listBranchesForSession(sessionId: SessionId): Promise<BranchId[]> {\n\t\tif (!this._persistBranches) return [];\n\t\treturn [...(this._branches.get(asSessionId(sessionId))?.keys() ?? [])].sort(compareCodePoint);\n\t}\n\n\tpublic async listSessions(): Promise<SessionId[]> {\n\t\tconst sessions = new Set<SessionId>();\n\t\tfor (const namespace of [this._histories, this._branches, this._edges, this._summaries]) {\n\t\t\tfor (const sessionId of namespace.keys()) sessions.add(sessionId);\n\t\t}\n\t\treturn [...sessions].sort(compareCodePoint);\n\t}\n\n\tpublic async healthy(): Promise<boolean> {\n\t\treturn true;\n\t}\n\n\tpublic async clearAll(): Promise<void> {\n\t\tthis._histories.clear();\n\t\tthis._branches.clear();\n\t\tthis._edges.clear();\n\t\tthis._summaries.clear();\n\t}\n\n\tpublic async clearSession(sessionId: SessionId): Promise<void> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tthis._histories.delete(validatedSessionId);\n\t\tthis._branches.delete(validatedSessionId);\n\t\tthis._edges.delete(validatedSessionId);\n\t\tthis._summaries.delete(validatedSessionId);\n\t}\n\n\tpublic async close(): Promise<void> {}\n\n\tpublic async saveEdges(sessionId: SessionId, edges: readonly Edge[]): Promise<void> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tassertEdgeScopes(validatedSessionId, edges);\n\t\tassertUniqueRecordIds(edges, `${validatedSessionId}/edges`, 'edge');\n\t\tif (edges.length === 0) this._edges.delete(validatedSessionId);\n\t\telse this._edges.set(validatedSessionId, [...edges].sort(compareCreatedThenId));\n\t}\n\n\tpublic async loadEdges(sessionId: SessionId): Promise<Edge[]> {\n\t\treturn [...(this._edges.get(asSessionId(sessionId)) ?? [])].sort(compareCreatedThenId);\n\t}\n\n\tpublic async saveSummaries(sessionId: SessionId, summaries: readonly Summary[]): Promise<void> {\n\t\tconst validatedSessionId = asSessionId(sessionId);\n\t\tassertSummaryScopes(validatedSessionId, summaries);\n\t\tassertUniqueRecordIds(summaries, `${validatedSessionId}/summaries`, 'summary');\n\t\tif (summaries.length === 0) this._summaries.delete(validatedSessionId);\n\t\telse this._summaries.set(validatedSessionId, [...summaries].sort(compareCreatedThenId));\n\t}\n\n\tpublic async loadSummaries(sessionId: SessionId): Promise<Summary[]> {\n\t\treturn [...(this._summaries.get(asSessionId(sessionId)) ?? [])].sort(compareCreatedThenId);\n\t}\n}\n"],"names":["MemoryPersistence","Map","options","configuredSize","undefined","sessionId","thought","validatedSessionId","asSessionId","assertThoughtScope","history","collections","branch","assertPersistableThoughtCollections","targetThoughtId","branches","staged","stageBacktrackPersistence","branchId","thoughts","validatedBranchId","parsePersistenceBranchId","assertBranchScope","compareCodePoint","sessions","Set","namespace","edges","assertEdgeScopes","assertUniqueRecordIds","compareCreatedThenId","summaries","assertSummaryScopes"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PersistenceCodec.d.ts","sourceRoot":"","sources":["../../src/persistence/PersistenceCodec.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAE9D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AA2FtD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,WAAW,
|
|
1
|
+
{"version":3,"file":"PersistenceCodec.d.ts","sourceRoot":"","sources":["../../src/persistence/PersistenceCodec.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAE9D,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AA2FtD,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,WAAW,CA0C9E;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAS5C;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAkBtE"}
|
|
@@ -36,6 +36,8 @@ function parseStepRecommendation(step, sourcePath) {
|
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
38
|
function parseThoughtData(raw, sourcePath) {
|
|
39
|
+
const retracted = 'object' == typeof raw && null !== raw && 'retracted' in raw ? Reflect.get(raw, 'retracted') : void 0;
|
|
40
|
+
if (void 0 !== retracted && 'boolean' != typeof retracted) throw new PersistenceCompatibilityError(sourcePath, 'thought retracted flag is not boolean');
|
|
39
41
|
const parsed = __rspack_external_valibot.parse(SequentialThinkingSchema, raw);
|
|
40
42
|
const { id, session_id, branch_id, merge_branch_ids, continuation_token, current_step, previous_steps, ...thought } = parsed;
|
|
41
43
|
return {
|
|
@@ -58,6 +60,9 @@ function parseThoughtData(raw, sourcePath) {
|
|
|
58
60
|
},
|
|
59
61
|
...void 0 === previous_steps ? {} : {
|
|
60
62
|
previous_steps: previous_steps.map((step)=>parseStepRecommendation(step, sourcePath))
|
|
63
|
+
},
|
|
64
|
+
...void 0 === retracted ? {} : {
|
|
65
|
+
retracted
|
|
61
66
|
}
|
|
62
67
|
};
|
|
63
68
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"persistence/PersistenceCodec.js","sources":["../../src/persistence/PersistenceCodec.ts"],"sourcesContent":["import * as v from 'valibot';\nimport {\n\tasBranchId,\n\tasEdgeId,\n\tasSessionId,\n\tasSuspensionToken,\n\tasThoughtId,\n} from '../contracts/ids.js';\nimport type { Summary } from '../core/compression/Summary.js';\nimport { SummarySchema } from '../core/compression/Summary.js';\nimport type { Edge } from '../core/graph/Edge.js';\nimport type { ThoughtData } from '../core/thought.js';\nimport type { StepRecommendation } from '../core/step.js';\nimport { EdgeSchema, SequentialThinkingSchema } from '../schema.js';\nimport { PersistenceCompatibilityError } from '../errors.js';\nimport { parsePersistenceBranchId } from './PersistenceScope.js';\n\ntype PersistedToolRecommendation = {\n\treadonly tool_name: string;\n\treadonly confidence?: number;\n\treadonly rationale?: string;\n\treadonly priority?: number;\n\treadonly suggested_inputs?: Record<string, string | number | boolean | null>;\n\treadonly alternatives?: string[];\n};\n\ntype PersistedSkillRecommendation = {\n\treadonly skill_name: string;\n\treadonly confidence?: number;\n\treadonly rationale?: string;\n\treadonly priority?: number;\n\treadonly alternatives?: string[];\n\treadonly allowed_tools?: string[];\n\treadonly user_invocable?: boolean;\n};\n\ntype PersistedStepRecommendation = {\n\treadonly step_description?: string;\n\treadonly recommended_tools: readonly PersistedToolRecommendation[];\n\treadonly recommended_skills?: readonly PersistedSkillRecommendation[];\n\treadonly expected_outcome?: string;\n\treadonly next_step_conditions?: string[];\n};\n\nfunction parseToolRecommendation(recommendation: PersistedToolRecommendation, sourcePath: string) {\n\tif (\n\t\trecommendation.confidence === undefined ||\n\t\trecommendation.rationale === undefined ||\n\t\trecommendation.priority === undefined\n\t) {\n\t\tthrow new PersistenceCompatibilityError(sourcePath, 'tool recommendation defaults are absent');\n\t}\n\treturn {\n\t\t...recommendation,\n\t\tconfidence: recommendation.confidence,\n\t\trationale: recommendation.rationale,\n\t\tpriority: recommendation.priority,\n\t};\n}\n\nfunction parseSkillRecommendation(\n\trecommendation: PersistedSkillRecommendation,\n\tsourcePath: string\n) {\n\tif (\n\t\trecommendation.confidence === undefined ||\n\t\trecommendation.rationale === undefined ||\n\t\trecommendation.priority === undefined\n\t) {\n\t\tthrow new PersistenceCompatibilityError(sourcePath, 'skill recommendation defaults are absent');\n\t}\n\treturn {\n\t\t...recommendation,\n\t\tconfidence: recommendation.confidence,\n\t\trationale: recommendation.rationale,\n\t\tpriority: recommendation.priority,\n\t};\n}\n\nfunction parseStepRecommendation(\n\tstep: PersistedStepRecommendation,\n\tsourcePath: string\n): StepRecommendation {\n\tif (step.step_description === undefined || step.expected_outcome === undefined) {\n\t\tthrow new PersistenceCompatibilityError(sourcePath, 'step recommendation defaults are absent');\n\t}\n\tconst { recommended_tools, recommended_skills, ...fields } = step;\n\treturn {\n\t\t...fields,\n\t\tstep_description: step.step_description,\n\t\texpected_outcome: step.expected_outcome,\n\t\trecommended_tools: recommended_tools.map((tool) => parseToolRecommendation(tool, sourcePath)),\n\t\t...(recommended_skills === undefined\n\t\t\t? {}\n\t\t\t: {\n\t\t\t\t\trecommended_skills: recommended_skills.map((skill) =>\n\t\t\t\t\t\tparseSkillRecommendation(skill, sourcePath)\n\t\t\t\t\t),\n\t\t\t\t}),\n\t};\n}\n\nexport function parseThoughtData(raw: unknown, sourcePath: string): ThoughtData {\n\tconst parsed = v.parse(SequentialThinkingSchema, raw);\n\tconst {\n\t\tid,\n\t\tsession_id,\n\t\tbranch_id,\n\t\tmerge_branch_ids,\n\t\tcontinuation_token,\n\t\tcurrent_step,\n\t\tprevious_steps,\n\t\t...thought\n\t} = parsed;\n\treturn {\n\t\t...thought,\n\t\t...(id === undefined ? {} : { id: asThoughtId(id) }),\n\t\tsession_id: asSessionId(session_id),\n\t\t...(branch_id === undefined\n\t\t\t? {}\n\t\t\t: { branch_id: parsePersistenceBranchId(branch_id, sourcePath) }),\n\t\t...(merge_branch_ids === undefined\n\t\t\t? {}\n\t\t\t: { merge_branch_ids: merge_branch_ids.map(asBranchId) }),\n\t\t...(continuation_token === undefined\n\t\t\t? {}\n\t\t\t: { continuation_token: asSuspensionToken(continuation_token) }),\n\t\t...(current_step === undefined\n\t\t\t? {}\n\t\t\t: { current_step: parseStepRecommendation(current_step, sourcePath) }),\n\t\t...(previous_steps === undefined\n\t\t\t? {}\n\t\t\t: {\n\t\t\t\t\tprevious_steps: previous_steps.map((step) => parseStepRecommendation(step, sourcePath)),\n\t\t\t\t}),\n\t};\n}\n\nexport function parseEdge(raw: unknown): Edge {\n\tconst parsed = v.parse(EdgeSchema, raw);\n\treturn {\n\t\t...parsed,\n\t\tid: asEdgeId(parsed.id),\n\t\tfrom: asThoughtId(parsed.from),\n\t\tto: asThoughtId(parsed.to),\n\t\tsessionId: asSessionId(parsed.sessionId),\n\t};\n}\n\nexport function parseSummary(raw: unknown, sourcePath: string): Summary {\n\tconst parsed = v.parse(SummarySchema, raw);\n\tconst { branchId, sessionId, rootThoughtId, coveredIds, coveredRange, ...summary } = parsed;\n\tconst [rangeStart, rangeEnd] = coveredRange;\n\tif (rangeStart === undefined || rangeEnd === undefined) {\n\t\tthrow new PersistenceCompatibilityError(\n\t\t\tsourcePath,\n\t\t\t'summary coveredRange must contain two values'\n\t\t);\n\t}\n\treturn {\n\t\t...summary,\n\t\tsessionId: asSessionId(sessionId),\n\t\t...(branchId === undefined ? {} : { branchId: parsePersistenceBranchId(branchId, sourcePath) }),\n\t\trootThoughtId: asThoughtId(rootThoughtId),\n\t\tcoveredIds: coveredIds.map(asThoughtId),\n\t\tcoveredRange: [rangeStart, rangeEnd],\n\t};\n}\n"],"names":["parseToolRecommendation","recommendation","sourcePath","undefined","PersistenceCompatibilityError","parseSkillRecommendation","parseStepRecommendation","step","recommended_tools","recommended_skills","fields","tool","skill","parseThoughtData","raw","parsed","v","SequentialThinkingSchema","id","session_id","branch_id","merge_branch_ids","continuation_token","current_step","previous_steps","thought","asThoughtId","asSessionId","parsePersistenceBranchId","asBranchId","asSuspensionToken","parseEdge","EdgeSchema","asEdgeId","parseSummary","SummarySchema","branchId","sessionId","rootThoughtId","coveredIds","coveredRange","summary","rangeStart","rangeEnd"],"mappings":";;;;;;AA4CA,SAASA,wBAAwBC,cAA2C,EAAEC,UAAkB;IAC/F,IACCD,AAA8BE,WAA9BF,eAAe,UAAU,IACzBA,AAA6BE,WAA7BF,eAAe,SAAS,IACxBA,AAA4BE,WAA5BF,eAAe,QAAQ,EAEvB,MAAM,IAAIG,8BAA8BF,YAAY;IAErD,OAAO;QACN,GAAGD,cAAc;QACjB,YAAYA,eAAe,UAAU;QACrC,WAAWA,eAAe,SAAS;QACnC,UAAUA,eAAe,QAAQ;IAClC;AACD;AAEA,SAASI,yBACRJ,cAA4C,EAC5CC,UAAkB;IAElB,IACCD,AAA8BE,WAA9BF,eAAe,UAAU,IACzBA,AAA6BE,WAA7BF,eAAe,SAAS,IACxBA,AAA4BE,WAA5BF,eAAe,QAAQ,EAEvB,MAAM,IAAIG,8BAA8BF,YAAY;IAErD,OAAO;QACN,GAAGD,cAAc;QACjB,YAAYA,eAAe,UAAU;QACrC,WAAWA,eAAe,SAAS;QACnC,UAAUA,eAAe,QAAQ;IAClC;AACD;AAEA,SAASK,wBACRC,IAAiC,EACjCL,UAAkB;IAElB,IAAIK,AAA0BJ,WAA1BI,KAAK,gBAAgB,IAAkBA,AAA0BJ,WAA1BI,KAAK,gBAAgB,EAC/D,MAAM,IAAIH,8BAA8BF,YAAY;IAErD,MAAM,EAAEM,iBAAiB,EAAEC,kBAAkB,EAAE,GAAGC,QAAQ,GAAGH;IAC7D,OAAO;QACN,GAAGG,MAAM;QACT,kBAAkBH,KAAK,gBAAgB;QACvC,kBAAkBA,KAAK,gBAAgB;QACvC,mBAAmBC,kBAAkB,GAAG,CAAC,CAACG,OAASX,wBAAwBW,MAAMT;QACjF,GAAIO,AAAuBN,WAAvBM,qBACD,CAAC,IACD;YACA,oBAAoBA,mBAAmB,GAAG,CAAC,CAACG,QAC3CP,yBAAyBO,OAAOV;QAElC,CAAC;IACJ;AACD;AAEO,SAASW,iBAAiBC,GAAY,EAAEZ,UAAkB;IAChE,MAAMa,SAASC,0BAAAA,KAAO,CAACC,
|
|
1
|
+
{"version":3,"file":"persistence/PersistenceCodec.js","sources":["../../src/persistence/PersistenceCodec.ts"],"sourcesContent":["import * as v from 'valibot';\nimport {\n\tasBranchId,\n\tasEdgeId,\n\tasSessionId,\n\tasSuspensionToken,\n\tasThoughtId,\n} from '../contracts/ids.js';\nimport type { Summary } from '../core/compression/Summary.js';\nimport { SummarySchema } from '../core/compression/Summary.js';\nimport type { Edge } from '../core/graph/Edge.js';\nimport type { ThoughtData } from '../core/thought.js';\nimport type { StepRecommendation } from '../core/step.js';\nimport { EdgeSchema, SequentialThinkingSchema } from '../schema.js';\nimport { PersistenceCompatibilityError } from '../errors.js';\nimport { parsePersistenceBranchId } from './PersistenceScope.js';\n\ntype PersistedToolRecommendation = {\n\treadonly tool_name: string;\n\treadonly confidence?: number;\n\treadonly rationale?: string;\n\treadonly priority?: number;\n\treadonly suggested_inputs?: Record<string, string | number | boolean | null>;\n\treadonly alternatives?: string[];\n};\n\ntype PersistedSkillRecommendation = {\n\treadonly skill_name: string;\n\treadonly confidence?: number;\n\treadonly rationale?: string;\n\treadonly priority?: number;\n\treadonly alternatives?: string[];\n\treadonly allowed_tools?: string[];\n\treadonly user_invocable?: boolean;\n};\n\ntype PersistedStepRecommendation = {\n\treadonly step_description?: string;\n\treadonly recommended_tools: readonly PersistedToolRecommendation[];\n\treadonly recommended_skills?: readonly PersistedSkillRecommendation[];\n\treadonly expected_outcome?: string;\n\treadonly next_step_conditions?: string[];\n};\n\nfunction parseToolRecommendation(recommendation: PersistedToolRecommendation, sourcePath: string) {\n\tif (\n\t\trecommendation.confidence === undefined ||\n\t\trecommendation.rationale === undefined ||\n\t\trecommendation.priority === undefined\n\t) {\n\t\tthrow new PersistenceCompatibilityError(sourcePath, 'tool recommendation defaults are absent');\n\t}\n\treturn {\n\t\t...recommendation,\n\t\tconfidence: recommendation.confidence,\n\t\trationale: recommendation.rationale,\n\t\tpriority: recommendation.priority,\n\t};\n}\n\nfunction parseSkillRecommendation(\n\trecommendation: PersistedSkillRecommendation,\n\tsourcePath: string\n) {\n\tif (\n\t\trecommendation.confidence === undefined ||\n\t\trecommendation.rationale === undefined ||\n\t\trecommendation.priority === undefined\n\t) {\n\t\tthrow new PersistenceCompatibilityError(sourcePath, 'skill recommendation defaults are absent');\n\t}\n\treturn {\n\t\t...recommendation,\n\t\tconfidence: recommendation.confidence,\n\t\trationale: recommendation.rationale,\n\t\tpriority: recommendation.priority,\n\t};\n}\n\nfunction parseStepRecommendation(\n\tstep: PersistedStepRecommendation,\n\tsourcePath: string\n): StepRecommendation {\n\tif (step.step_description === undefined || step.expected_outcome === undefined) {\n\t\tthrow new PersistenceCompatibilityError(sourcePath, 'step recommendation defaults are absent');\n\t}\n\tconst { recommended_tools, recommended_skills, ...fields } = step;\n\treturn {\n\t\t...fields,\n\t\tstep_description: step.step_description,\n\t\texpected_outcome: step.expected_outcome,\n\t\trecommended_tools: recommended_tools.map((tool) => parseToolRecommendation(tool, sourcePath)),\n\t\t...(recommended_skills === undefined\n\t\t\t? {}\n\t\t\t: {\n\t\t\t\t\trecommended_skills: recommended_skills.map((skill) =>\n\t\t\t\t\t\tparseSkillRecommendation(skill, sourcePath)\n\t\t\t\t\t),\n\t\t\t\t}),\n\t};\n}\n\nexport function parseThoughtData(raw: unknown, sourcePath: string): ThoughtData {\n\tconst retracted =\n\t\ttypeof raw === 'object' && raw !== null && 'retracted' in raw\n\t\t\t? Reflect.get(raw, 'retracted')\n\t\t\t: undefined;\n\tif (retracted !== undefined && typeof retracted !== 'boolean') {\n\t\tthrow new PersistenceCompatibilityError(sourcePath, 'thought retracted flag is not boolean');\n\t}\n\tconst parsed = v.parse(SequentialThinkingSchema, raw);\n\tconst {\n\t\tid,\n\t\tsession_id,\n\t\tbranch_id,\n\t\tmerge_branch_ids,\n\t\tcontinuation_token,\n\t\tcurrent_step,\n\t\tprevious_steps,\n\t\t...thought\n\t} = parsed;\n\treturn {\n\t\t...thought,\n\t\t...(id === undefined ? {} : { id: asThoughtId(id) }),\n\t\tsession_id: asSessionId(session_id),\n\t\t...(branch_id === undefined\n\t\t\t? {}\n\t\t\t: { branch_id: parsePersistenceBranchId(branch_id, sourcePath) }),\n\t\t...(merge_branch_ids === undefined\n\t\t\t? {}\n\t\t\t: { merge_branch_ids: merge_branch_ids.map(asBranchId) }),\n\t\t...(continuation_token === undefined\n\t\t\t? {}\n\t\t\t: { continuation_token: asSuspensionToken(continuation_token) }),\n\t\t...(current_step === undefined\n\t\t\t? {}\n\t\t\t: { current_step: parseStepRecommendation(current_step, sourcePath) }),\n\t\t...(previous_steps === undefined\n\t\t\t? {}\n\t\t\t: {\n\t\t\t\t\tprevious_steps: previous_steps.map((step) => parseStepRecommendation(step, sourcePath)),\n\t\t\t\t}),\n\t\t...(retracted === undefined ? {} : { retracted }),\n\t};\n}\n\nexport function parseEdge(raw: unknown): Edge {\n\tconst parsed = v.parse(EdgeSchema, raw);\n\treturn {\n\t\t...parsed,\n\t\tid: asEdgeId(parsed.id),\n\t\tfrom: asThoughtId(parsed.from),\n\t\tto: asThoughtId(parsed.to),\n\t\tsessionId: asSessionId(parsed.sessionId),\n\t};\n}\n\nexport function parseSummary(raw: unknown, sourcePath: string): Summary {\n\tconst parsed = v.parse(SummarySchema, raw);\n\tconst { branchId, sessionId, rootThoughtId, coveredIds, coveredRange, ...summary } = parsed;\n\tconst [rangeStart, rangeEnd] = coveredRange;\n\tif (rangeStart === undefined || rangeEnd === undefined) {\n\t\tthrow new PersistenceCompatibilityError(\n\t\t\tsourcePath,\n\t\t\t'summary coveredRange must contain two values'\n\t\t);\n\t}\n\treturn {\n\t\t...summary,\n\t\tsessionId: asSessionId(sessionId),\n\t\t...(branchId === undefined ? {} : { branchId: parsePersistenceBranchId(branchId, sourcePath) }),\n\t\trootThoughtId: asThoughtId(rootThoughtId),\n\t\tcoveredIds: coveredIds.map(asThoughtId),\n\t\tcoveredRange: [rangeStart, rangeEnd],\n\t};\n}\n"],"names":["parseToolRecommendation","recommendation","sourcePath","undefined","PersistenceCompatibilityError","parseSkillRecommendation","parseStepRecommendation","step","recommended_tools","recommended_skills","fields","tool","skill","parseThoughtData","raw","retracted","Reflect","parsed","v","SequentialThinkingSchema","id","session_id","branch_id","merge_branch_ids","continuation_token","current_step","previous_steps","thought","asThoughtId","asSessionId","parsePersistenceBranchId","asBranchId","asSuspensionToken","parseEdge","EdgeSchema","asEdgeId","parseSummary","SummarySchema","branchId","sessionId","rootThoughtId","coveredIds","coveredRange","summary","rangeStart","rangeEnd"],"mappings":"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"}
|