From 1a373145194dc7100c00dfbc061d42b04af28606 Mon Sep 17 00:00:00 2001 From: maogeigei Date: Sun, 18 Oct 2026 21:13:42 +0800 Subject: [PATCH] =?UTF-8?q?fix(session-mechanism):=20=E7=9B=AE=E6=A0=87?= =?UTF-8?q?=E6=A3=80=E6=9F=A5=E7=A9=BA=E9=97=B2=E9=98=88=E5=80=BC=203=20?= =?UTF-8?q?=E2=86=92=202=20=E5=88=86=E9=92=9F=EF=BC=8C=E5=B9=B6=E6=B8=85?= =?UTF-8?q?=E6=8E=89=E5=9B=9B=E5=A4=84=E8=BF=87=E6=97=B6=E8=AF=B4=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `CHECK_IDLE_MIN` 由 3 改为 2(2026-10-18 用户令;此前 20 → 10 → 6 → 3) - 同一文件里 4 处说明文字仍写着「静默 ≥20 分钟」,与参数不符(10-07 改参数时未同步) ⇒ 一律改为 2 分钟,含检查会话提示词里给会话看的那句「已静默 ≥N 分钟」 - 闸门数量口径统一:4 处「四道闸」改为「六道闸」(实际列的是六条) - 已同步到工作区运行副本并重启常驻,md5 双端一致 --- session-mechanism/scripts/collabd.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/session-mechanism/scripts/collabd.py b/session-mechanism/scripts/collabd.py index 7c058dc..bf227d5 100644 --- a/session-mechanism/scripts/collabd.py +++ b/session-mechanism/scripts/collabd.py @@ -17,7 +17,7 @@ 🔴 **2026-10-03 起本程序的真实现行口径**(用户原话「现在的机制是 协作程序接收和处理队列」): · **接收** = `--report` 把任务会话的执行状态写进 `tasks.json`(四态台账,唯一权威)。 - · **处理** = 建**检查会话排期**(`maybe_spawn_check_agent()`,四道闸)让会话去读队列干活 + · **处理** = 建**检查会话排期**(`maybe_spawn_check_agent()`,六道闸)让会话去读队列干活 —— 常驻 `--supervise` 每 2 轮判一次,是这条腿的**唯一载体**。 · **推送** = **没有这一环**。队列变化不再自动通知任何人,要落事得**显式建任务会话**。 @@ -27,7 +27,7 @@ (网关发现仍在读,只是不再拿它发消息)。 用法(🔴🔴 **2026-10-03 投递退役后的现行口径**;⛔ 已废弃「用自动任务当闹钟」): 🔴 **判据:常驻(`--supervise`)现在只干两件事** —— - ① **检查会话建排期**(唯一建排期的地方;四道闸在 `maybe_spawn_check_agent()` 内); + ① **检查会话建排期**(唯一建排期的地方;六道闸在 `maybe_spawn_check_agent()` 内); ② **写心跳**(`supervise-heartbeat.json` + `.log`)——「常驻在不在」的唯一机读判据。 ⛔ **它不再投递、不再唤醒**:那两段已真删(收件人已退役)⇒ **留着常驻的唯一理由是 ①**。 ⚠️ 载体结论(2026-10-02 23:0x 实测订正,推翻更早的"没有进程能一直活着"): @@ -2136,7 +2136,7 @@ TASK_EVENTS = INBOX / "tasks-events.jsonl" # 只作审计(append-only,⛔ TO_MAIN = INBOX / "TO-MAIN.md" # 投递给主会话的通知(投影 · 供人/AI 直接读) TASK_STATES = ("pending", "running", "done", "blocked") # 需求台账四态:待执行/执行中/已完成/有阻碍 QUEUE_IDLE_MIN = 5 # 唤醒**限流桶**(分钟):同一状态下最多每 **5** 分钟发一次(2026-09-30 用户拍板:30→10→**5**);⛔ 触发条件是 supervise() 的**四条件**(不是计时器) -CHECK_IDLE_MIN = 3 # 🔴🔴 2026-10-07 用户三度拍板:**20 → 10 → 6 → 3 分钟**(10-08 02:4x 第三次) +CHECK_IDLE_MIN = 2 # 🔴🔴 2026-10-18 用户令:**3 → 2 分钟**(此前 20 → 10 → 6 → 3,10-07/08 三度调整) # 原话一:「把检查程序的等待时间由 20分钟 改为 10分钟」;原话二:「检查程序的等待时间改为6分钟」(当日 18:25)。 # 「检查程序」判"已经静默够久、可以建检查会话"的阈值(`queue-empty` 那条闸)。 # ⚠️ 改这个数必须**一起改三处**,否则文案与判据打架: @@ -4470,14 +4470,14 @@ CHECK_PROMPT_RESULT = ( + _CHECK_TAIL_A + _CHECK_TAIL_B ) -# 【目标检查】—— 队列**空**且静默 >3 分钟时:核对目标完成状态(阈值=`CHECK_IDLE_MIN`,2026-10-07/08 三度调整:20 → 10 → 6 → 3) +# 【目标检查】—— 队列**空**且静默 >2 分钟时:核对目标完成状态(阈值=`CHECK_IDLE_MIN`,现 2 分钟;2026-10-18 由 3 改 2) CHECK_PROMPT_GOAL = ( "**【目标检查会话 · 第 %d 棒】**本轮只做这一件事:**核对目标完成状态**,**做完即停**。\n" "\n" "目标:%s\n" "\n" "## 一、为什么是你(🔴 触发条件已满足,不必重判)\n" - "**所有会话都已结束** + **队列为空** + **已静默 ≥3 分钟** + **本项目没有别的待执行排期**。\n" + "**所有会话都已结束** + **队列为空** + **已静默 ≥2 分钟** + **本项目没有别的待执行排期**。\n" "\n" "## 二、🔴 先读这五样,⛔ **只读这五个文件**,读完直接判断(⛔ 别到处找信息)\n" "> ⚠️ **不要在本工作区里到处翻文件**:2026-10-03 实测,检查会话因无边界地找资料\n" @@ -4963,7 +4963,7 @@ def maybe_spawn_check_agent(reason: str) -> dict |None: | reason | 排期名 | 触发条件 | 它的职责 | |---|---|---|---| - | `sessions-ended` | `[结果检查]-…` | 会话全结束 + **队列非空**(⛔ 不要求静默 20 分钟) | **跟进任务会话执行结果** ⇒ 判断是否**创建对应任务会话**继续完成目标,并创建 | + | `sessions-ended` | `[结果检查]-…` | 会话全结束 + **队列非空**(⛔ 不要求静默) | **跟进任务会话执行结果** ⇒ 判断是否**创建对应任务会话**继续完成目标,并创建 | | `queue-empty` | `[目标检查]-…` | 会话全结束 + **队列为空** + 静默 **≥20 分钟** | **核对目标完成状态** ⇒ 判断是**建任务会话**接着做、还是**改目标状态**(已完成),并执行 | ⇒ ⛔ **它们不是同一件事的两种触发**,⛔ 不许共用一个 prompt:前者面对"有活没人干", @@ -4987,7 +4987,7 @@ def maybe_spawn_check_agent(reason: str) -> dict |None: ⚠️ **配对必需**:只加这道闸而没有「谁去置阻碍」= 白加 ⇒ 出口见 `CHECK_PROMPT_RESULT` 第 3 条 (**结果检查会话**是唯一能看见 `blocked` 的那条腿;目标检查要"队列为空"才触发、永不触发)。 ② **所有会话都结束**了(含主会话 · 用户第②条) - ③ **队列状态要对得上 reason**:`queue-empty` 必须队列空 + 静默 ≥20 分钟; + ③ **队列状态要对得上 reason**:`queue-empty` 必须队列空 + 静默 ≥2 分钟; `sessions-ended` 必须队列**非空**(⛔ 队列也空 ⇒ 那是 `queue-empty` 那条的事,⛔ 不重复建) ④ 🔴🔴 **本工作区没有别的「待执行」排期**(用户 2026-10-03 新增判据,见 `ws_pending_schedules()`) ⑤ **同名排期未在册**(去抖) @@ -6239,7 +6239,7 @@ def supervise(st: dict, deliver: bool = True, mutate: bool = True) -> dict: 🔴 与用户口径「**协作程序接收和处理队列**」的关系(本条为准,2026-10-03): · **接收** = `--report` 写 `tasks.json`(`task_report()`)—— **原样保留,仍是活的**。 · **处理** = 建排期派任务会话(`maybe_spawn_check_agent()`,由 `--supervise` 循环 - 每 2 轮判一次,四道闸在函数内)—— **原样保留,仍是活的**。 + 每 2 轮判一次,六道闸在函数内)—— **原样保留,仍是活的**。 · **被删的只是"把队列变化推给某个会话"这一步** —— 它没有收件人,留着就是空转。 ⚠️ `deliver` / `mutate` 两个参数**只为兼容现有三处调用点的签名**(`--once` 传 @@ -6670,7 +6670,7 @@ def main() -> int: life, pend, idle, _all_sessions_idle())) # 🔴🔴 试算必须与 `maybe_spawn_check_agent()` 的闸**逐条对齐**(2026-10-04): # · `sessions-ended`(队列非空)⇒ **不受目标状态限制**; - # · `queue-empty` ⇒ 须目标「进行中」+ 静默 ≥20 分钟。 + # · `queue-empty` ⇒ 须目标「进行中」+ 静默 ≥2 分钟。 # ⛔ 这里若仍写"必须进行中"⇒ **试算说不会建、实际会建**(判据自相矛盾)。 _why_now = why or "queue-empty" _will = False @@ -6901,8 +6901,8 @@ def main() -> int: # 🔴🔴 2026-10-02 用户拍板方案 A:**检查会话建排期**(唯一建排期的地方在此)。 # 两条触发源(用户第①②条): # ① **任务会话全部结束** ⇒ 一次性读队列 → 建检查会话整体检查 - # ② **队列为空** ⇒ 静默 ≥20 分钟 → 建检查会话核对目标状态 - #⛔ 四道闸全在 `maybe_spawn_check_agent()` 里(目标须「进行中」+会话全结束+ + # ② **队列为空** ⇒ 静默 ≥2 分钟 → 建检查会话核对目标状态 + #⛔ 六道闸全在 `maybe_spawn_check_agent()` 里(目标须「进行中」+会话全结束+ # 静默时长+同名去抖);⛔ 建排期**只一条**,⛔ 不在循环里连建。 try: if _rd % 2 == 0: # 🔴 每 2 轮判一次(周期 30s ⇒≈60s)