51 lines
1.4 KiB
TypeScript
51 lines
1.4 KiB
TypeScript
import type { ConversationMessage } from "./types";
|
|
|
|
export interface ConversationRow {
|
|
readonly attachments: readonly {
|
|
readonly filename: string | null;
|
|
readonly id: string;
|
|
readonly mediaType: string;
|
|
readonly url: string | null;
|
|
}[];
|
|
readonly error: string | null;
|
|
readonly messageId: string;
|
|
readonly rawText: string;
|
|
readonly role: "assistant" | "user";
|
|
readonly status: "completed" | "failed" | "processing" | "queued";
|
|
}
|
|
|
|
export const projectConversation = (rows: readonly ConversationRow[]) => ({
|
|
failedError: rows.findLast(
|
|
(row) => row.role === "assistant" && row.status === "failed"
|
|
)?.error,
|
|
messages: rows
|
|
.filter((row) => row.role === "user" || row.status === "completed")
|
|
.map<ConversationMessage>((row) => ({
|
|
id: row.messageId,
|
|
parts: [
|
|
...row.attachments.map((attachment) => ({
|
|
filename: attachment.filename ?? undefined,
|
|
id: attachment.id,
|
|
mediaType: attachment.mediaType,
|
|
type: "file" as const,
|
|
url: attachment.url ?? undefined,
|
|
})),
|
|
...(row.rawText
|
|
? [
|
|
{
|
|
state: "done" as const,
|
|
text: row.rawText,
|
|
type: "text" as const,
|
|
},
|
|
]
|
|
: []),
|
|
],
|
|
role: row.role,
|
|
})),
|
|
pending: rows.some(
|
|
(row) =>
|
|
row.role === "assistant" &&
|
|
(row.status === "queued" || row.status === "processing")
|
|
),
|
|
});
|