fix(team): match suffixed live agents during reconcile
This commit is contained in:
parent
1223fa236a
commit
b29adf1008
2 changed files with 36 additions and 10 deletions
|
|
@ -12666,14 +12666,12 @@ export class TeamProvisioningService {
|
||||||
current.bootstrapConfirmed = true;
|
current.bootstrapConfirmed = true;
|
||||||
current.lastHeartbeatAt = current.lastHeartbeatAt ?? bootstrapMember.lastHeartbeatAt;
|
current.lastHeartbeatAt = current.lastHeartbeatAt ?? bootstrapMember.lastHeartbeatAt;
|
||||||
}
|
}
|
||||||
const matchedRuntimeNames = [...configMembers].filter((name) => {
|
const matchedConfigNames = [...configMembers].filter((name) =>
|
||||||
if (name === expected) return true;
|
matchesTeamMemberIdentity(name, expected)
|
||||||
const parsed = parseNumericSuffixName(name);
|
);
|
||||||
return parsed !== null && parsed.suffix >= 2 && parsed.base === expected;
|
const runtimeAlive = [...liveAgentNames].some((name) =>
|
||||||
});
|
matchesTeamMemberIdentity(name, expected)
|
||||||
const runtimeAlive =
|
);
|
||||||
liveAgentNames.has(expected) ||
|
|
||||||
matchedRuntimeNames.some((runtimeName) => liveAgentNames.has(runtimeName));
|
|
||||||
const heartbeatMessage = leadInboxMessages.find((message) => {
|
const heartbeatMessage = leadInboxMessages.find((message) => {
|
||||||
if (typeof message.from !== 'string' || message.from.trim() !== expected) return false;
|
if (typeof message.from !== 'string' || message.from.trim() !== expected) return false;
|
||||||
if (
|
if (
|
||||||
|
|
@ -12705,9 +12703,9 @@ export class TeamProvisioningService {
|
||||||
current.sources = {
|
current.sources = {
|
||||||
...(current.sources ?? {}),
|
...(current.sources ?? {}),
|
||||||
processAlive: runtimeAlive || undefined,
|
processAlive: runtimeAlive || undefined,
|
||||||
configRegistered: matchedRuntimeNames.length > 0 || undefined,
|
configRegistered: matchedConfigNames.length > 0 || undefined,
|
||||||
configDrift:
|
configDrift:
|
||||||
heartbeatMessage != null && matchedRuntimeNames.length === 0
|
heartbeatMessage != null && matchedConfigNames.length === 0
|
||||||
? true
|
? true
|
||||||
: current.sources?.configDrift,
|
: current.sources?.configDrift,
|
||||||
inboxHeartbeat: heartbeatMessage != null ? true : current.sources?.inboxHeartbeat,
|
inboxHeartbeat: heartbeatMessage != null ? true : current.sources?.inboxHeartbeat,
|
||||||
|
|
|
||||||
|
|
@ -5802,6 +5802,34 @@ describe('TeamProvisioningService', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('treats suffixed live runtime names as alive during persisted launch reconcile', async () => {
|
||||||
|
const teamName = 'suffixed-live-runtime-team';
|
||||||
|
const leadSessionId = 'lead-session';
|
||||||
|
writeLaunchConfig(teamName, '/Users/test/proj', leadSessionId, ['alice']);
|
||||||
|
writeLaunchState(teamName, leadSessionId, {
|
||||||
|
alice: {
|
||||||
|
launchState: 'runtime_pending_bootstrap',
|
||||||
|
agentToolAccepted: true,
|
||||||
|
runtimeAlive: false,
|
||||||
|
bootstrapConfirmed: false,
|
||||||
|
hardFailure: false,
|
||||||
|
hardFailureReason: undefined,
|
||||||
|
firstSpawnAcceptedAt: new Date(Date.now() - 5_000).toISOString(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const svc = new TeamProvisioningService();
|
||||||
|
(svc as any).getLiveTeamAgentNames = vi.fn(async () => new Set(['alice-2']));
|
||||||
|
|
||||||
|
const result = await svc.getMemberSpawnStatuses(teamName);
|
||||||
|
|
||||||
|
expect(result.statuses.alice).toMatchObject({
|
||||||
|
status: 'online',
|
||||||
|
launchState: 'runtime_pending_bootstrap',
|
||||||
|
runtimeAlive: true,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it('returns persisted expectedMembers as the union of expected and materialized launch members', async () => {
|
it('returns persisted expectedMembers as the union of expected and materialized launch members', async () => {
|
||||||
const teamName = 'persisted-union-member-spawn-team';
|
const teamName = 'persisted-union-member-spawn-team';
|
||||||
const teamDir = path.join(tempTeamsBase, teamName);
|
const teamDir = path.join(tempTeamsBase, teamName);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue