fix: hide duplicate opencode runtime replies

This commit is contained in:
777genius 2026-04-26 21:52:24 +03:00
parent dc3eae1555
commit b26f0b05ba
2 changed files with 81 additions and 0 deletions

View file

@ -90,6 +90,22 @@ function isRelayDuplicateOfVisibleMessage(
return normalizeMessageText(message.text) === normalizeMessageText(original.text);
}
function getRuntimeDeliveryRelayDuplicateKey(
message: InboxMessage,
relayOfMessageId: string
): string | null {
if (message.source !== 'runtime_delivery') {
return null;
}
const from = normalizeParticipant(message.from);
const to = normalizeParticipant(message.to);
const text = normalizeMessageText(message.text);
if (!from || !to || !text) {
return null;
}
return [relayOfMessageId, from, to, text].join('\0');
}
export function filterTeamMessages(
messages: InboxMessage[],
options: {
@ -163,6 +179,8 @@ export function filterTeamMessages(
.filter((entry): entry is readonly [string, InboxMessage] => entry !== null)
);
const seenRuntimeDeliveryRelayDuplicates = new Set<string>();
return list.filter((m) => {
const relayOfMessageId =
typeof m.relayOfMessageId === 'string' ? m.relayOfMessageId.trim() : '';
@ -173,6 +191,13 @@ export function filterTeamMessages(
if (relayOfMessageId === ownMessageId) {
return true;
}
const runtimeDuplicateKey = getRuntimeDeliveryRelayDuplicateKey(m, relayOfMessageId);
if (runtimeDuplicateKey) {
if (seenRuntimeDeliveryRelayDuplicates.has(runtimeDuplicateKey)) {
return false;
}
seenRuntimeDeliveryRelayDuplicates.add(runtimeDuplicateKey);
}
return !isRelayDuplicateOfVisibleMessage(
m,
visibleMessagesById.get(relayOfMessageId),

View file

@ -175,6 +175,62 @@ describe('filterTeamMessages', () => {
expect(result.map((message) => message.messageId)).toEqual(['reply-1', 'reply-2']);
});
it('hides exact duplicate OpenCode replies for the same delivered app message', () => {
const messages = [
makeMessage({
messageId: 'user-request-1',
from: 'user',
to: 'team-lead',
source: 'user_sent',
text: 'Ask everyone to message me.',
}),
makeMessage({
messageId: 'delivery-1',
from: 'team-lead',
to: 'bob',
source: 'runtime_delivery',
text: 'Please message the user directly.',
relayOfMessageId: 'user-request-1',
}),
makeMessage({
messageId: 'reply-1',
from: 'bob',
to: 'user',
source: 'runtime_delivery',
text: 'Привет! Я готов к работе.',
relayOfMessageId: 'delivery-1',
}),
makeMessage({
messageId: 'reply-2',
from: 'bob',
to: 'user',
source: 'runtime_delivery',
text: ' Привет! Я готов к работе. ',
relayOfMessageId: 'delivery-1',
}),
makeMessage({
messageId: 'reply-3',
from: 'bob',
to: 'user',
source: 'runtime_delivery',
text: 'Дополнительный контекст после проверки.',
relayOfMessageId: 'delivery-1',
}),
];
const result = filterTeamMessages(messages, {
timeWindow: null,
filter: { from: new Set(), to: new Set(), showNoise: true },
searchQuery: '',
});
expect(result.map((message) => message.messageId)).toEqual([
'user-request-1',
'reply-1',
'reply-3',
]);
});
it('hides internal lead relay deliveries while keeping member replies', () => {
const messages = [
makeMessage({