Repository: pydantic/pydantic-ai
File: pydantic_ai_slim/pydantic_ai/messages.py (Python)

Code before:

    This identifier can be provided to the model in a message to allow it to refer to this file in a tool call argument, and the tool can look up the file in question by iterating over the message history and finding the matching `FileUrl`.

    This identifier is only automatically passed to the model when the `FileUrl` is returned by a tool. If you're passing the `FileUrl` as a user message, it's up to you to include a separate text part with the identifier, e.g. "This is file <identifier>:" preceding the `FileUrl`.
    """

    vendor_metadata: dict[str, Any] | None = None
    """Vendor-specific metadata for the file.

    Supported by:
    - `GoogleModel`: `VideoUrl.vendor_metadata` is used as `video_metadata`: https://ai.google.dev/gemini-api/docs/video-understanding#customize-video-processing
    """

    _media_type: str | None = field(init=False, repr=False, compare=False)

    def __init__(
        self,
        url: str,
        force_download: bool = False,
        identifier: str | None = None,
        vendor_metadata: dict[str, Any] | None = None,
        media_type: str | None = None,
    ) -> None:
        self.url = url
        self.force_download = force_download
        self.identifier = identifier
        self.vendor_metadata = vendor_metadata
        self._media_type = media_type

    @property
    def media_type(self) -> str:
        """Return the media type of the file, based on the URL or the provided `media_type`."""
        return self._media_type or self._infer_media_type()

    @abstractmethod
    def _infer_media_type(self) -> str:
        """Infer the media type of the file based on the URL."""
        raise NotImplementedError

    @property
    @abstractmethod
    def format(self) -> str:
        """The file format."""
        raise NotImplementedError

    __repr__ = _utils.dataclasses_no_defaults_repr


@dataclass(init=False, repr=False)
class VideoUrl(FileUrl):
    """A URL to a video."""

Review comment (suggestion):
Can you see if we can move the `multi_modal_content_identifier` function that's used in `_agent_graph.py` to here, so we can use it if no `identifier` was explicitly provided? That way we may be able to define the field as always being `str` (so no `None`) and always use it without having to check if it's set, similar to `media_type`.

Code after:
    """The URL of the file."""

    _: KW_ONLY

    force_download: bool = False
    """If the model supports it:

    * If True, the file is downloaded and the data is sent to the model as bytes.
    * If False, the URL is sent directly to the model and no download is performed.
    """

    vendor_metadata: dict[str, Any] | None = None
    """Vendor-specific metadata for the file.

    Supported by:
    - `GoogleModel`: `VideoUrl.vendor_metadata` is used as `video_metadata`: https://ai.google.dev/gemini-api/docs/video-understanding#customize-video-processing
    """

    _media_type: Annotated[str | None, pydantic.Field(alias='media_type', default=None, exclude=True)] = field(
        compare=False, default=None
    )

    identifier: str | None = None
    """The identifier of the file, such as a unique ID. generating one from the url if not explicitly set

    This identifier can be provided to the model in a message to allow it to refer to this file in a tool call argument,
    and the tool can look up the file in question by iterating over the message history and finding the matching `FileUrl`.

    This identifier is only automatically passed to the model when the `FileUrl` is returned by a tool.
    If you're passing the `FileUrl` as a user message, it's up to you to include a separate text part with the identifier,
    e.g. "This is file <identifier>:" preceding the `FileUrl`.
    """

    def __init__(
        self,
        url: str,
        *,
        force_download: bool = False,
        vendor_metadata: dict[str, Any] | None = None,
        media_type: str | None = None,
        identifier: str | None = None,
    ) -> None:
        self.url = url
        self.force_download = force_download
        self.vendor_metadata = vendor_metadata
        self._media_type = media_type
        self.identifier = identifier or _multi_modal_content_identifier(url)

    @pydantic.computed_field
    @property
    def media_type(self) -> str: