@iworkforces/tracelattice 2.1.2 → 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 +19 -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/package.json +4 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core/PersistenceWorkQueue.js","sources":["../../src/core/PersistenceWorkQueue.ts"],"sourcesContent":["/**\n * Pure attributable queue for accepted persistence work.\n *\n * @module core/PersistenceWorkQueue\n */\n\n// allow: SIZE_OK - Task 8 requires this single-responsibility queue in exactly one production file.\n\nimport type {\n\tPersistenceGenerationResult,\n\tPersistenceWork,\n\tPersistenceWorkFailure,\n\tPersistenceWorkToken,\n} from '../contracts/persistence-work.js';\nimport type { BranchId, SessionId } from '../contracts/ids.js';\nimport { assertNever } from '../utils.js';\nimport type { Summary } from './compression/Summary.js';\nimport type { Edge } from './graph/Edge.js';\nimport type { ThoughtData } from './thought.js';\n\n/** Selects whether retained terminal failures are eligible for a generation. */\nexport type PersistenceSelectionMode = 'explicit' | 'background';\n\ntype WorkKind = PersistenceWork['kind'];\ntype WorkOf<K extends WorkKind> = Extract<PersistenceWork, { readonly kind: K }>;\n\ntype QueueEntry<K extends WorkKind> = {\n\treadonly acceptedSequence: number;\n\treadonly work: WorkOf<K>;\n\tterminalFailure: PersistenceWorkFailure | undefined;\n};\n\ntype ThoughtEntry = QueueEntry<'thought'>;\ntype BranchEntry = QueueEntry<'branch'>;\ntype EdgeEntry = QueueEntry<'edge'>;\ntype SummaryEntry = QueueEntry<'summary'>;\ntype AnyQueueEntry = ThoughtEntry | BranchEntry | EdgeEntry | SummaryEntry;\n\ntype Acceptance = {\n\treadonly token: PersistenceWorkToken;\n\treadonly sequence: number;\n};\n\n/**\n * Stores accepted persistence work independently from live session state.\n *\n * Thought entries retain FIFO acceptance order. Auxiliary snapshots coalesce at\n * their stable coordinate and use versioned compare-and-set acknowledgement.\n * Generation state remains caller-owned in a `Set` passed to selection methods.\n *\n * @example\n * ```ts\n * const queue = new PersistenceWorkQueue();\n * queue.enqueueThought(sessionId, thought);\n * const selected = new Set<PersistenceWorkToken>();\n * const work = queue.nextEligibleWork(selected, 'explicit');\n * if (work !== undefined) queue.acknowledgeSuccess(work);\n * ```\n */\nexport class PersistenceWorkQueue {\n\tprivate readonly _thoughts: ThoughtEntry[] = [];\n\tprivate readonly _branches = new Map<SessionId, Map<BranchId, BranchEntry>>();\n\tprivate readonly _edges = new Map<SessionId, EdgeEntry>();\n\tprivate readonly _summaries = new Map<SessionId, SummaryEntry>();\n\n\tprivate readonly _branchVersions = new Map<SessionId, Map<BranchId, number>>();\n\tprivate readonly _edgeVersions = new Map<SessionId, number>();\n\tprivate readonly _summaryVersions = new Map<SessionId, number>();\n\tprivate _nextSequence = 1;\n\n\t/**\n\t * Accepts one thought as a distinct FIFO work item.\n\t *\n\t * @param sessionId - Session that owns the thought write.\n\t * @param thought - Thought payload accepted by the coordinator.\n\t * @returns The exact immutable work handle used for acknowledgement.\n\t */\n\tpublic enqueueThought(sessionId: SessionId, thought: ThoughtData): WorkOf<'thought'> {\n\t\tconst acceptance = this._accept();\n\t\tconst work: WorkOf<'thought'> = Object.freeze({\n\t\t\tkind: 'thought',\n\t\t\ttoken: acceptance.token,\n\t\t\tsessionId,\n\t\t\tthought,\n\t\t});\n\t\tthis._thoughts.push({\n\t\t\tacceptedSequence: acceptance.sequence,\n\t\t\twork,\n\t\t\tterminalFailure: undefined,\n\t\t});\n\t\treturn work;\n\t}\n\n\t/**\n\t * Replaces the pending snapshot for one session-owned branch.\n\t *\n\t * @param sessionId - Session that owns the branch.\n\t * @param branchId - Stable branch coordinate within the session.\n\t * @param thoughts - Branch snapshot; its array is copied before storage.\n\t * @returns The new immutable, versioned work handle.\n\t */\n\tpublic replaceBranch(\n\t\tsessionId: SessionId,\n\t\tbranchId: BranchId,\n\t\tthoughts: readonly ThoughtData[]\n\t): WorkOf<'branch'> {\n\t\tconst versionMap = this._branchVersions.get(sessionId) ?? new Map<BranchId, number>();\n\t\tthis._branchVersions.set(sessionId, versionMap);\n\t\tconst version = (versionMap.get(branchId) ?? 0) + 1;\n\t\tversionMap.set(branchId, version);\n\n\t\tconst acceptance = this._accept();\n\t\tconst work: WorkOf<'branch'> = Object.freeze({\n\t\t\tkind: 'branch',\n\t\t\toperation: 'save',\n\t\t\ttoken: acceptance.token,\n\t\t\tsessionId,\n\t\t\tkey: branchId,\n\t\t\tversion,\n\t\t\tsnapshot: Object.freeze([...thoughts]),\n\t\t});\n\t\tconst branchMap = this._branches.get(sessionId) ?? new Map<BranchId, BranchEntry>();\n\t\tthis._branches.set(sessionId, branchMap);\n\t\tbranchMap.set(branchId, {\n\t\t\tacceptedSequence: acceptance.sequence,\n\t\t\twork,\n\t\t\tterminalFailure: undefined,\n\t\t});\n\t\treturn work;\n\t}\n\n\t/**\n\t * @param sessionId - Session that owns the branch.\n\t * @param branchId - Stable branch coordinate within the session.\n\t * @returns The new immutable, versioned deletion work handle.\n\t */\n\tpublic deleteBranch(sessionId: SessionId, branchId: BranchId): WorkOf<'branch'> {\n\t\tconst versionMap = this._branchVersions.get(sessionId) ?? new Map<BranchId, number>();\n\t\tthis._branchVersions.set(sessionId, versionMap);\n\t\tconst version = (versionMap.get(branchId) ?? 0) + 1;\n\t\tversionMap.set(branchId, version);\n\n\t\tconst acceptance = this._accept();\n\t\tconst work: WorkOf<'branch'> = Object.freeze({\n\t\t\tkind: 'branch',\n\t\t\toperation: 'delete',\n\t\t\ttoken: acceptance.token,\n\t\t\tsessionId,\n\t\t\tkey: branchId,\n\t\t\tversion,\n\t\t});\n\t\tconst branchMap = this._branches.get(sessionId) ?? new Map<BranchId, BranchEntry>();\n\t\tthis._branches.set(sessionId, branchMap);\n\t\tbranchMap.set(branchId, {\n\t\t\tacceptedSequence: acceptance.sequence,\n\t\t\twork,\n\t\t\tterminalFailure: undefined,\n\t\t});\n\t\treturn work;\n\t}\n\n\t/**\n\t * Replaces the pending edge snapshot for a session.\n\t *\n\t * @param sessionId - Stable session coordinate for the edge set.\n\t * @param edges - Edge snapshot; its array is copied before storage.\n\t * @returns The new immutable, versioned work handle.\n\t */\n\tpublic replaceEdges(sessionId: SessionId, edges: readonly Edge[]): WorkOf<'edge'> {\n\t\tconst version = (this._edgeVersions.get(sessionId) ?? 0) + 1;\n\t\tthis._edgeVersions.set(sessionId, version);\n\t\tconst acceptance = this._accept();\n\t\tconst work: WorkOf<'edge'> = Object.freeze({\n\t\t\tkind: 'edge',\n\t\t\ttoken: acceptance.token,\n\t\t\tsessionId,\n\t\t\tkey: sessionId,\n\t\t\tversion,\n\t\t\tsnapshot: Object.freeze([...edges]),\n\t\t});\n\t\tthis._edges.set(sessionId, {\n\t\t\tacceptedSequence: acceptance.sequence,\n\t\t\twork,\n\t\t\tterminalFailure: undefined,\n\t\t});\n\t\treturn work;\n\t}\n\n\t/**\n\t * Replaces the pending summary snapshot for a session.\n\t *\n\t * @param sessionId - Stable session coordinate for the summary set.\n\t * @param summaries - Summary snapshot; its array is copied before storage.\n\t * @returns The new immutable, versioned work handle.\n\t */\n\tpublic replaceSummaries(sessionId: SessionId, summaries: readonly Summary[]): WorkOf<'summary'> {\n\t\tconst version = (this._summaryVersions.get(sessionId) ?? 0) + 1;\n\t\tthis._summaryVersions.set(sessionId, version);\n\t\tconst acceptance = this._accept();\n\t\tconst work: WorkOf<'summary'> = Object.freeze({\n\t\t\tkind: 'summary',\n\t\t\ttoken: acceptance.token,\n\t\t\tsessionId,\n\t\t\tkey: sessionId,\n\t\t\tversion,\n\t\t\tsnapshot: Object.freeze([...summaries]),\n\t\t});\n\t\tthis._summaries.set(sessionId, {\n\t\t\tacceptedSequence: acceptance.sequence,\n\t\t\twork,\n\t\t\tterminalFailure: undefined,\n\t\t});\n\t\treturn work;\n\t}\n\n\t/**\n\t * Reports whether a generation can select current work.\n\t *\n\t * @param selectedTokens - Tokens already selected by the caller's generation.\n\t * @param mode - Explicit generations re-arm failures; background generations skip them.\n\t * @param sessionId - Optional session projection.\n\t * @returns `true` when at least one current entry is eligible.\n\t */\n\tpublic hasEligibleWork(\n\t\tselectedTokens: ReadonlySet<PersistenceWorkToken>,\n\t\tmode: PersistenceSelectionMode,\n\t\tsessionId?: SessionId\n\t): boolean {\n\t\treturn this._findEligible(selectedTokens, mode, sessionId) !== undefined;\n\t}\n\n\t/**\n\t * Selects the oldest currently eligible work and records it in the generation set.\n\t *\n\t * @param selectedTokens - Mutable set owned by the caller's generation.\n\t * @param mode - Explicit generations re-arm failures; background generations skip them.\n\t * @param sessionId - Optional session projection.\n\t * @returns The selected work, or `undefined` when no current entry is eligible.\n\t */\n\tpublic nextEligibleWork(\n\t\tselectedTokens: Set<PersistenceWorkToken>,\n\t\tmode: PersistenceSelectionMode,\n\t\tsessionId?: SessionId\n\t): PersistenceWork | undefined {\n\t\tconst entry = this._findEligible(selectedTokens, mode, sessionId);\n\t\tif (entry === undefined) return undefined;\n\t\tselectedTokens.add(entry.work.token);\n\t\treturn entry.work;\n\t}\n\n\t/**\n\t * Acknowledges successful persistence using exact token/version CAS semantics.\n\t *\n\t * @param work - Previously selected work handle.\n\t */\n\tpublic acknowledgeSuccess(work: PersistenceWork): void {\n\t\tconst entry = this._currentEntry(work);\n\t\tif (entry === undefined) return;\n\t\tswitch (work.kind) {\n\t\t\tcase 'thought': {\n\t\t\t\tconst index = this._thoughts.findIndex((candidate) => candidate === entry);\n\t\t\t\tif (index >= 0) this._thoughts.splice(index, 1);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase 'branch':\n\t\t\t\tthis._branches.get(work.sessionId)?.delete(work.key);\n\t\t\t\treturn;\n\t\t\tcase 'edge':\n\t\t\t\tthis._edges.delete(work.key);\n\t\t\t\treturn;\n\t\t\tcase 'summary':\n\t\t\t\tthis._summaries.delete(work.key);\n\t\t\t\treturn;\n\t\t\tdefault:\n\t\t\t\tassertNever(work);\n\t\t}\n\t}\n\n\t/**\n\t * Attaches a terminal failure only when both work and failure still match current work.\n\t *\n\t * @param work - Previously selected work handle.\n\t * @param failure - Terminal backend failure attributed to that handle.\n\t */\n\tpublic acknowledgeFailure(work: PersistenceWork, failure: PersistenceWorkFailure): void {\n\t\tif (!this._matchesFailure(work, failure)) return;\n\t\tconst entry = this._currentEntry(work);\n\t\tif (entry !== undefined) entry.terminalFailure = Object.freeze({ ...failure });\n\t}\n\n\t/**\n\t * Returns an immutable acceptance-ordered snapshot of current terminal failures.\n\t *\n\t * @param selectedTokens - Optional generation-token projection.\n\t * @param sessionId - Optional session projection.\n\t * @returns A fresh readonly failure array containing only failures on current entries.\n\t */\n\tpublic currentFailures(\n\t\tselectedTokens?: ReadonlySet<PersistenceWorkToken>,\n\t\tsessionId?: SessionId\n\t): readonly PersistenceWorkFailure[] {\n\t\tconst failures = this._entries()\n\t\t\t.filter(\n\t\t\t\t(entry) =>\n\t\t\t\t\tentry.terminalFailure !== undefined &&\n\t\t\t\t\t(selectedTokens === undefined || selectedTokens.has(entry.work.token)) &&\n\t\t\t\t\t(sessionId === undefined || entry.work.sessionId === sessionId)\n\t\t\t)\n\t\t\t.sort((left, right) => left.acceptedSequence - right.acceptedSequence)\n\t\t\t.flatMap((entry) => (entry.terminalFailure === undefined ? [] : [entry.terminalFailure]));\n\t\treturn Object.freeze(failures);\n\t}\n\n\t/**\n\t * Captures the current immutable result for a generation or session projection.\n\t *\n\t * @param selectedTokens - Optional generation-token projection.\n\t * @param sessionId - Optional session projection.\n\t * @returns A result containing a fresh readonly failure snapshot.\n\t */\n\tpublic generationResult(\n\t\tselectedTokens?: ReadonlySet<PersistenceWorkToken>,\n\t\tsessionId?: SessionId\n\t): PersistenceGenerationResult {\n\t\treturn Object.freeze({ failures: this.currentFailures(selectedTokens, sessionId) });\n\t}\n\n\t/** @returns Number of accepted thought writes not yet acknowledged successful. */\n\tpublic get pendingThoughtCount(): number {\n\t\treturn this._thoughts.length;\n\t}\n\n\t/** @returns Number of all current thought and coalesced auxiliary entries. */\n\tpublic get pendingWorkCount(): number {\n\t\tlet branchCount = 0;\n\t\tfor (const branches of this._branches.values()) branchCount += branches.size;\n\t\treturn this._thoughts.length + branchCount + this._edges.size + this._summaries.size;\n\t}\n\n\t/** @returns Whether any accepted work remains for a session across all work kinds. */\n\tpublic hasSessionWork(sessionId: SessionId): boolean {\n\t\treturn this._entries().some((entry) => entry.work.sessionId === sessionId);\n\t}\n\n\t/** @returns Whether current retained work for a session owns a terminal failure. */\n\tpublic hasSessionTerminalFailure(sessionId: SessionId): boolean {\n\t\treturn this.currentFailures(undefined, sessionId).length > 0;\n\t}\n\n\t/**\n\t * Forgets version coordinates only after all accepted work for a session is gone.\n\t *\n\t * @returns `false` without mutation while any accepted work remains.\n\t */\n\tpublic forgetQuiescentSession(sessionId: SessionId): boolean {\n\t\tif (this.hasSessionWork(sessionId)) return false;\n\t\tthis._branches.delete(sessionId);\n\t\tthis._branchVersions.delete(sessionId);\n\t\tthis._edgeVersions.delete(sessionId);\n\t\tthis._summaryVersions.delete(sessionId);\n\t\treturn true;\n\t}\n\n\t/** Discards every retained work item and version coordinate for one deleted session. */\n\tpublic discardSession(sessionId: SessionId): void {\n\t\tfor (let index = this._thoughts.length - 1; index >= 0; index -= 1) {\n\t\t\tif (this._thoughts[index]?.work.sessionId === sessionId) this._thoughts.splice(index, 1);\n\t\t}\n\t\tthis._branches.delete(sessionId);\n\t\tthis._edges.delete(sessionId);\n\t\tthis._summaries.delete(sessionId);\n\t\tthis._branchVersions.delete(sessionId);\n\t\tthis._edgeVersions.delete(sessionId);\n\t\tthis._summaryVersions.delete(sessionId);\n\t}\n\n\t/** Discards all retained work after a successful durable global reset. */\n\tpublic discardAll(): void {\n\t\tthis._thoughts.length = 0;\n\t\tthis._branches.clear();\n\t\tthis._edges.clear();\n\t\tthis._summaries.clear();\n\t\tthis._branchVersions.clear();\n\t\tthis._edgeVersions.clear();\n\t\tthis._summaryVersions.clear();\n\t}\n\n\tprivate _accept(): Acceptance {\n\t\tconst sequence = this._nextSequence;\n\t\tthis._nextSequence += 1;\n\t\treturn { token: `persistence-work-${sequence}`, sequence };\n\t}\n\n\tprivate _entries(): AnyQueueEntry[] {\n\t\tconst entries: AnyQueueEntry[] = [...this._thoughts];\n\t\tfor (const branches of this._branches.values()) entries.push(...branches.values());\n\t\tentries.push(...this._edges.values(), ...this._summaries.values());\n\t\treturn entries;\n\t}\n\n\tprivate _findEligible(\n\t\tselectedTokens: ReadonlySet<PersistenceWorkToken>,\n\t\tmode: PersistenceSelectionMode,\n\t\tsessionId?: SessionId\n\t): AnyQueueEntry | undefined {\n\t\tlet oldest: AnyQueueEntry | undefined;\n\t\tfor (const entry of this._entries()) {\n\t\t\tif (selectedTokens.has(entry.work.token)) continue;\n\t\t\tif (sessionId !== undefined && entry.work.sessionId !== sessionId) continue;\n\t\t\tif (!this._modeAllows(mode, entry.terminalFailure !== undefined)) continue;\n\t\t\tif (oldest === undefined || entry.acceptedSequence < oldest.acceptedSequence) oldest = entry;\n\t\t}\n\t\treturn oldest;\n\t}\n\n\tprivate _modeAllows(mode: PersistenceSelectionMode, hasTerminalFailure: boolean): boolean {\n\t\tswitch (mode) {\n\t\t\tcase 'explicit':\n\t\t\t\treturn true;\n\t\t\tcase 'background':\n\t\t\t\treturn !hasTerminalFailure;\n\t\t\tdefault:\n\t\t\t\treturn assertNever(mode);\n\t\t}\n\t}\n\n\tprivate _currentEntry(work: PersistenceWork): AnyQueueEntry | undefined {\n\t\tlet entry: AnyQueueEntry | undefined;\n\t\tswitch (work.kind) {\n\t\t\tcase 'thought':\n\t\t\t\tentry = this._thoughts.find((candidate) => candidate.work.token === work.token);\n\t\t\t\tbreak;\n\t\t\tcase 'branch':\n\t\t\t\tentry = this._branches.get(work.sessionId)?.get(work.key);\n\t\t\t\tbreak;\n\t\t\tcase 'edge':\n\t\t\t\tentry = this._edges.get(work.key);\n\t\t\t\tbreak;\n\t\t\tcase 'summary':\n\t\t\t\tentry = this._summaries.get(work.key);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\treturn assertNever(work);\n\t\t}\n\t\treturn entry !== undefined && this._matchesWork(entry.work, work) ? entry : undefined;\n\t}\n\n\tprivate _matchesWork(current: PersistenceWork, selected: PersistenceWork): boolean {\n\t\tif (\n\t\t\tcurrent.kind !== selected.kind ||\n\t\t\tcurrent.token !== selected.token ||\n\t\t\tcurrent.sessionId !== selected.sessionId\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\t\tswitch (selected.kind) {\n\t\t\tcase 'thought':\n\t\t\t\treturn current.kind === 'thought';\n\t\t\tcase 'branch':\n\t\t\t\treturn (\n\t\t\t\t\tcurrent.kind === 'branch' &&\n\t\t\t\t\tcurrent.operation === selected.operation &&\n\t\t\t\t\tcurrent.key === selected.key &&\n\t\t\t\t\tcurrent.version === selected.version\n\t\t\t\t);\n\t\t\tcase 'edge':\n\t\t\t\treturn (\n\t\t\t\t\tcurrent.kind === 'edge' &&\n\t\t\t\t\tcurrent.key === selected.key &&\n\t\t\t\t\tcurrent.version === selected.version\n\t\t\t\t);\n\t\t\tcase 'summary':\n\t\t\t\treturn (\n\t\t\t\t\tcurrent.kind === 'summary' &&\n\t\t\t\t\tcurrent.key === selected.key &&\n\t\t\t\t\tcurrent.version === selected.version\n\t\t\t\t);\n\t\t\tdefault:\n\t\t\t\treturn assertNever(selected);\n\t\t}\n\t}\n\n\tprivate _matchesFailure(work: PersistenceWork, failure: PersistenceWorkFailure): boolean {\n\t\tif (\n\t\t\twork.kind !== failure.kind ||\n\t\t\twork.token !== failure.token ||\n\t\t\twork.sessionId !== failure.sessionId\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\t\tswitch (work.kind) {\n\t\t\tcase 'thought':\n\t\t\t\treturn true;\n\t\t\tcase 'branch':\n\t\t\t\treturn (\n\t\t\t\t\tfailure.kind === 'branch' &&\n\t\t\t\t\twork.operation === failure.operation &&\n\t\t\t\t\twork.key === failure.key &&\n\t\t\t\t\twork.version === failure.version\n\t\t\t\t);\n\t\t\tcase 'edge':\n\t\t\tcase 'summary':\n\t\t\t\treturn 'key' in failure && work.key === failure.key && work.version === failure.version;\n\t\t\tdefault:\n\t\t\t\treturn assertNever(work);\n\t\t}\n\t}\n}\n"],"names":["PersistenceWorkQueue","Map","sessionId","thought","acceptance","work","Object","undefined","branchId","thoughts","versionMap","version","branchMap","edges","summaries","selectedTokens","mode","entry","index","candidate","assertNever","failure","failures","left","right","branchCount","branches","sequence","entries","oldest","hasTerminalFailure","current","selected"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"core/PersistenceWorkQueue.js","sources":["../../src/core/PersistenceWorkQueue.ts"],"sourcesContent":["/**\n * Pure attributable queue for accepted persistence work.\n *\n * @module core/PersistenceWorkQueue\n */\n\n// allow: SIZE_OK - Task 8 requires this single-responsibility queue in exactly one production file.\n\nimport type {\n\tPersistenceGenerationResult,\n\tPersistenceWork,\n\tPersistenceWorkFailure,\n\tPersistenceWorkToken,\n} from '../contracts/persistence-work.js';\nimport type { BranchId, SessionId, ThoughtId } from '../contracts/ids.js';\nimport { assertNever } from '../utils.js';\nimport type { Summary } from './compression/Summary.js';\nimport {\n\tDurableThoughtIdentityIndex,\n\ttype DurableIdentitySession,\n\tnormalizeDurableHistoryRetention,\n} from './DurableThoughtIdentityIndex.js';\nimport type { Edge } from './graph/Edge.js';\nimport type { ThoughtData } from './thought.js';\n\n/** Selects whether retained terminal failures are eligible for a generation. */\nexport type PersistenceSelectionMode = 'explicit' | 'background';\n\ntype WorkKind = PersistenceWork['kind'];\ntype WorkOf<K extends WorkKind> = Extract<PersistenceWork, { readonly kind: K }>;\n\ntype QueueEntry<K extends WorkKind> = {\n\treadonly acceptedSequence: number;\n\treadonly work: WorkOf<K>;\n\tterminalFailure: PersistenceWorkFailure | undefined;\n};\n\ntype ThoughtEntry = QueueEntry<'thought'>;\ntype BacktrackEntry = QueueEntry<'backtrack'>;\ntype BranchEntry = QueueEntry<'branch'>;\ntype EdgeEntry = QueueEntry<'edge'>;\ntype SummaryEntry = QueueEntry<'summary'>;\ntype AnyQueueEntry = ThoughtEntry | BacktrackEntry | BranchEntry | EdgeEntry | SummaryEntry;\n\ntype Acceptance = {\n\treadonly token: PersistenceWorkToken;\n\treadonly sequence: number;\n};\n\n/**\n * Stores accepted persistence work independently from live session state.\n *\n * Thought entries retain FIFO acceptance order. Auxiliary snapshots coalesce at\n * their stable coordinate and use versioned compare-and-set acknowledgement.\n * Generation state remains caller-owned in a `Set` passed to selection methods.\n *\n * @example\n * ```ts\n * const queue = new PersistenceWorkQueue();\n * queue.enqueueThought(sessionId, thought);\n * const selected = new Set<PersistenceWorkToken>();\n * const work = queue.nextEligibleWork(selected, 'explicit');\n * if (work !== undefined) queue.acknowledgeSuccess(work);\n * ```\n */\nexport class PersistenceWorkQueue {\n\tprivate readonly _thoughts: Array<ThoughtEntry | BacktrackEntry> = [];\n\tprivate readonly _thoughtIdentities = new Map<SessionId, Map<ThoughtId, number>>();\n\tprivate readonly _durableThoughtIdentities: DurableThoughtIdentityIndex;\n\tprivate readonly _persistBranches: boolean;\n\tprivate readonly _branches = new Map<SessionId, Map<BranchId, BranchEntry>>();\n\tprivate readonly _edges = new Map<SessionId, EdgeEntry>();\n\tprivate readonly _summaries = new Map<SessionId, SummaryEntry>();\n\n\tprivate readonly _branchVersions = new Map<SessionId, Map<BranchId, number>>();\n\tprivate readonly _edgeVersions = new Map<SessionId, number>();\n\tprivate readonly _summaryVersions = new Map<SessionId, number>();\n\tprivate _nextSequence = 1;\n\n\tpublic constructor(durableHistorySize = 10_000, persistBranches = true) {\n\t\tthis._durableThoughtIdentities = new DurableThoughtIdentityIndex(\n\t\t\tnormalizeDurableHistoryRetention(durableHistorySize)\n\t\t);\n\t\tthis._persistBranches = persistBranches;\n\t}\n\n\t/**\n\t * Accepts one thought as a distinct FIFO work item.\n\t *\n\t * @param sessionId - Session that owns the thought write.\n\t * @param thought - Thought payload accepted by the coordinator.\n\t * @returns The exact immutable work handle used for acknowledgement.\n\t */\n\tpublic enqueueThought(sessionId: SessionId, thought: ThoughtData): WorkOf<'thought'> {\n\t\tconst acceptance = this._accept();\n\t\tconst work: WorkOf<'thought'> = Object.freeze({\n\t\t\tkind: 'thought',\n\t\t\ttoken: acceptance.token,\n\t\t\tsessionId,\n\t\t\tthought: this._freezeClone(thought),\n\t\t});\n\t\tthis._thoughts.push({\n\t\t\tacceptedSequence: acceptance.sequence,\n\t\t\twork,\n\t\t\tterminalFailure: undefined,\n\t\t});\n\t\tif (thought.id !== undefined) this._addThoughtIdentity(sessionId, thought.id);\n\t\treturn work;\n\t}\n\n\tpublic enqueueBacktrack(\n\t\tsessionId: SessionId,\n\t\tthought: ThoughtData,\n\t\ttargetThoughtId: ThoughtId\n\t): WorkOf<'backtrack'> {\n\t\tconst acceptance = this._accept();\n\t\tconst work: WorkOf<'backtrack'> = Object.freeze({\n\t\t\tkind: 'backtrack',\n\t\t\ttoken: acceptance.token,\n\t\t\tsessionId,\n\t\t\tthought: this._freezeClone(thought),\n\t\t\ttargetThoughtId,\n\t\t});\n\t\tthis._thoughts.push({\n\t\t\tacceptedSequence: acceptance.sequence,\n\t\t\twork,\n\t\t\tterminalFailure: undefined,\n\t\t});\n\t\tif (thought.id !== undefined) this._addThoughtIdentity(sessionId, thought.id);\n\t\treturn work;\n\t}\n\n\tpublic hasThoughtIdentity(sessionId: SessionId, thoughtId: ThoughtId): boolean {\n\t\treturn (\n\t\t\tthis._thoughtIdentities.get(sessionId)?.has(thoughtId) === true ||\n\t\t\tthis._durableThoughtIdentities.has(sessionId, thoughtId)\n\t\t);\n\t}\n\n\tpublic replaceDurableThoughtIdentities(sessions: readonly DurableIdentitySession[]): void {\n\t\tthis._durableThoughtIdentities.replaceAll(sessions);\n\t}\n\n\t/**\n\t * Replaces the pending snapshot for one session-owned branch.\n\t *\n\t * @param sessionId - Session that owns the branch.\n\t * @param branchId - Stable branch coordinate within the session.\n\t * @param thoughts - Branch snapshot; its array is copied before storage.\n\t * @returns The new immutable, versioned work handle.\n\t */\n\tpublic replaceBranch(\n\t\tsessionId: SessionId,\n\t\tbranchId: BranchId,\n\t\tthoughts: readonly ThoughtData[]\n\t): WorkOf<'branch'> {\n\t\tconst versionMap = this._branchVersions.get(sessionId) ?? new Map<BranchId, number>();\n\t\tthis._branchVersions.set(sessionId, versionMap);\n\t\tconst version = (versionMap.get(branchId) ?? 0) + 1;\n\t\tversionMap.set(branchId, version);\n\n\t\tconst acceptance = this._accept();\n\t\tconst work: WorkOf<'branch'> = Object.freeze({\n\t\t\tkind: 'branch',\n\t\t\toperation: 'save',\n\t\t\ttoken: acceptance.token,\n\t\t\tsessionId,\n\t\t\tkey: branchId,\n\t\t\tversion,\n\t\t\tsnapshot: this._freezeClone(thoughts),\n\t\t});\n\t\tconst branchMap = this._branches.get(sessionId) ?? new Map<BranchId, BranchEntry>();\n\t\tthis._branches.set(sessionId, branchMap);\n\t\tbranchMap.set(branchId, {\n\t\t\tacceptedSequence: acceptance.sequence,\n\t\t\twork,\n\t\t\tterminalFailure: undefined,\n\t\t});\n\t\treturn work;\n\t}\n\n\t/**\n\t * @param sessionId - Session that owns the branch.\n\t * @param branchId - Stable branch coordinate within the session.\n\t * @returns The new immutable, versioned deletion work handle.\n\t */\n\tpublic deleteBranch(sessionId: SessionId, branchId: BranchId): WorkOf<'branch'> {\n\t\tconst versionMap = this._branchVersions.get(sessionId) ?? new Map<BranchId, number>();\n\t\tthis._branchVersions.set(sessionId, versionMap);\n\t\tconst version = (versionMap.get(branchId) ?? 0) + 1;\n\t\tversionMap.set(branchId, version);\n\n\t\tconst acceptance = this._accept();\n\t\tconst work: WorkOf<'branch'> = Object.freeze({\n\t\t\tkind: 'branch',\n\t\t\toperation: 'delete',\n\t\t\ttoken: acceptance.token,\n\t\t\tsessionId,\n\t\t\tkey: branchId,\n\t\t\tversion,\n\t\t});\n\t\tconst branchMap = this._branches.get(sessionId) ?? new Map<BranchId, BranchEntry>();\n\t\tthis._branches.set(sessionId, branchMap);\n\t\tbranchMap.set(branchId, {\n\t\t\tacceptedSequence: acceptance.sequence,\n\t\t\twork,\n\t\t\tterminalFailure: undefined,\n\t\t});\n\t\treturn work;\n\t}\n\n\t/**\n\t * Replaces the pending edge snapshot for a session.\n\t *\n\t * @param sessionId - Stable session coordinate for the edge set.\n\t * @param edges - Edge snapshot; its array is copied before storage.\n\t * @returns The new immutable, versioned work handle.\n\t */\n\tpublic replaceEdges(sessionId: SessionId, edges: readonly Edge[]): WorkOf<'edge'> {\n\t\tconst version = (this._edgeVersions.get(sessionId) ?? 0) + 1;\n\t\tthis._edgeVersions.set(sessionId, version);\n\t\tconst acceptance = this._accept();\n\t\tconst work: WorkOf<'edge'> = Object.freeze({\n\t\t\tkind: 'edge',\n\t\t\ttoken: acceptance.token,\n\t\t\tsessionId,\n\t\t\tkey: sessionId,\n\t\t\tversion,\n\t\t\tsnapshot: this._freezeClone(edges),\n\t\t});\n\t\tthis._edges.set(sessionId, {\n\t\t\tacceptedSequence: acceptance.sequence,\n\t\t\twork,\n\t\t\tterminalFailure: undefined,\n\t\t});\n\t\treturn work;\n\t}\n\n\t/**\n\t * Replaces the pending summary snapshot for a session.\n\t *\n\t * @param sessionId - Stable session coordinate for the summary set.\n\t * @param summaries - Summary snapshot; its array is copied before storage.\n\t * @returns The new immutable, versioned work handle.\n\t */\n\tpublic replaceSummaries(sessionId: SessionId, summaries: readonly Summary[]): WorkOf<'summary'> {\n\t\tconst version = (this._summaryVersions.get(sessionId) ?? 0) + 1;\n\t\tthis._summaryVersions.set(sessionId, version);\n\t\tconst acceptance = this._accept();\n\t\tconst work: WorkOf<'summary'> = Object.freeze({\n\t\t\tkind: 'summary',\n\t\t\ttoken: acceptance.token,\n\t\t\tsessionId,\n\t\t\tkey: sessionId,\n\t\t\tversion,\n\t\t\tsnapshot: this._freezeClone(summaries),\n\t\t});\n\t\tthis._summaries.set(sessionId, {\n\t\t\tacceptedSequence: acceptance.sequence,\n\t\t\twork,\n\t\t\tterminalFailure: undefined,\n\t\t});\n\t\treturn work;\n\t}\n\n\t/**\n\t * Reports whether a generation can select current work.\n\t *\n\t * @param selectedTokens - Tokens already selected by the caller's generation.\n\t * @param mode - Explicit generations re-arm failures; background generations skip them.\n\t * @param sessionId - Optional session projection.\n\t * @returns `true` when at least one current entry is eligible.\n\t */\n\tpublic hasEligibleWork(\n\t\tselectedTokens: ReadonlySet<PersistenceWorkToken>,\n\t\tmode: PersistenceSelectionMode,\n\t\tsessionId?: SessionId\n\t): boolean {\n\t\treturn this._findEligible(selectedTokens, mode, sessionId) !== undefined;\n\t}\n\n\t/**\n\t * Selects the oldest currently eligible work and records it in the generation set.\n\t *\n\t * @param selectedTokens - Mutable set owned by the caller's generation.\n\t * @param mode - Explicit generations re-arm failures; background generations skip them.\n\t * @param sessionId - Optional session projection.\n\t * @returns The selected work, or `undefined` when no current entry is eligible.\n\t */\n\tpublic nextEligibleWork(\n\t\tselectedTokens: Set<PersistenceWorkToken>,\n\t\tmode: PersistenceSelectionMode,\n\t\tsessionId?: SessionId\n\t): PersistenceWork | undefined {\n\t\tconst entry = this._findEligible(selectedTokens, mode, sessionId);\n\t\tif (entry === undefined) return undefined;\n\t\tselectedTokens.add(entry.work.token);\n\t\treturn entry.work;\n\t}\n\n\t/**\n\t * Acknowledges successful persistence using exact token/version CAS semantics.\n\t *\n\t * @param work - Previously selected work handle.\n\t */\n\tpublic acknowledgeSuccess(work: PersistenceWork): void {\n\t\tconst entry = this._currentEntry(work);\n\t\tif (entry === undefined) return;\n\t\tswitch (work.kind) {\n\t\t\tcase 'thought': {\n\t\t\t\tconst index = this._thoughts.findIndex((candidate) => candidate === entry);\n\t\t\t\tif (index >= 0) {\n\t\t\t\t\tthis._thoughts.splice(index, 1);\n\t\t\t\t\tif (work.thought.id !== undefined) {\n\t\t\t\t\t\tthis._removeThoughtIdentity(work.sessionId, work.thought.id);\n\t\t\t\t\t}\n\t\t\t\t\tthis._durableThoughtIdentities.appendThought(work.sessionId, work.thought);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase 'backtrack': {\n\t\t\t\tconst index = this._thoughts.findIndex((candidate) => candidate === entry);\n\t\t\t\tif (index >= 0) {\n\t\t\t\t\tthis._thoughts.splice(index, 1);\n\t\t\t\t\tif (work.thought.id !== undefined) {\n\t\t\t\t\t\tthis._removeThoughtIdentity(work.sessionId, work.thought.id);\n\t\t\t\t\t}\n\t\t\t\t\tthis._durableThoughtIdentities.appendThought(work.sessionId, work.thought);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tcase 'branch':\n\t\t\t\tthis._branches.get(work.sessionId)?.delete(work.key);\n\t\t\t\tif (!this._persistBranches) return;\n\t\t\t\tif (work.operation === 'save') {\n\t\t\t\t\tthis._durableThoughtIdentities.replaceBranch(work.sessionId, work.key, work.snapshot);\n\t\t\t\t} else {\n\t\t\t\t\tthis._durableThoughtIdentities.deleteBranch(work.sessionId, work.key);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\tcase 'edge':\n\t\t\t\tthis._edges.delete(work.key);\n\t\t\t\treturn;\n\t\t\tcase 'summary':\n\t\t\t\tthis._summaries.delete(work.key);\n\t\t\t\treturn;\n\t\t\tdefault:\n\t\t\t\tassertNever(work);\n\t\t}\n\t}\n\n\t/**\n\t * Attaches a terminal failure only when both work and failure still match current work.\n\t *\n\t * @param work - Previously selected work handle.\n\t * @param failure - Terminal backend failure attributed to that handle.\n\t */\n\tpublic acknowledgeFailure(work: PersistenceWork, failure: PersistenceWorkFailure): void {\n\t\tif (!this._matchesFailure(work, failure)) return;\n\t\tconst entry = this._currentEntry(work);\n\t\tif (entry !== undefined) entry.terminalFailure = Object.freeze({ ...failure });\n\t}\n\n\t/**\n\t * Returns an immutable acceptance-ordered snapshot of current terminal failures.\n\t *\n\t * @param selectedTokens - Optional generation-token projection.\n\t * @param sessionId - Optional session projection.\n\t * @returns A fresh readonly failure array containing only failures on current entries.\n\t */\n\tpublic currentFailures(\n\t\tselectedTokens?: ReadonlySet<PersistenceWorkToken>,\n\t\tsessionId?: SessionId\n\t): readonly PersistenceWorkFailure[] {\n\t\tconst failures = this._entries()\n\t\t\t.filter(\n\t\t\t\t(entry) =>\n\t\t\t\t\tentry.terminalFailure !== undefined &&\n\t\t\t\t\t(selectedTokens === undefined || selectedTokens.has(entry.work.token)) &&\n\t\t\t\t\t(sessionId === undefined || entry.work.sessionId === sessionId)\n\t\t\t)\n\t\t\t.sort((left, right) => left.acceptedSequence - right.acceptedSequence)\n\t\t\t.flatMap((entry) => (entry.terminalFailure === undefined ? [] : [entry.terminalFailure]));\n\t\treturn Object.freeze(failures);\n\t}\n\n\t/**\n\t * Captures the current immutable result for a generation or session projection.\n\t *\n\t * @param selectedTokens - Optional generation-token projection.\n\t * @param sessionId - Optional session projection.\n\t * @returns A result containing a fresh readonly failure snapshot.\n\t */\n\tpublic generationResult(\n\t\tselectedTokens?: ReadonlySet<PersistenceWorkToken>,\n\t\tsessionId?: SessionId\n\t): PersistenceGenerationResult {\n\t\treturn Object.freeze({ failures: this.currentFailures(selectedTokens, sessionId) });\n\t}\n\n\t/** @returns Number of accepted thought writes not yet acknowledged successful. */\n\tpublic get pendingThoughtCount(): number {\n\t\treturn this._thoughts.length;\n\t}\n\n\t/** @returns Number of all current thought and coalesced auxiliary entries. */\n\tpublic get pendingWorkCount(): number {\n\t\tlet branchCount = 0;\n\t\tfor (const branches of this._branches.values()) branchCount += branches.size;\n\t\treturn this._thoughts.length + branchCount + this._edges.size + this._summaries.size;\n\t}\n\n\t/** @returns Whether any accepted work remains for a session across all work kinds. */\n\tpublic hasSessionWork(sessionId: SessionId): boolean {\n\t\treturn this._entries().some((entry) => entry.work.sessionId === sessionId);\n\t}\n\n\t/** @returns Whether current retained work for a session owns a terminal failure. */\n\tpublic hasSessionTerminalFailure(sessionId: SessionId): boolean {\n\t\treturn this.currentFailures(undefined, sessionId).length > 0;\n\t}\n\n\t/**\n\t * Forgets version coordinates only after all accepted work for a session is gone.\n\t *\n\t * @returns `false` without mutation while any accepted work remains.\n\t */\n\tpublic forgetQuiescentSession(sessionId: SessionId): boolean {\n\t\tif (this.hasSessionWork(sessionId)) return false;\n\t\tthis._branches.delete(sessionId);\n\t\tthis._branchVersions.delete(sessionId);\n\t\tthis._edgeVersions.delete(sessionId);\n\t\tthis._summaryVersions.delete(sessionId);\n\t\treturn true;\n\t}\n\n\t/** Discards every retained work item and version coordinate for one deleted session. */\n\tpublic discardSession(sessionId: SessionId): void {\n\t\tfor (let index = this._thoughts.length - 1; index >= 0; index -= 1) {\n\t\t\tif (this._thoughts[index]?.work.sessionId === sessionId) this._thoughts.splice(index, 1);\n\t\t}\n\t\tthis._thoughtIdentities.delete(sessionId);\n\t\tthis._durableThoughtIdentities.clearSession(sessionId);\n\t\tthis._branches.delete(sessionId);\n\t\tthis._edges.delete(sessionId);\n\t\tthis._summaries.delete(sessionId);\n\t\tthis._branchVersions.delete(sessionId);\n\t\tthis._edgeVersions.delete(sessionId);\n\t\tthis._summaryVersions.delete(sessionId);\n\t}\n\n\t/** Discards all retained work after a successful durable global reset. */\n\tpublic discardAll(): void {\n\t\tthis._thoughts.length = 0;\n\t\tthis._thoughtIdentities.clear();\n\t\tthis._durableThoughtIdentities.clearAll();\n\t\tthis._branches.clear();\n\t\tthis._edges.clear();\n\t\tthis._summaries.clear();\n\t\tthis._branchVersions.clear();\n\t\tthis._edgeVersions.clear();\n\t\tthis._summaryVersions.clear();\n\t}\n\n\tprivate _accept(): Acceptance {\n\t\tconst sequence = this._nextSequence;\n\t\tthis._nextSequence += 1;\n\t\treturn { token: `persistence-work-${sequence}`, sequence };\n\t}\n\n\tprivate _freezeClone<T>(value: T): T {\n\t\tconst clone = structuredClone(value);\n\t\treturn this._deepFreeze(clone);\n\t}\n\n\tprivate _deepFreeze<T>(value: T): T {\n\t\tif (value !== null && typeof value === 'object') {\n\t\t\tfor (const nested of Object.values(value)) this._deepFreeze(nested);\n\t\t\tObject.freeze(value);\n\t\t}\n\t\treturn value;\n\t}\n\n\tprivate _addThoughtIdentity(sessionId: SessionId, thoughtId: ThoughtId): void {\n\t\tconst identities = this._thoughtIdentities.get(sessionId) ?? new Map<ThoughtId, number>();\n\t\tidentities.set(thoughtId, (identities.get(thoughtId) ?? 0) + 1);\n\t\tthis._thoughtIdentities.set(sessionId, identities);\n\t}\n\n\tprivate _removeThoughtIdentity(sessionId: SessionId, thoughtId: ThoughtId): void {\n\t\tconst identities = this._thoughtIdentities.get(sessionId);\n\t\tconst count = identities?.get(thoughtId);\n\t\tif (identities === undefined || count === undefined) return;\n\t\tif (count > 1) identities.set(thoughtId, count - 1);\n\t\telse identities.delete(thoughtId);\n\t\tif (identities.size === 0) this._thoughtIdentities.delete(sessionId);\n\t}\n\n\tprivate _entries(): AnyQueueEntry[] {\n\t\tconst entries: AnyQueueEntry[] = [...this._thoughts];\n\t\tfor (const branches of this._branches.values()) entries.push(...branches.values());\n\t\tentries.push(...this._edges.values(), ...this._summaries.values());\n\t\treturn entries;\n\t}\n\n\tprivate _findEligible(\n\t\tselectedTokens: ReadonlySet<PersistenceWorkToken>,\n\t\tmode: PersistenceSelectionMode,\n\t\tsessionId?: SessionId\n\t): AnyQueueEntry | undefined {\n\t\tlet oldest: AnyQueueEntry | undefined;\n\t\tfor (const entry of this._entries()) {\n\t\t\tif (selectedTokens.has(entry.work.token)) continue;\n\t\t\tif (sessionId !== undefined && entry.work.sessionId !== sessionId) continue;\n\t\t\tif (!this._modeAllows(mode, entry.terminalFailure !== undefined)) continue;\n\t\t\tif (oldest === undefined || entry.acceptedSequence < oldest.acceptedSequence) oldest = entry;\n\t\t}\n\t\treturn oldest;\n\t}\n\n\tprivate _modeAllows(mode: PersistenceSelectionMode, hasTerminalFailure: boolean): boolean {\n\t\tswitch (mode) {\n\t\t\tcase 'explicit':\n\t\t\t\treturn true;\n\t\t\tcase 'background':\n\t\t\t\treturn !hasTerminalFailure;\n\t\t\tdefault:\n\t\t\t\treturn assertNever(mode);\n\t\t}\n\t}\n\n\tprivate _currentEntry(work: PersistenceWork): AnyQueueEntry | undefined {\n\t\tlet entry: AnyQueueEntry | undefined;\n\t\tswitch (work.kind) {\n\t\t\tcase 'thought':\n\t\t\tcase 'backtrack':\n\t\t\t\tentry = this._thoughts.find((candidate) => candidate.work.token === work.token);\n\t\t\t\tbreak;\n\t\t\tcase 'branch':\n\t\t\t\tentry = this._branches.get(work.sessionId)?.get(work.key);\n\t\t\t\tbreak;\n\t\t\tcase 'edge':\n\t\t\t\tentry = this._edges.get(work.key);\n\t\t\t\tbreak;\n\t\t\tcase 'summary':\n\t\t\t\tentry = this._summaries.get(work.key);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\treturn assertNever(work);\n\t\t}\n\t\treturn entry !== undefined && this._matchesWork(entry.work, work) ? entry : undefined;\n\t}\n\n\tprivate _matchesWork(current: PersistenceWork, selected: PersistenceWork): boolean {\n\t\tif (\n\t\t\tcurrent.kind !== selected.kind ||\n\t\t\tcurrent.token !== selected.token ||\n\t\t\tcurrent.sessionId !== selected.sessionId\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\t\tswitch (selected.kind) {\n\t\t\tcase 'thought':\n\t\t\t\treturn current.kind === 'thought';\n\t\t\tcase 'backtrack':\n\t\t\t\treturn current.kind === 'backtrack' && current.targetThoughtId === selected.targetThoughtId;\n\t\t\tcase 'branch':\n\t\t\t\treturn (\n\t\t\t\t\tcurrent.kind === 'branch' &&\n\t\t\t\t\tcurrent.operation === selected.operation &&\n\t\t\t\t\tcurrent.key === selected.key &&\n\t\t\t\t\tcurrent.version === selected.version\n\t\t\t\t);\n\t\t\tcase 'edge':\n\t\t\t\treturn (\n\t\t\t\t\tcurrent.kind === 'edge' &&\n\t\t\t\t\tcurrent.key === selected.key &&\n\t\t\t\t\tcurrent.version === selected.version\n\t\t\t\t);\n\t\t\tcase 'summary':\n\t\t\t\treturn (\n\t\t\t\t\tcurrent.kind === 'summary' &&\n\t\t\t\t\tcurrent.key === selected.key &&\n\t\t\t\t\tcurrent.version === selected.version\n\t\t\t\t);\n\t\t\tdefault:\n\t\t\t\treturn assertNever(selected);\n\t\t}\n\t}\n\n\tprivate _matchesFailure(work: PersistenceWork, failure: PersistenceWorkFailure): boolean {\n\t\tif (\n\t\t\twork.kind !== failure.kind ||\n\t\t\twork.token !== failure.token ||\n\t\t\twork.sessionId !== failure.sessionId\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\t\tswitch (work.kind) {\n\t\t\tcase 'thought':\n\t\t\tcase 'backtrack':\n\t\t\t\treturn true;\n\t\t\tcase 'branch':\n\t\t\t\treturn (\n\t\t\t\t\tfailure.kind === 'branch' &&\n\t\t\t\t\twork.operation === failure.operation &&\n\t\t\t\t\twork.key === failure.key &&\n\t\t\t\t\twork.version === failure.version\n\t\t\t\t);\n\t\t\tcase 'edge':\n\t\t\tcase 'summary':\n\t\t\t\treturn 'key' in failure && work.key === failure.key && work.version === failure.version;\n\t\t\tdefault:\n\t\t\t\treturn assertNever(work);\n\t\t}\n\t}\n}\n"],"names":["PersistenceWorkQueue","Map","durableHistorySize","persistBranches","DurableThoughtIdentityIndex","normalizeDurableHistoryRetention","sessionId","thought","acceptance","work","Object","undefined","targetThoughtId","thoughtId","sessions","branchId","thoughts","versionMap","version","branchMap","edges","summaries","selectedTokens","mode","entry","index","candidate","assertNever","failure","failures","left","right","branchCount","branches","sequence","value","clone","structuredClone","nested","identities","count","entries","oldest","hasTerminalFailure","current","selected"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PersistenceWriter.d.ts","sourceRoot":"","sources":["../../src/core/PersistenceWriter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,OAAO,KAAK,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAKhG,yDAAyD;AACzD,MAAM,MAAM,gBAAgB,GAAG,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEvE,6EAA6E;AAC7E,MAAM,MAAM,uBAAuB,GAAG;IACrC,QAAQ,CAAC,WAAW,EAAE,kBAAkB,CAAC;IACzC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,QAAQ,CAAC,KAAK,CAAC,EAAE,gBAAgB,CAAC;CAClC,CAAC;AAEF,4EAA4E;AAC5E,MAAM,MAAM,sBAAsB,GAAG,IAAI,GAAG,sBAAsB,CAAC;AAMnE;;;;;;;;;;;;GAYG;AACH,qBAAa,iBAAiB;IAC7B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqB;IAClD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAoB;IACjD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;IAE1C;;;;;OAKG;gBACgB,MAAM,EAAE,uBAAuB;IAWlD;;;;;OAKG;IACU,KAAK,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAmB1E,OAAO,CAAC,WAAW;YAIL,SAAS;
|
|
1
|
+
{"version":3,"file":"PersistenceWriter.d.ts","sourceRoot":"","sources":["../../src/core/PersistenceWriter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AAC7E,OAAO,KAAK,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,kCAAkC,CAAC;AAKhG,yDAAyD;AACzD,MAAM,MAAM,gBAAgB,GAAG,CAAC,YAAY,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEvE,6EAA6E;AAC7E,MAAM,MAAM,uBAAuB,GAAG;IACrC,QAAQ,CAAC,WAAW,EAAE,kBAAkB,CAAC;IACzC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACzC,QAAQ,CAAC,KAAK,CAAC,EAAE,gBAAgB,CAAC;CAClC,CAAC;AAEF,4EAA4E;AAC5E,MAAM,MAAM,sBAAsB,GAAG,IAAI,GAAG,sBAAsB,CAAC;AAMnE;;;;;;;;;;;;GAYG;AACH,qBAAa,iBAAiB;IAC7B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqB;IAClD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAoB;IACjD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAmB;IAE1C;;;;;OAKG;gBACgB,MAAM,EAAE,uBAAuB;IAWlD;;;;;OAKG;IACU,KAAK,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAmB1E,OAAO,CAAC,WAAW;YAIL,SAAS;IAwBvB,OAAO,CAAC,QAAQ;CA4ChB"}
|
|
@@ -41,6 +41,8 @@ class PersistenceWriter {
|
|
|
41
41
|
switch(work.kind){
|
|
42
42
|
case 'thought':
|
|
43
43
|
return this._persistence.saveThoughtForSession(work.sessionId, work.thought);
|
|
44
|
+
case 'backtrack':
|
|
45
|
+
return this._persistence.saveBacktrackForSession(work.sessionId, work.thought, work.targetThoughtId);
|
|
44
46
|
case 'branch':
|
|
45
47
|
if ('delete' === work.operation) return this._persistence.deleteBranchForSession(work.sessionId, work.key);
|
|
46
48
|
return this._persistence.saveBranchForSession(work.sessionId, work.key, work.snapshot);
|
|
@@ -55,6 +57,7 @@ class PersistenceWriter {
|
|
|
55
57
|
_failure(work, attempts, cause) {
|
|
56
58
|
switch(work.kind){
|
|
57
59
|
case 'thought':
|
|
60
|
+
case 'backtrack':
|
|
58
61
|
return {
|
|
59
62
|
kind: work.kind,
|
|
60
63
|
token: work.token,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core/PersistenceWriter.js","sources":["../../src/core/PersistenceWriter.ts"],"sourcesContent":["/**\n * Bounded persistence dispatch for one accepted work item.\n *\n * @module PersistenceWriter\n */\n\nimport type { PersistenceBackend } from '../contracts/PersistenceBackend.js';\nimport type { PersistenceWork, PersistenceWorkFailure } from '../contracts/persistence-work.js';\nimport { assertNever } from '../utils.js';\n\nconst DEFAULT_RETRY_DELAYS = [100, 500, 2000] as const;\n\n/** Async scheduler used between persistence attempts. */\nexport type PersistenceDelay = (milliseconds: number) => Promise<void>;\n\n/** Immutable dependencies and retry policy for {@link PersistenceWriter}. */\nexport type PersistenceWriterConfig = {\n\treadonly persistence: PersistenceBackend;\n\treadonly maxRetries: number;\n\treadonly retryDelays?: readonly number[];\n\treadonly delay?: PersistenceDelay;\n};\n\n/** Allocation-free success sentinel or an attributable terminal failure. */\nexport type PersistenceWriteResult = true | PersistenceWorkFailure;\n\nfunction defaultDelay(milliseconds: number): Promise<void> {\n\treturn new Promise((resolve) => setTimeout(resolve, milliseconds));\n}\n\n/**\n * Writes one sealed persistence item with a bounded retry policy.\n *\n * The writer owns no queue or generation state. Each call preserves the work\n * coordinates and delegates retention or error aggregation to its caller.\n *\n * @example\n * ```ts\n * const writer = new PersistenceWriter({ persistence, maxRetries: 0 });\n * const result = await writer.write(work);\n * if (result !== true) failures.push(result);\n * ```\n */\nexport class PersistenceWriter {\n\tprivate readonly _persistence: PersistenceBackend;\n\tprivate readonly _maxRetries: number;\n\tprivate readonly _retryDelays: readonly number[];\n\tprivate readonly _delay: PersistenceDelay;\n\n\t/**\n\t * Creates a bounded writer.\n\t *\n\t * @param config - Persistence dependency, retry bound, cadence, and delay scheduler.\n\t * @throws {RangeError} When `maxRetries` is not a non-negative safe integer.\n\t */\n\tpublic constructor(config: PersistenceWriterConfig) {\n\t\tif (!Number.isSafeInteger(config.maxRetries) || config.maxRetries < 0) {\n\t\t\tthrow new RangeError('maxRetries must be a non-negative safe integer');\n\t\t}\n\n\t\tthis._persistence = config.persistence;\n\t\tthis._maxRetries = config.maxRetries;\n\t\tthis._retryDelays = [...(config.retryDelays ?? DEFAULT_RETRY_DELAYS)];\n\t\tthis._delay = config.delay ?? defaultDelay;\n\t}\n\n\t/**\n\t * Writes one item once initially and at most `maxRetries` additional times.\n\t *\n\t * @param work - Sealed persistence item selected by the coordinator.\n\t * @returns `true` on success, or the exact attributable failure after exhaustion.\n\t */\n\tpublic async write(work: PersistenceWork): Promise<PersistenceWriteResult> {\n\t\tlet finalCause: unknown;\n\n\t\tfor (let attemptIndex = 0; attemptIndex <= this._maxRetries; attemptIndex++) {\n\t\t\tif (attemptIndex > 0) {\n\t\t\t\tawait this._delay(this._retryDelay(attemptIndex - 1));\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tawait this._dispatch(work);\n\t\t\t\treturn true;\n\t\t\t} catch (cause) {\n\t\t\t\tfinalCause = cause;\n\t\t\t}\n\t\t}\n\n\t\treturn this._failure(work, this._maxRetries + 1, finalCause);\n\t}\n\n\tprivate _retryDelay(retryIndex: number): number {\n\t\treturn this._retryDelays[retryIndex] ?? this._retryDelays.at(-1) ?? 0;\n\t}\n\n\tprivate async _dispatch(work: PersistenceWork): Promise<void> {\n\t\tswitch (work.kind) {\n\t\t\tcase 'thought':\n\t\t\t\treturn this._persistence.saveThoughtForSession(work.sessionId, work.thought);\n\t\t\tcase 'branch':\n\t\t\t\tif (work.operation === 'delete') {\n\t\t\t\t\treturn this._persistence.deleteBranchForSession(work.sessionId, work.key);\n\t\t\t\t}\n\t\t\t\treturn this._persistence.saveBranchForSession(work.sessionId, work.key, work.snapshot);\n\t\t\tcase 'edge':\n\t\t\t\treturn this._persistence.saveEdges(work.sessionId, work.snapshot);\n\t\t\tcase 'summary':\n\t\t\t\treturn this._persistence.saveSummaries(work.sessionId, work.snapshot);\n\t\t\tdefault:\n\t\t\t\treturn assertNever(work);\n\t\t}\n\t}\n\n\tprivate _failure(\n\t\twork: PersistenceWork,\n\t\tattempts: number,\n\t\tcause: unknown\n\t): PersistenceWorkFailure {\n\t\tswitch (work.kind) {\n\t\t\tcase 'thought':\n\t\t\t\treturn { kind: work.kind, token: work.token, sessionId: work.sessionId, attempts, cause };\n\t\t\tcase 'branch':\n\t\t\t\treturn {\n\t\t\t\t\tkind: work.kind,\n\t\t\t\t\toperation: work.operation,\n\t\t\t\t\ttoken: work.token,\n\t\t\t\t\tsessionId: work.sessionId,\n\t\t\t\t\tkey: work.key,\n\t\t\t\t\tversion: work.version,\n\t\t\t\t\tattempts,\n\t\t\t\t\tcause,\n\t\t\t\t};\n\t\t\tcase 'edge':\n\t\t\t\treturn {\n\t\t\t\t\tkind: work.kind,\n\t\t\t\t\ttoken: work.token,\n\t\t\t\t\tsessionId: work.sessionId,\n\t\t\t\t\tkey: work.key,\n\t\t\t\t\tversion: work.version,\n\t\t\t\t\tattempts,\n\t\t\t\t\tcause,\n\t\t\t\t};\n\t\t\tcase 'summary':\n\t\t\t\treturn {\n\t\t\t\t\tkind: work.kind,\n\t\t\t\t\ttoken: work.token,\n\t\t\t\t\tsessionId: work.sessionId,\n\t\t\t\t\tkey: work.key,\n\t\t\t\t\tversion: work.version,\n\t\t\t\t\tattempts,\n\t\t\t\t\tcause,\n\t\t\t\t};\n\t\t\tdefault:\n\t\t\t\treturn assertNever(work);\n\t\t}\n\t}\n}\n"],"names":["DEFAULT_RETRY_DELAYS","defaultDelay","milliseconds","Promise","resolve","setTimeout","PersistenceWriter","config","Number","RangeError","work","finalCause","attemptIndex","cause","retryIndex","assertNever","attempts"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"core/PersistenceWriter.js","sources":["../../src/core/PersistenceWriter.ts"],"sourcesContent":["/**\n * Bounded persistence dispatch for one accepted work item.\n *\n * @module PersistenceWriter\n */\n\nimport type { PersistenceBackend } from '../contracts/PersistenceBackend.js';\nimport type { PersistenceWork, PersistenceWorkFailure } from '../contracts/persistence-work.js';\nimport { assertNever } from '../utils.js';\n\nconst DEFAULT_RETRY_DELAYS = [100, 500, 2000] as const;\n\n/** Async scheduler used between persistence attempts. */\nexport type PersistenceDelay = (milliseconds: number) => Promise<void>;\n\n/** Immutable dependencies and retry policy for {@link PersistenceWriter}. */\nexport type PersistenceWriterConfig = {\n\treadonly persistence: PersistenceBackend;\n\treadonly maxRetries: number;\n\treadonly retryDelays?: readonly number[];\n\treadonly delay?: PersistenceDelay;\n};\n\n/** Allocation-free success sentinel or an attributable terminal failure. */\nexport type PersistenceWriteResult = true | PersistenceWorkFailure;\n\nfunction defaultDelay(milliseconds: number): Promise<void> {\n\treturn new Promise((resolve) => setTimeout(resolve, milliseconds));\n}\n\n/**\n * Writes one sealed persistence item with a bounded retry policy.\n *\n * The writer owns no queue or generation state. Each call preserves the work\n * coordinates and delegates retention or error aggregation to its caller.\n *\n * @example\n * ```ts\n * const writer = new PersistenceWriter({ persistence, maxRetries: 0 });\n * const result = await writer.write(work);\n * if (result !== true) failures.push(result);\n * ```\n */\nexport class PersistenceWriter {\n\tprivate readonly _persistence: PersistenceBackend;\n\tprivate readonly _maxRetries: number;\n\tprivate readonly _retryDelays: readonly number[];\n\tprivate readonly _delay: PersistenceDelay;\n\n\t/**\n\t * Creates a bounded writer.\n\t *\n\t * @param config - Persistence dependency, retry bound, cadence, and delay scheduler.\n\t * @throws {RangeError} When `maxRetries` is not a non-negative safe integer.\n\t */\n\tpublic constructor(config: PersistenceWriterConfig) {\n\t\tif (!Number.isSafeInteger(config.maxRetries) || config.maxRetries < 0) {\n\t\t\tthrow new RangeError('maxRetries must be a non-negative safe integer');\n\t\t}\n\n\t\tthis._persistence = config.persistence;\n\t\tthis._maxRetries = config.maxRetries;\n\t\tthis._retryDelays = [...(config.retryDelays ?? DEFAULT_RETRY_DELAYS)];\n\t\tthis._delay = config.delay ?? defaultDelay;\n\t}\n\n\t/**\n\t * Writes one item once initially and at most `maxRetries` additional times.\n\t *\n\t * @param work - Sealed persistence item selected by the coordinator.\n\t * @returns `true` on success, or the exact attributable failure after exhaustion.\n\t */\n\tpublic async write(work: PersistenceWork): Promise<PersistenceWriteResult> {\n\t\tlet finalCause: unknown;\n\n\t\tfor (let attemptIndex = 0; attemptIndex <= this._maxRetries; attemptIndex++) {\n\t\t\tif (attemptIndex > 0) {\n\t\t\t\tawait this._delay(this._retryDelay(attemptIndex - 1));\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tawait this._dispatch(work);\n\t\t\t\treturn true;\n\t\t\t} catch (cause) {\n\t\t\t\tfinalCause = cause;\n\t\t\t}\n\t\t}\n\n\t\treturn this._failure(work, this._maxRetries + 1, finalCause);\n\t}\n\n\tprivate _retryDelay(retryIndex: number): number {\n\t\treturn this._retryDelays[retryIndex] ?? this._retryDelays.at(-1) ?? 0;\n\t}\n\n\tprivate async _dispatch(work: PersistenceWork): Promise<void> {\n\t\tswitch (work.kind) {\n\t\t\tcase 'thought':\n\t\t\t\treturn this._persistence.saveThoughtForSession(work.sessionId, work.thought);\n\t\t\tcase 'backtrack':\n\t\t\t\treturn this._persistence.saveBacktrackForSession(\n\t\t\t\t\twork.sessionId,\n\t\t\t\t\twork.thought,\n\t\t\t\t\twork.targetThoughtId\n\t\t\t\t);\n\t\t\tcase 'branch':\n\t\t\t\tif (work.operation === 'delete') {\n\t\t\t\t\treturn this._persistence.deleteBranchForSession(work.sessionId, work.key);\n\t\t\t\t}\n\t\t\t\treturn this._persistence.saveBranchForSession(work.sessionId, work.key, work.snapshot);\n\t\t\tcase 'edge':\n\t\t\t\treturn this._persistence.saveEdges(work.sessionId, work.snapshot);\n\t\t\tcase 'summary':\n\t\t\t\treturn this._persistence.saveSummaries(work.sessionId, work.snapshot);\n\t\t\tdefault:\n\t\t\t\treturn assertNever(work);\n\t\t}\n\t}\n\n\tprivate _failure(\n\t\twork: PersistenceWork,\n\t\tattempts: number,\n\t\tcause: unknown\n\t): PersistenceWorkFailure {\n\t\tswitch (work.kind) {\n\t\t\tcase 'thought':\n\t\t\tcase 'backtrack':\n\t\t\t\treturn { kind: work.kind, token: work.token, sessionId: work.sessionId, attempts, cause };\n\t\t\tcase 'branch':\n\t\t\t\treturn {\n\t\t\t\t\tkind: work.kind,\n\t\t\t\t\toperation: work.operation,\n\t\t\t\t\ttoken: work.token,\n\t\t\t\t\tsessionId: work.sessionId,\n\t\t\t\t\tkey: work.key,\n\t\t\t\t\tversion: work.version,\n\t\t\t\t\tattempts,\n\t\t\t\t\tcause,\n\t\t\t\t};\n\t\t\tcase 'edge':\n\t\t\t\treturn {\n\t\t\t\t\tkind: work.kind,\n\t\t\t\t\ttoken: work.token,\n\t\t\t\t\tsessionId: work.sessionId,\n\t\t\t\t\tkey: work.key,\n\t\t\t\t\tversion: work.version,\n\t\t\t\t\tattempts,\n\t\t\t\t\tcause,\n\t\t\t\t};\n\t\t\tcase 'summary':\n\t\t\t\treturn {\n\t\t\t\t\tkind: work.kind,\n\t\t\t\t\ttoken: work.token,\n\t\t\t\t\tsessionId: work.sessionId,\n\t\t\t\t\tkey: work.key,\n\t\t\t\t\tversion: work.version,\n\t\t\t\t\tattempts,\n\t\t\t\t\tcause,\n\t\t\t\t};\n\t\t\tdefault:\n\t\t\t\treturn assertNever(work);\n\t\t}\n\t}\n}\n"],"names":["DEFAULT_RETRY_DELAYS","defaultDelay","milliseconds","Promise","resolve","setTimeout","PersistenceWriter","config","Number","RangeError","work","finalCause","attemptIndex","cause","retryIndex","assertNever","attempts"],"mappings":"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"}
|
|
@@ -8,11 +8,14 @@
|
|
|
8
8
|
* @module core/ThoughtEvaluator
|
|
9
9
|
*/
|
|
10
10
|
import type { ICalibrator } from '../contracts/calibrator.js';
|
|
11
|
-
import type { SessionId } from '../contracts/ids.js';
|
|
11
|
+
import type { SessionId, ThoughtId } from '../contracts/ids.js';
|
|
12
12
|
import type { ConfidenceSignals, PatternSignal, ReasoningStats } from './reasoning.js';
|
|
13
13
|
import type { ThoughtData } from './thought.js';
|
|
14
|
+
export interface VerificationLinkContext {
|
|
15
|
+
readonly verificationTargets?: ReadonlyMap<ThoughtId, ThoughtId>;
|
|
16
|
+
}
|
|
14
17
|
/** Explicit thought and canonical session used for response calibration. */
|
|
15
|
-
export interface ConfidenceSignalContext {
|
|
18
|
+
export interface ConfidenceSignalContext extends VerificationLinkContext {
|
|
16
19
|
readonly currentThought: ThoughtData;
|
|
17
20
|
readonly sessionId: SessionId;
|
|
18
21
|
}
|
|
@@ -41,8 +44,8 @@ export declare class ThoughtEvaluator {
|
|
|
41
44
|
/** Compute confidence signals from history context. Pure computation. */
|
|
42
45
|
computeConfidenceSignals(history: ThoughtData[], branches: Record<string, ThoughtData[]>, context: ConfidenceSignalContext): ConfidenceSignals;
|
|
43
46
|
/** Compute aggregated reasoning analytics. Pure computation. */
|
|
44
|
-
computeReasoningStats(history: ThoughtData[], branches: Record<string, ThoughtData[]
|
|
47
|
+
computeReasoningStats(history: ThoughtData[], branches: Record<string, ThoughtData[]>, context?: VerificationLinkContext): ReasoningStats;
|
|
45
48
|
/** Detect reasoning patterns (anti-patterns and positive signals). Pure computation. */
|
|
46
|
-
computePatternSignals(history: ThoughtData[], branches: Record<string, ThoughtData[]
|
|
49
|
+
computePatternSignals(history: ThoughtData[], branches: Record<string, ThoughtData[]>, context?: VerificationLinkContext): PatternSignal[];
|
|
47
50
|
}
|
|
48
51
|
//# sourceMappingURL=ThoughtEvaluator.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThoughtEvaluator.d.ts","sourceRoot":"","sources":["../../src/core/ThoughtEvaluator.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"ThoughtEvaluator.d.ts","sourceRoot":"","sources":["../../src/core/ThoughtEvaluator.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,KAAK,EAAE,iBAAiB,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACvF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAMhD,MAAM,WAAW,uBAAuB;IACvC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,WAAW,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;CACjE;AAED,4EAA4E;AAC5E,MAAM,WAAW,uBAAwB,SAAQ,uBAAuB;IACvE,QAAQ,CAAC,cAAc,EAAE,WAAW,CAAC;IACrC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;CAC9B;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,gBAAgB;IAC5B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAiB;IACjD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAa;IACzC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAkB;IACnD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;gBAE9B,UAAU,EAAE,WAAW;IAOnC,yEAAyE;IAClE,wBAAwB,CAC9B,OAAO,EAAE,WAAW,EAAE,EACtB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,EACvC,OAAO,EAAE,uBAAuB,GAC9B,iBAAiB;IAsBpB,gEAAgE;IACzD,qBAAqB,CAC3B,OAAO,EAAE,WAAW,EAAE,EACtB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,EACvC,OAAO,GAAE,uBAA4B,GACnC,cAAc;IAMjB,wFAAwF;IACjF,qBAAqB,CAC3B,OAAO,EAAE,WAAW,EAAE,EACtB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,EACvC,OAAO,GAAE,uBAA4B,GACnC,aAAa,EAAE;CAKlB"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Aggregator } from "./evaluator/Aggregator.js";
|
|
2
2
|
import { PatternDetector } from "./evaluator/PatternDetector.js";
|
|
3
3
|
import { SignalComputer } from "./evaluator/SignalComputer.js";
|
|
4
|
+
import { resolveVerificationLinks } from "./evaluator/VerificationLinks.js";
|
|
4
5
|
class ThoughtEvaluator {
|
|
5
6
|
_signalComputer;
|
|
6
7
|
_aggregator;
|
|
@@ -13,8 +14,11 @@ class ThoughtEvaluator {
|
|
|
13
14
|
this._calibrator = calibrator;
|
|
14
15
|
}
|
|
15
16
|
computeConfidenceSignals(history, branches, context) {
|
|
16
|
-
const
|
|
17
|
-
const
|
|
17
|
+
const links = resolveVerificationLinks(history, branches, context.verificationTargets);
|
|
18
|
+
const { branches: b } = filterRetracted(history, branches);
|
|
19
|
+
const signals = this._signalComputer.computeConfidenceSignals([
|
|
20
|
+
...links.thoughts
|
|
21
|
+
], b, links);
|
|
18
22
|
if (!this._calibrator.enabled) return signals;
|
|
19
23
|
const thought = context.currentThought;
|
|
20
24
|
if (void 0 === thought.confidence) return signals;
|
|
@@ -26,13 +30,17 @@ class ThoughtEvaluator {
|
|
|
26
30
|
calibration_metrics: this._calibrator.metrics(sessionId)
|
|
27
31
|
};
|
|
28
32
|
}
|
|
29
|
-
computeReasoningStats(history, branches) {
|
|
30
|
-
const
|
|
31
|
-
|
|
33
|
+
computeReasoningStats(history, branches, context = {}) {
|
|
34
|
+
const links = resolveVerificationLinks(history, branches, context.verificationTargets);
|
|
35
|
+
const { branches: b } = filterRetracted(history, branches);
|
|
36
|
+
return this._aggregator.computeReasoningStats([
|
|
37
|
+
...links.thoughts
|
|
38
|
+
], b, links);
|
|
32
39
|
}
|
|
33
|
-
computePatternSignals(history, branches) {
|
|
40
|
+
computePatternSignals(history, branches, context = {}) {
|
|
34
41
|
const { history: h, branches: b } = filterRetracted(history, branches);
|
|
35
|
-
|
|
42
|
+
const links = resolveVerificationLinks(history, branches, context.verificationTargets);
|
|
43
|
+
return this._patternDetector.computePatternSignals(h, b, links);
|
|
36
44
|
}
|
|
37
45
|
}
|
|
38
46
|
function filterRetracted(history, branches) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"core/ThoughtEvaluator.js","sources":["../../src/core/ThoughtEvaluator.ts"],"sourcesContent":["/**\n * Quality signal computation for sequential thinking.\n *\n * Thin facade that composes the extracted evaluator submodules\n * ({@link SignalComputer}, {@link Aggregator}, {@link PatternDetector})\n * to preserve the original {@link ThoughtEvaluator} public API.\n *\n * @module core/ThoughtEvaluator\n */\n\nimport type { ICalibrator } from '../contracts/calibrator.js';\nimport type { SessionId } from '../contracts/ids.js';\nimport type { ConfidenceSignals, PatternSignal, ReasoningStats } from './reasoning.js';\nimport type { ThoughtData } from './thought.js';\nimport { Aggregator } from './evaluator/Aggregator.js';\nimport { PatternDetector } from './evaluator/PatternDetector.js';\nimport { SignalComputer } from './evaluator/SignalComputer.js';\n\n/** Explicit thought and canonical session used for response calibration. */\nexport interface ConfidenceSignalContext {\n\treadonly currentThought: ThoughtData;\n\treadonly sessionId: SessionId;\n}\n\n/**\n * Stateless service that computes quality signals and reasoning analytics\n * from thought history and branch data.\n *\n * @remarks\n * All methods are pure computations — no side effects, no I/O, no internal state.\n * Designed to be registered as transient in the DI container.\n *\n * @example\n * ```typescript\n * const evaluator = new ThoughtEvaluator(calibrator);\n * const signals = evaluator.computeConfidenceSignals(history, branches, context);\n * const stats = evaluator.computeReasoningStats(history, branches);\n * const patterns = evaluator.computePatternSignals(history, branches);\n * ```\n */\nexport class ThoughtEvaluator {\n\tprivate readonly _signalComputer: SignalComputer;\n\tprivate readonly _aggregator: Aggregator;\n\tprivate readonly _patternDetector: PatternDetector;\n\tprivate readonly _calibrator: ICalibrator;\n\n\tconstructor(calibrator: ICalibrator) {\n\t\tthis._signalComputer = new SignalComputer();\n\t\tthis._aggregator = new Aggregator();\n\t\tthis._patternDetector = new PatternDetector();\n\t\tthis._calibrator = calibrator;\n\t}\n\n\t/** Compute confidence signals from history context. Pure computation. */\n\tpublic computeConfidenceSignals(\n\t\thistory: ThoughtData[],\n\t\tbranches: Record<string, ThoughtData[]>,\n\t\tcontext: ConfidenceSignalContext\n\t): ConfidenceSignals {\n\t\tconst
|
|
1
|
+
{"version":3,"file":"core/ThoughtEvaluator.js","sources":["../../src/core/ThoughtEvaluator.ts"],"sourcesContent":["/**\n * Quality signal computation for sequential thinking.\n *\n * Thin facade that composes the extracted evaluator submodules\n * ({@link SignalComputer}, {@link Aggregator}, {@link PatternDetector})\n * to preserve the original {@link ThoughtEvaluator} public API.\n *\n * @module core/ThoughtEvaluator\n */\n\nimport type { ICalibrator } from '../contracts/calibrator.js';\nimport type { SessionId, ThoughtId } from '../contracts/ids.js';\nimport type { ConfidenceSignals, PatternSignal, ReasoningStats } from './reasoning.js';\nimport type { ThoughtData } from './thought.js';\nimport { Aggregator } from './evaluator/Aggregator.js';\nimport { PatternDetector } from './evaluator/PatternDetector.js';\nimport { SignalComputer } from './evaluator/SignalComputer.js';\nimport { resolveVerificationLinks } from './evaluator/VerificationLinks.js';\n\nexport interface VerificationLinkContext {\n\treadonly verificationTargets?: ReadonlyMap<ThoughtId, ThoughtId>;\n}\n\n/** Explicit thought and canonical session used for response calibration. */\nexport interface ConfidenceSignalContext extends VerificationLinkContext {\n\treadonly currentThought: ThoughtData;\n\treadonly sessionId: SessionId;\n}\n\n/**\n * Stateless service that computes quality signals and reasoning analytics\n * from thought history and branch data.\n *\n * @remarks\n * All methods are pure computations — no side effects, no I/O, no internal state.\n * Designed to be registered as transient in the DI container.\n *\n * @example\n * ```typescript\n * const evaluator = new ThoughtEvaluator(calibrator);\n * const signals = evaluator.computeConfidenceSignals(history, branches, context);\n * const stats = evaluator.computeReasoningStats(history, branches);\n * const patterns = evaluator.computePatternSignals(history, branches);\n * ```\n */\nexport class ThoughtEvaluator {\n\tprivate readonly _signalComputer: SignalComputer;\n\tprivate readonly _aggregator: Aggregator;\n\tprivate readonly _patternDetector: PatternDetector;\n\tprivate readonly _calibrator: ICalibrator;\n\n\tconstructor(calibrator: ICalibrator) {\n\t\tthis._signalComputer = new SignalComputer();\n\t\tthis._aggregator = new Aggregator();\n\t\tthis._patternDetector = new PatternDetector();\n\t\tthis._calibrator = calibrator;\n\t}\n\n\t/** Compute confidence signals from history context. Pure computation. */\n\tpublic computeConfidenceSignals(\n\t\thistory: ThoughtData[],\n\t\tbranches: Record<string, ThoughtData[]>,\n\t\tcontext: ConfidenceSignalContext\n\t): ConfidenceSignals {\n\t\tconst links = resolveVerificationLinks(history, branches, context.verificationTargets);\n\t\tconst { branches: b } = filterRetracted(history, branches);\n\t\tconst signals = this._signalComputer.computeConfidenceSignals([...links.thoughts], b, links);\n\t\tif (!this._calibrator.enabled) return signals;\n\n\t\tconst thought = context.currentThought;\n\t\tif (thought.confidence === undefined) return signals;\n\t\tconst sessionId = context.sessionId;\n\n\t\tconst result = this._calibrator.calibrate(\n\t\t\tthought.confidence,\n\t\t\tthought.thought_type ?? 'regular',\n\t\t\tsessionId\n\t\t);\n\t\treturn {\n\t\t\t...signals,\n\t\t\tcalibrated_confidence: result.calibrated,\n\t\t\tcalibration_metrics: this._calibrator.metrics(sessionId),\n\t\t};\n\t}\n\n\t/** Compute aggregated reasoning analytics. Pure computation. */\n\tpublic computeReasoningStats(\n\t\thistory: ThoughtData[],\n\t\tbranches: Record<string, ThoughtData[]>,\n\t\tcontext: VerificationLinkContext = {}\n\t): ReasoningStats {\n\t\tconst links = resolveVerificationLinks(history, branches, context.verificationTargets);\n\t\tconst { branches: b } = filterRetracted(history, branches);\n\t\treturn this._aggregator.computeReasoningStats([...links.thoughts], b, links);\n\t}\n\n\t/** Detect reasoning patterns (anti-patterns and positive signals). Pure computation. */\n\tpublic computePatternSignals(\n\t\thistory: ThoughtData[],\n\t\tbranches: Record<string, ThoughtData[]>,\n\t\tcontext: VerificationLinkContext = {}\n\t): PatternSignal[] {\n\t\tconst { history: h, branches: b } = filterRetracted(history, branches);\n\t\tconst links = resolveVerificationLinks(history, branches, context.verificationTargets);\n\t\treturn this._patternDetector.computePatternSignals(h, b, links);\n\t}\n}\n\n/**\n * Filters out logically retracted thoughts from history and branches.\n * Retracted thoughts remain in storage (event-sourcing) but are excluded\n * from quality signal calculations.\n */\nfunction filterRetracted(\n\thistory: ThoughtData[],\n\tbranches: Record<string, ThoughtData[]>\n): { history: ThoughtData[]; branches: Record<string, ThoughtData[]> } {\n\tconst h = history.filter((t) => !t.retracted);\n\tconst b: Record<string, ThoughtData[]> = {};\n\tfor (const [id, list] of Object.entries(branches)) {\n\t\tb[id] = list.filter((t) => !t.retracted);\n\t}\n\treturn { history: h, branches: b };\n}\n"],"names":["ThoughtEvaluator","calibrator","SignalComputer","Aggregator","PatternDetector","history","branches","context","links","resolveVerificationLinks","b","filterRetracted","signals","thought","undefined","sessionId","result","h","t","id","list","Object"],"mappings":";;;;AA6CO,MAAMA;IACK,gBAAgC;IAChC,YAAwB;IACxB,iBAAkC;IAClC,YAAyB;IAE1C,YAAYC,UAAuB,CAAE;QACpC,IAAI,CAAC,eAAe,GAAG,IAAIC;QAC3B,IAAI,CAAC,WAAW,GAAG,IAAIC;QACvB,IAAI,CAAC,gBAAgB,GAAG,IAAIC;QAC5B,IAAI,CAAC,WAAW,GAAGH;IACpB;IAGO,yBACNI,OAAsB,EACtBC,QAAuC,EACvCC,OAAgC,EACZ;QACpB,MAAMC,QAAQC,yBAAyBJ,SAASC,UAAUC,QAAQ,mBAAmB;QACrF,MAAM,EAAE,UAAUG,CAAC,EAAE,GAAGC,gBAAgBN,SAASC;QACjD,MAAMM,UAAU,IAAI,CAAC,eAAe,CAAC,wBAAwB,CAAC;eAAIJ,MAAM,QAAQ;SAAC,EAAEE,GAAGF;QACtF,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,OAAOI;QAEtC,MAAMC,UAAUN,QAAQ,cAAc;QACtC,IAAIM,AAAuBC,WAAvBD,QAAQ,UAAU,EAAgB,OAAOD;QAC7C,MAAMG,YAAYR,QAAQ,SAAS;QAEnC,MAAMS,SAAS,IAAI,CAAC,WAAW,CAAC,SAAS,CACxCH,QAAQ,UAAU,EAClBA,QAAQ,YAAY,IAAI,WACxBE;QAED,OAAO;YACN,GAAGH,OAAO;YACV,uBAAuBI,OAAO,UAAU;YACxC,qBAAqB,IAAI,CAAC,WAAW,CAAC,OAAO,CAACD;QAC/C;IACD;IAGO,sBACNV,OAAsB,EACtBC,QAAuC,EACvCC,UAAmC,CAAC,CAAC,EACpB;QACjB,MAAMC,QAAQC,yBAAyBJ,SAASC,UAAUC,QAAQ,mBAAmB;QACrF,MAAM,EAAE,UAAUG,CAAC,EAAE,GAAGC,gBAAgBN,SAASC;QACjD,OAAO,IAAI,CAAC,WAAW,CAAC,qBAAqB,CAAC;eAAIE,MAAM,QAAQ;SAAC,EAAEE,GAAGF;IACvE;IAGO,sBACNH,OAAsB,EACtBC,QAAuC,EACvCC,UAAmC,CAAC,CAAC,EACnB;QAClB,MAAM,EAAE,SAASU,CAAC,EAAE,UAAUP,CAAC,EAAE,GAAGC,gBAAgBN,SAASC;QAC7D,MAAME,QAAQC,yBAAyBJ,SAASC,UAAUC,QAAQ,mBAAmB;QACrF,OAAO,IAAI,CAAC,gBAAgB,CAAC,qBAAqB,CAACU,GAAGP,GAAGF;IAC1D;AACD;AAOA,SAASG,gBACRN,OAAsB,EACtBC,QAAuC;IAEvC,MAAMW,IAAIZ,QAAQ,MAAM,CAAC,CAACa,IAAM,CAACA,EAAE,SAAS;IAC5C,MAAMR,IAAmC,CAAC;IAC1C,KAAK,MAAM,CAACS,IAAIC,KAAK,IAAIC,OAAO,OAAO,CAACf,UACvCI,CAAC,CAACS,GAAG,GAAGC,KAAK,MAAM,CAAC,CAACF,IAAM,CAACA,EAAE,SAAS;IAExC,OAAO;QAAE,SAASD;QAAG,UAAUP;IAAE;AAClC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThoughtProcessor.d.ts","sourceRoot":"","sources":["../../src/core/ThoughtProcessor.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,EAIN,KAAK,SAAS,EAEd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAc,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC/E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAC9D,OAAO,KAAK,EAAE,gBAAgB,EAAoB,MAAM,4BAA4B,CAAC;AACrF,OAAO,KAAK,EAAE,kBAAkB,EAAoB,MAAM,0BAA0B,CAAC;AACrF,OAAO,EAAiB,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC5E,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"ThoughtProcessor.d.ts","sourceRoot":"","sources":["../../src/core/ThoughtProcessor.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,7 @@ import { InvalidBacktrackError, InvalidToolCallError, SequentialThinkingError, U
|
|
|
5
5
|
import { JsonShapeError, enforceJsonShape } from "../sanitize.js";
|
|
6
6
|
import { SequentialThinkingSchema } from "../schema.js";
|
|
7
7
|
import { GraphView } from "./graph/GraphView.js";
|
|
8
|
+
import { buildActiveEvidenceProjection } from "./reasoning/ActiveEvidenceProjection.js";
|
|
8
9
|
import { assertNever } from "../utils.js";
|
|
9
10
|
import { normalizeInput } from "./InputNormalizer.js";
|
|
10
11
|
import { SequentialStrategy } from "./reasoning/strategies/SequentialStrategy.js";
|
|
@@ -152,6 +153,7 @@ class ThoughtProcessor {
|
|
|
152
153
|
return {
|
|
153
154
|
history: [],
|
|
154
155
|
branches: {},
|
|
156
|
+
verificationTargets: new Map(),
|
|
155
157
|
branchIds: [],
|
|
156
158
|
availableMcpTools: void 0,
|
|
157
159
|
availableSkills: void 0
|
|
@@ -221,6 +223,7 @@ class ThoughtProcessor {
|
|
|
221
223
|
sessionId
|
|
222
224
|
});
|
|
223
225
|
}
|
|
226
|
+
this.historyManager.assertThoughtIdentityAvailable(checkedInput);
|
|
224
227
|
if (void 0 !== registerBranchId) this.historyManager.registerBranch(sessionId, registerBranchId);
|
|
225
228
|
if ('tool_call' === validated.thought_type && this._suspensionStore) return this._handleToolCall(validated, admissionContext);
|
|
226
229
|
if ('tool_observation' === validated.thought_type && this._suspensionStore) await this._handleToolObservation(validated, admissionContext);
|
|
@@ -252,12 +255,18 @@ class ThoughtProcessor {
|
|
|
252
255
|
const sessionId = input.session_id;
|
|
253
256
|
const history = this.historyManager.getHistory(sessionId);
|
|
254
257
|
const branches = this.historyManager.getBranches(sessionId);
|
|
258
|
+
const verificationTargets = this.historyManager.inspectSession(sessionId).verificationTargets;
|
|
255
259
|
const confidenceSignals = this._thoughtEvaluator.computeConfidenceSignals(history, branches, {
|
|
256
260
|
currentThought: input,
|
|
257
|
-
sessionId
|
|
261
|
+
sessionId,
|
|
262
|
+
verificationTargets
|
|
263
|
+
});
|
|
264
|
+
const reasoningStats = this._thoughtEvaluator.computeReasoningStats(history, branches, {
|
|
265
|
+
verificationTargets
|
|
266
|
+
});
|
|
267
|
+
const patternSignals = this._thoughtEvaluator.computePatternSignals(history, branches, {
|
|
268
|
+
verificationTargets
|
|
258
269
|
});
|
|
259
|
-
const reasoningStats = this._thoughtEvaluator.computeReasoningStats(history, branches);
|
|
260
|
-
const patternSignals = this._thoughtEvaluator.computePatternSignals(history, branches);
|
|
261
270
|
const reasoningHints = this._generateHints(patternSignals, input.thought_number, sessionId);
|
|
262
271
|
return {
|
|
263
272
|
history,
|
|
@@ -308,12 +317,15 @@ class ThoughtProcessor {
|
|
|
308
317
|
const sessionId = currentThought.session_id;
|
|
309
318
|
let decision;
|
|
310
319
|
try {
|
|
311
|
-
const
|
|
312
|
-
const graph = edgeStore ? new GraphView(edgeStore) : void 0;
|
|
313
|
-
decision = this.strategy.decide({
|
|
320
|
+
const evidence = buildActiveEvidenceProjection({
|
|
314
321
|
sessionId,
|
|
315
322
|
history,
|
|
316
|
-
|
|
323
|
+
branches: this.historyManager.getBranches(sessionId),
|
|
324
|
+
edgeStore: this._getEdgeStore()
|
|
325
|
+
});
|
|
326
|
+
decision = this.strategy.decide({
|
|
327
|
+
sessionId,
|
|
328
|
+
evidence,
|
|
317
329
|
stats,
|
|
318
330
|
currentThought
|
|
319
331
|
});
|