refactor: replace message.content with message.parts (#868)
This commit is contained in:
parent
553a3d825a
commit
47a630fd53
25 changed files with 1311 additions and 311 deletions
96
lib/utils.ts
96
lib/utils.ts
|
|
@ -5,11 +5,12 @@ import type {
|
|||
TextStreamPart,
|
||||
ToolInvocation,
|
||||
ToolSet,
|
||||
UIMessage,
|
||||
} from 'ai';
|
||||
import { type ClassValue, clsx } from 'clsx';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
import type { Message as DBMessage, Document } from '@/lib/db/schema';
|
||||
import type { DBMessage, Document } from '@/lib/db/schema';
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs));
|
||||
|
|
@ -85,52 +86,6 @@ function addToolMessageToChat({
|
|||
});
|
||||
}
|
||||
|
||||
export function convertToUIMessages(
|
||||
messages: Array<DBMessage>,
|
||||
): Array<Message> {
|
||||
return messages.reduce((chatMessages: Array<Message>, message) => {
|
||||
if (message.role === 'tool') {
|
||||
return addToolMessageToChat({
|
||||
toolMessage: message as CoreToolMessage,
|
||||
messages: chatMessages,
|
||||
});
|
||||
}
|
||||
|
||||
let textContent = '';
|
||||
let reasoning: string | undefined = undefined;
|
||||
const toolInvocations: Array<ToolInvocation> = [];
|
||||
|
||||
if (typeof message.content === 'string') {
|
||||
textContent = message.content;
|
||||
} else if (Array.isArray(message.content)) {
|
||||
for (const content of message.content) {
|
||||
if (content.type === 'text') {
|
||||
textContent += content.text;
|
||||
} else if (content.type === 'tool-call') {
|
||||
toolInvocations.push({
|
||||
state: 'call',
|
||||
toolCallId: content.toolCallId,
|
||||
toolName: content.toolName,
|
||||
args: content.args,
|
||||
});
|
||||
} else if (content.type === 'reasoning') {
|
||||
reasoning = content.reasoning;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
chatMessages.push({
|
||||
id: message.id,
|
||||
role: message.role as Message['role'],
|
||||
content: textContent,
|
||||
reasoning,
|
||||
toolInvocations,
|
||||
});
|
||||
|
||||
return chatMessages;
|
||||
}, []);
|
||||
}
|
||||
|
||||
type ResponseMessageWithoutId = CoreToolMessage | CoreAssistantMessage;
|
||||
type ResponseMessage = ResponseMessageWithoutId & { id: string };
|
||||
|
||||
|
|
@ -182,40 +137,7 @@ export function sanitizeResponseMessages({
|
|||
);
|
||||
}
|
||||
|
||||
export function sanitizeUIMessages(messages: Array<Message>): Array<Message> {
|
||||
const messagesBySanitizedToolInvocations = messages.map((message) => {
|
||||
if (message.role !== 'assistant') return message;
|
||||
|
||||
if (!message.toolInvocations) return message;
|
||||
|
||||
const toolResultIds: Array<string> = [];
|
||||
|
||||
for (const toolInvocation of message.toolInvocations) {
|
||||
if (toolInvocation.state === 'result') {
|
||||
toolResultIds.push(toolInvocation.toolCallId);
|
||||
}
|
||||
}
|
||||
|
||||
const sanitizedToolInvocations = message.toolInvocations.filter(
|
||||
(toolInvocation) =>
|
||||
toolInvocation.state === 'result' ||
|
||||
toolResultIds.includes(toolInvocation.toolCallId),
|
||||
);
|
||||
|
||||
return {
|
||||
...message,
|
||||
toolInvocations: sanitizedToolInvocations,
|
||||
};
|
||||
});
|
||||
|
||||
return messagesBySanitizedToolInvocations.filter(
|
||||
(message) =>
|
||||
message.content.length > 0 ||
|
||||
(message.toolInvocations && message.toolInvocations.length > 0),
|
||||
);
|
||||
}
|
||||
|
||||
export function getMostRecentUserMessage(messages: Array<Message>) {
|
||||
export function getMostRecentUserMessage(messages: Array<UIMessage>) {
|
||||
const userMessages = messages.filter((message) => message.role === 'user');
|
||||
return userMessages.at(-1);
|
||||
}
|
||||
|
|
@ -229,3 +151,15 @@ export function getDocumentTimestampByIndex(
|
|||
|
||||
return documents[index].createdAt;
|
||||
}
|
||||
|
||||
export function getTrailingMessageId({
|
||||
messages,
|
||||
}: {
|
||||
messages: Array<ResponseMessage>;
|
||||
}): string | null {
|
||||
const trailingMessage = messages.at(-1);
|
||||
|
||||
if (!trailingMessage) return null;
|
||||
|
||||
return trailingMessage.id;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue