继续重构会话消息处理逻辑

This commit is contained in:
xintaofei
2026-03-12 18:34:34 +08:00
parent 4e49e2f16a
commit bd5456423f
9 changed files with 452 additions and 779 deletions

View File

@@ -746,85 +746,3 @@ export function adaptMessageTurns(
adaptMessageTurn(turn, text, streamingIndices?.has(i) ?? false)
)
}
/**
* A visual message group that merges consecutive assistant/tool turns
* into a single block, split only by user or system messages.
*/
export interface MessageGroup {
id: string
role: "user" | "assistant" | "system"
parts: AdaptedContentPart[]
userResources?: UserResourceDisplay[]
userImages?: UserImageDisplay[]
usage?: TurnUsage | null
duration_ms?: number | null
model?: string | null
models?: string[]
}
function mergeUsage(
a: TurnUsage | null | undefined,
b: TurnUsage | null | undefined
): TurnUsage | null {
if (!a && !b) return null
if (!a) return b!
if (!b) return a
return {
input_tokens: a.input_tokens + b.input_tokens,
output_tokens: a.output_tokens + b.output_tokens,
cache_creation_input_tokens:
a.cache_creation_input_tokens + b.cache_creation_input_tokens,
cache_read_input_tokens:
a.cache_read_input_tokens + b.cache_read_input_tokens,
}
}
/**
* Group adapted messages so that consecutive assistant/tool messages
* are merged into one visual block, matching Claude Code terminal UX.
*/
export function groupAdaptedMessages(
messages: AdaptedMessage[]
): MessageGroup[] {
const groups: MessageGroup[] = []
let currentGroup: MessageGroup | null = null
for (const msg of messages) {
const effectiveRole = msg.role === "tool" ? "assistant" : msg.role
if (effectiveRole === "user" || effectiveRole === "system") {
currentGroup = null
groups.push({
id: msg.id,
role: effectiveRole,
parts: [...msg.content],
userResources: msg.userResources,
userImages: msg.userImages,
})
} else {
if (currentGroup && currentGroup.role === "assistant") {
currentGroup.parts.push(...msg.content)
currentGroup.usage = mergeUsage(currentGroup.usage, msg.usage)
currentGroup.duration_ms =
(currentGroup.duration_ms ?? 0) + (msg.duration_ms ?? 0)
if (msg.model && !currentGroup.models?.includes(msg.model)) {
currentGroup.models = [...(currentGroup.models ?? []), msg.model]
}
} else {
currentGroup = {
id: msg.id,
role: "assistant",
parts: [...msg.content],
usage: msg.usage,
duration_ms: msg.duration_ms,
model: msg.model,
models: msg.model ? [msg.model] : [],
}
groups.push(currentGroup)
}
}
}
return groups
}

View File

@@ -80,13 +80,6 @@ export type ContentBlock =
}
| { type: "thinking"; text: string }
export interface UnifiedMessage {
id: string
role: MessageRole
content: ContentBlock[]
timestamp: string
}
export type TurnRole = "user" | "assistant" | "system"
export interface TurnUsage {