feat(app): add tool call detail levels (#2031)

* feat(app): compact tool call sequences

* feat(app): summarize compact tool activity

* feat(app): add tool call detail levels

* fix(app): stabilize compact tool groups

* fix(app): address compact tool review feedback
This commit is contained in:
Matt Cowger
2026-07-14 18:55:06 +08:00
committed by GitHub
parent 3b078240a8
commit 81113d1582
16 changed files with 1488 additions and 13 deletions
@@ -212,6 +212,77 @@ function AutoExpandReasoningRow({ value, onChange }: AutoExpandReasoningRowProps
);
}
const TOOL_CALL_DETAIL_ROW_STYLE = [settingsStyles.row, settingsStyles.rowBorder];
const TOOL_CALL_DETAIL_LEVELS: readonly AppSettings["toolCallDetailLevel"][] = [
"overview",
"concise",
"detailed",
];
function getToolCallDetailLevelLabel(
t: TFunction,
value: AppSettings["toolCallDetailLevel"],
): string {
return t(`settings.general.toolCallDetail.options.${value}`);
}
interface ToolCallDetailMenuItemProps {
value: AppSettings["toolCallDetailLevel"];
selected: boolean;
onChange: (value: AppSettings["toolCallDetailLevel"]) => void;
}
function ToolCallDetailMenuItem({ value, selected, onChange }: ToolCallDetailMenuItemProps) {
const { t } = useTranslation();
const handleSelect = useCallback(() => onChange(value), [onChange, value]);
return (
<DropdownMenuItem selected={selected} onSelect={handleSelect}>
{getToolCallDetailLevelLabel(t, value)}
</DropdownMenuItem>
);
}
interface ToolCallDetailRowProps {
value: AppSettings["toolCallDetailLevel"];
onChange: (value: AppSettings["toolCallDetailLevel"]) => void;
}
function ToolCallDetailRow({ value, onChange }: ToolCallDetailRowProps) {
const { t } = useTranslation();
const selectedLabel = getToolCallDetailLevelLabel(t, value);
return (
<View style={TOOL_CALL_DETAIL_ROW_STYLE}>
<View style={settingsStyles.rowContent}>
<Text style={settingsStyles.rowTitle}>{t("settings.general.toolCallDetail.label")}</Text>
<Text style={settingsStyles.rowHint}>
{t("settings.general.toolCallDetail.description")}
</Text>
</View>
<DropdownMenu>
<DropdownMenuTrigger
style={dropdownTriggerStyle}
accessibilityLabel={t("settings.general.toolCallDetail.accessibilityLabel", {
value: selectedLabel,
})}
>
<Text style={styles.triggerText}>{selectedLabel}</Text>
<ThemedChevronDown size={ICON_SIZE.sm} uniProps={mutedColorMapping} />
</DropdownMenuTrigger>
<DropdownMenuContent side="bottom" align="end" width={200}>
{TOOL_CALL_DETAIL_LEVELS.map((option) => (
<ToolCallDetailMenuItem
key={option}
value={option}
selected={value === option}
onChange={onChange}
/>
))}
</DropdownMenuContent>
</DropdownMenu>
</View>
);
}
// ---------------------------------------------------------------------------
// Fonts: family text fields + numeric size fields (commit on blur/submit)
// ---------------------------------------------------------------------------
@@ -427,6 +498,13 @@ export function AppearanceSection() {
[updateSettings],
);
const handleToolCallDetailLevelChange = useCallback(
(toolCallDetailLevel: AppSettings["toolCallDetailLevel"]) => {
void updateSettings({ toolCallDetailLevel });
},
[updateSettings],
);
const commitUiFontFamily = useCallback(
(value: string) => {
const sanitized = sanitizeFontFamily(value);
@@ -513,6 +591,10 @@ export function AppearanceSection() {
value={settings.autoExpandReasoning}
onChange={handleAutoExpandReasoningChange}
/>
<ToolCallDetailRow
value={settings.toolCallDetailLevel}
onChange={handleToolCallDetailLevelChange}
/>
</View>
</SettingsSection>
<SettingsSection title={t("settings.appearance.fonts.title")}>