Справочник API: песочница, навыки и персональные переменные
Управление конфигурациями песочницы, каталогом навыков, задачами установки, интерактивным терминалом сессии и персональными переменными окружения. Пути используют префикс /api/v1; в примерах $BASE — адрес сервиса, $TOKEN — Bearer-токен текущего пользователя. Шаги работы в интерфейсе см. в Каталог навыков и песочница.
Права
| Ресурс | Чтение | Запись / проверка |
|---|---|---|
| Список/подробности конфигураций песочницы | Viewer+; API Key должен быть full-access | Admin+; API Key должен быть full-access |
| Реестр экземпляров песочницы, установленные навыки и файлы | Admin+ | Admin+; API Key должен быть full-access |
| Список каталога навыков | Viewer+, JWT | Добавление/удаление в каталоге, установка и просмотр файлов пакета требуют Admin+; API Key для группы записи должен быть full-access |
Доступные навыки /skills | Viewer+, JWT | Только чтение, параметр запроса sandbox_config_id; для общего агента дополнительно передаются agent_id, agent_source_tenant_id |
| Интерактивный терминал сессии | владелец сессии, только JWT входа | после получения ticket устанавливается WebSocket |
/me/env-vars* | текущий вызывающий, вошедший в систему | изменяет только свои значения, личность выводится на сервере; без дополнительного административного порога, используется Bearer JWT |
ID из другого пространства не дают прав доступа. Интерфейс персональных переменных не заменяет интерфейс управления навыками пространства.
Конфигурации песочницы
| Метод | Путь | Запрос / Ответ |
|---|---|---|
| GET | /sandbox-configs | 200 {success,data:[ConfigResponse],workspace_scripts_disabled} |
| POST | /sandbox-configs | {name,description?,config}; 201 {success,data:ConfigResponse} |
| GET | /sandbox-configs/:id | 200 {success,data:ConfigResponse} |
| PUT | /sandbox-configs/:id | {name,description?,config}; name обязательно; 200 как в подробностях |
| DELETE | /sandbox-configs/:id | необязательно force=true; 200 {success:true} |
| GET | /sandbox-configs/:id/sandboxes | 200 {success,data:SandboxInventory}; включает занятость и связанные агенты |
| PUT | /sandbox-configs/workspace-policy | {"scripts_disabled":true}; возвращает success/workspace_scripts_disabled |
| POST | /sandbox-configs/templates/query | {config,config_id?,ensure_standard?,replace_standard?,ensure_desktop?,replace_desktop?}; запрашивает удалённые шаблоны, может создать/заменить стандартный шаблон или шаблон рабочего стола; replace требует config_id |
ConfigResponse имеет вид {id,name,description,sandbox_type,config,created_at,updated_at}, учётные данные маскируются. При редактировании обновление выполняется на основе сохранённой конфигурации; маскированное значение-плейсхолдер сохраняет прежние учётные данные; skill_image поддерживается службой установки и не может быть заменено клиентом.
Поля config
| Поле | Тип | Описание |
|---|---|---|
sandbox_type | string | docker/cube/e2b; local удалён; host в Lite для рабочего стола нельзя сохранить как конфигурацию |
default_timeout_sec | int | таймаут выполнения; 0 — используется встроенное значение по умолчанию |
terminal_idle_disconnect_sec | int | через сколько бездействия терминала/рабочего стола происходит отключение; 0 — значение по умолчанию 900 секунд, допустимый диапазон от 60 секунд до 24 часов |
desktop_enabled | bool | объявляет, что выбранный шаблон — шаблон рабочего стола Cube/E2B; после установки навыка переключить нельзя |
allow_private_endpoints | bool | разрешает адреса приватного кластера, но не пропускает link-local/облачные метаданные |
env_vars | map[string]string | окружение этой конфигурации песочницы; значения хранятся в зашифрованном виде |
skill_rollout | string | next_turn (по умолчанию)/new_session |
network | object | сетевая политика Cube/E2B, см. ниже |
cube / e2b / docker | object | конфигурация подключения, соответствующая sandbox_type |
volume_mount | object | необязательная конфигурация тома; фактическое действие определяется возможностями бэкенда, наличие поля само по себе не означает поддержку |
skill_image | object | информация о снимке, поддерживаемая службой установки, только для чтения |
Поля volume_mount включают enabled, mount_path, provider, volume_id, volume_name; volume_owner_fingerprint управляется сервером. Возможность монтирования определяется совместно конфигурацией тома и возможностями бэкенда; при редактировании сохраняется информация о принадлежности, возвращённая сервером.
Конфигурация бэкендов:
| Бэкенд | Поля |
|---|---|
| cube | api_url, proxy_url, sandbox_domain, template_id; api_key требуется в зависимости от кластера; http_timeout_sec, cube_sandbox_ttl_seconds, dns_servers |
| e2b | api_key, template_id обязательны; api_url, sandbox_domain, proxy_url используются для самостоятельного хостинга; http_timeout_sec, e2b_sandbox_ttl_seconds |
| docker | image обязателен; host (пусто — локальный socket), tls_cert_path (обязателен для TCP), cpu_limit, memory_limit_mb, pids_limit, network_mode (bridge/none), runtime, idle_ttl_seconds, http_timeout_sec |
curl -X POST "$BASE/api/v1/sandbox-configs" \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"name":"Рабочее окружение E2B","config":{"sandbox_type":"e2b","e2b":{"api_key":"<e2b-key>","template_id":"<template-id>"}}}'
curl "$BASE/api/v1/sandbox-configs/cfg-1/sandboxes" \
-H "Authorization: Bearer $TOKEN"Изменение идентичности бэкенда и удаление конфигурации проверяют удалённые экземпляры. error.code для 409 может быть sandboxes_still_live, sandbox_inventory_unverifiable, skill_snapshot_release_failed и т. п.; 423 означает, что конфигурация изменяется другим запросом. force=true разрешает удаление только тогда, когда реестр невозможно проверить, и не пропускает подтверждённые активные/приостановленные экземпляры. Данные о занятости в ответе служат для поиска связанных сессий и агентов.
Сетевая политика
network:
| Поле | Описание |
|---|---|
deny_egress_by_default | false — исходящие по умолчанию разрешены; true — по умолчанию запрещены |
allow_out | IPv4/CIDR/домены или домены с одним wildcard-сегментом; домены используются в режиме запрета по умолчанию |
deny_out | список запретов IPv4/CIDR |
cube_rules | правила name/scheme/sni/host/methods/path/deny/audit/inject для Cube; порядок важен |
e2b_host_rules | правила host/headers для E2B; host также должен быть указан в allow_out |
allow_public_inbound | совместимость со старыми входными данными, при сохранении очищается; для входящих всегда требуются учётные данные |
cube_rules[].inject имеет вид [{header,secret,format}], e2b_host_rules[].headers — это header→secret; секретные поля хранятся в зашифрованном виде и маскируются. Docker использует docker.network_mode и не поддерживает эти правила L7.
{
"deny_egress_by_default": true,
"allow_out": ["pypi.org", "files.pythonhosted.org"],
"deny_out": []
}POST /system/sandbox-check
Запрос {config,config_id?,deep?}; config_id позволяет восстановить сохранённые маскированные учётные данные. deep=false выполняет проверку подключения; true дополнительно запускает временный скрипт, а удалённый бэкенд фактически создаёт и уничтожает песочницу, что может привести к расходу ресурсов бэкенда.
При успешном выполнении пробы возвращается {success:true,data:{ok,provider,checks,capabilities}}; неудачная проба тоже может вернуть HTTP 200, поэтому следует проверять data.ok; при неверных параметрах возвращается 400 с code/msg. Каждый check содержит name/ok/message/reason/latency_ms; ok=null означает пропуск. Например, при запрете исходящего трафика по умолчанию проба внешней сети пропускается политикой, что не равно успешной проверке доступа во внешнюю сеть.
curl -X POST "$BASE/api/v1/system/sandbox-check" \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"config_id":"cfg-1","deep":true}'Каталог навыков
| Метод | Путь | Запрос / Ответ |
|---|---|---|
| GET | /skills/catalog | 200 {success,data:[CatalogItem]}; CatalogItem содержит installations:[{sandbox_config_id,status,enabled,version,bundle_sha256,served?,...}] |
| POST | /skills/catalog | multipart file или JSON {"source":"@owner/slug"}; 201 {success,data:{id,name,version,description}} |
| POST | /skills/catalog/:id/install | {"sandbox_config_ids":["cfg-1","cfg-2"]}; 202 {success,data:{installs,errors?}} |
| GET | /skills/catalog/:id/files | 200 {success,data:[FileEntry]} |
| GET | /skills/catalog/:id/files/content?path=SKILL.md | 200 {success,data:FileContent} |
| DELETE | /skills/catalog/:id | удаляет при отсутствии ссылок на установку; 200 {success:true} |
Установка в несколько песочниц может быть принята частично: проверяйте data.installs и data.errors; HTTP 202 не означает, что установка во все песочницы завершена. Удаление из каталога не приводит к неявному удалению из песочниц.
curl -X POST "$BASE/api/v1/skills/catalog" \
-H "Authorization: Bearer $TOKEN" -F 'file=@skill.zip'
curl -X POST "$BASE/api/v1/skills/catalog/catalog-1/install" \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"sandbox_config_ids":["cfg-1"]}'Синтаксис указания источника, требования к анонимной загрузке и ограничения ZIP см. в Источники навыков.
Навыки в песочнице
Префикс следующих путей — /sandbox-configs/:id/skills; все операции, включая чтение, требуют Admin+.
| Метод | Суффикс | Поведение |
|---|---|---|
| GET | пусто | {success,data:[SkillResponse]} |
| POST | пусто | установка из ZIP file или source JSON; 202 {success,data:{skill_id}} |
| GET | /:skillId | {success,data:SkillResponse} |
| POST | /:skillId/reinstall | переустановка из повторно используемого пакета; необязательно {"instructions":"..."} (≤10000 символов) как инструкция по установке; 202 {success,data:{skill_id}} |
| POST | /:skillId/stop | остановка установки; 200 возвращает состояние навыка; при уже failed можно вызывать повторно, при других состояниях, отличных от installing, отклоняется |
| GET | /:skillId/guidance | инструкции текущего запуска установки: {success,data:{accepting,messages:[{id,content,status}]}} |
| POST | /:skillId/guidance | добавление инструкции во время установки {expected_message_id,steer_id,content}: expected_message_id берётся из install_message_id в SkillResponse, steer_id — сгенерированный клиентом UUID (при повторе не добавляется дважды), content — 1–10000 символов; 202 {success:true}; если установка сменила раунд, возвращается 409 |
| PATCH | /:skillId | enabled?, envs?; при пропуске не изменяется |
| DELETE | /:skillId | удаление из этой песочницы с сохранением пакета в каталоге |
| GET | /:skillId/files | список файлов |
| GET | /:skillId/files/content?path=SKILL.md | чтение файла по относительному пути, обход запрещён |
| GET | /:skillId/install-events | ход установки по SSE |
| GET | /:skillId/transcript | события процесса установки по SSE |
SkillResponse включает id/name/version/description/enabled/status/error/bundle_sha256/installed_snapshot_id/install_session_id/install_message_id/created_at/updated_at, а также envs:[{name,description,required,is_set}]. Во время обновления или переустановки, а также после сбоя, served:{version} указывает последнюю готовую версию, которую всё ещё предоставляет песочница; доступные агенту навыки соответствуют этой версии. Ответ с файлом может быть текстом UTF-8, base64 небольшого изображения или метаданными двоичных данных; нельзя предполагать, что у всех файлов есть текстовое содержимое.
envs в PATCH обновляет только объявленные переменные; необъявленные имена игнорируются, пустая строка очищает значение и сохраняет объявление.
curl -X PATCH "$BASE/api/v1/sandbox-configs/cfg-1/skills/skill-1" \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"enabled":true,"envs":{"API_TOKEN":"<workspace-token>"}}'
curl -N "$BASE/api/v1/sandbox-configs/cfg-1/skills/skill-1/install-events" \
-H "Authorization: Bearer $TOKEN"Полезная нагрузка о ходе имеет вид {percent,stage,log?,status?,done}. Разрыв соединения не отменяет установку; done может означать лишь невозможность дальше отслеживать ход, а окончательный результат определяется статусом навыка. Без Redis подсказка потока переключается на опрос состояния. 204 для transcript означает, что установка только началась и позиционирование событий ещё не готово; 404 может означать отсутствие журнала или истечение срока его действия, и по нему нельзя судить о сбое установки.
GET /skills?sandbox_config_id=cfg-1 возвращает метаданные навыков, доступных агенту: {success,data:[{name,description}],skills_available}, что отличается от полного набора записей установки, видимого администратору.
Ассистент вызывает этот интерфейс через skill.list, обязательно передавая sandbox_config_id из ответа agent.get (значение может быть пустым); проецируются только name, description и skills_available, параметры запроса общего агента и интерфейсы управления навыками не раскрываются. Пустой ID конфигурации возвращает пустой список и skills_available:false — следует предложить пользователю выбрать песочницу в редакторе агента; при настройке навыков используется возвращённый name, а не ID записи установки.
При одновременной передаче agent_id и agent_source_tenant_id (ID исходного пространства общего агента) выводится список навыков, которые этот общий агент может упомянуть через @: конфигурация песочницы берётся из самого агента, а sandbox_config_id из запроса игнорируется; если область навыков агента — selected, возвращаются только указанные навыки; если навыки отключены, возвращается пустой список и skills_available:false. Если вызывающий не имеет права использовать этого агента, возвращается 403.
Интерактивный терминал сессии
Терминал на боковой панели диалога подключается по WebSocket к удалённой песочнице текущей сессии; поддерживаются только Cube/E2B. Маршруты регистрируются в internal/router/routes_chat.go и пока не вынесены в Swagger; интерфейс рабочего стола см. в API сессий, требования к прокси — в Развёртывание песочницы.
POST /api/v1/sessions/:session_id/sandbox/terminal-ticket
Выдаётся handshake ticket, действительный две минуты. Требуется Bearer access token владельца сессии, вошедшего в систему; API Key вызвать нельзя.
curl -X POST "$BASE/api/v1/sessions/$SESSION_ID/sandbox/terminal-ticket" \
-H "Authorization: Bearer $TOKEN"Ответ: 200 {"success":true,"data":{"ticket":"<ticket>","expires_in":120}}.
GET /api/v1/sessions/:id/sandbox/terminal
Handshake WebSocket, не проходит через обычный промежуточный слой аутентификации:
| Параметр запроса | Обязательно | Описание |
|---|---|---|
ticket | да | ticket, полученный на предыдущем шаге; привязан к пользователю, пространству, сессии и access token на момент выдачи |
provision | нет | 1 разрешает создать или разбудить песочницу (может тарифицироваться); при пропуске подключается только к работающей песочнице |
agent_id / agent_source_tenant_id | нет | используется вместе с provision=1 и указывает, по конфигурации песочницы какого агента (включая общий) выполнять создание |
cols / rows | нет | начальный размер терминала |
pty_id | нет | повторное подключение к процессу Shell, возвращённому ранее в кадре ready |
После подключения бинарные кадры передают ввод-вывод терминала в обоих направлениях; текстовые кадры — управляющие сообщения JSON: сервер отправляет ready (с pty_id, backend, reattachable), exited (с exit_code) и error, клиент может отправлять {"type":"resize","cols":..,"rows":..}. Когда reattachable равен false (Docker), pty_id отсутствует: разрыв соединения завершает Shell, клиент не должен автоматически переподключаться. Коды ошибок включают SANDBOX_NOT_BOUND, SANDBOX_PAUSED, SANDBOX_STOPPED (для Docker-бэкенда, который не делает паузу: контейнер уже остановлен илиудалён по простоям), TERMINAL_UNSUPPORTED, IDLE_DISCONNECTED, AUTH_REVOKED, INTERNAL. Каждая сессия допускает не более 5 одновременных терминалов; при превышении возвращается 429.
Локальный каталог проекта Lite
Доступно только в настольной версии Lite; другие развёртывания возвращают 404. Оно открывает системный диалог выбора каталога на компьютере, где запущен Lite, и выбранный пользователем каталог добавляется в список одобренных; затем при создании сессии возвращённый dir передаётся как project_dir, что позволяет этой сессии использовать данный каталог в локальной песочнице. Поле project_dir см. в API сессий.
| Метод | Путь | Запрос / Ответ |
|---|---|---|
| POST | /system/host-project-dir | тело запроса отсутствует; 200 {"code":0,"msg":"success","data":{"dir":"/Users/me/project"}}; при отмене выбора dir пуст. Принимается только JWT входа, Viewer+, API Key отклоняется |
Персональные переменные окружения
Личность вызывающего определяется текущим контекстом аутентификации, user_id не принимается. Персональные эндпоинты возвращают имя переменной, источник и время обновления, но не возвращают значение в открытом виде.
| Метод | Путь | Запрос |
|---|---|---|
| GET | /me/env-vars | возвращает переменные конфигурации и навыков, сгруппированные по sandbox_config_id |
| PUT | /me/env-vars/skill | {skill_id,name,value}; имя должно быть объявлено навыком |
| DELETE | /me/env-vars/skill | {skill_id,name} |
| PUT | /me/env-vars/sandbox | {sandbox_config_id,name,value} |
| DELETE | /me/env-vars/sandbox | {sandbox_config_id,name} |
При чтении возвращается {success,data:[{sandbox_config_id,sandbox_config_name,description,vars,skills}]}; source помечает состояние user/workspace/unset и т. п. Успешная установка/удаление возвращают success; удаление неустановленного элемента возвращает 404. Персональные переменные песочницы отклоняют префикс WEKNORA_ и зарезервированные имена вроде PATH; для переменных, объявленных навыком, можно использовать необходимые имена учётных данных WEKNORA_*.
curl -X PUT "$BASE/api/v1/me/env-vars/skill" \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"skill_id":"skill-1","name":"API_TOKEN","value":"<my-token>"}'
curl -X DELETE "$BASE/api/v1/me/env-vars/skill" \
-H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d '{"skill_id":"skill-1","name":"API_TOKEN"}'Порядок переопределения: персональное значение навыка > персональное значение песочницы > значение навыка пространства. Запись персонального значения не изменяет административную конфигурацию. Справочник по реализации: internal/router/routes_infra.go, routes_agent.go, routes_auth_tenant.go, а также internal/handler/sandbox_config.go, sandbox_skill.go, skill_catalog.go, me_env_var.go, host_project_picker.go.
