55
66from pydantic import BaseModel , field_validator , model_validator
77
8+ from agno .utils .common import MIME_TO_EXTENSION
89from agno .utils .log import log_error
910
1011
@@ -52,6 +53,21 @@ def validate_and_normalize_content(cls, data: Any):
5253
5354 return data
5455
56+ @field_validator ("mime_type" )
57+ @classmethod
58+ def validate_mime_type (cls , v ):
59+ """Validate that the mime_type is one of the allowed types."""
60+ if v is not None :
61+ v_lower = v .lower ()
62+ if v_lower not in cls .valid_mime_types ():
63+ raise ValueError (f"Invalid MIME type: { v } . Must be one of: { cls .valid_mime_types ()} " )
64+ return v_lower
65+ return v
66+
67+ @classmethod
68+ def valid_mime_types (cls ) -> List [str ]:
69+ return [m for m , e in MIME_TO_EXTENSION .items () if m .startswith ("image/" )]
70+
5571 def get_content_bytes (self ) -> Optional [bytes ]:
5672 """Get image content as raw bytes, loading from URL/file if needed"""
5773 if self .content :
@@ -168,6 +184,21 @@ def validate_and_normalize_content(cls, data: Any):
168184
169185 return data
170186
187+ @field_validator ("mime_type" )
188+ @classmethod
189+ def validate_mime_type (cls , v ):
190+ """Validate that the mime_type is one of the allowed types."""
191+ if v is not None :
192+ v_lower = v .lower ()
193+ if v_lower not in cls .valid_mime_types ():
194+ raise ValueError (f"Invalid MIME type: { v } . Must be one of: { cls .valid_mime_types ()} " )
195+ return v_lower
196+ return v
197+
198+ @classmethod
199+ def valid_mime_types (cls ) -> List [str ]:
200+ return [m for m , e in MIME_TO_EXTENSION .items () if m .startswith ("audio/" )]
201+
171202 def get_content_bytes (self ) -> Optional [bytes ]:
172203 """Get audio content as raw bytes"""
173204 if self .content :
@@ -300,6 +331,21 @@ def validate_and_normalize_content(cls, data: Any):
300331
301332 return data
302333
334+ @field_validator ("mime_type" )
335+ @classmethod
336+ def validate_mime_type (cls , v ):
337+ """Validate that the mime_type is one of the allowed types."""
338+ if v is not None :
339+ v_lower = v .lower ()
340+ if v_lower not in cls .valid_mime_types ():
341+ raise ValueError (f"Invalid MIME type: { v } . Must be one of: { cls .valid_mime_types ()} " )
342+ return v_lower
343+ return v
344+
345+ @classmethod
346+ def valid_mime_types (cls ) -> List [str ]:
347+ return [m for m , e in MIME_TO_EXTENSION .items () if m .startswith ("video/" )]
348+
303349 def get_content_bytes (self ) -> Optional [bytes ]:
304350 """Get video content as raw bytes"""
305351 if self .content :
@@ -345,7 +391,7 @@ def from_base64(
345391 format : Optional [str ] = None ,
346392 ** kwargs ,
347393 ) -> "Video" :
348- """Create Image from base64 content"""
394+ """Create Video from base64 content"""
349395 import base64
350396
351397 try :
@@ -379,18 +425,18 @@ def to_dict(self, include_base64_content: bool = True) -> Dict[str, Any]:
379425
380426
381427class File (BaseModel ):
428+ # Core content fields (at least one required)
382429 id : Optional [str ] = None
383430 url : Optional [str ] = None
384431 filepath : Optional [Union [Path , str ]] = None
385- # Raw bytes content of a file
386- content : Optional [Any ] = None
387- mime_type : Optional [str ] = None
432+ content : Optional [Any ] = None # Raw bytes content of a file
433+ external : Optional [Any ] = None # External file object (e.g. GeminiFile)
388434
435+ # Metadata fields
436+ mime_type : Optional [str ] = None
389437 file_type : Optional [str ] = None
390438 filename : Optional [str ] = None
391439 size : Optional [int ] = None
392- # External file object (e.g. GeminiFile, must be a valid object as expected by the model you are using)
393- external : Optional [Any ] = None
394440 format : Optional [str ] = None # E.g. `pdf`, `txt`, `csv`, `xml`, etc.
395441 name : Optional [str ] = None # Name of the file, mandatory for AWS Bedrock document input
396442
@@ -408,28 +454,17 @@ def check_at_least_one_source(cls, data):
408454 @classmethod
409455 def validate_mime_type (cls , v ):
410456 """Validate that the mime_type is one of the allowed types."""
411- if v is not None and v not in cls .valid_mime_types ():
412- raise ValueError (f"Invalid MIME type: { v } . Must be one of: { cls .valid_mime_types ()} " )
457+ if v is not None :
458+ v_lower = v .lower ()
459+ if v_lower not in cls .valid_mime_types ():
460+ raise ValueError (f"Invalid MIME type: { v } . Must be one of: { cls .valid_mime_types ()} " )
461+ return v_lower
413462 return v
414463
415464 @classmethod
416465 def valid_mime_types (cls ) -> List [str ]:
417- return [
418- "application/pdf" ,
419- "application/json" ,
420- "application/x-javascript" ,
421- "application/vnd.openxmlformats-officedocument.wordprocessingml.document" ,
422- "text/javascript" ,
423- "application/x-python" ,
424- "text/x-python" ,
425- "text/plain" ,
426- "text/html" ,
427- "text/css" ,
428- "text/markdown" ,
429- "text/csv" ,
430- "text/xml" ,
431- "text/rtf" ,
432- ]
466+ # Return all MIME types defined in common.py for regular Files/Documents
467+ return list (MIME_TO_EXTENSION .keys ())
433468
434469 @classmethod
435470 def from_base64 (
0 commit comments