# Руководство разработчика [简体中文](./development.md) | [English](./development_en.md) | [日本語](./development_ja.md) | [한국어](./development_ko.md) | Русский | [Español](./development_es.md) | [Português (Brasil)](./development_pt.md) Это руководство для тех, кто хочет запускать AnyModelBot из исходников, собирать пакеты или участвовать в разработке. Для обычного использования скачайте установщик из [выпусков](https://github.com/modelflare-ai/AnyModelBot/releases); см. [README](../README_ru.md#-скачать-и-запустить). - Бот — это характер и роль, модель по умолчанию и память. Аккаунты глобальные («Настройки › Каналы чата»), общие для всех ботов; для каждого сервиса можно добавить сколько угодно. Приложение рассчитано на личное использование одним человеком. - Модели доступны через аккаунт Modelflare или ваши официальные API-ключи. [Modelflare](https://modelflare.dev/?utm_source=anymodelbot&utm_campaign=amb_readme). При первом запуске войдите или зарегистрируйтесь, и модели появятся автоматически. Запросы идут через встроенный шлюз [magpie](https://github.com/yetone/magpie). - Три способа запуска с одной кодовой базой: **настольное приложение Electron**, **командная строка `npm start`**, **Docker**. ## Структура репозитория ```text src/ core/ общие типы сообщений, очередь и дедупликация сеансов, выполнение /model и /reset, потоковые ответы, уведомление после перезапуска, владелец и список доступа, постоянная очередь исходящих delivery/ доставка проактивных сообщений: тихие часы, дневные лимиты, сводки, 24-часовое окно WeChat и напоминания о продлении agent/ режим агента: хост и мост DSH, разрешения, режимы доступа, память и управление контекстом, каталоги сеансов DSH prompts/ все инструкции для модели: личность, правила чата, память, первое сообщение сегмента, навыки tools/ возможности агента: веб-поиск (search.ts), изображения и видео (media/), управление компьютером (computer-use/), Windows PowerShell (pwsh/), подключение приложений — встроенные коннекторы и пользовательские MCP (apps/), существующие аккаунты Notion / Feishu (accounts/) llm/ клиент, совместимый с OpenAI, для доступа к моделям magpie/ супервизор magpie: изолированные каталоги, свободный порт, случайный секрет, проверки здоровья, перезапуск после сбоя, корректное завершение channels/ feishu/ (постоянное соединение и CardKit), weixin/ (iLink; MIT в LICENSE.openclaw-weixin), messenger/ (общий путь отправки и приёма Telegram, Slack, Discord) tasks/ фоновые задачи и правила: запуски, этапы, стоимость, хранение и очистка, расписания botkit/ фреймворк ботов из каталога: формат пакета, проверки, упаковка и подпись, каталог, установка, статические маршруты интерфейса (см. docs/bot-framework.md) skills/ навыки, которые пользователь устанавливает сам (ZIP-пакеты) store/ SQLite (node:sqlite, без нативной сборки) domain/ Чистые структуры данных и правила: настройки бота, тихие часы, расписания, записи ботов из каталога, шаги агента; без I/O, зависит только от i18n. store зависит только от него (направление зависимостей проверяет test/architecture.unit.test.ts) account/ Modelflare: вход PKCE через loopback, обновление токенов, баланс и уведомления, бюджетные ключи ботов, возможности и цены моделей web/ сервер консоли: server.ts запускает, проверяет доступ и распределяет запросы; routes/ — API по областям (JSON API и потоковый чат по SSE); http.ts — общие вспомогательные функции cli/ первоначальная настройка init, weixin-login providers/ откуда берутся модели: modelflare.ts (маршруты, проверка ключей GET /v1/models, маршрутизация и атрибуция), modelflare-domains.ts (замер скорости маршрутов), official.ts (таблица официальных API, адреса зафиксированы) updates/ обновления: check.ts (проверка новой версии), desktop.ts (загрузка и перезапуск настольной версии) guide.ts прогресс первых шагов i18n/ локализация сервера: ошибки, состояние, меню трея, системные сообщения ботов (messages/.ts) diagnostics.ts пробы, последние журналы, диагностический отчёт без секретов version.ts версия приложения (package.json) main.ts точка входа CLI electron/ основной процесс настольного приложения: запуск и трей ui/ интерфейс консоли: Preact + htm, без сборки design/ дизайн-система: tokens/, base/, components/, персонажи bots/ locales/ строки интерфейса: zh-CN/ и en/, файл на пространство имён css/ lib/ components/ screens/ assets/ main.js dsh-runtime/ манифест зависимостей среды DSH и плагины AnyModelBot (plugins/) scripts/ setup / build-magpie / fetch-cua-driver / prepare-dsh / bundle-dsh / electron-smoke / check-readme и другие vendor/ подмодули git: magpie (собирается при сборке), deepseek-harness, kimi-computer-use site/ сайт на Astro; см. site/README.md docs/ руководство разработчика, приватность, материалы README (docs/assets/) ``` ## Запуск из исходников через командную строку Требуются Node.js 22.13+ и Go 1.26.8+ для сборки magpie. ```bash npm install npm run setup # получить подмодуль vendor/magpie и собрать в build/bin/ npm run init # необязательно: настройка в терминале — вход Modelflare, данные Feishu npm start # шлюз, боты и консоль http://127.0.0.1:3600/ ``` По умолчанию данные находятся в `./data`; изменить можно через `AMB_DATA_DIR`. Остальные переменные перечислены в `.env.example`. ## Настольное приложение Electron ```bash npm run electron:dev # режим разработки npm run electron:smoke # базовая проверка; в Linux без экрана автоматически используется xvfb-run npm run dist # пакет для текущей платформы; magpie помещается в resources/magpie/ npm run dist:linux | dist:mac | dist:win npm run test:dsh-bundle # настоящий DSH под Electron с упакованным build/dsh; сначала prepare:dsh и bundle:dsh ``` - Среда DSH: `scripts/prepare-dsh.mjs` устанавливает `dsh-runtime/` для целевой платформы; `scripts/bundle-dsh.mjs` собирает `resources/dsh/dsh.asar` со всем JavaScript в одном файле и `resources/dsh/node_modules/` только с нативными пакетами, около 55 файлов. Основной процесс Electron и дочерние процессы `ELECTRON_RUN_AS_NODE` читают asar напрямую без распаковки при первом запуске. Поэтому установщик распаковывает лишь несколько сотен файлов: в Windows распаковка и антивирусная проверка каждого файла — главные причины медленной установки. Разработка по-прежнему использует `dsh-runtime/` напрямую. - PowerShell для команд агента в Windows: внутри песочницы Windows PowerShell 5.1 тратит 20–30 секунд на команду, PowerShell 7 — около секунды. Приоритет: рабочий системный PowerShell 7, однократно проверенный в фоне способом DSH без скачивания; затем собственный PowerShell 7 приложения; затем Windows PowerShell 5.1. Если рабочего 7 нет и агент включён, приложение в фоне скачивает официальный архив PowerShell 7.6.9 LTS в `%LOCALAPPDATA%\AnyModelBot\pwsh\`. Не нужны права администратора, не меняются реестр, PATH и ваш PowerShell. Версия и SHA256 архивов x64/arm64 закреплены в `src/tools/pwsh/private.ts`; обновление — `node scripts/pwsh-hashes.mjs `. После скачивания проверяется хеш, после распаковки — Authenticode-подпись Microsoft. Использование начинается только после пробы в стиле DSH: версия, запись и чтение временного файла, запуск внешней программы. Неудачные или неполные установки не используются и очищаются при следующем запуске. Прогресс виден в чате, «Настройки → Основные» и `/status`. До готовности используется 5.1, затем свободные процессы агента переключаются в фоне без перезапуска приложения. Если запуск перестал работать из-за удаления, карантина антивируса или политики, приложение возвращается к предыдущему варианту и объясняет причину. Раздел «Настройки → Диагностика» позволяет установить, переустановить или вернуть системный вариант. В системах старше Windows 10 1607 / Server 2016 ничего не скачивается. Настольное приложение использует системный прокси через сетевой стек Chromium; CLI — Node fetch, который в новых Node учитывает `HTTPS_PROXY` при `NODE_USE_ENV_PROXY=1`. `AMB_PWSH_MIRROR` задаёт префикс зеркала с сохранением проверки хеша и подписи; `AMB_PWSH_AUTO_INSTALL=0` отключает автоустановку. - Команды агента имеют доступ к сети; песочница ограничивает запись. Из окружения приложения передаются прокси `HTTP_PROXY` / `HTTPS_PROXY` / `ALL_PROXY` / `NO_PROXY`, их варианты в нижнем регистре, а также переменные сертификатов и индексов пакетов: `SSL_CERT_FILE`, `REQUESTS_CA_BUNDLE`, `NODE_EXTRA_CA_CERTS`, `PIP_INDEX_URL`, `npm_config_registry`, `GOPROXY` и другие. Если прокси не задан, настольное приложение при каждом запуске процесса агента получает системный прокси, включая PAC, и передаёт его как `http://host:port`; см. `src/agent/proxy-env.ts`. Loopback-адреса `127.0.0.1`, `localhost`, `::1` всегда добавлены в `NO_PROXY` и не проксируются. - Папка данных: `/data`; macOS — `~/Library/Application Support/anymodel bot/data`, Windows — `%APPDATA%\anymodel bot\data`, Linux — `~/.config/anymodel bot/data`. Журналы — в `logs/app.log` внутри неё. - Один экземпляр приложения. Закрытие окна по умолчанию скрывает его в трей; «Настройки → Основные» позволяют вместо этого выходить. Меню трея: открыть, открыть в браузере, запускать при входе в macOS/Windows, открыть папку данных, выйти. - В macOS нет полосы заголовка, оконные кнопки находятся вверху боковой панели; минимальная ширина окна — 860. - Консоль слушает только 127.0.0.1 и создаёт случайный токен при каждом запуске, чтобы другие локальные программы не вызывали API управления напрямую. - При выходе сначала останавливаются каналы, затем magpie. Если после принудительного завершения остался процесс magpie, следующий запуск удалит его в Linux/macOS. Для выпуска добавьте запись версии в `CHANGELOG.md`, `CHANGELOG_en.md`, `CHANGELOG_ja.md`, `CHANGELOG_ko.md`, `CHANGELOG_ru.md`, `CHANGELOG_es.md` и `CHANGELOG_pt.md`: заметные пользователю изменения, без сайта и внутренних деталей. Английская страница сайта пропускает строки с упоминанием WeChat или Feishu. Обновите `version` в `package.json`, создайте коммит и отправьте тег `v`. Без записи процесс выпуска сразу завершится ошибкой; при её наличии текст становится примечаниями GitHub Release и страницей изменений сайта. Тот же текст показывает окно «Что нового» в приложении: `CHANGELOG*.md` входит в установщики и Docker-образ (`src/changelog.ts`), а описание ещё не установленной версии загружается из её тега, когда пользователь его открывает. `.github/workflows/release.yml` собирает установщики на шести сочетаниях ОС и архитектуры и публикует их вместе с `SHA256SUMS`. Секреты для подписи и нотариализации описаны в комментарии в начале файла. Тот же тег запускает `.github/workflows/docker.yml`, публикующий x64/arm64-образ в `ghcr.io/modelflare-ai/anymodel-bot` с тегами `` и `latest`. При выпуске по тегу установщики macOS обязаны иметь подпись Developer ID и нотаризацию: после сборки .app и .app внутри DMG проверяются `spctl` и другими средствами, иначе запуск завершается ошибкой. В выпускных сборках инструменты разработчика выключены; для отладочной сборки используйте `npm run dist:debug` или отметьте `debug_build` при ручном запуске Release (в именах файлов есть `-debug-`, на тегах это запрещено, а `scripts/check-build-flavor.mjs` проверяет собранный результат). При каждом выпуске обновляйте сайт, связанную документацию и README на всех языках. Выполните `npm --prefix site run sync`, а после публикации GitHub Release и Docker-образа обновите рабочий сайт по [инструкции развёртывания](../site/README.md). Проверьте соответствие версии, ссылок загрузки и описаний на `/download`, `/changelog` и `/bots`. Выпуск завершён только после обновления рабочего сайта. Обновления из приложения доступны с 0.1.29 через `electron-updater` в установленных сборках macOS, Windows и Linux AppImage. Параметр `ui.autoDownloadUpdates` по умолчанию равен `true` и меняется в «Настройки → Общие». Скачивание только вызывает уведомление; обычный выход не устанавливает обновление. Перед перезапуском проверяются активные чаты и фоновые задачи. Пользователям 0.1.28 и более ранних версий нужна однократная ручная установка версии с обновлятором. GitHub создаёт DMG и ZIP для macOS, метаданные `latest-${arch}` по архитектурам и blockmap, публикуя Release только после загрузки всех файлов. CLI, Docker и запуск из исходников обновляются вручную. ## Docker Готовый образ запускается командой `docker run -d --name amb -p 3600:3600 -v amb-data:/data ghcr.io/modelflare-ai/anymodel-bot`. Самостоятельная сборка: ```bash git submodule update --init --depth 1 vendor/magpie docker build -t anymodel-bot . docker run -d --name amb -p 3600:3600 -v amb-data:/data anymodel-bot docker exec amb cat /data/ui-token # откройте http://:3600/?token= ``` В контейнере консоль слушает 0.0.0.0, поэтому токен обязателен. Не открывайте порт 3600 напрямую в интернет. Вход WeChat по QR-коду находится в разделе «Настройки › Каналы чата». ## Модели и Modelflare - При первом запуске показана кнопка «Войти / Зарегистрироваться в Modelflare». Войдите в системном браузере, при необходимости зарегистрируйтесь, и нажмите Continue для авторизации. После возврата приложению выдаётся отдельный API-ключ компьютера; выберите модель по умолчанию и начинайте общение. Docker и удалённые установки не принимают обратный вызов браузера: после входа браузер переходит на неоткрывающийся адрес `127.0.0.1`, и эту ссылку нужно вставить на экране первого запуска (`POST /amb/api/account/login/complete`, проверки state и PKCE те же). Если в старой версии был введён API-ключ без входа, при обновлении ключ удаляется с устройства и нужно войти. Страница обратного вызова в браузере сначала показывает «Завершаем вход» и сообщает «Вход выполнен» только после того, как обмен токенов, чтение аккаунта, выпуск ключа устройства и подключение шлюза прошли успешно (иначе показывает причину). Настольное приложение регистрирует ссылку `anymodelbot://`: страница один раз пытается открыть приложение при загрузке, кнопка «Открыть AnyModelBot» позволяет повторить, а «Вы вернулись» появляется, только когда приложение действительно получило эту ссылку. Со страницы собственного API-ключа тоже можно сразу войти аккаунтом Modelflare. При первом подключении, пока глобальная модель по умолчанию не задана, модель для первого знакомства выбирается один раз по правилу из `src/account/first-model.ts` (поддержка инструментов; резерв на запрос и типичная задача укладываются в пробный баланс; предпочтение DeepSeek). Если подходящей нет, ничего не выбирается, и пользователь выбирает сам. - Вход: OIDC authorization code + PKCE (RFC 7636) для нативных приложений по RFC 8252. Приложение — публичный клиент с `client_id` `anymodel-bot`, без клиентского секрета. Результат приходит на временный порт `127.0.0.1`. Доступ можно отозвать в разделе авторизованных приложений профиля Modelflare; приложение обнаружит это и вернёт экран входа. - Учётные данные аккаунта, то есть refresh token, хранятся в `modelflare-account.json` в папке данных с правами 600 и, как API-ключи встроенного шлюза, защищены только правами доступа к файлу; системная связка ключей не используется (файл, зашифрованный настольным приложением версии 0.1.30 или раньше, при первом чтении перезаписывается без шифрования). Интерфейс получает только имя аккаунта. Выход отзывает авторизацию компьютера; Modelflare удаляет ключи, выданные ему и его ботам при входе. - Баланс не занимает постоянное место на экране. Нажмите аватар внизу слева или откройте «Настройки → Модели». Оба показывают баланс кошелька. «Пополнить» открывает сайт Modelflare; при возврате баланс обновляется. Ниже порога, по умолчанию 1 доллар США, настраиваемого или отключаемого, приложение напоминает один раз и может отправить сообщение через бота в WeChat/Feishu. - После входа «Настройки → Модели» также показывают расходы по дням и моделям, уведомления и ссылку-приглашение. - Бюджет бота требует входа: «Настройки бота → Бюджет». При включении используется собственный ключ бота, отдельный поставщик в шлюзе, с заданным долларовым лимитом. При отключении возвращается общий ключ. - Глубина рассуждений: выбирается в панели выбора модели или в «Настройки → Модели» (Авто / Низкая / Средняя / Высокая). Это одна глобальная настройка, она действует со следующего хода. В режиме «Авто» параметр не отправляется и используется значение модели по умолчанию. Действует только на поддерживающие модели: модели с рассуждениями в Responses API, а также модели Chat и Claude, отмеченные как рассуждающие в профиле (Claude 4.6 и новее используют adaptive с `output_config.effort`, более ранние — `budget_tokens`). - Изображения и видео: в режиме агента доступны `media_models` — модели, значения по умолчанию, диапазоны параметров и цены; `media_docs` — получение актуального формата из docs.modelflare.dev; `generate_image` и `generate_video`, а также встроенный навык работы с медиа. Форматы различаются, поэтому тело запроса составляется по документации; образцы из рабочей папки указываются как `workspace:path`. Ключ остаётся внутри приложения: оно вызывает Modelflare ключом бота, сохраняет результат в `media/` его рабочей папки и доставляет в чат. - Подтверждение генерации: изображение или видео создаётся сразу. Другая модель или неточный запрос не требуют вопроса: бот выбирает разумное толкование, создаёт и кратко сообщает выбор. Чат предлагает выбрать модель с запросом, параметрами, ценой и причиной вопроса, только если оценка выше $0.5. Учитываются цена, количество изображений, длительность и разрешение видео; неоценимая стоимость видео тоже требует подтверждения. Можно подтвердить, сменить модель или отменить: в WeChat — номером или именем, в Feishu и веб-консоли — кнопкой. Без ответа за 10 минут генерация отменяется. Для постоянного подтверждения: «Настройки бота → Изображения и видео → Подтверждать перед созданием → Всегда». - Веб-поиск: `web_search` агента не использует встроенный поиск DeepSeek, которому нужен ключ DeepSeek. Плагин `amb-web-search` передаёт запрос приложению. По умолчанию поиск бесплатен и не требует настройки: публичный MCP Exa, Bing и DuckDuckGo пробуются по очереди, последний успешный — первым. Сервис с ошибкой лимита, проверкой бота или нерелевантными результатами Bing пропускается на 10 минут. «Настройки → Сеть и доступ → Поиск в интернете» позволяют выбрать Tavily, Exa, Bocha, Zhipu с ключом или свой SearXNG. Настроенный сервис пробуется первым, при неудаче используется бесплатный. Ключи хранятся в локальной БД, как токены каналов, и не попадают в процесс агента. Настольная версия использует системный прокси, CLI — Node fetch с `HTTPS_PROXY` при `NODE_USE_ENV_PROXY=1`. - Аккаунты каналов (`src/core/routes.ts`) — WeChat, Feishu, Telegram, Slack, Discord — тоже глобальны, добавляются в «Настройки › Каналы чата» и могут иметь имена. Сообщение направляется боту, выбранному пользователем через `/bot`, затем боту аккаунта по умолчанию, затем первому боту. `/bot` показывает список, `/bot name` переключает и запоминает выбор. Системная инструкция каждого бота перечисляет остальных и способ переключения. Владелец и доступ относятся к аккаунту, поэтому разрешённый пользователь может общаться с любым ботом. Ключ аккаунта — пространство имён: старые каналы сохраняют прежний ID бота как ключ, чтобы не перемещать входы, квоты, доступ и очереди; бот по умолчанию не меняется. Удаление бота не затрагивает аккаунты. - Подключение приложений (`src/tools/apps/service.ts`) — единый глобальный список (меню аватара › «Подключить приложения»). По умолчанию все боты могут пользоваться подключёнными приложениями; доступ можно сузить по ботам и по инструментам (настройки бота › «Приложения»). У приложения одна карточка на странице приложений и может быть несколько учётных записей — любому боту можно сказать «проверь мой первый и второй Feishu»; учётная запись выбирается аргументом `account` инструмента (номер или имя). - **Встроенные приложения** (`catalog.ts`): Feishu, Tencent Docs, DingTalk, Amap, Yuque, Notion, GitHub, Linear, Atlassian, Canva. Способы аутентификации те же, что у пользовательских коннекторов: вход с авторизацией (OAuth с динамической регистрацией, `oauth.ts`), заголовки запроса, параметры запроса, персональный URL. Yuque — локальная программа, поставляемая вместе с приложением (`vendor/yuque-mcp`, создаётся скриптом `scripts/vendor-yuque-mcp.mjs`); пользователь только вставляет токен. - **Пользовательские коннекторы**: удалённый Streamable HTTP (при неудаче — устаревший SSE) или локальная команда, не более 20. Распознавание вставленного текста и преобразование форма ⇄ JSON находятся в `ui/lib/connector-config.js`. Локальные команды запускаются с PATH из оболочки входа (`shell-path.ts`); программам запуска пакетов (npx, uvx) при первом старте, когда пакет ещё скачивается, даётся больше времени. - **Подключается основной процесс** (`mcp-client.ts`, официальный `@modelcontextprotocol/client`): учётные данные остаются в основном процессе и хранятся в `app-secrets.json` (права 600, вне базы данных, `secrets.ts`); плагин `amb-connections` передаёт каждый вызов инструмента приложению через bridge. Инструменты подключений MCP не регистрируются по одному — модель получает три постоянных инструмента: `app_tools` (найти инструмент), `app_tool_schema` (посмотреть параметры), `app_call` (выполнить), а также `app_connect`, чтобы попросить пользователя подключить приложение (в чате появляется карточка, после подключения задача продолжается). - **Подтверждение** (`gate` в `service.ts`; запрос к пользователю — в `agent/manager.ts`): чтение выполняется сразу; запись зависит от уровня прав бота (ботам только для чтения не предоставляется, на уровне по умолчанию сначала спрашивается с возможностью «всегда разрешать этот инструмент», при полном доступе выполняется сразу); удаление и отправка наружу всегда требуют подтверждения; правила «только наблюдение» не могут записывать. Тип инструмента определяется в `classify.ts`: для встроенных приложений — встроенная таблица и официальные аннотации, а аннотации пользовательского коннектора служат лишь начальным значением, которое пользователь может изменить. - **Существующие аккаунты Notion и Feishu** (`src/tools/accounts/`): подключённые до обновления продолжают работать без повторной авторизации; при первом запуске их токены переносятся из базы данных в `app-secrets.json`. Notion (`notion.ts`) — авторизация одним нажатием или токен: токен использует REST API, авторизация одним нажатием — OAuth + PKCE + динамическая регистрация с возвратом на локальный `/oauth/notion/callback` и вызовом официального удалённого MCP (`mcp.notion.com`); модель по-прежнему видит `notion_search`, `notion_read_page`, `notion_query_database`, `notion_create_page` и `notion_update_page`, удаления нет. Существующие аккаунты Feishu (`feishu.ts`) читают сообщения от имени пользователя (`feishu_list_chats`, `feishu_read_chat`, `feishu_search_messages`); новые аккаунты Feishu используют официальный удалённый MCP (чтение и запись облачных документов плюс чтение сообщений), и существующий аккаунт переходит на него при повторной авторизации. - Модели изображений и видео по умолчанию выбираются вместе с текстовой при настройке, позже меняются в «Настройки → Модели». «Авто» берёт первую модель в рекомендованном порядке, не требующую образца. - Список моделей показывает контекст, зрение, инструменты, рассуждения и начальную цену за миллион входных/выходных токенов из открытого каталога; окончательна сумма счёта. - Выгода требует входа: ключи приложения, компьютера и ботов, несут стратегию Smart Key `routing_strategy`: «Экономия» — `low_cost`, сначала группа с наименьшим множителем; «Баланс» — `balanced`, по умолчанию, начиная со средней цены; «Качество» — `stable`, сначала наибольший множитель. Меняется в «Настройки → Модели → Выгода» или первым ползунком выбора модели; существующие ключи обновляются через `PATCH /api/connected-app/api-keys/`, выбор хранится в `account.routing` локальной БД. Для вошедших пользователей без явного выбора «Баланс» применяется к старым ключам один раз при первой проверке с записью `applied the default key routing strategy` в журнал. Поддержка признаётся только если Modelflare возвращает `routing_strategy`. При отклонении поля с 400/422 ключ выпускается заново без него, чтобы не ломать выпуск, проверки и бюджеты. Игнорирование без возвращённого поля тоже означает отсутствие поддержки: настройка скрывается, повторная проверка через день. - Интеллект, второй ползунок: из доступных моделей с данными Artificial Analysis строится граница Парето по индексу интеллекта, где больше лучше, и стоимости задачи, где меньше лучше. До пяти позиций с обязательными самой дешёвой и самой сильной. Интеллект соответствует фактической глубине рассуждений: модели reasoning в Responses API по умолчанию используют medium, поэтому берётся строка AA medium; остальные — строка по умолчанию (`src/account/model-quality.ts`). Стоимость равна цене задачи AA по официальным тарифам, умноженной на ценовой коэффициент модели при текущей выгоде: множитель доступной публичной группы × скидочный множитель; минимум для экономии, максимум для качества, середина для баланса. Корпоративные группы исключаются; без входа или поддержки предполагается баланс. Ползунок выбирает модель позиции, имя открывает весь список; модель вне позиций отмечается как своя. Если позиций меньше двух, остаётся только список. Расчёт — `ui/lib/frontier.js`. - Данные AA хранятся в `assets/model-quality.json`: `updatedAt`, `source`, только используемые поля, уже сопоставленные с ID Modelflare. Обновление: `node scripts/update-model-quality.mjs`, который получает публичную таблицу https://artificialanalysis.ai/leaderboards/models и каталог цен Modelflare. При `AA_API_KEY` используется официальный API, чьи поля пока не проверены с ключом. `--html ` и `--pricing ` читают сохранённые копии, `--dry-run` только печатает. При изменении структуры, отсутствии колонки, неверных строках или числах, слишком малом числе строк или сопоставлений скрипт завершается с кодом 1 и причиной, не меняя снимок. Несопоставленные имена добавляются в `OVERRIDES`. Источник Artificial Analysis указан внизу выбора моделей. - Атрибуция: заголовок `X-Modelflare-Skill: anymodel-bot/` и ссылки с `utm_source=anymodelbot&utm_campaign=amb_`: внутри приложения `amb_signup`, `amb_topup`, `amb_console` и другие; в README и документации — `amb_readme`, на сайте — `amb_homepage`. Формат закрепляет `test/utm.unit.test.ts`. - Домены API: `https://modelflare.dev/v1`, `https://origin.modelflare.dev/v1` или `https://cf.modelflare.dev/v1` в разделе «Настройки → Модели → Домен API». Ручные тесты с устройства AnyModelBot запрашивают `/v1/models` всех трёх доменов без учётных данных и показывают медианное время ответа и число успехов из трёх. HTTP 401 означает ответ API, но не корректность ключа и не скорость генерации. Автопереключения нет. Старые значения `auto` / `global` выбирают основной домен, `cn` — origin, `cf` — cf; это совместимость, а не обозначение региона или качества. - «Настройки → Модели»: аккаунт, баланс и пополнение, порог уведомления, расходы, уведомления, приглашения; выгода и глубина рассуждений; модель по умолчанию, обновление списка моделей. - Кнопка модели справа в поле ввода меняет модель текущего сеанса или делает её основной для бота; работают `/model`, `/reset`, `/new`, `/status`, `/stop`, `/help`. - Действия: все шаги агента — запросы к моделям со временем и токенами, вызовы инструментов с аргументами и выводом, повторы, субагенты — свёрнуты в строку времени над ответом. Нажатие раскрывает их. Для WeChat/Feishu они видны в «Панель сведений → Недавние сеансы», где текущую работу можно остановить. - Зависание: `/stop` в любом канале или остановка на панели сведений сразу завершает текущий запрос. Запрос без прогресса 10 минут — без ответа модели и действий инструментов, только с повторами — останавливается автоматически. Ожидание разрешения или ответа пользователя не учитывается. Общий предел — 30 минут; `AMB_AGENT_IDLE_TIMEOUT_MS`, `AMB_AGENT_TURN_TIMEOUT_MS`. Плагин amb-control отменяет только этот разговор; другие продолжаются. Если за 10 секунд остановки нет (`AMB_STOP_GRACE_MS`), перезапускается процесс агента. `/status` показывает этап и время без прогресса. Переключение бота или перезагрузка веб-окна не прерывает запрос; при возврате восстанавливаются сообщение, частичный ответ и действия. Остановка работает также в очереди, при запуске агента, ожидании разрешения и в простом чате. - Уточнения во время работы: текст, изображения и файлы добавляются к текущему запросу; модель увидит их на следующем шаге и ответит вместе. Сначала отправляется короткое подтверждение через исходящую очередь, удаляемое, если не удалось отправить за 10 минут. Проверка доступа та же: сообщение постороннего не попадает в запрос. До принятия предыдущего сообщения агентом и при завершении текущего новое сообщение встаёт в очередь, как и команды `/model`, `/reset` и другие. Веб-чат позволяет продолжать ввод во время ответа. - Долгие команды уходят в фон: после 30 секунд, для PowerShell в Windows — 60, команда становится фоновой и не блокирует запрос; агент сообщает, что она работает. Завершение будит агента с результатом, и ответ приходит новым сообщением в тот же разговор. В веб-чате — сразу; в WeChat/Feishu — через исходящую очередь с ID из сеанса и запроса агента для однократной доставки. Окно WeChat и квота проверяются при отправке; в Feishu ответ привязан к последнему сообщению пользователя, ID которого хранится в БД. Шаги видны в действиях, а `/status`, остановка и сторожевой таймер работают как обычно. - Каждый разговор использует свою модель и API внутри одного процесса агента: по поставщику на API, контекст и максимум выхода на модель. Смена модели не перезапускает процесс; отсутствующая в стартовом патче модель добавляется во время работы. - Замена процесса: SDK DSH не закрывает сеансы, поэтому сеансы фоновых задач и запусков правил остаются до перезапуска. Измерено около 0,25–0,45 МБ на завершённый неактивный сеанс. После более 100 сеансов процесс заменяется в фоне, когда полностью свободен: нет запросов чата, выполняемых или завершающихся задач и правил, разрешений, сжатия и фоновых команд. Сеансы продолжаются без прерывания и видимых изменений. Диагностика показывает `taskSessions`, `recycles`; порог меняет `AMB_DSH_RECYCLE_SESSIONS`. - Уведомление после перезапуска: каждый разговор хранит в БД маркер незавершённого сообщения, удаляемый после обработки. Если приложение закрыли или оно упало, следующий запуск один раз сообщает в разговоре, что последний запрос не завершён из-за перезапуска и его нужно отправить заново. Автоповтора нет. В веб-чате это запись истории; WeChat использует сохранённый context_token и обычную квоту, а при закрытом окне или исчерпанной квоте уведомление приходит перед ответом на следующее сообщение. Feishu отправляет в исходный чат. - API агента выбирается по открытому каталогу Modelflare. Модели с Responses — GPT-5.4 и новее, Grok 4.5 и новее, DeepSeek V4, GLM-5, Kimi K3 и другие — используют `/v1/responses`; reasoning по умолчанию medium, зашифрованные рассуждения воспроизводятся с историей. Модели без Responses, но с Anthropic Messages, то есть Claude, используют `/v1/messages`; остальные, недоступный каталог, например без сети, и внешние API — Chat Completions. Выбор происходит при первом использовании модели процессом. Диагностика показывает `api` последнего запроса и модели процесса. `AMB_AGENT_API=chat` принудительно задаёт Chat Completions для диагностики; простой чат всегда использует его. Если провайдер отклоняет Responses/Messages с 400/404/405/415/422 или сообщением о неподдерживаемом параметре/endpoint, модель переводится на Chat Completions на 24 часа. Лимиты, баланс, доступ, сбои провайдера и переполнение контекста не учитываются. Запись — `dsh/api-fallback.json`, предупреждение в журнале, состояние `openai-completions (fallback: reason)`. Если инструменты ещё не вызывались, разговор повторяет запрос через Chat автоматически без перезапуска процесса. Иначе возвращается ошибка, следующий запрос использует Chat. - Встроенный шлюз: magpie работает в `--gateway` со своими HOME и каталогом конфигурации в папке данных. Он **не читает** подписочные данные Claude/Codex на компьютере, **не переписывает** конфигурации агентов; автообновление и обнаружение аккаунтов выключены. Вызывается только из процесса приложения; консоль больше не проксирует его страницы или `/v1`. - API-ключ хранится только в изолированной конфигурации шлюза, никогда в командной строке или журналах. Интерфейс получает лишь последние символы. - Разработка и тестирование: `AMB_MAGPIE_BASE_URL` задаёт произвольный совместимый с OpenAI endpoint, без запуска шлюза, со статусом подключения в интерфейсе и без функций аккаунта. `AMB_MODELFLARE_BASE_URL` перенаправляет базовый адрес Modelflare на локальную заглушку, `AMB_MODELFLARE_ISSUER` — вход и API аккаунта. ## Официальные API-ключи - Ключи вводятся через «Использовать свой API-ключ» на приветственном экране и в разделе «Настройки → Модели». Поставщики и адреса зафиксированы в `src/providers/official.ts`, а API (`GET /amb/api/official`, `PUT`/`DELETE /amb/api/official/`) принимает только id из таблицы и никогда — адрес. - Каждый поставщик — это provider во встроенном шлюзе с id `official-<поставщик>`, а id моделей — `official-<поставщик>/<модель>`, поэтому они не смешиваются с одноимёнными моделями Modelflare. Ключи не передаются через аргументы командной строки: они попадают в изолированную конфигурацию в теле запроса к локальному API шлюза. - Для проверки используется список моделей шлюза (прокси и способы авторизации находятся в шлюзе); ключ сохраняется, только если проверка пройдена. Раз в час модели сверяются со списком поставщика, а неподходящие для диалога (речь, изображения, эмбеддинги…) в список выбора не попадают. - API агента зависит от поставщика: Responses для OpenAI, Messages для Anthropic и Chat Completions для остальных. Размер контекста, цены и поддержка рассуждений берутся из каталога шлюза (`/v1/models`). Если есть только официальные ключи, каталог и аккаунт Modelflare не читаются. - Модели официальных API не получают `X-Modelflare-Skill`, не используют серверное сжатие (его адрес приходит из каталога Modelflare) и не ограничиваются бюджетом бота (бюджет — это лимит ключа Modelflare). Генерация изображений и видео доступна только при подключённом Modelflare. - Тесты: `AMB_OFFICIAL_BASE_URL` направляет всех поставщиков на локальную заглушку (`test/official-providers.integration.test.ts`). ## Интерфейс - Групповые чаты (`src/core/groups.ts`, `ui/screens/group.js`): при наличии двух ботов меню + позволяет создать группу. У участника свой разговор `:web:group:`, поэтому модель, разрешения, память, подтверждения и расходы работают как в личном чате. Сообщения пользователя хранятся в `group:`; лента объединяет их по ID. Отвечает упомянутый через @ бот, `@everyone` — все; без упоминания продолжает последний ответивший. Упоминание другого участника в ответе передаёт ему слово, максимум 6 раз на сообщение пользователя. В группе отвечает только один бот одновременно. - Боковая панель: список ботов с аватаром, именем и последним сообщением; + для создания, правая кнопка — переименование и удаление. Список разбит на разделы, которые можно создавать, переименовывать, удалять и перетаскивать (по умолчанию «Мои» и «Новые»; хранятся на сервере и общие для всех окон). Ботов, групповые чаты и боты из каталога можно перетащить в другой раздел или переместить через «Переместить в раздел»; новые боты из каталога попадают в «Новые». Внизу слева аватар открывает баланс, шестерёнка — настройки (`⌘/Ctrl+,`). - Чат: плавающая плашка имени сверху открывает панель сведений (`⌘/Ctrl+⇧+I`): аккаунты каналов, где бот отвечает по умолчанию, запросы разрешения, задачи и правила, память, недавние сеансы. Шестерёнка открывает настройки бота. Ответы поступают потоком, поддерживают Markdown и копирование кода одним нажатием; их можно остановить через `Esc`. Вопросы и разрешения появляются карточками. Прокрутка вверх не сбрасывается вниз. - Палитра команд — `⌘/Ctrl+K`; тема, системная, светлая или тёмная, находится в «Настройки → Основные». - Языки: упрощённый китайский, английский, японский, корейский, русский, испанский и португальский (Бразилия). Выбор — «Настройки → Основные → Язык», вверху справа первого экрана или в палитре команд. По умолчанию используется язык системы, а для неподдерживаемого — английский. Выбор хранится в `ui.lang` файла config.json; ему следуют меню трея, ошибки и состояние сервера, системные сообщения в WeChat/Feishu, включая `/help` и запросы разрешения. В CLI/Docker системный язык берётся из `AMB_LANG`, затем `LC_ALL` / `LC_MESSAGES` / `LANG`, иначе — упрощённый китайский. Журналы, инструкции модели и заданные пользователем имена ботов не переводятся. - Строки интерфейса: `ui/locales//.js`, вызов `t("namespace.key", { params })` через `ui/lib/i18n.js`. Серверные строки: `src/i18n/messages/.ts` с проверкой ключей типами. Каждый запрос интерфейса передаёт `x-amb-lang`; сервер отвечает на том же языке. - Добавляйте каждую новую строку на обоих языках. `node scripts/i18n-check.mjs [files…]` сообщает о китайском тексте в коде интерфейса, отсутствующих ключах и несовпадении словарей zh/en. То же проверяет `test/i18n.unit.test.ts` в `npm test`. Для необходимого китайского текста, например имён шрифтов и регулярных выражений, добавьте на строке `// i18n-ignore`. - Первые шаги: в пустом чате шесть пунктов — поздороваться, сменить модель, подключить WeChat, поручить работу, сохранить память, создать изображение. Последний воспроизводит встроенный пример независимо от наличия медиа-моделей. Как и настоящий сценарий, он сразу показывает результат в чате, но ничего не отправляет боту, не вызывает модель и не списывает средства; изображение — `ui/assets/guide-demo.svg`. Так пользователь узнаёт процесс без расходов. Настоящая просьба нарисовать или последующее получение изображения тоже завершает пункт. «Отправить» запускает пример; «Показать» или пункт внизу слева открывает подсказку с кольцевой подсветкой нужного элемента. Шаги отмечаются автоматически после ответа, смены модели, получения файла/изображения, подключения канала или записи памяти. Прогресс — `ui.guide` в config.json, API `/amb/api/guide`; уже выполненные действия старых пользователей засчитываются. Список можно свернуть вниз слева или скрыть; «Настройки → Основные → Список первых шагов» запускает его заново. «Поздороваться» засчитывается только при настоящем ответе (сообщения об ошибке не в счёт), канал должен быть действительно подключён (одних настроек мало). На шаге «Подключите привычный мессенджер» можно выбрать WeChat, Feishu, Telegram, Slack или Discord, язык интерфейса лишь определяет рекомендацию. Если пользователь прямо говорит «Запомни…», разбор памяти после хода выполняется сразу, а не через 90 секунд. Прогресс хранится отдельно для каждого пользователя (при входе в Modelflare — по аккаунту в KV `guide.owner.*`, иначе по-прежнему в `ui.guide` в config.json); после выполнения всех шагов список скрывается навсегда, а подсказки, появляющиеся сами, ждут, пока в поле ввода есть черновик или выполняется задача. - Оформление: нейтральные цвета и компоненты адаптированы из magpie под MIT; акцент — яркий жёлто-зелёный Modelflare `#d7ff00`. Дизайн-система описана в `ui/design/README.md`. ### Локализация и проверки выпуска Сопровождающие самостоятельно пишут и адаптируют переводы; генерация текстов через API перевода запрещена. Сохраняйте названия продуктов, ID моделей, команды, URL и параметры `{placeholder}`. - Сообщения приложения: `ui/locales//.js`; новые серверные локали: `src/i18n/locales//.ts`. - Сообщения сайта: `site/src/i18n/locales//`; например, `home/hero.ts` соответствует `home.hero.*`. Страницы читают каталог. - `ui/locales/manifest.json` содержит целевые языки и статус `ready`. Сайт хранит идентичный `site/src/i18n/manifest.json`; проверяется их совпадение. Незавершённые языки остаются `ready: false` и не попадают в публичные меню и языковые аннотации поисковиков. - `npm run i18n:status` показывает прогресс по языкам и частям продукта. `npm run i18n:check` проверяет все языки и документы. Отсутствующие, пустые и лишние ключи, повреждённые параметры и недостающие формы множественного числа блокируют выпуск. Подстановка английского при разработке не считается переводом. - Русские формы: `one / few / many / other`; испанские и португальские: `one / many / other` (`many` — только для круглых миллионов, пишется как `other`); японские и корейские: `other`. Локализуйте отображение, не меняя валюту, часовой пояс и суммы. - `npm run build` сайта проверяет все целевые локали, синхронизированные документы и изображения для публикации ссылок. `build:draft` предназначен для локального предпросмотра и не заменяет проверку выпуска. ## Личность и инструкции Все инструкции модели находятся в `src/agent/prompts/`. `test/prompts.unit.test.ts` проверяет обязательные и запрещённые фразы каждого фрагмента и лимит символов. `test/agent.integration.test.ts` с настоящим дочерним процессом DSH проверяет системную инструкцию, получаемую моделью, и общий лимит вместе с описаниями инструментов. - **Личность:** стандартная роль DSH — агент программирования с вводной фразой о DeepSeek Harness. Патч `host.ts` writePatch заменяет `personaPrefix` на личного помощника: общение, код, команды, файлы и, если включено, управление приложениями. Текст веб-страниц, файлов и пересланных сообщений считается данными, а не инструкциями. `includeHarnessIdentity` выключается; он управляет только вводной фразой. - **Раздел бота:** правила чата, инструкции памяти, если она включена, имя и заданный характер образуют последний раздел системы `amb:bot`. Перед каждым запросом хост записывает его в `dsh/.prompts/.md` папки данных. Инструменты агента не могут читать и менять файл; неизменённый раздел не перезаписывается. `dsh-runtime/plugins/amb-prompt.mjs` читает его при каждом обращении к модели, поэтому новые имя и характер действуют со следующего сообщения, без `/new` и перезапуска. DSH 0.2.1-rc.4 вызывает `text` раздела синхронно и не ждёт Promise, поэтому плагин читает файл вместо вызова моста. При конфликте характер бота важнее правил чата. Субагенты этот раздел не получают, так как не общаются с пользователем. - **Правила чата:** на китайском, адаптированы из принципа внимания dsh-superagent. Сначала ответ; перед долгой задачей — одна строка о действии, затем без пересказа шагов, видимых в панели действий. В конце — что сделано и где результат; незавершённое и ошибку надо называть прямо. Бот сам выбирает язык, формат, объём и стиль и сообщает выбор. Спрашивает лишь когда ошибка навредит, потратит деньги или большую часть работы, когда нужны доступные только пользователю вход, файл или пароль, либо перед необратимым шагом — оплатой, удалением данных, сообщением другим людям. Один конкретный вопрос за раз, варианты через `ask_user_question`, без лишних слов, кратко в WeChat/Feishu. Фоновые задачи следуют тем же правилам и указывают выбор в результате. - **Первое сообщение сегмента:** канал — WeChat только текст, Feishu и веб с Markdown, — снимок долговременной памяти, заметка прошлого сегмента, затем сообщение пользователя. Эти данные зависят от разговора и меняются с памятью; в системной инструкции они ломали бы общий префиксный кэш бота, поэтому помещаются сюда и не меняются внутри сегмента. Новая память читается через `recall`. - **Префиксный кэш:** неизменённый раздел оставляет системную инструкцию побайтно одинаковой; изменение характера затрагивает только последний раздел. Разговоры, начатые до обновления, сохраняют старую роль в первом сообщении до следующего сегмента через `/new` или управление контекстом. ## Доступ к файлам В режиме агента у каждого бота есть набор разрешений. Переключается плашкой слева внизу поля ввода или в «Настройки бота → Разрешения»; `/status` показывает текущий вариант. - **Запись в рабочую папку**, по умолчанию: команды в песочнице меняют только рабочую папку бота; за её пределами нужно разрешение в чате. - **Только чтение:** изменение файлов запрещено, команды выполняются в песочнице только для чтения. - **Полный доступ:** для тех, кто понимает риск и считает подтверждения слишком частыми. Команды выполняются **без песочницы** от вашего имени, выход за границы не требует вопроса. Доступны все файлы компьютера, включая данные AnyModelBot: БД, токены каналов и ключи. Подтверждается только **рекурсивное удаление**: номером в WeChat, карточкой в Feishu/веб. Распознаются `rm -r` / `-rf` / `--recursive`, включая `sudo`, `xargs`, `sh -c`; `find -delete`, `git clean`, `rsync --delete`; PowerShell `Remove-Item` / `rm` / `del` / `rd` / `rmdir` с `-Recurse` и сокращениями; cmd `rd /s`, `del /s`, `robocopy /MIR`; Python `shutil.rmtree` и Node `fs.rm(…, { recursive })`. Проверяются также указанные в команде скрипты. Сам выбор режима требует подтверждения; плашка и настройка красные. - Это защита от случайного удаления, а не граница безопасности: анализируется текст команды. Собираемые во время выполнения команды вроде `eval "$(…)"`, `curl … | sh`, а также `make clean` и `npm run clean` не видны проверке. При сомнениях она спрашивает. Включайте режим только при доверии к модели и задаче. ## Кто может пользоваться ботом Агент работает на вашем компьютере, возможно с полным доступом, поэтому по умолчанию общаться могут **только владелец и разрешённые пользователи**. Доступ учитывается по аккаунту канала; допущенный к аккаунту пользователь может общаться с любым ботом (`src/core/access.ts`). - **Владелец:** в WeChat — сканировавший QR-код аккаунт. У Feishu нет собственного входа ни при создании приложения сканированием, ни по App ID/Secret, поэтому владельцем становится **первый написавший боту лично после подключения** — доверие при первом использовании. Сразу после подключения напишите со своего Feishu; сообщение получит обычный ответ. Так же работает WeChat, если вход не вернул ID сканировавшего. В «Настройки бота → Кто может пользоваться» виден владелец Feishu. «Изменить» после подтверждения очищает его; владельцем станет следующий написавший. Смена приложения Feishu и отключение тоже сбрасывают владельца. Пользователь, которому отказали, владельцем не становится. Локальный веб-чат не ограничен. - **Остальные:** получают строку о том, что доступ ещё не разрешён и владелец уведомлён, максимум раз в час на человека. Сообщение не встаёт в очередь, модель не вызывается, средства не тратятся. Запрос появляется в управлении аккаунтом раздела «Настройки › Каналы чата» с разрешением/отказом и отправляется владельцу с четырёхзначным кодом, максимум три на аккаунт в час и только если владелец писал в этом канале за последние 24 часа. Ответ: `同意 1234` / `拒绝 1234` или `yes 1234` / `no 1234`. Коды доступа не пересекаются с кодами разрешений инструментов. Пользователи с отказом больше не получают ответа. - Список доступа расположен в управлении аккаунтом раздела «Настройки › Каналы чата». Запись можно удалить; пользователь сможет снова запросить доступ сообщением. Список показывает и `/status`. - При обновлении все ранее общавшиеся с ботом лично добавляются в список с отметкой об использовании до обновления. Повторное сканирование другим WeChat оставляет прежнего владельца в списке. - Групповые чаты каналами пока не доставляются: Feishu обрабатывает только личные, у WeChat iLink нет групп. Групповые сообщения пока не меняются; при добавлении групп правила появятся в `access.ts`. ## Ответы не теряются Итоговые ответы, файлы, запросы разрешений и уведомления записываются в исходящую очередь локальной БД до отправки (`src/core/outbox.ts`). Обновления потоковых карточек и индикатор набора туда не входят. - В одном разговоре сообщения идут по одному, по порядку. Сетевые и платформенные ошибки повторяются с задержкой от 5 секунд до 5 минут; отключённый канал ожидается. - После выхода или сбоя отправка продолжается при следующем запуске. Уже отправленное не повторяется; длинный ответ продолжается с первой неотправленной части. ID выводится из входящего сообщения, поэтому повторная доставка платформой не создаёт второй итоговый ответ. Дважды может уйти лишь часть, находившаяся в полёте в момент сбоя; у неё постоянные Feishu `uuid`, с дедупликацией в течение часа, и WeChat `client_id`. - WeChat позволяет отвечать 24 часа после последнего сообщения, максимум 10 раз на сообщение. Не помещающееся в лимит сохраняется. При следующем обращении пользователя сначала отправляются задержанные сообщения по порядку и один раз, затем новый ответ. Текстовые части объединяются в одно «Пока вас не было: …», если вмещаются в сообщение WeChat; файлы идут отдельно. Хранение — до 7 дней; краткоживущие подтверждения приёма и запросы разрешений имеют свои сроки. - Больше недоставляемые сообщения, например при постоянном отклонении платформой или долгом ожидании, отмечаются с причиной в журнале и диагностике. ## Фоновые задачи и правила Долгая работа выполняется в фоне и не задерживает чат. Проектирование — `docs/design/background-tasks-and-proactive.md`, код — `src/tasks/`. - **Фоновые задачи:** агент чата вызывает `task_start`, создавая отдельный сеанс DSH `task-` и папку `tasks/-/` в рабочей папке, и в одной строке сообщает намерение. Результат возвращается в исходный разговор; цитата в WeChat или ответ в Feishu продолжают задачу. В одном разговоре задача задаёт по одному вопросу за раз. После перезапуска она продолжается и проверяет состояние перед повторением внешних действий. `/tasks` показывает задачи и правила; `/stop ` останавливает нужное. - **Правила:** создаются через `rule_create` или «Настройки бота › Инициативные сообщения › Правила» и сразу выполняют действия. Слова пользователя — поручение: запуск проверяет условие и пишет лишь о важном; изменение текста сохраняет режим выполнения. Наблюдение включается явно просьбой «сначала наблюдай» или выбором в редакторе: только чтение, без отправки, с записью предполагаемого сообщения. После трёх наблюдений раздел «Требует внимания» предложит включить действия. Каждый запуск имеет новый сеанс; журнал экспортируется в Markdown. - **Видно, но не шумно:** раздел «Задачи» панели сведений показывает задачи и правила бота, завершённые сворачиваются в одну строку. В подробностях — источник, прогресс, бюджет, папка и шаги запусков. Всё ожидающее пользователя собирается в «Требует внимания». Отправляются только результаты, решения и ошибки. Тихие часы, по умолчанию 22:00–08:00, дневные лимиты — 3 в WeChat, 5 в Feishu — и сводки настраиваются в «Инициативные сообщения». - **Бюджеты:** по умолчанию $1 на задачу, $0.10 на запуск правила и $3 на правило в месяц, оценка по ценам Modelflare. Достигнув лимита, работа останавливается и спрашивает пользователя. Бюджеты меняются в сведениях задачи и редакторе правила. При остатке бюджетного ключа бота ниже 20% фон останавливается, сохраняя средства для чата. - **Пауза:** «Настройки бота › Инициативные сообщения › Приостановить фоновую работу» или просьба боту задерживает задачи, правила и исходящие уведомления; чат работает. - **Хранение:** задачи и журналы хранятся 30 дней, неактивная 30 дней задача архивируется. Её неиспользованная 30 дней папка удаляется вместе с файлами сеанса DSH в `dsh//sessions/`. У SDK нет удаления сеанса, поэтому файлы удаляет приложение; открытый в процессе сеанс удалится после замены процесса. Подтверждения и уведомления нет: на 27-й день назначается и отображается дата удаления, а «Сохранить» удерживает папку. Удаление не раньше чем через 3 дня после назначения даты. В подробностях виден размер папки и доступно удаление задачи вместе с ней. ## Управление компьютером В «Настройки бота», шестерёнка панели сведений, → «Управление компьютером» можно включить функцию, выбрать механизм и режим подтверждения. `/status` и настройки показывают механизм, доступность и причину недоступности. - **Механизмы:** - **Cua Driver**, по умолчанию на всех трёх настольных платформах: официальный готовый [cua-driver](https://github.com/trycua/cua/tree/main/libs/cua-driver) 0.37.0 под MIT включён в установщик. `scripts/fetch-cua-driver.mjs` скачивает его для платформы и архитектуры при сборке и проверяет SHA256. Он запускается как встроенный MCP-сервер `cua-driver mcp`, всегда с `CUA_DRIVER_PERMISSION_MODE=bounded` и манифестом возможностей, **никогда** с `--dangerously-bypass-approvals`. Окружение очищено от секретов, телеметрия выключена, `run_script` отключён. Видны только 24 нужных инструмента: окна, снимки, запуск приложений, клики, ввод, клавиши и сочетания, прокрутка, перетаскивание, значения, меню и другие. Скрипты, завершение процессов, буфер обмена, внедрение в браузер, запись, обновления и остальное скрыты от модели и отклоняются. Манифест перечисляет установленные GUI-приложения: .desktop в Linux, /Applications в macOS, меню «Пуск» в Windows, — и разрешает ввод по всему экрану. Срок — максимум 24 часа; драйвер перезапускается до истечения. - **Мост Codex Computer Use**, необязательный, только macOS: kimi-computer-use. Нужен локально установленный OpenAI Codex Computer Use; при недоступности используется Cua Driver. - **Подтверждения:** по умолчанию чтение, снимки, клики, ввод, клавиши, прокрутка, перетаскивание и установка значений **автоматические, без подтверждения**. Можно включить вопросы перед изменениями экрана, например кликами и вводом, оставив чтение автоматическим. При обновлении старые боты, включая основного, переводятся в автоматический режим. Ботам только для чтения доступны лишь инструменты чтения. - **Платформы:** - macOS: разрешите специальные возможности и запись экрана в системных настройках приватности и безопасности. Драйвер работает в `--direct`, ещё не проверенном на реальных устройствах. Без них вызовы инструментов управления компьютером блокируются, ход завершается сообщением, что задача не продолжена из-за отсутствия разрешения, а в чате появляется карточка только с недостающими разрешениями (системный запрос, открыть нужный раздел Системных настроек, проверить снова; для записи экрана обычно нужен перезапуск приложения — его можно сделать из карточки, неотправленные черновики вернутся). При первом запуске ничего не запрашивается. - Linux: X11 читает интерфейс через AT-SPI, требующий at-spi2-core и поддержки доступности приложениями. В Wayland возможности ограничены активным окном XWayland, о чём сообщает интерфейс. Без графического сеанса DISPLAY / WAYLAND_DISPLAY функция недоступна. - Windows: нужен интерактивный рабочий стол вошедшего пользователя. Неинтерактивные сеансы служб и планировщика не поддерживаются. - Снимки отправляются только моделям со зрением, не пересылаются в WeChat/Feishu и отправляются файлами лишь по просьбе пользователя. - Не включены cua-perception, OmniParser под AGPL и любые компоненты Cua Spaces под FSL. ## Настройка приложения Feishu Проще всего: «Настройки › Каналы чата → Feishu → Добавить аккаунт», отсканировать код в Feishu для создания бота, затем написать ему. Для имеющегося собственного корпоративного приложения выберите «Использовать своё приложение»: 1. На [открытой платформе Feishu](https://open.feishu.cn/app) создайте собственное корпоративное приложение и добавьте возможность Bot. 2. В разрешениях включите: - `im:message.p2p_msg:readonly` — чтение личных сообщений пользователей боту. - `im:message:send_as_bot` — отправка от имени приложения. - `cardkit:card:write` — создание и обновление карточек для потоковых ответов. - `im:message.history:readonly` — чтение истории. Постоянное соединение не повторяет сообщения, поступившие без приложения. Поэтому при старте и переподключении приложение догружает историю чатов, активных за последние 7 дней: сообщения последних 24 часов, максимум 20 на чат. Без разрешения остальное работает, но догрузки нет; приложение сообщает об этом один раз. 3. Сначала введите и сохраните App ID / App Secret в «Настройки › Каналы чата → Feishu → Добавить аккаунт → Использовать своё приложение». Постоянное соединение должно работать до сохранения следующего шага. 4. В Events & callbacks выберите режим подписки **Receive events through persistent connection** — получение событий через постоянное соединение — и добавьте `im.message.receive_v1`. 5. Опубликуйте версию, включите себя в область доступности и напишите боту со своего Feishu. Первый написавший после подключения становится владельцем; см. «Кто может пользоваться ботом». Пока обрабатываются только личные p2p-чаты; сообщения групп игнорируются. ## WeChat (iLink) - «Настройки › Каналы чата → WeChat → Добавить аккаунт → Войти по QR-коду»: отсканируйте в WeChat и подтвердите. Или выполните `npm run weixin:login`: код появится в терминале и сохранится PNG в папке данных. - Вход, курсор синхронизации и context_token хранятся в папке данных и восстанавливаются после перезапуска. - Ограничения платформы: после сообщения пользователя — максимум 10 ответов за 24 часа. Ответ отправляется после завершения генерации и разбивается при длине более 4000 символов. Во время генерации виден индикатор набора. - Изображения, файлы и видео, в том числе цитируемые, скачиваются с CDN WeChat и расшифровываются, до 50 МБ каждый. В режиме агента они сохраняются в `inbox/` рабочей папки, а сообщение содержит путь, чтобы агент мог прочитать, обработать или использовать файл как образец. Модели со зрением — Claude, GPT-5/6, Gemini, Grok 4, Kimi K3, Muse Spark и другие — также получают само изображение; остальные только путь. В Linux изображения напрямую агенту пока не передаются из-за сбоя sharp под Electron; доступен лишь путь. Файлы, переданные ботом через present, возвращаются в WeChat как изображения или файлы. - При истечении сеанса с кодом -14 канал приостанавливается, а интерфейс сообщает об этом. Повторное сканирование возобновляет работу. ## Разработка и тесты ```bash npm run typecheck npm test # модульные, автономные сквозные (заглушки Feishu/iLink/Modelflare, поток и остановка) и интеграционные тесты шлюза; нужен собранный magpie npm run docs:check # проверка README: наличие и размер файлов, структура zh/en, ссылки и якоря, запрещённые формулировки, alt-текст ``` Список материалов README и требования к записи — в [docs/assets/README.md](./assets/README.md). ## Лицензия MIT, см. `LICENSE`. Сторонние компоненты, включая magpie под MIT и адаптированные стили, Tencent openclaw-weixin под MIT и другие, перечислены в [THIRD_PARTY_NOTICES_ru.md](../THIRD_PARTY_NOTICES_ru.md) и в разделе «Настройки → О приложении». ## Пользовательские навыки и поиск по переписке Интерфейс и формат ZIP описаны в [руководстве по навыкам](./skills_ru.md). `src/skills/archive.ts` проверяет пути, лимиты распаковки и `SKILL.md`; `service.ts` хранит пакеты, состояния включения и идентификаторы версий отдельно для каждого бота. `src/web/skills.ts` предоставляет API предпросмотра и управления. Включённые навыки размещаются, когда DSH свободен, без прерывания диалога, субагентов или фоновых команд. При обновлении ботов каталога `src/botkit/installer.ts` проверяет совпадения имён. `src/store/chat-search.ts` поддерживает индекс сообщений в SQLite, фильтрацию, страницы результатов и контекст исходного сообщения. Общий поиск реализован в `ui/screens/message-search.js`, поиск в текущем чате — в `ui/components/chat-search.js`. Поиск читает локальную базу без вызовов модели. Связанные тесты: `test/skills*.test.ts` и `test/chat-search*.test.ts`. Путь к Chromium для проверки интерфейса задаётся через `AMB_TEST_CHROME`. При наличии DSH также проверяются обнаружение и загрузка навыков, чтение материалов и отключение навыка во время работы.