Skip to content

Воркфлоу агентов ​

Воркфлоу связывает агентов в цепочку: триггер, затем шаги, которые сервер выполняет сверху вниз, — шаги агентов (обычные задачи агентов), согласования, где решает человек там, где проверяют работу, детерминированные действия и вызовы других воркфлоу. Выполнение воркфлоу называется запуском.

Эндпоинты /api/workflows входят в модуль agents (тариф Pro). Запросы, кроме GET, подпадают под лимит ИИ-запросов — см. Ограничения частоты запросов.

Права и владелец ​

  • workflows:read — у всех ролей.
  • workflows:write — у editor, lead и администраторов.
  • workflows:run — у них же; API-ключ со scope workflows:run может запускать воркфлоу.

Запуск действует от имени владельца воркфлоу — того, кто последним сохранил или включил его, — с ролью владельца в проекте на момент старта запуска. Тот, кто запустил, записывается в startedBy и в журнал аудита вместе с входными данными. Сохранение отклоняет воркфлоу, шаги которого требуют прав, которых нет у сохраняющего (403 с missing). Если владельца удалили, деактивировали или он потерял право, воркфлоу помечается ownerProblem, и его запуски не стартуют, пока кто-нибудь не сохранит его заново.

Определение ​

definition: { name?, description?, trigger, limits?: { maxTokens?, maxItems? }, outputs?, steps[] }.

Триггер ​

trigger — один из вариантов:

  • { type: "manual", inputs?: { <name>: { type: "string", pattern?, maxLength? (≤ 200) } | { type: "enum", values } | { type: "number", min?, max? } | { type: "boolean" } | { type: "array", items, maxItems } }, runRoles? }
  • { type: "schedule", cron, timezone? }
  • { type: "run.imported", branches? (globs), onlyWithFailures? (true), sources?, includeAutotestBranches? (false) }
  • { type: "requirement.changed", sourceKinds?, keyPrefix? }

runRoles ограничивает, кто может запускать ручной воркфлоу; API-ключ считается ролью ci_runner, поэтому укажите её для воркфлоу, который должен запускать CI.

Шаги ​

  • { type: "agent", agent: agent0_coverage | agent1_generate | agent2_codegen | agent2_verify | agent3_triage | custom_agent, params }
  • { type: "approval", gate: agent1_drafts | merge_request | defect | confirm, of?, where?, show?, message?, auto? }
  • { type: "action", action: regression_suggest | create_run, params }
  • { type: "workflow", workflow: <slug>, inputs }
  • { type: "classify", question, show, choices: { <key>: what belongs to it } (2–10), minConfidence? (60) }

У любого шага может быть when, а у шагов agent, workflow и classify — forEach, maxItems (20; 5 для agent2_verify; не больше 50), overflow (fail | truncate), concurrency, onError (stop | continue).

Шаг classify ​

Шаг classify поручает модели отнести то, что содержит show, к одному из вариантов; на выходе — { choice, suggested, confidencePct, reason, input } (input — то, что классифицировалось). Ниже minConfidence или если модель не назвала ни один из вариантов, choice равно unsure, а suggested хранит, к чему она склонялась.

Последующие шаги ветвятся через when по steps.<id>.output.choice, а для шага classify, выполненного с forEach, — через forEach по steps.<id>.output и when по item.choice. Условие, сравнивающее поле со значением, которое оно никогда не принимает (вариант, которого шаг не предлагает, classification Агента 3, отличная от backend_defect, frontend_regression, flake или unknown), отклоняется при сохранении.

Согласование дефектов, черновиков или merge request может проверять работу через шаг classify, который прошёл по выходу своего агента, показывая каждый элемент (show: { "$ref": "item" }): его where читает item.choice (если туда входит unsure, сомнительные элементы тоже уходят человеку), и на ревью попадают элементы агента. Модель — classify в моделях агентов в настройках; шагу нужно право agents:write владельца, как и шагу агента.

Значения и условия ​

Значения — литералы или ссылки { "$ref": "trigger.<input>" | "steps.<id>.output.<field>" | "item.<field>", prefix?, suffix? }. Условия — { path, op: eq|neq|in|gt|gte|lt|lte|exists, value }, объединяются через { all: [...] } / { any: [...] }. Некоторые параметры задаются в определении и не могут быть ссылками (навыки, фреймворки, файлы воркфлоу CI, slug своего агента), поэтому тот, кто запускает воркфлоу, не может повлиять на то, с чем выполняются шаги владельца.

У выхода каждого типа шага фиксированные поля (например, agent1_generate → draftIds; согласование agent1_drafts → approvedCases: [{ id, title, priority }]; merge_request → artifactIds); POST /validate называет их, если ссылка неверна.

Воркфлоу проекта ​

  • GET /api/workflows — воркфлоу проекта с триггером, владельцем, ownerProblem, nextRunAt и последним запуском.
  • POST /api/workflows { slug, name, description?, definition, enabled? } (workflows:write) — 400 с errors для определения, которое не проходит проверку, и dependencyProblems — чего не хватает проекту (своего агента нет или он не проверен: тогда воркфлоу сохраняется только выключенным).
  • GET, PUT (с version; 409 version_conflict) и DELETE/api/workflows/:slug. DELETE отвечает 409, пока есть активные запуски или его вызывают другие воркфлоу.
  • GET /api/workflows/:slug/callers (workflows:read) — эти другие воркфлоу; по ним и нужно разрешать 409.
  • PATCH /api/workflows/:slug { enabled, version? } включает или выключает триггеры; включение заново проверяет воркфлоу и делает вызывающего его владельцем.

Slug runs, templates, validate, gates, events и chat зарезервированы.

POST /api/workflows/validate { definition, slug? } — проверка редактора, ничего не сохраняет: { valid, errors, warnings, dependencyProblems, permissions, estimate: { modelCalls, maxMinutes, note } }. Циклы вызовов (на любой глубине), вызовы глубже 3 уровней и входные данные, которые вызываемый воркфлоу не принимает, — ошибки.

Запуски ​

  • POST /api/workflows/:slug/runs { inputs } (workflows:run) — ручной запуск; входные данные проверяются по типам триггера (400 с details). Ответ — 202 с запуском.
  • GET /api/workflows/:slug/runs, GET /api/workflows/runs?status= (active — ожидающие, выполняющиеся и ждущие) — запуски, сначала новые.
  • GET /api/workflows/runs/:id — запуск с шагами (по строке на шаг и на каждый элемент forEach: статус, id задачи, выход, ошибка, попытки), элементами согласований, вызванными им запусками и токенами, потраченными всем деревом.
  • GET /api/workflows/runs/:id/stream присылает события snapshot, пока запуск идёт, и end, когда он завершается.
  • POST /api/workflows/runs/:id/cancel (workflows:run) — останавливает запуск, его задачи и вызванные им запуски; созданные черновики и автотесты остаются.
  • POST /api/workflows/runs/:id/steps/:stepRunId/retry (workflows:run) выполняет упавший шаг (или его упавшие элементы) заново в упавшем запуске.

Согласования ​

GET /api/workflows/gates — все согласования проекта, ждущие решения, с путём от корневого запуска («Requirement → autotest › Autotest for important cases › Open the merge requests») и правом, которое нужно для решения.

Согласования решаются там, где проверяют работу: одобрение и отбрасывание черновиков в очереди ревью Агента 1, открытие merge request (POST /api/repo/merge-request), заведение дефекта по результату. Запуск также принимает, с правом, которое нужно этому согласованию:

  • POST /api/workflows/runs/:id/steps/:stepRunId/finish{ remaining: "discard" | "detach" } — закрывает ревью с тем, что решено (остальные черновики отбрасываются или остаются в очереди сами по себе; неоткрытые merge requests просто отпускаются);
  • .../items/:objectId/dismiss — откладывает один автотест или результат;
  • .../confirm { continue } — решает согласование confirm.

Согласование, ждущее 14 дней, закрывает запуск как expired.

Триггеры по событиям ​

Импорт из CI (POST /api/runs/import) и проверка изменившихся требований записывают событие один раз на сборку или версию источника; сервер запускает подходящие включённые воркфлоу в течение десяти секунд.

  • Прогон, импортированный из ветки autotest/, ничего не запускает, если триггер не говорит иначе.
  • Импорт пайплайна, который запустил запуск воркфлоу, не запускает этот воркфлоу снова.
  • Воркфлоу запускается от событий и расписаний не больше 10 раз в час — то, что отклонено, видно в его запусках как skipped с причиной.
  • Расписание срабатывает один раз на каждое время; время, пропущенное, пока сервер не работал, не навёрстывается.

Лимиты ​

  • Задачи воркфлоу занимают не больше 2 из 3 мест проекта для задач агентов и не больше одной agent2_verify одновременно; шаг без свободного места ждёт (queued).
  • limits.maxTokens запуска распространяется на вызванные им запуски; токен, прочитанный из кеша промптов провайдера, считается как десятая часть, как он и тарифицируется (так же считается суточный KVALLI_LLM_DAILY_TOKENS).
  • Завершённые запуски хранятся 90 дней.
  • KVALLI_MAX_WORKFLOWS_PER_PROJECT (50), KVALLI_MAX_WORKFLOW_TEMPLATES (100).

Шаблоны ​

  • GET /api/workflows/templates — встроенные шаблоны и шаблоны организации.
  • POST /api/workflows/templates/:slug/instantiate (workflows:write) копирует шаблон в проект вместе с вызываемыми им воркфлоу, выключенным, и перечисляет, чего не хватает проекту.
  • POST /api/workflows/:slug/publish-template { templateSlug? } и DELETE /api/workflows/templates/:slug — для администраторов установки.

Копия — не ссылка: последующие изменения шаблона до неё не доходят.

Сборка воркфлоу в чате ​

POST /api/workflows/chat { messages: [{ role, content }], draft?, slug? } (workflows:write) составляет определение в беседе с моделью, которую настройки отводят чату воркфлоу (llm.agentModels.chat). Модель отвечает через инструменты (function calling в Gemini, OpenAI-совместимых провайдерах, Claude и Ollama): она может перечислить воркфлоу проекта, своих агентов и шаблоны и предлагает определение целиком, которое валидатор проверяет и возвращает ей на исправление. Ответ — { reply, proposal?: { definition, summary, validation }, steps }. Ничего не сохраняется.

Документация описывает последний выпуск Kvalli.