hermes-agent/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer-guide/acp-internals.md
ethernet d84e11af4d
rip out brew + pip/PyPI wheel support (#68217)
Removes Homebrew and PyPI wheel/sdist as Hermes distribution paths while
preserving the supported source, Docker, and Nix workflows.

Changes:
- Removes the Homebrew formula, PyPI publish workflow, sdist manifest
  (MANIFEST.in), and wheel/sdist release-attachment logic from scripts/release.py.
- Keeps setuptools metadata and entry points required by editable installs
  and Docker/Nix builds, but adds a setup.py guard that rejects wheel/sdist
  builds outside a sealed Nix derivation (HERMES_NIX_BUILD=1).
- Removes pip/Homebrew install detection, PyPI update checks, the pip
  self-update path, the deprecation-banner state, the postinstall subcommand,
  wheel data-directory fallbacks in agent/i18n.py and hermes_constants.py,
  and the ACP Registry manifest/version-lockstep release logic.
- Adds /nix/store/ path detection so `nix run` / `nix profile install`
  installs (which don't set HERMES_MANAGED) are correctly identified as
  "nix" rather than falling through to "git"/"unknown".
- Retired install-method values ("pip", "homebrew") in existing
  .install_method stamps (both code-scoped and home-scoped) are ignored by
  the allowlist reader and fall through to "unknown" instead of resurrecting
  a retired enum value.
- Updates Nix packaging to ship bare runtime data (locales, optional-mcps)
  through store symlinks and wrapper env vars instead of wheel data-files.
- Removes the ACP Registry manifest/icon and their version-lockstep tests.
- Deletes or rewrites packaging, pip-update, Homebrew, and ACP Registry
  tests; adds parametrized coverage for the packaging build guard covering
  BOTH sdist and wheel paths (the guards live in separate cmdclass entries
  — a passing sdist test proves nothing about the wheel path).
- Updates installation/platform documentation and related user-facing copy.
- Adjusts the supply-chain scan so deleted install-hook files do not trigger
  a finding, while additions or modifications still require the existing
  ci-reviewed label gate.

Supported installation paths (unchanged):
- git installer (install.sh)
- Docker
- Nix/NixOS
- editable development installs (uv sync, uv pip install -e ., pip install -e .)
2026-07-22 16:51:01 -04:00

4.7 KiB
Raw Blame History

sidebar_position title description
2 ACP 内部机制 ACP 适配器的工作原理:生命周期、会话、事件桥接、审批流程与工具渲染

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

启动流程

hermes acp / hermes-acp / python -m acp_adapter
  -> acp_adapter.entry.main()
  -> parse --version / --check / --setup before server startup
  -> load ~/.hermes/.env
  -> configure stderr logging
  -> construct HermesACPAgent
  -> acp.run_agent(agent, use_unstable_protocol=True)

stdout 保留用于 ACP JSON-RPC 传输。人类可读的日志输出至 stderr。

主要组件

HermesACPAgent

acp_adapter/server.py 实现 ACP agent 协议。

职责:

  • 初始化 / 认证
  • 新建/加载/恢复/fork/列出/取消会话方法
  • prompt提示词执行
  • 会话模型切换
  • 将同步 AIAgent 回调接入 ACP 异步通知

SessionManager

acp_adapter/session.py 跟踪活跃的 ACP 会话。

每个会话存储:

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

管理器线程安全,支持:

  • create
  • get
  • remove
  • fork
  • list
  • cleanup
  • cwd 更新

事件桥接

acp_adapter/events.py 将 AIAgent 回调转换为 ACP session_update 事件。

已桥接的回调:

  • tool_progress_callback
  • thinking_callback(当前在 ACP 桥接中设置为 None——推理内容通过 step_callback 转发)
  • step_callback

由于 AIAgent 在工作线程中运行,而 ACP I/O 位于主事件循环,桥接使用:

asyncio.run_coroutine_threadsafe(...)

权限桥接

acp_adapter/permissions.py 将危险终端审批 prompt 适配为 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()
  • 使 prompt 响应返回 stop_reason="cancelled"

Fork

fork_session() 将消息历史深拷贝至新的活跃会话,在保留对话状态的同时为 fork 分配独立的 session ID 和 cwd。

Provider/认证行为

ACP 不实现自己的认证存储。

而是复用 Hermes 的运行时解析器:

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

因此 ACP 通告并使用当前配置的 Hermes provider/凭据。它还始终通告一个终端 setup 认证方法(hermes-setup,参数 --setup),以便首次运行的 ACP 客户端在启动正常 ACP 会话前可以打开 Hermes 的交互式模型/provider 配置。

工作目录绑定

ACP 会话携带编辑器 cwd。

会话管理器通过任务作用域的终端/文件覆盖将该 cwd 绑定到 ACP session ID使文件和终端工具相对于编辑器工作区运行。

重复同名工具调用

事件桥接按工具名称以 FIFO 队列跟踪工具 ID而非每个名称仅保留一个 ID。这对以下场景至关重要

  • 并行同名调用
  • 单步内重复同名调用

若不使用 FIFO 队列,完成事件将附加到错误的工具调用上。

审批回调恢复

ACP 在 prompt 执行期间临时在终端工具上安装审批回调,执行完成后恢复之前的回调。这避免了将 ACP 会话特定的审批处理器永久全局安装。

当前限制

  • ACP 会话持久化至共享的 ~/.hermes/state.dbSessionDB在进程重启后透明恢复它们会出现在 session_search
  • 非文本 prompt 块在请求文本提取时当前被忽略
  • 编辑器特定的 UX 因 ACP 客户端实现而异

相关文件

  • tests/acp/ — ACP 测试套件
  • toolsets.pyhermes-acp toolset 定义
  • hermes_cli/main.pyhermes acp CLI 子命令
  • pyproject.toml[acp] 可选依赖 + hermes-acp 脚本