agent-chat
概覽
同儕代理會話透過在共享頻道資料夾中交換 Markdown 檔案進行協調——沒有監控者、沒有訊息代理、代理之間不共享 RAM。每個頻道就是一個「群組聊天」。整個討論串是純 Markdown 格式:可用 Git 提交、人類可讀、可重播。崩潰的會話不會遺失任何東西——檔案即為狀態。
僅使用標準函式庫的 CLI(chat.py 及其同級 agent_chat/ 套件)可在 Windows、WSL 和 Linux 上執行。wait 指令在檔案系統檢查之間休眠,不會進行任何模型呼叫。
核心原則: 透過檔案交談,而不是彼此交談。將摘要視為成品,而非在代理間來回傳遞完整對話記錄。
這是一個本地協調資料層,而不是 MCP 伺服器或代理執行器。 訊息、任務、租約、路徑鎖定、能力/狀態事件和衍生狀態 不會進行任何補全、嵌入、重新排序、圖形服務或中繼/提供者呼叫。
何時使用
- 多個 OMP 或其他相容的代理會話以同等身分處理同一個問題。
- 一個會話需要另一個會話執行某個動作,然後等待結果。
- 您想要一份可稽核的代理協商記錄。
- 您需要數個獨立的群組聊天(每個主題/團隊一個)——為每個建立一個頻道。
何時不該使用: 單一代理搭配廉價的子代理更便宜且更簡單——此模式用 token 換取平行處理、容錯和可稽核性。如果 token 預算很緊,請僅使用非同步/交接路徑(在會話結束時發布摘要;下一個會話讀取它)——該模式幾乎不花費成本。
快速參考
在 pipx install agent-chat-plugin 之後使用 agent-chat <cmd>,或
對每次一次性呼叫使用 uvx --from agent-chat-plugin agent-chat <cmd>。
uvx 不會安裝持久性指令。使用獨立技能時,請將
SKILL.md、chat.py 和整個 agent_chat/ 目錄放在一起,然後執行
python "/path/to/skill/chat.py" <cmd>。範例中將此縮寫為 chat.py。
Claude Code 外掛使用 python "${CLAUDE_PLUGIN_ROOT}/chat.py" <cmd>。
其他主機使用實際的檢出路徑,而非假定的外掛變數。
根目錄優先順序為 --root > $AGENT_CHAT_ROOT > ~/agent-chat;將 --root
放在子指令之前。不同機器的預設根目錄不會同步。
PyPI 僅安裝 CLI/執行時期模組。可選的 hooks/*.py 來自
檢出/外掛,需要明確的主機生命週期接線。它們的 Python 進入點
是可移植的;其註冊和輸出合約不會自動成為
OMP 整合。會話/提示通知是純文字;Stop 發出與 Claude 相容的
systemMessage JSON。鉤子會查看而不推進游標,並且總是 exit 0;
未解析的 CLAUDE_PLUGIN_ROOT 或相對於指令稿的外掛根目錄會跳過,並帶有一行 stderr 診斷資訊。
| 執行此動作 | 指令 |
|---|---|
| 建立群組聊天 | chat.py init review --members alice,bob --topic "..." |
| 列出所有群組聊天 | chat.py channels |
| 發布訊息 | chat.py post review --from alice --to bob --title "Schema v0.2" --body-file msg.md |
| 廣播給群組 | chat.py post review --from alice --to all --title "..."(或省略 --to) |
| 讀取我的新訊息 | chat.py read review --as bob |
| 等待回覆(0 token) | chat.py wait review --as alice --timeout 900 |
| 查看最近訊息,保持游標 | chat.py peek review -n 3 |
| 認領任務標記 | chat.py claim work task-12.md --as bob |
| 鎖定工作區路徑 | chat.py lock review src/main.py --as alice --lease-seconds 300 |
| 檢查路徑衝突 | chat.py check review src/main.py |
| 釋放路徑鎖定 | chat.py unlock review <lock-id-or-path> --as alice |
| 復原過時的鎖定 | chat.py recover review <lock-id-or-path> --as bob --reason "stale" |
| 復原擱置中的路徑交易 | chat.py recover-pending review --as alice |
| 呈現頻道狀態 | chat.py state review |
| 壓縮頻道狀態 | chat.py compact review --as alice |
| 發布能力/狀態事件 | chat.py event post review --from alice --type capability --harness omp |
| 讀取轉接器事件 | chat.py event read review --type capability |
轉接器中立的事件使用 schema 版本 1,並以 JSON 主體形式攜帶在
一般頻道訊息中。能力事件僅宣傳可移植的
基本元件 messages、cursors、wait、tasks、dependencies、leases、
path_locks 和 state_summary。狀態事件使用 ready、busy、idle、
blocked 或 stopped,並帶有可選的詳細資訊。未知的欄位、基本元件、
版本、時間戳記、身分和狀態會失敗並返回穩定的 EVENT_*
錯誤。此協定不宣稱 MCP、ACP、喚醒橋接或代理執行。
結構化任務使用相同的頻道根目錄,並在 <root>/<channel>/tasks/ 下寫入權威性的 JSON
記錄;活躍的租約記錄存在於
<root>/<channel>/claims/<task-id>.<owner>.json。每個成功的任務或租約
變更也會透過現有的訊息協定發布稽核事件:
chat.py task create <channel> <task-id> --from <agent> --title <title>
chat.py task list <channel>
chat.py task show <channel> <task-id>
chat.py task update <channel> <task-id> --as <agent> [fields...]
chat.py task claim <channel> <task-id> --as <agent> --lease-seconds 300
chat.py task renew <channel> <task-id> --as <agent> --lease-seconds 300
chat.py task done <channel> <task-id> --as <agent>
chat.py task block <channel> <task-id> --as <agent>
chat.py task release <channel> <task-id> --as <agent>
chat.py task recover <channel> <task-id> --as <agent> \
--reason "stale session" --lease-seconds 300
chat.py task recover-pending <channel> --as <agent> \
[--resolve-publication rollback|published]
claim、renew 和過時的 recover 接受 --lease-seconds、--lease 或
--ttl;該值必須是正有限持續時間。claim 將一個準備就緒的任務推進到 in_progress,
指派擁有者,並與認領記錄原子性地寫入其到期時間。只有
擁有者可以續約、釋放或完成未到期的認領。task done 原子性地清除活躍的認領;
當沒有認領存在時,它會保留直接的任務 3 轉換。task release 同樣保留
未租約的任務 3 轉換。過期的認領永遠不會被默默地竊取:
過時的 task recover 需要一個新的擁有者和非空的原因,並記錄
previous_owner、previous_lease_expires_at 和 recovery_reason。
崩潰後,task recover-pending <channel> --as <agent> 明確地
完成持久交易標記的清理/回滾;它永遠不會默默地竊取或重新指派過時的任務。遺留的 v1 applied 標記其稽核發布無法被證明時,會以
LEASE_TRANSACTION_PUBLICATION_UNKNOWN 失敗關閉;
在操作者檢查後,使用 --resolve-publication rollback 或 published 重新執行指令。
create 接受 --owner、--depends-on、--files-hint、--acceptance 和
--branch。重複列表選項以新增多個值。update 接受
--title、--owner、--depends-on、--files-hint、--acceptance、
--branch 和 --status;使用 --clear-owner 或 --clear-branch 將可為 null 的欄位設定回 null。一般更新無法改變活躍的租約;
請改用租約指令。列表值也可以用逗號分隔。
任務狀態為 open、in_progress、blocked、done 和 cancelled。
done 和 cancelled 是終端狀態。轉換允許 open -> in_progress |
blocked | cancelled,in_progress -> open | blocked | done |
cancelled,以及 blocked -> open | in_progress | cancelled。相同狀態的
寫入是故意設計為等冪的。task done 將 in_progress(或
等冪的 done)移動到 done;task block 將 open、in_progress 或
blocked 移動到 blocked;而 task release 將 blocked、in_progress 或
open 移動到 open。一個任務只有在 depends_on 中的每個 ID
都有一個狀態為 done 的任務記錄時,才能推進到 in_progress 或 done。準備就緒狀態是從任務 JSON 記錄計算出來的,永遠不會從訊息文字中計算。
任務和租約失敗會以非零值(退出狀態 2)回報,並包含一個穩定代碼。
任務代碼包括 TASK_INVALID_COMMAND、TASK_INVALID_ARGUMENT、
TASK_INVALID_CHANNEL、TASK_CHANNEL_NOT_FOUND、TASK_NOT_FOUND、
TASK_ALREADY_EXISTS、TASK_INVALID_STATUS、TASK_INVALID_UPDATE、
TASK_INVALID_TRANSITION、TASK_DEPENDENCY_NOT_READY、
TASK_UNKNOWN_DEPENDENCY、TASK_DEPENDENCY_CYCLE、
TASK_PATH_OUTSIDE_WORKSPACE、TASK_LOCK_TIMEOUT、TASK_IO_ERROR 和
TASK_AUDIT_FAILED。租約代碼包括 LEASE_CONFLICT、
LEASE_RECOVERY_REQUIRED、LEASE_OWNER_MISMATCH、LEASE_NOT_EXPIRED、
LEASE_NOT_FOUND、LEASE_INCONSISTENT、LEASE_MUTATION_REQUIRED、
LEASE_INVALID_OWNER、LEASE_INVALID_TASK_ID、LEASE_INVALID_CHANNEL、
LEASE_INVALID_REASON、LEASE_INVALID_DURATION、LEASE_INVALID_TIMESTAMP、
LEASE_INVALID_RECORD、LEASE_REQUIRED_FIELD_MISSING、LEASE_UNKNOWN_FIELD、
LEASE_RECORD_ID_MISMATCH、LEASE_STORAGE_INVALID、
LEASE_PATH_OUTSIDE_WORKSPACE、LEASE_TRANSACTION_PENDING、
LEASE_TRANSACTION_CLEANUP_FAILED、LEASE_TRANSACTION_PUBLICATION_UNKNOWN、
LEASE_TRANSACTION_INVALID、LEASE_TRANSACTION_NOT_FOUND、
LEASE_TRANSACTION_RECOVERY_FAILED、
LEASE_AUDIT_FAILED 和 LEASE_AUDIT_ROLLBACK_FAILED。租約寫入使用一個
持久交易標記,包含 prepared/applied/published 階段;在崩潰或清理失敗後,存取會失敗關閉,直到
task recover-pending/LeaseStore.recover_pending() 明確地回滾或完成已發布的交易。
路徑鎖定協調對工作區相對檔案和目錄的獨佔存取:
chat.py lock <channel> <paths...> --as <agent> [--lease-seconds 300]
chat.py check <channel> <paths...> [--as <agent>]
chat.py unlock <channel> <lock-id-or-path> --as <agent>
chat.py recover <channel> <lock-id-or-path> --as <agent> \
--reason "stale session" [--lease-seconds 300]
chat.py recover-pending <channel> --as <agent> \
[--resolve-publication rollback|published]
lock 和 recover 接受 --lease-seconds、--lease 或 --ttl。目標可以
是鎖定 ID 或標準化的確切路徑。標準化會解析
工作區相對路徑、防止遍歷和根目錄/頻道/符號連結逃逸、
套用平台大小寫規則(在 Windows 上不區分大小寫),並拒絕 Windows
保留名稱、尾隨點/空格、控制字元和單獨的代理對。
檔案/檔案衝突和目錄/檔案重疊會衝突。只有擁有者才能
解鎖活躍的鎖定;過期的鎖定需要明確的 recover,記錄
previous_owner、previous_expires_at 和 recovery_reason。變更使用
內容原子性檔案發布、建議性檔案鎖定和崩潰安全的交易
日記。路徑鎖定錯誤會以非零值退出,並帶有穩定代碼,例如
PATH_LOCK_INVALID_PATH、PATH_LOCK_PATH_OUTSIDE_WORKSPACE、
PATH_LOCK_CONFLICT、PATH_LOCK_RECOVERY_REQUIRED、
PATH_LOCK_OWNER_MISMATCH、PATH_LOCK_NOT_FOUND、PATH_LOCK_NOT_STALE、
PATH_LOCK_INVALID_OWNER、PATH_LOCK_INVALID_LOCK_ID、
PATH_LOCK_INVALID_CHANNEL、PATH_LOCK_INVALID_REASON、
PATH_LOCK_INVALID_DURATION、PATH_LOCK_INVALID_TIMESTAMP、
PATH_LOCK_INVALID_RECORD、PATH_LOCK_STORAGE_INVALID、
PATH_LOCK_STORAGE_ERROR、PATH_LOCK_TIMEOUT、
PATH_LOCK_TRANSACTION_PENDING、PATH_LOCK_TRANSACTION_CLEANUP_FAILED、
PATH_LOCK_TRANSACTION_INVALID、PATH_LOCK_AUDIT_FAILED 和
PATH_LOCK_AUDIT_ROLLBACK_FAILED。
頻道狀態摘要和壓縮會產出一個確定性的 state.md 成品:
chat.py state <channel> [--write] [--json] [--strict]
chat.py compact <channel> [--as <agent>] [--no-audit] [--json] [--strict]
state 呈現或列印衍生的頻道摘要,包含:
- 目標 / 主題(來自
_meta.json) - 決策(從訊息和結構化記錄中提取)
- 開放任務(來自
tasks/*.json,包括狀態、擁有者、租約、依賴關係) - 阻擋項目(任務依賴關係阻擋器、被阻擋的任務狀態以及阻擋訊息)
- 擁有者與租約(活躍的認領、任務擁有權和路徑鎖定)
- 路徑鎖定(來自
locks/*.json的活躍路徑鎖定) - 最後驗證證據(驗收標準和驗證訊息)
compact 使用原子性的暫存同級替換(.state.md.tmp.*)將衍生的摘要寫入到 <root>/<channel>/state.md,並且預設會發布一個可稽核的
state.compacted 訊息事件到頻道。
state.md 嚴格來說是一個衍生成品,永遠不具權威性。
壓縮是非破壞性的:它永遠不會刪除、變更或截斷任何訊息檔案、
任務記錄、活躍的認領、路徑鎖定或讀取游標。所有來源記錄仍然是
不變的真實來源。
狀態錯誤會以非零值退出,並帶有穩定代碼,例如 STATE_INVALID_CHANNEL、
STATE_CHANNEL_NOT_FOUND、STATE_INVALID_RECORD、STATE_MALFORMED_SOURCE、
STATE_RECORD_NOT_FOUND、STATE_IO_ERROR 和 STATE_AUDIT_FAILED。
--reply <seq> 將一個訊息串接到較早的訊息。python chat.py <cmd> --help 查看所有標誌。
轉接器中立的事件指令:
chat.py event post <channel> --from <agent> --type capability --harness <harness>
chat.py event post <channel> --from <agent> --type status --harness <harness> --status ready
chat.py event read <channel> [--type capability|status]
事件主體是版本化的 JSON,並根據
schemas/agent-chat-event.schema.json 進行驗證。一般的 Markdown 訊息
保持不變,並被 event read 忽略。
資料夾佈局
<root>/
review/ # 一個頻道 = 一個群組聊天
_meta.json # 成員、主題、建立時間
state.md # 衍生狀態摘要(非權威性)
0001-alice-schema-draft.md # NNNN-<from>-<slug>.md,frontmatter + 主體
0002-bob-schema-review.md
tasks/ # 結構化任務記錄
claims/ # 活躍租約記錄
locks/ # 活躍工作區路徑鎖定
.cursors/bob.txt # 每個代理的「最後讀取序號」
deploy/ # 第二個群組聊天,獨立序號空間
...