Skip to main content

Copilot CLI ACP сервер

Узнайте о интерфейс командной строки GitHub Copilotсервере протокола Agent Client от '.

Примечание.

Поддержка ACP в интерфейс командной строки GitHub Copilot системе Публичный предварительный просмотр и может измениться.

Обзор

Протокол агента-клиента (ACP) — это протокол, который стандартизирует коммуникацию между клиентами (такими как редакторы кода и IDE) и агентами (например Второй пилот CLI, ). Для получения дополнительной информации об этом протоколе см. официальное введение.

Случаи использования

  • Интеграции IDE: Встраивайте Copilot поддержку в любой редактор или среду разработки.
  • CI/CD pipelines: Оркестрирование задач агентного кодирования в автоматизированных рабочих процессах.
  • Кастомные фронтенды: Создавайте специализированные интерфейсы для конкретных рабочих процессов разработчиков.
  • Многоагентные системы: Координируйте Copilot действия с другими агентами ИИ по стандартному протоколу.

Запуск сервера ACP

--acp Используйте параметр copilot команды, чтобы запустить сервер ACP интерфейса командной строки. Можно указать режим транспорта с --stdio помощью параметров или --port параметров. Если режим транспорта не указан, сервер по умолчанию использует режим stdio.

Параметры, применяемые к каждому сеансу

Запрос ACP session/new позволяет клиенту задать несколько параметров сеанса, таких как рабочий каталог и серверы MCP. Он не содержит параметров фильтрации инструментов или причин. Чтобы настроить эти параметры, передайте соответствующие параметры при запуске сервера. Сервер хранит значения и применяет их в качестве начальной конфигурации для каждого сеанса, который он создает или загружает, для любого клиента, который подключается. Подключающийся клиент не выбирает эти значения, независимо от того, кто запускает сервер.

Параметр сервераПринятое значениеВлияние на каждый сеанс
--available-tools=TOOL ...Кавычек, разделенный запятыми список имен инструментовСеанс может использовать только перечисленные средства.
--excluded-tools=TOOL ...Кавычек, разделенный запятыми список имен инструментовПеречисленные средства удаляются из сеанса.
--effort=LEVEL, --reasoning-effort=LEVEL
low, medium, high, xhigh или maxЗадает начальную причину сеанса.

Например, эта команда запускает сервер, сеансы которого используют максимальное усилие по поводу и предоставляют только bash те и view средства:

copilot --acp --port 3000 --effort=max --available-tools="bash,view"

Каждый сеанс подключенного клиента открывается для этого сервера, наследуя эти параметры. Так как значения фиксируются при запуске сервера, клиент не может изменять их на сеанс.session/new

Режим stdio

Режим stdio по умолчанию выводится при запуске сервера ACP. Вы также можете использовать --stdio параметр для диамбигуации.

copilot --acp --stdio

Режим TCP

Если параметр --port предоставляется в сочетании с параметром --acp , сервер запускается в режиме TCP.

copilot --acp --port 3000

Выбор между stdio и TCP

Оба режима транспорта несут одни и те же сообщения ACP, закодированные в формате JSON с разделителями новой строки (NDJSON). Они отличаются только тем, как клиент подключается к серверу и как управляется жизненным циклом сервера. Два режима являются взаимоисключающими: передача обоих --stdio и --port отклонений.

АспектРежим stdioРежим TCP
Как клиент подключаетсяКлиент запускается copilot --acp как дочерний процесс и обменивается сообщениями по стандартным входным и выходным данным процесса.Сервер открывает прослушиватель TCP, к которому клиенты подключаются через сетевой сокет. По умолчанию он привязывается к адресу 127.0.0.1обратного цикла.
Количество клиентовОдин клиент — процесс, который породил сервер и владеет каналом.Прослушиватель принимает подключения сокетов, каждый из которых обрабатывается в качестве собственного подключения агента.
Жизненный циклПривязан к родительскому процессу. Когда входной поток закрывается , так как родительский выход или закрывает канал, сервер завершает работу автоматически.Независимо от одного клиента. Сервер продолжает прослушивать порт, пока он не будет остановлен, например с помощью CTRL+C.
Стандартные выходные данныеЗарезервировано для потока протокола NDJSON, поэтому его нельзя использовать для журналов или другого текста.Бесплатно для другого использования, так как трафик протокола перемещается по сокету.

Когда следует использовать каждый режим:

  • Используйте режим stdio , когда редактор, интегрированная среда разработки или скрипты возникают Второй пилот CLI непосредственно в качестве подпроцесса. Это по умолчанию и рекомендуемая настройка для интеграции интегрированной среды разработки, так как транспорт устанавливается автоматически при запуске процесса и отключается при завершении работы.
  • Используйте режим TCP , когда клиенту нужно связаться с сервером через сокет вместо канала, например из отдельного процесса или контейнера или при подключении к более длительному серверу на известном порту.

Пример: интеграция с сервером ACP

В следующем примере используется клиентское приложение, которое взаимодействует Copilot с интерфейс командной строки GitHub Copilotсервером ACP. Он запускает сервер ACP в режиме stdio, открывает сеанс, запрашивает ввод запроса, отправляет его и выводит потоковый ответ.

Существует растущая экосистема библиотек для программного взаимодействия с серверами ACP. В этом примере используется библиотека ACP TypeScript.

Чтобы запустить этот пример, вам потребуется следующие зависимости:

  • Node.js версии 18 или более поздней.
  • интерфейс командной строки GitHub Copilot, установленный и прошедший проверку подлинности.
  • Пакет @agentclientprotocol/sdk , предоставляющий библиотеку ACP TypeScript. Установите его, выполнив команду npm install @agentclientprotocol/sdk.
TypeScript
import * as acp from "@agentclientprotocol/sdk";
import { spawn } from "node:child_process";
import { Readable, Writable } from "node:stream";
import * as readline from "node:readline/promises";

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");

  // Ask the user to enter a prompt instead of using a hard-coded one.
  const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
  });
  const promptText = await rl.question("Enter a prompt: ");
  rl.close();

  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;
});

Чтобы выполнить пример, выполните следующие действия:

  1. Сохраните приведенный выше код в файл с именем acp-client.ts.

  2. Запустите файл с npx tsxфайлом, с помощью которого выполняется TypeScript напрямую без отдельного шага сборки:

    npx tsx acp-client.ts
    

Использование команд косой черты

интерфейс командной строки GitHub CopilotВстроенные команды косой черты могут выполняться по ACP. Чтобы вызвать его, отправьте его как обычный запрос, текст которого является командой, переданный в виде одного блока текстового содержимого, например /context или /session info. Сервер распознает команду и запускает ее напрямую: информационные команды, такие как или /context возвращающие их выходные данные без вызова модели, а команды действий, такие как /usage``/plan или /review запуск соответствующей задачи агента. В любом случае текст команды не отправляется в модель как вопрос.

Обнаружение доступных команд

Сервер объявляет команды, поддерживаемые с помощью стандартного уведомления сеанса ACP available_commands_update . Он отправляется после создания или загрузки сеанса, а также при каждом изменении набора, например при завершении загрузки навыков. Этот объявленный список является авторитетным, всегда текущим набором команд, которые можно запускать по ACP, и клиенты обычно отображают его в меню команд.

Объявленный список содержит следующее:

  • Встроенные команды, такие как /compact, /model``/env``/mcp``/plan``/context``/usage, /research``/review``/sessionи ./rename
  • Включено, неизменяемые пользователем навыки, которые отображаются в виде /SKILL-NAME команд.

Команды, которые сам клиент регистрирует, не объявляются обратно в него.

Доступ к списку из клиента

Так как список поступает как уведомление, а не в ответ на запрос, нет метода получения по запросу. Клиент обращается к нему, обрабатывая session/update уведомление и реагируя на обновления, тип которых имеет тип available_commands_update. Каждая запись имеет значение name (без начальной косой черты), а descriptionтакже необязательный элемент input.hint , описывающий аргументы команды. Уведомление отправляется повторно всякий раз при изменении набора, поэтому следует рассматривать каждую из них как полную замену любого кэшированного списка.

sessionUpdate Следующий обработчик записывает объявленные команды, расширяя client объект из примера, показанного ранее.

TypeScript
// Track the latest advertised commands for the session.
let availableCommands: acp.AvailableCommand[] = [];

const client: acp.Client = {
  async sessionUpdate(params) {
    const update = params.update;

    if (update.sessionUpdate === "available_commands_update") {
      // This notification is a full snapshot—replace any cached list.
      availableCommands = update.availableCommands;
      for (const command of availableCommands) {
        // command.name has no leading slash; invoke it by sending "/<name>" as a prompt.
        console.log(`/${command.name}${command.description}`);
      }
      return;
    }

    // ...handle other updates, such as agent_message_chunk
  },

  // ...other client methods, such as requestPermission
};

Чтобы выполнить одну из объявленных команд, отправьте его имя в виде запроса в одном блоке текстового содержимого( например, { type: "text", text: "/context" }как описано в разделе "Использование команд косой черты".

Команды, которые нельзя использовать для ACP

Команды косой черты, зависящие от интерактивного интерфейса терминала, не обрабатываются сервером ACP. Сюда входят команды, которые открывают средство выбора, диалоговое окно или полноэкранное представление, например /diff, /resume, /theme, /settings, /login, /helpи /tasks``/undo. Как правило, если команда не отображается в available_commands_update списке, она не будет выполняться по ACP: сервер обрабатывает текст как обычный запрос и пересылает его в модель вместо выполнения.

Так как у клиентов ACP нет интерактивных средства выбора, встроенная команда, которая обычно открывает подменю, возвращает параметры в виде текста. Предоставьте подкоманда явным образом, чтобы получить прямой результат, например, или /mcp list вместо того, /session info чтобы /session``/mcp или самостоятельно.

Полный список команд косой черты см Второй пилот CLI. в разделе Справочник команды GitHub Copilot CLI.

Дополнительные материалы