From 58a58f4e4e92b2480058315098e02708de775eb3 Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Thu, 8 Oct 2026 14:54:30 -0700 Subject: [PATCH] Show OMP sign-in guidance when OMP reports no model selected (#26649) * Recognize native chat sign-in failures across structured agents * Fix authentication failures and chat sign-in guidance * Preserve sign-in diagnostics and command retry context * fix(native-chat): keep visible sign-in guidance and localize startup rows * fix(native-chat): separate auth diagnostics from retry guidance * test(native-chat): align startup guidance expectations * fix(native-chat): treat OMP's signed-out 'No model selected' as not signed in * fix(native-chat): start a new agent for the send after it reports not signed in * fix(native-chat): scope the signed-out check by fence and read without a snapshot * fix(native-chat): keep a signed-out agent while it owes work, and read only its own rows * fix(native-chat): keep a signed-out agent that may owe a wake-up turn, and skip the check during a Stop --- src/main/acp/acp-dialects/omp-dialect.ts | 15 ++++++++++----- src/main/acp/acp-structured-sign-in.test.ts | 5 +++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/main/acp/acp-dialects/omp-dialect.ts b/src/main/acp/acp-dialects/omp-dialect.ts index 1714184b35f..0e38a7c2db5 100644 --- a/src/main/acp/acp-dialects/omp-dialect.ts +++ b/src/main/acp/acp-dialects/omp-dialect.ts @@ -9,6 +9,8 @@ import type { AcpDialect } from './acp-dialect' // background launch results do not establish a process exit. const textBlockSchema = z.looseObject({ type: z.literal('text'), text: z.string() }) const promptErrorDataSchema = z.looseObject({ details: z.string() }) +// OMP's prompt check: no usable model (nothing signed in), or the selected model's provider has no key. +const SIGNED_OUT_DETAIL_PREFIXES = ['No model selected.\n\nUse /login', 'No API key found for '] const toolResultSchema = z.looseObject({ content: z.array(z.unknown()), details: z @@ -95,9 +97,12 @@ function normalizeToolUpdate(update: ToolCallUpdate): ToolCallUpdate { export const OMP_ACP_DIALECT: AcpDialect = { normalizeToolUpdate, promptErrorDetail: (error) => promptErrorDataSchema.safeParse(error.data).data?.details, - authenticationRequired: (error) => - error.code === -32603 && - promptErrorDataSchema - .safeParse(error.data) - .data?.details.startsWith('No API key found for ') === true + authenticationRequired: (error) => { + const details = promptErrorDataSchema.safeParse(error.data).data?.details + return ( + error.code === -32603 && + details !== undefined && + SIGNED_OUT_DETAIL_PREFIXES.some((prefix) => details.startsWith(prefix)) + ) + } } diff --git a/src/main/acp/acp-structured-sign-in.test.ts b/src/main/acp/acp-structured-sign-in.test.ts index 06c4b8294d1..f7349b78470 100644 --- a/src/main/acp/acp-structured-sign-in.test.ts +++ b/src/main/acp/acp-structured-sign-in.test.ts @@ -99,6 +99,11 @@ it.each([ 'No API key found for anthropic.\n\nUse /login, set an API key environment variable, or create /host/agent.db', 'notSignedIn' ], + [ + 'No model selected.\n\nUse /login, set an API key environment variable, or create /host/agent.db\n\nThen use /model to select a model.', + 'notSignedIn' + ], + ['No model selected', undefined], ['Rate limit exceeded', undefined], ['Network connection failed', undefined], ['No API key found elsewhere', undefined]