把任何本地 LLM(Ollama、llama.cpp、OpenAI 相容的後端)變成 Agent Client Protocol 相容的 agent。在 Zed、JetBrains、ACP UI、Meuxe、Codex CLI 裡 spawn 它 — 資料不離開本機。
你在編輯器裡寫 code。編輯器 spawn acp-bridge 當 subprocess,透過 stdin/stdout 上的 JSON-RPC 跟它對話。acp-bridge 透過原生 HTTP API 跟你的本地 LLM(Ollama、llama.cpp、vLLM、LM Studio,任何 OpenAI 相容的都行)對話。Tool calls 不離開你的機器。
acp-bridge 在 init 時跟每個 client 協商 protocol version。下表是各 client 目前講的版本,跟 acp-bridge 會回應的 wire。
| Client | ACP 版本 | acp-bridge wire | 測試狀態 |
|---|---|---|---|
| Zed | v1 | v1 | ✓ zed_style.rs e2e |
| JetBrains IDEs | v1 | v1 | ✓ mirror Zed shape |
| ACP UI | v1 | v1 | ✓ via inspector_style.rs e2e |
| ACP Inspector | v1 | v1 | ✓ via inspector_style.rs e2e |
| Meuxe | v1 | v1 | ✓ — issue #13 已修 |
| Codex CLI adapter | v1 (minimal) | v1 | ✓ via minimal_style.rs e2e |
| Claude Code (Claude Agent SDK) | v1 | v1 | 手動驗過互通 |
| OpenCode | v2 (preview) | v1 (negotiated) | OpenCode 正式出 v2 後會自動協商到 v2 |
acp-bridge 同份 code base 完整實作 ACP v1 跟 v2。協商是自動的:init 時 client 送它偏好的 protocolVersion,acp-bridge 挑雙方都支援的最高版本,之後每個 notification 都用對應的 wire shape。
| 概念 | v1 wire | v2 wire |
|---|---|---|
initialize response | agentInfo + agentCapabilities | 統一 info + capabilities |
image capability | true / false | {}(marker)或 omit |
| Tool start notification | tool_call 帶 toolCallId + kind + status: "in_progress" | tool_call_update 帶同樣欄位(tool_call 不再發) |
| Plan | {sessionUpdate: "plan", entries[]} | {sessionUpdate: "plan_update", plan: {type: "items", planId, entries[]}} |
| Turn 結束 | (無) | state_update 帶 stopReason |
tool_calls 欄位,導致 agent 卡住。acp-bridge 現在會剝除 think 標籤,並從 content 內嵌的 JSON(fenced 或裸物件)復原 tool call,繼續正常 dispatch。185 個測試通過。session/close 跟 session/list、Ollama 原生 tool.arguments object 處理、web_fetch redirect 重新驗證 allowlist。171 tests passing。init 時協商 protocolVersion,emit 對應 v1 或 v2 wire shape。同份 code,根據版本 dispatch。One binary. Negotiation at init picks the right wire shape per Client. Today that means Zed / JetBrains / ACP UI / Meuxe / Codex CLI on v1, future v2-only Clients on v2.
read_file, list_dir, search_code, write_file, edit, web_fetch (opt-in), bash, git_status / git_diff / git_log / git_commit. Sandboxed to the session working dir.
Single 5 MB static Rust binary. No npm. No models.dev fetches. No LSP. Outbound only to the configured LLM endpoint, opt-in via LLM_WEB_ALLOWLIST.