Skip to main content

Copilot CLI ACP 服务器

了解 GitHub Copilot 命令行界面 的代理客户端协议 (ACP) 服务器。

注意

GitHub Copilot 命令行界面 中的 ACP 支持处于公开预览阶段(公共预览版),可能会发生变化。

概述

代理客户端协议 (ACP) 是一种标准化客户端(如代码编辑器和 IDE)与编码代理(如 Copilot 命令行界面(CLI))之间通信的协议。 有关此协议的更多详细信息,请参阅 官方简介

用例

  •         **IDE 集成:** 将 Copilot 支持构建到任何编辑器或开发环境中。
    
  •         **CI/CD 管道:** 在自动化工作流中协调代理编码任务。
    
  •         **自定义前端:** 为特定开发人员工作流创建专用接口。
    
  •         **多代理系统:** 使用标准协议协调 Copilot 与其他 AI 代理。
    

启动 ACP 服务器

可使用 --acp 标志将 GitHub Copilot 命令行界面 作为 ACP 服务器启动。 服务器支持两种模式, stdio 以及 TCP

默认情况下,在提供 --acp 标志时,stdio 模式将被推断出。 --stdio还可以提供标志来消除歧义。

copilot --acp --stdio

TCP 模式

          `--port`如果标志与`--acp`标志结合使用,则服务器以 TCP 模式启动。
copilot --acp --port 3000

与 ACP 服务器集成

库生态系统不断增加,以编程方式与 ACP 服务器交互。 假设 GitHub Copilot 命令行界面 已正确安装并通过身份验证,以下示例演示如何使用 typescript 客户端发送单个提示并打印 AI 响应。

import * as acp from "@agentclientprotocol/sdk";
import { spawn } from "node:child_process";
import { Readable, Writable } from "node:stream";

async function main() {
  const executable = process.env.COPILOT_CLI_PATH ?? "copilot";

  // ACP uses standard input/output (stdin/stdout) for transport; we pipe these for the NDJSON stream.
  const copilotProcess = spawn(executable, ["--acp", "--stdio"], {
    stdio: ["pipe", "pipe", "inherit"],
  });

  if (!copilotProcess.stdin || !copilotProcess.stdout) {
    throw new Error("Failed to start Copilot ACP process with piped stdio.");
  }

  // Create ACP streams (NDJSON over stdio)
  const output = Writable.toWeb(copilotProcess.stdin) as WritableStream<Uint8Array>;
  const input = Readable.toWeb(copilotProcess.stdout) as ReadableStream<Uint8Array>;
  const stream = acp.ndJsonStream(output, input);

  const client: acp.Client = {
    async requestPermission(params) {
      // This example should not trigger tool calls; if it does, refuse.
      return { outcome: { outcome: "cancelled" } };
    },

    async sessionUpdate(params) {
      const update = params.update;

      if (update.sessionUpdate === "agent_message_chunk" && update.content.type === "text") {
        process.stdout.write(update.content.text);
      }
    },
  };

  const connection = new acp.ClientSideConnection((_agent) => client, stream);

  await connection.initialize({
    protocolVersion: acp.PROTOCOL_VERSION,
    clientCapabilities: {},
  });

  const sessionResult = await connection.newSession({
    cwd: process.cwd(),
    mcpServers: [],
  });

  process.stdout.write("Session started!\n");
  const promptText = "Hello ACP Server!";
  process.stdout.write(`Sending prompt: '${promptText}'\n`);

  const promptResult = await connection.prompt({
    sessionId: sessionResult.sessionId,
    prompt: [{ type: "text", text: promptText }],
  });

  process.stdout.write("\n");

  if (promptResult.stopReason !== "end_turn") {
    process.stderr.write(`Prompt finished with stopReason=${promptResult.stopReason}\n`);
  }

  // Best-effort cleanup
  copilotProcess.stdin.end();
  copilotProcess.kill("SIGTERM");
  await new Promise<void>((resolve) => {
    copilotProcess.once("exit", () => resolve());
    setTimeout(() => resolve(), 2000);
  });
}

main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

延伸阅读

  •         [官方 ACP 文档](https://agentclientprotocol.com/protocol/overview)