From 20f3916d55046e44de58982a7905ca3ad4e8fc7d Mon Sep 17 00:00:00 2001 From: Tam Nhu Tran Date: Tue, 28 Apr 2026 12:26:42 -0400 Subject: [PATCH] fix(cliproxy): tighten session affinity status handling --- src/cliproxy/config/generator.ts | 4 ++- .../monitoring/proxy-status-widget.tsx | 28 ++++++++++++------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/cliproxy/config/generator.ts b/src/cliproxy/config/generator.ts index 926bdc9e..c10432e8 100644 --- a/src/cliproxy/config/generator.ts +++ b/src/cliproxy/config/generator.ts @@ -99,6 +99,8 @@ const MIN_STALE_HIGH_ONLY_GEMINI_MINOR_VERSIONS = 3; const MIN_STALE_GUESSED_GEMINI_AVERAGE_VARIANTS_PER_MINOR = 2; const LEGACY_GEMINI_STALE_ALIAS_MIGRATION_VERSION = 16; const MAX_LEGACY_MANUAL_GEMINI_MINOR_VERSION = 2; +const GO_DURATION_SEGMENT = String.raw`(?:\d+(?:\.\d+)?(?:ns|us|µs|μs|ms|s|m|h))`; +const GO_DURATION_PATTERN = new RegExp(`^${GO_DURATION_SEGMENT}+$`); /** * Get provider configuration @@ -139,7 +141,7 @@ function getSessionAffinityEnabled(): boolean { function getSessionAffinityTtl(): string { const ttl = loadOrCreateUnifiedConfig().cliproxy?.routing?.session_affinity_ttl?.trim(); - return ttl || '1h'; + return ttl && GO_DURATION_PATTERN.test(ttl) ? ttl : '1h'; } function sanitizeYamlScalar(rawValue: string): string { diff --git a/ui/src/components/monitoring/proxy-status-widget.tsx b/ui/src/components/monitoring/proxy-status-widget.tsx index 3ad7809b..0c6e1ffa 100644 --- a/ui/src/components/monitoring/proxy-status-widget.tsx +++ b/ui/src/components/monitoring/proxy-status-widget.tsx @@ -168,12 +168,20 @@ export function ProxyStatusWidget() { } = useCliproxySessionAffinity(); const updateSessionAffinity = useUpdateCliproxySessionAffinity(); const isSavingRoutingConfig = updateRouting.isPending || updateSessionAffinity.isPending; - const routingConfigError = - routingError instanceof Error - ? routingError - : sessionAffinityError instanceof Error - ? sessionAffinityError - : null; + const routingConfigError = routingError instanceof Error ? routingError : null; + const effectiveSessionAffinityState = + sessionAffinityState ?? + (sessionAffinityError instanceof Error + ? { + source: 'unsupported' as const, + target: (routingState?.target ?? (isRemoteMode ? 'remote' : 'local')) as + | 'local' + | 'remote', + reachable: false, + manageable: false, + message: sessionAffinityError.message, + } + : undefined); const startProxy = useStartProxy(); const stopProxy = useStopProxy(); const restartProxy = useRestartProxy(); @@ -330,11 +338,11 @@ export function ProxyStatusWidget() {