Эксперименты

ACP Thread Bound Agents

Обзор

Этот план определяет, как OpenClaw должен поддерживать ACP-агенты в каналах с поддержкой потоков (в первую очередь Discord) с производственным жизненным циклом и восстановлением. Связанный документ:

Целевой пользовательский опыт:

  • пользователь создает или фокусирует ACP-сессию в потоке
  • сообщения пользователя в этом потоке маршрутизируются в привязанную ACP-сессию
  • вывод агента стримится обратно в ту же персону потока
  • сессия может быть постоянной или одноразовой с явными элементами управления очисткой

Краткое изложение решений

Долгосрочная рекомендация — гибридная архитектура:

  • Ядро OpenClaw отвечает за аспекты плоскости управления ACP
    • идентификатор сессии и метаданные
    • привязка потока и решения по маршрутизации
    • инварианты доставки и подавление дубликатов
    • семантика очистки жизненного цикла и восстановления
  • Бэкенд среды выполнения ACP является подключаемым
    • первый бэкенд — это сервис плагина на основе acpx
    • среда выполнения отвечает за транспорт ACP, очереди, отмену, переподключение

OpenClaw не должен перереализовывать внутренности транспорта ACP в ядре. OpenClaw не должен полагаться на чисто плагиновый путь перехвата для маршрутизации.

Архитектура конечной цели (святой грааль)

Рассматривать ACP как первоклассную плоскость управления в OpenClaw с подключаемыми адаптерами среды выполнения. Непреложные инварианты:

  • каждая привязка потока ACP ссылается на валидную запись сессии ACP
  • каждая сессия ACP имеет явное состояние жизненного цикла (creating, idle, running, cancelling, closed, error)
  • каждый запуск ACP имеет явное состояние выполнения (queued, running, completed, failed, cancelled)
  • создание, привязка и первоначальная постановка в очередь являются атомарными
  • повторные попытки команд идемпотентны (без дублирования запусков или дублирования вывода в Discord)
  • вывод в привязанном потоке является проекцией событий запуска ACP, а не побочными эффектами ad-hoc

Долгосрочная модель владения:

  • AcpSessionManager — единственный писатель и оркестратор ACP
  • менеджер сначала находится в процессе шлюза; позже может быть перемещен в выделенный сайдкар за тем же интерфейсом
  • на каждый ключ сессии ACP менеджер владеет одним актором в памяти (сериализованное выполнение команд)
  • адаптеры (acpx, будущие бэкенды) — это только реализации транспорта/среды выполнения

Долгосрочная модель персистентности:

  • переместить состояние плоскости управления ACP в выделенное хранилище SQLite (режим WAL) в каталоге состояния OpenClaw
  • сохранить SessionEntry.acp как проекцию для совместимости во время миграции, а не как источник истины
  • хранить события ACP только для добавления, чтобы поддерживать воспроизведение, восстановление после сбоев и детерминированную доставку

Стратегия доставки (мост к конечной цели)

  • краткосрочный мост
    • сохранить текущую механику привязки потоков и существующую конфигурационную поверхность ACP
    • исправить баги с пробелами в метаданных и маршрутизировать ходы ACP через единую ветку ACP в ядре
    • немедленно добавить ключи идемпотентности и проверки маршрутизации с отказом при закрытии
  • долгосрочный переход
    • переместить источник истины ACP в БД плоскости управления + акторы
    • сделать доставку в привязанный поток чисто основанной на проекции событий
    • удалить устаревшее поведение fallback, зависящее от оппортунистических метаданных session-entry

Почему не только плагин

Текущие хуки плагинов недостаточны для сквозной маршрутизации сессий ACP без изменений в ядре.

  • входящая маршрутизация из привязки потока сначала разрешается в ключ сессии в основном диспетчере ядра
  • хуки сообщений являются fire-and-forget и не могут прервать основной путь ответа
  • команды плагинов хороши для операций управления, но не для замены основного потока диспетчеризации на ход

Результат:

  • среда выполнения ACP может быть плагинизирована
  • ветка маршрутизации ACP должна существовать в ядре

Существующий фундамент для повторного использования

Уже реализовано и должно оставаться каноническим:

  • цель привязки потока поддерживает subagent и acp
  • переопределение входящей маршрутизации потока разрешается привязкой перед обычной диспетчеризацией
  • идентичность исходящего потока через вебхук в доставке ответа
  • поток /focus и /unfocus с совместимостью цели ACP
  • постоянное хранилище привязок с восстановлением при запуске
  • жизненный цикл отвязки при архивации, удалении, снятии фокуса, сбросе и удалении

Этот план расширяет этот фундамент, а не заменяет его.

Архитектура

Модель границ

Ядро (должно быть в ядре OpenClaw):

  • ветка диспетчеризации режима сессии ACP в конвейере ответов
  • арбитраж доставки для избежания дублирования родительского канала и потока
  • персистентность плоскости управления ACP (с проекцией совместимости SessionEntry.acp во время миграции)
  • семантика отвязки жизненного цикла и отсоединения среды выполнения, привязанная к сбросу/удалению сессии

Бэкенд плагина (реализация acpx):

  • супервизия рабочих процессов среды выполнения ACP
  • вызов процесса acpx и парсинг событий
  • обработчики команд ACP (/acp ...) и UX оператора
  • значения по умолчанию и диагностика, специфичные для бэкенда

Модель владения средой выполнения

  • один процесс шлюза владеет состоянием оркестрации ACP
  • выполнение ACP запускается в дочерних процессах под супервизией через бэкенд acpx
  • стратегия процесса — долгоживущая на активный ключ сессии ACP, а не на сообщение

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

Контракт среды выполнения ядра

Добавить контракт среды выполнения ACP в ядро, чтобы код маршрутизации не зависел от деталей CLI и мог переключать бэкенды без изменения логики диспетчеризации:

export type AcpRuntimePromptMode = "prompt" | "steer";

export type AcpRuntimeHandle = {
  sessionKey: string;
  backend: string;
  runtimeSessionName: string;
};

export type AcpRuntimeEvent =
  | { type: "text_delta"; stream: "output" | "thought"; text: string }
  | { type: "tool_call"; name: string; argumentsText: string }
  | { type: "done"; usage?: Record<string, number> }
  | { type: "error"; code: string; message: string; retryable?: boolean };

export interface AcpRuntime {
  ensureSession(input: {
    sessionKey: string;
    agent: string;
    mode: "persistent" | "oneshot";
    cwd?: string;
    env?: Record<string, string>;
    idempotencyKey: string;
  }): Promise<AcpRuntimeHandle>;

  submit(input: {
    handle: AcpRuntimeHandle;
    text: string;
    mode: AcpRuntimePromptMode;
    idempotencyKey: string;
  }): Promise<{ runtimeRunId: string }>;

  stream(input: {
    handle: AcpRuntimeHandle;
    runtimeRunId: string;
    onEvent: (event: AcpRuntimeEvent) => Promise<void> | void;
    signal?: AbortSignal;
  }): Promise<void>;

  cancel(input: {
    handle: AcpRuntimeHandle;
    runtimeRunId?: string;
    reason?: string;
    idempotencyKey: string;
  }): Promise<void>;

  close(input: { handle: AcpRuntimeHandle; reason: string; idempotencyKey: string }): Promise<void>;

  health?(): Promise<{ ok: boolean; details?: string }>;
}

Деталь реализации:

  • первый бэкенд: AcpxRuntime, поставляемый как сервис плагина
  • ядро разрешает среду выполнения через реестр и завершается с явной ошибкой оператора, когда бэкенд среды выполнения ACP недоступен

Модель данных плоскости управления и персистентность

Долгосрочный источник истины — выделенная база данных ACP SQLite (режим WAL) для транзакционных обновлений и безопасного восстановления после сбоев:

  • acp_sessions
    • session_key (pk), backend, agent, mode, cwd, state, created_at, updated_at, last_error
  • acp_runs
    • run_id (pk), session_key (fk), state, requester_message_id, idempotency_key, started_at, ended_at, error_code, error_message
  • acp_bindings
    • binding_key (pk), thread_id, channel_id, account_id, session_key (fk), expires_at, bound_at
  • acp_events
    • event_id (pk), run_id (fk), seq, kind, payload_json, created_at
  • acp_delivery_checkpoint
    • run_id (pk/fk), last_event_seq, last_discord_message_id, updated_at
  • acp_idempotency
    • scope, idempotency_key, result_json, created_at, unique (scope, idempotency_key)
export type AcpSessionMeta = {
  backend: string;
  agent: string;
  runtimeSessionName: string;
  mode: "persistent" | "oneshot";
  cwd?: string;
  state: "idle" | "running" | "error";
  lastActivityAt: number;
  lastError?: string;
};

Правила хранения:

  • сохранить SessionEntry.acp как проекцию для совместимости во время миграции
  • идентификаторы процессов и сокеты остаются только в памяти
  • устойчивый жизненный цикл и статус выполнения живут в БД ACP, а не в общем JSON сессии
  • если владелец среды выполнения умирает, шлюз перегидратирует из БД ACP и возобновит работу с контрольных точек

Маршрутизация и доставка

Входящая:

  • сохранить текущий поиск привязки потока как первый шаг маршрутизации
  • если привязанная цель — сессия ACP, маршрутизировать в ветку среды выполнения ACP вместо getReplyFromConfig
  • явная команда /acp steer использует mode: "steer"

Исходящая:

  • поток событий ACP нормализуется в чанки ответов OpenClaw
  • цель доставки разрешается через существующий путь привязанного назначения
  • когда для этого хода сессии активен привязанный поток, завершение в родительском канале подавляется

Политика стриминга:

  • стримить частичный вывод с окном объединения
  • настраиваемый минимальный интервал и максимальное количество байт в чанке, чтобы оставаться в пределах лимитов скорости Discord
  • финальное сообщение всегда отправляется при завершении или сбое

Конечные автоматы и границы транзакций

Конечный автомат сессии:

  • creating -> idle -> running -> idle
  • running -> cancelling -> idle | error
  • idle -> closed
  • error -> idle | closed

Конечный автомат запуска:

  • queued -> running -> completed
  • running -> failed | cancelled
  • queued -> cancelled

Необходимые границы транзакций:

  • транзакция создания
    • создать строку сессии ACP
    • создать/обновить строку привязки потока ACP
    • поставить в очередь строку начального запуска
  • транзакция закрытия
    • пометить сессию закрытой
    • удалить/истечь строки привязок
    • записать финальное событие закрытия
  • транзакция отмены
    • пометить целевой запуск отменяемым/отмененным с ключом идемпотентности

Частичный успех через эти границы не допускается.

Модель акторов на сессию

AcpSessionManager запускает один актор на ключ сессии ACP:

  • почтовый ящик актора сериализует побочные эффекты submit, cancel, close и stream
  • актор владеет гидратацией хендла среды выполнения и жизненным циклом процесса адаптера среды выполнения для этой сессии
  • актор записывает события запуска по порядку (seq) до любой доставки в Discord
  • актор обновляет контрольные точки доставки после успешной отправки

Это устраняет гонки между ходами и предотвращает дублирование или вывод в неправильном порядке.

Идемпотентность и проекция доставки

Все внешние действия ACP должны нести ключи идемпотентности:

  • ключ идемпотентности создания
  • ключ идемпотентности промпта/управления
  • ключ идемпотентности отмены
  • ключ идемпотентности закрытия

Правила доставки:

  • сообщения Discord выводятся из acp_events плюс acp_delivery_checkpoint
  • повторные попытки возобновляются с контрольной точки без повторной отправки уже доставленных чанков
  • финальная эмиссия ответа — ровно один раз за запуск из логики проекции

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

При запуске шлюза:

  • загрузить нетерминальные сессии ACP (creating, idle, running, cancelling, error)
  • пересоздать акторов лениво при первом входящем событии или активно в пределах настроенного лимита
  • согласовать любые running запуски, пропустившие heartbeat, и пометить failed или восстановить через адаптер

При входящем сообщении в поток Discord:

  • если привязка существует, но сессия ACP отсутствует, завершиться с ошибкой с явным сообщением об устаревшей привязке
  • опционально автоматически отвязать устаревшую привязку после безопасной для оператора валидации
  • никогда не маршрутизировать устаревшие привязки ACP в обычный путь LLM молча

Жизненный цикл и безопасность

Поддерживаемые операции:

  • отменить текущий запуск: /acp cancel
  • отвязать поток: /unfocus
  • закрыть сессию ACP: /acp close
  • автоматическое закрытие простаивающих сессий по эффективному TTL

Политика TTL:

  • эффективный TTL — минимум из
    • глобального/сессионного TTL
    • TTL привязки потока Discord
    • TTL владельца среды выполнения ACP

Элементы управления безопасностью:

  • разрешительный список ACP-агентов по имени
  • ограничение корней рабочего пространства для сессий ACP
  • разрешительный список переменных окружения для передачи
  • максимальное количество одновременных сессий ACP на аккаунт и глобально
  • ограниченный откат перезапуска при сбоях среды выполнения

Конфигурационная поверхность

Ключи ядра:

  • acp.enabled
  • acp.dispatch.enabled (независимый выключатель маршрутизации ACP)
  • acp.backend (по умолчанию acpx)
  • acp.defaultAgent
  • acp.allowedAgents[]
  • acp.maxConcurrentSessions
  • acp.stream.coalesceIdleMs
  • acp.stream.maxChunkChars
  • acp.runtime.ttlMinutes
  • acp.controlPlane.store (sqlite по умолчанию)
  • acp.controlPlane.storePath
  • acp.controlPlane.recovery.eagerActors
  • acp.controlPlane.recovery.reconcileRunningAfterMs
  • acp.controlPlane.checkpoint.flushEveryEvents
  • acp.controlPlane.checkpoint.flushEveryMs
  • acp.idempotency.ttlHours
  • channels.discord.threadBindings.spawnAcpSessions

Ключи плагина/бэкенда (раздел плагина acpx):

  • переопределения команды/пути бэкенда
  • разрешительный список переменных окружения бэкенда
  • предустановки бэкенда на агента
  • таймауты запуска/остановки бэкенда
  • максимальное количество активных запусков на сессию для бэкенда

Спецификация реализации

Модули плоскости управления (новые)

Добавить выделенные модули плоскости управления ACP в ядро:

  • src/acp/control-plane/manager.ts
    • владеет акторами ACP, переходами жизненного цикла, сериализацией команд
  • src/acp/control-plane/store.ts
    • управление схемой SQLite, транзакции, вспомогательные запросы
  • src/acp/control-plane/events.ts
    • типизированные определения событий ACP и сериализация
  • src/acp/control-plane/checkpoint.ts
    • устойчивые контрольные точки доставки и курсоры воспроизведения
  • src/acp/control-plane/idempotency.ts
    • резервирование ключей идемпотентности и воспроизведение ответов
  • src/acp/control-plane/recovery.ts
    • согласование при загрузке и план перегидратации акторов

Мостовые модули совместимости:

  • src/acp/runtime/session-meta.ts
    • временно остается для проекции в SessionEntry.acp
    • должен перестать быть источником истины после перехода

Необходимые инварианты (должны быть обеспечены в коде)

  • создание сессии ACP и привязка потока атомарны (одна транзакция)
  • не более одного активного запуска на актор сессии ACP одновременно
  • seq события строго возрастает на запуск
  • контрольная точка доставки никогда не продвигается дальше последнего зафиксированного события
  • воспроизведение идемпотентности возвращает предыдущий успешный результат для дублирующихся ключей команд
  • устаревшие/отсутствующие метаданные ACP не могут маршрутизироваться в обычный путь ответа, не относящийся к ACP

Точки касания ядра

Файлы ядра для изменения:

  • src/auto-reply/reply/dispatch-from-config.ts
    • ветка ACP вызывает AcpSessionManager.submit и доставку проекции событий
    • удалить прямой fallback ACP, обходящий инварианты плоскости управления
  • src/auto-reply/reply/inbound-context.ts (или ближайшая граница нормализованного контекста)
    • предоставить нормализованные ключи маршрутизации и семена идемпотентности для плоскости управления ACP
  • src/config/sessions/types.ts
    • сохранить SessionEntry.acp как поле совместимости только для проекции
  • src/gateway/server-methods/sessions.ts
    • сброс/удаление/архивация должны вызывать путь транзакции закрытия/отвязки менеджера ACP
  • src/infra/outbound/bound-delivery-router.ts
    • обеспечить поведение назначения с отказом при закрытии для ходов привязанной сессии ACP
  • src/discord/monitor/thread-bindings.ts
    • добавить вспомогательные функции валидации устаревших привязок ACP, подключенные к поискам плоскости управления
  • src/auto-reply/reply/commands-acp.ts
    • маршрутизировать создание/отмену/закрытие/управление через API менеджера ACP
  • src/agents/acp-spawn.ts
    • прекратить ad-hoc запись метаданных; вызывать транзакцию создания менеджера ACP
  • src/plugin-sdk/** и мост среды выполнения плагина
    • предоставить регистрацию бэкенда ACP и семантику здоровья чисто

Файлы ядра, которые явно не заменяются:

  • src/discord/monitor/message-handler.preflight.ts
    • сохранить поведение переопределения привязки потока как канонический разрешитель ключа сессии

API реестра среды выполнения ACP

Добавить модуль реестра в ядро:

  • src/acp/runtime/registry.ts

Необходимый API:

export type AcpRuntimeBackend = {
  id: string;
  runtime: AcpRuntime;
  healthy?: () => boolean;
};

export function registerAcpRuntimeBackend(backend: AcpRuntimeBackend): void;
export function unregisterAcpRuntimeBackend(id: string): void;
export function getAcpRuntimeBackend(id?: string): AcpRuntimeBackend | null;
export function requireAcpRuntimeBackend(id?: string): AcpRuntimeBackend;

Поведение:

  • requireAcpRuntimeBackend выбрасывает типизированную ошибку отсутствия бэкенда ACP, когда он недоступен
  • сервис плагина регистрирует бэкенд при start и отменяет регистрацию при stop
  • поиски среды выполнения доступны только для чтения и локальны для процесса

Контракт плагина среды выполнения acpx (деталь реализации)

Для первого производственного бэкенда (extensions/acpx), OpenClaw и acpx соединяются строгим контрактом команд:

  • идентификатор бэкенда: acpx
  • идентификатор сервиса плагина: acpx-runtime
  • кодирование хендла среды выполнения: runtimeSessionName = acpx:v1:<base64url(json)>
  • закодированные поля:
    • name (именованная сессия acpx; использует sessionKey OpenClaw)
    • agent (команда агента acpx)
    • cwd (корень рабочего пространства сессии)
    • mode (persistent | oneshot)

Сопоставление команд:

  • обеспечить сессию:
    • acpx --format json --json-strict --cwd <cwd> <agent> sessions ensure --name <name>
  • ход промпта:
    • acpx --format json --json-strict --cwd <cwd> <agent> prompt --session <name> --file -
  • отмена:
    • acpx --format json --json-strict --cwd <cwd> <agent> cancel --session <name>
  • закрытие:
    • acpx --format json --json-strict --cwd <cwd> <agent> sessions close <name>

Стриминг:

  • OpenClaw потребляет события ndjson из acpx --format json --json-strict
  • text => text_delta/output
  • thought => text_delta/thought
  • tool_call => tool_call
  • done => done
  • error => error

Патч схемы сессии

Патч SessionEntry в src/config/sessions/types.ts:

type SessionAcpMeta = {
  backend: string;
  agent: string;
  runtimeSessionName: string;
  mode: "persistent" | "oneshot";
  cwd?: string;
  state: "idle" | "running" | "error";
  lastActivityAt: number;
  lastError?: string;
};

Сохраняемое поле:

  • SessionEntry.acp?: SessionAcpMeta

Правила миграции:

  • фаза A: двойная запись (проекция acp + источник истины SQLite ACP)
  • фаза B: основное чтение из SQLite ACP, fallback-чтение из устаревшего SessionEntry.acp
  • фаза C: команда миграции заполняет отсутствующие строки ACP из валидных устаревших записей
  • фаза D: удалить fallback-чтение и оставить проекцию опциональной только для UX
  • устаревшие поля (cliSessionIds, claudeCliSessionId) остаются нетронутыми

Контракт ошибок

Добавить стабильные коды ошибок ACP и сообщения для пользователей:

  • ACP_BACKEND_MISSING
    • сообщение: Бэкенд среды выполнения ACP не настроен. Установите и включите плагин среды выполнения acpx.
  • ACP_BACKEND_UNAVAILABLE
    • сообщение: Бэкенд среды выполнения ACP в настоящее время недоступен. Попробуйте снова через мгновение.
  • ACP_SESSION_INIT_FAILED
    • сообщение: Не удалось инициализировать среду выполнения сессии ACP.
  • ACP_TURN_FAILED
    • сообщение: Ход ACP завершился неудачно до завершения.

Правила:

  • возвращать понятное для пользователя сообщение в потоке
  • логировать детальную ошибку бэкенда/системы только в журналах среды выполнения
  • никогда не переходить молча на обычный путь LLM, когда маршрутизация ACP была явно выбрана

Арбитраж дублирующейся доставки

Единое правило маршрутизации для ходов с привязкой ACP:

  • если для целевой сессии ACP и контекста инициатора существует активная привязка потока, доставлять только в этот привязанный поток
  • не отправлять также в родительский канал для того же хода
  • если выбор привязанного назначения неоднозначен, завершиться с ошибкой (без неявного fallback на родительский канал)
  • если активной привязки не существует, использовать обычное поведение назначения сессии

Наблюдаемость и операционная готовность

Необходимые метрики:

  • количество успешных/неудачных созданий ACP по бэкенду и коду ошибки
  • процентили задержки запуска ACP (ожидание в очереди, время хода среды выполнения, время проекции доставки)
  • количество перезапусков актора ACP и причина перезапуска
  • количество обнаружений устаревших привязок
  • частота попаданий воспроизведения идемпотентности
  • счетчики повторных попыток доставки Discord и ограничений скорости

Необходимые логи:

  • структурированные логи с ключами sessionKey, runId, backend, threadId, idempotencyKey
  • явные логи переходов состояний для конечных автоматов сессии и запуска
  • логи команд адаптера с безопасными для редактирования аргументами и сводкой выхода

Необходимая диагностика:

  • /acp sessions включает состояние, активный запуск, последнюю ошибку и статус привязки
  • /acp doctor (или эквивалент) проверяет регистрацию бэкенда, здоровье хранилища и устаревшие привязки

Приоритет конфигурации и эффективные значения

Приоритет включения ACP:

  • переопределение аккаунта: channels.discord.accounts.<id>.threadBindings.spawnAcpSessions
  • переопределение канала: channels.discord.threadBindings.spawnAcpSessions
  • глобальный выключатель ACP: acp.enabled
  • выключатель диспетчеризации: acp.dispatch.enabled
  • доступность бэкенда: зарегистрированный бэкенд для acp.backend

Поведение авто-включения:

  • когда ACP настроен (acp.enabled=true, acp.dispatch.enabled=true или acp.backend=acpx), авто-включение плагина помечает plugins.entries.acpx.enabled=true, если не запрещено или явно не отключено

Эффективное значение TTL:

  • min(сессионный ttl, ttl привязки потока discord, ttl среды выполнения acp)

Карта тестов

Модульные тесты:

  • src/acp/runtime/registry.test.ts (новый)
  • src/auto-reply/reply/dispatch-from-config.acp.test.ts (новый)
  • src/infra/outbound/bound-delivery-router.test.ts (расширить случаи отказа при закрытии ACP)
  • src/config/sessions/types.test.ts или ближайшие тесты хранилища сессий (персистентность метаданных ACP)

Интеграционные тесты:

  • src/discord/monitor/reply-delivery.test.ts (поведение цели доставки привязанного ACP)
  • src/discord/monitor/message-handler.preflight*.test.ts (непрерывность маршрутизации ключа сессии привязанного ACP)
  • тесты среды выполнения плагина acpx в пакете бэкенда (регистрация/запуск/остановка сервиса + нормализация событий)

E2e тесты шлюза:

  • src/gateway/server.sessions.gateway-server-sessions-a.e2e.test.ts (расширить покрытие жизненного цикла сброса/удаления ACP)
  • e2e тест цикла хода в потоке ACP для создания, сообщения, стриминга, отмены, снятия фокуса, восстановления после перезапуска

Защита развертывания

Добавить независимый выключатель диспетчеризации ACP:

  • acp.dispatch.enabled по умолчанию false для первого релиза
  • когда отключено:
    • команды управления созданием/фокусировкой ACP все еще могут привязывать сессии
    • путь диспетчеризации ACP не активируется
    • пользователь получает явное сообщение, что диспетчеризация ACP отключена политикой
  • после валидации canary значение по умолчанию может быть изменено на true в более позднем релизе

План команд и UX

Новые команды

  • /acp spawn <agent-id> [--mode persistent|oneshot] [--thread auto|here|off]: создает новую ACP сессию с указанным агентом