Тема
Чат
Чат в боковой панели: беседы человека в проекте, которые сохраняются. Эндпоинты /api/chat входят в модуль agents (тариф Pro). Запросы, кроме GET, подпадают под лимит ИИ-запросов — см. Ограничения частоты запросов.
Что умеет чат
Чат отвечает по данным проекта: недавние падения, прогоны и их упавшие результаты, тест-кейсы (подсчёт и фильтр по приоритету, статусу, папке, тегу и автоматизации или один кейс целиком с последними результатами), запуски воркфлоу, то, что ждёт решения. Он составляет воркфлоу (как POST /api/workflows/chat) и предлагает запустить воркфлоу или агента: Агента 0, Агента 1 по задаче Jira или странице Confluence, Агента 2 для одного тест-кейса по его ключу, Агента 3 для одного упавшего результата. Разовая работа уходит агенту; воркфлоу составляется, только когда его просят, или для работы, которая повторяется или реагирует на события сама.
Карточка Агента 2 также открывает панель Агента 2 с выбранным кейсом (/agents/agent2?case=TC-12), чтобы сменить стек перед написанием или посмотреть код. Карточка подтверждённого агента следит за его задачей и сохраняет, к чему он пришёл, в result.outcome: поля, которые вывел бы его шаг воркфлоу, а для Агента 2 — имя файла спеки, проверку кода и её первые 60 строк.
Кейсы и прогоны
Чат записывает тест-кейсы и ручные прогоны проекта:
- создаёт кейс, меняет поля кейса (отказ, если кейс правили после того, как была выставлена карточка), перемещает кейсы в папку, отправляет кейсы в корзину (не больше 50);
- запускает ручной прогон по названным кейсам или тест-плану;
- записывает один вердикт для результатов названных кейсов, названных результатов или всех непроверенных;
- запускает перезапуск упавших кейсов прогона (или всех);
- закрывает прогон (с непроверенными результатами — только если человек сказал пометить их пропущенными);
- заводит дефект в трекере по упавшему или заблокированному результату (по его кейсу или itemId; отказ без подключённого трекера) и привязывает его к результату (
result.defectKey,defectUrl).
Свой агент проекта запускается как custom_agent по slug; агент, не проверенный после последнего изменения, выполняется как пробный запуск — так же, как его запускает его экран, — и проверяется снова при подтверждении карточки.
Планирование
- Тест-планы: создать; изменить название, описание, добавить или убрать кейсы, майлстоун; удалить.
- Майлстоуны: создать, изменить, завершить (с идущими прогонами — только если человек так сказал), открыть заново, удалить.
- Группы конфигураций прогонов: создать или изменить варианты, удалить; нужно
settings:write. - Сохранённые воркфлоу: сохранить определение, которое предложил чат, включить или выключить, удалить; в аудите — с
via: "chat". - Отчёт и публичная ссылка на него (
reports:share, модуль analytics). Ссылка есть только в ответе на подтверждение (result.shareUrl), а сохранённая карточка говоритshared: true— так же, как экран «Отчёты» выдаёт ссылку один раз.
Ревью и ежедневная работа
- Утверждает кейс, помечает его устаревшим или возвращает в черновики и возвращает на доработку с замечанием (
cases:approve). - Ставит теги кейсам, комментирует их.
- Восстанавливает кейсы и прогоны из корзины.
- Выдаёт результаты прогона человеку или забирает их.
- Запускает CI-пайплайн проекта (
pipelines:trigger, модуль ci). suggest_regression— запрос к подбору регрессии, чьи кейсы затем берёт карточка тест-плана или прогона.- Ведёт исследовательские сессии (начать, делать заметки, завершить), общие шаги (изменение применяется ко всем кейсам, которые его используют) и требования (создать, изменить, привязать или отвязать кейсы).
Починка тестов
heal_locatorчитает код теста упавшего результата (автоматизацию кейса или автотест Агента 2) и ошибку и отвечает исправлением локатора, ничего не записывая (healing:write, модуль healing).heal_on_standлечит тест упавшего результата на стенде проекта так же, как кнопка «Починить на стенде» Агента 3: запуск там, починка по странице в месте падения (сначала починщик локаторов, затем модель для роли сmodels:use), повторный запуск. Карточка сохраняетresult.heal { status, healedBy, diff, verified }; исправление — только если тест прошёл. Нужныhealing:write, модули healing и browser, браузерный воркер и стенд проекта; запускается автотест, который Агент 2 написал для кейса, иначе автоматизация кейса (Playwright TypeScript).
Комментарий ручного результата читается как описание того, что упало, — и чатом, и Агентом 3.
От требования до автотеста
list_drafts— черновики Агента 1; чат утверждает их в кейсы или отбрасывает.open_merge_request— открывает merge request с автотестом Агента 2; отказ проверки кода предлагается повторить сforce, только если человек так скажет.verify_in_ci— запуск в CI (карточкаagent2_verify;pipelines:trigger, открытый merge request).open_healing_mr— открывает merge request с исправлением, вылеченным на стенде (исправленный файл остаётся на карточке починки и никогда не проходит через модель).decide_gate— решает, чего ждёт воркфлоу: продолжить или остановить шаг confirm, завершить или отсоединить шаг ревью, отложить один элемент; с собственным правом согласования.waiting_decisionsназывает запуск и шаг (stepRunId) и ожидающие элементы.
История сообщает модели, к чему пришёл запущенный ею агент. Импорт результатов из чата не выполняется: для него нужен файл (но см. вложения).
Ограничения
Все эти действия проходят через те же функции, что и маршруты кейсов и прогонов, с теми же проверками и журналом изменений. Выполненная карточка называет кейс (result.caseId) или ручной прогон (result.testRun), который она создала или изменила. get_run перечисляет все результаты ручного прогона со статусами. Администрирование (люди, роли, ключи, настройки) из чата не выполняется.
Сам чат никогда ничего не запускает и не записывает: запрос — это карточка действия, и она выполняется, только когда человек её подтверждает, с его собственными правами (workflows:run для воркфлоу, agents:write для агента, cases:write / cases:delete для кейсов, runs:write для прогонов). Модель — llm.agentModels.chat.
Доступ и хранение
Для чата нужно право chat:use (у всех ролей, кроме demo: анонимные посетители делят одну роль и делили бы один список чатов). Беседа принадлежит её владельцу — учётной записи в проекте, где она начата (в открытом режиме — роли). Человек, удалённый из проекта, теряет свои чаты в нём; чат без сообщений в течение KVALLI_CHAT_RETENTION_DAYS (180) удаляется ежедневной очисткой. Деактивация учётной записи чаты сохраняет.
Беседы
GET /api/chat/conversations, POST /api/chat/conversations { title? }, GET / PATCH { title } / DELETE /api/chat/conversations/:id — сообщения приходят вместе с беседой: { role, content, steps, proposal, actions }.
Сообщения
POST /api/chat/conversations/:id/messages { content } — задать вопрос (нужно models:use: наблюдатель может читать беседы, но не спрашивать). Предыдущие ходы передаются модели из базы данных вместе с тем, что стало с каждым действием. Ответ — { question, reply }. Если модель не может ответить (нет ключа: 503, превышен бюджет: 429), вопрос сохраняется, а ошибка объясняет причину.
Потоковый ответ
С Accept: text/event-stream ответ передаётся по мере генерации (так спрашивает страница чата):
question— вопрос в сохранённом виде;stepна каждый запрос к данным ({ text });text({ delta }) — слова по мере того, как их пишет модель;reset— слова до этого момента были продолжены запросами к данным и не являются ответом;- затем
done({ question, reply }) илиerror({ status, error, question }).
Потоковую передачу поддерживают все провайдеры моделей; строка-комментарий каждые 15 с не даёт прокси закрыть молчащий поток. Чат просит модель думать так мало, как она позволяет (Gemini Flash: без размышлений; Gemini 3 Pro: thinkingLevel: "low"; модели рассуждений OpenAI: reasoning_effort: "low"); агенты думают как прежде.
Вложения
attachment: { name, content, base64?, mediaType? } отправляет файл вместе с вопросом: отчёт с результатами — текстом (JUnit XML, Playwright JSON или CSV с результатами), всё остальное — текстом или в base64 (base64: true), не больше 9,5 МБ в любом случае. Файл, который выглядит как отчёт, но не содержит результатов, или CSV-экспорт тест-кейсов сохраняется как файл.
Модели сообщается, что это за файл, но никогда — его содержимое:
- карточка
import_resultsимпортирует отчёт как прогон, один раз, так же какPOST /api/runs; attach_fileприкладывает любой файл к тест-кейсу или к результату прогона;import_casesимпортирует тест-кейсы из экспорта (Kvalli или Qase, CSV или JSON; TestRail CSV; Allure TestOps CSV — формат определяется по файлу).
Тогда вопрос несёт attachment: { name, kind, format, total, passed, failed, importedAs? } для отчёта и { name, kind: "file", mediaType, size } для любого другого файла.
Карточки действий
POST /api/chat/conversations/:id/actions/:actionId{ decision: "confirm" | "cancel" }— запускает (или отменяет) то, что просит карточка действия, один раз; карточка записывает запущенный прогон или задачу либо причину, по которой ничего не запущено (409, если решение уже принято). Воркфлоу, запущенный так, попадает в аудит сvia: "chat".POST /api/chat/conversations/:id/actions/:actionId/follow-up— когда агент, запущенный карточкой, завершился (его итог есть на карточке), чат отвечает, что из этого вышло и каков следующий шаг, — карточкой, если шаг её требует. Нужноmodels:use; передаётся потоком, как/messages, если запрошенtext/event-stream, иначе —{ reply }. Выполняется один раз на карточку (409, если уже было или агент ещё не завершился); карточка помечаетсяfollowedUp.- Карточка, которая запустила воркфлоу или план (
start_workflow,run_plan), отслеживается на каждой остановке его запуска — ожидание на согласовании, сбой, завершение — и при чтении чата на карточку записываетсяoutcome{ stop, status, step, error?, ended? }; по каждой остановке follow-up выполняется один раз (followedStop). - Ещё ожидающую карточку, от которой человек отказался словами, чат отзывает своим ответом: её
statusстановитсяwithdrawn, подтверждение получает 409, а ответ (событиеdoneили JSON-тело) несёт изменённые им прежние сообщения какchanged. - Карточка
cases_from_resultsделает то же, что кнопка «Создать кейсы» в прогоне (кейсы из результатов): черновик на каждый тест CI-прогона без кейса, в папке с именем прогона без номера сборки (или вfolder), с привязкой результатов.get_runсообщает моделиresultsWithoutCase— сколько результатов прогона без кейса. Карточкаlink_resultпривязывает результат (поitemIdили названию теста) к существующему кейсу; результаты того же теста в других браузерах привязываются вместе с ним. Обе требуютruns:writeиcases:write. - Карточка
run_planвыполняет цепочку шагов один раз: после подтверждения она сохраняется как скрытый воркфлоу (не выводится вGET /api/workflows, не учитывается в квоте), владелец которого — этот человек, и запускается; карточка записываетrunId.
Настройки чата
GET /api/chat/settings (chat:use), PUT /api/chat/settings{ analysisWithoutConfirm } (settings:write) — настройки чата проекта («Настройки → Чат», флажок «Запускать анализ без подтверждения»). С analysisWithoutConfirm чат запускает agent0_coverage и agent3_triage без карточки (карточка приходит сразу done, с jobId); все остальные агенты и записи по-прежнему ждут подтверждения.