| 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 |