diff --git a/frontend/src/i18n/locales/en.json b/frontend/src/i18n/locales/en.json index ecc980e131..2f96ec4119 100644 --- a/frontend/src/i18n/locales/en.json +++ b/frontend/src/i18n/locales/en.json @@ -1605,6 +1605,9 @@ "available": "Ready on Commonly", "revoked": "Disconnected: key revoked", "stale": "Not seen in {{count}} min", + "staleHours": "Not seen in {{count}} h", + "staleDays_one": "Not seen in {{count}} day", + "staleDays_other": "Not seen in {{count}} days", "never": "Not connected yet", "reconnect": "Reconnect", "reconnectWaiting": "Waiting for your computer to reconnect this agent.", diff --git a/frontend/src/i18n/locales/zh-CN.json b/frontend/src/i18n/locales/zh-CN.json index ec401c9906..8a09d9e955 100644 --- a/frontend/src/i18n/locales/zh-CN.json +++ b/frontend/src/i18n/locales/zh-CN.json @@ -1665,6 +1665,8 @@ "available": "可在 Commonly 使用", "revoked": "密钥已撤销,连接已断开", "stale": "已{{count}}分钟未连接", + "staleHours": "已{{count}}小时未连接", + "staleDays_other": "已{{count}}天未连接", "never": "尚未连接", "reconnect": "重新连接", "reconnectWaiting": "正在等待电脑重新连接此智能体。", diff --git a/frontend/src/v2/__tests__/agentConnection.test.ts b/frontend/src/v2/__tests__/agentConnection.test.ts index 69fdc0ee74..dc27db0668 100644 --- a/frontend/src/v2/__tests__/agentConnection.test.ts +++ b/frontend/src/v2/__tests__/agentConnection.test.ts @@ -20,3 +20,14 @@ it('shows elapsed minutes from the last poll', () => { expect(connectionLabel({ state: 'stale', lastSeenAt: '2026-10-23T15:54:00Z' }, t, Date.parse('2026-10-23T16:00:00Z'))).toBe('Not seen in 6 min'); }); + +it('reads an hour-plus gap in hours, and a day-plus gap in days', () => { + const now = Date.parse('2026-10-30T16:00:00Z'); + // 6390 minutes is 106 hours: four days, the case that read "6390 min" on the page. + expect(connectionLabel({ state: 'stale', lastSeenAt: new Date(now - 6390 * 60000).toISOString() }, (k, o) => `${k}:${o?.count}`, now)) + .toBe('agentConnection.staleDays:4'); + expect(connectionLabel({ state: 'stale', lastSeenAt: new Date(now - 90 * 60000).toISOString() }, (k, o) => `${k}:${o?.count}`, now)) + .toBe('agentConnection.staleHours:1'); + expect(connectionLabel({ state: 'stale', lastSeenAt: new Date(now - 59 * 60000).toISOString() }, (k, o) => `${k}:${o?.count}`, now)) + .toBe('agentConnection.stale:59'); +}); diff --git a/frontend/src/v2/utils/agentConnection.ts b/frontend/src/v2/utils/agentConnection.ts index 60e7f8ae8d..3a65f8db71 100644 --- a/frontend/src/v2/utils/agentConnection.ts +++ b/frontend/src/v2/utils/agentConnection.ts @@ -14,5 +14,8 @@ export const connectionLabel = ( if (connection.state === 'connected') return t('agentConnection.connected'); const seen = connection.lastSeenAt ? new Date(connection.lastSeenAt).getTime() : NaN; const minutes = Number.isFinite(seen) ? Math.max(1, Math.floor((now - seen) / 60000)) : 1; - return t('agentConnection.stale', { count: minutes }); + // Past an hour, minutes stop helping: 6390 min reads as four days. + if (minutes < 60) return t('agentConnection.stale', { count: minutes }); + if (minutes < 1440) return t('agentConnection.staleHours', { count: Math.floor(minutes / 60) }); + return t('agentConnection.staleDays', { count: Math.floor(minutes / 1440) }); };