From 057208e022a44dfbe83dff4e2d8f25e4d7204fe0 Mon Sep 17 00:00:00 2001 From: Ryan Vogel Date: Sat, 4 Apr 2026 19:43:50 +0000 Subject: [PATCH] fix: prevent spurious session-complete notifications from APN relay Remove message.updated -> complete classification in the mobile foreground SSE monitor. The processor cleanup stamps time.completed on every assistant message after each LLM step, not just at session end, causing premature complete events. The sole reliable signal is session.status with type idle. Remove the redundant status.set(idle) from the processor halt() path. The Runner onIdle callback already transitions to idle when the loop exits, so the explicit set in halt was firing a duplicate complete notification alongside the error notification. --- packages/mobile-voice/src/lib/opencode-events.ts | 16 ---------------- packages/opencode/src/session/processor.ts | 1 - 2 files changed, 17 deletions(-) diff --git a/packages/mobile-voice/src/lib/opencode-events.ts b/packages/mobile-voice/src/lib/opencode-events.ts index df4e34a67c..4ccf9829e2 100644 --- a/packages/mobile-voice/src/lib/opencode-events.ts +++ b/packages/mobile-voice/src/lib/opencode-events.ts @@ -48,22 +48,6 @@ export function classifyMonitorEvent(event: OpenCodeEvent): MonitorEventType | n } } - if (type === "message.updated") { - const info = event.properties?.info - if (info && typeof info === "object") { - const role = (info as Record).role - const time = (info as Record).time - if ( - role === "assistant" && - time && - typeof time === "object" && - "completed" in (time as Record) - ) { - return "complete" - } - } - } - return null } diff --git a/packages/opencode/src/session/processor.ts b/packages/opencode/src/session/processor.ts index 146c73f277..9adc63736d 100644 --- a/packages/opencode/src/session/processor.ts +++ b/packages/opencode/src/session/processor.ts @@ -426,7 +426,6 @@ export namespace SessionProcessor { sessionID: ctx.assistantMessage.sessionID, error: ctx.assistantMessage.error, }) - yield* status.set(ctx.sessionID, { type: "idle" }) }) const abort = Effect.fn("SessionProcessor.abort")(() =>