Download packages/transcript/src/history/groupTurns.ts from SaylorTwift/kimi-code: direct link, hf CLI and curl.
- Browser
- Download file 21.6 kB
-
https://huggingface.co/SaylorTwift/kimi-code/resolve/main/packages/transcript/src/history/groupTurns.ts
- Command line
-
hf download hf://SaylorTwift/kimi-code/packages/transcript/src/history/groupTurns.ts
-
curl -L -o groupTurns.ts https://huggingface.co/SaylorTwift/kimi-code/resolve/main/packages/transcript/src/history/groupTurns.ts
21.6 kB
| import type { AgentTranscriptSnapshot } from '../ops/operation'; | |
| import type { TranscriptAttachment } from '../model/attachment'; | |
| import type { TranscriptFrame, TranscriptUserOrigin } from '../model/frame'; | |
| import type { TranscriptItem, TranscriptMarker } from '../model/item'; | |
| import type { TurnOrigin } from '../model/turn'; | |
| import { daemonFileRefFromPairingPart } from '../contract/mediaRef'; | |
| import { projectTranscriptUserOrigin, projectTranscriptUserTurnOrigin } from '../contract/origin'; | |
| export type HistoryMediaSource = | |
| | { readonly kind: 'url'; readonly url: string } | |
| | { readonly kind: 'base64'; readonly media_type: string; readonly data: string } | |
| | { readonly kind: 'file' | 'session_media'; readonly file_id: string }; | |
| export type HistoryContentPart = | |
| | { readonly type: 'text'; readonly text: string } | |
| | { readonly type: 'think'; readonly think: string; readonly hidden?: boolean } | |
| | { readonly type: 'image' | 'video' | 'audio'; readonly source: HistoryMediaSource; readonly name?: string } | |
| | { | |
| readonly type: 'file'; | |
| readonly file_id: string; | |
| readonly name: string; | |
| readonly media_type: string; | |
| readonly size: number; | |
| } | |
| | { readonly type: string }; | |
| export interface HistoryToolCall { | |
| readonly id: string; | |
| readonly name: string; | |
| readonly arguments: string | null; | |
| } | |
| export interface HistoryMessage { | |
| readonly id?: string; | |
| readonly role: string; | |
| readonly content?: readonly HistoryContentPart[]; | |
| readonly toolCalls?: readonly HistoryToolCall[]; | |
| readonly toolCallId?: string; | |
| readonly isError?: boolean; | |
| readonly origin?: { readonly kind: string }; | |
| } | |
| interface TurnDraft { | |
| turnId: string; | |
| ordinal: number; | |
| triggerPromptId?: string; | |
| origin: TurnOrigin; | |
| prompt?: string; | |
| attachmentIds?: string[]; | |
| steps: StepDraft[]; | |
| } | |
| interface StepDraft { | |
| stepId: string; | |
| ordinal: number; | |
| frames: TranscriptFrame[]; | |
| } | |
| const HIDDEN_USER_ORIGINS = new Set(['injection', 'system_trigger', 'retry']); | |
| const TURN_OPENING_SYSTEM_TRIGGERS = new Set(['goal_continuation', 'subagent']); | |
| const MARKER_USER_ORIGINS: Readonly<Record<string, string>> = { | |
| skill_activation: 'skill', | |
| plugin_command: 'skill', | |
| compaction_summary: 'compaction', | |
| }; | |
| const FALLBACK_ORIGIN: TurnOrigin = { kind: 'other' }; | |
| export function groupMessagesIntoSnapshot( | |
| messages: readonly HistoryMessage[], | |
| options?: { | |
| readonly taskOriginTurnTaskIds?: ReadonlySet<string>; | |
| readonly steeredContents?: ReadonlyMap<string, ReadonlyMap<string, number>>; | |
| }, | |
| ): AgentTranscriptSnapshot { | |
| const items: TranscriptItem[] = []; | |
| const attachments: TranscriptAttachment[] = []; | |
| const steeredContents = new Map( | |
| [...(options?.steeredContents ?? [])].map(([key, byKind]) => [key, new Map(byKind)]), | |
| ); | |
| let turn: TurnDraft | undefined; | |
| let pendingNotificationFrames: { | |
| text: string; | |
| taskId: string | undefined; | |
| attachmentIds?: string[]; | |
| promptIds?: readonly string[]; | |
| origin?: TranscriptUserOrigin; | |
| steered?: boolean; | |
| }[] = []; | |
| let nextOrdinal = 0; | |
| let markerCount = 0; | |
| const foldTurnOpeningInput = ( | |
| message: HistoryMessage, | |
| ): { text: string; attachmentIds?: string[] } => { | |
| const parts = message.content ?? []; | |
| const ids: string[] = []; | |
| const texts: string[] = []; | |
| for (const part of parts) { | |
| if (part.type === 'text' && 'text' in part && typeof part.text === 'string') { | |
| texts.push(part.text); | |
| continue; | |
| } | |
| if (part.type === 'image' || part.type === 'video' || part.type === 'audio') { | |
| if (!('source' in part) || part.source === undefined) continue; | |
| const source = part.source as HistoryMediaSource; | |
| const entity: TranscriptAttachment = { | |
| attachmentId: `att_${attachments.length + 1}`, | |
| mediaType: | |
| source.kind === 'base64' ? source.media_type : `${part.type}/*`, | |
| name: part.name, | |
| source: | |
| source.kind === 'url' | |
| ? { kind: 'url', url: source.url } | |
| : source.kind === 'file' || source.kind === 'session_media' | |
| ? { kind: source.kind, fileId: source.file_id } | |
| : undefined, | |
| }; | |
| attachments.push(entity); | |
| ids.push(entity.attachmentId); | |
| continue; | |
| } | |
| if (part.type === 'file' && 'file_id' in part) { | |
| const entity: TranscriptAttachment = { | |
| attachmentId: `att_${attachments.length + 1}`, | |
| mediaType: part.media_type as string, | |
| name: part.name as string, | |
| size: part.size as number, | |
| source: { kind: 'file', fileId: part.file_id as string }, | |
| }; | |
| attachments.push(entity); | |
| ids.push(entity.attachmentId); | |
| continue; | |
| } | |
| const ref = daemonFileRefFromPairingPart(part); | |
| if (ref !== undefined) { | |
| const entity: TranscriptAttachment = { | |
| attachmentId: `att_${attachments.length + 1}`, | |
| mediaType: `${ref.kind}/*`, | |
| name: ref.name, | |
| source: { kind: 'session_media', fileId: ref.ref.fileId }, | |
| }; | |
| attachments.push(entity); | |
| ids.push(entity.attachmentId); | |
| } | |
| } | |
| for (const attachment of originFileAttachments(message)) { | |
| const entity: TranscriptAttachment = { | |
| attachmentId: `att_${attachments.length + 1}`, | |
| mediaType: attachment.mediaType, | |
| name: attachment.name, | |
| size: attachment.size, | |
| }; | |
| attachments.push(entity); | |
| ids.push(entity.attachmentId); | |
| } | |
| return { text: texts.join(''), attachmentIds: ids.length > 0 ? ids : undefined }; | |
| }; | |
| const ensureTurn = (origin: TurnOrigin = FALLBACK_ORIGIN): TurnDraft => { | |
| if (!turn) { | |
| const ordinal = nextOrdinal; | |
| nextOrdinal += 1; | |
| turn = { turnId: `t${ordinal}`, ordinal, origin, steps: [] }; | |
| items.push(draftToTurnItem(turn)); | |
| } | |
| return turn; | |
| }; | |
| const flushSteeredLeftovers = (): void => { | |
| const leftovers = pendingNotificationFrames.filter((pending) => pending.steered); | |
| if (leftovers.length === 0) return; | |
| pendingNotificationFrames = pendingNotificationFrames.filter((pending) => !pending.steered); | |
| for (const pending of leftovers) { | |
| const targetTurn = turn ?? startTurn({ kind: 'user' }); | |
| let lastStep = targetTurn.steps.at(-1); | |
| if (lastStep === undefined) { | |
| const ordinal = targetTurn.steps.length + 1; | |
| lastStep = { | |
| stepId: `${targetTurn.turnId}.${ordinal}`, | |
| ordinal, | |
| frames: [], | |
| }; | |
| targetTurn.steps.push(lastStep); | |
| } | |
| lastStep.frames.push({ | |
| kind: 'text', | |
| frameId: `${lastStep.stepId}.f${lastStep.frames.length + 1}`, | |
| role: 'user', | |
| text: pending.text, | |
| attachmentIds: pending.attachmentIds, | |
| promptIds: pending.promptIds, | |
| origin: pending.origin, | |
| }); | |
| syncTurnItem(items, targetTurn); | |
| } | |
| }; | |
| const startTurn = ( | |
| origin: TurnOrigin, | |
| prompt?: string, | |
| attachmentIds?: string[], | |
| triggerPromptId?: string, | |
| ): TurnDraft => { | |
| flushSteeredLeftovers(); | |
| const ordinal = nextOrdinal; | |
| nextOrdinal += 1; | |
| pendingNotificationFrames = []; | |
| turn = { turnId: `t${ordinal}`, ordinal, triggerPromptId, origin, prompt, attachmentIds, steps: [] }; | |
| items.push(draftToTurnItem(turn)); | |
| return turn; | |
| }; | |
| const pushMarker = (marker: string, payload?: unknown): void => { | |
| markerCount += 1; | |
| const item: TranscriptMarker = { kind: 'marker', markerId: `m${markerCount}`, marker, payload }; | |
| items.push(item); | |
| }; | |
| let prevNonTaskRole: string | undefined; | |
| for (const message of messages) { | |
| if (message.role === 'system') continue; | |
| const originKind = message.origin?.kind; | |
| const isTaskOrigin = | |
| originKind === 'task' || originKind === 'background_task' || originKind === 'task_notification'; | |
| const prevRoleAtEntry = prevNonTaskRole; | |
| if (!isTaskOrigin) prevNonTaskRole = message.role; | |
| if (message.role === 'user') { | |
| if (originKind !== undefined && HIDDEN_USER_ORIGINS.has(originKind)) { | |
| if (opensOwnTurn(message)) { | |
| const opening = | |
| (message.origin as { name?: unknown }).name === 'subagent' | |
| ? foldTurnOpeningInput(message) | |
| : undefined; | |
| startTurn(mapOrigin(message), opening?.text || undefined, opening?.attachmentIds); | |
| } | |
| continue; | |
| } | |
| const markerKey = originKind !== undefined ? MARKER_USER_ORIGINS[originKind] : undefined; | |
| if (markerKey !== undefined && !isUserSlashPrompt(message)) { | |
| pushMarker(markerKey, { text: textOf(message), origin: message.origin }); | |
| continue; | |
| } | |
| const contentKey = JSON.stringify(message.content ?? []); | |
| const steerKind = originKind ?? 'user'; | |
| const steeredByKind = steeredContents.get(contentKey); | |
| const steeredRemaining = steeredByKind?.get(steerKind) ?? 0; | |
| if (steeredByKind !== undefined && steeredRemaining > 0) { | |
| steeredByKind.set(steerKind, steeredRemaining - 1); | |
| const bundled = bundledSkillActivations(message); | |
| const parts = message.content ?? []; | |
| bundled.forEach((activation, index) => { | |
| const block = parts[index]; | |
| pushMarker('skill', { | |
| text: block !== undefined && block.type === 'text' && 'text' in block ? block.text : '', | |
| origin: { kind: 'skill_activation', trigger: 'user-slash', ...activation }, | |
| }); | |
| }); | |
| const opening = foldTurnOpeningInput({ ...message, content: parts.slice(bundled.length) }); | |
| pendingNotificationFrames.push({ | |
| text: opening.text, | |
| taskId: undefined, | |
| attachmentIds: opening.attachmentIds, | |
| origin: projectTranscriptUserOrigin(message.origin), | |
| steered: true, | |
| }); | |
| continue; | |
| } | |
| if (markerKey !== undefined) { | |
| const opening = isUserSlashPrompt(message) ? foldTurnOpeningInput(message) : undefined; | |
| pushMarker(markerKey, { text: opening?.text ?? textOf(message), origin: message.origin }); | |
| if (opening !== undefined) { | |
| startTurn(mapOrigin(message), opening.text, opening.attachmentIds, triggerPromptIdOf(message)); | |
| } | |
| continue; | |
| } | |
| if (isTaskOrigin) { | |
| const origin = message.origin as { taskId?: unknown } | undefined; | |
| const taskId = typeof origin?.taskId === 'string' ? origin.taskId : undefined; | |
| const opensOwn = options?.taskOriginTurnTaskIds === undefined | |
| ? prevRoleAtEntry !== 'assistant' && prevRoleAtEntry !== 'tool' | |
| : taskId === undefined || | |
| options.taskOriginTurnTaskIds.has(taskId) || | |
| originKind === 'background_task'; | |
| if (opensOwn) { | |
| const opening = foldTurnOpeningInput(message); | |
| startTurn(mapOrigin(message), opening.text, opening.attachmentIds); | |
| continue; | |
| } | |
| pendingNotificationFrames.push({ text: notificationFrameText(textOf(message)), taskId }); | |
| continue; | |
| } | |
| const bundled = bundledSkillActivations(message); | |
| if (bundled.length > 0) { | |
| const parts = message.content ?? []; | |
| bundled.forEach((activation, index) => { | |
| const block = parts[index]; | |
| pushMarker('skill', { | |
| text: block !== undefined && block.type === 'text' && 'text' in block ? block.text : '', | |
| origin: { kind: 'skill_activation', trigger: 'user-slash', ...activation }, | |
| }); | |
| }); | |
| const callerMessage = { ...message, content: parts.slice(bundled.length) }; | |
| const opening = foldTurnOpeningInput(callerMessage); | |
| startTurn(mapOrigin(message), opening.text, opening.attachmentIds, triggerPromptIdOf(message)); | |
| continue; | |
| } | |
| const opening = foldTurnOpeningInput(message); | |
| startTurn(mapOrigin(message), opening.text, opening.attachmentIds, triggerPromptIdOf(message)); | |
| continue; | |
| } | |
| if (message.role === 'assistant') { | |
| const current = ensureTurn(); | |
| const stepOrdinal = current.steps.length + 1; | |
| const step: StepDraft = { | |
| stepId: `${current.turnId}.${stepOrdinal}`, | |
| ordinal: stepOrdinal, | |
| frames: [], | |
| }; | |
| current.steps.push(step); | |
| let frameCount = 0; | |
| const nextFrameId = (): string => { | |
| frameCount += 1; | |
| return `${step.stepId}.f${frameCount}`; | |
| }; | |
| for (const pending of pendingNotificationFrames) { | |
| step.frames.push({ | |
| kind: 'text', | |
| frameId: nextFrameId(), | |
| role: 'user', | |
| text: pending.text, | |
| taskId: pending.taskId, | |
| attachmentIds: pending.attachmentIds, | |
| promptIds: pending.promptIds, | |
| origin: pending.origin, | |
| }); | |
| } | |
| pendingNotificationFrames = []; | |
| for (const part of message.content ?? []) { | |
| if (part.type === 'text' && 'text' in part && typeof part.text === 'string' && part.text.length > 0) { | |
| step.frames.push({ kind: 'text', frameId: nextFrameId(), role: 'assistant', text: part.text }); | |
| } else if (part.type === 'think' && 'think' in part && typeof part.think === 'string' && part.think.length > 0 && part.hidden !== true) { | |
| step.frames.push({ kind: 'thinking', frameId: nextFrameId(), text: part.think }); | |
| } | |
| } | |
| for (const call of message.toolCalls ?? []) { | |
| step.frames.push({ | |
| kind: 'tool', | |
| frameId: `${step.stepId}.${call.id}`, | |
| toolCallId: call.id, | |
| name: call.name, | |
| state: 'running', | |
| input: parseArguments(call.arguments), | |
| }); | |
| } | |
| syncTurnItem(items, current); | |
| continue; | |
| } | |
| if (message.role === 'tool') { | |
| const frame = currentTurnToolFrame(turn, message.toolCallId); | |
| if (frame && frame.kind === 'tool') { | |
| const output = textOf(message); | |
| const patched: TranscriptFrame = { | |
| ...frame, | |
| state: message.isError ? 'error' : 'done', | |
| output, | |
| error: message.isError ? output : undefined, | |
| }; | |
| replaceToolFrame(turn!, message.toolCallId!, patched); | |
| syncTurnItem(items, turn!); | |
| } | |
| } | |
| } | |
| flushSteeredLeftovers(); | |
| return { items, tasks: [], interactions: [], attachments, todos: [], prompts: [], meta: {} }; | |
| } | |
| function notificationFrameText(text: string): string { | |
| if (!text.startsWith('<notification')) return text; | |
| const openingEnd = text.indexOf('>'); | |
| const closingStart = text.lastIndexOf('</notification>'); | |
| if (openingEnd === -1 || closingStart <= openingEnd) return text; | |
| const inner = text.slice(openingEnd + 1, closingStart); | |
| const lines = inner.split('\n'); | |
| let headerEnd = 0; | |
| while (headerEnd < lines.length && lines[headerEnd]!.trim() === '') headerEnd += 1; | |
| let title = ''; | |
| let bodyStart = headerEnd; | |
| const titleLine = lines[bodyStart]; | |
| if (titleLine !== undefined && titleLine.startsWith('Title: ')) { | |
| title = titleLine.slice('Title: '.length); | |
| bodyStart += 1; | |
| } | |
| const severityLine = lines[bodyStart]; | |
| if (severityLine !== undefined && severityLine.startsWith('Severity: ')) { | |
| bodyStart += 1; | |
| } | |
| const bodyLines = lines.slice(bodyStart); | |
| const childStart = bodyLines.findIndex((line) => { | |
| const trimmed = line.trimStart(); | |
| return ( | |
| trimmed.startsWith('<output-file') || | |
| trimmed.startsWith('<output-preview') || | |
| trimmed.startsWith('<answer') | |
| ); | |
| }); | |
| const body = (childStart === -1 ? bodyLines : bodyLines.slice(0, childStart)).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 ( | |
| origin?.kind === 'system_trigger' && | |
| typeof origin.name === 'string' && | |
| TURN_OPENING_SYSTEM_TRIGGERS.has(origin.name) | |
| ); | |
| } | |
| function isUserSlashPrompt(message: HistoryMessage): boolean { | |
| const origin = message.origin as { kind?: unknown; trigger?: unknown } | undefined; | |
| return ( | |
| (origin?.kind === 'skill_activation' || origin?.kind === 'plugin_command') && | |
| origin.trigger === 'user-slash' | |
| ); | |
| } | |
| function triggerPromptIdOf(message: HistoryMessage): string | undefined { | |
| if (typeof message.id !== 'string' || message.id.length === 0) return undefined; | |
| const origin = message.origin as { kind?: unknown; trigger?: unknown } | undefined; | |
| if (origin?.kind === undefined || origin.kind === 'user') return message.id; | |
| return ( | |
| (origin.kind === 'skill_activation' || origin.kind === 'plugin_command') && | |
| origin.trigger === 'user-slash' | |
| ) | |
| ? message.id | |
| : undefined; | |
| } | |
| function mapOrigin(message: HistoryMessage): TurnOrigin { | |
| const origin = message.origin; | |
| switch (origin?.kind) { | |
| case 'cron_job': | |
| case 'cron_missed': { | |
| const jobId = (origin as { jobId?: unknown }).jobId; | |
| return { kind: 'cron', taskId: typeof jobId === 'string' ? jobId : undefined, payload: origin }; | |
| } | |
| case 'task': | |
| case 'background_task': { | |
| const taskId = (origin as { taskId?: unknown }).taskId; | |
| return taskId !== undefined && typeof taskId === 'string' | |
| ? { kind: 'task', taskId, payload: origin } | |
| : { kind: 'other', payload: origin }; | |
| } | |
| case 'hook_result': | |
| return { kind: 'hook', payload: origin }; | |
| case 'shell_command': | |
| return { kind: 'user', payload: origin }; | |
| case 'user': | |
| return projectTranscriptUserTurnOrigin(origin); | |
| case undefined: | |
| return { kind: 'user' }; | |
| default: | |
| return { kind: 'other', payload: origin }; | |
| } | |
| } | |
| interface BundledSkillActivation { | |
| readonly activationId: string; | |
| readonly skillName: string; | |
| readonly skillArgs?: string; | |
| readonly skillType?: string; | |
| readonly skillPath?: string; | |
| readonly skillSource?: string; | |
| } | |
| function bundledSkillActivations(message: HistoryMessage): readonly BundledSkillActivation[] { | |
| if (message.origin?.kind !== 'user') return []; | |
| const activations = (message.origin as { readonly skillActivations?: unknown }).skillActivations; | |
| if (!Array.isArray(activations)) return []; | |
| return activations.filter( | |
| (activation): activation is BundledSkillActivation => | |
| typeof activation === 'object' && | |
| activation !== null && | |
| typeof (activation as { activationId?: unknown }).activationId === 'string' && | |
| typeof (activation as { skillName?: unknown }).skillName === 'string', | |
| ); | |
| } | |
| interface OriginFileAttachment { | |
| readonly name: string; | |
| readonly mediaType: string; | |
| readonly size: number; | |
| readonly path: string; | |
| } | |
| function originFileAttachments(message: HistoryMessage): readonly OriginFileAttachment[] { | |
| if (message.origin?.kind !== 'user' && message.origin?.kind !== 'skill_activation') return []; | |
| const attachments = (message.origin as { readonly attachments?: unknown }).attachments; | |
| if (!Array.isArray(attachments)) return []; | |
| return attachments.filter( | |
| (attachment): attachment is OriginFileAttachment => | |
| typeof attachment === 'object' && | |
| attachment !== null && | |
| typeof (attachment as { name?: unknown }).name === 'string' && | |
| typeof (attachment as { mediaType?: unknown }).mediaType === 'string' && | |
| typeof (attachment as { size?: unknown }).size === 'number' && | |
| typeof (attachment as { path?: unknown }).path === 'string', | |
| ); | |
| } | |
| function textOf(message: HistoryMessage): string { | |
| return (message.content ?? []) | |
| .filter((part): part is { readonly type: 'text'; readonly text: string } => part.type === 'text' && 'text' in part) | |
| .map((part) => part.text) | |
| .join(''); | |
| } | |
| function parseArguments(raw: string | null): unknown { | |
| if (!raw) return undefined; | |
| try { | |
| return JSON.parse(raw) as unknown; | |
| } catch { | |
| return raw; | |
| } | |
| } | |
| function draftToTurnItem(draft: TurnDraft): TranscriptItem { | |
| return { | |
| kind: 'turn', | |
| turnId: draft.turnId, | |
| triggerPromptId: draft.triggerPromptId, | |
| ordinal: draft.ordinal, | |
| state: 'completed', | |
| origin: draft.origin, | |
| prompt: draft.prompt, | |
| attachmentIds: draft.attachmentIds, | |
| steps: draft.steps.map((step) => ({ | |
| kind: 'step' as const, | |
| stepId: step.stepId, | |
| turnId: draft.turnId, | |
| ordinal: step.ordinal, | |
| state: 'completed' as const, | |
| frames: step.frames, | |
| })), | |
| }; | |
| } | |
| function syncTurnItem(items: TranscriptItem[], draft: TurnDraft): void { | |
| const index = items.findIndex((entry) => entry.kind === 'turn' && entry.turnId === draft.turnId); | |
| if (index >= 0) items[index] = draftToTurnItem(draft); | |
| } | |
| function currentTurnToolFrame(turn: TurnDraft | undefined, toolCallId: string | undefined): TranscriptFrame | undefined { | |
| if (!turn || toolCallId === undefined) return undefined; | |
| for (let s = turn.steps.length - 1; s >= 0; s -= 1) { | |
| const frames = turn.steps[s]?.frames ?? []; | |
| for (let f = frames.length - 1; f >= 0; f -= 1) { | |
| const frame = frames[f]; | |
| if (frame?.kind === 'tool' && frame.toolCallId === toolCallId) return frame; | |
| } | |
| } | |
| return undefined; | |
| } | |
| function replaceToolFrame(turn: TurnDraft, toolCallId: string, next: TranscriptFrame): void { | |
| for (let s = turn.steps.length - 1; s >= 0; s -= 1) { | |
| const step = turn.steps[s]; | |
| if (!step) continue; | |
| const index = step.frames.findIndex((frame) => frame.kind === 'tool' && frame.toolCallId === toolCallId); | |
| if (index >= 0) { | |
| step.frames[index] = next; | |
| return; | |
| } | |
| } | |
| } | |