@nowcrew/daemon 0.6.88-beta.12 → 0.6.88-beta.14
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.
|
@@ -878,23 +878,26 @@ export function createExecutionJournal(agentsRoot, options = {}) {
|
|
|
878
878
|
},
|
|
879
879
|
acknowledgeCompletion: async (executionId) => {
|
|
880
880
|
validateExecutionId(executionId);
|
|
881
|
-
const
|
|
881
|
+
const result = await serializedExecution(executionId, "acknowledge_completion", async () => {
|
|
882
882
|
const entry = await requireRecord(executionId);
|
|
883
883
|
if (entry.state !== "completed" && entry.state !== "interrupted") {
|
|
884
884
|
throw new JournalTransitionError(`Cannot acknowledge ${entry.state} execution`);
|
|
885
885
|
}
|
|
886
|
-
if (entry.completionAcknowledged)
|
|
887
|
-
return confirmDurable(entry);
|
|
886
|
+
if (entry.completionAcknowledged) {
|
|
887
|
+
return { entry: await confirmDurable(entry), newlyAcknowledged: false };
|
|
888
|
+
}
|
|
888
889
|
const updated = JournalEntrySchema.parse({
|
|
889
890
|
...entry,
|
|
890
891
|
completionAcknowledged: true,
|
|
891
892
|
updatedAt: now().toISOString(),
|
|
892
893
|
});
|
|
893
894
|
await writeRecord(updated);
|
|
894
|
-
return updated;
|
|
895
|
+
return { entry: updated, newlyAcknowledged: true };
|
|
895
896
|
});
|
|
896
|
-
|
|
897
|
-
|
|
897
|
+
// 重复 ACK 仍确认持久化,但不能反复全目录清理并阻塞后续控制帧。
|
|
898
|
+
if (result.newlyAcknowledged)
|
|
899
|
+
await serializedDirectory(pruneInternal);
|
|
900
|
+
return result.entry;
|
|
898
901
|
},
|
|
899
902
|
get: async (executionId) => {
|
|
900
903
|
validateExecutionId(executionId);
|
|
@@ -109,9 +109,15 @@ function replaceGeneratedIndex(memory, entries) {
|
|
|
109
109
|
}
|
|
110
110
|
return `${memory.trimEnd()}\n\n## Knowledge Index\n${generated}\n`;
|
|
111
111
|
}
|
|
112
|
+
function unwrappedNoteBody(title, body) {
|
|
113
|
+
const detail = body.trim();
|
|
114
|
+
const heading = /^([^\r\n]+)\r?\n\r?\n/u.exec(detail);
|
|
115
|
+
// Agent 可能回传包含包装标题的全文;只解开一层,保留内部及历史标题。
|
|
116
|
+
return heading?.[1] === `## ${title}` ? detail.slice(heading[0].length) : detail;
|
|
117
|
+
}
|
|
112
118
|
function noteSection(id, revision, title, body) {
|
|
113
119
|
return `<!-- NOWWORK:MEMORY_ENTRY:BEGIN id=${id} revision=${revision} -->\n`
|
|
114
|
-
+ `## ${title}\n\n${body
|
|
120
|
+
+ `## ${title}\n\n${unwrappedNoteBody(title, body)}\n`
|
|
115
121
|
+ `<!-- NOWWORK:MEMORY_ENTRY:END id=${id} -->\n`;
|
|
116
122
|
}
|
|
117
123
|
function notePattern(id) {
|
|
@@ -455,8 +461,10 @@ export async function applyLocalMemoryResult(input) {
|
|
|
455
461
|
if (duplicate !== undefined) {
|
|
456
462
|
const duplicatePath = resolve(input.agentDir, duplicate.file);
|
|
457
463
|
const duplicateBody = readNoteBody(noteUpdates.get(duplicatePath) ?? await readNote(duplicatePath), duplicate.id);
|
|
458
|
-
if (duplicateBody === change.detailBody
|
|
464
|
+
if (duplicateBody === change.detailBody
|
|
465
|
+
|| duplicateBody === unwrappedNoteBody(change.title, change.detailBody).trim()) {
|
|
459
466
|
resolvedPendingIds.add(pending.pendingId);
|
|
467
|
+
}
|
|
460
468
|
continue;
|
|
461
469
|
}
|
|
462
470
|
const entry = entryFromChange(change, id, 1, "active");
|