defmodule AgentSea.Embedder.Cohere do
@moduledoc """
Cohere embeddings adapter (`POST /v1/embed`) over `Req` — a remote
`AgentSea.Embedder`.
Options: `:api_key` (defaults to `COHERE_API_KEY`), `:model` (default
`embed-english-v3.0`), `:input_type` (default `search_document`; use
`search_query` for queries), `:base_url`, `:adapter`. `dimensions/0` reads
`config :agentsea_embeddings, :cohere_dimensions` (default 1024).
"""
@behaviour AgentSea.Embedder
@base_url "https://api.cohere.com"
@impl true
def embed(texts, opts) do
body = %{
model: opts[:model] || "embed-english-v3.0",
texts: texts,
input_type: opts[:input_type] || "search_document"
}
case Req.post(req(opts), url: "/v1/embed", json: body) do
{:ok, %Req.Response{status: 200, body: %{"embeddings" => embeddings}}} ->
{:ok, embeddings}
{:ok, %Req.Response{status: status, body: body}} ->
{:error, {:http_error, status, body}}
{:error, reason} ->
{:error, reason}
end
end
@impl true
def dimensions do
Application.get_env(:agentsea_embeddings, :cohere_dimensions, 1024)
end
defp req(opts) do
api_key = opts[:api_key] || System.get_env("COHERE_API_KEY")
[
base_url: opts[:base_url] || @base_url,
headers: [{"authorization", "Bearer #{api_key || ""}"}]
]
|> maybe_put(:adapter, opts[:adapter])
|> Req.new()
end
defp maybe_put(kw, _key, nil), do: kw
defp maybe_put(kw, key, value), do: Keyword.put(kw, key, value)
end