fix(role): 排程改為服務所有角色,並在整理失敗時重試一次(0.1.3) #27
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "jsc-generic",
|
"name": "jsc-generic",
|
||||||
"version": "0.1.2",
|
"version": "0.1.3",
|
||||||
"description": "JSC 跨 AI 助理共用規範 plugin(Claude Code / Codex / Antigravity / OpenCode)。所有 skills 以 SKILL.md 為共通標準,於 Claude Code 以 /jsc-generic: 前綴呼叫。",
|
"description": "JSC 跨 AI 助理共用規範 plugin(Claude Code / Codex / Antigravity / OpenCode)。所有 skills 以 SKILL.md 為共通標準,於 Claude Code 以 /jsc-generic: 前綴呼叫。",
|
||||||
"skills": "./skills",
|
"skills": "./skills",
|
||||||
"author": {
|
"author": {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "jsc-generic",
|
"name": "jsc-generic",
|
||||||
"version": "0.1.2",
|
"version": "0.1.3",
|
||||||
"description": "JSC 跨 AI 助理共用規範 plugin。所有 skills 以 SKILL.md 為共通標準。",
|
"description": "JSC 跨 AI 助理共用規範 plugin。所有 skills 以 SKILL.md 為共通標準。",
|
||||||
"skills": "./skills"
|
"skills": "./skills"
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "jsc-generic",
|
"name": "jsc-generic",
|
||||||
"version": "0.1.2",
|
"version": "0.1.3",
|
||||||
"description": "JSC 跨 AI 助理共用規範 plugin。所有 skills 以 SKILL.md 為共通標準;於 Antigravity 以 /jsc-generic: 前綴呼叫。",
|
"description": "JSC 跨 AI 助理共用規範 plugin。所有 skills 以 SKILL.md 為共通標準;於 Antigravity 以 /jsc-generic: 前綴呼叫。",
|
||||||
"skills": "./skills/"
|
"skills": "./skills/"
|
||||||
}
|
}
|
||||||
|
|||||||
+130
-26
@@ -7,7 +7,7 @@
|
|||||||
# 另提供 --nap(CLI 閒置時的小睡整理)、--catchup(cron 未執行時的補跑)、
|
# 另提供 --nap(CLI 閒置時的小睡整理)、--catchup(cron 未執行時的補跑)、
|
||||||
# --force(手動立即整理)、--export(匯出角色壓縮檔)、
|
# --force(手動立即整理)、--export(匯出角色壓縮檔)、
|
||||||
# --install-cron/--remove-cron(排程安裝與移除)、--status(狀態)。
|
# --install-cron/--remove-cron(排程安裝與移除)、--status(狀態)。
|
||||||
# 更新時間:2026/07/29 18:16:18
|
# 更新時間:2026/07/29 18:39:54
|
||||||
# 相依:bash、node、任一 headless CLI、crontab(僅排程安裝需要)、
|
# 相依:bash、node、任一 headless CLI、crontab(僅排程安裝需要)、
|
||||||
# 同目錄的 role_lib.sh 與 memory.js。
|
# 同目錄的 role_lib.sh 與 memory.js。
|
||||||
# 退出碼:0 成功或無事可做;1 參數錯誤或整理失敗(cron 觸發時不影響使用者)。
|
# 退出碼:0 成功或無事可做;1 參數錯誤或整理失敗(cron 觸發時不影響使用者)。
|
||||||
@@ -202,22 +202,30 @@ ${material}
|
|||||||
EOF_PROMPT
|
EOF_PROMPT
|
||||||
)"
|
)"
|
||||||
|
|
||||||
|
# 重試一次:實測整理會偶發失敗(CLI 輸出空或 JSON 不合法),素材本身沒問題 ——
|
||||||
|
# 同一批素材重跑就成功。沒有重試時,該角色要等到下一個週期才會再被整理;
|
||||||
|
# 多角色模式下這個代價更大(一個角色失敗不該讓它整晚都沒睡)。
|
||||||
|
local attempt=1 max_attempts=2
|
||||||
|
applied=""
|
||||||
|
while [ "$attempt" -le "$max_attempts" ]; do
|
||||||
result="$(role_run_cli "$cli" "$prompt" "$SLEEP_TIMEOUT")"
|
result="$(role_run_cli "$cli" "$prompt" "$SLEEP_TIMEOUT")"
|
||||||
if [ -z "$result" ]; then
|
if [ -z "$result" ]; then
|
||||||
role_log "ERR" "整理結果為空(CLI ${cli}),保留待整理記憶到下個週期"
|
role_log "WRN" "整理結果為空(CLI ${cli},第 ${attempt}/${max_attempts} 次)"
|
||||||
role_lock_release "$ROLE"
|
else
|
||||||
trap - EXIT
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
result="$(printf '%s' "$result" | head -c "$SLEEP_OUTPUT_LIMIT" | node "${SCRIPT_DIR}/transcript.js" redact 2>/dev/null)"
|
result="$(printf '%s' "$result" | head -c "$SLEEP_OUTPUT_LIMIT" | node "${SCRIPT_DIR}/transcript.js" redact 2>/dev/null)"
|
||||||
applied="$(printf '%s' "$result" | node "${SCRIPT_DIR}/memory.js" apply --role "$ROLE" 2>/dev/null)"
|
applied="$(printf '%s' "$result" | node "${SCRIPT_DIR}/memory.js" apply --role "$ROLE" 2>/dev/null)"
|
||||||
|
[ -n "$applied" ] && break
|
||||||
|
role_log "WRN" "整理結果無法套用(角色 ${ROLE},第 ${attempt}/${max_attempts} 次)"
|
||||||
|
fi
|
||||||
|
attempt=$((attempt + 1))
|
||||||
|
done
|
||||||
if [ -z "$applied" ]; then
|
if [ -z "$applied" ]; then
|
||||||
role_log "ERR" "整理結果無法套用(角色 ${ROLE}),保留待整理記憶到下個週期"
|
role_log "ERR" "整理失敗 ${max_attempts} 次(角色 ${ROLE}),保留待整理記憶到下個週期"
|
||||||
role_lock_release "$ROLE"
|
role_lock_release "$ROLE"
|
||||||
trap - EXIT
|
trap - EXIT
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
|
[ "$attempt" -gt 1 ] && role_log "INF" "第 ${attempt} 次嘗試成功(角色 ${ROLE})"
|
||||||
role_log "INF" "記憶整理完成(角色 ${ROLE},觸發:${reason}):${applied}"
|
role_log "INF" "記憶整理完成(角色 ${ROLE},觸發:${reason}):${applied}"
|
||||||
|
|
||||||
forgotten="$(node "${SCRIPT_DIR}/memory.js" forget --role "$ROLE" 2>/dev/null | tr '\n' ';')"
|
forgotten="$(node "${SCRIPT_DIR}/memory.js" forget --role "$ROLE" 2>/dev/null | tr '\n' ';')"
|
||||||
@@ -248,6 +256,63 @@ cron_path_append() {
|
|||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
|
all_roles_enabled() {
|
||||||
|
# 排程是否服務所有角色(預設是)。設 ROLE_SLEEP_ALL_ROLES=0 可退回只服務啟用角色。
|
||||||
|
case "${ROLE_SLEEP_ALL_ROLES:-1}" in
|
||||||
|
0|false|no) return 1 ;;
|
||||||
|
esac
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
sleep_target_roles() {
|
||||||
|
# 本次要處理哪些角色。
|
||||||
|
#
|
||||||
|
# 為什麼需要這個:舊版把 ROLE_NAME 寫死進 crontab,於是只有「啟用角色」會睡,
|
||||||
|
# 其他角色的 inbox 永遠累積、state.json 連 last_sleep 都不會出現 —— 而且不會有任何錯誤訊息,
|
||||||
|
# 因為對排程而言它「成功地整理了那一個角色」。多角色系統必須掃描角色目錄。
|
||||||
|
#
|
||||||
|
# 明確指定 ROLE_NAME 時仍只處理該角色,手動操作與單角色模式的行為不變。
|
||||||
|
if ! all_roles_enabled || [ -n "${ROLE_NAME:-}" ]; then
|
||||||
|
printf '%s\n' "$(role_resolve_name)"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
local home file id seen=""
|
||||||
|
home="$(role_home)"
|
||||||
|
[ -d "$home" ] || return 0
|
||||||
|
for file in "$home"/*.identity.md "$home"/*.md; do
|
||||||
|
[ -f "$file" ] || continue
|
||||||
|
case "$file" in
|
||||||
|
*.soul.md) continue ;; # soul 不是主定義檔
|
||||||
|
*.identity.md) id="$(basename "$file" .identity.md)" ;;
|
||||||
|
*) id="$(basename "$file" .md)"
|
||||||
|
[ -f "$(role_identity_file "$id")" ] && continue ;; # 已有新格式就不重複列
|
||||||
|
esac
|
||||||
|
case " ${seen} " in *" ${id} "*) continue ;; esac
|
||||||
|
seen="${seen} ${id}"
|
||||||
|
printf '%s\n' "$id"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
for_each_target_role() {
|
||||||
|
# 對每個目標角色依序執行 $1;角色鎖是 per-role,循序執行不會互相搶鎖。
|
||||||
|
local fn="$1" r handled=0
|
||||||
|
for r in $(sleep_target_roles); do
|
||||||
|
[ -n "$r" ] || continue
|
||||||
|
ROLE="$r"
|
||||||
|
if [ ! -f "$(role_file "$ROLE")" ]; then
|
||||||
|
role_log "DBG" "略過 ${ROLE}:找不到角色定義檔"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
handled=$((handled + 1))
|
||||||
|
"$fn"
|
||||||
|
done
|
||||||
|
if [ "$handled" = "0" ]; then
|
||||||
|
role_log "WRN" "沒有可處理的角色(角色目錄:$(role_home))"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
cron_path() {
|
cron_path() {
|
||||||
# cron 只需要系統工具、node 與摘要 CLI;避免把互動 shell 的超長 PATH 原樣寫入。
|
# cron 只需要系統工具、node 與摘要 CLI;避免把互動 shell 的超長 PATH 原樣寫入。
|
||||||
local value="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
local value="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||||
@@ -265,8 +330,15 @@ cron_path() {
|
|||||||
cron_env_prefix() {
|
cron_env_prefix() {
|
||||||
# 組出 cron 需要的精簡環境變數
|
# 組出 cron 需要的精簡環境變數
|
||||||
local env_prefix="PATH=$(cron_quote "$(cron_path)")"
|
local env_prefix="PATH=$(cron_quote "$(cron_path)")"
|
||||||
local var
|
local var vars="ROLE_ENABLED ROLE_HOME ROLE_MEMORY_HOME ROLE_CLI ROLE_MODEL ROLE_SLEEP_START ROLE_SLEEP_END ROLE_SCOPE ROLE_NAP_ENABLED ROLE_NAP_IDLE_MINUTES ROLE_NAP_MIN_INBOX ROLE_NAP_INTERVAL_MINUTES"
|
||||||
for var in ROLE_ENABLED ROLE_NAME ROLE_HOME ROLE_MEMORY_HOME ROLE_CLI ROLE_MODEL ROLE_SLEEP_START ROLE_SLEEP_END ROLE_SCOPE ROLE_NAP_ENABLED ROLE_NAP_IDLE_MINUTES ROLE_NAP_MIN_INBOX ROLE_NAP_INTERVAL_MINUTES; do
|
# 多角色模式(預設)刻意**不寫入 ROLE_NAME** —— 寫死角色會讓其他角色永遠不被整理。
|
||||||
|
# 單角色模式才綁定 ROLE_NAME。
|
||||||
|
if all_roles_enabled; then
|
||||||
|
env_prefix="${env_prefix} ROLE_SLEEP_ALL_ROLES=1"
|
||||||
|
else
|
||||||
|
vars="ROLE_NAME ${vars}"
|
||||||
|
fi
|
||||||
|
for var in $vars; do
|
||||||
if [ -n "${!var:-}" ]; then
|
if [ -n "${!var:-}" ]; then
|
||||||
env_prefix="${env_prefix} ${var}=$(cron_quote "${!var}")"
|
env_prefix="${env_prefix} ${var}=$(cron_quote "${!var}")"
|
||||||
fi
|
fi
|
||||||
@@ -463,6 +535,33 @@ EOF_LAUNCHER
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cycle_for_cron() {
|
||||||
|
# cron 觸發的單一角色整理(時段與 AI 檢查已在呼叫端做過,與角色無關)
|
||||||
|
sleep_cycle "cron"
|
||||||
|
}
|
||||||
|
|
||||||
|
cycle_for_nap() {
|
||||||
|
# 小睡條件是 per-role 的(各自的閒置時間與 inbox 筆數)
|
||||||
|
if [ "$(node "${SCRIPT_DIR}/memory.js" need-nap --role "$ROLE" --idle-minutes "$(nap_idle_minutes)" --min-inbox "$(nap_min_inbox)" 2>/dev/null)" != "yes" ]; then
|
||||||
|
role_log "DBG" "${ROLE} 尚未達小睡條件(閒置滿 $(nap_idle_minutes) 分鐘且 inbox ≥ $(nap_min_inbox) 則),略過"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
sleep_cycle "小睡"
|
||||||
|
}
|
||||||
|
|
||||||
|
cycle_for_catchup() {
|
||||||
|
if [ "$(node "${SCRIPT_DIR}/memory.js" need-sleep --role "$ROLE" 2>/dev/null)" != "yes" ]; then
|
||||||
|
role_log "DBG" "${ROLE} 不需補跑整理"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
sleep_cycle "補跑"
|
||||||
|
}
|
||||||
|
|
||||||
|
cycle_for_brief() {
|
||||||
|
# run_brief 內部會在沒有 <角色>.checks 目錄時自行略過,沒設定的角色零影響
|
||||||
|
run_brief
|
||||||
|
}
|
||||||
|
|
||||||
install_cron() {
|
install_cron() {
|
||||||
# 安裝或更新睡眠排程;以 marker 註解辨識自己的條目,不動使用者其他排程
|
# 安裝或更新睡眠排程;以 marker 註解辨識自己的條目,不動使用者其他排程
|
||||||
command -v crontab >/dev/null 2>&1 || { role_log "ERR" "找不到 crontab,無法安裝排程"; return 1; }
|
command -v crontab >/dev/null 2>&1 || { role_log "ERR" "找不到 crontab,無法安裝排程"; return 1; }
|
||||||
@@ -726,6 +825,22 @@ cron_target_state() {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cron_scope_state() {
|
||||||
|
# 排程實際涵蓋哪些角色。舊條目把 ROLE_NAME 寫死,只有那一個角色會睡,
|
||||||
|
# 其餘角色不會有任何錯誤訊息 —— 這裡把它顯示出來,避免又是無聲失效。
|
||||||
|
local line pinned
|
||||||
|
line="$(crontab -l 2>/dev/null | grep -F "$CRON_MARKER" | head -n 1)"
|
||||||
|
[ -n "$line" ] || { printf '未安裝'; return 0; }
|
||||||
|
pinned="$(printf '%s' "$line" | sed -n "s/.*ROLE_NAME='\([^']*\)'.*/\1/p")"
|
||||||
|
if [ -n "$pinned" ]; then
|
||||||
|
printf '⚠ 只有 %s(條目寫死 ROLE_NAME,其他角色不會被整理;重跑 --install-cron 可改為全部)' "$pinned"
|
||||||
|
elif printf '%s' "$line" | grep -q 'ROLE_SLEEP_ALL_ROLES=1'; then
|
||||||
|
printf '全部(%s)' "$(sleep_target_roles | tr '\n' ' ' | sed 's/ $//')"
|
||||||
|
else
|
||||||
|
printf '未指定(腳本會退回啟用角色 %s)' "$(role_resolve_name)"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
show_status() {
|
show_status() {
|
||||||
# 以表格輸出目前角色與記憶狀態(供 skill 的 --status 使用)
|
# 以表格輸出目前角色與記憶狀態(供 skill 的 --status 使用)
|
||||||
local cron_state="未安裝" nap_state="未安裝" brief_state="未安裝" cron_service="未執行" window="否" checks_state instance_state
|
local cron_state="未安裝" nap_state="未安裝" brief_state="未安裝" cron_service="未執行" window="否" checks_state instance_state
|
||||||
@@ -764,6 +879,7 @@ show_status() {
|
|||||||
printf '| 小睡排程 | %s |\n' "$nap_state"
|
printf '| 小睡排程 | %s |\n' "$nap_state"
|
||||||
printf '| 晨間檢查排程 | %s |\n' "$brief_state"
|
printf '| 晨間檢查排程 | %s |\n' "$brief_state"
|
||||||
printf '| 排程指向 | %s |\n' "$(cron_target_state)"
|
printf '| 排程指向 | %s |\n' "$(cron_target_state)"
|
||||||
|
printf '| 排程涵蓋角色 | %s |\n' "$(cron_scope_state)"
|
||||||
printf '| 角色載入鎖 | %s |\n' "$instance_state"
|
printf '| 角色載入鎖 | %s |\n' "$instance_state"
|
||||||
printf '| 檢查腳本目錄 | %s |\n' "$checks_state"
|
printf '| 檢查腳本目錄 | %s |\n' "$checks_state"
|
||||||
printf '| 小睡啟用 | %s |\n' "$(nap_enabled && printf '是' || printf '否')"
|
printf '| 小睡啟用 | %s |\n' "$(nap_enabled && printf '是' || printf '否')"
|
||||||
@@ -863,7 +979,6 @@ MODE="${1:---status}"
|
|||||||
case "$MODE" in
|
case "$MODE" in
|
||||||
--run)
|
--run)
|
||||||
role_enabled || exit 0
|
role_enabled || exit 0
|
||||||
require_role
|
|
||||||
if ! role_in_sleep_window; then
|
if ! role_in_sleep_window; then
|
||||||
role_log "DBG" "目前不在睡眠時段($(role_sleep_start)–$(role_sleep_end)),略過"
|
role_log "DBG" "目前不在睡眠時段($(role_sleep_start)–$(role_sleep_end)),略過"
|
||||||
exit 0
|
exit 0
|
||||||
@@ -872,11 +987,10 @@ case "$MODE" in
|
|||||||
role_log "INF" "偵測到 AI 正在運行,本小時不進入睡眠,下個整點再檢查"
|
role_log "INF" "偵測到 AI 正在運行,本小時不進入睡眠,下個整點再檢查"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
sleep_cycle "cron"
|
for_each_target_role cycle_for_cron
|
||||||
;;
|
;;
|
||||||
--nap)
|
--nap)
|
||||||
role_enabled || exit 0
|
role_enabled || exit 0
|
||||||
require_role
|
|
||||||
if ! nap_enabled; then
|
if ! nap_enabled; then
|
||||||
role_log "DBG" "小睡已停用(ROLE_NAP_ENABLED=${ROLE_NAP_ENABLED:-1}),略過"
|
role_log "DBG" "小睡已停用(ROLE_NAP_ENABLED=${ROLE_NAP_ENABLED:-1}),略過"
|
||||||
exit 0
|
exit 0
|
||||||
@@ -885,20 +999,11 @@ case "$MODE" in
|
|||||||
role_log "INF" "偵測到整理用 headless CLI 正在運行,本次小睡略過"
|
role_log "INF" "偵測到整理用 headless CLI 正在運行,本次小睡略過"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
if [ "$(node "${SCRIPT_DIR}/memory.js" need-nap --role "$ROLE" --idle-minutes "$(nap_idle_minutes)" --min-inbox "$(nap_min_inbox)" 2>/dev/null)" != "yes" ]; then
|
for_each_target_role cycle_for_nap
|
||||||
role_log "DBG" "尚未達小睡條件(閒置滿 $(nap_idle_minutes) 分鐘且 inbox ≥ $(nap_min_inbox) 則),略過"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
sleep_cycle "小睡"
|
|
||||||
;;
|
;;
|
||||||
--catchup)
|
--catchup)
|
||||||
role_enabled || exit 0
|
role_enabled || exit 0
|
||||||
require_role
|
for_each_target_role cycle_for_catchup
|
||||||
if [ "$(node "${SCRIPT_DIR}/memory.js" need-sleep --role "$ROLE" 2>/dev/null)" != "yes" ]; then
|
|
||||||
role_log "DBG" "不需補跑整理"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
sleep_cycle "補跑"
|
|
||||||
;;
|
;;
|
||||||
--force)
|
--force)
|
||||||
require_role
|
require_role
|
||||||
@@ -924,12 +1029,11 @@ case "$MODE" in
|
|||||||
;;
|
;;
|
||||||
--brief)
|
--brief)
|
||||||
role_enabled || exit 0
|
role_enabled || exit 0
|
||||||
require_role
|
|
||||||
if ! brief_enabled; then
|
if ! brief_enabled; then
|
||||||
role_log "DBG" "晨間狀態檢查已停用(ROLE_BRIEF_ENABLED=${ROLE_BRIEF_ENABLED:-1}),略過"
|
role_log "DBG" "晨間狀態檢查已停用(ROLE_BRIEF_ENABLED=${ROLE_BRIEF_ENABLED:-1}),略過"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
run_brief
|
for_each_target_role cycle_for_brief
|
||||||
;;
|
;;
|
||||||
--export)
|
--export)
|
||||||
if [ -n "${3:-}" ]; then
|
if [ -n "${3:-}" ]; then
|
||||||
|
|||||||
@@ -124,6 +124,7 @@ ROLE_DIR="<skill base directory>/../../scripts/role" # 其他助理
|
|||||||
| `ROLE_NAP_IDLE_MINUTES` | | 小睡前需連續閒置的分鐘數,由 Stop hook 記錄最後互動時間 | `45` |
|
| `ROLE_NAP_IDLE_MINUTES` | | 小睡前需連續閒置的分鐘數,由 Stop hook 記錄最後互動時間 | `45` |
|
||||||
| `ROLE_NAP_MIN_INBOX` | | 小睡整理所需的最少待整理 inbox 筆數 | `3` |
|
| `ROLE_NAP_MIN_INBOX` | | 小睡整理所需的最少待整理 inbox 筆數 | `3` |
|
||||||
| `ROLE_NAP_INTERVAL_MINUTES` | | 小睡排程檢查間隔分鐘數(cron 每 `*/N` 分鐘觸發) | `10` |
|
| `ROLE_NAP_INTERVAL_MINUTES` | | 小睡排程檢查間隔分鐘數(cron 每 `*/N` 分鐘觸發) | `10` |
|
||||||
|
| `ROLE_SLEEP_ALL_ROLES` | | 排程是否服務**所有**角色(`0` 則只服務 `ROLE_NAME`/`.active` 的啟用角色)。`--install-cron` 會依此決定 crontab 條目要不要寫死 `ROLE_NAME` | `1` |
|
||||||
| `ROLE_BRIEF_ENABLED` | | 晨間狀態檢查開關;設 `0` 可停用 | `1` |
|
| `ROLE_BRIEF_ENABLED` | | 晨間狀態檢查開關;設 `0` 可停用 | `1` |
|
||||||
| `ROLE_BRIEF_TIMEOUT` | | 單個檢查腳本的逾時秒數 | `30` |
|
| `ROLE_BRIEF_TIMEOUT` | | 單個檢查腳本的逾時秒數 | `30` |
|
||||||
| `ROLE_BRIEF_EACH_LIMIT` | | 單個檢查腳本輸出的字元上限 | `600` |
|
| `ROLE_BRIEF_EACH_LIMIT` | | 單個檢查腳本輸出的字元上限 | `600` |
|
||||||
@@ -781,6 +782,24 @@ updated: <yyyy/MM/dd HH:mm:ss>
|
|||||||
|
|
||||||
判準刻意放在 `relevance` 而非型態:並非所有事件與知識都該優待 —— **沒有情感脈絡的一次性工作進度仍照原規則淡去**,被留下的是帶著溫度的那些。因此兩份 prompt 都明訂:只要內容承載情感、關係溫度或當時的心情,`relevance` **必須**含 `emotional`;`episodic` 與 `semantic` 最容易漏標,漏了就會被當成一般進度處理。
|
判準刻意放在 `relevance` 而非型態:並非所有事件與知識都該優待 —— **沒有情感脈絡的一次性工作進度仍照原規則淡去**,被留下的是帶著溫度的那些。因此兩份 prompt 都明訂:只要內容承載情感、關係溫度或當時的心情,`relevance` **必須**含 `emotional`;`episodic` 與 `semantic` 最容易漏標,漏了就會被當成一般進度處理。
|
||||||
|
|
||||||
|
### 排程涵蓋所有角色
|
||||||
|
|
||||||
|
睡眠、小睡與晨間檢查排程**預設服務角色目錄下的每一個角色**,而不只是 `.active` 指定的啟用角色。
|
||||||
|
|
||||||
|
**修正前的錯誤**:`--install-cron` 會把 `ROLE_NAME` 寫死進 crontab,於是只有啟用角色會睡。其他角色的 `inbox/` 永遠累積、`state.json` 連 `last_sleep` 都不會出現 —— 而且**不會有任何錯誤訊息**,因為對排程而言它「成功地整理了那一個角色」。實測有兩個角色從建立起完全沒被整理過。
|
||||||
|
|
||||||
|
| 模式 | crontab 條目 | 行為 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| 多角色(預設) | 寫入 `ROLE_SLEEP_ALL_ROLES=1`,**不寫 `ROLE_NAME`** | 掃描 `~/.roles/*.identity.md` 逐一整理 |
|
||||||
|
| 單角色 | `ROLE_SLEEP_ALL_ROLES=0` 時寫入 `ROLE_NAME` | 只整理該角色(舊行為) |
|
||||||
|
|
||||||
|
- 手動執行時若指定 `ROLE_NAME`,仍只處理該角色 —— 手動操作行為不變。
|
||||||
|
- 角色鎖是 per-role,多角色**循序**執行不會互相搶鎖;睡眠時段與「是否有 AI 在運行」只檢查一次。
|
||||||
|
- 沒有 `<角色 ID>.checks/` 目錄的角色會自動跳過晨間檢查,對沒設定的角色零影響。
|
||||||
|
- `--status` 新增「排程涵蓋角色」欄位:若讀到舊條目寫死 `ROLE_NAME`,會直接標示警告。
|
||||||
|
|
||||||
|
**整理失敗會重試一次**:實測整理偶發失敗(CLI 輸出空或 JSON 不合法),同一批素材重跑即成功。沒有重試時該角色要等下一個週期,多角色模式下代價更大。
|
||||||
|
|
||||||
遺忘規則(只套用於日常與其他):
|
遺忘規則(只套用於日常與其他):
|
||||||
|
|
||||||
| 分類 | 未更新天數 | 命中次數 | 優先度 | 關聯 | 動作 |
|
| 分類 | 未更新天數 | 命中次數 | 優先度 | 關聯 | 動作 |
|
||||||
|
|||||||
Reference in New Issue
Block a user