> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-vortex-format.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Демо-дни — 2026-08-21

> Демо-дни ClickStack за 2026-08-21

<h2 id="metric-formulas-in-the-chart-editor">
  Формулы метрик в редакторе графиков
</h2>

*Демо от [@wrn14897](https://github.com/wrn14897)*

<iframe width="768" height="432" src="https://www.youtube.com/embed/tSCoW-GGXTU" title="Видеоплеер YouTube" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen />

Графики метрик теперь умеют выполнять арифметические операции. До этой недели две метрики на одном графике были просто двумя линиями — объединить их было нечем.

Серии на графике обозначаются как `A`, `B`, `C` и так далее. Строка формулы позволяет построить производную серию на основе этих обозначений. Например, `A / (A + B + C) * 100` даёт коэффициент использования очереди. Точно так же можно рассчитать насыщение по числу принятых и отправленных сообщений коллектора.

К одному графику можно добавить несколько формул, выбрать, показывать ли исходные серии вместе с результатом или только формулу, а также смешивать серии из разных метрик. Оповещения тоже работают с формулами.

Сама арифметика выполняется в ClickHouse. Каждая формула компилируется из проверенного AST в составной запрос метрики, поэтому ClickHouse вычисляет её в рамках одного запроса, а не приложение объединяет результаты постфактум. Каждая серия становится CTE, а формула вычисляется поверх объединённого результата.

Отсутствующие операнды считаются нулём, поэтому группа без ошибок показывает 0%, а не N/A. Каждый знаменатель деления оборачивается в `nullif(..., 0)`, так что нулевой или отсутствующий знаменатель отображается как разрыв, а не как ноль или ошибка.

В последующем изменении `HAVING`, `ORDER BY` и `LIMIT` были перенесены на финальный JOIN вместо применения к каждой ветви `UNION`. Раньше эти секции выполнялись в области видимости, где имена выходных полей, видимые пользователю, ещё не существовали. Это означало, что каждая серия фильтровалась независимо до JOIN, а итоговый порядок строк оставался недетерминированным.

Поле ввода принимает буквенные ссылки и простую арифметику, но пока не произвольный SQL. Ссылки на неизвестные серии, некорректные выражения и выражения, состоящие только из констант, подсвечиваются в реальном времени под полем ввода. Та же проверка блокирует сохранение и запуск, поэтому некорректное выражение никогда не попадёт в ClickHouse.

Побитовые операторы и функции ClickHouse пока не поддерживаются. Никакой глубокой причины для этого нет — просто на этом остановилась первая версия, и более широкая поддержка выражений вполне может появиться следующей.

В обсуждении всплыли ещё две вещи, которые пока не реализованы. Формулы не могут ссылаться на другие формулы, поэтому связать `F1` с `F2` не получится. Кроме того, отдельные переключатели показа/скрытия для каждой серии были бы полезнее, чем общий для всего графика переключатель операндов. Скрыть `A` и `B`, сохранив их в формуле, — вот сценарий, который людям действительно нужен.

Прозвучал также справедливый вопрос о том, насколько далеко можно заходить с JOIN, прежде чем они перестанут быть полезными. Всякий, кто пользовался делением в PromQL, знает характерный сбой: JOIN не совпадает так, как ожидалось, и молча возвращает пустой результат.

**Связанные PR:** [#2908](https://github.com/hyperdxio/hyperdx/pull/2908) — отрисовка формул в составном запросе метрики, [#2909](https://github.com/hyperdxio/hyperdx/pull/2909) — интерфейс редактора графиков для формул метрик, [#2946](https://github.com/hyperdxio/hyperdx/pull/2946) — применение HAVING/ORDER BY/LIMIT к составному JOIN метрики, а не к отдельным ветвям серий, [#2952](https://github.com/hyperdxio/hyperdx/pull/2952) — поддержка формул во всех API, [#2953](https://github.com/hyperdxio/hyperdx/pull/2953) — поддержка формул для источников событий логов и трассировок

<h2 id="dependent-dashboard-variables-and-macros">
  Зависимые переменные панели мониторинга и макросы
</h2>

*Демо от [@pulpdrew](https://github.com/pulpdrew)*

<iframe width="768" height="432" src="https://www.youtube.com/embed/Y0CaapNH1Vc" title="Видеоплеер YouTube" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen />

Две просьбы, прозвучавшие после демонстрации на прошлой неделе, реализованы.

Определения фильтров теперь могут ссылаться на другие переменные в своём предложении `WHERE`, поэтому один dropdown может ограничивать другой. Фильтр по уровню серьёзности, ссылающийся на фильтр по имени сервиса, изначально пуст. После выбора сервиса он предлагает только те уровни серьёзности, которые встречаются у этого сервиса.

Варианты по-прежнему запрашиваются и тогда, когда в переменной, на которую идёт ссылка, ничего не выбрано. Если вы хотите, чтобы значения заполнялись и в этом состоянии, используйте `$__filters` или `$__conditionalAll`. Простое выражение `<expression> IN ($var)` не вернёт ничего, пока в `$var` нет выбранного значения. Теперь причину поясняет всплывающая подсказка — вместо пустого списка без каких-либо объяснений. Автодополнение переменных и макросов работает и в поле `WHERE` модального окна фильтра.

Циклические зависимости создать можно, но реального вреда они не наносят: переменные заменяются выбранными значениями, а не вычисляются рекурсивно.

Макросы теперь раскрывают переменные, переданные в качестве аргументов, поэтому `$__timeFilter($TimeColumn)` работает. Выберите столбец временной метки через переменную — и макрос развернётся в полноценный фильтр по времени вокруг него. Переменные, передаваемые в `$__filter` и `$__conditionalAll`, теперь должны использовать форму `$var`. Раньше принималась и запись `var` без символа доллара — эта нестрогость по большей части лишь вносила путаницу.

Переменные понимают и внешний API v2, и MCP server, а значит, и Terraform тоже. Агент может собрать панель мониторинга с переменными и broadcast-фильтрами, зависимыми dropdown-списками и tiles, которые ссылаются на эти переменные напрямую или через макрос. Инструменты создания, сохранения и применения patch предупреждают, когда переменные используются там, где они не сработают.

Инструменты для query tile также принимают значения переменных, поэтому агент может проверить собственные подстановки, прежде чем передать панель мониторинга дальше.

**Связанные PR:** [#2923](https://github.com/hyperdxio/hyperdx/pull/2923) поддержка запросов значений зависимых переменных, [#2937](https://github.com/hyperdxio/hyperdx/pull/2937) поддержка вложенных макросов и ссылок на переменные в макросах, [#2944](https://github.com/hyperdxio/hyperdx/pull/2944) добавление переменных панели мониторинга во внешний API, [#2951](https://github.com/hyperdxio/hyperdx/pull/2951) поддержка переменных панели мониторинга в MCP server

<h2 id="mcp-tool-schemas-that-strict-clients-accept">
  Схемы инструментов MCP, которые принимают строгие клиенты
</h2>

*Демо от [@teeohhem](https://github.com/teeohhem)*

<iframe width="768" height="432" src="https://www.youtube.com/embed/W4dvgYj47ZM" title="Видеоплеер YouTube" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen />

Клиент сообщил, что вообще не может использовать наш MCP server со своим агентом.

Некоторые агентские фреймворки запрашивают список доступных инструментов и проверяют каждую входную схему, прежде чем отправить их провайдеру модели. Если хотя бы одна схема оказывается невалидной, фреймворк отклоняет весь список инструментов, а не только проблемный инструмент, и из-за этого сервер выглядит полностью нерабочим.

Многие агентские окружения относятся к этому терпимее, но не все. Для затронутых клиентов единственным способом вернуть агента в рабочее состояние было отключение сервера.

Теперь добавлен тест, который проверяет, что входная схема каждого инструмента соответствует JSON Schema draft 2020-12, — поэтому новый инструмент больше не сможет тем же образом сломать строгие клиенты.

**Связанные PR:** [#2925](https://github.com/hyperdxio/hyperdx/pull/2925) — формирование входных схем инструментов, валидных по draft-2020-12, [#2971](https://github.com/hyperdxio/hyperdx/pull/2971) — объявление уровня quantile как строкового enum

<h2 id="rotatable-personal-api-access-keys">
  Ротируемые персональные ключи доступа к API
</h2>

*Демо от [@teeohhem](https://github.com/teeohhem)*

<iframe width="768" height="432" src="https://www.youtube.com/embed/tHQoaFaVPpY" title="Видеоплеер YouTube" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen />

Personal API Access Key теперь можно ротировать в разделе Team Settings → API & Agents.

Этот ключ используется как bearer-токен для external API v2 и MCP server. Раньше он создавался один раз при создании аккаунта и не подлежал изменению. Единственным способом справиться с утечкой ключа было удаление пользователя.

Ротация выполняется немедленно, без переходного периода, при этом сеанс в браузере остаётся активным. Будьте внимательны: ключ принадлежит аккаунту, а не команде. Если вы состоите в нескольких командах, придётся обновить всё, что использует этот ключ, в каждой из них.

В Enterprise на этот счёт выводится предупреждение. В установке с открытым исходным кодом с единственной командой предупреждать не о чем, поэтому там оно не отображается.

Действуют два намеренных ограничения. Маршрут `PATCH /me/accessKey` не принимает идентификатор пользователя, поскольку ID берётся из сеанса. Он может ротировать только собственный ключ вызывающей стороны.

Кроме того, этот маршрут не доступен через external API v2 с аутентификацией по bearer-токену. Утёкший ключ и так позволяет прочитать там сам себя. Если бы он давал ещё и возможность ротации, злоумышленник мог бы отрезать владельцу доступ к его собственным инструментам.

**Связанные PR:** [#2926](https://github.com/hyperdxio/hyperdx/pull/2926) — Personal API Access Keys сделаны ротируемыми

<h2 id="alphabetical-keys-in-the-column-values-tab">
  Алфавитный порядок ключей во вкладке Column Values
</h2>

*Демо от [@teeohhem](https://github.com/teeohhem)*

<iframe width="768" height="432" src="https://www.youtube.com/embed/9RfTL-dtZF0" title="Видеоплеер YouTube" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen />

Ключи во вкладке Column Values боковой панели строки теперь сортируются по алфавиту на каждом уровне вложенности — как для журналов, так и для traces.

Раньше JSON-дерево показывало ключи в порядке их физического хранения в ClickHouse, который выглядел практически случайным. У столбца типа `Map`, например `ProfileEvents`, со 125 ключами не было никакого предсказуемого порядка, поэтому найти нужный можно было, только просмотрев весь список.

Менее очевидная часть проблемы состояла в том, что каждый уровень ограничен 50 строками, а срез выполнялся до сортировки. Те 50 ключей, которые вы видели, представляли собой произвольное подмножество, и единственным способом добраться до остальных была кнопка «Expand 75 more properties».

Теперь сортировка выполняется в `TreeNode` до обрезки списка. Она учитывает числа, поэтому `key2` идёт перед `key10`.

**Связанные PR:** [#2943](https://github.com/hyperdxio/hyperdx/pull/2943) сортировка ключей в просмотрщике JSON по алфавиту

<h2 id="storybook-as-a-browsable-design-system">
  Storybook как просматриваемая дизайн-система
</h2>

*Демо от [@elizabetdev](https://github.com/elizabetdev)*

<iframe width="768" height="432" src="https://www.youtube.com/embed/mnHtrsuKsC8" title="Видеоплеер YouTube" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen />

Теперь Storybook — это просматриваемая дизайн-система, а не песочница для компонентов. Боковая панель выстроена в порядке: Guidelines → Brand → Icons → Design Tokens → Components.

Раздел Guidelines отображает Markdown из `agent_docs` напрямую, поэтому стиль кода, оформление тем, макет страниц и цвета для визуализации данных собраны в одном месте. Это в равной мере сделано и для агентов, и для людей. Если направить агента на тот же документ, который читает новый участник команды, сгенерированные компоненты будут лучше согласовываться с тем, что уже есть.

Разделы Brand и Icons содержат логотипы HyperDX и ClickStack, а также наши собственные иконки, включая `IconAiNotebook`. SVG можно скопировать или скачать; там же есть рекомендации, когда использовать контурную иконку, совместимую с Tabler, а когда — фирменный знак.

Всё началось с иконок, потому что в слайдах использовали всё, что выглядело более-менее похоже. Если вам нужен знак для презентации, берите его отсюда.

Панель Brand переключает между HyperDX и ClickStack, а панель Theme — между светлой и тёмной темой. Новые компоненты можно проверить во всех сочетаниях ещё до выпуска. Истории компонентов, которые раньше оставались без категории, теперь вложены в `Components/`, а рядом с ними доступны компоненты карточек с графиками.

Попутно выяснились две вещи. CSS-переменные шрифтов Storybook теперь заданы на `<html>`, как и в приложении, поэтому основной текст и всплывающие элементы, отрисованные через портал, больше не отображаются шрифтом Times.

Кроме того, мы непоследовательно используем набор иконок Tabler. Для PromQL, вероятно, нужна отдельная иконка, а метрики и traces сейчас в разных местах обозначаются разными иконками. Теперь ориентиром служит Storybook.

Запустить локально: `yarn workspace @hyperdx/app storybook`.

**Связанные PR:** [#2935](https://github.com/hyperdxio/hyperdx/pull/2935) превращение Storybook в просматриваемую дизайн-систему

<h2 id="categorical-palette-on-histogram-charts">
  Категориальная палитра на гистограммах
</h2>

*Демо от [@elizabetdev](https://github.com/elizabetdev)*

<iframe width="768" height="432" src="https://www.youtube.com/embed/wybAadS6ms0" title="Видеоплеер YouTube" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen />

Для гистограмм, включая Request Latency на панели мониторинга Services, цвет был жёстко задан как `#50FA7B`. Этот неоново-зелёный не входит в палитру графиков и не давал достаточной контрастности. Тем же цветом во всплывающей подсказке выводилась и надпись «Number of events».

Теперь график берёт `chart-blue` через `getColorFromCSSToken`. Всплывающая подсказка использует общие `ChartTooltipContainer` и `ChartTooltipItem` — тем самым она приведена к единому виду с линейными, столбчатыми и круговыми диаграммами.

Ссылка **View events** во всплывающей подсказке убрана. `generateSearchUrl` принимался внутренней гистограммой и подсказкой, но из `DBHistogramChart` никогда не передавался, так что в продакшне ссылка всё равно не появлялась.

У единственного вызывающего кода нет построителя поискового URL для бакета длительности, а фильтрация событий по диапазону задержки — это отдельная возможность, а не просто «дотягивание» параметров.

Мелочь, но из таких мелочей и складывается качество.

**Связанные PR:** [#2949](https://github.com/hyperdxio/hyperdx/pull/2949) use categorical palette on histogram charts
