fix(team): keep launch failure copy without live details
This commit is contained in:
parent
1cb9af3fc7
commit
065ec81466
2 changed files with 124 additions and 3 deletions
|
|
@ -108,6 +108,19 @@ function buildFailedSpawnCompactDetail(
|
|||
return `${failedSpawnDetails.length} teammates failed to start`;
|
||||
}
|
||||
|
||||
function buildGenericFailedSpawnPanelMessage(
|
||||
failedSpawnCount: number,
|
||||
expectedTeammateCount: number
|
||||
): string | null {
|
||||
if (failedSpawnCount <= 0) {
|
||||
return null;
|
||||
}
|
||||
if (failedSpawnCount === 1) {
|
||||
return '1 teammate failed to start';
|
||||
}
|
||||
return `${failedSpawnCount}/${Math.max(expectedTeammateCount, failedSpawnCount)} teammates failed to start`;
|
||||
}
|
||||
|
||||
export interface TeamProvisioningPresentation {
|
||||
progress: TeamProvisioningProgress;
|
||||
isActive: boolean;
|
||||
|
|
@ -184,6 +197,10 @@ export function buildTeamProvisioningPresentation({
|
|||
const failedSpawnDetails = getFailedSpawnDetails(memberSpawnStatuses);
|
||||
const failedSpawnPanelMessage = buildFailedSpawnPanelMessage(failedSpawnDetails);
|
||||
const failedSpawnCompactDetail = buildFailedSpawnCompactDetail(failedSpawnDetails);
|
||||
const genericFailedSpawnPanelMessage = buildGenericFailedSpawnPanelMessage(
|
||||
failedSpawnCount,
|
||||
expectedTeammateCount
|
||||
);
|
||||
|
||||
const { allTeammatesConfirmedAlive, hasMembersStillJoining, remainingJoinCount } =
|
||||
getLaunchJoinState({
|
||||
|
|
@ -220,7 +237,7 @@ export function buildTeamProvisioningPresentation({
|
|||
hasMembersStillJoining,
|
||||
remainingJoinCount,
|
||||
panelTitle: 'Launch failed',
|
||||
panelMessage: progress.error ?? failedSpawnPanelMessage ?? null,
|
||||
panelMessage: progress.error ?? failedSpawnPanelMessage ?? genericFailedSpawnPanelMessage,
|
||||
panelTone: 'error',
|
||||
defaultLiveOutputOpen: true,
|
||||
compactTitle: 'Launch failed',
|
||||
|
|
@ -245,7 +262,7 @@ export function buildTeamProvisioningPresentation({
|
|||
: `All ${expectedTeammateCount} teammates joined`;
|
||||
const readyDetailMessage =
|
||||
failedSpawnCount > 0
|
||||
? (failedSpawnPanelMessage ?? progress.message)
|
||||
? (failedSpawnPanelMessage ?? genericFailedSpawnPanelMessage ?? progress.message)
|
||||
: expectedTeammateCount === 0
|
||||
? 'Team provisioned - lead online'
|
||||
: allTeammatesConfirmedAlive
|
||||
|
|
@ -316,7 +333,9 @@ export function buildTeamProvisioningPresentation({
|
|||
remainingJoinCount,
|
||||
panelTitle: 'Launching team',
|
||||
panelMessage:
|
||||
failedSpawnCount > 0 ? (failedSpawnPanelMessage ?? progress.message) : progress.message,
|
||||
failedSpawnCount > 0
|
||||
? (failedSpawnPanelMessage ?? genericFailedSpawnPanelMessage ?? progress.message)
|
||||
: progress.message,
|
||||
panelMessageSeverity: failedSpawnCount > 0 ? 'warning' : progress.messageSeverity,
|
||||
defaultLiveOutputOpen: false,
|
||||
compactTitle: 'Launching team',
|
||||
|
|
|
|||
|
|
@ -155,6 +155,57 @@ describe('buildTeamProvisioningPresentation', () => {
|
|||
expect(presentation?.compactDetail).toBe('jack failed to start');
|
||||
});
|
||||
|
||||
it('keeps a generic failed teammate message when only persisted failure counts remain', () => {
|
||||
const presentation = buildTeamProvisioningPresentation({
|
||||
progress: {
|
||||
runId: 'run-3b',
|
||||
teamName: 'codex-team',
|
||||
state: 'ready',
|
||||
startedAt: '2026-04-13T10:00:00.000Z',
|
||||
updatedAt: '2026-04-13T10:00:08.000Z',
|
||||
message: 'Launch completed',
|
||||
messageSeverity: undefined,
|
||||
pid: 4321,
|
||||
cliLogsTail: '',
|
||||
assistantOutput: '',
|
||||
},
|
||||
members: [
|
||||
{
|
||||
name: 'team-lead',
|
||||
agentType: 'team-lead',
|
||||
status: 'active',
|
||||
currentTaskId: null,
|
||||
taskCount: 0,
|
||||
lastActiveAt: null,
|
||||
messageCount: 0,
|
||||
},
|
||||
{
|
||||
name: 'jack',
|
||||
agentType: 'engineer',
|
||||
status: 'unknown',
|
||||
currentTaskId: null,
|
||||
taskCount: 0,
|
||||
lastActiveAt: null,
|
||||
messageCount: 0,
|
||||
},
|
||||
],
|
||||
memberSpawnStatuses: {},
|
||||
memberSpawnSnapshot: {
|
||||
expectedMembers: ['jack'],
|
||||
summary: {
|
||||
confirmedCount: 0,
|
||||
pendingCount: 0,
|
||||
failedCount: 1,
|
||||
runtimeAlivePendingCount: 0,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(presentation?.successMessage).toBe('Launch finished with errors - 1/1 teammates failed to start');
|
||||
expect(presentation?.panelMessage).toBe('1 teammate failed to start');
|
||||
expect(presentation?.compactDetail).toBe('1 teammate failed to start');
|
||||
});
|
||||
|
||||
it('prefers live member spawn statuses over a stale persisted launch summary', () => {
|
||||
const presentation = buildTeamProvisioningPresentation({
|
||||
progress: {
|
||||
|
|
@ -218,6 +269,57 @@ describe('buildTeamProvisioningPresentation', () => {
|
|||
expect(presentation?.panelMessage).toBe('1 teammate still joining');
|
||||
});
|
||||
|
||||
it('keeps a generic failed teammate message while launch is still active if only persisted failure counts remain', () => {
|
||||
const presentation = buildTeamProvisioningPresentation({
|
||||
progress: {
|
||||
runId: 'run-4b',
|
||||
teamName: 'codex-team',
|
||||
state: 'assembling',
|
||||
startedAt: '2026-04-13T10:00:00.000Z',
|
||||
updatedAt: '2026-04-13T10:00:05.000Z',
|
||||
message: 'Finalizing launch...',
|
||||
messageSeverity: undefined,
|
||||
pid: 4321,
|
||||
cliLogsTail: '',
|
||||
assistantOutput: '',
|
||||
},
|
||||
members: [
|
||||
{
|
||||
name: 'team-lead',
|
||||
agentType: 'team-lead',
|
||||
status: 'active',
|
||||
currentTaskId: null,
|
||||
taskCount: 0,
|
||||
lastActiveAt: null,
|
||||
messageCount: 0,
|
||||
},
|
||||
{
|
||||
name: 'jack',
|
||||
agentType: 'engineer',
|
||||
status: 'unknown',
|
||||
currentTaskId: null,
|
||||
taskCount: 0,
|
||||
lastActiveAt: null,
|
||||
messageCount: 0,
|
||||
},
|
||||
],
|
||||
memberSpawnStatuses: {},
|
||||
memberSpawnSnapshot: {
|
||||
expectedMembers: ['jack'],
|
||||
summary: {
|
||||
confirmedCount: 0,
|
||||
pendingCount: 0,
|
||||
failedCount: 1,
|
||||
runtimeAlivePendingCount: 0,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(presentation?.panelMessage).toBe('1 teammate failed to start');
|
||||
expect(presentation?.compactDetail).toBe('1 teammate failed to start');
|
||||
expect(presentation?.compactTone).toBe('warning');
|
||||
});
|
||||
|
||||
it('prefers live confirmed teammates over a stale persisted launch summary', () => {
|
||||
const presentation = buildTeamProvisioningPresentation({
|
||||
progress: {
|
||||
|
|
|
|||
Loading…
Reference in a new issue