diff --git a/packages/transcript/src/history/groupTurns.ts b/packages/transcript/src/history/groupTurns.ts
index 8d283eda5..88fa56121 100644
--- a/packages/transcript/src/history/groupTurns.ts
+++ b/packages/transcript/src/history/groupTurns.ts
@@ -200,7 +200,7 @@ export function groupMessagesIntoSnapshot(
kind: 'text',
frameId: `${step.stepId}.f${step.frames.length + 1}`,
role: 'user',
- text: textOf(message),
+ text: notificationFrameText(textOf(message)),
...(taskId !== undefined ? { taskId } : {}),
});
syncTurnItem(items, current);
@@ -280,6 +280,29 @@ export function groupMessagesIntoSnapshot(
return { items, tasks: [], interactions: [], attachments, todos: [], prompts: [], meta: {} };
}
+function notificationFrameText(text: string): string {
+ if (!text.startsWith('');
+ const closingStart = text.lastIndexOf('');
+ if (openingEnd === -1 || closingStart <= openingEnd) return text;
+ const inner = text.slice(openingEnd + 1, closingStart);
+ const lines = inner.split('\n');
+ let title = '';
+ let lastHeaderIndex = -1;
+ for (let i = 0; i < lines.length; i++) {
+ const line = lines[i]!;
+ if (line.startsWith('Title: ')) {
+ title = line.slice('Title: '.length);
+ lastHeaderIndex = i;
+ } else if (line.startsWith('Severity: ')) {
+ lastHeaderIndex = i;
+ }
+ }
+ const body = lines.slice(lastHeaderIndex + 1).join('\n').trim();
+ if (title.length > 0 && body.length > 0) return `${title}\n${body}`;
+ return title.length > 0 ? title : body.length > 0 ? body : text;
+}
+
function opensOwnTurn(message: HistoryMessage): boolean {
const origin = message.origin as { kind?: unknown; name?: unknown } | undefined;
return (
diff --git a/packages/transcript/test/layers.test.ts b/packages/transcript/test/layers.test.ts
index 17a227f84..d7e8aed35 100644
--- a/packages/transcript/test/layers.test.ts
+++ b/packages/transcript/test/layers.test.ts
@@ -454,7 +454,10 @@ describe('groupMessagesIntoSnapshot (cold path)', () => {
},
{
role: 'user',
- content: [{ type: 'text', text: '' }],
+ content: [{
+ type: 'text',
+ text: '\nTitle: Background agent completed\nSeverity: info\ninspect done.\n',
+ }],
toolCalls: [],
origin: { kind: 'task', taskId: 'task-9' } as { kind: string },
},
@@ -481,6 +484,7 @@ describe('groupMessagesIntoSnapshot (cold path)', () => {
.flatMap((step) => step.frames)
.filter((f) => f.kind === 'text' && f.role === 'user');
expect(userFrames.map((f) => f.kind === 'text' && f.taskId)).toEqual(['task-9', 'task-8']);
+ expect(userFrames[0]).toMatchObject({ text: 'Background agent completed\ninspect done.' });
const assistantTexts = turn.steps
.flatMap((step) => step.frames)
.filter((f) => f.kind === 'text' && f.role === 'assistant')