feat(role): 多角色協作、身分人格分離、記憶處理強化與壓縮邊界保全 #18

Merged
admin merged 6 commits from develop into master 2026-07-29 04:05:55 +00:00
2 changed files with 67 additions and 1 deletions
Showing only changes of commit 40c2d2ae46 - Show all commits
+35
View File
@@ -157,6 +157,37 @@ const natureFm = soulRaw ? soulFm : fm;
const nature = section(natureSrc, "本質(nature") || natureFm.nature || "";
const vibe = section(natureSrc, "氛圍(vibe") || natureFm.vibe || "";
// soul 檔的其餘章節(例如核心信念、語氣與風格、邊界與規範)也要注入。
// 只抽固定的兩節會讓使用者在人格檔裡寫的其他章節被靜默丟棄。
function extraSections(text, skip) {
if (!text) return "";
const body = text.replace(/^---\n[\s\S]*?\n---\n?/, "");
const out = [];
const re = /^##\s+(.+)$/gm;
const marks = [];
let m;
while ((m = re.exec(body)) !== null) marks.push([m.index, m[0].length, m[1].trim()]);
for (let i = 0; i < marks.length; i += 1) {
const [idx, len, title] = marks[i];
if (skip.some((s) => title.startsWith(s))) continue;
const end = i + 1 < marks.length ? marks[i + 1][0] : body.length;
const content = body.slice(idx + len, end).trim();
if (content) out.push(`## ${title}`, "", content);
}
return out.join("\n");
}
const extra = extraSections(soulRaw, ["本質", "氛圍"]);
// 標題後、第一個 ## 之前的前言段落(使用者常在此寫存在本質、角色原型等摘要條目)。
// 只抽 frontmatter 與具名章節會讓這段被靜默丟棄。
function preamble(text) {
if (!text) return "";
const body = text.replace(/^---\n[\s\S]*?\n---\n?/, "").replace(/^#\s+[^\n]*\n/, "");
const idx = body.search(/^##\s+/m);
return (idx < 0 ? body : body.slice(0, idx)).trim();
}
const intro = preamble(raw);
// 身分只可能在 identity/舊檔裡
const emoji = section(raw, "簽名 emoji") || fm.emoji || "";
const source = section(raw, "來源(source") || fm.source || "";
@@ -167,6 +198,7 @@ const lines = [
`- 顯示名稱:${fm.name || title || ""}`,
`- 簽名 emoji${fm.emoji || ""}`,
];
if (intro) lines.push("", intro);
if (source) lines.push("", "## 來源(source", "", source);
if (relationship) lines.push("", "## 關係定位(relationship", "", relationship);
lines.push(
@@ -178,6 +210,9 @@ lines.push(
"## 氛圍(vibe",
"",
vibe || "(未設定)",
);
if (extra) lines.push("", extra);
lines.push(
"",
"## 簽名 emoji",
"",
+32 -1
View File
@@ -170,7 +170,10 @@ ROLE_DIR="<skill base directory>/../../scripts/role" # 其他助理
| 共用行為區塊 | 版本 A | 版本 B | 是/否 |
個性欄位若使用者只想改其中一項,其餘一律沿用舊值;**共用行為區塊一律以本 skill 的最新版本覆寫**(該區塊由系統維護)。使用者不確認就不寫入。
8. 寫入 `~/.roles/<id>.identity.md``~/.roles/<id>.soul.md`(UTF-8 無 BOM,格式見「角色檔標準格式」)。身分檔需填來源與關係定位;共用行為不寫入角色檔。
8. 寫入 `~/.roles/<id>.identity.md``~/.roles/<id>.soul.md`(UTF-8 無 BOM,格式見「角色檔標準格式」)。
身分檔需填**來源**與**關係定位**,並可在標題下以條目寫存在本質、角色原型、主要稱呼等摘要;
人格檔除必要的本質與氛圍外,可依角色特性增加核心信念、語氣與風格、邊界與規範等章節。
共用行為**不寫入角色檔**(由 `role_load.sh` 注入)。
9. 建立記憶目錄:`node "${ROLE_DIR}/memory.js" stats --role "<id>"`(會順帶建好 `inbox/`、六個分類與 `archive/`)。
10. 若使用者同意網路搜尋且已取得可保存內容,將搜尋摘要寫成已整理記憶,不進 inbox:
@@ -431,6 +434,8 @@ updated: <yyyy/MM/dd HH:mm:ss>
### `<角色 ID>.soul.md`
`## 本質` 與 `## 氛圍`是必要章節;**其餘章節可自由增加,會一併注入**(例如核心信念、語氣與風格、邊界與規範)。
````markdown
---
id: <角色 ID>
@@ -444,8 +449,34 @@ updated: <yyyy/MM/dd HH:mm:ss>
## 氛圍(vibe
<3 至 5 行:語氣、句子長度、對使用者的稱呼、幽默感尺度、明確禁忌>
## 核心信念
<選填:這個角色在意什麼、用什麼視角看世界、主動性到哪裡>
## 語氣與風格
<選填:語調、表情符號與顏文字習慣、口頭禪;並註明僅適用於自然語言回覆>
## 邊界與規範
<選填:角色專屬的邊界。與共用行為衝突時以共用行為為準>
````
### 注入規則
| 來源 | 是否注入 |
| --- | --- |
| `identity` 的 frontmatter`id``name``emoji` | ✅ |
| `identity` 標題後、第一個 `##` 之前的**前言段落** | ✅ 常用來寫存在本質、角色原型等摘要條目 |
| `identity` 的 `## 來源``## 關係定位``## 簽名 emoji` | ✅ |
| `soul` 的 `## 本質``## 氛圍` | ✅ |
| `soul` 的**其他任何 `##` 章節** | ✅ 不限章節名 |
寫進角色檔的內容若未被注入就等於白寫,因此上述兩處(前言段落與自由章節)都會完整帶入 —— 曾發生使用者在人格檔補寫章節卻被靜默丟棄的情況。
**角色專屬邊界不得放寬共用行為的限制**:共用行為(由 `role_load.sh` 注入)永遠優先,角色檔只能加嚴不能放寬。
`~/.roles/.active` 只放一行角色 ID,代表目前啟用的角色。
---