message.py 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. from enum import Enum
  2. from pydantic import BaseModel, Field, model_serializer
  3. from typing_extensions import Literal
  4. class ContentType(Enum):
  5. TEXT = 'text'
  6. IMAGE_URL = 'image_url'
  7. class Content(BaseModel):
  8. type: ContentType
  9. @model_serializer
  10. def serialize_model(self):
  11. raise NotImplementedError('Subclasses should implement this method.')
  12. class TextContent(Content):
  13. type: ContentType = ContentType.TEXT
  14. text: str
  15. @model_serializer
  16. def serialize_model(self):
  17. return {'type': self.type.value, 'text': self.text}
  18. class ImageContent(Content):
  19. type: ContentType = ContentType.IMAGE_URL
  20. image_urls: list[str]
  21. @model_serializer
  22. def serialize_model(self):
  23. images: list[dict[str, str | dict[str, str]]] = []
  24. for url in self.image_urls:
  25. images.append({'type': self.type.value, 'image_url': {'url': url}})
  26. return images
  27. class Message(BaseModel):
  28. role: Literal['user', 'system', 'assistant']
  29. content: list[TextContent | ImageContent] = Field(default=list)
  30. @property
  31. def contains_image(self) -> bool:
  32. return any(isinstance(content, ImageContent) for content in self.content)
  33. @model_serializer
  34. def serialize_model(self) -> dict:
  35. content: list[dict[str, str | dict[str, str]]] = []
  36. for item in self.content:
  37. if isinstance(item, TextContent):
  38. content.append(item.model_dump())
  39. elif isinstance(item, ImageContent):
  40. content.extend(item.model_dump())
  41. return {'role': self.role, 'content': content}