diff --git a/apps/desktop/src/features/chat/transcript/ActivityGroup.tsx b/apps/desktop/src/features/chat/transcript/ActivityGroup.tsx index 9018094476..b4a20e3114 100644 --- a/apps/desktop/src/features/chat/transcript/ActivityGroup.tsx +++ b/apps/desktop/src/features/chat/transcript/ActivityGroup.tsx @@ -503,6 +503,11 @@ export function RunActivityIndicator({ activity }: { activity: AgentActivity }) {retryErrorSummary} {retryError.code} + {/* The transport errno names the failing layer (ENOTFOUND, a + TLS code, a dropped socket) while the localized summary + cannot; it is a technical token in the same style as the + code beside it, so it needs no translation (issue #234). */} + {retryError.networkCode ? ` · ${retryError.networkCode}` : ""} {retryError.providerStatus !== undefined ? ` · HTTP ${retryError.providerStatus}` : ""} diff --git a/apps/desktop/src/features/chat/transcript/shared.tsx b/apps/desktop/src/features/chat/transcript/shared.tsx index 89dcc66884..4fe311e50b 100644 --- a/apps/desktop/src/features/chat/transcript/shared.tsx +++ b/apps/desktop/src/features/chat/transcript/shared.tsx @@ -149,6 +149,15 @@ export function AssistantErrorMessage({ message }: { message: UiMessage }) { "PROVIDER_SECRET_MISSING", "PROVIDER_UNAUTHORIZED", ].includes(error.code); + // The transport errno is what separates "DNS did not resolve" from "TLS was + // rejected" from "the socket died" for the user; the localized summary can + // only say "can't reach the provider" (issue #234). + const networkCode = (() => { + const details = error.details; + if (!details || typeof details !== "object") return undefined; + const value = (details as { networkCode?: unknown }).networkCode; + return typeof value === "string" ? value : undefined; + })(); return (
@@ -158,7 +167,10 @@ export function AssistantErrorMessage({ message }: { message: UiMessage }) {
{summary} - {error.code} + + {error.code} + {networkCode ? ` · ${networkCode}` : ""} +