fix(desktop): expire unknown readiness notices and clear on recovery
This commit is contained in:
@@ -246,28 +246,31 @@ describe('refreshOnboarding', () => {
|
||||
expect(window.localStorage.getItem('hermes-desktop-onboarded-v1')).toBe('1')
|
||||
})
|
||||
|
||||
it('shows a non-blocking notification when preserving configured on fallback', async () => {
|
||||
const notifySpy = vi.spyOn(notifications, 'notify')
|
||||
|
||||
it('keeps an unknown readiness notice temporary and clears it on recovery (#124545)', async () => {
|
||||
vi.useFakeTimers()
|
||||
notifications.clearNotifications()
|
||||
installApiMock(vi.fn())
|
||||
$desktopOnboarding.set(
|
||||
baseState({
|
||||
configured: true,
|
||||
providers: [makeOAuthProvider('cached')],
|
||||
reason: null,
|
||||
requested: false
|
||||
})
|
||||
)
|
||||
$desktopOnboarding.set(baseState({ configured: true }))
|
||||
|
||||
await refreshOnboarding(onboardingContext(fallbackTimeoutGateway()))
|
||||
try {
|
||||
await refreshOnboarding(onboardingContext(fallbackTimeoutGateway()))
|
||||
expect(notifications.$notifications.get()).toEqual([
|
||||
expect.objectContaining({ id: 'runtime-not-ready', kind: 'info' })
|
||||
])
|
||||
expect($desktopOnboarding.get().configured).toBe(true)
|
||||
await vi.advanceTimersByTimeAsync(5_000)
|
||||
expect(notifications.$notifications.get()).toEqual([])
|
||||
|
||||
expect(notifySpy).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
id: 'runtime-not-ready',
|
||||
kind: 'error'
|
||||
})
|
||||
)
|
||||
expect($desktopOnboarding.get().configured).toBe(true)
|
||||
// A later outage can show a fresh notice; an authoritative ready clears it
|
||||
// without waiting for its timer, and must not dismiss unrelated errors.
|
||||
await refreshOnboarding(onboardingContext(fallbackTimeoutGateway()))
|
||||
notifications.notify({ id: 'unrelated', kind: 'error', message: 'Keep me' })
|
||||
await refreshOnboarding(onboardingContext(keylessCustomGateway()))
|
||||
expect(notifications.$notifications.get().map(item => item.id)).toEqual(['unrelated'])
|
||||
} finally {
|
||||
notifications.clearNotifications()
|
||||
vi.useRealTimers()
|
||||
}
|
||||
})
|
||||
|
||||
it('enters setup when the selected OpenRouter credential is genuinely empty', async () => {
|
||||
|
||||
@@ -18,7 +18,7 @@ import { isProviderSetupErrorMessage } from '@/lib/provider-setup-errors'
|
||||
import { evaluateRuntimeReadiness, type RuntimeReadinessResult } from '@/lib/runtime-readiness'
|
||||
import { ackFreeTierNotice, freeTierReadyPending, refreshFreeTierStatus, setFreeTierRoute } from '@/store/free-tier'
|
||||
import { setMainModelAssignment } from '@/store/model-assignment'
|
||||
import { notify, notifyError } from '@/store/notifications'
|
||||
import { dismissNotification, notify, notifyError } from '@/store/notifications'
|
||||
import { guidedOnboardingActive } from '@/store/onboarding-gate'
|
||||
import { captureOnboardingScope, type OnboardingScope } from '@/store/onboarding-scope'
|
||||
import type { OAuthProvider, OAuthStartResponse } from '@/types/hermes'
|
||||
@@ -645,6 +645,7 @@ export function closeManualOnboarding() {
|
||||
|
||||
export function completeDesktopOnboarding() {
|
||||
clearPoll()
|
||||
dismissNotification('runtime-not-ready')
|
||||
writeCachedConfigured(true)
|
||||
// A real provider is now connected, so any earlier "choose later" skip is
|
||||
// moot — clear it so the flag never lingers in a configured install.
|
||||
@@ -721,12 +722,11 @@ export async function refreshOnboarding(ctx: OnboardingContext, stillWanted?: ()
|
||||
|
||||
if (shouldPreserveConfiguredOnFallback(runtime, state)) {
|
||||
// Gateway probes timed out but the user was already configured — don't
|
||||
// downgrade to the blocking onboarding overlay. Surface a non-blocking
|
||||
// notification with a stable id so repeated calls during an outage dedup
|
||||
// instead of stacking toasts.
|
||||
// downgrade to the blocking onboarding overlay or claim an error verdict.
|
||||
// Use the temporary informational notice; recovery clears it early.
|
||||
notify({
|
||||
id: 'runtime-not-ready',
|
||||
kind: 'error',
|
||||
kind: 'info',
|
||||
title: 'Runtime not ready',
|
||||
message:
|
||||
'Hermes Desktop could not verify the running backend on startup. Some features may be unavailable until the gateway is reachable.'
|
||||
|
||||
Reference in New Issue
Block a user