Skip to content

Commit f17c4c5

Browse files
authored
feat(opentrons-ai-server,-opentrons-ai-client): backend attach file (#18994)
# Overview Closes AUTH-2019 PR implements backend support for Attach file. Current Flow: 1. User selects files → handleFileSelect() 2. When sending message → readFileContent() reads file locally 3. File content is embedded in fileAttachments array 4. Sent directly in the chat request body **Attach** <img width="1108" height="202" alt="image" src="https://github.com/user-attachments/assets/20119f7e-74fc-42da-956b-e212eae5bfd4" /> **Send** <img width="1147" height="900" alt="image" src="https://github.com/user-attachments/assets/d35a8b87-cdad-4850-a2bd-0f54ada6f039" /> ## Test Plan and Hands on Testing CI ## Review requests Attach a Python, CSV, or PDF and ask some questions. ## Risk assessment Mid
1 parent e4fa84f commit f17c4c5

File tree

17 files changed

+1435
-546
lines changed

17 files changed

+1435
-546
lines changed

opentrons-ai-client/src/atoms/AttachedFileItem/index.tsx

Lines changed: 20 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,18 @@
11
import { COLORS, Icon } from '@opentrons/components'
22

3-
import { getFileType } from '/ai-client/resources/utils/fileUtils'
3+
import {
4+
getFileExtension,
5+
getFileType,
6+
} from '/ai-client/resources/utils/fileUtils'
47

58
import styles from './attachedfileitem.module.css'
69

710
interface AttachedFileItemProps {
8-
file: {
9-
name: string
10-
size?: number
11-
}
11+
file: File | { name: string; type?: string }
1212
onRemove?: () => void
1313
showRemoveButton?: boolean
1414
}
1515

16-
// Helper to get simple file type labels
17-
const getSimpleFileTypeLabel = (type: string, fileName: string): string => {
18-
// Check for Python files first
19-
if (fileName.toLowerCase().endsWith('.py')) {
20-
return 'Python file'
21-
}
22-
23-
switch (type) {
24-
case 'pdf':
25-
return 'PDF file'
26-
case 'csv':
27-
return 'CSV file'
28-
case 'image':
29-
return 'Image file'
30-
case 'json':
31-
return 'JSON file'
32-
default:
33-
return 'File'
34-
}
35-
}
36-
37-
// Helper to get file extension for display in the icon container
38-
// eg., example.py, somehting.pdf. first.csv
39-
const getFileExtension = (fileName: string): string => {
40-
const extension = fileName.split('.').pop()?.toLowerCase()
41-
return extension != null && extension !== '' ? `.${extension}` : '.file'
42-
}
43-
4416
export function AttachedFileItem({
4517
file,
4618
onRemove,
@@ -54,18 +26,29 @@ export function AttachedFileItem({
5426
: styles.container_without_remove
5527
}`
5628

29+
const getFileTypeLabel = (type: ReturnType<typeof getFileType>): string => {
30+
switch (type) {
31+
case 'pdf':
32+
return 'PDF file'
33+
case 'csv':
34+
return 'CSV file'
35+
case 'python':
36+
return 'Python file'
37+
default:
38+
return 'Unknown file'
39+
}
40+
}
41+
5742
return (
5843
<div className={containerClass}>
5944
<div className={styles.file_icon_container}>
6045
<div className={styles.file_extension}>
61-
{getFileExtension(file.name)}
46+
{getFileExtension(file as File)}
6247
</div>
6348
</div>
6449
<div className={styles.file_details_container}>
6550
<div className={styles.file_name}>{file.name}</div>
66-
<div className={styles.file_details}>
67-
{getSimpleFileTypeLabel(fileType, file.name)}
68-
</div>
51+
<div className={styles.file_details}>{getFileTypeLabel(fileType)}</div>
6952
</div>
7053
{showRemoveButton && onRemove != null && (
7154
<button

0 commit comments

Comments
 (0)