test(selftest): 補動作格渲染與三段式覆寫的案例,641 → 646
新增五項:room read 的括號帶動作格、一對一也拿到括號格式、害羞預設破口是臉紅、 三段式逐人格覆寫生效且不套用預設收尾、沒寫覆寫的人格照舊。 改一項:「劇場模式強制只輸出對話」原本斷言 ctx 含字面「名字:內容」, Q6 把格式改成「名字(情緒・動作):內容」之後那個斷言必然失敗—— 斷言跟著格式走,不是把格式改回去。 覆寫測試的 fixture 刻意用 sulk 這個 key 而不是「鬧彆扭」:後者是 MODESTY_SIGNALS 的推力詞,寫進 IDENTITY 會把羞恥度推過 75 落到惱羞那級,就測不到嘴硬的三段。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+25
-2
@@ -388,6 +388,12 @@ check("room script 只輸出 `名字:內容`(無時間戳、無 slug、無
|
|||||||
script.includes("Beta(") && script.includes(":我是 Beta。") && !script.includes("[20") && !script.includes("system"),
|
script.includes("Beta(") && script.includes(":我是 Beta。") && !script.includes("[20") && !script.includes("system"),
|
||||||
JSON.stringify(script));
|
JSON.stringify(script));
|
||||||
check("劇場模式的對話有 emoji 前綴", script.includes("🌙") && script.includes("🪼"), script);
|
check("劇場模式的對話有 emoji 前綴", script.includes("🌙") && script.includes("🪼"), script);
|
||||||
|
const acted = cli(["room", "post", "--session", S_HOST, "--room", room, "--as", "alpha",
|
||||||
|
"--text", "你不要看這邊。", "--emotion", "羞愧", "--action", "別過頭"]);
|
||||||
|
const roomReadOut = cli(["room", "read", "--session", S_HOST, "--room", room]).stdout;
|
||||||
|
check("room read 的括號也帶動作格(不是只印情緒)",
|
||||||
|
acted.status === 0 && roomReadOut.includes("(羞愧・別過頭)"),
|
||||||
|
JSON.stringify(roomReadOut.slice(-300)));
|
||||||
const quiet = cli(["room", "post", "--session", S_HOST, "--room", room, "--as", "alpha", "--text", "安靜發言", "--quiet"]);
|
const quiet = cli(["room", "post", "--session", S_HOST, "--room", room, "--as", "alpha", "--text", "安靜發言", "--quiet"]);
|
||||||
check("--quiet 成功時不輸出任何字", quiet.status === 0 && quiet.stdout === "", JSON.stringify(quiet.stdout));
|
check("--quiet 成功時不輸出任何字", quiet.status === 0 && quiet.stdout === "", JSON.stringify(quiet.stdout));
|
||||||
cli(["remember", "--persona", "beta", "--session", S_HOST, "--as-guest", "--scope", "inbox", "--room", room,
|
cli(["remember", "--persona", "beta", "--session", S_HOST, "--as-guest", "--scope", "inbox", "--room", room,
|
||||||
@@ -477,8 +483,13 @@ out = hook("turn_end.mjs", { session_id: S_HOST, last_assistant_message: "🪼 A
|
|||||||
check("劇場模式時 Stop 不發任何提醒", out.systemMessage === undefined, JSON.stringify(out));
|
check("劇場模式時 Stop 不發任何提醒", out.systemMessage === undefined, JSON.stringify(out));
|
||||||
out = hook("prompt_submit.mjs", { session_id: S_HOST, prompt: "你們繼續", cwd: HERE });
|
out = hook("prompt_submit.mjs", { session_id: S_HOST, prompt: "你們繼續", cwd: HERE });
|
||||||
ctx = out.hookSpecificOutput?.additionalContext || "";
|
ctx = out.hookSpecificOutput?.additionalContext || "";
|
||||||
check("劇場模式時 UserPromptSubmit 強制只輸出對話", ctx.includes("只能") && ctx.includes("名字:內容"), ctx.slice(-300));
|
check("劇場模式時 UserPromptSubmit 強制只輸出對話",
|
||||||
|
ctx.includes("只能") && ctx.includes("名字(情緒・動作):內容"), ctx.slice(-300));
|
||||||
cli(["room", "theater", "--session", S_HOST, "--off"]);
|
cli(["room", "theater", "--session", S_HOST, "--off"]);
|
||||||
|
out = hook("prompt_submit.mjs", { session_id: S_HOST, prompt: "回來一對一", cwd: HERE });
|
||||||
|
ctx = out.hookSpecificOutput?.additionalContext || "";
|
||||||
|
check("一對一也拿到括號格式(Q6 拍板的是格式,不是只給劇場)",
|
||||||
|
ctx.includes("名字(情緒・動作):內容") && ctx.includes("一對一也適用"), ctx.slice(-400));
|
||||||
out = hook("session_end.mjs", { session_id: S_HOST, reason: "exit" });
|
out = hook("session_end.mjs", { session_id: S_HOST, reason: "exit" });
|
||||||
check("SessionEnd 釋放鎖", !pl.lockStatus("alpha").locked);
|
check("SessionEnd 釋放鎖", !pl.lockStatus("alpha").locked);
|
||||||
check("釋放後其他 session 可載入", cli(["load", "--persona", "alpha", "--session", S_THIRD]).status === 0);
|
check("釋放後其他 session 可載入", cli(["load", "--persona", "alpha", "--session", S_THIRD]).status === 0);
|
||||||
@@ -1062,7 +1073,7 @@ check("情緒的破口有注入,且說明是演出來不是講出來", (() =>
|
|||||||
const ctxTell = pl.turnContext("alpha", S_SPEAK, "那件事做完了嗎");
|
const ctxTell = pl.turnContext("alpha", S_SPEAK, "那件事做完了嗎");
|
||||||
return ctxTell.includes("此刻不自覺會出現的") && ctxTell.includes("疊字") &&
|
return ctxTell.includes("此刻不自覺會出現的") && ctxTell.includes("疊字") &&
|
||||||
ctxTell.includes("不要用旁白說明") && ctxTell.includes("一輪最多露 2 個動作") &&
|
ctxTell.includes("不要用旁白說明") && ctxTell.includes("一輪最多露 2 個動作") &&
|
||||||
ctxTell.includes("同一種情緒");
|
ctxTell.includes("同一種情緒") && ctxTell.includes("算在這個額度裡");
|
||||||
})(), pl.turnContext("alpha", S_SPEAK, "那件事做完了嗎").slice(0, 900));
|
})(), pl.turnContext("alpha", S_SPEAK, "那件事做完了嗎").slice(0, 900));
|
||||||
check("十二情緒每一種都有破口可演",
|
check("十二情緒每一種都有破口可演",
|
||||||
pl.EMOTION_KEYS.every((k) => (pl.EMOTION_TELLS[k] || []).length >= 3));
|
pl.EMOTION_KEYS.every((k) => (pl.EMOTION_TELLS[k] || []).length >= 3));
|
||||||
@@ -1133,6 +1144,8 @@ check("括號兩格:情緒在前、動作在後、用・分隔",
|
|||||||
check("只有情緒時括號照舊(現行行為不變)", pl.roomTag({ emotion: "😳" }) === "(😳)");
|
check("只有情緒時括號照舊(現行行為不變)", pl.roomTag({ emotion: "😳" }) === "(😳)");
|
||||||
check("只有動作時也成立", pl.roomTag({ action: "別過頭" }) === "(別過頭)");
|
check("只有動作時也成立", pl.roomTag({ action: "別過頭" }) === "(別過頭)");
|
||||||
check("兩格都沒有就不出現括號", pl.roomTag({}) === "");
|
check("兩格都沒有就不出現括號", pl.roomTag({}) === "");
|
||||||
|
check("害羞的預設破口第一個就是臉紅(括號動作格的預設值)",
|
||||||
|
pl.EMOTION_TELLS.shame[0] === "臉紅", JSON.stringify(pl.EMOTION_TELLS.shame));
|
||||||
check("記憶可以記行為備註(做了什麼,不是感覺到什麼)", (() => {
|
check("記憶可以記行為備註(做了什麼,不是感覺到什麼)", (() => {
|
||||||
const out = cli(["remember", "--persona", "alpha", "--session", S_SPEAK, "--role", "persona",
|
const out = cli(["remember", "--persona", "alpha", "--session", S_SPEAK, "--role", "persona",
|
||||||
"--text", "他說我修得比上次穩", "--behavior", "把手縮回來", "--salience", "45"]);
|
"--text", "他說我修得比上次穩", "--behavior", "把手縮回來", "--salience", "45"]);
|
||||||
@@ -1170,6 +1183,16 @@ console.log("⑥-d 鬧彆扭的階梯與三段式");
|
|||||||
check("傲嬌那一路的詞會推高羞恥敏感度",
|
check("傲嬌那一路的詞會推高羞恥敏感度",
|
||||||
pl.modestyOf("tsun").value > pl.modestyOf("plainf").value,
|
pl.modestyOf("tsun").value > pl.modestyOf("plainf").value,
|
||||||
`${pl.modestyOf("tsun").value} vs ${pl.modestyOf("plainf").value}`);
|
`${pl.modestyOf("tsun").value} vs ${pl.modestyOf("plainf").value}`);
|
||||||
|
// 覆寫用 `sulk` 這個 key,不用「鬧彆扭」——後者是 MODESTY_SIGNALS 的推力詞,
|
||||||
|
// 寫進 IDENTITY 會把羞恥度推過 75,那就落到惱羞那一級、測不到嘴硬的三段。
|
||||||
|
mkp("ownsulk", "- Name: 丑\n- Creature: 人類女性\n\n## Tells\n- sulk: 把書擋在臉前 → 你很閒嗎 → ⋯隨便你\n",
|
||||||
|
"講話簡短。");
|
||||||
|
const ownShape = pl.modestyDirective("ownsulk", {});
|
||||||
|
check("三段式可以逐人格覆寫(## Tells 的 sulk 那一行)",
|
||||||
|
ownShape.includes("這個人格自己的形狀") && ownShape.includes("把書擋在臉前") &&
|
||||||
|
ownShape.includes("⋯隨便你") && !ownShape.includes("音量掉下來"),
|
||||||
|
`${pl.modestyOf("ownsulk").value}|${ownShape.slice(0, 220)}`);
|
||||||
|
check("沒寫覆寫的人格照舊用預設模板", pl.personaSulk("shyladder").length === 0);
|
||||||
}
|
}
|
||||||
check("說話規則有注入「話短、日常字、看得見的東西、不要回頭解釋」", (() => {
|
check("說話規則有注入「話短、日常字、看得見的東西、不要回頭解釋」", (() => {
|
||||||
const ctxSay = pl.turnContext("alpha", S_SPEAK, "隨便講");
|
const ctxSay = pl.turnContext("alpha", S_SPEAK, "隨便講");
|
||||||
|
|||||||
Reference in New Issue
Block a user