mirror of
https://github.com/sdwolf4103/opencode-working-memory.git
synced 2026-07-17 12:56:42 +02:00
fix: parser accepts bracketless format, rejects project snapshots, adds durable-content prompt
P0a: Parser now accepts both - [type] text and - type text formats P0b: Prompt adds durable-content guidance to avoid session-specific snapshots P0c: Parser quality gate rejects exact test counts, file counts, phase progress - Only rejects phase progress when it appears early in the string (snapshot) - Stable config values with numbers (Admin PIN, Scrypt) still pass - Adds 7 new tests covering bracketless parsing and snapshot rejection
This commit is contained in:
+19
-3
@@ -218,6 +218,19 @@ function shouldAcceptWorkspaceMemoryCandidate(entry: {
|
||||
const pathCount = (text.match(/\/[\w.-]+(\/[\w.-]+)+/g) || []).length;
|
||||
if (pathCount > 2) return false;
|
||||
|
||||
// Session-specific progress snapshots for project type
|
||||
// Only reject when Phase/completed appears at/near START (not mid-description)
|
||||
if (entry.type === "project") {
|
||||
if (/\b\d+\s+tests?\s+pass(?:ed)?\b/i.test(text)) return false;
|
||||
if (/\b\d+\s+suites?\b/i.test(text)) return false;
|
||||
if (/\b\d+\s+(?:files?|文件)\b/i.test(text)) return false;
|
||||
// Reject "Phase N completed" only when it appears early in the string (snapshot)
|
||||
if (text.toLowerCase().indexOf("phase") < 25) {
|
||||
if (/\bphase\s*\d+(?:\s*[-–]\s*\d+)?\s*(?:completed|done|finished)\b/i.test(text)) return false;
|
||||
if (/已完成\s*Phase\s*\d+/i.test(text)) return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -253,10 +266,13 @@ export function parseWorkspaceMemoryCandidates(summary: string): LongTermMemoryE
|
||||
const entries: LongTermMemoryEntry[] = [];
|
||||
|
||||
for (const line of block.split("\n")) {
|
||||
const item = line.trim().match(/^-\s*\[(feedback|project|decision|reference)\]\s*(.+)$/i);
|
||||
// Accept both "- [type] text" (bracketed) and "- type text" (bracketless)
|
||||
const item = line.trim().match(
|
||||
/^-\s*(?:\[(feedback|project|decision|reference)\]|(feedback|project|decision|reference)\b)\s+(.+)$/i,
|
||||
);
|
||||
if (!item) continue;
|
||||
const type = item[1].toLowerCase() as LongTermType;
|
||||
const body = item[2].trim();
|
||||
const type = (item[1] ?? item[2]).toLowerCase() as LongTermType;
|
||||
const body = item[3].trim();
|
||||
if (body.length < 12) continue;
|
||||
|
||||
// Apply quality gate
|
||||
|
||||
+9
-2
@@ -89,8 +89,13 @@ function buildCompactionPrompt(privateContext: string): string {
|
||||
"",
|
||||
"## Relevant Files",
|
||||
"",
|
||||
"At the end of the summary, extract durable memory entries for future",
|
||||
"sessions using these labels:",
|
||||
"At the end of the summary, extract durable memory entries for future sessions.",
|
||||
"Only extract facts that are likely to stay true across sessions.",
|
||||
"Do not extract session-specific progress like exact test counts, file counts, or phase numbers.",
|
||||
"For progress, extract the stable goal or durable milestone, not the current number.",
|
||||
"For references, extract configuration values that do not usually change between sessions.",
|
||||
"For feedback, extract unresolved issues or user preferences that future sessions need to know.",
|
||||
"Use exactly this candidate format, including square brackets around the type:",
|
||||
"",
|
||||
"Memory candidates:",
|
||||
"- [feedback] content",
|
||||
@@ -98,6 +103,8 @@ function buildCompactionPrompt(privateContext: string): string {
|
||||
"- [decision] content",
|
||||
"- [reference] content",
|
||||
"",
|
||||
"Do not write '- project content'; write '- [project] content'.",
|
||||
"",
|
||||
"Background context, use this to inform the summary above.",
|
||||
"Do not output this context verbatim:",
|
||||
"",
|
||||
|
||||
Reference in New Issue
Block a user