fix(team): stop counting inbox noise as check-ins
This commit is contained in:
parent
a641d263c0
commit
3b0fe0bcbf
4 changed files with 41 additions and 3 deletions
|
|
@ -35,6 +35,7 @@ import { resolveLanguageName } from '@shared/utils/agentLanguage';
|
||||||
import { parseCliArgs } from '@shared/utils/cliArgsParser';
|
import { parseCliArgs } from '@shared/utils/cliArgsParser';
|
||||||
import {
|
import {
|
||||||
isInboxNoiseMessage,
|
isInboxNoiseMessage,
|
||||||
|
isMeaningfulBootstrapCheckInMessage,
|
||||||
type ParsedPermissionRequest,
|
type ParsedPermissionRequest,
|
||||||
parsePermissionRequest,
|
parsePermissionRequest,
|
||||||
} from '@shared/utils/inboxNoise';
|
} from '@shared/utils/inboxNoise';
|
||||||
|
|
@ -2593,7 +2594,10 @@ export class TeamProvisioningService {
|
||||||
// runtime produced a real post-spawn message, unlike writes to inboxes/<member>.json
|
// runtime produced a real post-spawn message, unlike writes to inboxes/<member>.json
|
||||||
// which may simply be user/lead messages addressed TO the teammate.
|
// which may simply be user/lead messages addressed TO the teammate.
|
||||||
const sameTeamBlocks = blocks.filter((block) => !parseCrossTeamPrefix(block.content));
|
const sameTeamBlocks = blocks.filter((block) => !parseCrossTeamPrefix(block.content));
|
||||||
for (const block of sameTeamBlocks) {
|
const meaningfulSameTeamBlocks = sameTeamBlocks.filter((block) =>
|
||||||
|
isMeaningfulBootstrapCheckInMessage(block.content)
|
||||||
|
);
|
||||||
|
for (const block of meaningfulSameTeamBlocks) {
|
||||||
this.setMemberSpawnStatus(run, block.teammateId, 'online', undefined, 'heartbeat');
|
this.setMemberSpawnStatus(run, block.teammateId, 'online', undefined, 'heartbeat');
|
||||||
}
|
}
|
||||||
for (const block of sameTeamBlocks) {
|
for (const block of sameTeamBlocks) {
|
||||||
|
|
@ -6491,7 +6495,12 @@ export class TeamProvisioningService {
|
||||||
matchedRuntimeNames.some((runtimeName) => liveAgentNames.has(runtimeName));
|
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 (typeof message.text !== 'string' || message.text.trim().length === 0) return false;
|
if (
|
||||||
|
typeof message.text !== 'string' ||
|
||||||
|
!isMeaningfulBootstrapCheckInMessage(message.text)
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
const firstAcceptedAt = current.firstSpawnAcceptedAt
|
const firstAcceptedAt = current.firstSpawnAcceptedAt
|
||||||
? Date.parse(current.firstSpawnAcceptedAt)
|
? Date.parse(current.firstSpawnAcceptedAt)
|
||||||
: NaN;
|
: NaN;
|
||||||
|
|
|
||||||
|
|
@ -180,7 +180,7 @@ export const TeamProvisioningBanner = ({
|
||||||
<ProvisioningProgressBlock
|
<ProvisioningProgressBlock
|
||||||
key={progress.runId}
|
key={progress.runId}
|
||||||
title="Launch details"
|
title="Launch details"
|
||||||
message={readyDetailMessage}
|
message={failedSpawnCount > 0 ? readyDetailMessage : null}
|
||||||
messageSeverity={readyDetailSeverity}
|
messageSeverity={readyDetailSeverity}
|
||||||
currentStepIndex={progressStepIndex >= 0 ? progressStepIndex : -1}
|
currentStepIndex={progressStepIndex >= 0 ? progressStepIndex : -1}
|
||||||
startedAt={progress.startedAt}
|
startedAt={progress.startedAt}
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,16 @@ export function isInboxNoiseMessage(text: string): boolean {
|
||||||
return !!type && INBOX_NOISE_SET.has(type);
|
return !!type && INBOX_NOISE_SET.has(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true when a teammate message is substantive enough to count as a real
|
||||||
|
* bootstrap/check-in signal. Internal coordination noise like idle/shutdown
|
||||||
|
* JSON should keep the runtime marked alive, but must not be treated as a
|
||||||
|
* teammate "checked in" signal in launch UX.
|
||||||
|
*/
|
||||||
|
export function isMeaningfulBootstrapCheckInMessage(text: string): boolean {
|
||||||
|
return text.trim().length > 0 && !isInboxNoiseMessage(text);
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Teammate permission request parsing
|
// Teammate permission request parsing
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import { describe, expect, it } from 'vitest';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
isInboxNoiseMessage,
|
isInboxNoiseMessage,
|
||||||
|
isMeaningfulBootstrapCheckInMessage,
|
||||||
isOnlyTeammateMessageBlocks,
|
isOnlyTeammateMessageBlocks,
|
||||||
isThoughtProtocolNoise,
|
isThoughtProtocolNoise,
|
||||||
stripTeammateMessageBlocks,
|
stripTeammateMessageBlocks,
|
||||||
|
|
@ -124,3 +125,21 @@ describe('isInboxNoiseMessage', () => {
|
||||||
expect(isInboxNoiseMessage('Hello world')).toBe(false);
|
expect(isInboxNoiseMessage('Hello world')).toBe(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('isMeaningfulBootstrapCheckInMessage', () => {
|
||||||
|
it('rejects idle_notification noise', () => {
|
||||||
|
expect(
|
||||||
|
isMeaningfulBootstrapCheckInMessage(
|
||||||
|
'{"type":"idle_notification","from":"alice","idleReason":"available"}'
|
||||||
|
)
|
||||||
|
).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('accepts normal plain-text teammate replies', () => {
|
||||||
|
expect(isMeaningfulBootstrapCheckInMessage('Я на месте и готов продолжать.')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('rejects blank text', () => {
|
||||||
|
expect(isMeaningfulBootstrapCheckInMessage(' ')).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue