mirror of
https://github.com/MoonshotAI/kimi-code.git
synced 2026-08-24 08:06:38 +00:00
fix(transcript): fold mid-turn task notifications into the current turn on cold rebuild
This commit is contained in:
parent
30e7f62d2c
commit
d9459eaf79
2 changed files with 64 additions and 0 deletions
|
|
@ -151,9 +151,12 @@ export function groupMessagesIntoSnapshot(
|
|||
items.push(item);
|
||||
};
|
||||
|
||||
let prevRole: string | undefined;
|
||||
for (const message of messages) {
|
||||
if (message.role === 'system') continue;
|
||||
const originKind = message.origin?.kind;
|
||||
const prevRoleAtEntry = prevRole;
|
||||
prevRole = message.role;
|
||||
|
||||
if (message.role === 'user') {
|
||||
if (originKind !== undefined && HIDDEN_USER_ORIGINS.has(originKind)) {
|
||||
|
|
@ -171,6 +174,30 @@ export function groupMessagesIntoSnapshot(
|
|||
}
|
||||
continue;
|
||||
}
|
||||
if (originKind === 'task' || originKind === 'background_task' || originKind === 'task_notification') {
|
||||
if (prevRoleAtEntry !== 'assistant' && prevRoleAtEntry !== 'tool') {
|
||||
const opening = foldTurnOpeningInput(message);
|
||||
startTurn(mapOrigin(message), opening.text, opening.attachmentIds);
|
||||
continue;
|
||||
}
|
||||
const origin = message.origin as { taskId?: unknown } | undefined;
|
||||
const taskId = typeof origin?.taskId === 'string' ? origin.taskId : undefined;
|
||||
const current = ensureTurn(mapOrigin(message));
|
||||
let step = current.steps.at(-1);
|
||||
if (step === undefined) {
|
||||
step = { stepId: `${current.turnId}.1`, ordinal: 1, frames: [] };
|
||||
current.steps.push(step);
|
||||
}
|
||||
step.frames.push({
|
||||
kind: 'text',
|
||||
frameId: `${step.stepId}.f${step.frames.length + 1}`,
|
||||
role: 'user',
|
||||
text: textOf(message),
|
||||
...(taskId !== undefined ? { taskId } : {}),
|
||||
});
|
||||
syncTurnItem(items, current);
|
||||
continue;
|
||||
}
|
||||
const bundled = bundledSkillActivations(message);
|
||||
if (bundled.length > 0) {
|
||||
const parts = message.content ?? [];
|
||||
|
|
|
|||
|
|
@ -443,6 +443,43 @@ describe('groupMessagesIntoSnapshot (cold path)', () => {
|
|||
expect(marker?.kind === 'marker' && marker.marker).toBe('compaction');
|
||||
});
|
||||
|
||||
it('folds task-notification user messages into the current turn instead of opening their own', () => {
|
||||
const snapshot = groupMessagesIntoSnapshot([
|
||||
{ role: 'user', content: [{ type: 'text', text: 'run it' }], toolCalls: [], origin: { kind: 'user' } },
|
||||
{
|
||||
role: 'assistant',
|
||||
content: [{ type: 'text', text: 'starting' }],
|
||||
toolCalls: [{ id: 'c1', name: 'Bash', arguments: '{"command":"ls"}' }],
|
||||
},
|
||||
{
|
||||
role: 'user',
|
||||
content: [{ type: 'text', text: '<notification id="task:task-9:completed"></notification>' }],
|
||||
toolCalls: [],
|
||||
origin: { kind: 'task', taskId: 'task-9' } as { kind: string },
|
||||
},
|
||||
{
|
||||
role: 'assistant',
|
||||
content: [{ type: 'text', text: 'continuing' }],
|
||||
toolCalls: [],
|
||||
},
|
||||
]);
|
||||
|
||||
const turns = snapshot.items.filter((i) => i.kind === 'turn');
|
||||
expect(turns).toHaveLength(1);
|
||||
const turn = turns[0];
|
||||
if (turn?.kind !== 'turn') throw new Error('expected turn');
|
||||
const userFrames = turn.steps
|
||||
.flatMap((step) => step.frames)
|
||||
.filter((f) => f.kind === 'text' && f.role === 'user');
|
||||
expect(userFrames).toHaveLength(1);
|
||||
expect(userFrames[0]).toMatchObject({ taskId: 'task-9' });
|
||||
const assistantTexts = turn.steps
|
||||
.flatMap((step) => step.frames)
|
||||
.filter((f) => f.kind === 'text' && f.role === 'assistant')
|
||||
.map((f) => f.kind === 'text' && f.text);
|
||||
expect(assistantTexts).toEqual(['starting', 'continuing']);
|
||||
});
|
||||
|
||||
it('expands a bundled prompt into per-skill markers and a caller-text turn', () => {
|
||||
const snapshot = groupMessagesIntoSnapshot([
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue