Fix generating title from messages (#442)
This commit is contained in:
parent
2705d83d6c
commit
00b125378c
4 changed files with 103 additions and 77 deletions
|
|
@ -1,84 +1,11 @@
|
|||
import { CoreMessage, CoreToolMessage, Message, ToolInvocation } from "ai";
|
||||
import { CoreMessage } from "ai";
|
||||
import { notFound } from "next/navigation";
|
||||
|
||||
import { auth } from "@/app/(auth)/auth";
|
||||
import { Chat as PreviewChat } from "@/components/custom/chat";
|
||||
import { getChatById } from "@/db/queries";
|
||||
import { Chat } from "@/db/schema";
|
||||
import { generateUUID } from "@/lib/utils";
|
||||
|
||||
function addToolMessageToChat({
|
||||
toolMessage,
|
||||
messages,
|
||||
}: {
|
||||
toolMessage: CoreToolMessage;
|
||||
messages: Array<Message>;
|
||||
}): Array<Message> {
|
||||
return messages.map((message) => {
|
||||
if (message.toolInvocations) {
|
||||
return {
|
||||
...message,
|
||||
toolInvocations: message.toolInvocations.map((toolInvocation) => {
|
||||
const toolResult = toolMessage.content.find(
|
||||
(tool) => tool.toolCallId === toolInvocation.toolCallId,
|
||||
);
|
||||
|
||||
if (toolResult) {
|
||||
return {
|
||||
...toolInvocation,
|
||||
state: "result",
|
||||
result: toolResult.result,
|
||||
};
|
||||
}
|
||||
|
||||
return toolInvocation;
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
return message;
|
||||
});
|
||||
}
|
||||
|
||||
function convertToUIMessages(messages: Array<CoreMessage>): Array<Message> {
|
||||
return messages.reduce((chatMessages: Array<Message>, message) => {
|
||||
if (message.role === "tool") {
|
||||
return addToolMessageToChat({
|
||||
toolMessage: message as CoreToolMessage,
|
||||
messages: chatMessages,
|
||||
});
|
||||
}
|
||||
|
||||
let textContent = "";
|
||||
let 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,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
chatMessages.push({
|
||||
id: generateUUID(),
|
||||
role: message.role,
|
||||
content: textContent,
|
||||
toolInvocations,
|
||||
});
|
||||
|
||||
return chatMessages;
|
||||
}, []);
|
||||
}
|
||||
import { convertToUIMessages, generateUUID } from "@/lib/utils";
|
||||
|
||||
export default async function Page({ params }: { params: any }) {
|
||||
const { id } = params;
|
||||
|
|
|
|||
|
|
@ -103,6 +103,10 @@
|
|||
}
|
||||
|
||||
.skeleton {
|
||||
* {
|
||||
pointer-events: none !important;
|
||||
}
|
||||
|
||||
*[class^="text-"] {
|
||||
color: transparent;
|
||||
@apply rounded-md bg-foreground/20 select-none animate-pulse;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import { toast } from "sonner";
|
|||
import useSWR from "swr";
|
||||
|
||||
import { Chat } from "@/db/schema";
|
||||
import { fetcher } from "@/lib/utils";
|
||||
import { fetcher, getTitleFromChat } from "@/lib/utils";
|
||||
|
||||
import {
|
||||
InfoIcon,
|
||||
|
|
@ -183,7 +183,7 @@ export const History = ({ user }: { user: User | undefined }) => {
|
|||
href={`/chat/${chat.id}`}
|
||||
className="text-ellipsis overflow-hidden text-left py-2 pl-2 rounded-lg outline-zinc-900"
|
||||
>
|
||||
{chat.messages[0].content as string}
|
||||
{getTitleFromChat(chat)}
|
||||
</Link>
|
||||
</Button>
|
||||
|
||||
|
|
|
|||
95
lib/utils.ts
95
lib/utils.ts
|
|
@ -1,6 +1,15 @@
|
|||
import {
|
||||
CoreMessage,
|
||||
CoreToolMessage,
|
||||
generateId,
|
||||
Message,
|
||||
ToolInvocation,
|
||||
} from "ai";
|
||||
import { clsx, type ClassValue } from "clsx";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
import { Chat } from "@/db/schema";
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs));
|
||||
}
|
||||
|
|
@ -41,3 +50,89 @@ export function generateUUID(): string {
|
|||
return v.toString(16);
|
||||
});
|
||||
}
|
||||
|
||||
function addToolMessageToChat({
|
||||
toolMessage,
|
||||
messages,
|
||||
}: {
|
||||
toolMessage: CoreToolMessage;
|
||||
messages: Array<Message>;
|
||||
}): Array<Message> {
|
||||
return messages.map((message) => {
|
||||
if (message.toolInvocations) {
|
||||
return {
|
||||
...message,
|
||||
toolInvocations: message.toolInvocations.map((toolInvocation) => {
|
||||
const toolResult = toolMessage.content.find(
|
||||
(tool) => tool.toolCallId === toolInvocation.toolCallId,
|
||||
);
|
||||
|
||||
if (toolResult) {
|
||||
return {
|
||||
...toolInvocation,
|
||||
state: "result",
|
||||
result: toolResult.result,
|
||||
};
|
||||
}
|
||||
|
||||
return toolInvocation;
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
return message;
|
||||
});
|
||||
}
|
||||
|
||||
export function convertToUIMessages(
|
||||
messages: Array<CoreMessage>,
|
||||
): Array<Message> {
|
||||
return messages.reduce((chatMessages: Array<Message>, message) => {
|
||||
if (message.role === "tool") {
|
||||
return addToolMessageToChat({
|
||||
toolMessage: message as CoreToolMessage,
|
||||
messages: chatMessages,
|
||||
});
|
||||
}
|
||||
|
||||
let textContent = "";
|
||||
let 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,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
chatMessages.push({
|
||||
id: generateId(),
|
||||
role: message.role,
|
||||
content: textContent,
|
||||
toolInvocations,
|
||||
});
|
||||
|
||||
return chatMessages;
|
||||
}, []);
|
||||
}
|
||||
|
||||
export function getTitleFromChat(chat: Chat) {
|
||||
const messages = convertToUIMessages(chat.messages as Array<CoreMessage>);
|
||||
const firstMessage = messages[0];
|
||||
|
||||
if (!firstMessage) {
|
||||
return "Untitled";
|
||||
}
|
||||
|
||||
return firstMessage.content;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue