AI Platform Docs
API

API Control Plane

HTTP-интерфейс управляющей подсистемы Control Plane

Состояние контракта

АтрибутЗначение
Базовый путь/control-plane
Путь API/api/v1
OpenAPI3.1.2
JSON Schema2020-12
Версия контракта1.0-r2
Состояниеr2-target-accepted-by-ADR-0002-ADR-0003-ADR-0004
АутентификацияOIDC/JWT (Bearer) для всех операций
АвторизацияПрямая проверка разрешения в Platform AuthZ (SpiceDB), fail-closed
ИдемпотентностьЗаголовок Idempotency-Key для write-операций
Контроль ревизийIf-Match (ETag вида "r<revision>") для PATCH/DELETE

Скачать OpenAPI JSON

SHA-256 и путь нормативного источника опубликованы в манифесте артефактов.

OpenAPI содержит относительные ссылки на схемы из соседнего каталога schemas. Используйте опубликованный адрес OpenAPI; для работы без сети скачайте также все файлы этого каталога из манифеста, сохранив расположение api/ и schemas/. Один скачанный JSON-файл не включает зависимости. В опубликованных схемах адреса $id и $ref приведены к локальным ссылкам; правила проверки данных сохранены. Манифест содержит SHA-256 опубликованного файла и отдельный sourceSha256 его нормативного источника.

Control Plane — центральный управляющий компонент Платформы ИИ. Он хранит желаемое состояние и управляет длительными операциями, но не участвует в обработке запросов LLM-инференса и в вызовах агентов (A2A). Каталог агентов и их вызов — отдельные API (Agent Registry и Platform Agent Gateway).

Асинхронные операции изменения состояния возвращают 202 Accepted со ссылкой на Operation — это подтверждение принятия намерения, а не факта выполнения. Фактическое применение отслеживается через поле verifiedState ресурса и GET /api/v1/operations/{operationId}.

Права доступа

ПравоНазначение
control_plane#observeЧтение безопасного статуса, дрейфа и аудита
control_plane#administerУправление уровнями, провайдерами, моделями, ключами и политиками
control_plane#operateОперации, согласование и восстановление
control_plane#author_publicationПубликация low-code агентов
agent_publication#manageУправление публикацией конкретного агента
agent#diagnoseДиагностика и статус публикации
api_key#view / api_key#manageСамообслуживание ключами текущего субъекта
api_key#activity_readАгрегаты и диагностика LLM-запросов конкретного ключа
agent#activity_aggregateАгрегаты обращений к агенту и LLM-потребления его ключей
agent#activity_diagnoseДополнительно журнал и карточки LLM-запросов ключей агента

Проверка выполняется прямо на целевом ресурсе. Недоступность или неопределённый результат SpiceDB приводит к отказу (fail-closed), а не к частичному доступу.

Операции

Метод и путьНазначениеПраво
GET /api/v1/system/statusБезопасный статус областей Control Planecontrol_plane#observe
GET / PATCH /api/v1/key-issuance-policyПолитика выдачи ключей (синглтон)control_plane#administer
GET / PATCH /api/v1/agent-publication-policyПолитика публикации агентов (синглтон)control_plane#administer
GET / POST /api/v1/tiersСписок и создание уровнейcontrol_plane#administer
GET / PATCH / DELETE /api/v1/tiers/{tierId}Операции с уровнемcontrol_plane#administer
GET / POST /api/v1/providersСписок и создание провайдеровcontrol_plane#administer
GET / PATCH / DELETE /api/v1/providers/{providerId}Операции с провайдеромcontrol_plane#administer
PUT /api/v1/providers/{providerId}/credentialУстановить учётные данные провайдераcontrol_plane#administer
GET / POST /api/v1/modelsСписок и создание моделейcontrol_plane#administer
GET / PATCH / DELETE /api/v1/models/{modelId}Операции с модельюcontrol_plane#administer
GET / POST /api/v1/keysСписок и выдача ключей (админ)control_plane#administer
GET / PATCH /api/v1/keys/{keyId}Метаданные и политика ключаcontrol_plane#administer
POST /api/v1/keys/{keyId}:rotateРотация ключаcontrol_plane#administer
POST /api/v1/keys/{keyId}:revokeОтзыв ключаcontrol_plane#administer
POST /api/v1/bulk/previewsПредпросмотр пакетных измененийcontrol_plane#administer
POST /api/v1/bulk/previews/{previewId}:executeВыполнить предпросмотрcontrol_plane#administer
GET /api/v1/me/key-issuance-policyПолитика выдачи для текущего субъектаАутентифицированный человек
GET / POST /api/v1/me/keysКлючи субъекта и самообслуживающая выдачаapi_key#view
GET /api/v1/me/keys/{keyId}Свой ключapi_key#view
POST /api/v1/me/keys/{keyId}:rotateРотация своего ключаapi_key#manage
POST /api/v1/me/keys/{keyId}:revokeОтзыв своего ключаapi_key#manage
GET /api/v1/me/agent-publication-envelopeОбёртка публикации low-code для субъектаcontrol_plane#author_publication
POST /api/v1/low-code/artifactsЗагрузка канонического low-code источникаcontrol_plane#author_publication
GET / POST /api/v1/agentsСписок и создание управляемых агентовagent_publication#manage / control_plane#author_publication
GET / PATCH /api/v1/agents/{agentId}Метаданные и владелец агентаagent_publication#manage
GET / POST /api/v1/agents/{agentId}/versionsСписок и создание версийagent_publication#manage
GET /api/v1/agents/{agentId}/versions/{versionId}Версия агентаagent_publication#manage / agent#diagnose
POST /api/v1/agents/{agentId}:rollbackОткат к версииagent_publication#manage
POST /api/v1/agents/{agentId}:unpublishСкрытие агентаagent_publication#manage
POST /api/v1/agents/{agentId}:revalidateПовторная валидацияagent_publication#manage
GET /api/v1/agents/{agentId}/statusСтатус публикацииagent_publication#manage / agent#diagnose
GET /api/v1/operationsСписок операцийcontrol_plane#operate
GET /api/v1/operations/{operationId}Статус операцииcontrol_plane#operate / operation#view
POST /api/v1/operations/{operationId}:cancelОтмена операцииcontrol_plane#operate / operation#cancel
GET /api/v1/system/driftОтчёт о дрейфеcontrol_plane#observe
GET /api/v1/auditЖурнал аудитаcontrol_plane#observe
POST /api/v1/system:reconcileСогласование по областиcontrol_plane#operate
POST /api/v1/recovery/previewsПредпросмотр восстановленияcontrol_plane#operate
POST /api/v1/recovery/previews/{previewId}:executeВыполнение восстановленияcontrol_plane#operate

Параметры постраничной навигации: cursor (непрозрачный, привязан к идентификации и фильтрам) и limit (1–100, по умолчанию 20). Ответ страницы содержит items и page.nextCursor.

Активность и потребление

Activity API предоставляет агрегаты LLM-потребления, журнал LLM-запросов и отдельные агрегаты HTTP-обращений к агентам. Все десять операций — безопасные GET; они не создают объект Operation и не требуют Idempotency-Key. Полные схемы параметров и ответов находятся в каноническом OpenAPI выпуска. Ниже пути указаны относительно /control-plane.

Метод и путьРезультат
GET /api/v1/activity/llm/summaryВыбранные метрики за весь интервал
GET /api/v1/activity/llm/seriesВременной ряд одной метрики, при необходимости по разрезам
GET /api/v1/activity/llm/breakdownТаблица одного или двух разрезов, общий итог и «Остальные»
GET /api/v1/activity/llm/requestsЖурнал завершённых логических LLM-запросов
GET /api/v1/activity/llm/requests/{requestId}Карточка запроса и наблюдаемые попытки
GET /api/v1/activity/llm/filter-optionsДоступные наблюдаемые значения одного разреза
GET /api/v1/activity/agents/summaryИтоги HTTP-обращений к агентам
GET /api/v1/activity/agents/seriesВременной ряд обращений к агентам
GET /api/v1/activity/agents/breakdownТаблица по агентам и их версиям
GET /api/v1/activity/agents/filter-optionsДоступные агенты или версии для фильтра

Метрики агентов относятся к HTTP-обращению на шлюзе: это не жизненный цикл асинхронной A2A-задачи. Для агентов нет журнала, карточки обращения, разреза вызывающего пользователя или связи «обращение → внутренние LLM-запросы». Инициатор LLM-потребления общего процесса агента неизвестен. Денежной стоимости и остатка накопительной квоты в этих ответах нет.

Область доступа

control_plane#administer разрешает Activity всей установки. Владелец обычного ключа получает api_key#activity_read: агрегаты, журнал и карточки своего ключа. Владелец агента получает agent#activity_aggregate: агрегаты агента и его LLM-ключей. Для журнала этих ключей нужно отдельное agent#activity_diagnose либо разрешение на конкретный ключ. Права control_plane#observe, control_plane#operate, просмотра или вызова агента сами по себе Activity не открывают.

У LLM-агрегатов и вариантов фильтра есть явный выбор access=aggregate (по умолчанию) или access=diagnostic. Второй вариант оставляет записи, для которых разрешена диагностика, поэтому его итог может быть меньше. Журнал и карточка всегда используют диагностику, Agent API — только агрегаты. ownership=mine ограничивает LLM-выборку ключами, непосредственно принадлежащими текущему человеку или сервису по паре issuer + subject; ключи его агентов и «вызовы, сделанные мной» сюда не входят.

Ответ сообщает meta.allowedDimensions, meta.allowedFilters и meta.detailAccess (full, limited, none). Ключ и его владелец доступны как разрезы в диагностике, в ownership=mine или администратору установки. Точные фильтры requestId/traceId также требуют диагностических прав. Недопустимый разрез возвращает отказ: сервер не сужает область незаметно.

Права проверяются заново перед каждым чтением, включая следующую страницу и известный идентификатор карточки, до агрегирования и выбора лидеров. Отзыв ключа не удаляет историю за срок хранения, но отзыв права закрывает следующее чтение. Недоступность сервиса авторизации возвращает ошибку, без старых результатов.

Параметры выборки и группировки

Неизвестные параметры и повтор скалярного параметра отклоняются. Массив задаётся повтором имени: modelId=A&modelId=B, без разделения запятыми. Значения одного фильтра объединяются через «ИЛИ», разные фильтры — через «И». Идентификаторы ресурсов — канонические UUIDv7.

ПараметрГде и как используется
from, toПара RFC3339 со смещением, например окончание Z; интервал по началу запроса [from, to), конец не в будущем. Без пары — последние 24 часа
observationНепрозрачный токен из предыдущего ответа для связанного чтения с той же границей поступления данных
access, ownershipТолько LLM; область доступа описана выше. Журнал не принимает access, поскольку он всегда диагностический
agentId, agentVersionIdПовторяемые точные фильтры обеих групп API, до 50 значений каждого
keyId, modelId, finalProviderId, attemptProviderIdПовторяемые точные фильтры LLM, до 50 значений каждого
ownerType, ownerIssuer, ownerSubject, ownerAgentIdОдин точный владелец LLM-ключа: principal/service вместе с issuer и subject либо agent вместе с идентификатором агента; неполная комбинация недопустима
outcome, reasonCodeПовторяемые LLM-фильтры. Исход: success, rejected, error, cancelled, unknown; причина — безопасный код из OpenAPI, без произвольного текста ошибки
requestId, traceIdТочные LLM-фильтры: соответственно 64 и 32 строчных шестнадцатеричных символа; не разрезы группировки
unknownПовторяемые имена разрезов с отсутствующим значением; agentId=A&unknown=agentId выбирает A и записи без известного агента
metricТолько агрегаты. summary без параметра возвращает совместимые метрики; series требует ровно одну, breakdown — хотя бы одну
groupByПовторяемый упорядоченный список: для series 0–2 разных разреза, для breakdown 1–2
granularityТолько series: auto, minute, hour, day. auto выбирает минуты до 24 часов включительно, иначе часы
top, rankByseries/breakdown: 1–20 лидеров, по умолчанию 10. Ранжирование по выбранной метрике, либо durationMs.mean/p50/p95, ttftMs.p50/p95
sortbreakdown: rank или -rank (по умолчанию). Журнал: startedAt, -startedAt (по умолчанию), durationMs, -durationMs
limit, cursorТолько журнал и варианты фильтров: размер 1–100, по умолчанию 20, и непрозрачный токен следующей страницы
dimension, qТолько filter-options: обязательный разрез ресурса и необязательная подстрока идентификатора или безопасного названия, 1–256 символов после удаления крайних пробелов, без учёта регистра

Карточка /llm/requests/{requestId} принимает только необязательный observation; период, фильтры и размер страницы ей не передают.

Разрезы LLM: keyId, keyOwner, agentId, agentVersionId, modelId, finalProviderId, attemptProviderId, outcome, reasonCode, с учётом прав. У Agent API доступны только agentId и agentVersionId. filter-options принимает только разрезы ресурсов, исключает собственный фильтр dimension и сохраняет остальные. Недоступные значения и их количество не раскрываются; это не каталог всех пользователей или ресурсов платформы.

finalProviderId означает провайдера последней попытки и совместим с числом запросов, исходами и задержками. attemptProviderId относится к наблюдаемым попыткам и совместим с токенами. Смешивать оба разреза или несовместимые метрики нельзя. В журнале фильтр attemptProviderId выбирает запросы с наблюдаемой попыткой этого провайдера: usage остаётся расходом всего запроса, а matchedAttemptUsage содержит расход совпавших попыток.

Хранится скользящий интервал 30 дней. Истёкшая часть периода вызывает ошибку, а не незаметное обрезание. Минутные интервалы допустимы только для периода до 24 часов; максимум — 2000 временных интервалов. Границы считаются в UTC, краевые интервалы обрезаются по from/to. Лидеры определяются за весь период, не заново в каждой точке. «Остальные» и общий итог вычисляются по исходной разрешённой выборке, включая корректный пересчёт процентилей.

Ответ, полнота и страницы

Успешный ответ содержит schemaVersion, meta, data; schemaVersion равен agent-platform.control-plane.activity/v1. Ответы имеют Cache-Control: private, no-store.

ОперацияДанные в data
summarymetrics — выбранные метрики
seriesgranularity, total, series; у ряда есть group, isOther и points с from, to, metrics
breakdowntotal, items с group/metrics, other либо null
requestsitems и page.nextCursor, без количества скрытых строк
Карточкаrequest, attempts, attemptsComplete
filter-optionsitems с value/label и page.nextCursor

LLM-метрики: requests, errorRate, rejectionRate, inputTokens, outputTokens, totalTokens, cachedInputTokens, reasoningTokens, durationMs, ttftMs. Agent-метрики: agentRequests, httpErrors, gatewayRejections, durationMs. Доли имеют значения 0–1; длительности — миллисекунды. requests.byOutcome показывает исходы. В знаменатель долей ошибок и отклонений входят все выбранные запросы, включая неизвестный исход; coverage позволяет увидеть число известных наблюдений. Для LLM задержки по умолчанию считаются по успешным запросам; явный outcome меняет выборку, а outcomes в метрике сообщает её. Задержки агентов учитывают все наблюдения.

Значение null означает отсутствие измерения, а не ноль. У обычных метрик есть coverage.known/total, у отдельных токенных метрик дополнительно coverage.partial. Для totalTokens покрытие разделено на complete, partial, unknown, conflict, total: известная сумма не обещает полный расход, если часть запросов измерена не полностью. Конфликтные компоненты не превращаются в достоверные числа. В пустой выборке суммы запросов и токенов равны 0, покрытие — 0/0, доли и задержки — null.

Журнал содержит одну строку на логический запрос. Карточка показывает только наблюдаемые попытки, коды исхода, измерения времени, безопасные идентификаторы и числовые данные о расходе токенов; промежуточные попытки не восстанавливаются догадкой. Текст запроса, ответ модели, заголовки, токены доступа, произвольный текст ошибки и внутренний URL провайдера в Activity API не возвращаются.

Для следующей страницы передают page.nextCursor и те же фильтры/сортировку. Окончание списка — только nextCursor=null: даже пустая страница может иметь продолжение. Клиенту следует устранять повторные requestId при объединении страниц. Отзыв доступа и истечение срока хранения учитываются при каждом чтении.

meta.observation действует один час, связывает пользователя, установку, группу API и asOf — границу поступления данных. Его можно использовать с другими фильтрами при переходе от графика к журналу и карточке. Он не фиксирует права и не гарантирует неизменный снимок БД: начавшаяся раньше вставка может стать видимой позднее. Для обновления данных выполняют новый запрос без токена и курсора. meta.retentionFrom сообщает текущую границу хранения.

meta.freshness.state — current, delayed или unknown; checkedAt относится к проверке доставки, lastReceivedAt — к последнему доступному факту. current не доказывает доставку всей истории. meta.completeness.state — unknown или known_gap; gaps содержит периоды проблем доставки с причиной delivery_loss или source_gap. Эти признаки отдельны от полноты токенов в конкретной метрике.

Ошибки Activity

HTTP / кодЗначение и действие клиента
400 invalid_requestИсправить параметры, типы или несовместимую комбинацию
400 activity_metric_dimension_mismatchРазделить метрики запросов и токенов при анализе провайдеров
400 invalid_cursor / observation_expiredНачать новое чтение; не подменять фильтры старого курсора
401Требуется действительная аутентификация
403 activity_dimension_forbiddenВыбрать разрешённый разрез или явно перейти в доступную диагностическую область
404 not_foundКарточка отсутствует, истекла или недоступна; причины не различаются
422 activity_range_unavailableВыбрать период в пределах текущего срока хранения
422 activity_query_too_largeУкрупнить временные интервалы или сократить период
422 activity_scope_too_broadСузить запрос точным ключом/агентом; сервер не вернул усечённый итог
429 management_rate_limitedПовторить с учётом Retry-After
503 authorization_unavailableТекущие права не удалось проверить; повторить после восстановления
503 activity_unavailableActivity, хранилище или необходимые привязки недоступны; повторить после восстановления

Ошибка не заменяется успешным пустым ответом. Примеры работы через интерфейс — в руководстве пользователя, команды — в руководстве cpctl.

Управление моделями

Три связанных сущности: Tier (профиль скорости и квот), Provider (внешний LLM-провайдер) и Model (конкретная модель, привязанная к провайдеру). Все операции, изменяющие состояние, возвращают 202 Accepted. Чтение ресурса возвращает заголовок ETag вида "r<revision>", обязательный в If-Match для PATCH/DELETE.

Tier (Уровень)

Профиль обслуживания ключа: лимит запросов в минуту и квота токенов в минуту. Tier не имеет членов, владельцев или унаследованных прав.

ПолеТипОписание
namestringУникальное имя, ^[a-z][a-z0-9._-]{0,127}$; неизменяемо
displayNamestring (1–128)Отображаемое имя (необязательно)
requestsPerMinuteinteger (≥1)Лимит запросов в минуту
tokensPerMinuteinteger (≥1)Квота токенов в минуту
desiredStateenumenabled / disabled

Удаление (DELETE) выполняется только для неиспользуемого уровня; при наличии зависимостей возвращается 409 Conflict. Список (GET /tiers) поддерживает точный fingerprint (sha256:…) в пределах аутентифицированного владельца; expand=models принимается только вместе с fingerprint.

Provider (Поставщик)

Конфигурация внешнего LLM-провайдера. Создание — небезопасное и отключённое: POST /providers принимает name, kind (единственное значение openai_compatible), endpoint (только https://) и desiredState: "disabled".

ПолеТипОписание
kindconstopenai_compatible
endpointuriHTTPS-адрес; неизменяемо при создании
credentialStatusenummissing, pending, verified, invalid
credentialFingerprintstringsha256:…, если учётные данные установлены

Учётные данные задаются отдельным ресурсом PUT /providers/{providerId}/credential. Значение поля credential (16–8192 символов) — writeOnly и sensitive: API не возвращает его. Провайдер можно включить (desiredState: "enabled") только после проверки учётных данных. Список и чтение провайдера не содержат сырых учётных данных. Удаление (DELETE) возможно только когда на провайдера не ссылаются модели.

Учётные данные провайдера удалить нельзя: их можно только установить или заменить через PUT /providers/{providerId}/credential.

Model (Модель)

Конкретная модель с именем для шлюза, привязкой к провайдеру и профилем. Наличие модели не создаёт права доступа — доступ выдаётся только явными привязками моделей к ключам.

ПолеТипОписание
gatewayNamestringИмя для Gateway, ^[a-z][a-z0-9._-]{0,127}$; неизменяемо
providerIdUUIDv7Привязанный провайдер; неизменяемо
upstreamModelstring (1–256)Имя модели у внешнего провайдера (например, gpt-4o)
profileenuminternal — внутренняя, external — внешняя
desiredStateenumenabled / disabled

В PATCH входят только upstreamModel, profile и desiredState: сменить «внутреннее» имя gatewayName или провайдера нельзя — можно только сменить модель, на которую указывает upstreamModel. Удаление (DELETE) возможно только когда модель не требуется активными ключами или маршрутами, иначе 409 Conflict. Смена состояния модели в масштабе — через пакетные операции set_model_state (см. «Пакетные операции»).

Управление ключами

ApiKey (Ключ API)

Виртуальный ключ доступа к LLM: один владелец, один Tier, непустой набор разрешённых моделей. Ключ создаётся через защищённую транзакцию — сначала сервис авторизации подтверждает операцию и владельца, затем ключ проверяется Gateway, и только после этого возвращается секретный материал.

ПолеТипОписание
idUUIDv7Стабильный идентификатор ключа
labelstring (1–128)Читаемое название (необязательно)
ownerobjectprincipal / service (issuer, subject) или agent (agentId)
tierIdUUIDv7Идентификатор уровня
modelIdsUUIDv7[] (1–256)Разрешённые модели, уникальные
statusenumpending, active, revoking, revoked, degraded
generationinteger (≥1)Номер поколения, инкрементируется при ротации
fingerprintstringsha256:… — контроль без раскрытия ключа
operationId / operationLinkUUIDv7 / pathОперация, создавшая текущую ревизию

Поведение выдачи и ротации:

  • Операция не возвращает 202. Первичный успешный вызов — 201 с oneTimeSecret (формат cpk_…) и Idempotency-Replayed: false; точная идемпотентная повторная отправка — 200 только с метаданными и Replayed: true.
  • Секрет возвращается только один раз. Сырой ключ в базе не хранится — только хэш fingerprint.
  • Ключи с владельцем-агентом (owner.type = "agent") нельзя обновлять, ротировать или отзывать административными методами — их жизненный цикл принадлежит публикации агента. Попытка приводит к 409 Conflict с кодом agent_key_lifecycle_owned_by_publication.
  • Отзыв (revoke) проверяется через Gateway; если Gateway не отвечает за отведённое время, возвращается 504 VerificationTimeout.

KeyIssuancePolicy (Политика выдачи ключей)

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

ПолеТипОписание
enabledbooleanВключена ли выдача
allowedTierIdsUUIDv7[] (0–256)Разрешённые уровни; одно значение фиксирует, несколько дают выбор
allowedModelIdsUUIDv7[] (0–256)Точный набор, материализуемый в каждый новый ключ
maxActiveKeysPerPrincipalinteger (1–100)Лимит активных ключей на субъекта

PATCH сливается с текущим синглтоном, затем проверяется итог; при enabled: true требуются минимум один Tier и одна Model. Операции: GET /key-issuance-policy — полная политика; GET /me/key-issuance-policy — сокращённая обёртка для аутентифицированного человека (allowedTiers, allowedModels, remainingActiveKeys и т.д.).

Самообслуживание ключами

Операции /api/v1/me/* работают с ключами, принадлежащими самому аутентифицированному субъекту (человеку или сервису). Владелец, Tier и набор моделей определяются по удостоверению и политике выдачи; в теле передаётся только label и, при много-Tier политике, tierId.

Метод и путьНазначениеПраво
POST /me/keysВыдать ключ по политике (выдача один раз)аутентифицированный человек
GET /me/keysСписок своих ключейapi_key#view
GET /me/keys/{keyId}Метаданные своего ключаapi_key#view
POST /me/keys/{keyId}:rotateРотация своего ключаapi_key#manage
POST /me/keys/{keyId}:revokeОтзыв своего ключаapi_key#manage

Отсутствующий или намеренно скрытый ключ возвращает 404 (hidden_or_absent), не раскрывая его существования.

Пакетные операции

POST /bulk/previews принимает до 1000 типизированных изменений — set_key_policy, revoke_key, set_model_state — и возвращает ограниченный семантический предпросмотр без вывода провайдера: список изменений и сводку воздействия (количество затронутых ключей, моделей, шардов, разрушительных операций). Предпросмотр неизменяем, имеет requestDigest и срок действия.

POST /bulk/previews/{previewId}:execute выполняет неистёкший предпросмотр как одну длительную операцию, сверяя requestDigest. Истёкший предпросмотр — 410; если хоть одна цель — ключ агента, отказ (409).

Публикация агентов

Управление low-code агентами: создание, версии, откат, скрытие и повторная валидация. Каталог (чтение карточек, поиск, вызов) — это отдельный API Agent Registry, здесь ведётся только желаемое состояние публикации. Жёсткое удаление агента не предусмотрено — вместо него unpublish.

Low-code источник

POST /low-code/artifacts проверяет и устойчиво сохраняет канонические байты low-code источника и подтверждает связь владения. Источник LowCodeSource ссылается на Поток:

ПолеЗначение
adapterlow-code — единственный поддерживаемый адаптер
flowId / revisionIdUUID потока и ревизии
revisionNumberНомер ревизии (≥1)
uriS3 или OCI URI (s3://…, oci://…@sha256:…)
sourceSha256[0-9a-f]{64}; проверяется по содержимому uri
schemaVersionplatform.low-code.flow/v1

Источник не содержит секретов, ключей, путей к Kubernetes, токенов и внутренних адресов. Прямая загрузка в OCI, Kubernetes или Agent Registry запрещена. Превышение фиксированного R2-лимита — 413; исчерпание лимита — 429.

Agent (Агент)

Сущность low-code агента со стабильным идентификатором и изменяемыми метаданными. Владелец — ровно один прямой (человек или сервис) или отсутствует.

ПолеТипОписание
idUUIDv7Стабильный идентификатор
namestring^a-z0-9?$
displayNamestring (1–256)Отображаемое имя
descriptionstring (≤4096)Описание
ownerDirectOwnerprincipal или service (необязательно)
publicationStateenumactive, degraded, suspended, unpublished
selectedVersionIdUUIDv7Выбранная версия
publicationRevision / revisionintegerРевизия публикации / ревизия ресурса (ETag)

POST /agents создаёт агента и начальную неизменяемую версию, принимая name, displayName, необязательное description, необязательного owner и initialVersion. Опущенный owner равен аутентифицированному вызывающему; явная подстановка владельца допускается только администратором.

PATCH /agents/{agentId} изменяет name, displayName, description или owner, но не затрагивает неизменяемые версии и карточку. Смена владельца требует активного сервиса: Registry атомарно заменяет кортеж владения, а Control Plane фиксирует квитанцию согласованности до успеха.

AgentVersion (Версия агента)

Неизменяемая версия с SemVer и исходным low-code артефактом. Любое изменение неизменяемых данных создаёт новую версию. Версия замораживает допустимый набор моделей, уровень и ревизию политики публикации.

ПолеТипОписание
id / agentIdUUIDv7Идентификатор версии и родительского агента
semanticVersionstringВерсия в формате SemVer
protocolconsta2a
sourceLowCodeSourceНизкоуровневый источник (адаптер low-code)
artifactDigestDigestSHA-256 артефакта после детерминированной OCI-упаковки
llmRequiredbooleanВыводится из проверенного неизменяемого потока
modelIdsUUIDv7[] (0–256)Выводимые разрешения моделей; пусто, только если llmRequired=false
tierIdUUIDv7Уровень из политики публикации; обязателен, если llmRequired=true
publicationPolicyRevision / publicationPolicyDigestinteger / DigestРевизия и дайджест политики на момент создания

Важно: llmRequired, modelIds и tierId — выводимые поля, а не задаваемые. Их вычисляет сервер по AgentPublicationPolicy и low-code источнику; передача в запросе создания отклоняется как 400 InvalidRequest.

POST /agents/{agentId}/versions создаёт новую неизменяемую версию-кандидат и публикует её. Создание версии проверяется против политики публикации: выключенная или недоступная политика блокирует создание новых LLM-версий, но не влияет на уже активные.

AgentPublicationPolicy (Политика пНастраиваемый синглтон, задающий допустимый уровень (tierId) и

набор моделей (не более 256) для новых версий агентов.сий агентов. Замораживается при создании версии; последующие изменения не действуют задним числом.

ПолеТипОписание
enabledbooleanВключена ли политика
tierIdUUIDv7Уровень по умолчанию; обязателен, если enabled
allowedModelIdsUUIDv7[] (0–256)Разрешённые модели; минимум 1, если enabled
policyDigestDigestДайджест политики

GET/PATCH /agent-publication-policy — управление политикой; GET /me/agent-publication-envelope — безопасная обёртка для конкретного вызывающего (кэшируется с private, no-store).

Команды жизненного цикла

Все команды возвращают 202 Accepted и создают длительную операцию.

КомандаМетодПоведение
ОткатPOST /agents/{agentId}:rollbackВыбор ранее проверенной неизменяемой версии (targetAgentVersionId). Создаёт новую ревизию и привязку; предыдущий Service UID и наблюдения Registry не наследуются
СкрытиеPOST /agents/{agentId}:unpublishСнимает доступность, сохраняя идентичность и историю. Причины: user_requested, security_response, source_retired, operational
Повторная валидацияPOST /agents/{agentId}:revalidateПроходит все гейты заново. Триггеры: scope_restored, operator_recovery, provider_recovered
СтатусGET /agents/{agentId}/statusБезопасный желаемый, применённый, проверенный и проекционный статус

Статус публикации GET /agents/{agentId}/status содержит желаемое, применённое, проверенное состояние и проекции Registry. В ответ не включаются исходные байты, сырой ключ, координаты Secret, bearer-токены, учётные данные провайдера, сырой манифест, внутренние адреса и стек-трейсы.

Агент становится active только после прохождения всех применимых гейтов; состояния degraded и suspended возникают при незавершённых или не пройденных гейтах. Подробности о гейтах и наблюдениях Registry описаны в руководстве администратора Control Plane.

Операции

Каждая изменяющая команда порождает одну длительную операцию (Operation) — устойчивое намерение в PostgreSQL, которое переживает перезапуск и повторяется до завершения или компенсации. Одна операция — одна конечная Workflow.

ПолеОписание
operationIdUUIDv7 устойчивого идентификатора
stateaccepted, running, retry_wait, verifying, compensating, succeeded, failed, cancelled
operationLink/control-plane/api/v1/operations/{operationId}

GET /operations фильтруется по state; GET /operations/{operationId} — статус одной операции. Операция не может содержать секретный материал. POST /operations/{operationId}:cancel запрашивает ограниченную отмену; уже применённые эффекты закрываются компенсацией, а не откатом.

Идемпотентность: заголовок Idempotency-Key (16–128 символов, ^[A-Za-z0-9._~-]+$) обязателен для write-операций. Устойчивое намерение и выделенные идентификаторы повторно используются при точном повторе того же ключа. Различный дайджест при том же ключе — 409 Conflict (idempotency_conflict).

Статус, дрейф и аудит

GET /system/status возвращает безопасный статус трёх областей (model_policy, key_policy, publication): состояние, ревизии (желаемая, применённая, проверенная), временная метка. Состояния: ready, reconciling, degraded, blocked.

GET /system/drift — классифицированный отчёт о дрейфе. Каждая запись содержит ресурс (resource.type, resource.id), область, классификацию (pending_convergence, unauthorized_external_change, missing_object, unsupported_provider_state, stale_observation, blocked_recovery), желаемую и наблюдаемую ревизию и время обнаружения. Фильтруется по domain.

GET /audit — неизменяемый журнал управления. Записи содержат исполнителя (человек или сервис), действие, ресурс, результат (accepted, succeeded, failed, denied), requestId и опционально operationId.

POST /system:reconcile запрашивает типизированное согласование по области (observe или repair). Вызывающий не выбирает инфраструктурные координаты. Согласование может обнаружить blocked_recovery, но не разрешает его.

Восстановление

POST /recovery/previews сохраняет неизменяемый observe-only предпросмотр. Сервер связывает типизированную причину с текущим полным снимком, инвентарём и областью действия; вызывающий не передаёт ссылки на инфраструктуру.

POST /recovery/previews/{previewId}:execute выполняет точные решения из неистёкшего предпросмотра. Каждое решение привязано к записи, наблюдению и ревизии. Разрушительное подтверждение становится неизменяемым аудит-фактом, привязанным к исполнителю.

Ошибки

Ошибки возвращают единый объект error (схема error-v1). Сообщение не раскрывает стек, токен, внутренний адрес, учётные данные и существование запрещённого объекта.

HTTPКласс ошибки
400Неверная форма или закрытая структура запроса
401Отсутствует или недействительно токен управления
403Подтверждённому субъекту запрещено функциональное право
404Ресурс отсутствует; у вызывающего — отсутствует или намеренно скрыт
409Конфликт идемпотентности, зависимостей или несовместимое состояние
410Сохранённый предпросмотр истёк и должен быть создан заново
412If-Match не называет текущую точную ревизию
413Фреймированный запрос или канонический источник превышают фиксированный R2-лимит
429Исчерпан лимит частоты, объектов или байт источника
503Недоступна авторизация — запрос завершается отказом (fail-closed)
504Кандидат ключа не проверен за синхронный бюджет; секрет не возвращается

Кодовые идентификаторы конфликтов включают, например, idempotency_conflict и agent_key_lifecycle_owned_by_publication.

Совместимость

Потребитель фиксирует SHA-256 OpenAPI и проверяет различия перед обновлением. Несовместимое изменение поля, пути или права требует новой версии API либо принятого периода перехода с проверками поставщика и потребителя и условием удаления прежней формы. Версия контракта 1.0-r2; r2 — релиз продукта, v1 — независимый мажорный номер API.

На этой странице