97 lines
2.9 KiB
TypeScript
97 lines
2.9 KiB
TypeScript
import { decodeHtmlEntities } from "../../lib/markdown"
|
|
import { partHasRenderableText } from "../../types/message"
|
|
import type { MessageDisplayParts, Message } from "../../types/message"
|
|
|
|
function decodeTextSegment(segment: any): any {
|
|
if (typeof segment === "string") {
|
|
return decodeHtmlEntities(segment)
|
|
}
|
|
|
|
if (segment && typeof segment === "object") {
|
|
const updated: Record<string, any> = { ...segment }
|
|
|
|
if (typeof updated.text === "string") {
|
|
updated.text = decodeHtmlEntities(updated.text)
|
|
}
|
|
|
|
if (typeof updated.value === "string") {
|
|
updated.value = decodeHtmlEntities(updated.value)
|
|
}
|
|
|
|
if (Array.isArray(updated.content)) {
|
|
updated.content = updated.content.map((item: any) => decodeTextSegment(item))
|
|
}
|
|
|
|
return updated
|
|
}
|
|
|
|
return segment
|
|
}
|
|
|
|
export function normalizeMessagePart(part: any): any {
|
|
if (!part || typeof part !== "object") {
|
|
return part
|
|
}
|
|
|
|
if (part.type !== "text") {
|
|
return part
|
|
}
|
|
|
|
const normalized: Record<string, any> = { ...part, renderCache: undefined }
|
|
|
|
if (typeof normalized.text === "string") {
|
|
normalized.text = decodeHtmlEntities(normalized.text)
|
|
} else if (normalized.text && typeof normalized.text === "object") {
|
|
const textObject: Record<string, any> = { ...normalized.text }
|
|
|
|
if (typeof textObject.value === "string") {
|
|
textObject.value = decodeHtmlEntities(textObject.value)
|
|
}
|
|
|
|
if (Array.isArray(textObject.content)) {
|
|
textObject.content = textObject.content.map((item: any) => decodeTextSegment(item))
|
|
}
|
|
|
|
if (typeof textObject.text === "string") {
|
|
textObject.text = decodeHtmlEntities(textObject.text)
|
|
}
|
|
|
|
normalized.text = textObject
|
|
}
|
|
|
|
if (Array.isArray(normalized.content)) {
|
|
normalized.content = normalized.content.map((item: any) => decodeTextSegment(item))
|
|
}
|
|
|
|
if (normalized.thinking && typeof normalized.thinking === "object") {
|
|
const thinking: Record<string, any> = { ...normalized.thinking }
|
|
if (Array.isArray(thinking.content)) {
|
|
thinking.content = thinking.content.map((item: any) => decodeTextSegment(item))
|
|
}
|
|
normalized.thinking = thinking
|
|
}
|
|
|
|
return normalized
|
|
}
|
|
|
|
export function computeDisplayParts(message: Message, showThinking: boolean): MessageDisplayParts {
|
|
const text: any[] = []
|
|
const tool: any[] = []
|
|
const reasoning: any[] = []
|
|
|
|
for (const part of message.parts) {
|
|
if (part.type === "text" && !part.synthetic && partHasRenderableText(part)) {
|
|
text.push(part)
|
|
} else if (part.type === "tool") {
|
|
tool.push(part)
|
|
} else if (part.type === "reasoning" && showThinking && partHasRenderableText(part)) {
|
|
reasoning.push(part)
|
|
}
|
|
}
|
|
|
|
const combined = reasoning.length > 0 ? [...text, ...reasoning] : [...text]
|
|
const version = typeof message.version === "number" ? message.version : 0
|
|
|
|
return { text, tool, reasoning, combined, showThinking, version }
|
|
}
|