feat(ui): add tool input visibility preference
This commit is contained in:
@@ -72,6 +72,7 @@ const App: Component = () => {
|
||||
setToolOutputExpansion,
|
||||
setDiagnosticsExpansion,
|
||||
setThinkingBlocksExpansion,
|
||||
setToolInputsVisibility,
|
||||
} = useConfig()
|
||||
const [escapeInDebounce, setEscapeInDebounce] = createSignal(false)
|
||||
interface LaunchErrorState {
|
||||
@@ -402,6 +403,7 @@ const App: Component = () => {
|
||||
setToolOutputExpansion,
|
||||
setDiagnosticsExpansion,
|
||||
setThinkingBlocksExpansion,
|
||||
setToolInputsVisibility,
|
||||
handleNewInstanceRequest,
|
||||
handleCloseInstance,
|
||||
handleNewSession,
|
||||
|
||||
@@ -84,7 +84,7 @@ interface ToolCallProps {
|
||||
|
||||
|
||||
export default function ToolCall(props: ToolCallProps) {
|
||||
const { preferences, setDiffViewMode } = useConfig()
|
||||
const { preferences, setDiffViewMode, setToolInputsVisibility } = useConfig()
|
||||
const { isDark } = useTheme()
|
||||
const { t } = useI18n()
|
||||
const toolCallMemo = createMemo(() => props.toolCall)
|
||||
@@ -172,9 +172,21 @@ export default function ToolCall(props: ToolCallProps) {
|
||||
})
|
||||
|
||||
const [userExpanded, setUserExpanded] = createSignal<boolean | null>(null)
|
||||
const [inputVisible, setInputVisible] = createSignal(false)
|
||||
const [inputSectionExpanded, setInputSectionExpanded] = createSignal(false)
|
||||
const [outputSectionExpanded, setOutputSectionExpanded] = createSignal(true)
|
||||
const toolInputsVisibility = createMemo(() => preferences().toolInputsVisibility || "hidden")
|
||||
const isToolInputVisible = createMemo(() => toolInputsVisibility() !== "hidden")
|
||||
const inputDefaultExpanded = createMemo(() => toolInputsVisibility() === "expanded")
|
||||
const [inputSectionOverride, setInputSectionOverride] = createSignal<boolean | null>(null)
|
||||
const [outputSectionOverride, setOutputSectionOverride] = createSignal<boolean | null>(null)
|
||||
const inputSectionExpanded = () => {
|
||||
const override = inputSectionOverride()
|
||||
if (override !== null) return override
|
||||
return inputDefaultExpanded()
|
||||
}
|
||||
const outputSectionExpanded = () => {
|
||||
const override = outputSectionOverride()
|
||||
if (override !== null) return override
|
||||
return true
|
||||
}
|
||||
|
||||
const isPermissionActive = createMemo(() => {
|
||||
const pending = pendingPermission()
|
||||
@@ -591,22 +603,24 @@ export default function ToolCall(props: ToolCallProps) {
|
||||
})
|
||||
}
|
||||
|
||||
createEffect(() => {
|
||||
// When global preference changes, reset per-tool-call overrides so palette changes apply.
|
||||
toolInputsVisibility()
|
||||
setInputSectionOverride(null)
|
||||
setOutputSectionOverride(null)
|
||||
})
|
||||
|
||||
const handleToggleInputVisibility = (event: MouseEvent) => {
|
||||
event.preventDefault()
|
||||
event.stopPropagation()
|
||||
if (!expanded()) {
|
||||
toggle()
|
||||
}
|
||||
setInputVisible((prev) => {
|
||||
const next = !prev
|
||||
if (!next) {
|
||||
setInputSectionExpanded(false)
|
||||
} else {
|
||||
setInputSectionExpanded(true)
|
||||
setOutputSectionExpanded(true)
|
||||
}
|
||||
return next
|
||||
})
|
||||
if (isToolInputVisible()) {
|
||||
setToolInputsVisibility("hidden")
|
||||
return
|
||||
}
|
||||
setToolInputsVisibility("expanded")
|
||||
}
|
||||
|
||||
const renderer = createMemo(() => resolveToolRenderer(toolName()))
|
||||
@@ -855,13 +869,13 @@ export default function ToolCall(props: ToolCallProps) {
|
||||
type="button"
|
||||
class="tool-call-header-input"
|
||||
onClick={handleToggleInputVisibility}
|
||||
aria-pressed={inputVisible()}
|
||||
aria-pressed={isToolInputVisible()}
|
||||
aria-label={
|
||||
inputVisible()
|
||||
isToolInputVisible()
|
||||
? t("toolCall.header.hideInputAriaLabel")
|
||||
: t("toolCall.header.showInputAriaLabel")
|
||||
}
|
||||
title={inputVisible() ? t("toolCall.header.hideInputTitle") : t("toolCall.header.showInputTitle")}
|
||||
title={isToolInputVisible() ? t("toolCall.header.hideInputTitle") : t("toolCall.header.showInputTitle")}
|
||||
>
|
||||
<ArrowRightSquare class="w-3.5 h-3.5" />
|
||||
</button>
|
||||
@@ -885,7 +899,7 @@ export default function ToolCall(props: ToolCallProps) {
|
||||
{expanded() && (
|
||||
<div class="tool-call-details">
|
||||
<Show
|
||||
when={inputVisible() && hasToolInput()}
|
||||
when={isToolInputVisible() && hasToolInput()}
|
||||
fallback={
|
||||
<>
|
||||
{renderToolBody()}
|
||||
@@ -906,7 +920,10 @@ export default function ToolCall(props: ToolCallProps) {
|
||||
type="button"
|
||||
class="tool-call-io-toggle"
|
||||
aria-expanded={inputSectionExpanded()}
|
||||
onClick={() => setInputSectionExpanded((prev) => !prev)}
|
||||
onClick={() => setInputSectionOverride((prev) => {
|
||||
const current = prev === null ? inputSectionExpanded() : prev
|
||||
return !current
|
||||
})}
|
||||
>
|
||||
<span class="tool-call-io-title">{t("toolCall.io.input")}</span>
|
||||
</button>
|
||||
@@ -927,7 +944,10 @@ export default function ToolCall(props: ToolCallProps) {
|
||||
type="button"
|
||||
class="tool-call-io-toggle"
|
||||
aria-expanded={outputSectionExpanded()}
|
||||
onClick={() => setOutputSectionExpanded((prev) => !prev)}
|
||||
onClick={() => setOutputSectionOverride((prev) => {
|
||||
const current = prev === null ? outputSectionExpanded() : prev
|
||||
return !current
|
||||
})}
|
||||
>
|
||||
<span class="tool-call-io-title">{t("toolCall.io.output")}</span>
|
||||
</button>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { createSignal, onMount } from "solid-js"
|
||||
import type { Accessor } from "solid-js"
|
||||
import type { Preferences, ExpansionPreference } from "../../stores/preferences"
|
||||
import type { Preferences, ExpansionPreference, ToolInputsVisibilityPreference } from "../../stores/preferences"
|
||||
import { createCommandRegistry, type Command } from "../commands"
|
||||
import { instances, activeInstanceId, setActiveInstanceId } from "../../stores/instances"
|
||||
import type { ClientPart, MessageInfo } from "../../types/message"
|
||||
@@ -38,6 +38,7 @@ export interface UseCommandsOptions {
|
||||
setToolOutputExpansion: (mode: ExpansionPreference) => void
|
||||
setDiagnosticsExpansion: (mode: ExpansionPreference) => void
|
||||
setThinkingBlocksExpansion: (mode: ExpansionPreference) => void
|
||||
setToolInputsVisibility: (mode: ToolInputsVisibilityPreference) => void
|
||||
handleNewInstanceRequest: () => void
|
||||
handleCloseInstance: (instanceId: string) => Promise<void>
|
||||
handleNewSession: (instanceId: string) => Promise<void>
|
||||
@@ -551,6 +552,29 @@ export function useCommands(options: UseCommandsOptions) {
|
||||
},
|
||||
})
|
||||
|
||||
commandRegistry.register({
|
||||
id: "tool-inputs-visibility",
|
||||
label: () => {
|
||||
const mode = options.preferences().toolInputsVisibility || "hidden"
|
||||
const state =
|
||||
mode === "expanded"
|
||||
? tGlobal("commands.common.expanded")
|
||||
: mode === "collapsed"
|
||||
? tGlobal("commands.common.collapsed")
|
||||
: tGlobal("commands.common.hidden")
|
||||
return tGlobal("commands.toolInputsVisibility.label", { state })
|
||||
},
|
||||
description: () => tGlobal("commands.toolInputsVisibility.description"),
|
||||
category: "System",
|
||||
keywords: () => splitKeywords("commands.toolInputsVisibility.keywords"),
|
||||
action: () => {
|
||||
const mode = options.preferences().toolInputsVisibility || "hidden"
|
||||
const next: ToolInputsVisibilityPreference =
|
||||
mode === "hidden" ? "collapsed" : mode === "collapsed" ? "expanded" : "hidden"
|
||||
options.setToolInputsVisibility(next)
|
||||
},
|
||||
})
|
||||
|
||||
commandRegistry.register({
|
||||
id: "token-usage-visibility",
|
||||
label: () => {
|
||||
|
||||
@@ -130,6 +130,10 @@ export const commandMessages = {
|
||||
"commands.diagnosticsDefault.description": "Toggle default expansion for diagnostics output",
|
||||
"commands.diagnosticsDefault.keywords": "diagnostics, expand, collapse",
|
||||
|
||||
"commands.toolInputsVisibility.label": "Tool Inputs Visibility · {state}",
|
||||
"commands.toolInputsVisibility.description": "Set default visibility for tool call input arguments",
|
||||
"commands.toolInputsVisibility.keywords": "tool, inputs, arguments, visibility, hide, show, expand, collapse",
|
||||
|
||||
"commands.tokenUsageDisplay.label": "Token Usage Display · {state}",
|
||||
"commands.tokenUsageDisplay.description": "Show or hide token and cost stats for assistant messages",
|
||||
"commands.tokenUsageDisplay.keywords": "token, usage, cost, stats",
|
||||
|
||||
@@ -130,6 +130,10 @@ export const commandMessages = {
|
||||
"commands.diagnosticsDefault.description": "Alternar la expansión por defecto de la salida de diagnósticos",
|
||||
"commands.diagnosticsDefault.keywords": "diagnósticos, expandir, colapsar",
|
||||
|
||||
"commands.toolInputsVisibility.label": "Visibilidad de entradas de herramientas · {state}",
|
||||
"commands.toolInputsVisibility.description": "Configurar la visibilidad por defecto de los argumentos de entrada de llamadas de herramienta",
|
||||
"commands.toolInputsVisibility.keywords": "herramienta, entradas, argumentos, visibilidad, ocultar, mostrar, expandir, colapsar",
|
||||
|
||||
"commands.tokenUsageDisplay.label": "Mostrar uso de tokens · {state}",
|
||||
"commands.tokenUsageDisplay.description": "Mostrar u ocultar estadísticas de tokens y costo en los mensajes del asistente",
|
||||
"commands.tokenUsageDisplay.keywords": "token, uso, costo, estadísticas",
|
||||
|
||||
@@ -130,6 +130,10 @@ export const commandMessages = {
|
||||
"commands.diagnosticsDefault.description": "Choisir l'ouverture par défaut de la sortie des diagnostics",
|
||||
"commands.diagnosticsDefault.keywords": "diagnostics, développer, réduire",
|
||||
|
||||
"commands.toolInputsVisibility.label": "Visibilité des entrées d'outil · {state}",
|
||||
"commands.toolInputsVisibility.description": "Définir la visibilité par défaut des arguments d'entrée des appels d'outil",
|
||||
"commands.toolInputsVisibility.keywords": "outil, entrées, arguments, visibilité, masquer, afficher, développer, réduire",
|
||||
|
||||
"commands.tokenUsageDisplay.label": "Affichage de l'usage des tokens · {state}",
|
||||
"commands.tokenUsageDisplay.description": "Afficher ou masquer les stats de tokens et de coût pour les messages de l'assistant",
|
||||
"commands.tokenUsageDisplay.keywords": "token, usage, coût, stats",
|
||||
|
||||
@@ -130,6 +130,10 @@ export const commandMessages = {
|
||||
"commands.diagnosticsDefault.description": "診断出力を既定で展開するか切り替え",
|
||||
"commands.diagnosticsDefault.keywords": "診断, 展開, 折りたたみ, diagnostics, expand, collapse",
|
||||
|
||||
"commands.toolInputsVisibility.label": "ツール入力の表示 · {state}",
|
||||
"commands.toolInputsVisibility.description": "ツール呼び出しの入力引数の既定の表示状態を設定します",
|
||||
"commands.toolInputsVisibility.keywords": "ツール, 入力, 引数, 表示, 非表示, 展開, 折りたたみ, tool, inputs, arguments, visibility, hide, show, expand, collapse",
|
||||
|
||||
"commands.tokenUsageDisplay.label": "トークン使用量表示 · {state}",
|
||||
"commands.tokenUsageDisplay.description": "アシスタントメッセージのトークン/コスト統計を表示/非表示",
|
||||
"commands.tokenUsageDisplay.keywords": "トークン, 使用量, コスト, 統計, token, usage, cost, stats",
|
||||
|
||||
@@ -130,6 +130,10 @@ export const commandMessages = {
|
||||
"commands.diagnosticsDefault.description": "Переключить, разворачивать ли вывод диагностики по умолчанию",
|
||||
"commands.diagnosticsDefault.keywords": "diagnostics, развернуть, свернуть",
|
||||
|
||||
"commands.toolInputsVisibility.label": "Видимость входных данных инструмента · {state}",
|
||||
"commands.toolInputsVisibility.description": "Установить видимость аргументов входа вызовов инструментов по умолчанию",
|
||||
"commands.toolInputsVisibility.keywords": "инструмент, вход, аргументы, видимость, скрыть, показать, раскрыть, свернуть, tool, inputs, arguments, visibility, hide, show, expand, collapse",
|
||||
|
||||
"commands.tokenUsageDisplay.label": "Отображение token-статистики · {state}",
|
||||
"commands.tokenUsageDisplay.description": "Показать или скрыть статистику token и стоимости для сообщений ассистента",
|
||||
"commands.tokenUsageDisplay.keywords": "token, usage, cost, статистика",
|
||||
|
||||
@@ -130,6 +130,10 @@ export const commandMessages = {
|
||||
"commands.diagnosticsDefault.description": "切换诊断输出是否默认展开",
|
||||
"commands.diagnosticsDefault.keywords": "diagnostics, expand, collapse, 诊断, 展开, 折叠",
|
||||
|
||||
"commands.toolInputsVisibility.label": "工具输入可见性 · {state}",
|
||||
"commands.toolInputsVisibility.description": "设置工具调用输入参数的默认可见性",
|
||||
"commands.toolInputsVisibility.keywords": "工具, 输入, 参数, 可见性, 隐藏, 显示, 展开, 折叠, tool, inputs, arguments, visibility, hide, show, expand, collapse",
|
||||
|
||||
"commands.tokenUsageDisplay.label": "Token 使用显示 · {state}",
|
||||
"commands.tokenUsageDisplay.description": "显示或隐藏助手消息的 token 和费用统计",
|
||||
"commands.tokenUsageDisplay.keywords": "token, usage, cost, stats, 令牌, 用量, 费用, 统计",
|
||||
|
||||
@@ -25,6 +25,7 @@ export interface ModelPreference {
|
||||
|
||||
export type DiffViewMode = "split" | "unified"
|
||||
export type ExpansionPreference = "expanded" | "collapsed"
|
||||
export type ToolInputsVisibilityPreference = "hidden" | "collapsed" | "expanded"
|
||||
export type ListeningMode = "local" | "all"
|
||||
|
||||
export interface UiSettings {
|
||||
@@ -37,6 +38,7 @@ export interface UiSettings {
|
||||
diffViewMode: DiffViewMode
|
||||
toolOutputExpansion: ExpansionPreference
|
||||
diagnosticsExpansion: ExpansionPreference
|
||||
toolInputsVisibility: ToolInputsVisibilityPreference
|
||||
showUsageMetrics: boolean
|
||||
autoCleanupBlankSessions: boolean
|
||||
|
||||
@@ -108,6 +110,7 @@ const defaultUiSettings: UiSettings = {
|
||||
diffViewMode: "split",
|
||||
toolOutputExpansion: "expanded",
|
||||
diagnosticsExpansion: "expanded",
|
||||
toolInputsVisibility: "hidden",
|
||||
showUsageMetrics: true,
|
||||
autoCleanupBlankSessions: true,
|
||||
|
||||
@@ -130,6 +133,10 @@ function normalizeUiSettings(input?: Partial<UiSettings> | null): UiSettings {
|
||||
diffViewMode: sanitized.diffViewMode ?? defaultUiSettings.diffViewMode,
|
||||
toolOutputExpansion: sanitized.toolOutputExpansion ?? defaultUiSettings.toolOutputExpansion,
|
||||
diagnosticsExpansion: sanitized.diagnosticsExpansion ?? defaultUiSettings.diagnosticsExpansion,
|
||||
toolInputsVisibility:
|
||||
sanitized.toolInputsVisibility === "collapsed" || sanitized.toolInputsVisibility === "expanded"
|
||||
? sanitized.toolInputsVisibility
|
||||
: defaultUiSettings.toolInputsVisibility,
|
||||
showUsageMetrics: sanitized.showUsageMetrics ?? defaultUiSettings.showUsageMetrics,
|
||||
autoCleanupBlankSessions: sanitized.autoCleanupBlankSessions ?? defaultUiSettings.autoCleanupBlankSessions,
|
||||
osNotificationsEnabled: sanitized.osNotificationsEnabled ?? defaultUiSettings.osNotificationsEnabled,
|
||||
@@ -439,6 +446,11 @@ function setDiagnosticsExpansion(mode: ExpansionPreference): void {
|
||||
updateUiSettings({ diagnosticsExpansion: mode })
|
||||
}
|
||||
|
||||
function setToolInputsVisibility(mode: ToolInputsVisibilityPreference): void {
|
||||
if (preferences().toolInputsVisibility === mode) return
|
||||
updateUiSettings({ toolInputsVisibility: mode })
|
||||
}
|
||||
|
||||
function setThinkingBlocksExpansion(mode: ExpansionPreference): void {
|
||||
if (preferences().thinkingBlocksExpansion === mode) return
|
||||
updateUiSettings({ thinkingBlocksExpansion: mode })
|
||||
@@ -536,6 +548,7 @@ interface ConfigContextValue {
|
||||
setToolOutputExpansion: typeof setToolOutputExpansion
|
||||
setDiagnosticsExpansion: typeof setDiagnosticsExpansion
|
||||
setThinkingBlocksExpansion: typeof setThinkingBlocksExpansion
|
||||
setToolInputsVisibility: typeof setToolInputsVisibility
|
||||
|
||||
// instance scoped
|
||||
setAgentModelPreference: typeof setAgentModelPreference
|
||||
@@ -579,6 +592,7 @@ const configContextValue: ConfigContextValue = {
|
||||
setToolOutputExpansion,
|
||||
setDiagnosticsExpansion,
|
||||
setThinkingBlocksExpansion,
|
||||
setToolInputsVisibility,
|
||||
setAgentModelPreference,
|
||||
getAgentModelPreference,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user