diff --git a/src/main/services/infrastructure/CliInstallerService.ts b/src/main/services/infrastructure/CliInstallerService.ts index 4833861b..ee902cb7 100644 --- a/src/main/services/infrastructure/CliInstallerService.ts +++ b/src/main/services/infrastructure/CliInstallerService.ts @@ -734,6 +734,38 @@ export class CliInstallerService { }; } + private getLatestProviderStatusForModelVerification( + providerId: CliProviderId, + binaryPath: string, + installedVersion: string | null + ): CliProviderStatus | null { + const snapshot = this.latestStatusSnapshot; + if ( + !snapshot || + snapshot.flavor !== 'agent_teams_orchestrator' || + snapshot.binaryPath !== binaryPath || + snapshot.installedVersion !== installedVersion + ) { + return null; + } + + const provider = + cloneCliInstallationStatus(snapshot).providers.find( + (candidate) => candidate.providerId === providerId + ) ?? null; + if ( + !provider || + provider.models.length <= 0 || + provider.supported !== true || + provider.authenticated !== true || + provider.capabilities.oneShot !== true + ) { + return null; + } + + return provider; + } + // --------------------------------------------------------------------------- // Public: getStatus // --------------------------------------------------------------------------- @@ -844,10 +876,12 @@ export class CliInstallerService { return nextProviderStatus; } - const providerStatus = await this.multimodelBridgeService.getProviderStatus( - binaryPath, - providerId - ); + const providerStatus = + this.getLatestProviderStatusForModelVerification( + providerId, + binaryPath, + versionProbe.version + ) ?? (await this.multimodelBridgeService.getProviderStatus(binaryPath, providerId)); const nextProviderStatus = this.applyProviderModelAvailabilityToProvider( binaryPath, versionProbe.version, diff --git a/test/main/services/team/TeamInboxWriter.test.ts b/test/main/services/team/TeamInboxWriter.test.ts index 6d24dccb..2ef629a1 100644 --- a/test/main/services/team/TeamInboxWriter.test.ts +++ b/test/main/services/team/TeamInboxWriter.test.ts @@ -70,6 +70,7 @@ vi.mock('../../../../src/main/services/team/atomicWrite', () => ({ vi.mock('../../../../src/main/services/team/fileLock', () => ({ withFileLock: async (_path: string, fn: () => Promise) => await fn(), + withFileLockSync: (_path: string, fn: () => unknown) => fn(), })); vi.mock('../../../../src/main/services/team/inboxLock', () => ({ diff --git a/test/main/services/team/TeamProvisioningServiceLiveMessages.test.ts b/test/main/services/team/TeamProvisioningServiceLiveMessages.test.ts index 5309f8d1..25a990c2 100644 --- a/test/main/services/team/TeamProvisioningServiceLiveMessages.test.ts +++ b/test/main/services/team/TeamProvisioningServiceLiveMessages.test.ts @@ -75,6 +75,7 @@ vi.mock('../../../../src/main/services/team/atomicWrite', () => ({ vi.mock('../../../../src/main/services/team/fileLock', () => ({ withFileLock: async (_filePath: string, fn: () => Promise) => await fn(), + withFileLockSync: (_filePath: string, fn: () => unknown) => fn(), })); vi.mock('../../../../src/main/services/team/inboxLock', () => ({ diff --git a/test/main/services/team/TeamProvisioningServicePostCompact.test.ts b/test/main/services/team/TeamProvisioningServicePostCompact.test.ts index ff2d20c2..76541954 100644 --- a/test/main/services/team/TeamProvisioningServicePostCompact.test.ts +++ b/test/main/services/team/TeamProvisioningServicePostCompact.test.ts @@ -346,7 +346,7 @@ describe('TeamProvisioningService post-compact lifecycle', () => { expect(text).not.toContain('continue with any pending work'); // Should be context-only expect(text).toContain('Do NOT start new work'); - expect(text).toContain('Reply with a single word'); + expect(text).toContain('Reply with one concise user-facing team status line'); // Should contain persistent context expect(text).toContain('Constraints:'); expect(text).toContain('Do NOT call TeamDelete'); diff --git a/test/main/services/team/TeamProvisioningServicePrompts.test.ts b/test/main/services/team/TeamProvisioningServicePrompts.test.ts index 1d86e610..86d0fe8d 100644 --- a/test/main/services/team/TeamProvisioningServicePrompts.test.ts +++ b/test/main/services/team/TeamProvisioningServicePrompts.test.ts @@ -288,7 +288,7 @@ describe('TeamProvisioningService prompt content (solo mode discipline)', () => ); expect(prompt).toContain('Do NOT start implementation in this turn.'); expect(prompt).toContain( - 'Use this turn only to refresh context, review the current board snapshot, and confirm you are ready.' + 'Use this turn only to review the current board snapshot and confirm operational readiness.' ); expect(prompt).toContain( 'Do NOT create, assign, or delegate any new task in this turn. If the board is empty, stay silent and wait for a fresh user instruction.' @@ -866,7 +866,7 @@ describe('TeamProvisioningService prompt content (solo mode discipline)', () => ); expect(prompt).toContain('Do NOT use Agent to spawn or restore teammates.'); expect(prompt).toContain( - 'Use this turn only to refresh context and review the current board snapshot.' + 'Use this turn only to review the current board snapshot and teammate readiness.' ); expect(prompt).toContain( 'Do NOT create, assign, or delegate any new task in this turn. If the board is empty, stay silent and wait for a fresh user instruction.' diff --git a/test/main/services/team/TeamProvisioningServiceRelay.test.ts b/test/main/services/team/TeamProvisioningServiceRelay.test.ts index 8028e288..ee8a5e2b 100644 --- a/test/main/services/team/TeamProvisioningServiceRelay.test.ts +++ b/test/main/services/team/TeamProvisioningServiceRelay.test.ts @@ -113,6 +113,7 @@ vi.mock('../../../../src/main/services/team/atomicWrite', () => ({ vi.mock('../../../../src/main/services/team/fileLock', () => ({ withFileLock: async (_filePath: string, fn: () => Promise) => await fn(), + withFileLockSync: (_filePath: string, fn: () => unknown) => fn(), })); vi.mock('../../../../src/main/services/team/inboxLock', () => ({