From 7c36d456ea03c43f2ead5e6561dd9381e06f1b87 Mon Sep 17 00:00:00 2001 From: qer Date: Thu, 20 Aug 2026 01:01:08 +0800 Subject: [PATCH] fix(transcript): keep other tasks' notifications in task-origin turns --- .../src/services/transcript/coreEventMap.ts | 2 +- .../test/services/transcript.test.ts | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/packages/kap-server/src/services/transcript/coreEventMap.ts b/packages/kap-server/src/services/transcript/coreEventMap.ts index 322e0e3e7..2573227e2 100644 --- a/packages/kap-server/src/services/transcript/coreEventMap.ts +++ b/packages/kap-server/src/services/transcript/coreEventMap.ts @@ -896,7 +896,7 @@ export class AgentTranscriptProjector { }; return [{ op: 'frame.upsert', turnId: turn.turnId, stepId: step.stepId, frame }]; } - if (turn.origin?.kind === 'task') return []; + if (turn.origin?.kind === 'task' && (turn.origin.taskId === undefined || turn.origin.taskId === event.sourceId)) return []; this.pendingTaskNotifications.push({ text, taskId: event.sourceId }); return []; } diff --git a/packages/kap-server/test/services/transcript.test.ts b/packages/kap-server/test/services/transcript.test.ts index 230333dde..88730d439 100644 --- a/packages/kap-server/test/services/transcript.test.ts +++ b/packages/kap-server/test/services/transcript.test.ts @@ -1514,6 +1514,28 @@ describe('AgentTranscriptProjector', () => { expect(turnOps('t1', tx.getItems()).steps[0]!.frames).toHaveLength(0); }); + it('keeps a different task’s notification in a task-origin turn', () => { + const projector = new AgentTranscriptProjector('main'); + const tx = new AgentTranscript('main'); + const feed = (event: ProjectorBusEvent): void => void tx.apply(projector.map(event)); + + feed(ev({ type: 'turn.started', turnId: 1, origin: { kind: 'task', taskId: 'task_1' } })); + feed( + ev({ + type: 'task.notified', + notificationType: 'task.completed', + title: 'Background agent completed', + body: 'second task done.', + severity: 'info', + sourceKind: 'background_task', + sourceId: 'task_2', + }), + ); + feed(ev({ type: 'turn.step.started', turnId: 1, step: 1 })); + const frames = turnOps('t1', tx.getItems()).steps[0]!.frames; + expect(frames.map((f) => f.kind === 'text' && f.taskId)).toEqual(['task_2']); + }); + it('drops a buffered task notification when the turn ends before the next step', () => { const projector = new AgentTranscriptProjector('main'); const tx = new AgentTranscript('main');