refactor(prompt): decouple subjective from objective, add POV HARD GATE

This commit is contained in:
youzini
2026-06-09 13:47:01 +00:00
parent 63cac35a04
commit b31d59d0e0
5 changed files with 46 additions and 101 deletions

View File

@@ -254,18 +254,20 @@ async function captureTaskTypesForExtract(settings, options = {}) {
const subjectivePayload = capturedPayloads.find(
(payload) => payload.taskType === "extract_subjective",
);
const objectiveRefMapBlock = subjectivePayload?.promptMessages?.find(
(message) => message.sourceKey === "objectiveRefMap",
assert.doesNotMatch(
subjectivePayloadText,
/objectiveRefMap/,
"subjective extraction prompt should NOT receive objective draft/ref context (decoupled)",
);
assert.doesNotMatch(
subjectivePayloadText,
/objectiveExtractionDraft/,
"subjective extraction prompt should NOT receive raw objective draft",
);
assert.match(
subjectivePayloadText,
/evt-clock/,
"subjective extraction prompt should receive objective draft/ref context",
);
assert.match(
String(objectiveRefMapBlock?.content || ""),
/evt-clock/,
"subjective extraction prompt should render objectiveRefMap with objective refs",
/activeCharacterOwner/,
"subjective extraction prompt should receive independently built ownerContext",
);
}

View File

@@ -299,10 +299,7 @@ const splitContextSourceKeys = splitContextPayload.promptMessages
.map((message) => message.sourceKey)
.filter(Boolean);
for (const sourceKey of [
"objectiveExtractionDraft",
"objectiveRefMap",
"ownerContext",
"batchStoryTime",
"relevantPovMemories",
"cognitionStateDigest",
]) {
@@ -311,14 +308,16 @@ for (const sourceKey of [
`subjective prompt should include ${sourceKey}`,
);
}
assert.match(
String(
splitContextPayload.promptMessages.find(
(message) => message.sourceKey === "objectiveExtractionDraft",
)?.content || "",
),
/"ref": "evt1"/,
);
for (const removedKey of [
"objectiveExtractionDraft",
"objectiveRefMap",
"batchStoryTime",
]) {
assert.ok(
!splitContextSourceKeys.includes(removedKey),
`subjective prompt should NOT include ${removedKey}`,
);
}
assert.match(
String(
splitContextPayload.promptMessages.find(
@@ -327,14 +326,6 @@ assert.match(
),
/"ownerName": "艾琳"/,
);
assert.match(
String(
splitContextPayload.promptMessages.find(
(message) => message.sourceKey === "batchStoryTime",
)?.content || "",
),
/"第二天清晨"/,
);
assert.match(
String(
splitContextPayload.promptMessages.find(
@@ -393,6 +384,8 @@ assert.match(String(subFormatBlock?.content || ""), /pov_memory/);
assert.match(String(subFormatBlock?.content || ""), /cognitionUpdates/);
assert.doesNotMatch(String(subFormatBlock?.content || ""), /\"type\": \"event\"/);
assert.doesNotMatch(String(subFormatBlock?.content || ""), /\\\"type\\\"/);
assert.match(String(subRulesBlock?.content || ""), /POV 记忆字段/);
assert.match(String(subRulesBlock?.content || ""), /POV HARD GATE/);
assert.match(String(subRulesBlock?.content || ""), /反锚定/);
assert.match(String(subRulesBlock?.content || ""), /常见错误/);
console.log("prompt-builder-defaults tests passed");