|
import json |
|
import sys |
|
from collections.abc import Mapping, Sequence |
|
from typing import Any |
|
|
|
from pydantic import BaseModel, ConfigDict, field_validator |
|
|
|
from core.file import File |
|
|
|
from .types import SegmentType |
|
|
|
|
|
class Segment(BaseModel): |
|
model_config = ConfigDict(frozen=True) |
|
|
|
value_type: SegmentType |
|
value: Any |
|
|
|
@field_validator("value_type") |
|
@classmethod |
|
def validate_value_type(cls, value): |
|
""" |
|
This validator checks if the provided value is equal to the default value of the 'value_type' field. |
|
If the value is different, a ValueError is raised. |
|
""" |
|
if value != cls.model_fields["value_type"].default: |
|
raise ValueError("Cannot modify 'value_type'") |
|
return value |
|
|
|
@property |
|
def text(self) -> str: |
|
return str(self.value) |
|
|
|
@property |
|
def log(self) -> str: |
|
return str(self.value) |
|
|
|
@property |
|
def markdown(self) -> str: |
|
return str(self.value) |
|
|
|
@property |
|
def size(self) -> int: |
|
""" |
|
Return the size of the value in bytes. |
|
""" |
|
return sys.getsizeof(self.value) |
|
|
|
def to_object(self) -> Any: |
|
return self.value |
|
|
|
|
|
class NoneSegment(Segment): |
|
value_type: SegmentType = SegmentType.NONE |
|
value: None = None |
|
|
|
@property |
|
def text(self) -> str: |
|
return "" |
|
|
|
@property |
|
def log(self) -> str: |
|
return "" |
|
|
|
@property |
|
def markdown(self) -> str: |
|
return "" |
|
|
|
|
|
class StringSegment(Segment): |
|
value_type: SegmentType = SegmentType.STRING |
|
value: str |
|
|
|
|
|
class FloatSegment(Segment): |
|
value_type: SegmentType = SegmentType.NUMBER |
|
value: float |
|
|
|
|
|
class IntegerSegment(Segment): |
|
value_type: SegmentType = SegmentType.NUMBER |
|
value: int |
|
|
|
|
|
class ObjectSegment(Segment): |
|
value_type: SegmentType = SegmentType.OBJECT |
|
value: Mapping[str, Any] |
|
|
|
@property |
|
def text(self) -> str: |
|
return json.dumps(self.model_dump()["value"], ensure_ascii=False) |
|
|
|
@property |
|
def log(self) -> str: |
|
return json.dumps(self.model_dump()["value"], ensure_ascii=False, indent=2) |
|
|
|
@property |
|
def markdown(self) -> str: |
|
return json.dumps(self.model_dump()["value"], ensure_ascii=False, indent=2) |
|
|
|
|
|
class ArraySegment(Segment): |
|
@property |
|
def markdown(self) -> str: |
|
items = [] |
|
for item in self.value: |
|
items.append(str(item)) |
|
return "\n".join(items) |
|
|
|
|
|
class FileSegment(Segment): |
|
value_type: SegmentType = SegmentType.FILE |
|
value: File |
|
|
|
@property |
|
def markdown(self) -> str: |
|
return self.value.markdown |
|
|
|
@property |
|
def log(self) -> str: |
|
return str(self.value) |
|
|
|
@property |
|
def text(self) -> str: |
|
return str(self.value) |
|
|
|
|
|
class ArrayAnySegment(ArraySegment): |
|
value_type: SegmentType = SegmentType.ARRAY_ANY |
|
value: Sequence[Any] |
|
|
|
|
|
class ArrayStringSegment(ArraySegment): |
|
value_type: SegmentType = SegmentType.ARRAY_STRING |
|
value: Sequence[str] |
|
|
|
|
|
class ArrayNumberSegment(ArraySegment): |
|
value_type: SegmentType = SegmentType.ARRAY_NUMBER |
|
value: Sequence[float | int] |
|
|
|
|
|
class ArrayObjectSegment(ArraySegment): |
|
value_type: SegmentType = SegmentType.ARRAY_OBJECT |
|
value: Sequence[Mapping[str, Any]] |
|
|
|
|
|
class ArrayFileSegment(ArraySegment): |
|
value_type: SegmentType = SegmentType.ARRAY_FILE |
|
value: Sequence[File] |
|
|
|
@property |
|
def markdown(self) -> str: |
|
items = [] |
|
for item in self.value: |
|
items.append(item.markdown) |
|
return "\n".join(items) |
|
|