Единый механизм отображения результатов работы инструментов
Предыстория
В TUI ранее было два режима отображения результатов работы инструментов:
- Компактный режим (Ctrl+O): сворачивал завершённые результаты инструментов в однострочную сводку
- Обычный режим: показывал полные результаты инструментов внутри потока, что приводило к излишнему вертикальному шуму
Пользователям приходилось вручную переключаться между режимами. В большинстве случаев завершённые результаты инструментов (содержимое файлов, результаты поиска и т.д.) не добавляли ценности в ход диалога.
Дизайн
Основной принцип
Единый режим: отображение инструмента определяется его категорией, а не переключаемым пользователем режимом. Инструменты сбора информации (чтение/поиск/список) сворачиваются в сводку; инструменты модификации (правка/запись/команда/агент) всегда отображаются по отдельности с полными результатами.
Смысловая сводка (buildToolSummary)
Вместо отображения сырых имён и количества инструментов (ReadFile x 3) генерируется читаемая сводка в формате на основе количества:
| Сценарий | Вывод |
|---|---|
| Один инструмент | Прочитан 1 файл / Выполнена 1 команда |
| Несколько однотипных | Прочитано 3 файла |
| Смешанные типы | Выполнена 1 команда, прочитано 3 файла, отредактировано 2 файла |
| Активный (выполняется) | Чтение 1 файла (настоящее продолженное время) |
| Завершённый | Прочитан 1 файл (прошедшее время) |
Категории инструментов
| Категория | Отображаемые имена | Глагол прош. вр. | Глагол наст. вр. | Сворачиваемый |
|---|---|---|---|---|
| read | ReadFile, Read File(s) | Прочитал | Читаю | Да |
| edit | Edit, NotebookEdit | Отредактировал | Редактирую | Нет |
| write | WriteFile | Записал | Записываю | Нет |
| search | Grep, Glob | Выполнил поиск | Ищу | Да |
| list | ListFiles, Read Directory | Перечислил | Перечисляю | Да |
| command | Shell | Выполнил | Выполняю | Нет |
| agent | Agent, Workflow, SendMessage | Выполнил | Выполняю | Нет |
| other | (всё остальное) | Использовал | Использую | Нет |
Правила отображения
- Разделение по типу: инструменты делятся с помощью
isCollapsibleTool()— сворачиваемые (read/search/list) отображаются одной строкой черезCompactToolGroupDisplay; несворачиваемые (edit/write/command/agent/other) отображаются по отдельности черезToolMessage - Группы только с памятью имеют отдельный путь отображения (значок количества чтений/записей), который имеет приоритет, но только когда все операции успешны (
!hasErrorTool && every status === Success) - Сворачивание результатов: только сворачиваемые инструменты со статусом
Successсворачивают текстовый/ANSI вывод. Несворачиваемые инструменты (включая MCP-инструменты, WebFetch и т.д.) всегда показывают результаты. Отменённые инструменты оставляют частичный вывод видимым - Имена инструментов отображаются жирным шрифтом независимо от статуса, обеспечивая единый стиль как в
CompactToolGroupDisplay, так и в отдельныхToolMessage - Условия принудительного раскрытия: когда любой инструмент в группе находится в состоянии подтверждения, ошибки, инициирован пользователем, находится в фокусированной оболочке или является терминальным саб-агентом, ВСЕ инструменты отображаются по отдельности (без разделения), причём результаты принудительно показываются только для вызвавших это инструментов (с ошибкой, подтверждением, терминальный саб-агент) — успешные соседи сохраняют обычное сворачивание
- Элементы
tool_use_summary(семантические сводки, сгенерированные LLM) отображаются безусловно вместе с механическим подсчётомCompactToolGroupDisplay— они служат разным целям (семантический контекст vs подсчёт инструментов) - Значок памяти: отображается как в пути со всеми сворачиваемыми инструментами, так и в смешанном пути, когда операции с памятью присутствуют в группе, не состоящей только из памяти
Ключевые изменения
| Файл | Изменение |
|---|---|
CompactToolGroupDisplay.tsx | Добавлены buildToolSummary() с форматом подсчёта, isCollapsibleTool(), удалены стили границ |
ToolMessage.tsx | shouldCollapseResult ограничен только isCollapsibleTool() и Success; удалён isDim |
ToolGroupMessage.tsx | Разделение по типу заменяет showCompact; forceShowResult упрощён до forceExpandAll; бюджет высоты учитывает строку сводки сворачиваемых |
MainContent.tsx | Удалены псевдоним mergedHistory, absorbedCallIds, summaryByCallId, кросс-групповое слияние |
HistoryItemDisplay.tsx | tool_use_summary отображается безусловно (удалён шлюз summaryAbsorbed) |
mergeCompactToolGroups.ts | compactToggleHasVisualEffect больше не срабатывает на tool_group (компактный режим не влияет на отображение инструментов) |
Рассмотренные альтернативы
- Оставить два режима с улучшенными сводками: Отвергнуто — излишняя когнитивная нагрузка для пользователей
- Сводка для каждого инструмента (стиль Gemini CLI): Каждый инструмент получает свою стрелку сводки. Отвергнуто — всё ещё слишком подробно для больших наборов инструментов
- Поэтапное внедрение: Отвергнуто — предпочтение пользователей отдано единому проходу реализации
Last updated on