From adb66052d54dff825213396c62000bc8ac1903c4 Mon Sep 17 00:00:00 2001 From: Kristjan Kruus Date: Wed, 25 Mar 2026 17:15:20 +0200 Subject: [PATCH] fix: address PR review feedback for config UI controls - Fix subturn_max_depth_hint: clarify that 0 uses default (3), not disable - Fix subturn_default_timeout_hint: clarify that 0 uses system default (5 min) - Add fatal log level option to i18n translations (en + zh) - Extract select .find() lookups to component-level variables - Add validation: routing enabled requires non-empty light_model - Only parse filterMinLength when filter_sensitive_data is enabled --- .../src/components/config/config-page.tsx | 16 +++-- .../src/components/config/config-sections.tsx | 72 +++++++++---------- web/frontend/src/i18n/locales/en.json | 5 +- web/frontend/src/i18n/locales/zh.json | 5 +- 4 files changed, 50 insertions(+), 48 deletions(-) diff --git a/web/frontend/src/components/config/config-page.tsx b/web/frontend/src/components/config/config-page.tsx index 5af2902bd..779ac2856 100644 --- a/web/frontend/src/components/config/config-page.tsx +++ b/web/frontend/src/components/config/config-page.tsx @@ -213,6 +213,9 @@ export function ConfigPage() { ) // Routing fields + if (form.routingEnabled && !form.routingLightModel.trim()) { + throw new Error("Light Model is required when Smart Routing is enabled.") + } const routingThreshold = form.routingEnabled ? parseFloatField(form.routingThreshold, "Routing threshold", { min: 0, @@ -230,11 +233,12 @@ export function ConfigPage() { const maxMediaSize = form.maxMediaSize.trim() ? parseIntField(form.maxMediaSize, "Max media size", { min: 0 }) : undefined - const filterMinLength = parseIntField( - form.filterMinLength, - "Filter min length", - { min: 0 }, - ) + const filterMinLength = + form.filterSensitiveData && form.filterMinLength.trim() + ? parseIntField(form.filterMinLength, "Filter min length", { + min: 0, + }) + : undefined const execConfigPatch: Record = { enabled: form.execEnabled, @@ -287,7 +291,7 @@ export function ConfigPage() { routing: form.routingEnabled ? { enabled: true, - light_model: form.routingLightModel, + light_model: form.routingLightModel.trim() || undefined, threshold: routingThreshold, } : { enabled: false }, diff --git a/web/frontend/src/components/config/config-sections.tsx b/web/frontend/src/components/config/config-sections.tsx index da5c574d2..3ea00562a 100644 --- a/web/frontend/src/components/config/config-sections.tsx +++ b/web/frontend/src/components/config/config-sections.tsx @@ -72,6 +72,9 @@ export function AgentDefaultsSection({ onFieldChange, }: AgentDefaultsSectionProps) { const { t } = useTranslation() + const selectedSteeringModeOption = STEERING_MODE_OPTIONS.find( + (o) => o.value === form.steeringMode, + ) return ( @@ -210,36 +213,28 @@ export function AgentDefaultsSection({ hint={t("pages.config.steering_mode_hint")} layout="setting-row" > - {(() => { - const selectedSteeringModeOption = STEERING_MODE_OPTIONS.find( - (o) => o.value === form.steeringMode, - ) - - return ( - - ) - })()} + o.value === form.gatewayLogLevel, + ) const selectedDmScopeOption = DM_SCOPE_OPTIONS.find( (scope) => scope.value === form.dmScope, ) @@ -704,14 +702,12 @@ export function RuntimeSection({ form, onFieldChange }: RuntimeSectionProps) { > - {(() => { - const selected = LOG_LEVEL_OPTIONS.find( - (o) => o.value === form.gatewayLogLevel, - ) - return selected - ? t(selected.labelKey, selected.labelDefault) - : form.gatewayLogLevel - })()} + {selectedLogLevelOption + ? t( + selectedLogLevelOption.labelKey, + selectedLogLevelOption.labelDefault, + ) + : form.gatewayLogLevel} diff --git a/web/frontend/src/i18n/locales/en.json b/web/frontend/src/i18n/locales/en.json index a919c4eb7..f7d8f33c7 100644 --- a/web/frontend/src/i18n/locales/en.json +++ b/web/frontend/src/i18n/locales/en.json @@ -513,11 +513,11 @@ "max_media_size_hint": "Maximum upload file size in bytes. Leave empty for the default (20 MB).", "subturn_description": "Configure sub-turn spawning for background tasks and parallel agent work.", "subturn_max_depth": "Max Depth", - "subturn_max_depth_hint": "Maximum nesting depth for spawned sub-turns. Set to 0 to disable spawning.", + "subturn_max_depth_hint": "Maximum nesting depth for spawned sub-turns. Values \u2264 0 use the default (3).", "subturn_max_concurrent": "Max Concurrent", "subturn_max_concurrent_hint": "Maximum number of sub-turns that can run in parallel.", "subturn_default_timeout": "Default Timeout (minutes)", - "subturn_default_timeout_hint": "Default timeout in minutes for spawned sub-turns. Set to 0 for no timeout.", + "subturn_default_timeout_hint": "Default timeout in minutes for spawned sub-turns. Leave empty or set to 0 to use the system default (5 minutes).", "subturn_token_budget": "Token Budget", "subturn_token_budget_hint": "Default token budget for each sub-turn. Set to 0 for unlimited.", "subturn_concurrency_timeout": "Concurrency Timeout (seconds)", @@ -541,6 +541,7 @@ "log_level_info": "Info", "log_level_warn": "Warn", "log_level_error": "Error", + "log_level_fatal": "Fatal", "sections": { "agent": "Agent", "runtime": "Runtime", diff --git a/web/frontend/src/i18n/locales/zh.json b/web/frontend/src/i18n/locales/zh.json index 3d22b3303..32378fc59 100644 --- a/web/frontend/src/i18n/locales/zh.json +++ b/web/frontend/src/i18n/locales/zh.json @@ -513,11 +513,11 @@ "max_media_size_hint": "上传文件的最大字节数。留空使用默认值(20 MB)。", "subturn_description": "配置子轮次的后台任务派生与并行工作。", "subturn_max_depth": "最大深度", - "subturn_max_depth_hint": "派生子轮次的最大嵌套深度。设为 0 禁用派生。", + "subturn_max_depth_hint": "派生子轮次的最大嵌套深度。设为 0 或留空将使用默认值(3)。", "subturn_max_concurrent": "最大并发数", "subturn_max_concurrent_hint": "可同时运行的子轮次最大数量。", "subturn_default_timeout": "默认超时(分钟)", - "subturn_default_timeout_hint": "派生子轮次的默认超时时间(分钟)。设为 0 表示无超时。", + "subturn_default_timeout_hint": "派生子轮次的默认超时时间(分钟)。留空或设为 0 使用系统默认值(5 分钟)。", "subturn_token_budget": "Token 预算", "subturn_token_budget_hint": "每个子轮次的默认 Token 预算。设为 0 表示不限制。", "subturn_concurrency_timeout": "并发超时(秒)", @@ -541,6 +541,7 @@ "log_level_info": "信息", "log_level_warn": "警告", "log_level_error": "错误", + "log_level_fatal": "致命", "sections": { "agent": "智能体", "runtime": "运行时",