Codex App Server

Codex app-server — это интерфейс, который Codex использует для работы полнофункциональных клиентов (например, расширения Codex для VS Code). Используйте его для глубокой интеграции Codex в собственный продукт, включая аутентификацию, историю диалогов, подтверждения и потоковую передачу событий агента. Реализация app-server имеет открытый исходный код и доступна в репозитории Codex на GitHub (openai/codex/codex-rs/app-server). Полный список компонентов Codex с открытым исходным кодом приведён на странице Открытый исходный код.

Подключение терминального интерфейса CLI

Режим удалённого терминального интерфейса позволяет запустить app-server на одном компьютере и подключить терминальный интерфейс Codex CLI с другого. Запустите прослушиватель WebSocket:

codex app-server --listen ws://127.0.0.1:4500

Затем подключите терминальный интерфейс:

codex --remote ws://127.0.0.1:4500

Для нелокального подключения настройте аутентификацию WebSocket и защитите подключение с помощью TLS. Сохраните bearer-токен в переменной окружения и передайте её имя, не указывая сам токен в командной строке:

export CODEX_REMOTE_TOKEN="$(cat "$HOME/.codex/app-server-token")"
codex --remote wss://remote-host:4500 \
  --remote-auth-token-env CODEX_REMOTE_TOKEN

Параметр --remote принимает конечные точки ws://, wss://, unix:// и unix://PATH. Используйте WebSocket без шифрования только для localhost или подключения с перенаправлением порта через SSH.

Подключение удалённого хоста Code Mode

По умолчанию app-server запускает локальный хост Code Mode. Чтобы использовать вместо него удалённый хост, передайте его защищённый URL-адрес WebSocket:

codex app-server --code-mode-host wss://code-mode.example.com/host

--code-mode-host управляет исходящим подключением app-server к его хосту Code Mode. Этот параметр не изменяет --listen, который определяет способ подключения клиентов к app-server. Все потоки в одном процессе app-server используют выбранное подключение к хосту Code Mode.

Для удалённого хоста используйте wss://. Используйте ws:// только для localhost или подключения с перенаправлением через SSH. Команда app-server и транспорт WebSocket являются экспериментальными и не поддерживаются для производственных нагрузок.

Протокол

Как и MCP, codex app-server поддерживает двунаправленное взаимодействие посредством сообщений JSON-RPC 2.0 (заголовок "jsonrpc":"2.0" не передаётся по сети).

Поддерживаемые транспорты:

  • stdio (--listen stdio://, по умолчанию): JSON с разделением по строкам (JSONL).
  • websocket (--listen ws://IP:PORT, экспериментальный и неподдерживаемый): одно сообщение JSON-RPC в каждом текстовом кадре WebSocket.
  • Сокет Unix (--listen unix:// или --listen unix://PATH): подключения WebSocket через стандартный управляющий сокет app-server в Codex или пользовательский путь к сокету Unix с использованием стандартного согласования HTTP Upgrade.
  • off (--listen off): не предоставлять локальный транспорт.

При запуске с --listen ws://IP:PORT тот же прослушиватель также обслуживает базовые проверки работоспособности HTTP:

  • GET /readyz возвращает 200 OK, когда прослушиватель начинает принимать новые подключения.
  • GET /healthz возвращает 200 OK, если запрос не содержит заголовок Origin.
  • Запросы с заголовком Origin отклоняются с кодом 403 Forbidden.

Транспорт WebSocket является экспериментальным и не поддерживается. Локальные прослушиватели, такие как ws://127.0.0.1:PORT, подходят для рабочих процессов с localhost и перенаправлением портов через SSH. В ходе развёртывания прослушиватели WebSocket на интерфейсах, отличных от loopback, по умолчанию допускают подключения без аутентификации, поэтому перед удалённым предоставлением доступа настройте аутентификацию WebSocket.

Поддерживаемые флаги аутентификации WebSocket:

  • --ws-auth capability-token --ws-token-file /absolute/path
  • --ws-auth capability-token --ws-token-sha256 HEX
  • --ws-auth signed-bearer-token --ws-shared-secret-file /absolute/path

Для подписанных bearer-токенов также можно задать --ws-issuer, --ws-audience и --ws-max-clock-skew-seconds. Клиенты передают учётные данные как Authorization: Bearer <token> во время согласования WebSocket, а app-server проверяет аутентификацию до выполнения JSON-RPC initialize.

Предпочитайте --ws-token-file передаче необработанных bearer-токенов в командной строке. Используйте --ws-token-sha256 только в том случае, если клиент хранит исходный токен с высокой энтропией в отдельном локальном хранилище секретов: хеш служит лишь средством проверки, а клиентам всё равно нужен исходный токен.

В режиме WebSocket app-server использует очереди ограниченного размера. Когда очередь входящих запросов заполнена, сервер отклоняет новые запросы с кодом ошибки JSON-RPC -32001 и сообщением "Server overloaded; retry later." Клиентам следует повторять запросы с экспоненциально увеличивающейся задержкой и джиттером.

Схема сообщений

Запросы содержат method, params и id.

В примерах используется GPT-6.1 Sol, доступ к которой должен быть предоставлен учётной записи, с которой вы вошли в систему, или рабочему пространству. Используйте model/list, чтобы при необходимости выбрать доступную модель.

{ "method": "thread/start", "id": 10, "params": { "model": "gpt-6.1-sol" } }

Ответы повторяют id и содержат либо result, либо error:

{ "id": 10, "result": { "thread": { "id": "thr_123" } } }
{ "id": 10, "error": { "code": 123, "message": "Something went wrong" } }

В уведомлениях отсутствует id и используются только method и params:

{ "method": "turn/started", "params": { "turn": { "id": "turn_456" } } }

С помощью CLI можно создать схему TypeScript или пакет JSON Schema. Каждый результат соответствует конкретной запущенной версии Codex, поэтому созданные артефакты в точности соответствуют этой версии:

codex app-server generate-ts --out ./schemas
codex app-server generate-json-schema --out ./schemas

Начало работы

  1. Запустите сервер с помощью codex app-server (транспорт stdio по умолчанию), codex app-server --listen ws://127.0.0.1:4500 (TCP WebSocket) или codex app-server --listen unix:// (сокет Unix по умолчанию).
  2. Подключите клиент через выбранный транспорт, затем отправьте initialize, а после него — уведомление initialized.
  3. Запустите поток и ход, после чего продолжайте считывать уведомления из активного транспортного потока.

Пример (Node.js / TypeScript):

import { spawn } from "node:child_process";

const proc = spawn("codex", ["app-server"], {
  stdio: ["pipe", "pipe", "inherit"],
});
const rl = readline.createInterface({ input: proc.stdout });
const send = (message: unknown) => {
  proc.stdin.write(`${JSON.stringify(message)}\n`);
};
let threadId: string | null = null;
rl.on("line", (line) => {
  const msg = JSON.parse(line) as any;
  console.log("server:", msg);
  if (msg.id === 1 && msg.result?.thread?.id && !threadId) {
    threadId = msg.result.thread.id;
    send({
      method: "turn/start",
      id: 2,
      params: {
        threadId,
        input: [{ type: "text", text: "Summarize this repo." }],
      },
    });
  }
});
send({
  method: "initialize",
  id: 0,
  params: {
    clientInfo: {
      name: "my_product",
      title: "My Product",
      version: "0.1.0",
    },
  },
});
send({ method: "initialized", params: {} });
send({ method: "thread/start", id: 1, params: { model: "gpt-6.1-sol" } });

Основные сущности

  • Поток: диалог между пользователем и агентом Codex. Потоки содержат ходы.
  • Ход: один запрос пользователя и последующая работа агента. Ходы содержат элементы и передают добавочные обновления.
  • Элемент: единица входных или выходных данных (сообщение пользователя, сообщение агента, выполнение команды, изменение файла, вызов инструмента и многое другое).

Используйте API потоков для создания, просмотра списка и архивирования диалогов. Управляйте диалогом через API ходов и передавайте сведения о ходе выполнения посредством уведомлений о ходе.

Обзор жизненного цикла

  • Инициализация один раз для каждого подключения: сразу после открытия транспортного подключения отправьте запрос initialize с метаданными клиента, а затем уведомление initialized. Сервер отклоняет любые запросы через это подключение до завершения согласования.
  • Запуск (или возобновление) потока: вызовите thread/start для нового диалога, thread/resume для продолжения существующего или thread/fork для ответвления истории в поток с новым идентификатором.
  • Начало хода: вызовите turn/start, указав целевой threadId и пользовательский ввод. Необязательные поля переопределяют модель, стиль общения, cwd, политику песочницы и другие параметры.
  • Корректировка активного хода: вызовите turn/steer, чтобы добавить пользовательский ввод в выполняющийся ход без создания нового хода.
  • Потоковая передача событий: после turn/start продолжайте считывать уведомления из stdout: thread/archived, thread/unarchived, item/started, item/completed, item/agentMessage/delta, сведения о ходе выполнения инструментов и другие обновления.
  • Завершение хода: когда модель завершает работу или после отмены через turn/interrupt, сервер отправляет turn/completed с итоговым статусом.

Инициализация

До вызова любого другого метода клиенты должны отправить один запрос initialize для каждого транспортного подключения, а затем подтвердить его уведомлением initialized. Запросы, отправленные до инициализации, получают ошибку Not initialized, а повторные вызовы initialize через то же подключение возвращают Already initialized.

Сервер возвращает строку user agent, которую он будет передавать вышестоящим сервисам, а также значения platformFamily и platformOs, описывающие целевую среду выполнения. Задайте clientInfo, чтобы идентифицировать интеграцию.

initialize.params.capabilities также поддерживает следующие возможности клиента:

  • optOutNotificationMethods — точные имена методов уведомлений, которые необходимо подавить для этого подключения. Сопоставление выполняется точно (без подстановочных знаков и префиксов); неизвестные имена принимаются и игнорируются.
  • requestAttestation — согласие на инициируемый сервером запрос attestation/generate. Настольные хосты, предоставляющие вышестоящую аттестацию, отвечают непрозрачным значением { "token": "..." }.
  • mcpServerOpenaiFormElicitation — разрешение нижестоящим MCP servers отправлять расширенный вариант OpenAI для mcpServer/elicitation/request.

Важно: используйте clientInfo.name, чтобы идентифицировать свой клиент для OpenAI Compliance Logs Platform. Если вы разрабатываете новую интеграцию Codex для корпоративного использования, обратитесь в OpenAI, чтобы её добавили в список известных клиентов. Дополнительные сведения см. в справочнике по журналам Codex.

Пример (из расширения Codex для VS Code):

{
  "method": "initialize",
  "id": 0,
  "params": {
    "clientInfo": {
      "name": "codex_vscode",
      "title": "Codex VS Code Extension",
      "version": "0.1.0"
    }
  }
}

Пример с отказом от уведомлений:

{
  "method": "initialize",
  "id": 1,
  "params": {
    "clientInfo": {
      "name": "my_client",
      "title": "My Client",
      "version": "0.1.0"
    },
    "capabilities": {
      "experimentalApi": true,
      "optOutNotificationMethods": ["thread/started", "item/agentMessage/delta"]
    }
  }
}

Включение экспериментального API

Некоторые методы и поля app-server намеренно доступны только при наличии возможности experimentalApi.

  • Не указывайте capabilities (или задайте для experimentalApi значение false), чтобы использовать стабильную поверхность API; в этом случае сервер отклоняет экспериментальные методы и поля.
  • Задайте для capabilities.experimentalApi значение true, чтобы включить экспериментальные методы и поля.
{
  "method": "initialize",
  "id": 1,
  "params": {
    "clientInfo": {
      "name": "my_client",
      "title": "My Client",
      "version": "0.1.0"
    },
    "capabilities": {
      "experimentalApi": true
    }
  }
}

Если клиент отправляет экспериментальный метод или поле, не включив эту возможность, app-server отклоняет его со следующей ошибкой:

<descriptor> requires experimentalApi capability

Обзор API

  • thread/start — создать новый поток; отправляет thread/started и автоматически подписывает вас на события ходов и элементов этого потока.
  • thread/resume — повторно открыть существующий поток по идентификатору, чтобы последующие вызовы turn/start добавлялись в него.
  • thread/fork — создать ответвление потока с новым идентификатором, скопировав сохранённую историю. Передайте lastTurnId, чтобы скопировать историю до этого хода включительно и исключить последующие ходы, либо ephemeral: true, чтобы создать ответвление в памяти. Отправляет thread/started для нового потока; возвращаемые потоки содержат forkedFromId, если это значение доступно.
  • thread/read - считывает сохранённые метаданные потока по идентификатору, не возобновляя его. Используйте thread/turns/list и thread/items/list для загрузки истории. Возвращаемые объекты thread включают status времени выполнения.
  • thread/list — постранично просматривать журналы сохранённых потоков; поддерживает пагинацию на основе курсора, а также modelProviders, sourceKinds, archived, isPinned, cwd, useStateDbOnly, searchTerm и экспериментальные фильтры parentThreadId или ancestorThreadId. Возвращаемые объекты thread содержат сведения о среде выполнения в status.
  • thread/turns/list - постранично просматривает историю ходов сохранённого потока, не возобновляя его. itemsView определяет, будут ли элементы ходов исключены, представлены кратко или загружены полностью.
  • thread/items/list - постранично просматривает сохранённые элементы потока с возможностью ограничить выборку одним turnId. Активное хранилище потоков должно поддерживать пагинацию элементов.
  • thread/loaded/list — вывести идентификаторы потоков, загруженных в память в данный момент.
  • thread/name/set — задать или обновить отображаемое для пользователя имя загруженного потока или сохранённого журнала выполнения; отправляет thread/name/updated.
  • thread/goal/set — задать цель потока; отправляет thread/goal/updated.
  • thread/goal/get — прочитать текущую цель потока.
  • thread/goal/clear — очистить цель потока; отправляет thread/goal/cleared.
  • thread/metadata/update — частично обновить метаданные сохранённого потока в SQLite, включая сохранённые gitInfo и isPinned.
  • thread/archive — переместить файл журнала потока в каталог архивов и попытаться архивировать журналы порождённых дочерних потоков, которые ещё не архивированы; при успехе возвращает {} и отправляет thread/archived для каждого архивированного потока.
  • thread/delete — безвозвратно удалить сохранённый активный или архивный поток и все порождённые дочерние потоки; при успехе возвращает {} и отправляет thread/deleted для каждого удалённого потока.
  • thread/unsubscribe — отменить подписку этого соединения на события ходов и элементов потока. Если это был последний подписчик, сервер выгружает поток после льготного периода бездействия без подписчиков и отправляет thread/closed.
  • thread/unarchive — восстановить архивный журнал выполнения потока в каталог активных сеансов; возвращает восстановленный thread и отправляет thread/unarchived.
  • thread/status/changed — уведомление, отправляемое при изменении status среды выполнения загруженного потока.
  • thread/compact/start — запустить сжатие истории разговора для потока; немедленно возвращает {}, а сведения о ходе выполнения передаются через уведомления turn/* и item/*.
  • thread/shellCommand — выполнить инициированную пользователем команду оболочки в контексте потока. Она выполняется вне песочницы с полным доступом и не наследует политику песочницы потока.
  • thread/backgroundTerminals/clean — остановить все работающие фоновые терминалы потока (экспериментальный метод; требуется capabilities.experimentalApi).
  • thread/backgroundTerminals/list — вывести работающие фоновые терминалы загруженного потока (экспериментальный метод; требуется capabilities.experimentalApi).
  • thread/backgroundTerminals/terminate — завершить один работающий фоновый терминал по processId app-server (экспериментальный метод; требуется capabilities.experimentalApi).
  • thread/revert - удаляет указанный ход и все последующие ходы из истории постоянного потока с пагинацией; возвращает обновлённые метаданные и курсоры истории, затем отправляет thread/reverted.
  • turn/start — добавить пользовательский ввод или отдельный вывод инструмента в поток и начать генерацию Codex; возвращает исходный turn и передаёт события в потоковом режиме. Для collaborationMode значение settings.developer_instructions: null означает «использовать встроенные инструкции для выбранного режима».
  • thread/inject_items — добавить необработанные элементы Responses API в видимую модели историю загруженного потока, не начиная пользовательский ход.
  • turn/steer — добавить пользовательский ввод в активный выполняющийся ход потока; возвращает принятый turnId.
  • turn/interrupt — запросить отмену выполняющегося хода; успешный результат — {}, после чего ход завершается с status: "interrupted".
  • review/start — запустить рецензента Codex для потока; отправляет элементы enteredReviewMode и exitedReviewMode.
  • command/exec — выполнить одну команду в серверной песочнице, не создавая поток или ход.
  • command/exec/write — записать байты stdin в работающий сеанс command/exec или закрыть stdin.
  • command/exec/resize — изменить размер работающего сеанса command/exec на базе PTY.
  • command/exec/terminate — остановить работающий сеанс command/exec.
  • command/exec/outputDelta (уведомление) — отправляется для фрагментов stdout/stderr в кодировке base64 из потокового сеанса command/exec.
  • process/spawn — запустить явно заданный сеанс процесса вне песочницы Codex (экспериментальный метод; требуется capabilities.experimentalApi).
  • process/writeStdin — записать байты стандартного ввода в работающий сеанс process/spawn или закрыть стандартный ввод (экспериментальный метод).
  • process/resizePty — изменить размер работающего сеанса процесса на базе PTY (экспериментальный метод).
  • process/kill — завершить работающий сеанс процесса (экспериментальный метод).
  • process/outputDelta и process/exited (уведомления) — отправляются для потокового вывода процесса и статуса его завершения (экспериментальный метод).
  • model/list — вывести доступные модели (задайте includeHidden: true, чтобы включить записи с hidden: true), варианты уровня рассуждений, необязательный upgrade и inputModalities.
  • modelProvider/capabilities/read — прочитать ограничения возможностей поставщика для сочетаний модели и поставщика.
  • experimentalFeature/list — вывести флаги функций с метаданными этапа жизненного цикла и пагинацией на основе курсора.
  • experimentalFeature/enablement/set — частично обновить параметры среды выполнения в памяти для поддерживаемых ключей функций, таких как apps и plugins.
  • environment/info — экспериментальный метод; подключиться к настроенной среде выполнения и вернуть её оболочку и рабочий каталог по умолчанию.
  • permissionProfile/list — вывести бета-профили разрешений и сведения о том, допускают ли их действующие требования, с пагинацией на основе курсора.
  • collaborationMode/list — вывести предустановки режима совместной работы (экспериментальный метод, без пагинации).
  • skills/list — вывести навыки для одного или нескольких значений cwd (поддерживаются forceReload и необязательный perCwdExtraUserRoots).
  • skills/extraRoots/set — заменить дополнительные корневые каталоги уровня процесса, используемые для обнаружения автономных навыков, без их сохранения.
  • skills/changed (уведомление) — отправляется при изменении отслеживаемых локальных файлов навыков.
  • hooks/list — вывести обнаруженные перехватчики жизненного цикла для одного или нескольких значений cwd.
  • marketplace/add — добавить удалённый маркетплейс плагинов и сохранить его в пользовательской конфигурации маркетплейсов.
  • marketplace/remove — удалить настроенный маркетплейс и, если он существует, корневой каталог установленного маркетплейса.
  • marketplace/upgrade — обновить настроенный Git-маркетплейс или все настроенные Git-маркетплейсы, если имя маркетплейса не указано.
  • plugin/list — находится в разработке; вывести обнаруженные маркетплейсы плагинов и состояние плагинов, включая метаданные политик установки и аутентификации, ошибки загрузки маркетплейсов, идентификаторы рекомендуемых плагинов и метаданные источников локальных, Git-, реестровых или удалённых плагинов. Сводки могут содержать удалённый version, локальный localVersion, структурированные значки для светлой и тёмной тем, а также installPolicySource, который для текущих удалённых записей может иметь значение null, WORKSPACE_SETTING или IMPLICIT_CANONICAL_APP. Пока не вызывайте этот метод из клиентов в рабочей среде.
  • plugin/read — находится в разработке; прочитать один плагин по пути в маркетплейсе либо по имени удалённого маркетплейса и имени плагина, включая входящие в комплект навыки, приложения, имена MCP servers и shareUrl удалённого плагина, если он предоставлен удалённым каталогом. Пока не вызывайте этот метод из клиентов в рабочей среде.
  • plugin/install — находится в разработке; установить плагин из маркетплейса по пути или имени удалённого маркетплейса. Пока не вызывайте этот метод из клиентов в рабочей среде.
  • plugin/uninstall — находится в разработке; удалить установленный плагин. Пока не вызывайте этот метод из клиентов в рабочей среде.
  • plugin/skill/read — по запросу прочитать Markdown удалённого навыка плагина, указав удалённый маркетплейс, идентификатор плагина и имя навыка.
  • app/installed — прочитать состояние среды выполнения установленных приложений, включая действующие состояния включения и доступности для вызова каждого приложения.
  • app/list — вывести доступные приложения (коннекторы) с пагинацией и метаданными доступности и включения.
  • app/read — получить метаданные и необязательные сводки инструментов, предназначенные только для отображения, для указанных идентификаторов приложений.
  • skills/config/write — включить или отключить навыки по пути.
  • mcpServer/oauth/login — начать вход через OAuth для настроенного MCP server; возвращает URL авторизации и по завершении отправляет mcpServer/oauthLogin/completed.
  • tool/requestUserInput — задать пользователю от одного до трёх коротких вопросов для вызова инструмента (экспериментальный метод); в вопросах можно задать isOther для варианта со свободным вводом.
  • mcpServer/elicitation/request (запрос сервера) — запросить у клиента структурированный ввод в форме или подтверждение перехода по URL, запрошенного MCP server.
  • item/permissions/requestApproval (запрос сервера) — запросить у клиента предоставление подмножества разрешений на доступ к сети или файловой системе, запрошенных встроенным инструментом request_permissions.
  • config/mcpServer/reload — повторно загрузить с диска конфигурацию MCP servers и поставить в очередь обновление загруженных потоков.
  • mcpServerStatus/list — вывести MCP servers, инструменты, ресурсы и статус аутентификации (пагинация с курсором и ограничением). Используйте detail: "full" для получения полных данных или detail: "toolsAndAuthOnly", чтобы исключить ресурсы. Передайте serverName для обнаружения одного сервера; при передаче threadId запрос повторно использует соединение MCP этого потока.
  • mcpServer/resource/read — прочитать отдельный ресурс MCP через инициализированный MCP server.
  • mcpServer/tool/call — вызвать инструмент на настроенном для потока MCP server.
  • mcpServer/startupStatus/updated (уведомление) — отправляется при изменении статуса запуска настроенного MCP server для загруженного потока.
  • windowsSandbox/setupStart — запустить настройку песочницы Windows для режима elevated или unelevated; быстро возвращает результат, а позднее отправляет windowsSandbox/setupCompleted.
  • feedback/upload — отправить отчёт с обратной связью (классификация, необязательные причина, журналы и идентификатор разговора, а также необязательные вложения extraLogFiles).
  • config/read — получить действующую конфигурацию на диске после разрешения её уровней.
  • externalAgentConfig/detect — обнаружить артефакты внешнего агента, которые можно перенести с помощью includeHome и необязательного cwds; каждый обнаруженный элемент содержит cwd (null для домашнего каталога).
  • externalAgentConfig/import — применить выбранные элементы миграции внешнего агента, передав явно заданные migrationItems с cwd (null для домашнего каталога). Поддерживаются такие типы элементов, как конфигурация, навыки, AGENTS.md, плагины, конфигурация MCP servers, субагенты, перехватчики, команды и сеансы; при непустом импорте по мере выполнения работы отправляются externalAgentConfig/import/progress и externalAgentConfig/import/completed. Импорт плагинов и сеансов может завершаться асинхронно.
  • config/value/write — записать отдельную пару «ключ — значение» конфигурации в пользовательский config.toml на диске.
  • config/batchWrite — атомарно применить изменения конфигурации к пользовательскому config.toml на диске.
  • configRequirements/read — получить требования из requirements.toml и/или MDM, включая точную управляемую конфигурацию, списки разрешений, закреплённые featureRequirements и требования к сети (либо null, если они не настроены).
  • fs/readFile, fs/writeFile, fs/createDirectory, fs/getMetadata, fs/readDirectory, fs/remove, fs/copy, fs/watch, fs/unwatch и fs/changed (уведомление) — выполняют операции с абсолютными путями файловой системы через API файловой системы app-server v2.

Сводки плагинов содержат объединение source. Локальные плагины возвращают { "type": "local", "path": ... }, записи магазинов на базе Git — { "type": "git", "url": ..., "path": ..., "refName": ..., "sha": ... }, записи реестра пакетов — { "type": "npm", "package": ..., "version": ..., "registry": ... }, а записи удалённого каталога — { "type": "remote" }. Для записей, существующих только в удалённом каталоге, PluginMarketplaceEntry.path может иметь значение null; при чтении или установке таких плагинов передавайте remoteMarketplaceName вместо marketplacePath.

Модели

Получение списка моделей (model/list)

Перед отображением элементов выбора модели или стиля общения вызовите model/list, чтобы узнать о доступных моделях и их возможностях.

В приведённом ниже ответе показана структура. Доступные модели, уровни глубины рассуждений и значения по умолчанию зависят от клиента и учётной записи; используйте возвращённые значения, а не задавайте значения из этого примера жёстко в коде.

{ "method": "model/list", "id": 6, "params": { "limit": 20, "includeHidden": false } }
{ "id": 6, "result": {
  "data": [{
    "id": "gpt-6.1-sol",
    "model": "gpt-6.1-sol",
    "displayName": "GPT-6.1 Sol",
    "hidden": false,
    "defaultReasoningEffort": "medium",
    "supportedReasoningEfforts": [{
      "reasoningEffort": "medium",
      "description": "Balances speed and reasoning depth for everyday tasks"
    }],
    "inputModalities": ["text", "image"],
    "supportsPersonality": false,
    "isDefault": true
  }],
  "nextCursor": null
} }

Каждая запись модели может содержать:

  • supportedReasoningEfforts — поддерживаемые моделью варианты уровня рассуждений.
  • defaultReasoningEffort — рекомендуемый клиентам уровень рассуждений по умолчанию.
  • upgrade — необязательный идентификатор модели, рекомендуемой для обновления в клиентских запросах на миграцию.
  • upgradeInfo — необязательные метаданные обновления для клиентских запросов на миграцию.
  • hidden — признак того, скрыта ли модель из стандартного списка выбора.
  • inputModalities — поддерживаемые моделью типы входных данных (например, text, image).
  • supportsPersonality - устаревшее поле совместимости; всегда false. Модели больше не поддерживают выбор стиля общения.
  • isDefault — признак того, является ли модель рекомендуемой по умолчанию.

По умолчанию model/list возвращает только модели, отображаемые в элементе выбора. Задайте includeHidden: true, если вам нужен полный список и вы хотите фильтровать его на стороне клиента с помощью hidden.

Если inputModalities отсутствует (в старых каталогах моделей), для обратной совместимости считайте его равным ["text", "image"].

Получение списка экспериментальных функций (experimentalFeature/list)

Используйте эту конечную точку, чтобы получить флаги функций с метаданными и этапами жизненного цикла:

{ "method": "experimentalFeature/list", "id": 7, "params": { "limit": 20 } }
{ "id": 7, "result": {
  "data": [{
    "name": "unified_exec",
    "stage": "beta",
    "displayName": "Unified exec",
    "description": "Use the unified PTY-backed execution tool.",
    "announcement": "Beta rollout for improved command execution reliability.",
    "enabled": false,
    "defaultEnabled": false
  }],
  "nextCursor": null
} }

stage может принимать значения beta, underDevelopment, stable, deprecated или removed. Для флагов, не находящихся на этапе бета-тестирования, displayName, description и announcement могут иметь значение null.

Проверка среды выполнения (экспериментальная возможность)

Используйте environment/info, чтобы проверить настроенную удалённую среду перед началом работы в ней. Для этого метода требуется capabilities.experimentalApi = true.

{ "method": "environment/info", "id": 8, "params": { "environmentId": "devbox" } }
{ "id": 8, "result": {
  "shell": { "name": "zsh", "path": "/bin/zsh" },
  "cwd": "file:///workspace/project"
} }

cwd может иметь значение null. Если оно присутствует, это канонический URI file:, использующий собственный синтаксис путей среды. Неизвестные идентификаторы сред, а также ошибки подключения или протокола возвращаются как ошибки запроса.

Потоки

  • thread/read считывает сохранённые метаданные потока, не подписываясь на него.
  • thread/turns/list постранично просматривает историю ходов сохранённого потока, не возобновляя его. Используйте itemsView, чтобы выбрать, будут ли элементы ходов исключены, представлены кратко или загружены полностью.
  • thread/items/list постранично просматривает сохранённые элементы потока с возможностью ограничить выборку одним ходом.
  • thread/list поддерживает пагинацию на основе курсора, а также modelProviders, sourceKinds, archived, isPinned, cwd, useStateDbOnly, searchTerm и экспериментальную фильтрацию по parentThreadId или ancestorThreadId.
  • thread/loaded/list возвращает идентификаторы потоков, находящихся в памяти.
  • thread/archive перемещает сохранённый журнал JSONL потока в каталог архивов и пытается архивировать журналы созданных дочерних потоков, если они ещё не архивированы.
  • thread/delete безвозвратно удаляет сохранённый активный или архивный поток и созданные им дочерние потоки.
  • thread/metadata/update изменяет метаданные сохранённого потока, включая сохранённые gitInfo и isPinned.
  • thread/unsubscribe отменяет подписку текущего подключения на загруженный поток и может вызвать thread/closed по истечении льготного периода бездействия.
  • thread/unarchive восстанавливает архивный журнал выполнения потока в каталоге активных сеансов.
  • thread/compact/start запускает уплотнение и немедленно возвращает {}.
  • thread/revert удаляет указанный ход и все последующие ходы из истории постоянного потока с пагинацией. Локальные файлы при этом не изменяются.
  • thread/inject_items добавляет необработанные элементы Responses API в видимую модели историю загруженного потока, не начиная пользовательский ход.

Запуск или возобновление потока

Создайте новый поток, когда требуется новый диалог с Codex.

{ "method": "thread/start", "id": 10, "params": {
  "model": "gpt-6.1-sol",
  "cwd": "/Users/me/project",
  "approvalPolicy": "never",
  "sandbox": "workspaceWrite",
  "serviceName": "my_app_server_client"
} }
{ "id": 10, "result": {
  "thread": {
    "id": "thr_123",
    "sessionId": "thr_123",
    "preview": "",
    "ephemeral": false,
    "modelProvider": "openai",
    "createdAt": 1730910000
  }
} }
{ "method": "thread/started", "params": { "thread": { "id": "thr_123" } } }

serviceName является необязательным. Задайте его, если хотите, чтобы app-server помечал метрики уровня потока именем сервиса вашей интеграции.

thread/start, thread/resume и thread/fork возвращают instructionSources — массив путей к загруженным файлам инструкций. Каждый путь использует собственный абсолютный синтаксис исходной среды, в том числе для удалённых сред.

Новые постоянные локальные потоки по умолчанию используют историю с пагинацией. Загружайте историю с помощью thread/turns/list и thread/items/list. Явное задание для historyMode значения "legacy" или "paginated" в thread/start является экспериментальной функцией и требует capabilities.experimentalApi = true.

Бета-клиенты, включившие capabilities.experimentalApi, могут передавать именованный идентификатор профиля разрешений в permissions вместо устаревшего поля sandbox. Не отправляйте permissions и sandbox одновременно. Используйте permissionProfile/list с проектом cwd, чтобы узнать о доступных профилях и о том, разрешён ли каждый из них управляемыми требованиями.

thread.sessionId идентифицирует корень текущего дерева активных сеансов. Корневые потоки используют собственный идентификатор потока как идентификатор сеанса; ответвлённые потоки сохраняют идентификатор сеанса корневого потока, от которого они произошли. Клиентам следует считывать идентификатор сеанса из thread.sessionId, а не выводить его из идентификатора потока.

Чтобы продолжить сохранённый сеанс, вызовите thread/resume с ранее записанным thread.id. Передайте excludeTurns: true, чтобы получить метаданные потока и текущее состояние сеанса, затем загрузите историю с помощью методов пагинации:

{ "method": "thread/resume", "id": 11, "params": {
  "threadId": "thr_123",
  "excludeTurns": true
} }
{ "id": 11, "result": { "thread": { "id": "thr_123", "name": "Bug bash notes", "ephemeral": false } } }

Для потоков с пагинацией ответы с полной историей от thread/resume и thread/fork устарели и вызывают отправку deprecationNotice. Оба метода принимают excludeTurns: true без включения экспериментального API. Ответ thread/resume также может возвращать turnsBackwardsCursor и itemsBackwardsCursor. Передавайте каждый из них соответствующему методу пагинации с sortDirection: "desc"; первая страница включает опорный элемент курсора.

Само по себе возобновление потока не обновляет thread.updatedAt (или время изменения файла журнала выполнения). Временная метка обновляется при запуске хода.

Если в конфигурации включённый MCP server помечен как required и его не удаётся инициализировать, thread/start и thread/resume завершаются ошибкой, а не продолжают работу без него.

dynamicTools в thread/start — экспериментальное поле (требуется capabilities.experimentalApi = true). Codex сохраняет эти динамические инструменты в метаданных журнала выполнения потока и восстанавливает их при thread/resume, если новые динамические инструменты не указаны.

Если возобновить поток с моделью, отличной от записанной в журнале выполнения, Codex отправляет предупреждение и применяет одноразовую инструкцию о переключении модели при следующем ходе.

Управление целью потока

Используйте thread/goal/set, thread/goal/get и thread/goal/clear для управления тем же сохранённым состоянием цели, которое отображается через /goal в TUI.

{ "method": "thread/goal/set", "id": 13, "params": {
  "threadId": "thr_123",
  "objective": "Finish the migration and keep tests green",
  "status": "active",
  "tokenBudget": 40000
} }
{ "id": 13, "result": { "goal": {
  "threadId": "thr_123",
  "objective": "Finish the migration and keep tests green",
  "status": "active",
  "tokenBudget": 40000,
  "tokensUsed": 0,
  "timeUsedSeconds": 0
} } }
{ "method": "thread/goal/updated", "params": {
  "threadId": "thr_123",
  "goal": {
    "threadId": "thr_123",
    "objective": "Finish the migration and keep tests green",
    "status": "active",
    "tokenBudget": 40000,
    "tokensUsed": 0,
    "timeUsedSeconds": 0
  }
} }

Формулировка цели не должна быть пустой и может содержать не более 4 000 символов. При указании новой формулировки цель заменяется, а учёт использования сбрасывается. Указание текущей незавершённой формулировки или отсутствие objective обновляет статус или бюджет токенов, сохраняя историю использования.

Чтобы создать ответвление сохранённого сеанса, вызовите thread/fork с thread.id. Будет создан новый идентификатор потока и отправлено уведомление thread/started. Передайте lastTurnId, чтобы скопировать историю до указанного хода включительно и исключить последующие ходы:

{ "method": "thread/fork", "id": 12, "params": { "threadId": "thr_123", "lastTurnId": "turn_456", "excludeTurns": true } }
{ "id": 12, "result": { "thread": { "id": "thr_456", "sessionId": "thr_123", "forkedFromId": "thr_123" } } }
{ "method": "thread/started", "params": { "thread": { "id": "thr_456" } } }

App-server отклоняет выполняющийся lastTurnId. Если не указывать это поле, пока исходный поток находится в середине хода, ответвление записывает маркер прерывания, а не сохраняет непомеченный частичный ход.

Передайте ephemeral: true, чтобы создать ответвление в памяти, не добавляя его в списки сохранённых потоков:

{
  "method": "thread/fork",
  "id": 13,
  "params": {
    "threadId": "thr_123",
    "ephemeral": true,
    "excludeTurns": true
  }
}
{
  "id": 13,
  "result": {
    "thread": {
      "id": "thr_789",
      "sessionId": "thr_789",
      "forkedFromId": "thr_123",
      "ephemeral": true
    }
  }
}

Для временных ответвлений потоков с пагинацией требуется excludeTurns: true.

Если для потока задано название, отображаемое пользователю, app-server заполняет thread.name в ответах thread/list, thread/read, thread/resume и thread/unarchive. Ответы thread/start и thread/fork могут не содержать name (или возвращать null), пока название не будет задано позднее.

Чтение сохранённого потока (без возобновления)

Используйте thread/read, когда нужны данные сохранённого потока, но не требуется возобновлять поток или подписываться на его события.

  • includeTurns - если задано значение false или параметр отсутствует, возвращается только сводка потока. Значение true приводит к загрузке полной истории; для потоков с пагинацией этот способ устарел и вызывает отправку deprecationNotice. Вместо него используйте методы пагинации.
  • Возвращаемые объекты thread содержат сведения среды выполнения status (notLoaded, idle, systemError или active с activeFlags).
{ "method": "thread/read", "id": 19, "params": { "threadId": "thr_123" } }
{ "id": 19, "result": { "thread": { "id": "thr_123", "name": "Bug bash notes", "ephemeral": false, "status": { "type": "notLoaded" }, "turns": [] } } }

В отличие от thread/resume, thread/read не загружает поток в память и не отправляет thread/started.

Получение списка ходов потока

Используйте thread/turns/list для постраничного чтения истории ходов сохранённого потока без его возобновления. По умолчанию результаты возвращаются от новых к старым, чтобы клиенты могли получать более ранние ходы с помощью nextCursor. Ответ также содержит backwardsCursor; передайте его как cursor с противоположным значением sortDirection, чтобы изменить направление. При этом опорный ход включается повторно, чтобы вы могли получить его обновления.

itemsView определяет объём данных элементов хода в ответе:

  • notLoaded исключает элементы.
  • summary возвращает сводные данные элементов и используется по умолчанию, если поле отсутствует.
  • full возвращает полные данные элементов.
{ "method": "thread/turns/list", "id": 20, "params": {
  "threadId": "thr_123",
  "limit": 50,
  "sortDirection": "desc",
  "itemsView": "summary"
} }
{ "id": 20, "result": {
  "data": [],
  "nextCursor": "older-turns-cursor-or-null",
  "backwardsCursor": "newer-turns-cursor-or-null"
} }

Получение списка элементов потока

thread/items/list возвращает сохранённые элементы постранично без возобновления потока. Передайте turnId, чтобы ограничить результаты одним ходом, или опустите его, чтобы получать элементы всего потока постранично. По умолчанию результаты упорядочены от старых к новым (sortDirection: "asc"). Активное хранилище потоков должно поддерживать пагинацию элементов; иначе сервер вернёт ошибку неподдерживаемого метода.

Для продолжения пагинации передайте непрозрачный курсор nextCursor из предыдущего ответа. Чтобы начать после известного элемента, передайте опорный элемент и непустой turnId:

{ "method": "thread/items/list", "id": 21, "params": {
  "threadId": "thr_123",
  "turnId": "turn_456",
  "cursor": { "type": "item", "itemId": "item_123" },
  "sortDirection": "asc",
  "limit": 50
} }
{ "id": 21, "result": {
  "data": [],
  "nextCursor": null,
  "backwardsCursor": null
} }

При использовании опорного элемента сам он исключается: при сортировке по возрастанию возвращаются более новые элементы, а по убыванию — более старые. Элемент должен принадлежать видимой истории запрошенного хода. Отсутствие turnId, пустой ID элемента или неизвестный элемент либо элемент вне области запроса приводят к ошибке недопустимых параметров (-32602). Продолжайте с помощью возвращённой строки nextCursor. Каждая запись результата содержит turnId, item, а также необязательные сохранённые отметки времени начала и завершения.

Получение списка потоков (с пагинацией и фильтрами)

thread/list позволяет отображать интерфейс истории. По умолчанию результаты упорядочены от новых к старым по createdAt. Фильтры применяются до пагинации. Передайте любое сочетание следующих параметров:

  • cursor — непрозрачная строка из предыдущего ответа; не указывайте для первой страницы.
  • limit — если значение не задано, сервер использует подходящий размер страницы по умолчанию.
  • sortKey — created_at (по умолчанию), updated_at или recency_at.
  • sortDirection — desc (по умолчанию) или asc.
  • modelProviders — ограничивает результаты указанными поставщиками; отсутствие значения, null или пустой массив включает всех поставщиков.
  • sourceKinds — ограничивает результаты указанными источниками потоков. Если параметр отсутствует или равен [], сервер по умолчанию включает только интерактивные источники: cli и vscode.
  • archived — при значении true возвращает только архивные потоки. При значении false или отсутствии параметра возвращает неархивные потоки (по умолчанию).
  • isPinned — если параметр указан, возвращает только потоки с соответствующим сохранённым состоянием закрепления. Не указывайте его, чтобы возвращать как закреплённые, так и незакреплённые потоки.
  • cwd — ограничивает результаты потоками, текущий рабочий каталог сеанса которых в точности соответствует этому пути или одному из путей в массиве. Относительные пути разрешаются относительно рабочего каталога процесса app-server.
  • useStateDbOnly — при значении true возвращает результаты из базы данных состояний без сканирования журналов потоков JSONL для исправления метаданных. Не указывайте параметр или передайте false, чтобы использовать стандартное сканирование и исправление.
  • searchTerm — ограничивает результаты потоками, извлечённый заголовок которых содержит этот текстовый фрагмент с учётом регистра.
  • parentThreadId — ограничивает результаты непосредственными дочерними потоками указанного родительского потока. Это экспериментальный фильтр, для которого требуется capabilities.experimentalApi = true.
  • ancestorThreadId — ограничивает результаты созданными потомками указанного потока на любой глубине. Это экспериментальный фильтр, для которого требуется capabilities.experimentalApi = true; не сочетайте его с parentThreadId.

sourceKinds принимает следующие значения:

  • cli
  • vscode
  • exec
  • appServer
  • subAgent
  • subAgentReview
  • subAgentCompact
  • subAgentThreadSpawn
  • subAgentOther
  • unknown

Пример:

{ "method": "thread/list", "id": 20, "params": {
  "cursor": null,
  "limit": 25,
  "sortKey": "created_at"
} }
{ "id": 20, "result": {
  "data": [
    { "id": "thr_a", "preview": "Create a TUI", "ephemeral": false, "isPinned": true, "modelProvider": "openai", "createdAt": 1730831111, "updatedAt": 1730831111, "name": "TUI prototype", "status": { "type": "notLoaded" } },
    { "id": "thr_b", "preview": "Fix tests", "ephemeral": false, "isPinned": false, "modelProvider": "openai", "createdAt": 1730750000, "updatedAt": 1730750000, "status": { "type": "notLoaded" } }
  ],
  "nextCursor": "opaque-token-or-null"
} }

Если nextCursor имеет значение null, достигнута последняя страница.

Обновление метаданных сохранённого потока

Используйте thread/metadata/update, чтобы изменить метаданные сохранённого потока, не возобновляя его. Задайте isPinned, чтобы закрепить или открепить поток, либо обновите gitInfo, чтобы изменить сохранённые метаданные Git. Пропущенные поля остаются без изменений; явное значение null удаляет сохранённое значение метаданных Git.

{ "method": "thread/metadata/update", "id": 21, "params": {
  "threadId": "thr_123",
  "isPinned": true,
  "gitInfo": { "branch": "feature/sidebar-pr" }
} }
{ "id": 21, "result": {
  "thread": {
    "id": "thr_123",
    "isPinned": true,
    "gitInfo": { "sha": null, "branch": "feature/sidebar-pr", "originUrl": null }
  }
} }

Отслеживание изменений статуса потока

thread/status/changed отправляется при каждом изменении состояния среды выполнения загруженного потока. Полезная нагрузка содержит threadId и новое значение status.

{
  "method": "thread/status/changed",
  "params": {
    "threadId": "thr_123",
    "status": { "type": "active", "activeFlags": ["waitingOnApproval"] }
  }
}

Получение списка загруженных потоков

thread/loaded/list возвращает идентификаторы потоков, загруженных в память.

{ "method": "thread/loaded/list", "id": 21 }
{ "id": 21, "result": { "data": ["thr_123", "thr_456"] } }

Отмена подписки на загруженный поток

thread/unsubscribe удаляет подписку текущего подключения на поток. Ответ содержит один из следующих статусов:

  • unsubscribed, если подключение было подписано и теперь подписка удалена.
  • notSubscribed, если подключение не было подписано на этот поток.
  • notLoaded, если поток не загружен.

Если это был последний подписчик, сервер сохраняет поток загруженным, пока у него не останется подписчиков и активности в течение 30 минут. По истечении льготного периода app-server выгружает поток и отправляет переход thread/status/changed в notLoaded, а также thread/closed.

{ "method": "thread/unsubscribe", "id": 22, "params": { "threadId": "thr_123" } }
{ "id": 22, "result": { "status": "unsubscribed" } }

Если срок действия потока позднее истечёт:

{ "method": "thread/status/changed", "params": {
    "threadId": "thr_123",
    "status": { "type": "notLoaded" }
} }
{ "method": "thread/closed", "params": { "threadId": "thr_123" } }

Архивирование потока

Используйте thread/archive, чтобы переместить сохранённый журнал потока (хранящийся на диске в виде файла JSONL) в каталог архивных сеансов. При архивировании потока также предпринимается попытка архивировать созданные им дочерние потоки, если они ещё не архивированы.

{ "method": "thread/archive", "id": 22, "params": { "threadId": "thr_b" } }
{ "id": 22, "result": {} }
{ "method": "thread/archived", "params": { "threadId": "thr_b" } }
{ "method": "thread/archived", "params": { "threadId": "thr_child" } }

Архивные потоки не будут отображаться при последующих вызовах thread/list, если не передать archived: true. Сервер отправляет по одному уведомлению thread/archived для каждого фактически архивированного потока; если созданный дочерний поток не удаётся архивировать, запрос всё равно может завершиться успешно, но уведомление об архивировании этого дочернего потока отправлено не будет.

Удаление потока

Используйте thread/delete, чтобы безвозвратно удалить сохранённый активный или архивный поток и порождённые им дочерние потоки. Перед возвратом успешного результата сервер удаляет существующие файлы журналов выполнения и связанные метаданные; отсутствующие файлы журналов выполнения считаются уже удалёнными. Временные корневые потоки удалить нельзя.

{ "method": "thread/delete", "id": 23, "params": { "threadId": "thr_b" } }
{ "id": 23, "result": {} }
{ "method": "thread/deleted", "params": { "threadId": "thr_b" } }
{ "method": "thread/deleted", "params": { "threadId": "thr_child" } }

Разархивирование потока

Используйте thread/unarchive, чтобы переместить журнал выполнения архивного потока обратно в каталог активных сеансов.

{ "method": "thread/unarchive", "id": 24, "params": { "threadId": "thr_b" } }
{ "id": 24, "result": { "thread": { "id": "thr_b", "name": "Bug bash notes" } } }
{ "method": "thread/unarchived", "params": { "threadId": "thr_b" } }

Запуск сжатия потока

Используйте thread/compact/start, чтобы вручную запустить сжатие истории потока. Запрос немедленно возвращает {}.

App-server передаёт сведения о ходе выполнения в виде стандартных уведомлений turn/* и item/* через тот же threadId, включая жизненный цикл элемента contextCompaction (сначала item/started, затем item/completed).

{ "method": "thread/compact/start", "id": 25, "params": { "threadId": "thr_b" } }
{ "id": 25, "result": {} }

Выполнение команды оболочки в потоке

Используйте thread/shellCommand для инициированных пользователем команд оболочки, относящихся к потоку. Запрос немедленно возвращает {}, а сведения о ходе выполнения передаются через стандартные уведомления turn/* и item/*.

Этот API работает вне песочницы с полным доступом и не наследует политику песочницы потока. Клиенты должны предоставлять его только для команд, явно инициированных пользователем.

Если в потоке уже есть активный ход, команда выполняется как вспомогательное действие в рамках этого хода, а её форматированный вывод добавляется в поток сообщений хода. Если поток бездействует, app-server запускает для команды оболочки отдельный ход.

Задайте timeoutMs, чтобы ограничить время выполнения в миллисекундах. Если параметр не указан или передано null, используется значение по умолчанию — один час. 0 запрашивает немедленное истечение времени ожидания; отрицательные значения отклоняются. Время ожидания не задерживает немедленное подтверждение RPC.

{ "method": "thread/shellCommand", "id": 26, "params": { "threadId": "thr_b", "command": "git status --short", "timeoutMs": 10000 } }
{ "id": 26, "result": {} }

Очистка фоновых терминалов

Используйте thread/backgroundTerminals/clean, чтобы остановить все работающие фоновые терминалы, связанные с потоком. Этот метод является экспериментальным и требует capabilities.experimentalApi = true.

{ "method": "thread/backgroundTerminals/clean", "id": 27, "params": { "threadId": "thr_b" } }
{ "id": 27, "result": {} }

Используйте thread/backgroundTerminals/list, чтобы просмотреть работающие фоновые терминалы загруженного потока. Запрос поддерживает стандартную пагинацию cursor и limit, а возвращаемый processId является идентификатором процесса app-server. Этот метод является экспериментальным и требует capabilities.experimentalApi = true:

{ "method": "thread/backgroundTerminals/list", "id": 28, "params": { "threadId": "thr_b" } }
{ "id": 28, "result": { "data": [
  {
    "itemId": "item_456",
    "processId": "42",
    "command": "python3 -m http.server",
    "cwd": "/workspace",
    "osPid": null,
    "cpuPercent": null,
    "rssKb": null
  }
], "nextCursor": null } }

Используйте thread/backgroundTerminals/terminate с этим processId, чтобы остановить один фоновый терминал. Этот метод является экспериментальным и требует capabilities.experimentalApi = true:

{ "method": "thread/backgroundTerminals/terminate", "id": 29, "params": { "threadId": "thr_b", "processId": "42" } }
{ "id": 29, "result": { "terminated": true } }

Откат истории потока

Используйте thread/revert, чтобы удалить ход beforeTurnId и все последующие ходы из истории диалога постоянного потока с пагинацией. Это не отменяет локальные изменения файлов. Если поток не загружен, сначала возобновите его. Временные потоки и потоки с историей в устаревшем формате не поддерживаются.

{ "method": "thread/revert", "id": 30, "params": { "threadId": "thr_b", "beforeTurnId": "turn_456" } }
{ "id": 30, "result": {
  "thread": { "id": "thr_b", "ephemeral": false, "turns": [] },
  "turnsBackwardsCursor": "retained-turn-cursor-or-null",
  "itemsBackwardsCursor": "retained-item-cursor-or-null"
} }
{ "method": "thread/reverted", "params": { "threadId": "thr_b" } }

Возвращаемое поле thread.turns всегда пусто. Используйте возвращённые курсоры с thread/turns/list или thread/items/list и sortDirection: "desc", чтобы загрузить сохранённую часть истории, включая опорный элемент курсора.

thread/rollback удалён и возвращает ошибку неизвестного метода. Существующие маркеры отката в ранее сохранённых потоках по-прежнему доступны для чтения.

Ходы

Поле input принимает список элементов:

  • { "type": "text", "text": "Explain this diff" }
  • { "type": "image", "url": "https://.../design.png" }
  • { "type": "localImage", "path": "/tmp/screenshot.png" }

Вы можете переопределять настройки для каждого хода (модель, уровень усилий, cwd, политику песочницы, сводку). Если эти настройки указаны, они становятся значениями по умолчанию для последующих ходов в том же потоке. outputSchema применяется только к текущему ходу. Для sandboxPolicy.type = "externalSandbox" задайте для networkAccess значение restricted или enabled; для workspaceWrite параметр networkAccess остаётся логическим.

Для turn/start.collaborationMode значение settings.developer_instructions: null означает «использовать встроенные инструкции для выбранного режима», а не очистить инструкции режима.

Доступ на чтение в песочнице (ReadOnlyAccess)

sandboxPolicy поддерживает явное управление доступом на чтение:

  • readOnly: необязательный access (по умолчанию { "type": "fullAccess" } либо ограниченный набор корневых каталогов).
  • workspaceWrite: необязательный readOnlyAccess (по умолчанию { "type": "fullAccess" } либо ограниченный набор корневых каталогов).

Структура ограниченного доступа на чтение:

{
  "type": "restricted",
  "includePlatformDefaults": true,
  "readableRoots": ["/Users/me/shared-read-only"]
}

В macOS includePlatformDefaults: true добавляет подготовленную стандартную для платформы политику Seatbelt для сеансов с ограниченным чтением. Это улучшает совместимость инструментов, не предоставляя широкий доступ ко всему /System.

Примеры:

{ "type": "readOnly", "access": { "type": "fullAccess" } }
{
  "type": "workspaceWrite",
  "writableRoots": ["/Users/me/project"],
  "readOnlyAccess": {
    "type": "restricted",
    "includePlatformDefaults": true,
    "readableRoots": ["/Users/me/shared-read-only"]
  },
  "networkAccess": false
}

Запуск хода

{ "method": "turn/start", "id": 30, "params": {
  "threadId": "thr_123",
  "input": [ { "type": "text", "text": "Run tests" } ],
  "cwd": "/Users/me/project",
  "approvalPolicy": "unlessTrusted",
  "sandboxPolicy": {
    "type": "workspaceWrite",
    "writableRoots": ["/Users/me/project"],
    "networkAccess": true
  },
  "model": "gpt-6.1-sol",
  "effort": "medium",
  "summary": "concise",
  "personality": "friendly",
  "outputSchema": {
    "type": "object",
    "properties": { "answer": { "type": "string" } },
    "required": ["answer"],
    "additionalProperties": false
  }
} }
{ "id": 30, "result": { "turn": { "id": "turn_456", "status": "inProgress", "items": [], "error": null } } }

Чтобы начать ход с выводом инструмента, запущенного вашим клиентом, передайте toolOutput с непустым name, необязательным namespace и строкой output либо массивом элементов содержимого. Задайте для input пустой массив; нельзя сочетать toolOutput с непустым пользовательским вводом.

{
  "method": "turn/start",
  "id": 31,
  "params": {
    "threadId": "thr_123",
    "input": [],
    "toolOutput": {
      "name": "run_tests",
      "namespace": null,
      "output": "All 42 tests passed."
    }
  }
}

Вывод остаётся выводом инструмента в разговоре и отображается как элемент functionCallOutput в уведомлениях и сохранённой истории. Если обычный ход уже активен, Codex ставит вывод в очередь для этого хода.

Добавление элементов в поток

Используйте thread/inject_items, чтобы добавить готовые элементы Responses API в историю запросов загруженного потока без запуска пользовательского хода. Эти элементы сохраняются в журнале выполнения и включаются в последующие запросы к модели.

{ "method": "thread/inject_items", "id": 31, "params": {
  "threadId": "thr_123",
  "items": [
    {
      "type": "message",
      "role": "assistant",
      "content": [{ "type": "output_text", "text": "Previously computed context." }]
    }
  ]
} }
{ "id": 31, "result": {} }

Корректировка активного хода

Используйте turn/steer, чтобы добавить новые пользовательские входные данные в активный выполняющийся ход.

  • Включите expectedTurnId; значение должно совпадать с идентификатором активного хода.
  • Запрос завершается ошибкой, если в потоке нет активного хода.
  • turn/steer не отправляет новое уведомление turn/started.
  • turn/steer не принимает переопределения уровня хода (model, cwd, sandboxPolicy или outputSchema).
{ "method": "turn/steer", "id": 32, "params": {
  "threadId": "thr_123",
  "input": [ { "type": "text", "text": "Actually focus on failing tests first." } ],
  "expectedTurnId": "turn_456"
} }
{ "id": 32, "result": { "turnId": "turn_456" } }

Запуск хода (вызов навыка)

Явно вызовите навык, включив $<skill-name> в текстовые входные данные и добавив рядом элемент входных данных skill.

{ "method": "turn/start", "id": 33, "params": {
  "threadId": "thr_123",
  "input": [
    { "type": "text", "text": "$skill-creator Add a new skill for triaging flaky CI and include step-by-step usage." },
    { "type": "skill", "name": "skill-creator", "path": "/Users/me/.codex/skills/skill-creator/SKILL.md" }
  ]
} }
{ "id": 33, "result": { "turn": { "id": "turn_457", "status": "inProgress", "items": [], "error": null } } }

Прерывание хода

{ "method": "turn/interrupt", "id": 31, "params": { "threadId": "thr_123", "turnId": "turn_456" } }
{ "id": 31, "result": {} }

При успешном выполнении ход завершается со значением status: "interrupted".

Проверка

review/start запускает средство проверки Codex для потока и передаёт элементы проверки в потоковом режиме. Доступны следующие цели:

  • uncommittedChanges
  • baseBranch (различия относительно ветки)
  • commit (проверка определённого коммита)
  • custom (инструкции в свободной форме)

Используйте delivery: "inline" (значение по умолчанию), чтобы выполнить проверку в существующем потоке. Для проверки в отдельном потоке вызовите thread/start, а затем запустите проверку непосредственно в новом потоке.

Пример запроса и ответа:

{ "method": "review/start", "id": 40, "params": {
  "threadId": "thr_123",
  "delivery": "inline",
  "target": { "type": "commit", "sha": "1234567deadbeef", "title": "Polish tui colors" }
} }
{ "id": 40, "result": {
  "turn": {
    "id": "turn_900",
    "status": "inProgress",
    "items": [
      { "type": "userMessage", "id": "turn_900", "content": [ { "type": "text", "text": "Review commit 1234567: Polish tui colors" } ] }
    ],
    "error": null
  },
  "reviewThreadId": "thr_123"
} }

delivery: "detached" устарел, вызывает отправку deprecationNotice и не поддерживается для родительских потоков с пагинацией. Если отдельной проверке нужна существующая история диалога, используйте thread/fork, а затем turn/start с инструкциями по проверке.

Codex передаёт обычное уведомление turn/started, а затем item/started с элементом enteredReviewMode:

{
  "method": "item/started",
  "params": {
    "item": {
      "type": "enteredReviewMode",
      "id": "turn_900",
      "review": "current changes"
    }
  }
}

Когда средство проверки завершает работу, сервер отправляет item/started и item/completed, содержащий элемент exitedReviewMode с итоговым текстом проверки:

{
  "method": "item/completed",
  "params": {
    "item": {
      "type": "exitedReviewMode",
      "id": "turn_900",
      "review": "Looks solid overall..."
    }
  }
}

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

Выполнение процессов

process/* — экспериментальный API для явного управления процессами. Он требует capabilities.experimentalApi = true и работает вне песочницы Codex. Используйте его, только если ваш клиент намеренно предоставляет управление локальными процессами без песочницы.

Запустите процесс с помощью process/spawn и укажите processHandle, а затем используйте этот дескриптор в запросах передачи данных в stdin, изменения размера и завершения. Вывод передаётся через уведомления process/outputDelta, а сведения о завершении — через process/exited.

{ "method": "process/spawn", "id": 48, "params": {
  "command": ["python3", "-m", "pytest", "-q"],
  "processHandle": "pytest-1",
  "cwd": "/Users/me/project",
  "tty": true
} }
{ "id": 48, "result": {} }
{ "method": "process/outputDelta", "params": {
  "processHandle": "pytest-1",
  "stream": "stdout",
  "deltaBase64": "Li4u"
} }
{ "method": "process/exited", "params": {
  "processHandle": "pytest-1",
  "exitCode": 0
} }

Используйте process/writeStdin с deltaBase64, closeStdin или обоими параметрами, чтобы отправить входные данные. Используйте process/resizePty для событий изменения размера PTY и process/kill, чтобы завершить работающий процесс.

Выполнение команд

command/exec выполняет одну команду (массив argv) в песочнице сервера, не создавая поток.

{ "method": "command/exec", "id": 50, "params": {
  "command": ["ls", "-la"],
  "cwd": "/Users/me/project",
  "sandboxPolicy": { "type": "workspaceWrite" },
  "timeoutMs": 10000
} }
{ "id": 50, "result": { "exitCode": 0, "stdout": "...", "stderr": "" } }

Используйте sandboxPolicy.type = "externalSandbox", если процесс сервера уже выполняется в песочнице и вы хотите, чтобы Codex пропустил собственное применение песочницы. Для режима внешней песочницы задайте networkAccess равным restricted (по умолчанию) или enabled. Для readOnly и workspaceWrite используйте ту же необязательную структуру access / readOnlyAccess, которая показана выше.

Примечания:

  • Сервер отклоняет пустые массивы command.
  • sandboxPolicy принимает ту же структуру, что и turn/start (например, dangerFullAccess, readOnly, workspaceWrite, externalSandbox).
  • Если timeoutMs не указан, используется значение сервера по умолчанию.
  • Задайте tty: true для сеансов на базе PTY и используйте processId, если планируете затем вызвать command/exec/write, command/exec/resize или command/exec/terminate.
  • Задайте streamStdoutStderr: true, чтобы получать уведомления command/exec/outputDelta во время выполнения команды.

Чтение требований администратора (configRequirements/read)

Используйте configRequirements/read, чтобы просмотреть действующие требования администратора, загруженные из requirements.toml и/или MDM.

{ "method": "configRequirements/read", "id": 52, "params": {} }
{ "id": 52, "result": {
  "requirements": {
    "allowedApprovalPolicies": ["onRequest", "unlessTrusted"],
    "allowedSandboxModes": ["readOnly", "workspaceWrite"],
    "featureRequirements": {
      "personality": true,
      "unified_exec": false
    },
    "network": {
      "enabled": true,
      "allowedDomains": ["api.openai.com"],
      "allowUnixSockets": ["/tmp/example.sock"],
      "dangerouslyAllowAllUnixSockets": false
    }
  }
} }

result.requirements имеет значение null, если требования не настроены. Подробности о поддерживаемых ключах и значениях см. в документации по requirements.toml.

Настройка песочницы Windows (windowsSandbox/setupStart)

Пользовательские клиенты Windows могут запускать настройку песочницы асинхронно, не блокируя проверку при запуске.

{ "method": "windowsSandbox/setupStart", "id": 53, "params": { "mode": "elevated" } }
{ "id": 53, "result": { "started": true } }

App-server запускает настройку в фоновом режиме и позднее отправляет уведомление о завершении:

{
  "method": "windowsSandbox/setupCompleted",
  "params": { "mode": "elevated", "success": true, "error": null }
}

Режимы:

  • elevated — выполнить настройку песочницы Windows с повышенными привилегиями.
  • unelevated — выполнить устаревшую настройку или предварительную проверку.

Файловая система

API файловой системы v2 работают с абсолютными путями. Используйте fs/watch, когда клиенту требуется сбросить состояние пользовательского интерфейса после изменения файла или каталога.

{ "method": "fs/watch", "id": 54, "params": {
  "watchId": "0195ec6b-1d6f-7c2e-8c7a-56f2c4a8b9d1",
  "path": "/Users/me/project/.git/HEAD"
} }
{ "id": 54, "result": { "path": "/Users/me/project/.git/HEAD" } }
{ "method": "fs/changed", "params": {
  "watchId": "0195ec6b-1d6f-7c2e-8c7a-56f2c4a8b9d1",
  "changedPaths": ["/Users/me/project/.git/HEAD"]
} }
{ "method": "fs/unwatch", "id": 55, "params": {
  "watchId": "0195ec6b-1d6f-7c2e-8c7a-56f2c4a8b9d1"
} }
{ "id": 55, "result": {} }

При отслеживании файла для его пути отправляется fs/changed, в том числе при обновлениях посредством замены или переименования.

События

Уведомления о событиях — это инициируемый сервером поток данных о жизненных циклах потоков, ходов и содержащихся в них элементов. После запуска или возобновления потока продолжайте читать активный транспортный поток для получения уведомлений thread/started, thread/archived, thread/unarchived, thread/closed, thread/status/changed, turn/*, item/* и serverRequest/resolved.

Отключение уведомлений

Клиенты могут отключать определённые уведомления для каждого соединения, передавая точные имена методов в initialize.params.capabilities.optOutNotificationMethods.

  • Только точное совпадение: item/agentMessage/delta отключает только этот метод.
  • Неизвестные имена методов игнорируются.
  • Применяется к текущим thread/*, turn/*, item/* и связанным уведомлениям v2.
  • Не применяется к запросам, ответам и ошибкам.

События нечёткого поиска файлов (экспериментальная возможность)

API сеансов нечёткого поиска файлов отправляет уведомления для каждого запроса:

  • fuzzyFileSearch/sessionUpdated — { sessionId, query, files } с текущими совпадениями для активного запроса.
  • fuzzyFileSearch/sessionCompleted — { sessionId } после завершения индексирования и сопоставления для этого запроса.

События предупреждений

  • configWarning — { summary, details?, path?, range? } для устранимых проблем конфигурации или инициализации.
  • warning — { threadId?, message } для некритических предупреждений времени выполнения.

События настройки песочницы Windows

  • windowsSandbox/setupCompleted — { mode, success, error }, отправляемый после завершения запроса windowsSandbox/setupStart.

События ходов

  • turn/started — { turn } с идентификатором хода, пустым items и status: "inProgress".
  • turn/completed — { turn }, где turn.status имеет значение completed, interrupted или failed; при сбоях передаётся { error: { message, codexErrorInfo?, additionalDetails? } }.
  • turn/diff/updated — { threadId, turnId, diff } с последним объединённым списком различий по всем изменениям файлов в ходе.
  • turn/plan/updated — { turnId, explanation?, plan } при каждой публикации или изменении плана агентом; каждая запись plan представляет собой { step, status } с status в состоянии pending, inProgress или completed.
  • hook/started и hook/completed — { threadId, turnId?, run } при запуске синхронного обработчика жизненного цикла и после получения итоговой сводки его выполнения. Для асинхронных обработчиков эти уведомления не отправляются.
  • model/safetyBuffering/updated — { threadId, turnId, model, useCases, reasons, showBufferingUi, fasterModel }, когда ответ поступает во временный буфер безопасности.
  • model/rerouted — { threadId, turnId, fromModel, toModel, reason }, когда сервис перенаправляет запрос другой модели.
  • model/verification — { threadId, turnId, verifications }, когда сервису требуется дополнительная проверка учётной записи.
  • thread/tokenUsage/updated — обновления данных об использовании для активного потока.

turn/diff/updated и turn/plan/updated сейчас содержат пустые массивы items, даже когда события элементов передаются потоково. Используйте уведомления item/* как достоверный источник данных об элементах хода.

Элементы

ThreadItem — размеченное объединение, передаваемое в ответах хода и уведомлениях item/*. Распространённые типы элементов:

  • userMessage — {id, content}, где content — список элементов пользовательского ввода (text, image или localImage).
  • functionCallOutput — {id, name, namespace, output} для отдельного вывода инструмента, переданного через turn/start.toolOutput. namespace может иметь значение null.
  • agentMessage - {id, text, phase?} с накопленным ответом агента. Если поле phase присутствует, оно использует значения протокола Responses API (commentary, partial_answer, final_answer). partial_answer — это готовый фрагмент ответа, за которым могут следовать дополнительный вывод или вызовы инструментов.
  • plan — {id, text}, содержащий текст предложенного плана в режиме планирования. Считайте окончательный элемент plan из item/completed достоверным.
  • reasoning — {id, summary, content}, где summary содержит потоковые сводки рассуждений, а content — необработанные блоки рассуждений.
  • commandExecution — {id, command, cwd, status, commandActions, aggregatedOutput?, exitCode?, durationMs?}.
  • fileChange — {id, changes, status}, описывающий предлагаемые изменения; changes перечисляет {path, kind, diff}.
  • mcpToolCall — {id, server, tool, status, arguments, appContext?, pluginId?, result?, error?}. Для доверенных приложений MCP appContext может содержать connectorId, linkId, resourceUri, appName, templateId и стабильный идентификатор коннектора actionName. В старых сохранённых элементах новые метаданные могут отсутствовать. Используйте appContext.resourceUri вместо устаревшего mcpAppResourceUri верхнего уровня.
  • dynamicToolCall — {id, tool, arguments, status, contentItems?, success?, durationMs?} для выполняемых клиентом динамических вызовов инструментов.
  • collabToolCall — {id, tool, status, senderThreadId, receiverThreadId?, newThreadId?, prompt?, agentStatus?}.
  • webSearch — {id, query, action?} для запросов веб-поиска, отправленных агентом.
  • imageView — {id, path}, отправляемый при вызове агентом инструмента просмотра изображений.
  • enteredReviewMode — {id, review}, отправляемый при запуске рецензента.
  • exitedReviewMode — {id, review}, отправляемый по завершении работы рецензента.
  • contextCompaction — {id}, отправляемый, когда Codex сжимает историю разговора.

Для webSearch.action действие type может иметь значение search (query?, queries?), openPage (url?) или findInPage (url?, pattern?).

App-server прекращает поддержку устаревшего уведомления thread/compacted; вместо него используйте элемент contextCompaction.

Все элементы отправляют два общих события жизненного цикла:

  • item/started — отправляет полный item при начале новой единицы работы; item.id совпадает с itemId, используемым в приращениях.
  • item/completed — отправляет окончательный item после завершения работы; считайте его достоверным состоянием.

Приращения элементов

  • item/agentMessage/delta — добавляет потоковый текст сообщения агента.
  • item/plan/delta — передаёт потоковый текст предложенного плана. Окончательный элемент plan может не полностью совпадать с объединёнными приращениями.
  • item/reasoning/summaryTextDelta — передаёт удобочитаемые сводки рассуждений; summaryIndex увеличивается при открытии нового раздела сводки.
  • item/reasoning/summaryPartAdded — обозначает границу между разделами сводки рассуждений.
  • item/reasoning/textDelta — передаёт необработанный текст рассуждений (если он поддерживается моделью).
  • item/commandExecution/outputDelta — передаёт stdout/stderr команды; добавляйте приращения по порядку.
  • item/fileChange/outputDelta — устаревшее уведомление для совместимости с текстовым выводом прежнего apply_patch. Текущие версии app-server больше его не отправляют; используйте элементы fileChange и turn/diff/updated.

Ошибки

Если ход завершается сбоем, сервер отправляет событие error с { error: { message, codexErrorInfo?, additionalDetails? } }, а затем завершает ход со значением status: "failed". Если доступен код состояния вышестоящего HTTP-сервиса, он указывается в codexErrorInfo.httpStatusCode.

Распространённые значения codexErrorInfo:

  • ContextWindowExceeded
  • UsageLimitExceeded
  • HttpConnectionFailed (ошибки 4xx/5xx вышестоящего сервиса)
  • ResponseStreamConnectionFailed
  • ResponseStreamDisconnected
  • ResponseTooManyFailedAttempts
  • BadRequest, Unauthorized, SandboxError, InternalServerError, Other

Если доступен код состояния вышестоящего HTTP-сервиса, сервер передаёт его в httpStatusCode соответствующего варианта codexErrorInfo.

Подтверждения

В зависимости от настроек Codex пользователя для выполнения команд и изменения файлов может потребоваться подтверждение. App-server отправляет клиенту инициированный сервером запрос JSON-RPC, а клиент отвечает данными решения.

  • Решения о выполнении команд: accept, acceptForSession, decline, cancel или { "acceptWithExecpolicyAmendment": { "execpolicy_amendment": ["cmd", "..."] } }.

  • Решения об изменении файлов: accept, acceptForSession, decline, cancel.

  • Запросы содержат threadId и turnId — используйте их, чтобы ограничить состояние пользовательского интерфейса активной беседой.

  • Сервер возобновляет или отклоняет работу и завершает элемент со значением item/completed.

Подтверждения выполнения команд

Порядок сообщений:

  1. item/started показывает ожидающий элемент commandExecution с command, cwd и другими полями.
  2. item/commandExecution/requestApproval содержит itemId, threadId, turnId, необязательный reason, необязательный command, необязательный cwd, необязательный commandActions, необязательный proposedExecpolicyAmendment, необязательный networkApprovalContext и необязательный availableDecisions. Если initialize.params.capabilities.experimentalApi = true, данные также могут содержать экспериментальный additionalPermissions с описанием запрошенного доступа к песочнице для отдельных команд. Все пути файловой системы внутри additionalPermissions передаются как абсолютные.
  3. Клиент отвечает одним из перечисленных выше решений о подтверждении выполнения команды.
  4. serverRequest/resolved подтверждает, что ожидающий запрос получил ответ или был удалён.
  5. item/completed возвращает окончательный элемент commandExecution с status: completed | failed | declined.

Если присутствует networkApprovalContext, запрос относится к управляемому сетевому доступу (а не к общему подтверждению команды оболочки). Текущая схема v2 предоставляет целевые host и protocol; клиенты должны отображать специальный запрос для сети и не рассчитывать, что command будет понятным пользователю предварительным представлением команды оболочки.

Codex группирует одновременные запросы подтверждения сетевого доступа по месту назначения (host, протоколу и порту). Поэтому app-server может отправить один запрос, разрешающий несколько ожидающих обращений к одному месту назначения, тогда как разные порты одного узла обрабатываются отдельно.

Подтверждения изменения файлов

Порядок сообщений:

  1. item/started отправляет элемент fileChange с предлагаемыми changes и status: "inProgress".
  2. item/fileChange/requestApproval содержит itemId, threadId, turnId, необязательный reason и необязательный grantRoot.
  3. Клиент отвечает одним из перечисленных выше решений о подтверждении изменения файлов.
  4. serverRequest/resolved подтверждает, что ожидающий запрос получил ответ или был удалён.
  5. item/completed возвращает окончательный элемент fileChange с status: completed | failed | declined.

tool/requestUserInput

Когда клиент отвечает на item/tool/requestUserInput, app-server отправляет serverRequest/resolved с { threadId, requestId }. Если ожидающий запрос удаляется при запуске, завершении или прерывании хода до ответа клиента, сервер отправляет такое же уведомление об очистке.

Параметры запроса содержат autoResolutionMs в виде целочисленного тайм-аута в миллисекундах или null. Если параметр присутствует, хост-клиенты могут автоматически обработать запрос по истечении этого интервала, если пользователь не ответит.

Запросы разрешений

Встроенный инструмент request_permissions отправляет item/permissions/requestApproval с threadId, turnId, itemId, environmentId, cwd, необязательным reason и запрошенными разрешениями для сети или файловой системы. Ответьте с помощью permissions, включив только предоставленное подмножество разрешений. Задайте scope равным "session", чтобы сохранить разрешение для последующих ходов того же сеанса; не указывайте его или используйте "turn" для разрешения в рамках одного хода. Разрешения, которые не были запрошены, игнорируются.

Запросы уточнений от MCP server

MCP server может прервать ход с помощью mcpServer/elicitation/request. Запрос содержит threadId, необязательный turnId, serverName и одну из следующих структур запроса:

  • mode: "form" или mode: "openai/form" с message и requestedSchema.
  • mode: "url" с message, url и elicitationId.

Ответьте с помощью action: "accept" и запрошенного content либо с помощью action: "decline" или "cancel" и content: null. Затем app-server отправит serverRequest/resolved. Чтобы получать вариант openai/form, включите его с помощью initialize.params.capabilities.mcpServerOpenaiFormElicitation.

Вызовы динамических инструментов (экспериментальная возможность)

dynamicTools в thread/start и соответствующая последовательность запросов или ответов item/tool/call являются экспериментальными API.

Имена динамических инструментов и пространств имён должны соответствовать ограничениям именования Responses API. Не используйте зарезервированные имена пространств имён встроенных инструментов Codex.

При вызове динамического инструмента во время хода app-server отправляет:

  1. item/started с item.type = "dynamicToolCall", status = "inProgress", а также tool и arguments.
  2. item/tool/call в виде серверного запроса клиенту.
  3. Ответ клиента с возвращёнными элементами содержимого.
  4. item/completed с item.type = "dynamicToolCall", окончательным status и любым возвращённым значением contentItems или success.

Подтверждения вызовов инструментов MCP (приложения)

Вызовы инструментов приложений (коннекторов) также могут требовать подтверждения. Если вызов инструмента приложения имеет побочные эффекты, сервер может запросить подтверждение с помощью tool/requestUserInput и таких вариантов, как Принять, Отклонить и Отменить. Аннотации о разрушительных действиях всегда вызывают запрос подтверждения, даже если инструмент также заявляет менее привилегированные характеристики. Если пользователь отклоняет или отменяет запрос, связанный элемент mcpToolCall завершается с ошибкой без запуска инструмента.

Навыки

Вызовите навык, включив $<skill-name> в пользовательские текстовые входные данные. Добавьте элемент входных данных skill (рекомендуется), чтобы сервер внедрил полные инструкции навыка, а не полагался на разрешение имени моделью.

{
  "method": "turn/start",
  "id": 101,
  "params": {
    "threadId": "thread-1",
    "input": [
      {
        "type": "text",
        "text": "$skill-creator Add a new skill for triaging flaky CI."
      },
      {
        "type": "skill",
        "name": "skill-creator",
        "path": "/Users/me/.codex/skills/skill-creator/SKILL.md"
      }
    ]
  }
}

Если не добавить элемент skill, модель всё равно обработает маркер $<skill-name> и попытается найти навык, что может увеличить задержку.

Пример:

$skill-creator Add a new skill for triaging flaky CI and include step-by-step usage.

Используйте skills/list, чтобы получить доступные навыки (при необходимости ограничив область с помощью cwds и forceReload). Можно также включить perCwdExtraUserRoots, чтобы сканировать дополнительные абсолютные пути как область user для определённых значений cwd. App-server игнорирует записи, для которых cwd отсутствует в cwds. skills/list может повторно использовать кэшированный результат для каждого cwd; задайте forceReload: true, чтобы обновить данные с диска. При наличии сервер считывает interface и dependencies из SKILL.json.

{ "method": "skills/list", "id": 25, "params": {
  "cwds": ["/Users/me/project", "/Users/me/other-project"],
  "forceReload": true,
  "perCwdExtraUserRoots": [
    {
      "cwd": "/Users/me/project",
      "extraUserRoots": ["/Users/me/shared-skills"]
    }
  ]
} }
{ "id": 25, "result": {
  "data": [{
    "cwd": "/Users/me/project",
    "skills": [
      {
        "name": "skill-creator",
        "description": "Create or update a Codex skill",
        "enabled": true,
        "interface": {
          "displayName": "Skill Creator",
          "shortDescription": "Create or update a Codex skill"
        },
        "dependencies": {
          "tools": [
            {
              "type": "env_var",
              "value": "GITHUB_TOKEN",
              "description": "GitHub API token"
            },
            {
              "type": "mcp",
              "value": "github",
              "transport": "streamable_http",
              "url": "https://example.com/mcp"
            }
          ]
        }
      }
    ],
    "errors": []
  }]
} }

Сервер также отправляет уведомления skills/changed при изменении отслеживаемых локальных файлов навыков. Считайте это сигналом об аннулировании данных и при необходимости повторно запустите skills/list с текущими параметрами.

Чтобы включить или отключить навык по пути:

{
  "method": "skills/config/write",
  "id": 26,
  "params": {
    "path": "/Users/me/.codex/skills/skill-creator/SKILL.md",
    "enabled": false
  }
}

Приложения (коннекторы)

Используйте app/installed, чтобы прочитать последний зафиксированный снимок среды выполнения установленных приложений. Каждый результат содержит id приложения, runtimeName (или null), действующее состояние enabled и состояние callable. Приложение доступно для вызова, только если действующая конфигурация включает его и хотя бы один видимый модели инструмент соответствует политикам приложения и инструментов.

{
  "method": "app/installed",
  "id": 49,
  "params": {
    "threadId": "thread-1",
    "forceRefresh": false
  }
}
{
  "id": 49,
  "result": {
    "apps": [
      {
        "id": "demo-app",
        "runtimeName": "Demo App",
        "enabled": true,
        "callable": true
      }
    ]
  }
}

Не указывайте threadId, чтобы использовать глобальную конфигурацию вместо конфигурации загруженного потока. Задайте forceRefresh: true, чтобы обновить снимок среды выполнения коннектора перед чтением. Если глобальная политика или политика рабочей области блокирует доступ к приложению, обнаруженное приложение всё равно может отображаться с enabled и callable, равными false.

Используйте app/list, чтобы получить доступные приложения. В CLI/TUI /apps — средство выбора для пользователя; в пользовательских клиентах вызывайте app/list напрямую. Каждая запись содержит как isAccessible (доступность пользователю), так и isEnabled (включение в config.toml), чтобы клиенты могли различать установку или доступ и локальное включённое состояние. Записи приложений также могут содержать необязательные поля branding, appMetadata и labels.

{ "method": "app/list", "id": 50, "params": {
  "cursor": null,
  "limit": 50,
  "threadId": "thread-1",
  "forceRefetch": false
} }
{ "id": 50, "result": {
  "data": [
    {
      "id": "demo-app",
      "name": "Demo App",
      "description": "Example connector for documentation.",
      "logoUrl": "https://example.com/demo-app.png",
      "logoUrlDark": null,
      "distributionChannel": null,
      "branding": null,
      "appMetadata": null,
      "labels": null,
      "installUrl": "https://chatgpt.com/apps/demo-app/demo-app",
      "isAccessible": true,
      "isEnabled": true
    }
  ],
  "nextCursor": null
} }

Если указать threadId, для ограничения возможностей приложения (features.apps) используется снимок конфигурации этого потока. Если параметр не указан, app-server использует последнюю глобальную конфигурацию.

app/list возвращается после загрузки как доступных приложений, так и приложений из каталога. Задайте forceRefetch: true, чтобы обойти кэши приложений и получить свежие данные. Записи кэша заменяются только при успешном обновлении.

Сервер также отправляет уведомления app/list/updated после завершения загрузки каждого источника (доступных приложений или приложений из каталога). Каждое уведомление содержит последний объединённый список приложений.

{
  "method": "app/list/updated",
  "params": {
    "data": [
      {
        "id": "demo-app",
        "name": "Demo App",
        "description": "Example connector for documentation.",
        "logoUrl": "https://example.com/demo-app.png",
        "logoUrlDark": null,
        "distributionChannel": null,
        "branding": null,
        "appMetadata": null,
        "labels": null,
        "installUrl": "https://chatgpt.com/apps/demo-app/demo-app",
        "isAccessible": true,
        "isEnabled": true
      }
    ]
  }
}

Используйте app/read, если идентификаторы приложений уже известны и нужны метаданные приложений, а не состояние установленной среды выполнения. Передавайте не более 100 appIds. Сервер сохраняет только первое вхождение каждого повторяющегося идентификатора и сохраняет этот порядок как в apps, так и в missingAppIds. Неизвестные или недоступные приложения возвращаются в missingAppIds без завершения всего запроса с ошибкой.

{
  "method": "app/read",
  "id": 52,
  "params": {
    "appIds": ["demo-app", "missing-app"],
    "includeTools": true
  }
}
{
  "id": 52,
  "result": {
    "apps": [
      {
        "id": "demo-app",
        "name": "Demo App",
        "description": "Example connector for documentation.",
        "iconUrl": null,
        "iconUrlDark": null,
        "distributionChannel": null,
        "installUrl": null,
        "pluginDisplayNames": [],
        "toolSummaries": [
          {
            "name": "search",
            "title": "Search",
            "description": "Search the app.",
            "isEnabled": true,
            "disabledReason": null,
            "isReadOnly": true
          }
        ]
      }
    ],
    "missingAppIds": ["missing-app"]
  }
}

Задайте includeTools: true, чтобы запросить предназначенные только для отображения общедоступные сводки инструментов. Ответ с метаданными не содержит состояния установленной среды выполнения приложения и не разрешает вызов инструмента; используйте app/installed, чтобы проверить действующее состояние enabled и callable.

Вызовите приложение, вставив $<app-slug> в текстовые входные данные и добавив элемент входных данных mention с путём app://<id> (рекомендуется).

{
  "method": "turn/start",
  "id": 51,
  "params": {
    "threadId": "thread-1",
    "input": [
      {
        "type": "text",
        "text": "$demo-app Pull the latest updates from the team."
      },
      {
        "type": "mention",
        "name": "Demo App",
        "path": "app://demo-app"
      }
    ]
  }
}

Примеры RPC конфигурации для настроек приложений

Используйте config/read, config/value/write и config/batchWrite, чтобы просматривать или изменять параметры управления приложениями в config.toml.

Чтение действующей структуры конфигурации приложения (включая _default и переопределения для отдельных инструментов):

{ "method": "config/read", "id": 60, "params": { "includeLayers": false } }
{ "id": 60, "result": {
  "config": {
    "apps": {
      "_default": {
        "enabled": true,
        "destructive_enabled": true,
        "open_world_enabled": true,
        "approvals_reviewer": "user",
        "default_tools_approval_mode": "auto"
      },
      "google_drive": {
        "enabled": true,
        "destructive_enabled": false,
        "approvals_reviewer": "auto_review",
        "default_tools_approval_mode": "prompt",
        "tools": {
          "files/delete": { "enabled": false, "approval_mode": "approve" }
        }
      }
    }
  }
} }

apps._default.approvals_reviewer задаёт средство проверки для всех приложений, если оно не переопределено значением отдельного приложения. Если оба значения отсутствуют, приложение наследует значение approvals_reviewer верхнего уровня. apps._default.default_tools_approval_mode задаёт резервный режим подтверждения для инструментов без переопределения на уровне приложения или инструмента. Управляемые требования к режиму подтверждения имеют приоритет над настройками режима подтверждения инструментов.

Изменение одной настройки приложения:

{
  "method": "config/value/write",
  "id": 61,
  "params": {
    "keyPath": "apps.google_drive.default_tools_approval_mode",
    "value": "prompt",
    "mergeStrategy": "replace"
  }
}

Атомарное применение нескольких изменений приложения:

{
  "method": "config/batchWrite",
  "id": 62,
  "params": {
    "edits": [
      {
        "keyPath": "apps._default.destructive_enabled",
        "value": false,
        "mergeStrategy": "upsert"
      },
      {
        "keyPath": "apps.google_drive.tools.files/delete.approval_mode",
        "value": "approve",
        "mergeStrategy": "upsert"
      }
    ]
  }
}

Обнаружение и импорт конфигурации внешнего агента

Используйте externalAgentConfig/detect, чтобы обнаружить артефакты внешнего агента, которые можно перенести, а затем передайте выбранные записи в externalAgentConfig/import.

Пример обнаружения:

{ "method": "externalAgentConfig/detect", "id": 63, "params": {
  "includeHome": true,
  "cwds": ["/Users/me/project"]
} }
{ "id": 63, "result": {
  "items": [
    {
      "itemType": "AGENTS_MD",
      "description": "Import /Users/me/project/CLAUDE.md to /Users/me/project/AGENTS.md.",
      "cwd": "/Users/me/project"
    },
    {
      "itemType": "SKILLS",
      "description": "Copy skill folders from /Users/me/.claude/skills to /Users/me/.agents/skills.",
      "cwd": null
    }
  ]
} }

Пример импорта:

{ "method": "externalAgentConfig/import", "id": 64, "params": {
  "migrationItems": [
    {
      "itemType": "AGENTS_MD",
      "description": "Import /Users/me/project/CLAUDE.md to /Users/me/project/AGENTS.md.",
      "cwd": "/Users/me/project"
    }
  ],
  "source": "claude-code"
} }
{ "id": 64, "result": { "importId": "8ae96ff3-3425-4f4c-8772-b6fd61502868" } }

Необязательный параметр импорта верхнего уровня source указывает продукт, который создал выбранные элементы переноса.

Сервер отправляет externalAgentConfig/import/progress по мере завершения обработки типов элементов, а externalAgentConfig/import/completed — после завершения всех синхронных и фоновых операций импорта. Эти уведомления содержат тот же importId из ответа и itemTypeResults с successes и failures для каждого типа. Уведомление о завершении может поступить сразу после ответа либо после завершения фонового удалённого импорта.

{ "method": "externalAgentConfig/import/progress", "params": {
  "importId": "8ae96ff3-3425-4f4c-8772-b6fd61502868",
  "itemTypeResults": [
    {
      "itemType": "AGENTS_MD",
      "successes": [
        { "itemType": "AGENTS_MD", "cwd": "/Users/me/project", "source": null, "target": "/Users/me/project/AGENTS.md" }
      ],
      "failures": []
    }
  ]
} }
{ "method": "externalAgentConfig/import/completed", "params": {
  "importId": "8ae96ff3-3425-4f4c-8772-b6fd61502868",
  "itemTypeResults": [
    {
      "itemType": "AGENTS_MD",
      "successes": [
        { "itemType": "AGENTS_MD", "cwd": "/Users/me/project", "source": null, "target": "/Users/me/project/AGENTS.md" }
      ],
      "failures": []
    }
  ]
} }

Чтение ранее завершённых операций импорта:

{ "method": "externalAgentConfig/import/readHistories", "id": 65 }
{ "id": 65, "result": { "data": [
  {
    "importId": "8ae96ff3-3425-4f4c-8772-b6fd61502868",
    "completedAtMs": 1781784000000,
    "successes": [
      { "itemType": "AGENTS_MD", "cwd": "/Users/me/project", "source": null, "target": "/Users/me/project/AGENTS.md" }
    ],
    "failures": []
  }
] } }

Поддерживаемые значения itemType: AGENTS_MD, CONFIG, SKILLS, PLUGINS, MCP_SERVER_CONFIG, SUBAGENTS, HOOKS, COMMANDS и SESSIONS. Для элементов PLUGINS в details.plugins перечислены каждый marketplaceName и pluginNames, которые Codex может попытаться перенести. При обнаружении возвращаются только элементы, с которыми ещё нужно выполнить работу. Например, Codex пропускает перенос AGENTS, если AGENTS.md уже существует и не пуст, а при импорте навыков существующие каталоги навыков не перезаписываются.

При обнаружении плагинов из .claude/settings.json Codex считывает настроенные источники маркетплейса из extraKnownMarketplaces. Если enabledPlugins содержит плагины из claude-plugins-official, но источник маркетплейса отсутствует, Codex определяет anthropics/claude-plugins-official как источник.

Конечные точки аутентификации

Поверхность JSON-RPC для аутентификации и учётных записей предоставляет методы запросов и ответов, а также инициированные сервером уведомления (без id). Используйте их, чтобы определять состояние аутентификации, запускать или отменять вход, выходить из системы, просматривать ограничения частоты запросов ChatGPT и уведомлять владельцев рабочей области об исчерпании кредитов или достижении лимитов использования.

Режимы аутентификации

Codex поддерживает следующие режимы аутентификации. account/updated.authMode показывает активный режим и при наличии содержит текущий planType ChatGPT. account/read также сообщает сведения об учётной записи и тарифном плане.

  • API key (apikey) — вызывающая сторона передаёт OpenAI API key с помощью type: "apiKey", а Codex сохраняет его для запросов API.
  • Управляемая аутентификация ChatGPT (chatgpt) — Codex управляет потоком OAuth ChatGPT, сохраняет токены и автоматически обновляет их. Начните с type: "chatgpt" для потока через браузер или с type: "chatgptDeviceCode" для потока с кодом устройства.
  • Внешние токены ChatGPT (chatgptAuthTokens) — экспериментальный режим для хост-приложений, которые уже управляют жизненным циклом аутентификации пользователя в ChatGPT. Хост-приложение напрямую передаёт accessToken, chatgptAccountId и необязательный chatgptPlanType и должно обновлять токен по запросу.
  • Amazon Bedrock — account/read сообщает об учётных записях Bedrock как type: "amazonBedrock" и указывает, получены ли учётные данные из управляемого Codex Bedrock API key (credentialSource: "codexManaged") или внешней цепочки учётных данных AWS (credentialSource: "awsManaged"). account/updated.authMode использует bedrockApiKey для управляемых Codex Bedrock API key.

Обзор API

  • account/read — получить текущие сведения об учётной записи; при необходимости обновить токены.
  • account/login/start — начать вход (apiKey, chatgpt, chatgptDeviceCode или экспериментальный chatgptAuthTokens).
  • account/login/completed (уведомление) — отправляется после завершения попытки входа (успешно или с ошибкой).
  • account/login/cancel — отменить ожидающий управляемый вход в ChatGPT по loginId.
  • account/logout — выйти из системы; вызывает account/updated.
  • account/updated (уведомление) — отправляется при каждом изменении режима аутентификации (authMode: apikey, chatgpt, chatgptAuthTokens, agentIdentity, personalAccessToken, bedrockApiKey или null) и при наличии содержит planType.
  • account/chatgptAuthTokens/refresh (серверный запрос) — запросить новые внешне управляемые токены ChatGPT после ошибки авторизации.
  • account/rateLimits/read — получить ограничения частоты запросов ChatGPT.
  • account/rateLimits/updated (уведомление) — отправляется при каждом изменении ограничений частоты запросов ChatGPT пользователя.
  • account/sendAddCreditsNudgeEmail — попросить ChatGPT отправить владельцу рабочей области электронное письмо об исчерпании кредитов или достижении лимита использования.
  • account/rateLimitResetCredit/consume — использовать один заработанный сброс ограничения частоты запросов со значением idempotencyKey, переданным вызывающей стороной.
  • account/usage/read — получить сводки активности токенов учётной записи ChatGPT и данные по дням.
  • account/workspaceMessages/read — получить активные сообщения рабочей области, включая заголовки уведомлений, если они доступны.
  • mcpServer/oauthLogin/completed (уведомление) — отправляется после завершения потока mcpServer/oauth/login; данные содержат { name, threadId, success, error? }. threadId может иметь значение null для потоков OAuth на уровне приложения или плагина.
  • mcpServer/startupStatus/updated (уведомление) — отправляется при изменении состояния запуска настроенного MCP server; данные содержат { threadId, name, status, error, failureReason }. threadId имеет значение null для запуска на уровне приложения. Если запуск завершился сбоем, failureReason: "reauthenticationRequired" означает, что сохранённые учётные данные OAuth истекли и их не удалось обновить, поэтому клиент должен предложить повторно подключить сервер.

1) Проверка состояния аутентификации

Запрос:

{ "method": "account/read", "id": 1, "params": { "refreshToken": false } }

Примеры ответов:

{ "id": 1, "result": { "account": null, "requiresOpenaiAuth": false } }
{ "id": 1, "result": { "account": null, "requiresOpenaiAuth": true } }
{
  "id": 1,
  "result": { "account": { "type": "apiKey" }, "requiresOpenaiAuth": true }
}
{
  "id": 1,
  "result": {
    "account": {
      "type": "amazonBedrock",
      "credentialSource": "codexManaged"
    },
    "requiresOpenaiAuth": false
  }
}
{
  "id": 1,
  "result": {
    "account": {
      "type": "amazonBedrock",
      "credentialSource": "awsManaged"
    },
    "requiresOpenaiAuth": false
  }
}
{
  "id": 1,
  "result": {
    "account": {
      "type": "chatgpt",
      "email": "user@example.com",
      "planType": "pro"
    },
    "requiresOpenaiAuth": true
  }
}

Примечания к полям:

  • refreshToken (логическое значение): задайте true, чтобы принудительно обновить токен в управляемом режиме ChatGPT. В режиме внешних токенов (chatgptAuthTokens) app-server игнорирует этот флаг.
  • email имеет значение null, если в учётной записи ChatGPT отсутствует адрес электронной почты.
  • requiresOpenaiAuth отражает активного поставщика; при значении false Codex может работать без учётных данных OpenAI.
  • Amazon Bedrock сообщает credentialSource: "codexManaged", когда используется Bedrock API key под управлением Codex. Для внешнего пути учётных данных AWS сообщается credentialSource: "awsManaged". Это указывает выбранный источник учётных данных, но не подтверждает, что цепочка учётных данных AWS способна получить учётные данные.

2) Вход с помощью API key

  1. Отправьте:
   {
     "method": "account/login/start",
     "id": 2,
     "params": { "type": "apiKey", "apiKey": "sk-..." }
   }
  1. Ожидайте:
   { "id": 2, "result": { "type": "apiKey" } }
  1. Уведомления:
   {
     "method": "account/login/completed",
     "params": { "loginId": null, "success": true, "error": null }
   }
   {
     "method": "account/updated",
     "params": { "authMode": "apikey", "planType": null }
   }

3) Вход с помощью ChatGPT (поток через браузер)

  1. Запустите:
   {
     "method": "account/login/start",
     "id": 3,
     "params": {
       "type": "chatgpt",
       "useHostedLoginSuccessPage": true,
       "appBrand": "chatgpt"
     }
   }

По умолчанию после успешного обратного вызова браузер перенаправляется на локальную страницу успешного выполнения. Задайте useHostedLoginSuccessPage: true, чтобы использовать размещённую страницу успешного выполнения, когда настройка организации не требуется. Если размещённая страница включена, appBrand может иметь значение "codex" или "chatgpt"; отсутствующее значение или значение null по умолчанию заменяется на "codex".

   {
     "id": 3,
     "result": {
       "type": "chatgpt",
       "loginId": "<uuid>",
       "authUrl": "https://chatgpt.com/...&redirect_uri=http%3A%2F%2Flocalhost%3A<port>%2Fauth%2Fcallback"
     }
   }
  1. Откройте authUrl в браузере; app-server размещает локальный обработчик обратного вызова.
  2. Ожидайте уведомлений:
   {
     "method": "account/login/completed",
     "params": { "loginId": "<uuid>", "success": true, "error": null }
   }
   {
     "method": "account/updated",
     "params": { "authMode": "chatgpt", "planType": "plus" }
   }

3b) Вход с помощью ChatGPT (поток с кодом устройства)

Используйте этот поток, когда клиент управляет процедурой входа или когда обратный вызов браузера работает ненадёжно.

  1. Запустите:
   {
     "method": "account/login/start",
     "id": 4,
     "params": { "type": "chatgptDeviceCode" }
   }
   {
     "id": 4,
     "result": {
       "type": "chatgptDeviceCode",
       "loginId": "<uuid>",
       "verificationUrl": "https://auth.openai.com/codex/device",
       "userCode": "ABCD-1234"
     }
   }
  1. Покажите пользователю verificationUrl и userCode; за взаимодействие с пользователем отвечает интерфейс.
  2. Ожидайте уведомлений:
   {
     "method": "account/login/completed",
     "params": { "loginId": "<uuid>", "success": true, "error": null }
   }
   {
     "method": "account/updated",
     "params": { "authMode": "chatgpt", "planType": "plus" }
   }

3c) Вход с помощью внешне управляемых токенов ChatGPT (chatgptAuthTokens)

Используйте этот экспериментальный режим, только когда хост-приложение управляет жизненным циклом аутентификации пользователя в ChatGPT и напрямую передаёт токены. Перед использованием этого типа входа клиенты должны задать capabilities.experimentalApi = true во время initialize.

  1. Отправьте:
   {
     "method": "account/login/start",
     "id": 7,
     "params": {
       "type": "chatgptAuthTokens",
       "accessToken": "<jwt>",
       "chatgptAccountId": "org-123",
       "chatgptPlanType": "business"
     }
   }
  1. Ожидайте:
   { "id": 7, "result": { "type": "chatgptAuthTokens" } }
  1. Уведомления:
   {
     "method": "account/login/completed",
     "params": { "loginId": null, "success": true, "error": null }
   }
   {
     "method": "account/updated",
     "params": { "authMode": "chatgptAuthTokens", "planType": "business" }
   }

Получив 401 Unauthorized, сервер может запросить у хост-приложения обновлённые токены:

{
  "method": "account/chatgptAuthTokens/refresh",
  "id": 8,
  "params": { "reason": "unauthorized", "previousAccountId": "org-123" }
}
{ "id": 8, "result": { "accessToken": "<jwt>", "chatgptAccountId": "org-123", "chatgptPlanType": "business" } }

После успешного ответа с обновлением сервер повторяет исходный запрос. Время ожидания запросов истекает примерно через 10 секунд.

4) Отмена входа в ChatGPT

{ "method": "account/login/cancel", "id": 4, "params": { "loginId": "<uuid>" } }
{ "method": "account/login/completed", "params": { "loginId": "<uuid>", "success": false, "error": "..." } }

5) Выход из системы

{ "method": "account/logout", "id": 5 }
{ "id": 5, "result": {} }
{ "method": "account/updated", "params": { "authMode": null, "planType": null } }

6) Ограничения частоты запросов (ChatGPT)

{ "method": "account/rateLimits/read", "id": 6 }
{ "id": 6, "result": {
  "rateLimits": {
    "limitId": "codex",
    "limitName": null,
    "primary": { "usedPercent": 25, "windowDurationMins": 15, "resetsAt": 1730947200 },
    "secondary": null,
    "rateLimitReachedType": null
  },
  "rateLimitsByLimitId": {
    "codex": {
      "limitId": "codex",
      "limitName": null,
      "primary": { "usedPercent": 25, "windowDurationMins": 15, "resetsAt": 1730947200 },
      "secondary": null,
      "rateLimitReachedType": null
    },
    "codex_other": {
      "limitId": "codex_other",
      "limitName": "codex_other",
      "primary": { "usedPercent": 42, "windowDurationMins": 60, "resetsAt": 1730950800 },
      "secondary": null,
      "rateLimitReachedType": null
    }
  },
  "rateLimitResetCredits": {
    "availableCount": 2,
    "credits": [{
      "id": "RateLimitResetCredit_1",
      "resetType": "codexRateLimits",
      "status": "available",
      "grantedAt": 1781654400,
      "expiresAt": 1784246400,
      "title": "Rate-limit reset",
      "description": "Reset an eligible Codex rate-limit window."
    }]
  }
} }
{ "method": "account/rateLimits/updated", "params": {
  "rateLimits": {
    "limitId": "codex",
    "primary": { "usedPercent": 31, "windowDurationMins": 15, "resetsAt": 1730948100 }
  }
} }

Примечания к полям:

  • rateLimits — представление одного сегмента для обратной совместимости.
  • rateLimitsByLimitId (если присутствует) — представление нескольких сегментов с ключами по тарифицируемому limit_id (например, codex).
  • limitId — идентификатор тарифицируемого сегмента.
  • limitName — необязательная понятная пользователю метка сегмента.
  • usedPercent — текущее использование в пределах окна квоты.
  • windowDurationMins — продолжительность окна квоты.
  • resetsAt — временная метка Unix (в секундах) следующего сброса.
  • planType включается, когда сервер возвращает тарифный план ChatGPT, связанный с сегментом.
  • credits включается, когда сервер возвращает сведения об оставшихся кредитах рабочей области.
  • rateLimitReachedType определяет классифицированное сервером состояние ограничения, если оно достигнуто.
  • rateLimitResetCredits содержит количество доступных заработанных сбросов, если сервис его предоставляет; в противном случае имеет значение null.
  • rateLimitResetCredits.credits имеет значение null, когда известно только количество. Пустой массив означает, что сервис получил подробные сведения и не обнаружил доступных кредитов. Сервис может ограничивать количество строк с подробностями, поэтому availableCount является достоверным значением.
  • Каждая строка подробностей содержит непрозрачный id, resetType, status, grantedAt, expiresAt (который может иметь значение null), title (который может иметь значение null) и description (который может иметь значение null).
  • Получите account/rateLimits/read после использования сброса.

7) Использование токенов (ChatGPT)

Используйте account/usage/read, чтобы получить сводные поля активности токенов ChatGPT и необязательные данные по дням.

{ "method": "account/usage/read", "id": 7 }
{ "id": 7, "result": {
  "summary": {
    "lifetimeTokens": 1234567,
    "peakDailyTokens": 45678,
    "longestRunningTurnSec": 540,
    "currentStreakDays": 8,
    "longestStreakDays": 14
  },
  "dailyUsageBuckets": [
    { "startDate": "2026-06-18", "tokens": 12345 }
  ]
} }

Примечания к полям:

  • Значения summary могут быть равны null, если сервис ещё не вернул этот показатель.
  • dailyUsageBuckets может иметь значение null; если поле присутствует, каждый сегмент содержит startDate и tokens.
  • Конечная точка требует аутентификации на основе сервисов Codex. Поддерживаются ChatGPT, внешние токены ChatGPT, идентификатор агента и аутентификация с помощью персонального токена доступа; аутентификация только по API key и через Bedrock не поддерживается.

8) Заработанные сбросы ограничения частоты запросов (ChatGPT)

Используйте account/rateLimitResetCredit/consume, чтобы применить один заработанный сброс.

{ "method": "account/rateLimitResetCredit/consume", "id": 8, "params": { "idempotencyKey": "8ae96ff3-3425-4f4c-8772-b6fd61502868", "creditId": "RateLimitResetCredit_1" } }
{ "id": 8, "result": { "outcome": "reset" } }

Примечания к полям:

  • idempotencyKey не должен быть пустым. Используйте UUID для каждой логической попытки погашения и повторно используйте то же значение при повторных запросах в рамках этой попытки.
  • creditId необязателен. Если он указан, это должен быть непустой непрозрачный идентификатор из account/rateLimits/read. Если он не указан, сервис выбирает следующий доступный кредит.
  • reset означает, что кредит был использован.
  • alreadyRedeemed означает, что такое же погашение уже было выполнено. Считайте это идемпотентным успешным результатом и обновите ограничения учётной записи.
  • nothingToReset означает, что нет подходящего окна ограничения частоты запросов для сброса.
  • noCredit означает, что в учётной записи нет доступных заработанных кредитов сброса.
  • После использования сброса получите account/rateLimits/read, а не вычисляйте обновлённые окна по этому ответу.

9) Уведомление владельца рабочей области об ограничении

Используйте account/sendAddCreditsNudgeEmail, чтобы попросить ChatGPT отправить владельцу рабочей области электронное письмо при исчерпании кредитов или достижении лимита использования.

{ "method": "account/sendAddCreditsNudgeEmail", "id": 9, "params": { "creditType": "credits" } }
{ "id": 9, "result": { "status": "sent" } }

Используйте creditType: "credits" при исчерпании кредитов рабочей области или creditType: "usage_limit" при достижении лимита использования рабочей области. Если владелец уже недавно получал уведомление, ответ имеет состояние cooldown_active.

10) Сообщения рабочей области (ChatGPT)

Используйте account/workspaceMessages/read, чтобы получить активные сообщения текущей рабочей области, включая заголовки уведомлений, если они доступны.

{ "method": "account/workspaceMessages/read", "id": 10 }
{ "id": 10, "result": { "featureEnabled": true, "messages": [
  { "messageId": "msg_123", "messageType": "headline", "messageBody": "Workspace maintenance starts at 5pm.", "createdAt": 1781395200, "archivedAt": null }
] } }