fix(team): hide review pickup escalation rows
This commit is contained in:
parent
fa829f92c8
commit
5d3ec8a8bd
5 changed files with 92 additions and 12 deletions
|
|
@ -287,29 +287,42 @@ function buildMemberWorkSyncReviewPickupEscalationText(input: {
|
|||
}): string {
|
||||
const taskLines = input.taskRefs.length
|
||||
? input.taskRefs
|
||||
.map(
|
||||
(taskRef) => `- ${taskRef.displayId ?? taskRef.taskId.slice(0, 8)} (${taskRef.taskId})`
|
||||
)
|
||||
.map((taskRef) => `- ${taskRef.displayId ?? taskRef.taskId.slice(0, 8)}`)
|
||||
.join('\n')
|
||||
: '- No task refs recorded';
|
||||
const diagnostics = [...new Set(input.diagnostics ?? [])].filter(Boolean);
|
||||
const reasonText = describeMemberWorkSyncReviewPickupEscalationReason(input.reason);
|
||||
return [
|
||||
'Review pickup still pending in member work-sync.',
|
||||
'Review pickup needs lead attention.',
|
||||
'',
|
||||
`Reviewer: ${input.memberName}`,
|
||||
`Reason: ${input.reason}`,
|
||||
reasonText,
|
||||
'',
|
||||
'Tasks:',
|
||||
taskLines,
|
||||
'',
|
||||
'No review_start, review_approve, or review_request_changes was recorded for the current review request after the member correction path.',
|
||||
'No review_start, review_approve, or review_request_changes was recorded for the current review request.',
|
||||
'Consider reassigning the reviewer or sending a direct instruction.',
|
||||
diagnostics.length ? `Diagnostics: ${diagnostics.join(', ')}` : '',
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join('\n');
|
||||
}
|
||||
|
||||
function describeMemberWorkSyncReviewPickupEscalationReason(reason: string): string {
|
||||
if (reason.startsWith('provider_not_supported:')) {
|
||||
return 'Direct review-pickup wake is not available for this member runtime, so the lead needs to handle the stuck review.';
|
||||
}
|
||||
if (reason === 'review_pickup_already_delivered_still_stuck') {
|
||||
return 'A review-pickup reminder was delivered, but the review is still waiting for a review tool action.';
|
||||
}
|
||||
if (reason === 'review_pickup_delivery_failed_still_stuck') {
|
||||
return 'The review-pickup reminder could not be delivered reliably, and the review is still waiting.';
|
||||
}
|
||||
if (reason.includes('delivery_port_unavailable')) {
|
||||
return 'No reliable review-pickup delivery path is available for this member runtime.';
|
||||
}
|
||||
return 'The current review request is still waiting for explicit review pickup.';
|
||||
}
|
||||
|
||||
async function createOpenCodeRuntimeAdapterRegistry(
|
||||
reportProgress: (phase: string, message: string) => void = () => undefined
|
||||
): Promise<TeamRuntimeAdapterRegistry> {
|
||||
|
|
|
|||
|
|
@ -24,7 +24,10 @@ import { filterTeamMessages } from '@renderer/utils/teamMessageFiltering';
|
|||
import { toMessageKey } from '@renderer/utils/teamMessageKey';
|
||||
import { shouldExcludeInboxTextFromReplyCandidates } from '@shared/utils/idleNotificationSemantics';
|
||||
import { isLeadMember } from '@shared/utils/leadDetection';
|
||||
import { isTaskStallRemediationMessage } from '@shared/utils/teamAutomationMessages';
|
||||
import {
|
||||
isReviewPickupEscalationMessage,
|
||||
isTaskStallRemediationMessage,
|
||||
} from '@shared/utils/teamAutomationMessages';
|
||||
import {
|
||||
CheckCheck,
|
||||
ChevronsDownUp,
|
||||
|
|
@ -603,6 +606,7 @@ export const MessagesPanel = memo(function MessagesPanel({
|
|||
(m) =>
|
||||
m.messageKind !== 'task_comment_notification' &&
|
||||
!isTaskStallRemediationMessage(m) &&
|
||||
!isReviewPickupEscalationMessage(m) &&
|
||||
!shouldExcludeInboxTextFromReplyCandidates(typeof m.text === 'string' ? m.text : '')
|
||||
),
|
||||
[effectiveMessages]
|
||||
|
|
|
|||
|
|
@ -4,7 +4,10 @@ import {
|
|||
} from '@renderer/utils/bootstrapPromptSanitizer';
|
||||
import { shouldKeepIdleMessageInActivityWhenNoiseHidden } from '@renderer/utils/idleNotificationSemantics';
|
||||
import { isInboxNoiseMessage } from '@shared/utils/inboxNoise';
|
||||
import { isTaskStallRemediationMessage } from '@shared/utils/teamAutomationMessages';
|
||||
import {
|
||||
isReviewPickupEscalationMessage,
|
||||
isTaskStallRemediationMessage,
|
||||
} from '@shared/utils/teamAutomationMessages';
|
||||
import { isTeamInternalControlMessageEnvelope } from '@shared/utils/teamInternalControlMessages';
|
||||
|
||||
import type { InboxMessage } from '@shared/types';
|
||||
|
|
@ -133,6 +136,7 @@ export function filterTeamMessages(
|
|||
(m) =>
|
||||
m.messageKind !== 'task_comment_notification' &&
|
||||
(includeAutomationEvents || !isTaskStallRemediationMessage(m)) &&
|
||||
!isReviewPickupEscalationMessage(m) &&
|
||||
!isTeamInternalControlMessageEnvelope(m)
|
||||
);
|
||||
if (timeWindow) {
|
||||
|
|
|
|||
|
|
@ -2,15 +2,26 @@ import type { InboxMessage } from '@shared/types';
|
|||
|
||||
type AutomationMessageLike = Pick<InboxMessage, 'from' | 'messageId' | 'messageKind' | 'source'>;
|
||||
|
||||
function getMessageId(message: AutomationMessageLike): string {
|
||||
return typeof message.messageId === 'string' ? message.messageId.trim() : '';
|
||||
}
|
||||
|
||||
export function isTaskStallRemediationMessage(message: AutomationMessageLike): boolean {
|
||||
if (message.messageKind === 'task_stall_remediation') {
|
||||
return true;
|
||||
}
|
||||
|
||||
const messageId = typeof message.messageId === 'string' ? message.messageId.trim() : '';
|
||||
return (
|
||||
message.source === 'system_notification' &&
|
||||
message.from === 'system' &&
|
||||
messageId.startsWith('task-stall:')
|
||||
getMessageId(message).startsWith('task-stall:')
|
||||
);
|
||||
}
|
||||
|
||||
export function isReviewPickupEscalationMessage(message: AutomationMessageLike): boolean {
|
||||
return (
|
||||
message.source === 'system_notification' &&
|
||||
message.from === 'system' &&
|
||||
getMessageId(message).startsWith('member-work-sync-review-pickup-escalation:')
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -585,6 +585,31 @@ Messages:
|
|||
expect(result.map((message) => message.messageId)).toEqual(['msg-2']);
|
||||
});
|
||||
|
||||
it('hides review pickup escalation automation rows from conversational message counts by default', () => {
|
||||
const messages = [
|
||||
makeMessage({
|
||||
messageId: 'member-work-sync-review-pickup-escalation:abc123',
|
||||
from: 'system',
|
||||
to: 'lead',
|
||||
source: 'system_notification',
|
||||
summary: 'Review pickup still pending',
|
||||
text: 'Review pickup needs lead attention.\n\nReviewer: tom',
|
||||
}),
|
||||
makeMessage({
|
||||
messageId: 'msg-2',
|
||||
text: 'Visible message',
|
||||
}),
|
||||
];
|
||||
|
||||
const result = filterTeamMessages(messages, {
|
||||
timeWindow: null,
|
||||
filter: { from: new Set(), to: new Set(), showNoise: true },
|
||||
searchQuery: '',
|
||||
});
|
||||
|
||||
expect(result.map((message) => message.messageId)).toEqual(['msg-2']);
|
||||
});
|
||||
|
||||
it('can include task stall remediation automation rows for the activity timeline', () => {
|
||||
const messages = [
|
||||
makeMessage({
|
||||
|
|
@ -608,4 +633,27 @@ Messages:
|
|||
'task-stall:demo:task-a:legacy-epoch',
|
||||
]);
|
||||
});
|
||||
|
||||
it('keeps review pickup escalation hidden even when regular automation rows are included', () => {
|
||||
const messages = [
|
||||
makeMessage({
|
||||
messageId: 'member-work-sync-review-pickup-escalation:abc123',
|
||||
from: 'system',
|
||||
to: 'lead',
|
||||
source: 'system_notification',
|
||||
summary: 'Review pickup still pending',
|
||||
text: 'Review pickup needs lead attention.\n\nReviewer: tom',
|
||||
}),
|
||||
];
|
||||
|
||||
const result = filterTeamMessages(messages, {
|
||||
includeAutomationEvents: true,
|
||||
timeWindow: null,
|
||||
filter: { from: new Set(), to: new Set(), showNoise: true },
|
||||
searchQuery: '',
|
||||
});
|
||||
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue