返回 presentation-ai
attachments.ts
根目录 / src / lib / notebook / attachments.ts
1 export type NotebookAttachment = {
2 fileAssetId?: string;
3 name: string;
4 mimeType?: string;
5 processingStatus?: string | null;
6 ragId?: string | null;
7 url: string;
8 };
9
10 export type NotebookAttachmentWithRagId = NotebookAttachment & {
11 ragId?: string | null;
12 };
13
14 export type NotebookSelectedChunk = {
15 chunkId: string;
16 ragId: string;
17 slideNumber?: number | null;
18 content?: string;
19 };
20
21 export function getNotebookAttachmentId(
22 attachment: NotebookAttachment,
23 ): string {
24 return attachment.fileAssetId ?? attachment.url;
25 }
26
27 export function getNotebookAttachmentSignature(
28 attachments: NotebookAttachment[],
29 ): string {
30 return attachments.map(getNotebookAttachmentId).join(",");
31 }
32
33 export function getNotebookAttachmentRagId({
34 attachment,
35 attachments,
36 extractorRagIds,
37 index,
38 }: {
39 attachment: NotebookAttachmentWithRagId;
40 attachments: NotebookAttachmentWithRagId[];
41 extractorRagIds: string[];
42 index: number;
43 }): string | null {
44 if (attachment.ragId) {
45 return attachment.ragId;
46 }
47
48 if (extractorRagIds.length === attachments.length) {
49 return extractorRagIds[index] ?? null;
50 }
51
52 return null;
53 }
54
55 export function mergeNotebookAttachments(
56 attachments: NotebookAttachment[],
57 ): NotebookAttachment[] {
58 const attachmentsById = new Map<string, NotebookAttachment>();
59
60 for (const attachment of attachments) {
61 attachmentsById.set(getNotebookAttachmentId(attachment), attachment);
62 }
63
64 return [...attachmentsById.values()];
65 }
66
67 export function getNotebookAttachmentContext(
68 attachments: NotebookAttachmentWithRagId[],
69 ): {
70 attachments: NotebookAttachment[];
71 ragIds: string[];
72 currentRagId: string | null;
73 } {
74 const normalizedAttachments = attachments.map(
75 ({ fileAssetId, name, mimeType, processingStatus, ragId, url }) => ({
76 fileAssetId,
77 name,
78 mimeType,
79 processingStatus,
80 ragId,
81 url,
82 }),
83 );
84 const ragIds = attachments.flatMap((attachment) =>
85 attachment.ragId ? [attachment.ragId] : [],
86 );
87
88 return {
89 attachments: mergeNotebookAttachments(normalizedAttachments),
90 ragIds,
91 currentRagId: ragIds[0] ?? null,
92 };
93 }
94
95 const IMAGE_EXTENSION_PATTERN =
96 /\.(avif|bmp|gif|heic|heif|jpe?g|png|svg|webp)(?:$|[?#])/i;
97 const _PDF_EXTENSION_PATTERN = /\.pdf(?:$|[?#])/i;
98
99 export function isNotebookImageAttachment(
100 attachment: NotebookAttachment,
101 ): boolean {
102 if (attachment.mimeType?.startsWith("image/")) {
103 return true;
104 }
105
106 if (IMAGE_EXTENSION_PATTERN.test(attachment.name)) {
107 return true;
108 }
109
110 return IMAGE_EXTENSION_PATTERN.test(attachment.url);
111 }
112
112 lines TYPESCRIPT