> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hubtalk.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# 20. Тесты и Copilot

> Проверка, чат-тест, голосовой звонок и чтение трейса диалога.

# Проверка, чат-тест, голосовой тест, Copilot

<Info>
  **Цель модуля:** находить ошибки до клиента и уметь читать трейс диалога.
</Info>

Три инструмента проверки, от дешёвого к дорогому: **Проверка** (мгновенно, без моделей), **чат-тест** (реальный движок, без телефонии), **голосовой звонок в браузере** (реальный голос, реальные задержки).

<Frame caption="Проверка. Ошибки блокируют публикацию, предупреждения — нет. Здесь честное предупреждение учебного агента: напоминание при молчании (8 с) прозвучит раньше таймера ответа (12 с).">
  <img src="https://mintcdn.com/hubtalk/GMvtjWdqWk0BhtuQ/images/tutorial/tut-39-validation-panel.webp?fit=max&auto=format&n=GMvtjWdqWk0BhtuQ&q=85&s=1fff0c6842114c7ee37f5cc87202209d" alt="Панель «Проверка» с одним предупреждением" width="760" height="497" data-path="images/tutorial/tut-39-validation-panel.webp" />
</Frame>

Клик по находке **показывает нужный узел на холсте**: холст панорамируется к нему, даже если узел был за пределами видимой части. Повторный клик по той же находке возвращает к узлу — удобно, когда правишь и снова теряешь его из вида. Находки уровня всего флоу (не привязанные к узлу) кликабельными не выглядят: у них некуда переходить.

<Frame caption="Тест → Голосовой звонок. Звонок из браузера по черновику или по опубликованной версии, со своими переменными звонка и экспортом метрик задержки.">
  <img src="https://mintcdn.com/hubtalk/cKl-cjuDGhk4sToG/images/tutorial/tut-40-test-voice.webp?fit=max&auto=format&n=cKl-cjuDGhk4sToG&q=85&s=327007fc890a9542c0e03ea173b5c941" alt="Тест-панель, вкладка «Голосовой звонок»" width="1280" height="1181" data-path="images/tutorial/tut-40-test-voice.webp" />
</Frame>

## Старт теста с выбранной ноды

Ноду в середине графа не нужно **доразговаривать** от начала: разговор идёт по рёбрам от Begin через приветствие, сбор данных и ветвления, и попасть в нужную ветку с первой попытки удаётся не всегда — одна фраза не так понята классификатором, и разговор ушёл в соседнюю ветку.

**Выделите ноду на канвасе** — и в тест-панели появится кнопка **«▶ С ноды `<имя>`»**. Сессия начинается сразу с неё: ребро от Begin не проходится, нода исполняется тем же механизмом, что при обычном приходе по ребру. Работает и в чате, и в голосовом тесте. **«↺ Заново»** перезапускает с той же ноды, поэтому один участок можно прокрутить подряд сколько угодно раз.

Без выделения и на ноде Begin кнопки нет — предлагать бессмысленное действие незачем.

В **Истории сессии** старт с ноды помечен отдельным событием с именем ноды: читающий запись не гадает, почему разговор начался с середины.

<Warning>
  **Переменные пути не заполняются — это главное, что нужно знать.**

  Сессия получает только значения по умолчанию из флоу. Если нода читает переменную, которую заполняет нода выше по пути, переменная будет **пустой**, и нода поведёт себя не так, как в живом разговоре. Это не дефект: собрать такие значения автоматически нельзя надёжно — в переменные пишут ещё и глобальные ноды, и результаты функций, и статический разбор графа дал бы неверную картину.

  **Синтетической истории разговора тоже нет.** Движок не выдумывает реплики, которые «были бы» сказаны по пути к ноде: транскрипт начинается прямо с неё.
</Warning>

<Note>
  **Границы, о которых стоит знать заранее:**

  * **Только тестовые входы.** Публичный API, телефония и передача звонка другому агенту поле стартовой ноды не принимают. Разговор с реальным клиентом, начатый с середины и с пустыми переменными, — это дефект, а не возможность.
  * **Вход один — кнопка в тест-панели.** Контекстного меню на канвасе нет.
  * **Внутрь опубликованного компонента стартовать нельзя:** у нод его тела нет собственного выделения на канвасе. Для черновика это работает — нода-компонент резолвится в свою точку входа.
</Note>

## Как читать трейс чат-теста

Каждый ход в тест-панели показывает не только реплику, но и **решение движка**: какой переход сработал и по какому типу (`PROMPT`, `EQUATION`, `ALWAYS`, `DEFAULT`), сколько заняли классификатор и генерация, что вернул вызов функции, что нашлось в базах знаний, какая цель закрылась. Это главный отладочный инструмент: если агент «ушёл не туда», ответ виден в строке перехода, а не в догадках.

<Frame caption="Тест → Чат. Реальный прогон: клиент просит перенести визит, срабатывает промпт-переход, extract достаёт дату, Function отдаёт мок-ответ CRM (200), формула ведёт в узел с окнами. Переключатели сверху: rigid/flex, черновик/опубликованная, заглушки HTTP или реальные вызовы.">
  <img src="https://mintcdn.com/hubtalk/cKl-cjuDGhk4sToG/images/tutorial/tut-41-test-chat.webp?fit=max&auto=format&n=cKl-cjuDGhk4sToG&q=85&s=93ee4a2a096628ded17ee88359db59cc" alt="Тест-панель: живой диалог с трейсом переходов, вызовом функции и таймингами" width="1280" height="1194" data-path="images/tutorial/tut-41-test-chat.webp" />
</Frame>

<Warning>
  **Обязательный минимум тестов перед публикацией**

  * Счастливый путь целиком — до End.
  * Каждая ветка ветвлений: «окон нет», «CRM не ответила», «клиент отменяет».
  * Оба глобальных узла: вопрос не по теме (и возврат в сценарий) и просьба человека.
  * Молчание клиента — сработал ли таймер и напоминания.
  * Голосом — минимум один полный звонок: только там слышны паузы, перебивания и произношение чисел и дат.
</Warning>

<Frame caption="Copilot — правки словами: «добавь узел, который спрашивает удобное время, и веди его в проверку слотов». Copilot никогда не меняет флоу молча: он показывает предложение, вы принимаете или отклоняете.">
  <img src="https://mintcdn.com/hubtalk/cKl-cjuDGhk4sToG/images/tutorial/tut-42-copilot.webp?fit=max&auto=format&n=cKl-cjuDGhk4sToG&q=85&s=3efd820f399c9fce6b5b8451057e1250" alt="Панель Copilot в редакторе" width="1280" height="1185" data-path="images/tutorial/tut-42-copilot.webp" />
</Frame>

Предложение проверяется и применяется **целиком**: когда новая ветка приходит одним предложением, шаг внутри него может ссылаться на узел, который создаётся следующим шагом того же предложения. А если применить что-то нельзя, Copilot называет настоящую причину с путём до поля, а производные симптомы честно помечает как «зависит от операции …» — чтобы одна опечатка не превращалась в пять одинаковых карточек «Неприменимо».
