( filePath: string, maxTokens: number = getDefaultFileReadingLimits().maxTokens, maxBytes?: number, )
| 1095 | * @returns Image data with appropriate compression applied |
| 1096 | */ |
| 1097 | export async function readImageWithTokenBudget( |
| 1098 | filePath: string, |
| 1099 | maxTokens: number = getDefaultFileReadingLimits().maxTokens, |
| 1100 | maxBytes?: number, |
| 1101 | ): Promise<ImageResult> { |
| 1102 | // Read file ONCE — capped to maxBytes to avoid OOM on huge files |
| 1103 | const imageBuffer = await getFsImplementation().readFileBytes( |
| 1104 | filePath, |
| 1105 | maxBytes, |
| 1106 | ) |
| 1107 | const originalSize = imageBuffer.length |
| 1108 | |
| 1109 | if (originalSize === 0) { |
| 1110 | throw new Error(`Image file is empty: ${filePath}`) |
| 1111 | } |
| 1112 | |
| 1113 | const detectedMediaType = detectImageFormatFromBuffer(imageBuffer) |
| 1114 | const detectedFormat = detectedMediaType.split('/')[1] || 'png' |
| 1115 | |
| 1116 | // Try standard resize |
| 1117 | let result: ImageResult |
| 1118 | try { |
| 1119 | const resized = await maybeResizeAndDownsampleImageBuffer( |
| 1120 | imageBuffer, |
| 1121 | originalSize, |
| 1122 | detectedFormat, |
| 1123 | ) |
| 1124 | result = createImageResponse( |
| 1125 | resized.buffer, |
| 1126 | resized.mediaType, |
| 1127 | originalSize, |
| 1128 | resized.dimensions, |
| 1129 | ) |
| 1130 | } catch (e) { |
| 1131 | if (e instanceof ImageResizeError) throw e |
| 1132 | logError(e) |
| 1133 | result = createImageResponse(imageBuffer, detectedFormat, originalSize) |
| 1134 | } |
| 1135 | |
| 1136 | // Check if it fits in token budget |
| 1137 | const estimatedTokens = Math.ceil(result.file.base64.length * 0.125) |
| 1138 | if (estimatedTokens > maxTokens) { |
| 1139 | // Aggressive compression from the SAME buffer (no re-read) |
| 1140 | try { |
| 1141 | const compressed = await compressImageBufferWithTokenLimit( |
| 1142 | imageBuffer, |
| 1143 | maxTokens, |
| 1144 | detectedMediaType, |
| 1145 | ) |
| 1146 | return { |
| 1147 | type: 'image', |
| 1148 | file: { |
| 1149 | base64: compressed.base64, |
| 1150 | type: compressed.mediaType, |
| 1151 | originalSize, |
| 1152 | }, |
| 1153 | } |
| 1154 | } catch (e) { |
no test coverage detected