feat(role): 角色分層載入與個人記憶同意狀態
role_load.sh 不再原封不動注入整份角色檔,改採 SOUL/AGENTS/USER/MEMORY 分層:只抽出角色 ID、顯示名稱、本質、氛圍與簽名 emoji 作為人格層,由 hook 產生固定操作邊界,記憶與同意狀態獨立成一區。避免人格檔裡的背景故事與模板 文字污染工程與安全規則。 memory.js 新增 consent/consent-status 子命令,同意狀態寫入 ~/.memory/<角色 ID>/state.json 的 personal_memory_consent(accepted/ declined/unknown);role_capture.sh 於本輪出現明確同意或拒絕時更新狀態, 偵測不到明確表述時不自行推論。accepted 後不再每次重問。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+60
-2
@@ -4,7 +4,7 @@
|
||||
// inbox,(2) 產生 SessionStart 要注入的記憶區塊,(3) 睡眠整理時輸出待整理
|
||||
// 素材並套用整理結果(NREM 鞏固/REM 整合、分類、去重、標籤、總結、
|
||||
// 優先度、關聯、壓縮歸檔),(4) 依使用頻率與優先度遺忘日常與其他類記憶。
|
||||
// 更新時間:2026/07/28 12:40:24
|
||||
// 更新時間:2026/07/28 13:50:43
|
||||
// 相依:Node.js 標準庫。
|
||||
// 退出碼:0 成功;1 無內容可處理;2 參數錯誤。呼叫端(hook)一律不得因此中斷。
|
||||
// ==============================================================================
|
||||
@@ -775,6 +775,7 @@ function cmdStats(args) {
|
||||
rows.push(`| 待整理(inbox) | ${listInbox(args.role).length} | - |`);
|
||||
rows.push("");
|
||||
rows.push(`- 記憶目錄:${memoryRoot(args.role)}`);
|
||||
rows.push(`- 個人記憶同意狀態:${consentStatusValue(args.role)}`);
|
||||
rows.push(`- 上次睡眠整理:${state.last_sleep || "尚未整理"}`);
|
||||
rows.push(`- 上次睡眠摘要:${state.last_sleep_digest || "尚無"}`);
|
||||
rows.push(`- 上次遺忘:${state.last_forget || "尚未執行"}`);
|
||||
@@ -803,6 +804,61 @@ function cmdNeedSleep(args) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
function cmdConsent(args) {
|
||||
const value = String(args.value || "").trim().toLowerCase();
|
||||
const normalized = {
|
||||
accept: "accepted",
|
||||
accepted: "accepted",
|
||||
yes: "accepted",
|
||||
true: "accepted",
|
||||
"1": "accepted",
|
||||
decline: "declined",
|
||||
declined: "declined",
|
||||
no: "declined",
|
||||
false: "declined",
|
||||
"0": "declined",
|
||||
unknown: "unknown",
|
||||
}[value];
|
||||
if (!normalized) {
|
||||
process.stderr.write("同意狀態只接受 accepted/declined/unknown\n");
|
||||
return 2;
|
||||
}
|
||||
writeState(args.role, {
|
||||
personal_memory_consent: normalized,
|
||||
personal_memory_consent_updated: nowStamp(),
|
||||
});
|
||||
process.stdout.write(normalized);
|
||||
return 0;
|
||||
}
|
||||
|
||||
function cmdConsentStatus(args) {
|
||||
process.stdout.write(consentStatusValue(args.role));
|
||||
return 0;
|
||||
}
|
||||
|
||||
function consentStatusValue(role) {
|
||||
ensureLayout(role);
|
||||
const state = readState(role);
|
||||
const status = String(state.personal_memory_consent || "unknown").trim();
|
||||
if (["accepted", "declined"].includes(status)) return status;
|
||||
|
||||
const haystacks = [];
|
||||
for (const [meta, content] of listInbox(role)) haystacks.push(`${meta.summary}\n${content}`);
|
||||
for (const category of CATEGORIES) {
|
||||
for (const [meta, content] of listMemories(role, category)) haystacks.push(`${meta.summary}\n${content}`);
|
||||
}
|
||||
const consentText = haystacks
|
||||
.filter((text) => /個人資料|個資|記憶|記住|保存|同意|拒絕/.test(text))
|
||||
.join("\n");
|
||||
if (/不同意|不願意|不要保存|不要記住|拒絕|不可以保存|不可以記住/.test(consentText)) {
|
||||
return "declined";
|
||||
}
|
||||
if (/已同意|明確同意|同意.*保存|同意.*記住|可以保存|可以記住|願意.*保存|願意.*記住/.test(consentText)) {
|
||||
return "accepted";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
function parseArgs(argv) {
|
||||
const command = argv[0];
|
||||
const opts = { command };
|
||||
@@ -836,7 +892,7 @@ function requireRole(args) {
|
||||
function main(argv) {
|
||||
const args = parseArgs(argv);
|
||||
if (!args.command || args.command === "-h" || args.command === "--help") {
|
||||
process.stdout.write(`用法:memory.js <子命令> [參數]\n\n子命令:write、seed、load、collect、apply、forget、stats、mark-sleep、need-sleep\n`);
|
||||
process.stdout.write(`用法:memory.js <子命令> [參數]\n\n子命令:write、seed、load、collect、apply、forget、stats、mark-sleep、need-sleep、consent、consent-status\n`);
|
||||
return 0;
|
||||
}
|
||||
if (!requireRole(args)) return 2;
|
||||
@@ -874,6 +930,8 @@ function main(argv) {
|
||||
stats: cmdStats,
|
||||
"mark-sleep": cmdMarkSleep,
|
||||
"need-sleep": cmdNeedSleep,
|
||||
consent: cmdConsent,
|
||||
"consent-status": cmdConsentStatus,
|
||||
};
|
||||
if (!commands[args.command]) {
|
||||
process.stderr.write("未知子命令\n");
|
||||
|
||||
Reference in New Issue
Block a user