defmodule Omni.Tools.WebFetch.Strategy.Default do @moduledoc false @behaviour Omni.Tools.WebFetch.Strategy @impl true def match?(_uri, _opts), do: true @impl true def extract(%{body: body}, _opts) when body in [nil, ""] do "(empty response)" end def extract(response, _opts) do content_type = parse_content_type(response) cond do content_type == "text/html" -> Html2Markdown.convert(response.body) json_type?(content_type) -> pretty_json(response.body) String.starts_with?(content_type, "text/") -> response.body true -> "Binary content: #{content_type}, #{format_bytes(byte_size(response.body))}" end end defp json_type?("application/json"), do: true defp json_type?(type), do: String.ends_with?(type, "+json") defp pretty_json(body) do case Jason.decode(body) do {:ok, decoded} -> Jason.encode!(decoded, pretty: true) {:error, _} -> body end end defp parse_content_type(response) do case Req.Response.get_header(response, "content-type") do [value | _] -> value |> String.split(";", parts: 2) |> hd() |> String.trim() |> String.downcase() [] -> "application/octet-stream" end end defp format_bytes(bytes) when bytes < 1_024, do: "#{bytes}B" defp format_bytes(bytes) when bytes < 1_048_576 do kb = Float.round(bytes / 1_024, 1) "#{kb}KB" end defp format_bytes(bytes) do mb = Float.round(bytes / 1_048_576, 1) "#{mb}MB" end end