跳到主要內容

ACP 內部機制

ACP 適配器將 Hermes 的同步 AIAgent 包裝為一個異步 JSON-RPC 標準輸入/輸出(stdio)服務器。

關鍵實現文件:

  • acp_adapter/entry.py
  • acp_adapter/server.py
  • acp_adapter/session.py
  • acp_adapter/events.py
  • acp_adapter/permissions.py
  • acp_adapter/tools.py
  • acp_adapter/auth.py
  • acp_registry/agent.json

啟動流程

hermes acp / hermes-acp / python -m acp_adapter
-> acp_adapter.entry.main()
-> load ~/.hermes/.env
-> configure stderr logging
-> construct HermesACPAgent
-> acp.run_agent(agent)

標準輸出(stdout)保留用於 ACP JSON-RPC 傳輸。人類可讀的日誌輸出到標準錯誤(stderr)。

主要組件

HermesACPAgent

acp_adapter/server.py 實現了 ACP Agent 協議。

職責包括:

  • 初始化 / 認證
  • 新建 / 加載 / 恢復 / 分叉 / 列出 / 取消會話方法
  • 提示執行
  • 會話模型切換
  • 將同步的 AIAgent 回調連接到 ACP 的異步通知機制

SessionManager

acp_adapter/session.py 跟蹤當前活躍的 ACP 會話。

每個會話存儲以下信息:

  • session_id
  • agent
  • cwd
  • model
  • history
  • cancel_event

該管理器是線程安全的,支持:

  • 創建
  • 獲取
  • 移除
  • 分叉
  • 列出
  • 清理
  • 工作目錄(cwd)更新

事件橋接

acp_adapter/events.pyAIAgent 的回調轉換為 ACP 的 session_update 事件。

橋接的回調包括:

  • tool_progress_callback
  • thinking_callback
  • step_callback
  • message_callback

由於 AIAgent 在工作線程中運行,而 ACP I/O 在主線程事件循環中運行,因此橋接使用:

asyncio.run_coroutine_threadsafe(...)

權限橋接

acp_adapter/permissions.py 將危險的終端確認提示轉換為 ACP 的權限請求。

映射關係如下:

  • allow_once → Hermes once
  • allow_always → Hermes always
  • 拒絕選項 → Hermes deny

超時或橋接失敗時,默認拒絕。

工具渲染輔助函數

acp_adapter/tools.py 將 Hermes 工具映射到 ACP 工具類型,並構建面向編輯器的顯示內容。

示例:

  • patch / write_file → 文件差異(diff)
  • terminal → Shell 命令文本
  • read_file / search_files → 文本預覽
  • 大型結果 → 截斷的文本塊,確保 UI 安全

會話生命週期

new_session(cwd)
-> create SessionState
-> create AIAgent(platform="acp", enabled_toolsets=["hermes-acp"])
-> bind task_id/session_id to cwd override

prompt(..., session_id)
-> extract text from ACP content blocks
-> reset cancel event
-> install callbacks + approval bridge
-> run AIAgent in ThreadPoolExecutor
-> update session history
-> emit final agent message chunk

取消操作

cancel(session_id)

  • 設置會話取消事件
  • 若可用則調用 agent.interrupt()
  • 導致提示響應返回 stop_reason="cancelled"

分叉操作

fork_session() 將消息歷史深度複製到一個新的活躍會話中,保留對話狀態,同時為分叉會話分配獨立的 session_idcwd

提供者/認證行為

ACP 未實現自己的認證存儲。

而是複用 Hermes 的運行時解析器:

  • acp_adapter/auth.py
  • hermes_cli/runtime_provider.py

因此,ACP 宣告並使用當前配置的 Hermes 提供者/憑證。

工作目錄綁定

ACP 會話攜帶編輯器的工作目錄(cwd)。

會話管理器通過任務作用域的終端/文件覆蓋機制,將該 cwd 綁定到 ACP 會話 ID,使得文件和終端工具的操作均相對於編輯器工作區進行。

同名工具調用重複問題

事件橋接按工具名稱維護 FIFO 隊列(先進先出),而非僅每個名稱一個 ID。這一點對於以下情況至關重要:

  • 並行的同名調用
  • 單步中重複的同名調用

若無 FIFO 隊列,完成事件將錯誤地關聯到錯誤的工具調用。

批准回調恢復

ACP 在提示執行期間臨時安裝一個終端工具的批准回調,執行完成後恢復之前的回調。這避免了將 ACP 會話特定的批准處理器永久全局安裝。

當前限制

  • 從 ACP 服務器的角度看,ACP 會話是進程本地的
  • 非文本提示塊目前在請求文本提取時被忽略
  • 編輯器特定的用戶體驗因 ACP 客戶端實現而異
  • tests/acp/ — ACP 測試套件
  • toolsets.pyhermes-acp 工具集定義
  • hermes_cli/main.pyhermes acp CLI 子命令
  • pyproject.toml[acp] 可選依賴項 + hermes-acp 腳本