From d50d81632a26df0cd9fae63b361e8827be891b50 Mon Sep 17 00:00:00 2001 From: 777genius Date: Sun, 31 May 2026 09:31:50 +0300 Subject: [PATCH] fix(renderer): suppress recoverable OpenCode refresh advisories --- src/renderer/utils/memberHelpers.ts | 3 +- src/renderer/utils/memberLaunchDiagnostics.ts | 3 +- test/renderer/utils/memberHelpers.test.ts | 7 ++- .../utils/memberLaunchDiagnostics.test.ts | 62 +++++++++++++++++++ 4 files changed, 70 insertions(+), 5 deletions(-) diff --git a/src/renderer/utils/memberHelpers.ts b/src/renderer/utils/memberHelpers.ts index 2f5b1d00..63314306 100644 --- a/src/renderer/utils/memberHelpers.ts +++ b/src/renderer/utils/memberHelpers.ts @@ -414,7 +414,8 @@ function isRecoverableOpenCodeSessionRefreshMessage(message: string | undefined) refreshMarkerText === 'opencode session changed; refreshing the session before retry' || refreshMarkerText === 'opencode session refresh scheduled after resolved behavior changed' || refreshMarkerText === 'opencode_prompt_delivery_session_refresh_scheduled' || - refreshMarkerText === 'opencode_session_refresh_scheduled_after_resolved_behavior_changed' + refreshMarkerText === 'opencode_session_refresh_scheduled_after_resolved_behavior_changed' || + refreshMarkerText === 'opencode_session_stale_observe_scheduled_after_accepted_prompt' ) { return true; } diff --git a/src/renderer/utils/memberLaunchDiagnostics.ts b/src/renderer/utils/memberLaunchDiagnostics.ts index e4efbeeb..0010fe55 100644 --- a/src/renderer/utils/memberLaunchDiagnostics.ts +++ b/src/renderer/utils/memberLaunchDiagnostics.ts @@ -214,7 +214,8 @@ function isRecoverableOpenCodeSessionRefreshText(value: string | undefined): boo refreshMarkerText === 'opencode session changed; refreshing the session before retry' || refreshMarkerText === 'opencode session refresh scheduled after resolved behavior changed' || refreshMarkerText === 'opencode_prompt_delivery_session_refresh_scheduled' || - refreshMarkerText === 'opencode_session_refresh_scheduled_after_resolved_behavior_changed' + refreshMarkerText === 'opencode_session_refresh_scheduled_after_resolved_behavior_changed' || + refreshMarkerText === 'opencode_session_stale_observe_scheduled_after_accepted_prompt' ) { return true; } diff --git a/test/renderer/utils/memberHelpers.test.ts b/test/renderer/utils/memberHelpers.test.ts index b717d5f0..7a84f6aa 100644 --- a/test/renderer/utils/memberHelpers.test.ts +++ b/test/renderer/utils/memberHelpers.test.ts @@ -1,12 +1,12 @@ import { buildMemberLaunchPresentation, getLaunchAwarePresenceLabel, - getSpawnAwareDotClass, - getSpawnAwarePresenceLabel, - getSpawnCardClass, getMemberRuntimeAdvisoryLabel, getMemberRuntimeAdvisoryTitle, getMemberRuntimeAdvisoryTone, + getSpawnAwareDotClass, + getSpawnAwarePresenceLabel, + getSpawnCardClass, isOpenCodeRelaunchActionable, shouldDisplayMemberCurrentTask, } from '@renderer/utils/memberHelpers'; @@ -1333,6 +1333,7 @@ describe('memberHelpers spawn-aware presence', () => { 'OpenCode API error. opencode_prompt_delivery_session_refresh_scheduled.', 'OpenCode session refresh scheduled after resolved behavior changed', 'opencode_session_refresh_scheduled_after_resolved_behavior_changed', + 'OpenCode API error. opencode_session_stale_observe_scheduled_after_accepted_prompt', ])('renders recoverable OpenCode session refresh advisory %s as a warning', (message) => { const advisory = { kind: 'api_error' as const, diff --git a/test/renderer/utils/memberLaunchDiagnostics.test.ts b/test/renderer/utils/memberLaunchDiagnostics.test.ts index 1117052e..ab8b7d73 100644 --- a/test/renderer/utils/memberLaunchDiagnostics.test.ts +++ b/test/renderer/utils/memberLaunchDiagnostics.test.ts @@ -851,6 +851,68 @@ describe('member launch diagnostics', () => { expect(hasMemberLaunchDiagnosticsError(payload)).toBe(false); }); + it('suppresses stale observe scheduled OpenCode API advisories while the runtime is alive', () => { + const payload = buildMemberLaunchDiagnosticsPayload({ + teamName: 'atlas-hq-15', + runId: 'd78fd1d5-f60b-4704-9df3-867c79e840b3', + memberName: 'bob', + member: { + name: 'bob', + providerId: 'opencode', + model: 'opencode/deepseek-v4-flash-free', + agentType: 'general-purpose', + laneId: 'secondary:opencode:bob', + laneKind: 'secondary', + laneOwnerProviderId: 'opencode', + }, + spawnEntry: { + status: 'online', + launchState: 'confirmed_alive', + runtimeAlive: true, + bootstrapConfirmed: true, + agentToolAccepted: true, + hardFailure: false, + runtimeDiagnostic: 'OpenCode runtime process detected after bootstrap confirmation', + runtimeDiagnosticSeverity: 'info', + livenessKind: 'runtime_process', + livenessSource: 'heartbeat', + updatedAt: '2026-05-30T17:17:33.910Z', + }, + runtimeEntry: { + memberName: 'bob', + providerId: 'opencode', + runtimeModel: 'opencode/deepseek-v4-flash-free', + backendType: 'process', + alive: true, + restartable: false, + livenessKind: 'runtime_process', + runtimeDiagnostic: 'OpenCode runtime process detected after bootstrap confirmation', + runtimeDiagnosticSeverity: 'info', + diagnostics: [ + 'OpenCode API error', + 'opencode_session_stale_observe_scheduled_after_accepted_prompt', + 'matched OpenCode runtime pid and process identity', + 'bootstrap confirmed', + ], + updatedAt: '2026-05-30T17:28:39.655Z', + }, + runtimeAdvisoryLabel: 'OpenCode API error', + runtimeAdvisoryTitle: 'OpenCode API error', + runtimeAdvisory: { + kind: 'api_error', + observedAt: '2026-05-30T17:26:24.466Z', + reasonCode: 'backend_error', + message: 'OpenCode API error. opencode_session_stale_observe_scheduled_after_accepted_prompt', + }, + }); + + expect(payload.memberCardError).toBeUndefined(); + expect(hasMemberLaunchDiagnosticsError(payload)).toBe(false); + expect(payload.diagnostics).toContain( + 'opencode_session_stale_observe_scheduled_after_accepted_prompt' + ); + }); + it('treats member card errors from runtime advisory as diagnostics errors', () => { const payload = buildMemberLaunchDiagnosticsPayload({ memberName: 'tom',