# `ReqLLM.Message.ContentPart`
[🔗](https://github.com/agentjido/req_llm/blob/main/lib/req_llm/message/content_part.ex#L1)

ContentPart represents a single piece of content within a message.

Supports multiple content types:
- `:text` - Plain text content
- `:image_url` - Image from URL
- `:video_url` - Video from URL
- `:image` - Image from binary data
- `:file` - File attachment or uploaded file reference
- `:thinking` - Chain-of-thought thinking content
- `:provider_block` - An opaque, provider-owned block that must be replayed
  unchanged (e.g. Anthropic `server_tool_use` / `tool_search_tool_result`)

Provider-owned file references are opt-in through `owned_file_id/3`. Legacy
`file_id/1` values remain unowned and preserve their existing behavior.

## See also

- `ReqLLM.Message` - Multi-modal message composition using ContentPart collections

# `t`

```elixir
@type t() :: %ReqLLM.Message.ContentPart{
  data: nil | nil | any(),
  file_id: nil | nil | binary(),
  filename: nil | nil | binary(),
  media_type: nil | nil | binary(),
  metadata: map(),
  text: nil | nil | binary(),
  type:
    :text
    | :image_url
    | :video_url
    | :image
    | :file
    | :thinking
    | :provider_block,
  url: nil | nil | binary()
}
```

# `file`

```elixir
@spec file(binary(), String.t(), String.t(), map()) :: t()
```

# `file_id`

```elixir
@spec file_id(String.t(), String.t(), map()) :: t()
```

# `image`

```elixir
@spec image(binary(), String.t()) :: t()
```

# `image`

```elixir
@spec image(binary(), String.t(), map()) :: t()
```

# `image_url`

```elixir
@spec image_url(String.t()) :: t()
```

# `image_url`

```elixir
@spec image_url(String.t(), map()) :: t()
```

# `inspect_provider_file`

```elixir
@spec inspect_provider_file(t() | map()) ::
  {:ok, ReqLLM.ProviderFileReference.t()} | :error
```

Returns redacted provider file metadata suitable for logs and diagnostics.

# `owned_file?`

```elixir
@spec owned_file?(t() | map()) :: boolean()
```

Returns whether a file reference has explicit provider ownership metadata.

# `owned_file_id`

```elixir
@spec owned_file_id(String.t(), atom() | String.t(), keyword()) :: t()
```

Creates an explicitly provider-owned file reference.

Ownership is stored in the reserved `"req_llm" -> "provider_file"` metadata
namespace. Legacy `file_id/1` references remain unowned and keep their existing
behavior.

Supported options are `:media_type`, `:metadata`, `:purpose`, `:status`,
`:expires_at`, `:size`, `:sha256`, and `:provider_metadata`.

# `provider_block`

```elixir
@spec provider_block(atom(), map(), map()) :: t()
```

Wraps a provider-owned content block that ReqLLM does not model itself.

The raw block lives in `:data` exactly as the provider returned it, and
`:metadata` carries the owning `:provider` (plus a `:block_type` for
inspection). The owning provider's encoder replays the block verbatim in
the assistant turn; every other provider drops it. Anthropic's tool-search
blocks (`server_tool_use`, `tool_search_tool_result`) are the first case —
the API rejects a replayed assistant turn that lost them when extended
thinking is on ("thinking blocks … cannot be modified").

# `provider_file_reference`

```elixir
@spec provider_file_reference(t() | map()) ::
  {:ok, ReqLLM.ProviderFileReference.t()} | :error
```

Returns the full metadata record for an explicitly owned provider file.

# `schema`

Returns the Zoi schema for this module

# `text`

```elixir
@spec text(String.t()) :: t()
```

# `text`

```elixir
@spec text(String.t(), map()) :: t()
```

# `thinking`

```elixir
@spec thinking(String.t()) :: t()
```

# `thinking`

```elixir
@spec thinking(String.t(), map()) :: t()
```

# `valid?`

```elixir
@spec valid?(t()) :: boolean()
```

# `video_url`

```elixir
@spec video_url(String.t()) :: t()
```

# `video_url`

```elixir
@spec video_url(String.t(), map()) :: t()
```

---

*Consult [api-reference.md](api-reference.md) for complete listing*
