From c730a9976d139fdd6abf46a1b9f2fe3605bb3449 Mon Sep 17 00:00:00 2001 From: Brooklyn Nicholson Date: Thu, 7 May 2026 22:44:55 -0400 Subject: [PATCH] fix(desktop): surface provider onboarding from session warnings Propagate credential warnings through session runtime info and open desktop onboarding whenever a session reports no usable provider, so unconfigured installs cannot fall through to prompt errors. --- apps/desktop/src/app/session/hooks/use-message-stream.ts | 5 +++++ apps/desktop/src/app/session/hooks/use-session-actions.ts | 5 +++++ apps/desktop/src/lib/chat-messages.ts | 1 + apps/desktop/src/types/hermes.ts | 2 ++ tui_gateway/server.py | 6 +++--- 5 files changed, 16 insertions(+), 3 deletions(-) diff --git a/apps/desktop/src/app/session/hooks/use-message-stream.ts b/apps/desktop/src/app/session/hooks/use-message-stream.ts index 180f7eaa8ba..529da6769d2 100644 --- a/apps/desktop/src/app/session/hooks/use-message-stream.ts +++ b/apps/desktop/src/app/session/hooks/use-message-stream.ts @@ -17,6 +17,7 @@ import { coerceGatewayText, coerceThinkingText, normalizePersonalityValue } from import { triggerHaptic } from '@/lib/haptics' import { setClarifyRequest } from '@/store/clarify' import { notify } from '@/store/notifications' +import { requestDesktopOnboarding } from '@/store/onboarding' import { setCurrentBranch, setCurrentCwd, @@ -476,6 +477,10 @@ export function useMessageStream({ setCurrentUsage(current => ({ ...current, ...payload.usage })) } + if (typeof payload?.credential_warning === 'string' && payload.credential_warning) { + requestDesktopOnboarding(payload.credential_warning) + } + void refreshHermesConfig() if (modelChanged || providerChanged) { diff --git a/apps/desktop/src/app/session/hooks/use-session-actions.ts b/apps/desktop/src/app/session/hooks/use-session-actions.ts index b73b9be6d6c..926f934e698 100644 --- a/apps/desktop/src/app/session/hooks/use-session-actions.ts +++ b/apps/desktop/src/app/session/hooks/use-session-actions.ts @@ -9,6 +9,7 @@ import { embeddedImageUrls, textWithoutEmbeddedImages } from '@/lib/embedded-ima import { clearComposerAttachments, clearComposerDraft } from '@/store/composer' import { $pinnedSessionIds } from '@/store/layout' import { clearNotifications, notify, notifyError } from '@/store/notifications' +import { requestDesktopOnboarding } from '@/store/onboarding' import { $messages, $sessions, @@ -187,6 +188,10 @@ function applyRuntimeInfo(info: SessionCreateResponse['info'] | undefined) { return } + if (info.credential_warning) { + requestDesktopOnboarding(info.credential_warning) + } + if (info.model) { setCurrentModel(info.model) } diff --git a/apps/desktop/src/lib/chat-messages.ts b/apps/desktop/src/lib/chat-messages.ts index ce36101f127..0c072db3aea 100644 --- a/apps/desktop/src/lib/chat-messages.ts +++ b/apps/desktop/src/lib/chat-messages.ts @@ -39,6 +39,7 @@ export type GatewayEventPayload = { running?: boolean cwd?: string branch?: string + credential_warning?: string personality?: string usage?: Partial // clarify.request diff --git a/apps/desktop/src/types/hermes.ts b/apps/desktop/src/types/hermes.ts index 2bbb07b4bf7..b61f4e91954 100644 --- a/apps/desktop/src/types/hermes.ts +++ b/apps/desktop/src/types/hermes.ts @@ -164,6 +164,8 @@ export interface SessionResumeResponse { export interface SessionRuntimeInfo { branch?: string + config_warning?: string + credential_warning?: string cwd?: string fast?: boolean model?: string diff --git a/tui_gateway/server.py b/tui_gateway/server.py index 707b0adb111..12297e9a9e9 100644 --- a/tui_gateway/server.py +++ b/tui_gateway/server.py @@ -583,9 +583,6 @@ def _start_agent_build(sid: str, session: dict) -> None: _notify_session_boundary("on_session_reset", key) info = _session_info(agent, current) - warn = _probe_credentials(agent) - if warn: - info["credential_warning"] = warn cfg_warn = _probe_config_health(_load_cfg()) if cfg_warn: info["config_warning"] = cfg_warn @@ -1513,6 +1510,9 @@ def _session_info(agent, session: dict | None = None) -> dict: info["update_command"] = recommended_update_command() except Exception: pass + warn = _probe_credentials(agent) + if warn: + info["credential_warning"] = warn return info