🤖 AI-агенты для бизнеса

11. Cron-задания — агенты по расписанию

🔵 Agent OS умеет запускать агента по расписанию, без пользователя. Cron-задание впрыскивает промпт в сессию шаблона и запускает один ход — ровно как чат-запрос, поэтому бюджеты, хуки, инструменты и событийное хранилище ведут себя одинаково. Итоговый ответ доставляется в один или несколько sink'ов.

Где задаются

1. На агента — список cron: в config/agents/<agent>/agent.yaml (template по умолчанию = сам агент):

# config/agents/rss/agent.yaml
cron:
  - name: morning-digest
    schedule: "0 0 9 * * *"
    prompt: "Резюмируй сегодняшние заголовки."
    notify: [{ type: log }]

2. Глобальноconfig/cron.yaml (каждое задание называет template):

# config/cron.yaml
jobs:
  - name: morning-digest
    template: rss
    schedule: "0 0 9 * * *"
    prompt: "Резюмируй сегодняшние заголовки."

При коллизии имён config/cron.yaml выигрывает у agent.yaml. Оба источника hot-reload'ятся; динамические (скриптовые) задания независимы от обоих.

Справочник задания

Поле Тип Смысл
name string (обязат.) уникальный id задания
template string шаблон для запуска (в agent.yaml — неявный)
schedule string cron-выражение: sec min hour dom month dow (UTC)
timezone string IANA-таймзона (напр. Europe/Moscow), в которой интерпретируется schedule; по умолчанию UTC
interval_secs int фиксированный интервал (альтернатива schedule)
oneshot_at string RFC 3339 время — сработать разово, затем уйти
prompt string (обязат.) сообщение пользователя, впрыскиваемое в сессию
persistent bool true переиспользует сессию cron:<name> (хранит контекст); по умолчанию false
timeout_secs int лимит одного запуска
overlap string skip (по умолч.) | queue | parallel
retry map { max, backoff_secs } (зарезервировано)
enabled bool по умолчанию true
notify list куда доставляется результат (sink'и ниже)

Ровно одно из schedule / interval_secs / oneshot_at должно быть задано.

Sink'и

У задания может быть любая комбинация sink'ов. Без notify результат доступен только через историю запусков (GET /v1/cron, cron.db).

type Что делает Поля
log пишет ответ в лог сервера
webhook POST результата (JSON) на URL url, token_env (опциональный bearer из env)
telegram отправляет ответ в чат Telegram chat_id, token_env (опц.; по умолчанию — бот шаблона)
messages_db персистит ответ в message store scope (по умолчанию cron:run:<name>)
agent подаёт ответ другому агенту как сообщение template, session (опц.), run (по умолч. true), prompt_wrap (опц., {result})
email шлёт ответ по SMTP to, subject (опц.; по умолчанию имя задания), smtp
workflow запускает воркфлоу (игнорирует запуск агента) name, input

Пример с несколькими sink'ами:

notify:
  - type: log
  - type: webhook
    url: "https://hooks.example.com/ingest"
    token_env: "CRON_WEBHOOK_SECRET"
  - type: telegram
    chat_id: 123456789
  - type: messages_db
    scope: "cron:reports"
  - type: agent
    template: summarizer
    session: "pipeline:reports"
    run: true
    prompt_wrap: "Новый отчёт:\n{result}"
  - type: email
    to: "ops@example.com"
    subject: "Cron: reports"
    smtp:
      host: "smtp.example.com"
      username: "agent@example.com"
      password_env: "SMTP_PASSWORD"
      from: "agent@example.com"

Скриптовый API

Скрипты инструментов и хуков могут планировать задания в рантайме (контракт общий для Rhai и JS). Эти задания — dynamic, персистятся через рестарты.

const r = schedule_cron({
    name: "watch-price",
    template: "hello-agent",
    interval_secs: 3600,
    prompt: "Проверь цену и сообщи.",
});
// r = { name: "watch-price", ok: true }

const gone = cancel_cron("watch-price");   // -> bool
const jobs = list_cron();                  // -> массив статусов заданий

schedule_cron возвращает { name, ok, error? }; cancel_cron(name) — bool; list_cron() — массив статусов (name, template, schedule, last run). Ошибки бросают только когда cron-сервис не подключён (например hook_tool без сервера).

История и мониторинг

Каждый запуск пишется в logs/cron.db (таблица cron_runs) со статусом (success / error / budget_exhausted / rate_limited / timeout), числом токенов, оценкой стоимости и таймингами.

Примечания