Fix beta build: image check accepts Blob attachments (#131)
Unit Tests / test (push) Successful in 12s
Deploy Beta / unit-tests (push) Successful in 37s
Deploy Beta / deploy-beta (push) Failing after 3m49s

## Summary
- Closes #130.
- [Deploy Beta run 929](https://git.aimloperations.com/ai_ml_operations/chat_web_app/actions/runs/929) failed `npm run build:beta` with `TS2345`: `isImageFile` took a `File`, but the composer file is a `Blob`.
- The helper now accepts `Blob`. `URL.createObjectURL` already does. The `as File` casts are gone.
- Jest stayed green on that run because it does not typecheck this call. `tsc --noEmit` is clean on this branch.

## Test plan
- [ ] `npx tsc --noEmit` in `llm-fe`
- [ ] `npm run build:beta` (or the next Deploy Beta) compiles
- [ ] Image attach still shows a thumbnail and sends
- [ ] Document attach still shows the filename

Reviewed-on: #131
This commit was merged in pull request #131.
This commit is contained in:
westfarn committed 2026-10-20 08:07:39 -07:00
1 parent 89228719b5
commit ac165a2db4
3 files changed
+8 -7

No files matched your search

@@ -335,15 +335,15 @@ const AlwaysScrollToBottom = ({ trigger }: { trigger: string | number }): JSX.El
return <div ref={elementRef} />;
};
const AttachmentPreview = ({ file }: { file: File | null }): JSX.Element | null => {
const AttachmentPreview = ({ file }: { file: Blob | null }): JSX.Element | null => {
const theme = useContext(ThemeContext);
const [url, setUrl] = useState<string | null>(null);
useEffect(() => {
if (!isImageFile(file)) {
if (!file || !isImageFile(file)) {
setUrl(null);
return;
}
const next = URL.createObjectURL(file as File);
const next = URL.createObjectURL(file);
setUrl(next);
return () => URL.revokeObjectURL(next);
}, [file]);
@@ -370,7 +370,7 @@ const AttachmentPreview = ({ file }: { file: File | null }): JSX.Element | null
color: theme?.darkMode ? "rgba(255,255,255,0.6)" : "rgba(0,0,0,0.6)",
textAlign: "center",
}}>
Attached: {file.name}
Attached: {file instanceof File ? file.name : "attachment"}
</div>
);
};
@@ -473,7 +473,7 @@ const AsyncDashboardInner = (): JSX.Element => {
}
try {
clearActivity();
const attachedImage = isImageFile(file) ? URL.createObjectURL(file as File) : null;
const attachedImage = file && isImageFile(file) ? URL.createObjectURL(file) : null;
const tempConversations: ConversationPrompt[] = [
...conversationDetails,
new ConversationPrompt({
@@ -753,7 +753,7 @@ const AsyncDashboardInner = (): JSX.Element => {
</span>
</Tooltip>
</StyledInputContainer>
<AttachmentPreview file={formik.values.file as File | null} />
<AttachmentPreview file={formik.values.file} />
</Form>
)}
</Formik>
@@ -16,6 +16,7 @@ describe('visionAttachment', () => {
it('detects image files', () => {
expect(isImageFile(new File(['x'], 'a.png', { type: 'image/png' }))).toBe(true);
expect(isImageFile(new File(['x'], 'a.pdf', { type: 'application/pdf' }))).toBe(false);
expect(isImageFile(new Blob(['x'], { type: 'image/png' }))).toBe(true);
expect(isImageFile(null)).toBe(false);
});
});
+1 -1
View File
@@ -1,7 +1,7 @@
export const CHAT_FILE_ACCEPT =
'.csv,.xlsx,.txt,.pdf,.PDF,image/png,image/jpeg,image/webp,image/gif';
export function isImageFile(file: File | null | undefined): boolean {
export function isImageFile(file: Blob | null | undefined): boolean {
return Boolean(file && file.type.startsWith('image/'));
}