Skip to main content
Glama

vanth

Событийно-ориентированные фоновые задания для агентов.

Vanth — это демон фоновых заданий на локальном хосте с интерфейсом Model Context Protocol (MCP). Он запускает отсоединённые, неинтерактивные команды оболочки; надёжно сохраняет их вывод; анализирует необязательные структурированные события AGENT_EVENT в индикаторы прогресса, ряды метрик и контрольные точки; и может пробудить сеанс Codex или OpenCode, когда заданию требуется внимание. Он создан для одного доверенного пользователя на одной машине.

  • Любая команда: загрузки, обработка изображений/аудио, ETL, обучение ML — если это работает в оболочке, Vanth может запустить это отсоединённо и отслеживать.

  • Надёжность: задания и события хранятся в SQLite (WAL, busy-timeout) и переживают перезапуски демона, MCP и машины.

  • События в первую очередь: агенты используют job_wait для значимых событий вместо опроса логов.

  • Пробуждение по необходимости: надёжные доставки с гарантией хотя бы один раз возобновляют поток Codex или сеанс OpenCode, когда заданию требуется человек или агент.

  • Терминальная панель: встроенный монитор на Go отображает живую панель заданий, метрик и графиков в стиле W&B-LEET.

Вне рамок v1: удалённый сетевой доступ, TLS, многопользовательский режим/RBAC, квоты, интерактивный stdin и веб-интерфейс.

Для агентов: начинайте работу с job_start, затем используйте job_wait для событий progress/checkpoint/completed вместо опроса; заставьте задания генерировать строки AGENT_EVENT (ниже), чтобы прогресс, метрики и контрольные точки отображались в реальном времени на панели vanth-monitor; и позвольте длительным заданиям возобновлять вас через цели пробуждения, вместо того чтобы вы проверяли статус.


Быстрый старт

Установка (требуется uv; работает на Python 3.11+):

uv tool install vanth

Это устанавливает MCP-сервер vanth, демон vanthd, vanth-monitor и CLI для операций как отдельные инструменты (колесо включает встроенный монитор на Go, поэтому цепочка инструментов Go не требуется).

Из исходного кода (разработка):

git clone https://github.com/abhim-dv/vanth.git && cd vanth
uv sync

Запустите демон (держите этот терминал открытым):

uv run vanthd

Во втором терминале запустите отслеживаемое задание через MCP-сервер:

uv run vanth

или используйте инструменты напрямую из MCP-клиента (см. Интеграция с MCP).

Проверьте, что всё работает:

job_doctor()

Сквозной пример: запуск отслеживаемого задания

Как только MCP-клиент подключён, вот полный цикл:

job_start(
  command="uv run python examples\\long_job.py",
  name="demo run",
  notify_on=["checkpoint", "failed", "completed"],
)
# -> job_<id>

job_wait(job_id="job_<id>", filters=["checkpoint"], timeout_seconds=120)
# -> returns the first checkpoint event + current status

job_wait(job_id="job_<id>", filters=["completed", "failed"], timeout_seconds=300)
# -> returns the terminal event + exit code

И в третьем терминале наблюдайте в реальном времени:

uv run vanth-monitor

Точки входа командной строки

Команда

Назначение

uv run vanth

MCP-сервер stdio (мост к демону); также подкоманды status / doctor / restart

uv run vanthd

Фоновый HTTP-демон

uv run vanth-monitor

Терминальная панель в реальном времени (бинарник Go, встроен в колесо)

uv run vanth-codex-notify

Адаптер доставки: читает полезную нагрузку пробуждения из stdin, отправляет её в Codex

CLI для операций

uv run vanth status              # is the daemon up? pid, schema, running jobs, deliveries
uv run vanth status --json       # machine-readable version
uv run vanth doctor              # full health report (same as job_doctor, human-readable)
uv run vanth restart             # gracefully stop + start the daemon (jobs survive)
uv run vanth setup               # register the MCP server in your clients' configs
uv run vanth setup --remove      # unregister it

vanth restart — это надёжный способ применить обновление кода/версии: он отправляет демону корректное завершение через loopback, ждёт, пока старый процесс полностью освободит блокировку домашней директории, затем запускает новый демон. Выполняющиеся задания принадлежат отсоединённым исполнителям, поэтому они продолжаются после перезапуска.


Related MCP server: Background Process MCP

Как это работает

MCP client / HTTP client
        |
        v
   vanthd (localhost HTTP daemon, bearer-token auth)
        |                 |                    |
        |                 |                    +---> wake adapters
        |                 |                          (local_command / codex_thread / opencode_thread)
        |                 |
        |                 +----> jobs.sqlite (durable source of truth)
        |
        +----> vanth.runner (detached worker process)
                    |
                    +----> your command (own process group)
                              |
                              +----> stdout/stderr -> logs/ + AGENT_EVENT parsing

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

  • исполнитель владеет реальной командой, её таймаутом и очисткой потоков;

  • демон владеет обслуживанием, диспетчеризацией доставки, запросами API и восстановлением;

  • SQLite является источником истины при перезапусках процессов;

  • MCP и HTTP клиентам не нужно оставаться активными для продолжения заданий.

Задание не считается завершённым, пока оба потока вывода не достигнут EOF и все структурированные события не будут сохранены.

Жизненный цикл задания

Задание проходит через небольшой набор состояний. Конечные состояния являются постоянными.

Состояние

Значение

running

Нагрузка запущена; исполнитель передаёт вывод и отправляет сигналы пульса

completed

Команда завершилась с кодом 0, потоки очищены, события сохранены

failed

Команда завершилась с ненулевым кодом

timeout

Команда превысила timeout_seconds; исполнитель завершил её

cancelled

Была выдана команда job_stop, и дерево процессов действительно завершено

orphaned

Исполнитель неожиданно завершился (сбой); никогда не отбрасывается молча

Исполнитель соблюдает timeout_seconds даже при перезапусках демона. При восстановлении задание в состоянии running, чей исполнитель исчез, помечается как cancelled (если был запрошен останов) или orphaned (если нет) — никогда не остаётся как зомби-строка running.


Установка MCP-сервера

vanth — это MCP-сервер stdio. Он общается с демоном, запуская его автоматически при первом использовании, если он ещё не запущен.

Одноразовая настройка

После установки инструмента подключите его к MCP-клиентам на вашей машине за один шаг:

uv tool install vanth
vanth setup

vanth setup обнаруживает установленные клиенты (opencode, Codex и клиенты в стиле mcpServers, такие как Claude Code / Cursor), показывает, что найдено, создаёт резервную копию каждого конфига перед изменением (.vanth-setup-<ts>.bak) и добавляет или обновляет запись Vanth MCP — оставляя все остальные настройки и комментарии нетронутыми.

vanth setup                  # detect + configure everything found (prompts)
vanth setup --yes            # apply without prompting (scripts/CI)
vanth setup opencode codex   # only specific clients
vanth setup --json           # machine-readable result
vanth setup --remove         # remove the Vanth MCP entries instead

Конфиги, которыми он управляет:

Клиент

Файл

Раздел

opencode

~/.config/opencode/opencode.json

mcp.vanth

Codex

~/.codex/config.toml

[mcp_servers.vanth]

Claude Code / Cursor

~/.claude.json

mcpServers.vanth

Вручную те же записи:

opencode

Добавьте в ~/.config/opencode/opencode.json:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "vanth": {
      "type": "local",
      "command": ["vanth"],
      "enabled": true,
      "timeout": 15000
    }
  }
}

Из исходного кода используйте uv напрямую вместо простого vanth:

{
  "mcp": {
    "vanth": {
      "type": "local",
      "command": ["uv", "run", "--directory", "/path/to/vanth", "vanth"],
      "enabled": true,
      "timeout": 15000
    }
  }
}

Проверьте подключение и инструменты:

opencode mcp list

MCP-клиенты в стиле Claude (mcpServers)

Опубликованное колесо:

{
  "mcpServers": {
    "vanth": { "command": "vanth", "env": { "VANTH_HOME": "C:/Users/you/.vanth" } }
  }
}

Из исходного кода:

{
  "mcpServers": {
    "vanth": {
      "command": "uv",
      "args": ["--directory", "/path/to/vanth", "run", "vanth"],
      "env": { "VANTH_HOME": "C:/Users/you/.vanth" }
    }
  }
}

Настройка домашней директории демона

И MCP-сервер, и демон используют один и тот же корень состояния из VANTH_HOME (по умолчанию %USERPROFILE%\.vanth на Windows, ~/.vanth на Unix; AGENT_BG_HOME принимается как псевдоним). Если оба установлены, они должны указывать на одну и ту же директорию.


Инструментирование заданий с помощью agent_event

Любой Python-скрипт может отправлять структурированные события в stdout (или stderr), которые Vanth анализирует, а монитор отображает в виде графиков. Это необязательно — обычные скрипты всё равно выполняются и логируются, — но именно это превращает задание в полноценный отслеживаемый объект.

from vanth.agent_events import agent_event, progress

# A checkpoint: something meaningful happened.
agent_event("checkpoint", "epoch complete", epoch=10, val_loss=0.42)

# A progress update: drives the progress bar and progress.* plots.
progress(10, 100, unit="epoch", stage="train", message="10/100 epochs")

# Arbitrary scalar metrics: become their own line plots.
agent_event("metric", _step=10, loss=0.42, acc=0.88, mbps=12.4)

Примечания:

  • вспомогательная функция выводит AGENT_EVENT {json} с flush=True (сброс важен);

  • progress(current, total, unit=..., stage=...) вычисляет percent за вас;

  • полезные нагрузки metric: числовые поля становятся рядами; _step (если присутствует и числовой) является осью x, в противном случае используется порядковый номер события; ключи, начинающиеся с _, кроме _step, игнорируются; логические значения не являются метриками; значения NaN/Infinity/null пропускаются и учитываются в значке предупреждения монитора;

  • любое другое поле (например, file, stage, phase) сохраняется и отображается в таблице точных событий.

Пример: отслеживаемый загрузчик

# downloader.py
import os
from vanth.agent_events import agent_event, progress

files = ["a.bin", "b.bin", "c.bin"]
total = sum(os.path.getsize(f) for f in files)
done = 0

for f in files:
    agent_event("checkpoint", f"starting {f}", file=f)
    # ... download f ...
    done += os.path.getsize(f)
    progress(done, total, unit="bytes", stage="download",
             message=f"{done}/{total} bytes")

Пример: пакетная обработка изображений

from vanth.agent_events import agent_event, progress

images = list(find_images("input/"))
for i, img in enumerate(images, 1):
    out = process(img)                    # resize, denoise, ...
    agent_event("metric", _step=i, sharpness=out.sharpness, size_mb=out.size_mb)
    progress(i, len(images), unit="images", stage="process", message=img.name)

Логирование с временными метками и уровнями с помощью loguru

Vanth поставляется с обёрткой loguru, которая направляет каждую запись в структурированную строку лога AGENT_EVENT, так что логи отображаются как события с временными метками и уровнями в таблице событий (со значком уровня и точными временными метками) вместо простого текста:

from vanth.agent_logger import logger, log_with_context

logger.info("training started", lr=8e-5, batch_size=8)     # event type "log", level info
logger.warning("low disk", free_gb=2.5)
log_with_context("error", "failed to load checkpoint", path="best.pt")

Каждый вызов генерирует AGENT_EVENT {"type":"log","level":"info","message":"...","data":{...}}, который демон сохраняет как надёжное событие. data содержит дополнительный контекст. Монитор отображает их в таблице точных событий рядом с событиями metric/progress.


Справочник инструментов (все 20 MCP-инструментов)

Инструмент

Назначение

job_start

Запустить команду как отсоединённое задание

job_rerun

Повторно запустить задание с его исходной командой/окружением/рабочей директорией/целями

job_wait

Блокироваться до совпадающего события (или таймаута) — предпочтительный способ ожидания заданий

job_status

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

job_list

Недавние задания, фильтруемые по status / thread_id / name / tags

job_view

Сводки для агентов, отсортированные по приоритету внимания

job_events

Структурированные события для задания (прямой порядок через since_event_id или сначала новые через reverse)

job_tail

Ограниченный хвост лога stdout/stderr со смещениями байтов

job_metrics_query

Чтение сохранённых рядов скалярных метрик (loss, acc, progress.percent, ...)

job_metric_compare

Сравнение одной метрики между заданиями (последнее/среднее/мин/макс/сумма/количество)

job_run_summary

Одним вызовом "сработало?" — статус, время выполнения, прогресс, метрики, артефакты

job_artifact_add

Прикрепить артефакт (контрольная точка, CSV, вывод) к заданию

job_artifacts

Список артефактов, прикреплённых к заданию

job_dashboard

Просмотр данных графика с пониженной частотой для любого рендерера

job_deliveries

Доставки пробуждения для задания, фильтруемые по status

job_mark_delivery

Вручную установить статус доставки

job_retry_delivery

Повторно поставить неудачную доставку в очередь для отправки

job_delivery_attempts

История попыток/аренды для одной доставки

job_stop

Остановить выполняющееся задание (завершить дерево процессов)

job_doctor

Здоровье демона, схема, таблицы, доступность бинарника

job_cleanup

Пробный или реальный удаление старых завершённых заданий

job_start

job_start(
  command="uv run python examples\\long_job.py",
  name="training run",
  cwd="F:\\git\\project",            # optional
  env={"CUDA_VISIBLE_DEVICES": "0"}, # optional
  timeout_seconds=3600,              # optional; None = no timeout
  notify_on=["progress","checkpoint","failed","completed"],
  origin_thread_id="019f...",        # the agent thread that launched it
  tags=["training","gpu"],           # optional
  wake_targets=[...]                 # optional, see below
)

Возвращает job_id, status, worker_pid и пути к логам/событиям.

job_status — просмотр того, что выполняет задание

job_status(job_id="job_...")

Возвращает статус, команду, cwd, env, timeout_seconds, заметки, запуск (автор, имя хоста, ОС, версия Python, CPU/GPU, git репозиторий/ветка/коммит), runtime_seconds, прогресс, последнее событие, связи с потоком, теги и код выхода. Это самый быстрый способ для агента ответить на вопрос "что делает это задание?" — и отражает обзор запуска, который вы бы увидели для запуска в W&B.

Передайте notes="..." в job_start, чтобы аннотировать запуск ("что делает этот запуск особенным?"), что сохраняется при job_rerun и отображается в мониторе.

job_rerun — повторный запуск неудачного задания

job_rerun(job_id="job_...")

Повторно запускает задание с его исходной командой, cwd, окружением, таймаутом, именем, тегами, исходным потоком и целями пробуждения — возвращается новый job_id. Используйте его для повторной попытки неудачной загрузки, нестабильной пакетной обработки или временного сбоя без повторного создания запроса.

job_list — фильтрация по имени или тегу

job_list(status=["running"], name="train", tags=["gpu"], limit=20)

Фильтры: status (список), thread_id, name (подстрока), tags (должны содержать все перечисленные теги).

job_events — прямой порядок или сначала новые

job_events(job_id="job_...", since_event_id="evt_...", limit=20)      # events after the cursor
job_events(job_id="job_...", reverse=true, limit=20)                   # the 20 newest events, newest first

reverse: true возвращает самые последние события (сначала новые) — идеально для вопроса "что произошло недавно?" — и может комбинироваться с since_event_id для обратной навигации по страницам.

job_wait — сердце использования агента

job_wait(job_id="job_...", filters=["checkpoint","failed","completed"], timeout_seconds=3600)
  • ожидает первое событие, соответствующее любому фильтру, возвращая его с текущим статусом;

  • передайте since_event_id, чтобы ожидать только события новее тех, что вы уже видели;

  • по таймауту возвращает result: "timeout"; при завершении демона возвращает result: "shutdown".

job_view — что показывать пользователю

job_view(thread_id="019f...", limit=20)

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

job_stop — остановить выполняющееся задание

job_stop(job_id="job_...", signal="terminate", kill_after_seconds=10)

Завершает дерево процессов задания. Сначала отправляется корректный signal (по умолчанию terminate); если задание не завершилось в течение kill_after_seconds, оно принудительно завершается. Задание переходит в состояние cancelled только после фактического завершения дерева рабочих процессов; в противном случае оно остаётся running, и остановку можно повторить.

job_mark_delivery / job_retry_delivery — ручное управление доставкой

job_mark_delivery(delivery_id="del_...", status="delivered", error="optional reason")
job_retry_delivery(delivery_id="del_...")   # requeue a failed delivery

job_mark_delivery вручную устанавливает статус доставки (например, после решения проблемы с адаптером); job_retry_delivery повторно ставит в очередь неудачную доставку для следующего прохода диспетчеризации. job_delivery_attempts показывает историю захватов/аренды.

job_cleanup — удаление старых завершённых заданий

job_cleanup(older_than_seconds=86400, dry_run=true)   # preview
job_cleanup(older_than_seconds=86400, dry_run=false)  # delete

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

job_metrics_query — чтение сохранённых скалярных рядов

job_metrics_query(job_id="job_...", metric="loss", from_ms=..., to_ms=..., limit=1000)

Возвращает сохранённые ряды для одного задания, сгруппированные по имени метрики. metric фильтрует до одного ряда (например, loss, acc, progress.percent); from_ms/to_ms фильтруют по временной метке события (эпоха в миллисекундах). Точки упорядочены по последовательности событий. Это сторона чтения данных терминального монитора.

job_metric_compare — сравнение метрики между запусками

job_metric_compare(job_ids=["job_a", "job_b"], metric="val_loss", aggregation="min")

Сравнивает одну метрику между заданиями (например, val_loss между сидами или конфигурациями). aggregation может быть latest, mean, min, max, sum или count; результат включает значение для каждого задания плюс первую/последнюю точки. Это примитив в стиле W&B "какой запуск победил?".

job_run_summary — сработало ли?

job_run_summary(job_id="job_...")

Один вызов возвращает статус, имя, время выполнения, код завершения, последний прогресс, заметки, обзор по метрикам (последнее/первое/мин/макс/количество) и прикреплённые артефакты — самый быстрый способ для агента сообщить о завершённом задании.

job_artifact_add / job_artifacts — прикрепление выходных данных

job_artifact_add(job_id="job_...", name="best.pt", uri="file:///...", kind="checkpoint",
                 size_bytes=..., sha256="...", meta={"epoch": 5})
job_artifacts(job_id="job_...")

Прикрепляет артефакты (контрольные точки, CSV, визуализированные результаты) к заданию, чтобы они отображались в job_run_summary и были доступны позже. meta — это свободный JSON.

job_dashboard — данные для построения графиков для любого рендерера

job_dashboard(job_ids=["job_..."], limit=5000)

Возвращает список заданий плюс каждый сохранённый ряд метрик, прореженный до limit точек на ряд — те же данные, которые отображает терминальный монитор Go, доступные через HTTP/MCP, чтобы любой клиент (будущая веб/облачная панель) мог их визуализировать.


Цели пробуждения (пробуждение агента, когда задание требует внимания)

Когда задание генерирует соответствующее событие, демон создаёт надёжную доставку и отправляет её через адаптер. Доставка — как минимум один раз; каждая полезная нагрузка содержит delivery_id для дедупликации.

local_command

Запускает произвольную команду, передавая полезную нагрузку доставки как JSON на stdin:

{
  "type": "local_command",
  "events": ["checkpoint", "failed", "completed"],
  "command": ["python", "deliver.py"]
}

Выход с кодом 0 помечает доставку как delivered; любой другой выход помечает её как failed.

codex_thread

Возобновляет поток Codex через локальный сервер приложений:

{
  "type": "codex_thread",
  "thread_id": "019f...",
  "events": ["checkpoint", "failed", "completed"],
  "codex_command": ["C:\\codex\\codex.exe"]
}

Протокол: initialize -> thread/resume -> turn/start.

opencode_thread

Возобновляет сеанс OpenCode:

{
  "type": "opencode_thread",
  "thread_id": "ses_...",
  "events": ["checkpoint", "failed", "completed"],
  "cwd": "F:\\git\\project",
  "opencode_command": ["opencode"],     # override the binary
  "attach": "http://127.0.0.1:4096",    # submit via an opencode serve instance
  "timeout_seconds": 120
}

Таймаут по умолчанию для хода OpenCode составляет 30 секунд; увеличьте его для длинных ходов.

Общие параметры доставки

{
  "type": "codex_thread",
  "thread_id": "019f...",
  "events": ["checkpoint"],
  "auto_dispatch": false,      // leave the delivery pending for manual inspection
  "max_attempts": 3,           // default 1
  "retry_delay_seconds": 5,    // default 5
  "timeout_seconds": 30        // adapter timeout; also sizes the delivery lease
}

С auto_dispatch: false доставки остаются pending, пока агент не отправит их вручную или не изменит цель.

Операции доставки

job_deliveries(job_id="job_...")
job_delivery_attempts(delivery_id="del_...")
job_retry_delivery(delivery_id="del_...")     # requeue a failed delivery
job_mark_delivery(delivery_id="del_...", status="delivered")

История попыток записывает токен захвата, время начала/окончания, статус и была ли попытка отозвана после истечения аренды. Если демон аварийно завершается после того, как адаптер принял пробуждение, но до того, как Vanth зафиксировал успех, доставка отзывается и повторяется — отображается как попытка reclaimed, а не как доставка ровно один раз.


Запуск демона

На переднем плане (для разработки или диагностики):

uv run vanthd

Параметры автозапуска:

  • Windows: демон запускается из папки автозагрузки пользователя (startup_commands.bat) вместе с другими командами автозагрузки; шаблон действия планировщика задач также находится в deploy/vanthd.cmd.

  • Unix: deploy/vanthd.service — это пользовательская служба systemd.

Разрешается только один демон на VANTH_HOME. Второй демон для того же дома немедленно завершается (блокировка на уровне ОС). Демон привязывается только к loopback (127.0.0.1 / ::1 / localhost); не-loopback VANTH_DAEMON_HOST отклоняется.

Безопасность

  • Каждый маршрут данных требует Authorization: Bearer <token>; токен генерируется для каждого дома и никогда не логируется. GET /health — единственный неаутентифицированный маршрут (дешёвый зонд жизнеспособности для супервизоров).

  • При запуске демона каталог состояния повторно ограничивается владельцем: Unix chmod 0700/0600; Windows отключает наследование ACL и предоставляет доступ только владельцу, SYSTEM и администраторам через icacls. Это блокирует другим учётным записям (например, пользователям песочницы/CI, которые наследуют чтение из профиля пользователя) чтение токена или данных окружения/спецификации для каждого задания.

  • В Windows сокет SO_REUSEADDR отключён, чтобы второй демон не мог стать призрачным слушателем на том же порту; неудачная привязка освобождает блокировку дома и корректно завершается.

Терминальный монитор Go

Встроенная панель Go читает тот же дом только для чтения и отображает живые графики, индикаторы прогресса, точную таблицу событий и хвосты логов:

uv run vanth-monitor

Из собранного колеса vanth-monitor запускает встроенный нативный бинарник (не требуется инструментарий Go). Из исходников он собирает монитор при первом использовании и кэширует его в ~/.cache/vanth/ (требуется go в PATH):

go build -o bin\vanth.exe ./cmd\vanth
bin\vanth.exe monitor

Клавиши: up/down или j/k выбирают задания · enter закрепляет ряд задания · e таблица событий · l хвост лога · +/- масштабирование графика · [/] панорамирование · t назад к живому хвосту · ? справка · q или Ctrl+C выход.


Справочник по конфигурации

Переменные окружения (значения по умолчанию находятся в src/vanth/server.py, src/vanth/daemon.py, src/vanth/migrations.py):

Переменная

По умолчанию

Назначение

VANTH_HOME

~/.vanth

Корень состояния (псевдоним: AGENT_BG_HOME)

VANTH_DAEMON_URL

http://127.0.0.1:8765

Где клиенты обращаются к демону

VANTH_DAEMON_HOST

127.0.0.1

Адрес привязки (только loopback)

VANTH_DAEMON_PORT

8765

Порт привязки

VANTH_MAX_REQUEST_BYTES

1 MiB

Лимит тела HTTP-запроса

VANTH_MAX_RESPONSE_BYTES

4 MiB

Лимит HTTP-ответа

VANTH_MAX_EVENT_BYTES

64 KiB

Лимит полезной нагрузки одного события

VANTH_MAX_EVENT_LINE_BYTES

1 MiB

Лимит строки AGENT_EVENT

VANTH_MAX_LOG_BYTES

10 MiB

Лимит лога на поток (слив продолжается)

VANTH_MAX_EVENTS_PER_JOB

100000

Лимит структурированных событий на задание

VANTH_DELIVERY_POLL_INTERVAL

0.2s

Частота цикла обслуживания

VANTH_DELIVERY_LEASE_MARGIN

5s

Дополнительное время аренды сверх таймаута адаптера

VANTH_RUNNER_HEARTBEAT_INTERVAL

1s

Сердцебиение жизнеспособности исполнителя

VANTH_RUNNER_HEARTBEAT_STALE_AFTER

10s

Порог устаревания сердцебиения

VANTH_CODEX_BIN

codex / C:\codex\codex.exe

Бинарник Codex

VANTH_OPENCODE_BIN

opencode (через shutil.which)

Бинарник OpenCode

VANTH_LOG_LEVEL

INFO

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

VANTH_LOG_MAX_BYTES

5 MiB

Размер ротации лога демона

VANTH_LOG_BACKUP_COUNT

3

Количество ротаций лога демона

VANTH_BUSY_TIMEOUT_MS

30000

Ожидание блокировки записи SQLite


Операции

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

~/.vanth/
  jobs.sqlite      durable jobs (incl. env, notes, run-overview) / events / deliveries / targets / attempts / tombstones
  token            bearer token (owner-only permissions)
  daemon.lock      single-daemon OS lock
  daemon.json      discovery metadata (url, pid, started_at, schema) — written atomically, removed on graceful shutdown
  logs/            daemon.log + per-job runner/stdout/stderr logs
  events/          per-job JSONL event mirrors (monitor fallback source)
  specs/           per-job launch specs (removed once the runner starts)
  backups/         pre-migration SQLite backups

Здоровье, готовность и диагностика

job_doctor()

Сообщает каталог состояния, таблицы базы данных, количество доставок по статусу, версию схемы, PRAGMA quick_check, просроченные аренды доставок, свободное место на диске, путь к токену и разрешаются ли бинарники Codex/OpenCode. Он никогда не раскрывает токен.

HTTP-демон также предоставляет:

  • GET /health — дешёвый, неаутентифицированный зонд жизнеспособности для супервизоров;

  • GET /ready — аутентифицированная готовность (отчёт доктора; 503, если не в порядке).

Обновления и резервное копирование

Изменения схемы — это упорядоченные миграции SQLite. Перед первой миграцией существующей базы данных создаётся резервная копия с временной меткой в каталоге backups/ через API резервного копирования SQLite (никогда не копируется сырой файл, пока активен WAL). Для ручного обновления сначала скопируйте последний backups/*.sqlite. Будущая схема базы данных отклоняется без изменения файлов.


HTTP API (эквивалент инструментов MCP)

Аутентифицируется с помощью Authorization: Bearer <token>.

Метод

Путь

Назначение

GET

/jobs

Список заданий (status, limit, thread_id, name, tags)

POST

/jobs

Запустить задание

POST

/jobs/{id}/rerun

Повторно запустить задание с его исходной конфигурацией

GET

/jobs/{id}/status

Статус задания (включает command/env/cwd)

GET

/jobs/{id}/events

События (since_event_id, types, limit, reverse)

GET

/jobs/{id}/metrics

Ряд метрик (metric, from_ms, to_ms, limit)

GET

/jobs/{id}/summary

Сводка запуска (status, runtime, metrics, artifacts)

GET

/jobs/{id}/artifacts

Артефакты (limit)

POST

/jobs/{id}/artifacts

Добавить артефакт

GET

/metrics/compare

Сравнить метрику между заданиями (job_ids, metric, aggregation)

GET

/dashboard

Данные диаграммы (job_ids, limit)

GET

/jobs/{id}/tail

Хвост лога (stream, max_bytes, offset)

POST

/jobs/{id}/wait

Ожидать событие

POST

/jobs/{id}/stop

Остановить задание

GET

/view

Представление агента (thread_id, limit)

GET

/deliveries

Доставки (job_id, status, limit)

GET

/deliveries/{id}/attempts

История попыток

POST

/deliveries/{id}/mark

Отметить доставку

POST

/deliveries/{id}/retry

Повторить доставку

POST

/cleanup

Очистка (older_than_seconds, dry_run)

GET

/doctor

Отчёт о состоянии

GET

/health

Проверка доступности без аутентификации


Советы по использованию агента

  1. Ожидайте, не опрашивайте. Используйте job_wait(job_id, filters=[...], timeout_seconds=...) вместо циклического вызова job_status. Демон немедленно пробуждает ожидание, как только соответствующее событие сохраняется.

  2. Передавайте since_event_id следующему job_wait после обработки события, чтобы не обрабатывать старое повторно.

  3. Помечайте и группируйте задания. Устанавливайте origin_thread_id (поток агента, запустившего задание) и tags; используйте job_view(thread_id=...) для сводки.

  4. Отдавайте предпочтение job_view перед job_status при представлении ситуации пользователю — он уже отсортирован по приоритету внимания.

  5. Делайте задания самоописываемыми. Выводите строки AGENT_EVENT progress / checkpoint / metric (см. выше). Тихие задания тоже работают, но задания с отслеживанием гораздо проще анализировать.

  6. Используйте цели пробуждения для долгих заданий. Если тренировочный прогон или длительная загрузка требуют решения на контрольной точке, добавьте цель codex_thread или opencode_thread с events: ["checkpoint", "failed", "completed"], чтобы агент возобновлял работу, а не опрашивал.

  7. Проверяйте сбои доставки. job_delivery_attempts показывает историю аренды/захвата; job_retry_delivery повторно ставит в очередь неудачную доставку после устранения причины.

  8. Устанавливайте разумное значение timeout_seconds в job_start, чтобы зависшая команда переходила в состояние timeout (конечное) вместо бесконечного выполнения; исполнитель обеспечивает это даже при перезапусках демона.

  9. Очищайте старые состояния с помощью job_cleanup(older_than_seconds=..., dry_run=false), чтобы хранилище SQLite и файлы логов оставались ограниченными.

  10. Перезапускайте упавшие задания, не создавайте их заново. job_rerun(job_id=...) запускает повторно с исходной командой, окружением, рабочей директорией и целями пробуждения — идеально для повторной попытки временно неудачной загрузки или пакета.

  11. Спрашивайте «что это за задание?» с помощью job_status. Теперь он возвращает команду, рабочую директорию, окружение и таймаут, так что вы можете объяснить задание пользователю без чтения логов.

  12. Фильтруйте списки по имени/тегу. job_list(name="train", tags=["gpu"]) сужает растущий список заданий без перелистывания всего.

  13. Используйте reverse=true для «что произошло недавно». job_events(job_id, reverse=true, limit=20) возвращает сначала самые новые события, а листать назад можно с помощью since_event_id, указывая старейший просмотренный идентификатор.

  14. Задание переживает демона. Исполнитель отсоединён; задания продолжают работать при перезапусках демона/MCP. Если исполнитель исчез при восстановлении, задание помечается как orphaned (никогда не удаляется молча).


Примеры

uv run python examples\long_job.py    # emits progress + checkpoints

examples/long_job.py — небольшое эталонное задание, использующее vanth.agent_events. Запустите его через job_start и наблюдайте в vanth monitor.


Устранение неполадок

  • Unauthorized (401): носитель токена в ~/.vanth/token — это то, что ожидает демон. Убедитесь, что VANTH_HOME одинаков для демона и клиента.

  • Второй демон не запускается: another vanthd already owns this VANTH_HOME. Один демон на один домен по замыслу.

  • Задание зависло в состоянии running, затем orphaned: процесс исполнителя завершился. Проверьте logs/<job_id>.runner.log и пороги пульса.

  • В мониторе нет графиков: задание не выводит строки AGENT_EVENT metric или progress — добавьте их (опционально).

  • Таймаут пробуждения OpenCode: увеличьте timeout_seconds для цели пробуждения сверх ожидаемой продолжительности такта.

  • Монитор показывает пустое состояние: убедитесь, что VANTH_HOME указывает на домашнюю папку демона и что jobs.sqlite существует в ней.


Разработка

uv run pytest -q                 # Python suite (112 passed, 1 Linux-only skip)
uv run python -m compileall -q src tests examples
uv build                         # sdist + wheel; wheel bundles the Go monitor
go vet ./... && go test ./...    # Go: config, state, monitor

Сборка колеса запускает хуок сборки hatchling (build-hooks/bundle_monitor.py), который компилирует Go-монитор для хост-платформы и упаковывает его в vanth/monitor-bin/, поэтому vanth-monitor не требует инструментария Go во время выполнения. go должен быть в PATH при сборке колеса; для установки или запуска он не нужен. Колёса помечены платформой (py3-none-<platform>), поскольку содержат нативный бинарник.

Автоматизация выпуска находится в scripts/:

  • scripts/chaos_matrix.py — тяжёлые синтетические нагрузки и матрица убийства/перезапуска;

  • scripts/real_adapter_smoke.py — опциональное живое дымовое тестирование Codex/OpenCode (установите VANTH_SMOKE_CODEX_THREAD / VANTH_SMOKE_OPENCODE_SESSION);

  • scripts/generate_go_fixture.py — регенерирует детерминированный фикстур соответствия схемы v5 в testdata/;

  • scripts/demo_jobs.py — запускает демонстрационные задания (тренировочный прогон, быстрая задача, сбойная задача) для монитора.

Ограничения (v1)

  • Интерактивный stdin и job_send не реализованы; задания выполняются с закрытым stdin (используйте неинтерактивные флаги в командах).

  • Доставка как минимум однократная; сбой после того, как адаптер принял пробуждение, но до того, как Vanth записал успех, — это задокументированная, явная неоднозначность.

  • Удалённый доступ, TLS, многопользовательская политика, квоты, распределённые рабочие и собственный менеджер служб выходят за рамки.

A
license - permissive license
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • Git-backed platform for skills, tools, and context for AI agents

  • Persistent memory and knowledge management for AI agents with semantic search and 50+ tools.

  • Reliable async execution for agent tool calls: schema gating, retries, idempotency, audit trail.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/abhim-dv/vanth'

If you have feedback or need assistance with the MCP directory API, please join our Discord server