ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

CodeCompanion.nvim 的 Agent Client Protocol (ACP) 支持:会话、工具与权限的完整技术解析

CodeCompanion.nvim 的 Agent Client Protocol (ACP) 支持:会话、工具与权限的完整技术解析 CodeCompanion.nvim 的 Agent Client Protocol (ACP) 支持会话、工具与权限的完整技术解析【免费下载链接】codecompanion.nvim✨ AI Coding, Vim Style项目地址: https://gitcode.com/GitHub_Trending/co/codecompanion.nvimACPAgent Client Protocol是 CodeCompanion.nvim 连接外部编码 Agent如 Claude Code、Codex、Gemini CLI的开放协议通道它让 Neovim 用户可以直接在聊天缓冲区中驱动独立的 AI 编码 Agent。本文以仓库中的 doc/agent-client-protocol.md 为主干结合lua/codecompanion/acp/与lua/codecompanion/interactions/chat/acp/下的源码实现系统讲解 CodeCompanion 对 ACP 的能力覆盖、有状态会话管理、权限审批、会话恢复与模型切换机制以及当前协议版本的已知限制帮助你在实际配置与二次开发中快速定位所需能力。ACP 是什么CodeCompanion 如何接入ACP 是一个开放的通信标准用于规范“客户端Client”与“AI Agent”之间的结构化交互。CodeCompanion 作为客户端通过 ACP 与独立的编码 Agent 进程通信从而获得会话管理、文件系统操作、工具执行和权限处理等能力这些能力全部在 Neovim 内部完成无需离开编辑器。从源码结构看ACP 相关的实现被组织为两个层次协议核心层lua/codecompanion/acp/init.lua 中的Connection类负责进程生命周期、JSON-RPC 收发、会话建立与认证lua/codecompanion/acp/methods.lua 集中定义了全部协议方法名。交互层lua/codecompanion/interactions/chat/acp/ 下的handler.lua、commands.lua、fs.lua、request_permission.lua等模块负责把协议事件渲染到聊天缓冲区、管理 Agent 动态注册的斜杠命令、执行文件读写与权限审批 UI。功能实现总览哪些能力已落地文档给出了一张完整的能力对照表CodeCompanion 对 ACP 规范的支持覆盖了核心协议、认证、内容类型、文件系统、MCP 集成、权限、会话管理与工具调用功能类别支持情况说明核心协议✅JSON-RPC 2.0、流式响应、消息缓冲认证✅多种认证方式、适配器级钩子内容类型✅文本、图片、嵌入资源文件系统✅支持行范围的文件读写MCP 集成✅Stdio、HTTP 与 SSE 传输权限✅带 diff 预览的交互式审批 UI会话管理✅创建、列出、加载与恢复会话含状态追踪会话模式✅模式切换会话模型✅选择指定模型工具调用✅内容块、文件 diff、状态更新Agent 计划❌Agent 执行计划的可视化展示终端操作❌Agent 访问 Neovim 终端其中“消息缓冲”在实现层面体现为Connection内的jsonrpc.LineBuffer由于 JSON-RPC 的消息边界不一定与 I/O 边界对齐lua/codecompanion/acp/init.lua 中的buffer_stdout_and_dispatch会先把 stdout 数据压入行缓冲再逐行派发给handle_rpc_message解析这是保证长流式响应稳定解析的关键。支持的适配器与客户端能力声明适配器生态CodeCompanion 为 ACP 兼容的 CLI 工具预置了众多适配器源码位于 lua/codecompanion/adapters/acp/包括claude_code、codex、gemini_cli、copilot_acp、cursor_cli、opencode、cagent、cline_cli、goose、kilocode、kimi_cli、kiro、mistral_vibe、auggie_cli等。具体安装与配置方式见 doc/configuration/adapters-acp.md那里给出了每种工具的前置安装步骤、认证方式与自定义命令示例。每个 ACP 适配器都是一个结构化的 Lua 表以 claude_code.lua 为例它声明了commands.default启动 Agent 的进程命令如claude-agent-acpenv需要注入的环境变量如CLAUDE_CODE_OAUTH_TOKENparameters初始化握手参数包括protocolVersion 1与clientCapabilitieshandlerssetup、auth、form_messages、on_exit等生命周期钩子。客户端能力声明CodeCompanion 通过初始化握手向 ACP Agent 声明自身能力文档给出了完整的声明内容{ fs { readTextFile true, -- Read files with optional line ranges writeTextFile true -- Write/create files }, terminal false -- Terminal operations not supported }这段声明与源码中每个 ACP 适配器的parameters.clientCapabilities一致见 claude_code.lua 第 33-35 行文件系统读写能力被开放而终端能力被显式关闭Agent 无法获得 Neovim 终端访问权。内容类型能收发什么文档用一张表明确了 ACP 通道的内容类型支持内容类型发送给 Agent从 Agent 接收文本✅✅文件 Diff不适用✅图片✅❌音频❌❌嵌入资源❌❌在实现层面内容类型的解析由 lua/codecompanion/acp/prompt_builder.lua 的extract_text函数完成它根据内容块的type字段区分text、resource_link、resource、image、audio把非文本块转换为可展示的占位符如[image]、[resource: uri]再交给聊天缓冲区的渲染层。图片发送则由 lua/codecompanion/adapters/acp/helpers.lua 的form_messages处理只有当 Agent 通过promptCapabilities声明支持图片时才会生成image内容块否则会记录一条警告日志。这也解释了为何 Agent 到客户端的图片如截图回传当前不被支持。有状态会话与 HTTP 适配器的本质差异文档强调了一个关键设计差异HTTP 适配器是无状态的每次请求都携带完整对话历史而ACP 适配器是有状态的——对话上下文由 Agent 维护CodeCompanion 每次提示只发送新增消息并通过session_id在整个会话生命周期内追踪状态。这一点在 helpers.lua 的form_messages中得到印证它只保留role user且_meta.sent未被标记的消息即“Agent 还没看过的消息”从而避免重复发送历史。相应地连接对象Connection维护_initialized、_authenticated、session_id等状态标志并通过is_connected()/is_ready()暴露给上层判断当前连接状态。会话建立流程从 lua/codecompanion/acp/init.lua 的调用链可以还原完整的会话建立流程connect_and_authenticate()启动 Agent 子进程start_agent_process发送initialize握手请求校验双方protocolVersion随后进入认证阶段_authenticate()优先调用适配器自定义的handlers.auth钩子如 Claude Code 的 OAuth token 注入否则读取 Agent 广播的authMethods匹配配置的auth_method并发送authenticate请求_establish_session()根据session_id是否存在以及 Agent 是否支持loadSession决定发送session/load还是session/new。会话建立时还会携带cwd与mcpServers参数。认证顺序在源码中表现为“适配器钩子优先、协议认证兜底”自定义钩子成功即完成认证否则才尝试 Agent 广播的认证方法。若配置的auth_method未被 Agent 广播连接会直接失败并给出可用的方法列表。文件上下文处理重新读取而非复用缓冲区文档指出当把文件作为嵌入资源发送给 Agent 时CodeCompanion 会重新读取文件内容而不是使用聊天缓冲区中的表示。这样做的目的是避免 HTTP 适配器专用的attachment标签出现在 ACP 消息中——该类标签对 LLM 适配器有意义对 ACP Agent 则没有意义。实际发送时见 helpers.lua文件与缓冲区上下文被转换为纯文本形式Sharing the following file as context: path而 Agent 侧的主动文件读取则走fs/read_text_file/fs/write_text_file协议方法实现在 lua/codecompanion/interactions/chat/acp/fs.lua读取支持line与limit参数实现行范围切片若文件不存在则返回ENOENTCodeCompanion 会把它当作空内容返回给 Agent从而允许 Agent 直接创建新文件写入优先写入已打开的缓冲区保持 Neovim 内的同步否则直接写盘成功后触发FileEdited事件供其他模块响应。动态斜杠命令Agent 自主宣传能力ACP Agent 可以动态宣传自己的斜杠命令。CodeCompanion 在聊天缓冲区中通过\command访问这些命令并在发送提示前自动将其转换为/command格式。底层实现位于 lua/codecompanion/interactions/chat/acp/commands.luaAgent 通过session/update通知中的available_commands_update推送命令列表由 acp/init.lua 的handle_available_commands_update接收命令按session_id存储并通过link_buffer_to_session把聊天缓冲区与会话绑定实现按缓冲区查询可用命令命令更新后会触发CodeCompanionACPCommandsUpdate用户事件供补全插件如 blink、cmp 等刷新候选列表缓冲区关闭时通过CodeCompanionChatClosed自动解绑避免内存泄漏。会话恢复/resume的完整链路如果 Agent 支持session/list能力就可以在新的聊天缓冲区中用/resume斜杠命令恢复历史会话。文档描述的流程是调用session/list发现历史会话再调用session/load把所选会话的对话历史恢复到聊天缓冲区。对应实现见 lua/codecompanion/interactions/chat/slash_commands/builtin/resume.lua其中有两个重要细节能力预检命令的enabled钩子会先检查can_list_sessions()与can_load_session()二者分别对应 Agent 广播的sessionCapabilities.list与loadSession能力见 acp/init.lua 第 282-295 行不满足时命令直接禁用并给出原因提示分页拉取session_list支持max_sessions上限默认 500与nextCursor游标分页并且session/load加载过程中收到的session/update通知会被收集用于在加载完成后重放渲染出完整历史restore_session同时恢复会话标题并触发ACPChatRestored事件。session/list与session/load的方法名定义可参见 lua/codecompanion/acp/methods.lua。模型选择session/set_model与配置项联动CodeCompanion 实现了session/set_model方法允许为当前会话切换模型。文档特别注明该方法不属于官方 ACP 规范官方规范中使用的是session/set_config_option因此在未来版本中可能变化。从 acp/init.lua 的实现看模型选择依赖 Agent 在会话开始时通过configOptions广播的配置项_apply_config_optionsget_models()从category model且type select的配置项中提取当前模型 ID 与可选模型列表set_model(model_id)本质上是把set_config_option(opt.id, model_id)包装了一层flatten_config_options处理 ACP 规范允许的分组选项sessionconfigselectgroup把分组内的值展开为扁平列表。模型还可以通过配置直接预置见 doc/configuration/adapters-acp.md 的 “Setting Default Session Config Options” 一节支持三种方式-- 方式一在 interactions 中直接指定 require(codecompanion).setup({ interactions { chat { adapter { name codex, model gpt-5.4, }, }, }, }) -- 方式二在适配器 defaults 中以静态字符串指定 -- 方式三在适配器 defaults 中以函数动态计算指定 require(codecompanion).setup({ adapters { acp { codex function() return require(codecompanion.adapters).extend(codex, { defaults { session_config_options { model function(self) return gpt-5.4 end, mode Full Access, -- 其他会话配置项 thought_level Xhigh, }, }, }) end, }, }, })若想查看某个适配器具体支持哪些会话配置项可以打开聊天缓冲区的 调试窗口Debug Window查看 Agent 广播的configOptions原始数据。权限审批带 diff 预览的交互式 UI权限处理是 ACP 交互中最具实战价值的环节。当 Agent 需要执行工具调用时会发送session/request_permission请求CodeCompanion 通过 lua/codecompanion/interactions/chat/acp/request_permission.lua 呈现审批界面。其核心机制包括选项映射将 ACP 的权限选项种类allow_once、allow_always、reject_once、reject_always映射到 CodeCompanion 统一的审批快捷键接受、始终接受、拒绝、取消键位定义来自 lua/codecompanion/interactions/chat/tools/labels.luadiff 预览如果工具调用的内容块类型为diff且 diff 非空审批界面会优先展示旧文本/新文本的对比支持q关闭、Next/Prev在 hunk 间跳转、以及按对应的审批键直接响应响应协议所有审批最终通过send_result(id, { outcome ... })回给 Agentselected携带所选optionId取消则返回cancelled这与 prompt_builder.lua 中handle_permission_request的响应构造保持一致。生命周期与清理VimLeavePre兜底CodeCompanion 通过监听 Neovim 的VimLeavePre自动命令保证与 ACP Agent 的干净断开见 acp/init.lua 第 149-156 行即使 Neovim 异常退出也会调用disconnect()向 Agent 进程发送SIGTERM确保子进程被正确终止。进程意外退出时handle_process_exit会做完整的收尾触发适配器的on_exit钩子、释放所有挂起的异步回调防止协程悬挂、重置认证/初始化/会话状态并把活动提示标记为canceled。协议版本协商CodeCompanion 目前实现的是ACP Protocol Version 1protocolVersion 1。协议版本在初始化阶段协商如果 Agent 选择了不同的版本CodeCompanion 会记录一条警告日志但仍会继续运行并遵循 Agent 选择的版本工作。对应源码在connect_and_authenticate中的版本比对逻辑见 acp/init.lua 第 136-144 行。当前限制文档明确列出了三个尚未实现的能力配置前值得留意终端操作terminal/*系列方法terminal/create、terminal/output、terminal/release等均未实现CodeCompanion 不会向 Agent 声明终端能力客户端能力中terminal falseAgent 计划渲染来自 Agent 的 Plan 更新会被接收并记录日志handle_session_update中的plan分支但目前不会在聊天缓冲区 UI 中渲染可视化执行计划音频内容音频既不能发送也不能接收。相关资源Agent Client Protocol 官方规范ACP 的完整协议文档配置 ACP 适配器各 CLI Agent 的安装与配置步骤、自定义适配器写法在聊天中使用 Agent 与工具聊天缓冲区中与 Agent 交互的日常用法MCP 配置如何定义 MCP 服务器并通过mcpServers inherit_from_config让 ACP Agent 自动继承核心实现源码lua/codecompanion/acp/init.lua、lua/codecompanion/acp/prompt_builder.lua、lua/codecompanion/interactions/chat/acp/测试用例tests/acp/与tests/adapters/acp/目录下的test_acp.lua、test_prompt_builder.lua等覆盖了连接、消息解析与提示构建等核心路径可作为二次开发的行为参考【免费下载链接】codecompanion.nvim✨ AI Coding, Vim Style项目地址: https://gitcode.com/GitHub_Trending/co/codecompanion.nvim创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表