Русский

Сервер приложений Codex

Сервер приложений Codex

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:

{ "method": "thread/start", "id": 10, "params": { "model": "gpt-5.6-terra" } }

Ответы повторяют 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):




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-5.6-terra" } });

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

  • Поток: диалог между пользователем и агентом 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 отправлять расширенный вариант 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 — прочитать сохранённый поток по идентификатору, не возобновляя его; задайте includeTurns, чтобы вернуть полную историю ходов. Возвращаемые объекты 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/rollback — устаревший метод; удалить последние N ходов из контекста в памяти и сохранить маркер отката; возвращает обновлённый thread.
  • 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 и shareUrl удалённого плагина, если он предоставлен удалённым каталогом. Пока не вызывайте этот метод из клиентов в рабочей среде.
  • plugin/install — находится в разработке; установить плагин из маркетплейса по пути или имени удалённого маркетплейса. Пока не вызывайте этот метод из клиентов в рабочей среде.
  • plugin/uninstall — находится в разработке; удалить установленный плагин. Пока не вызывайте этот метод из клиентов в рабочей среде.
  • plugin/skill/read — по запросу прочитать Markdown удалённого навыка плагина, указав удалённый маркетплейс, идентификатор плагина и имя навыка.
  • app/installed — прочитать состояние среды выполнения установленных приложений, включая действующие состояния включения и доступности для вызова каждого приложения.
  • app/list — вывести доступные приложения (коннекторы) с пагинацией и метаданными доступности и включения.
  • app/read — получить метаданные и необязательные сводки инструментов, предназначенные только для отображения, для указанных идентификаторов приложений.
  • skills/config/write — включить или отключить навыки по пути.
  • mcpServer/oauth/login — начать вход через OAuth для настроенного сервера MCP; возвращает URL авторизации и по завершении отправляет mcpServer/oauthLogin/completed.
  • tool/requestUserInput — задать пользователю от одного до трёх коротких вопросов для вызова инструмента (экспериментальный метод); в вопросах можно задать isOther для варианта со свободным вводом.
  • mcpServer/elicitation/request (запрос сервера) — запросить у клиента структурированный ввод в форме или подтверждение перехода по URL, запрошенного сервером MCP.
  • item/permissions/requestApproval (запрос сервера) — запросить у клиента предоставление подмножества разрешений на доступ к сети или файловой системе, запрошенных встроенным инструментом request_permissions.
  • config/mcpServer/reload — повторно загрузить с диска конфигурацию серверов MCP и поставить в очередь обновление загруженных потоков.
  • mcpServerStatus/list — вывести серверы MCP, инструменты, ресурсы и статус аутентификации (пагинация с курсором и ограничением). Используйте detail: "full" для получения полных данных или detail: "toolsAndAuthOnly", чтобы исключить ресурсы.
  • mcpServer/resource/read — прочитать отдельный ресурс MCP через инициализированный сервер MCP.
  • mcpServer/tool/call — вызвать инструмент на настроенном для потока сервере MCP.
  • mcpServer/startupStatus/updated (уведомление) — отправляется при изменении статуса запуска настроенного сервера MCP для загруженного потока.
  • 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, субагенты, перехватчики, команды и сеансы; при непустом импорте по мере выполнения работы отправляются 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-5.6-sol",
    "model": "gpt-5.6-sol",
    "displayName": "GPT-5.6-Sol",
    "hidden": false,
    "defaultReasoningEffort": "low",
    "supportedReasoningEfforts": [{
      "reasoningEffort": "low",
      "description": "Fast responses with lighter reasoning"
    }],
    "inputModalities": ["text", "image"],
    "supportsPersonality": true,
    "isDefault": true
  }],
  "nextCursor": null
} }

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

  • supportedReasoningEfforts — поддерживаемые моделью варианты уровня рассуждений.
  • defaultReasoningEffort — рекомендуемый клиентам уровень рассуждений по умолчанию.
  • upgrade — необязательный идентификатор модели, рекомендуемой для обновления в клиентских запросах на миграцию.
  • upgradeInfo — необязательные метаданные обновления для клиентских запросов на миграцию.
  • hidden — признак того, скрыта ли модель из стандартного списка выбора.
  • inputModalities — поддерживаемые моделью типы входных данных (например, text, image).
  • supportsPersonality — признак поддержки моделью инструкций для определённого стиля общения, таких как /personality.
  • 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 считывает сохранённый поток без подписки на него; задайте includeTurns, чтобы включить ходы.
  • 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/rollback устарел. Он удаляет последние N ходов из контекста в памяти и записывает маркер отката в сохранённый журнал JSONL потока.
  • thread/inject_items добавляет необработанные элементы Responses API в видимую модели историю загруженного потока, не начиная пользовательский ход.

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

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

{ "method": "thread/start", "id": 10, "params": {
  "model": "gpt-5.6-terra",
  "cwd": "/Users/me/project",
  "approvalPolicy": "never",
  "sandbox": "workspaceWrite",
  "personality": "friendly",
  "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 — массив путей к загруженным файлам инструкций. Каждый путь использует собственный абсолютный синтаксис исходной среды, в том числе для удалённых сред.

Экспериментальные клиенты могут задать для historyMode в thread/start значение "legacy" (по умолчанию) или "paginated". Создание потока с пагинацией пока не поддерживается и возвращает ошибку JSON-RPC -32601. App-server может выводить список существующих записей с пагинацией и читать их сводки, но чтение полной истории, пагинация ходов и возобновление завершаются отказом до появления поддержки истории с пагинацией.

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

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

Чтобы продолжить сохранённый сеанс, вызовите thread/resume с записанным ранее thread.id. Структура ответа совпадает с thread/start. Также можно передать те же переопределения конфигурации, которые поддерживает thread/start, например personality:

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

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

Если в конфигурации включённый сервер MCP помечен как 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" } }
{ "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
  }
}
{
  "id": 13,
  "result": {
    "thread": {
      "id": "thr_789",
      "sessionId": "thr_789",
      "forkedFromId": "thr_123",
      "ephemeral": true
    }
  }
}

Для временных ответвлений потоков с пагинацией также требуется excludeTurns: true. Это экспериментальное поле, для которого требуется capabilities.experimentalApi = true.

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

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

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

  • includeTurns — при значении true ответ содержит ходы потока; при значении false или отсутствии поля возвращается только сводка потока.
  • Возвращаемые объекты thread содержат сведения среды выполнения status (notLoaded, idle, systemError или active с activeFlags).
{ "method": "thread/read", "id": 19, "params": { "threadId": "thr_123", "includeTurns": true } }
{ "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: "asc", чтобы получить ходы новее первого элемента предыдущей страницы.

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, чтобы ограничить результаты одним ходом, или не указывайте его, чтобы постранично получать элементы всего потока. Активное хранилище потоков должно поддерживать пагинацию элементов; в противном случае сервер возвращает ошибку неподдерживаемого метода.

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

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

  • cursor — непрозрачная строка из предыдущего ответа; не указывайте для первой страницы.
  • limit — если значение не задано, сервер использует подходящий размер страницы по умолчанию.
  • sortKeycreated_at (по умолчанию), updated_at или recency_at.
  • sortDirectiondesc (по умолчанию) или 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/rollback устарел и будет удалён. Он удаляет последние numTurns записей из контекста в памяти и сохраняет маркер отката в журнале выполнения. Возвращаемый thread содержит turns, заполненный после отката.

{ "method": "thread/rollback", "id": 30, "params": { "threadId": "thr_b", "numTurns": 1 } }
{ "id": 30, "result": { "thread": { "id": "thr_b", "name": "Bug bash notes", "ephemeral": false } } }

Ходы

Поле 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-5.6-terra",
  "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" (по умолчанию), чтобы выполнить проверку в существующем потоке, или delivery: "detached", чтобы создать ответвлённый поток проверки.

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

{ "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". Ответ имеет ту же структуру, но reviewThreadId будет идентификатором нового потока проверки (отличным от исходного threadId). Перед потоковой передачей хода проверки сервер также отправляет для нового потока уведомление thread/started.

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, final_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

Сервер MCP может прервать ход с помощью 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 Bedrockaccount/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; данные содержат { 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 }
] } }