一套组件,接入所有 ACP Agent:acp-components 介绍

基于 Agent Client Protocol (ACP) 的通用前端组件库,帮你把任意 ACP 兼容的 Agent 包装成开箱即用的桌面/Web 工作台------也可以作为依赖库,快速构建你自己的 Agent 应用。

📦 项目地址:github.com/zvzuola/acp... · MIT License

如果你正在寻找一个能同时满足「我要一个现成的 Agent 工作台」和「我要把它当 SDK 集成进我自己的应用」两种诉求的方案,acp-components 正是为这两种用法设计的。它不是一个只能跑 demo 的玩具,而是一个分层清晰、可插拔、可扩展的组件体系:

  • @acp-components/core ------ 框架无关的 TypeScript 数据层:负责传输、状态管理、业务逻辑,零 React 依赖。你可以用它配 Vue / Svelte / Solid / 原生 JS。
  • @acp-components/react ------ React UI 层:上下文 Provider + 25+ 组件 + hooks,负责渲染与交互。

下面我们通过示例应用来快速感受它「开箱即用」的部分,再看它「作为依赖库」时有多灵活。


一、开箱即用:两种宿主示例

仓库自带两个示例应用,分别覆盖 Web桌面(Tauri) 两种宿主形态,它们同时也是你集成时的参考实现。

1. Web Demo(浏览器版 Agent 工作台)

Web demo 用 Vite 驱动,通过一个 WebSocket ↔ stdio 桥接服务器 把本地 Agent 进程暴露给浏览器。这套桥接架构很有代表性:浏览器无法直接 spawn 子进程,于是用 dev:server 起一个 WebSocket 服务,背后用 stdio 拉起 opencode(或 Codex / Claude)的 ACP 子命令,前端用 websocket 传输连进去。

bash 复制代码
# Terminal 1 --- 桥接服务器(WebSocket ↔ stdio 代理)
pnpm dev:server          # 默认 opencode
# 或换 Codex / Claude
pnpm dev:server-codex
pnpm dev:server-claude

# Terminal 2 --- Vite 前端
pnpm dev                 # http://localhost:5173

启动后你将看到一个完整的工作台 Shell:左侧侧边栏(导航 + 会话列表 + 底部菜单),右侧主区域随导航切换 Sessions / Skills / New Session / Settings 等视图。

2. Tauri Desktop(原生桌面版)

Tauri 版则直接用 stdio 传输 拉起本地 Agent 进程,省去了桥接服务器------这是真正意义上的「本地优先」桌面应用。它用 Tauri 的 plugin-fs / plugin-dialog 实现原生文件读写与目录选择,Monaco 做代码预览。

bash 复制代码
pnpm dev:tauri      # 桌面开发模式
pnpm build:tauri    # 生产构建

关键差异:{ type: 'stdio' } 配置需要宿主提供 platform.process.createStdioTransport 能力(即真的能 spawn 子进程)。浏览器无法 spawn,所以 Web demo 走 websocket 连桥接服务器;桌面端走 stdio 直连。同一个组件库,两种传输策略,同一套 UI。


二、当前支持的能力一览

示例应用的「能用」背后,是组件库一整套能力。下面按使用场景梳理:

多 Agent · 多工作区 · 多会话

  • 多 Agent :可同时连接多个 ACP Agent,各自独立的传输、能力与会话管理。用户运行时添加的 Agent 会持久化到 storage('agents'),下次启动自动恢复;内置(宿主提供的)Agent 不可被用户移除。
  • 多工作区(Workspace) :按工作目录(cwd)组织会话,工作区列表由 <PlatformWorkspacesAuto> 自动持久化到 storage('workspaces')
  • 多会话 + 分屏:可在可调整大小的分栏中并排运行/查看多个会话,每个会话状态完全隔离(消息、流式、工具调用、权限)。逐会话的 chunk 批处理保证多路并发流互不干扰。

传输层:Stdio / HTTP / WebSocket / Custom

每个 Agent 独立配置传输,按宿主能力挑选:

rust 复制代码
// Stdio --- 直接 spawn Agent 进程(Electron / Tauri / Node 桌面)
{ id: 'desktop', name: 'Desktop', transport: { type: 'stdio', command: 'opencode', args: ['acp'] } }

// HTTP --- 通过 HTTP POST 连接
{ id: 'http', name: 'HTTP', transport: { type: 'http', url: 'http://localhost:8080/acp' } }

// WebSocket --- 连接桥接服务器(浏览器环境)
{ id: 'ws', name: 'WebSocket', transport: { type: 'websocket', url: 'ws://127.0.0.1:3100' } }

// Custom --- 自己实现 AcpTransport(Tauri IPC / Electron IPC / iframe postMessage...)
{ id: 'custom', name: 'Custom', transport: { type: 'custom', transport: myTransport } }

会话视图与会话面板

SessionView 是核心工作面:左侧 SessionPanes(可分屏聊天列),右侧 SessionPanel 自带 Files 标签页FileTree + FileViewer 两栏),并支持宿主注入额外标签页。

  • FileTree :按工作区的懒加载文件树,支持展开/折叠、刷新、打开时定位。可选实时监听(watchFileTree)。
  • FileViewer :面板内置 Monaco 文件查看器,语法高亮 + revealLine 行定位。

聊天 · 流式 · 工具调用 · 计划

  • ChatView :把消息按用户/Agent 轮次分组,内联渲染 plan、usage 进度条、config 面板与权限提示
  • 流式 UX:实时内容与思考流式(逐会话批处理),带动画指示器、实时工具调用状态、token 用量追踪。
  • ToolCallCard:展示工具调用名称、状态、输入/输出、文件位置与 diff。
  • PlanView / ThoughtView / DiffView:计划条目、思考链、文件改动 diff 各自的可视化。

权限与认证

  • 权限流程 :基于 Promise 的逐会话权限流,PermissionPromptChatView 内联渲染,批准或拒绝工具调用请求;会话关闭或 Agent 断开时自动拒绝。
  • 认证 :内置 LoginDialog,支持 env_var 与 terminal 两种认证方式,env var 表单输入,5 分钟超时。

Skills 目录 · 设置 · 命令面板

  • SkillView :通过 listSkills() 实时拉取每个已连接 Agent 的技能目录,按作用域(用户级 vs 项目 cwd 级)分组,带搜索。
  • SettingsView :全页设置(Appearance 主题 + Agents 管理),可通过追加 SETTINGS_SECTIONS 扩展。
  • CommandPalette:可用命令的斜杠命令面板。

主题与国际化

  • 主题 :暗色 / 亮色内置主题,全部走 CSS 自定义属性(--acp-*),运行时 useSettings().setTheme() 切换;支持自定义主题覆盖变量。
  • i18n :内置 en-US / zh-CN,i18next 自动从宿主 Platform.system.getLocale() 检测(Web: navigator.language,桌面: 系统语言)。

三、作为依赖库:构建你自己的 Agent 应用

示例应用之外,acp-components 的真正价值在于「当依赖库用」。最小可用配置只需三个 Provider 套一层 WorkbenchShell

javascript 复制代码
import {
  I18nProvider, PlatformProvider, AcpProvider,
  WorkbenchShell, LoginDialog, useAcpStore,
} from '@acp-components/react';
import { createWebPlatform } from './webPlatform'; // 你自己的宿主 Platform 工厂

function AppInner() {
  const activeSessionId = useAcpStore((s) => s.activeSessionId);
  return (
    <>
      <WorkbenchShell sessionId={activeSessionId} />
      <LoginDialog />
    </>
  );
}

function App() {
  return (
    <PlatformProvider platform={createWebPlatform()}>
      <I18nProvider>
        <AcpProvider
          agents={[
            { id: 'main', name: 'Main Agent',
              transport: { type: 'websocket', url: 'ws://127.0.0.1:3100' } },
          ]}
          theme="dark"
        >
          <AppInner />
        </AcpProvider>
      </I18nProvider>
    </PlatformProvider>
  );
}

多 Agent 集成示例

同时连接不同模式、不同用途的多个 Agent:

bash 复制代码
<AcpProvider
  agents={[
    { id: 'craft', name: 'Craft Agent', transport: { type: 'websocket', url: 'ws://127.0.0.1:3100' } },
    { id: 'ask',    name: 'Ask Agent',    transport: { type: 'stdio', command: 'opencode', args: ['acp', '--mode', 'ask'] } },
  ]}
  theme="dark"
>
  <App />
</AcpProvider>

框架无关的核心层

@acp-components/core 零 React 依赖,可直接配 Vue / Svelte:

php 复制代码
import { acpStore, sessionStore, fileTreeStore, skillStore, createAcpProvider, sendPrompt } from '@acp-components/core';

const provider = createAcpProvider(
  { agents: [{ id: 'main', name: 'Main', transport: { type: 'stdio', command: 'opencode', args: ['acp'] } }] },
  stdioFactory, // 宿主的 spawn 能力;无此能力传 null
);

provider.subscribe(() => { if (provider.ready) console.log('All agents connected!'); });

// 直接读 vanilla store
acpStore.getState().workspaces;
skillStore.getState();

// 命令式动作
const client = provider.getClient('main');
await sendPrompt(client!, sessionId, blocks);

// 动态增删 Agent(运行时添加的会持久化)
await provider.addAgent({ id: 'analyze', name: 'Analyze', transport: { type: 'websocket', url: 'ws://...' } });
await provider.removeAgent('analyze');

provider.destroy();

扩展点

扩展 做法
自定义传输 实现 AcpTransport 接口,按 { type: 'custom', transport: instance } 传入。真实场景:Tauri IPC、Electron IPC、Chrome 扩展消息、iframe postMessage。
自定义 Platform 实现 Platform 接口(fs? / dialogs? / openExternalEditor? / updater? / system?storage 必填),按切片/方法是否存在表达能力,调用处用 ?. 守卫。参考 createWebPlatform() / createTauriPlatform()
扩展工作台 WorkbenchShell 注入 navItems(主区视图)与向 SessionView 注入 tabs(侧面板标签页),例如注入一个 Terminal 视图。
动态 Agent 管理 useAcpContext()addAgent / removeAgent 带持久化;内置 Agent 不可移除。

能力(capability)与数据(data)正交:Platform 拥有「原生能力」(如 fs.readDirectory),而「要 spawn 哪个 Agent」(command/args/env)只是 AgentConfig.transport 上的纯数据------两者分离,互不耦合。


四、两种用法,怎么选?

场景 推荐
想要一个现成的多 Agent 工作台,支持接入各种 ACP Agent 直接用 examples/tauri(桌面)或 examples/demo(Web)作为起点
已有 React 应用,想集成 Agent 工作台 UI @acp-components/react 作为依赖,按需引入组件
非 React 技术栈(Vue/Svelte/原生),只要协议与状态层 @acp-components/core 单独使用
自研传输(IPC / postMessage / 自定义协议) 实现 AcpTransport,走 { type: 'custom' }
自研宿主能力(文件、对话框、更新器) 实现 Platform 接口,注入 <PlatformProvider>

五、技术栈与状态

技术
协议 @agentclientprotocol/sdk
状态 Zustand v5(vanilla store,无 React 依赖)
UI React 18 / 19
代码编辑器 Monaco(可选 peer dep,仅 FileViewer 用)
i18n i18next + react-i18next
Markdown react-markdown + remark-gfm
样式 SCSS Modules + CSS 自定义属性
构建 Vite 6(库模式,ESM/CJS 双产物)
测试 Vitest + @testing-library/react + jsdom
包管理 pnpm workspace monorepo

安装

sql 复制代码
pnpm add @acp-components/core @acp-components/react

Peer 依赖:react (^18 || ^19)、react-dom (^18 || ^19)。monaco-editor 为可选 peer dep------仅当你用内置 FileViewer 时才需要。


六、下一步

  • 想跑起来看看:克隆仓库后按 README.md 的 Web Demo / Tauri Desktop 步骤启动。
  • 想当依赖用:从上面「最小可用配置」开始,按你的宿主实现 Platform
  • 想扩展:从「扩展点」表格里挑一个方向------自定义传输、自定义 Platform、注入工作台视图。

ACP 的目标是让 Agent 与客户端解耦,acp-components 的目标是让前端不再重复造轮子。如果你在构建 Agent 工作台,欢迎试试------也欢迎 issue / PR。

📦 项目地址:github.com/zvzuola/acp... · MIT License

相关推荐
一枚菜鸟_1 小时前
在 Flutter 项目里装 Skills:从 0 搭建 AI 辅助开发体系
flutter·ai编程
项羽欧大哥2 小时前
LangChain 和 LangGraph 到底有什么区别?实际项目中应该怎么选
langchain·agent·langgraph
李燚2 小时前
ToolsNode 源码:LLM 返回 tool_calls 之后发生了什么(第53篇-E39)
agent·tool·multi-agent·eino·toolsnode
孤狼GPT3 小时前
Codex免费版够用吗?Free、Plus和Pro怎么选
chatgpt·ai编程·codex·chatgpt plus·chatgpt pro
掉鱼的猫3 小时前
用 Solon ReActAgent 落地发票识别与智能报销
java·llm·agent
jvmind_dev3 小时前
第一章:AI Agent 如何重新定义 Java 性能分析
java·agent
Qiye3 小时前
【Hermes Agent】多Profile实战 + 机制深度解析
agent
小小放舟、4 小时前
PaiCLI-Demo:从零实现 ReAct Agent + Tool Call
java·后端·intellij-idea·springboot·agent·react·tool call
袋鼠云数栈UED团队5 小时前
Agent Loop:让 Agent 真正跑起来的核心机制
ai编程