Current section

Files

Jump to
langchain lib file_uploaders file_result.ex
Raw

lib/file_uploaders/file_result.ex

defmodule LangChain.FileUploader.FileResult do
@moduledoc """
Represents the result of a file upload to an LLM provider.
Different providers return different types of file references:
- **OpenAI** and **Anthropic** return a `file_id` string
- **Google Gemini** returns a `file_uri` URL
At least one of `file_id` or `file_uri` will always be present.
The `raw` field contains the full provider response for accessing
provider-specific fields not covered by the struct.
"""
use Ecto.Schema
import Ecto.Changeset
alias __MODULE__
alias LangChain.LangChainError
@primary_key false
embedded_schema do
field :file_id, :string
field :file_uri, :string
field :filename, :string
field :mime_type, :string
field :size_bytes, :integer
field :provider, Ecto.Enum, values: [:openai, :anthropic, :google]
field :raw, :map, virtual: true, default: %{}
end
@type t :: %FileResult{}
@create_fields [:file_id, :file_uri, :filename, :mime_type, :size_bytes, :provider, :raw]
@required_fields [:provider]
@doc """
Build a new FileResult and return an `:ok`/`:error` tuple with the result.
"""
@spec new(attrs :: map()) :: {:ok, t()} | {:error, Ecto.Changeset.t()}
def new(%{} = attrs) do
%FileResult{}
|> cast(attrs, @create_fields)
|> validate_required(@required_fields)
|> validate_reference_present()
|> apply_action(:insert)
end
@doc """
Build a new FileResult and return it or raise an error if invalid.
"""
@spec new!(attrs :: map()) :: t() | no_return()
def new!(attrs) do
case new(attrs) do
{:ok, result} -> result
{:error, changeset} -> raise LangChainError, changeset
end
end
defp validate_reference_present(changeset) do
file_id = get_field(changeset, :file_id)
file_uri = get_field(changeset, :file_uri)
if is_nil(file_id) and is_nil(file_uri) do
add_error(changeset, :file_id, "either file_id or file_uri must be present")
else
changeset
end
end
end