GenAI.Provider.MediaHelpers (Noizu Labs, GenAI Wrapper v0.3.2)

Copy Markdown

Shared helpers for the sync media-generation providers (ADR-016 / ede43647): API-key resolution (request -> env, fast-fail when absent), prompt-text extraction, and the base64-image decode into the {:ok, %{data, mime, meta}} return contract. One definition reused by the OpenAI + Gemini image providers (and future media providers).

Summary

Functions

Access helper for the first element of a list inside a get_in path.

Map a common audio response_format (extension) to its MIME type.

Runtime base_url for a provider, read from config :genai, <config_key>, base_url:.

Wrap a raw-binary provider response (e.g. TTS audio bytes) into the media contract.

Decode a provider JSON image response: pull the base64 string at path (e.g. ["data", access0(), "b64_json"]) and decode into the media return map.

Decode a JSON response and pull a string field (e.g. a transcript) at path.

Default Finch options for media calls — image/audio/video generation can be slow.

Build a multipart/form-data request: fields is a keyword of string values, file is {field, filename, binary, content_type} (or nil). Returns {content_type, body} for a raw Finch POST — NOT for api_call/5, which JSON-encodes its body.

Bearer-authed JSON POST (body JSON-encoded). Returns the raw Finch response.

Flatten a request prompt (string or content parts) to the text the image API takes.

Raw Finch POST (body sent verbatim, not JSON-encoded) — for multipart/form uploads.

Resolve the API key from the request or env var; fast-fail (no doomed call) when unset.

Functions

access0()

Access helper for the first element of a list inside a get_in path.

audio_mime(fmt)

Map a common audio response_format (extension) to its MIME type.

base_url(config_key, default)

@spec base_url(atom(), String.t()) :: String.t()

Runtime base_url for a provider, read from config :genai, <config_key>, base_url:.

binary_result(body, mime)

@spec binary_result(binary(), String.t()) ::
  {:ok, %{data: binary(), mime: String.t(), meta: map()}}

Wrap a raw-binary provider response (e.g. TTS audio bytes) into the media contract.

decode_image(body, path, mime \\ "image/png")

@spec decode_image(binary(), list(), String.t()) ::
  {:ok, %{data: binary(), mime: String.t(), meta: map()}} | {:error, term()}

Decode a provider JSON image response: pull the base64 string at path (e.g. ["data", access0(), "b64_json"]) and decode into the media return map.

decode_text(body, path, mime \\ "text/plain")

@spec decode_text(binary(), list(), String.t()) ::
  {:ok, %{data: String.t(), mime: String.t(), meta: map()}} | {:error, term()}

Decode a JSON response and pull a string field (e.g. a transcript) at path.

media_opts(extra \\ [])

Default Finch options for media calls — image/audio/video generation can be slow.

multipart(fields, file \\ nil)

@spec multipart(
  keyword(),
  {atom() | String.t(), String.t(), binary(), String.t()} | nil
) :: {String.t(), binary()}

Build a multipart/form-data request: fields is a keyword of string values, file is {field, filename, binary, content_type} (or nil). Returns {content_type, body} for a raw Finch POST — NOT for api_call/5, which JSON-encodes its body.

post_json(url, key, body, options \\ [])

@spec post_json(String.t(), String.t(), map(), keyword()) ::
  {:ok, Finch.Response.t()} | {:error, term()}

Bearer-authed JSON POST (body JSON-encoded). Returns the raw Finch response.

prompt_text(prompt)

@spec prompt_text(term()) :: String.t()

Flatten a request prompt (string or content parts) to the text the image API takes.

raw_post(url, headers, body, options \\ [])

@spec raw_post(String.t(), list(), binary(), keyword()) ::
  {:ok, Finch.Response.t()} | {:error, term()}

Raw Finch POST (body sent verbatim, not JSON-encoded) — for multipart/form uploads.

require_key(request, env)

@spec require_key(GenAI.Media.Request.t(), String.t()) ::
  {:ok, String.t()} | {:error, :missing_api_key}

Resolve the API key from the request or env var; fast-fail (no doomed call) when unset.