( imagePath: string, cwd: string, replacePlaceholder?: string, )
| 23 | * @param replacePlaceholder - If provided, replaces an existing placeholder entry instead of adding new |
| 24 | */ |
| 25 | export async function addPendingImageFromFile( |
| 26 | imagePath: string, |
| 27 | cwd: string, |
| 28 | replacePlaceholder?: string, |
| 29 | ): Promise<void> { |
| 30 | const filename = path.basename(imagePath) |
| 31 | |
| 32 | if (replacePlaceholder) { |
| 33 | // Replace existing placeholder with actual image info (still processing) |
| 34 | useChatStore.setState((state) => ({ |
| 35 | pendingAttachments: state.pendingAttachments.map((att) => |
| 36 | att.kind === 'image' && att.path === replacePlaceholder |
| 37 | ? { ...att, path: imagePath, filename } |
| 38 | : att |
| 39 | ), |
| 40 | })) |
| 41 | } else { |
| 42 | // Add to pending state immediately with processing status so user sees loading state |
| 43 | useChatStore.getState().addPendingImage({ |
| 44 | path: imagePath, |
| 45 | filename, |
| 46 | status: 'processing', |
| 47 | }) |
| 48 | } |
| 49 | |
| 50 | // Process the image in background |
| 51 | const result = await processImageFile(imagePath, cwd) |
| 52 | |
| 53 | // Update the pending image with processed data |
| 54 | useChatStore.setState((state) => ({ |
| 55 | pendingAttachments: state.pendingAttachments.map((att) => { |
| 56 | if (att.kind !== 'image' || att.path !== imagePath) return att |
| 57 | |
| 58 | if (result.success && result.imagePart) { |
| 59 | return { |
| 60 | ...att, |
| 61 | status: 'ready' as const, |
| 62 | size: result.imagePart.size, |
| 63 | width: result.imagePart.width, |
| 64 | height: result.imagePart.height, |
| 65 | note: result.wasCompressed ? 'compressed' : undefined, |
| 66 | processedImage: { |
| 67 | base64: result.imagePart.image, |
| 68 | mediaType: result.imagePart.mediaType, |
| 69 | }, |
| 70 | } |
| 71 | } |
| 72 | |
| 73 | return { |
| 74 | ...att, |
| 75 | status: 'error' as const, |
| 76 | note: result.error || 'failed', |
| 77 | } |
| 78 | }), |
| 79 | })) |
| 80 | |
| 81 | // Exit image mode after successfully processing an image |
| 82 | if (result.success) { |
no test coverage detected