'use strict'; var crypto = require('crypto'); var diff = require('diff'); // src/processors/working-memory-state/processor.ts var WORKING_MEMORY_STATE_ID = "working-memory"; var WORKING_MEMORY_STATE_PROCESSOR_ID = "working-memory-state"; var WorkingMemoryStateProcessor = class { constructor(memory, memoryConfig) { this.memory = memory; this.memoryConfig = memoryConfig; } memory; memoryConfig; id = WORKING_MEMORY_STATE_PROCESSOR_ID; stateId = WORKING_MEMORY_STATE_ID; async computeStateSignal(args) { const template = await this.memory.getWorkingMemoryTemplate({ memoryConfig: this.memoryConfig }); if (!template) return; const data = await this.memory.getWorkingMemory({ threadId: args.threadId, resourceId: args.resourceId, memoryConfig: this.memoryConfig }); const contents = data?.trim(); if (!contents) return; const cacheKey = stableWorkingMemoryCacheKey({ format: template.format, data: contents }); const shouldMakeSnapshot = !args.contextWindow.hasSnapshot; if (args.tracking?.currentCacheKey === cacheKey && !shouldMakeSnapshot) return; const mergedConfig = this.memory.getMergedThreadConfig(this.memoryConfig); const scope = mergedConfig.workingMemory?.scope ?? "resource"; const deltaCandidate = template.format === "markdown" && !shouldMakeSnapshot ? buildMarkdownDelta({ lastSnapshot: args.lastSnapshot, deltasSinceSnapshot: args.deltasSinceSnapshot, nextContents: contents }) : void 0; if (deltaCandidate) { return { id: WORKING_MEMORY_STATE_ID, mode: "delta", cacheKey, tagName: "working-memory", contents: deltaCandidate.contents, delta: deltaCandidate.contents, // Stash the full post-edit text on the signal so the next turn can // diff against the most recently emitted state instead of the older // snapshot. Invisible to the model. value: contents, attributes: { format: template.format, scope, patch: "unified-diff" } }; } return { id: WORKING_MEMORY_STATE_ID, mode: "snapshot", cacheKey, tagName: "working-memory", contents, // Mirror contents in value so the first delta after a snapshot has a // typed prior-state to diff against without falling back to contents. value: contents, attributes: { format: template.format, scope } }; } }; function stableWorkingMemoryCacheKey(input) { const hash = crypto.createHash("sha256"); hash.update(input.format); hash.update("\0"); hash.update(input.data ?? ""); return `sha256:${hash.digest("hex")}`; } function buildMarkdownDelta(args) { const { lastSnapshot, deltasSinceSnapshot, nextContents } = args; const latestDelta = deltasSinceSnapshot.at(-1); const prior = pickStringValue(readSignalValue(latestDelta)) ?? pickStringValue(readSignalValue(lastSnapshot)) ?? (typeof lastSnapshot?.contents === "string" ? lastSnapshot.contents : void 0); if (!prior) return; const patch = renderHunksOnly(prior, nextContents); return { contents: patch }; } function pickStringValue(value) { return typeof value === "string" ? value : void 0; } function readSignalValue(signal) { return signal?.metadata?.value; } function renderHunksOnly(prior, next) { const { hunks } = diff.structuredPatch("", "", prior, next, "", "", { context: 0 }); return hunks.map((hunk) => { const header = `@@ -${hunk.oldStart},${hunk.oldLines} +${hunk.newStart},${hunk.newLines} @@`; const lines = hunk.lines.filter((line) => !line.startsWith("\\ No newline at end of file")); return [header, ...lines].join("\n"); }).join("\n"); } exports.WORKING_MEMORY_STATE_ID = WORKING_MEMORY_STATE_ID; exports.WORKING_MEMORY_STATE_PROCESSOR_ID = WORKING_MEMORY_STATE_PROCESSOR_ID; exports.WorkingMemoryStateProcessor = WorkingMemoryStateProcessor; exports.stableWorkingMemoryCacheKey = stableWorkingMemoryCacheKey; //# sourceMappingURL=chunk-43FJOLKM.cjs.map //# sourceMappingURL=chunk-43FJOLKM.cjs.map