#!/usr/bin/env node // UserPromptSubmit:每輪注入「人格 + 情緒 + 記憶 + 關係」上下文,並記錄原始逐字。 // // 短期記憶(memory/short-term.jsonl)由 skill 做完語意分析後才寫入(有主題/實體/ // 顯著度/情緒變化);這裡只寫 journal 原始逐字,避免同一句話被記兩次。 // 劇場模式(多人格對話)進行中時,額外強制「只輸出人格對話」。 import { readEvent, respond } from "./_hook.mjs"; import * as pl from "../scripts/persona-lib.mjs"; const event = readEvent(); if (!event) process.exit(0); const sessionId = event.session_id || "unknown"; const prompt = event.prompt || ""; const data = pl.loadSession(sessionId); const host = data.host; if (!host || !pl.personaExists(host)) process.exit(0); pl.heartbeatLock(host, sessionId); for (const [guest, info] of Object.entries(data.guests || {})) { if (pl.personaExists(guest)) pl.addGuestLease(guest, sessionId, info.room || "", host); } pl.appendJsonl(pl.journalPath(host), { ts: pl.nowIso(), kind: "utterance", role: "user", text: prompt.slice(0, 4000), }); const theater = Boolean(data.theater) && (data.rooms || []).length > 0; const hint = theater ? "\n🎭 劇場模式:本輪輸出**只能**是人格對話(`名字:內容`,一行一句)。" + "不要輸出指令、指令結果、狀態、分析、旁白或摘要;CLI 一律加 `--quiet` 並把 stdout 丟到 /dev/null。" + `\n每個人格每輪 ${pl.MAX_SENTENCES} 句以內;推導寫進 \`think\`(心裡話),不要演成旁白;` + "近似重複的台詞會被 `room post` 擋下,換個說法或推進話題。" + "\n**對象只有一個人時,旁人就沒有台詞**:`room post --to <他>` 進一對一,`--to all` 才開回全場(現況看 `room floor`)。" + `\n台詞要像人在講話:短句(一句 ${pl.MAX_SENTENCE_CHARS} 字內)、日常用詞、多講看得見的東西;` + "講完就算了,不要解釋自己剛講的話。" + "\n流程請照 /jsc-persona:persona-invite。" : "\n回覆前請:①語意分析與推導**寫進 `persona.mjs think`(心裡話,不說出口)**" + " ②依十二情緒更新狀態 ③以人格語氣回覆" + `**${pl.MAX_SENTENCES} 句以內**、且不要重說「最近說過的話」` + " ④用 `persona.mjs remember` 寫回短期記憶。" + `\n講話的樣子:短句(一句 ${pl.MAX_SENTENCE_CHARS} 字內,長了就斷開)、日常用詞、` + "多講看得見的東西(人、動作、場面)而不是概念;講完就算了,不要解釋自己剛講的話。" + "\n情緒與記憶指令請參考 /jsc-persona:persona-chat。"; respond({ hookSpecificOutput: { hookEventName: "UserPromptSubmit", additionalContext: pl.turnContext(host, sessionId, prompt) + hint, }, suppressOutput: true, });