segments.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. import json
  2. import sys
  3. from collections.abc import Mapping, Sequence
  4. from typing import Any
  5. from pydantic import BaseModel, ConfigDict, field_validator
  6. from core.file.file_obj import FileVar
  7. from .types import SegmentType
  8. class Segment(BaseModel):
  9. model_config = ConfigDict(frozen=True)
  10. value_type: SegmentType
  11. value: Any
  12. @field_validator('value_type')
  13. def validate_value_type(cls, value):
  14. """
  15. This validator checks if the provided value is equal to the default value of the 'value_type' field.
  16. If the value is different, a ValueError is raised.
  17. """
  18. if value != cls.model_fields['value_type'].default:
  19. raise ValueError("Cannot modify 'value_type'")
  20. return value
  21. @property
  22. def text(self) -> str:
  23. return str(self.value)
  24. @property
  25. def log(self) -> str:
  26. return str(self.value)
  27. @property
  28. def markdown(self) -> str:
  29. return str(self.value)
  30. @property
  31. def size(self) -> int:
  32. return sys.getsizeof(self.value)
  33. def to_object(self) -> Any:
  34. return self.value
  35. class NoneSegment(Segment):
  36. value_type: SegmentType = SegmentType.NONE
  37. value: None = None
  38. @property
  39. def text(self) -> str:
  40. return 'null'
  41. @property
  42. def log(self) -> str:
  43. return 'null'
  44. @property
  45. def markdown(self) -> str:
  46. return 'null'
  47. class StringSegment(Segment):
  48. value_type: SegmentType = SegmentType.STRING
  49. value: str
  50. class FloatSegment(Segment):
  51. value_type: SegmentType = SegmentType.NUMBER
  52. value: float
  53. class IntegerSegment(Segment):
  54. value_type: SegmentType = SegmentType.NUMBER
  55. value: int
  56. class FileSegment(Segment):
  57. value_type: SegmentType = SegmentType.FILE
  58. # TODO: embed FileVar in this model.
  59. value: FileVar
  60. @property
  61. def markdown(self) -> str:
  62. return self.value.to_markdown()
  63. class ObjectSegment(Segment):
  64. value_type: SegmentType = SegmentType.OBJECT
  65. value: Mapping[str, Any]
  66. @property
  67. def text(self) -> str:
  68. return json.dumps(self.model_dump()['value'], ensure_ascii=False)
  69. @property
  70. def log(self) -> str:
  71. return json.dumps(self.model_dump()['value'], ensure_ascii=False, indent=2)
  72. @property
  73. def markdown(self) -> str:
  74. return json.dumps(self.model_dump()['value'], ensure_ascii=False, indent=2)
  75. class ArraySegment(Segment):
  76. @property
  77. def markdown(self) -> str:
  78. return '\n'.join(['- ' + item.markdown for item in self.value])
  79. class ArrayAnySegment(ArraySegment):
  80. value_type: SegmentType = SegmentType.ARRAY_ANY
  81. value: Sequence[Any]
  82. class ArrayStringSegment(ArraySegment):
  83. value_type: SegmentType = SegmentType.ARRAY_STRING
  84. value: Sequence[str]
  85. class ArrayNumberSegment(ArraySegment):
  86. value_type: SegmentType = SegmentType.ARRAY_NUMBER
  87. value: Sequence[float | int]
  88. class ArrayObjectSegment(ArraySegment):
  89. value_type: SegmentType = SegmentType.ARRAY_OBJECT
  90. value: Sequence[Mapping[str, Any]]
  91. class ArrayFileSegment(ArraySegment):
  92. value_type: SegmentType = SegmentType.ARRAY_FILE
  93. value: Sequence[FileSegment]