Packages
llm_composer
0.20.2
0.20.2
0.20.1
0.20.0
0.19.6
0.19.5
0.19.4
0.19.3
0.19.2
0.19.1
0.19.0
0.18.2
0.18.1
0.18.0
0.17.1
0.17.0
0.16.2
0.16.1
0.16.0
0.15.0
0.14.2
0.14.1
0.14.0
0.13.1
0.13.0
0.12.3
0.12.2
0.12.0
0.11.2
0.11.1
0.11.0
0.10.0
0.8.0
0.7.0
0.6.0
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.0
0.3.6
0.3.5
0.3.4
0.3.3
0.3.2
0.3.1
0.3.0
0.2.0
0.1.0
LlmComposer is an Elixir library that facilitates chat interactions with language models, providing tools to handle user messages, generate responses, and execute functions automatically based on model outputs.
Current section
Files
Jump to
Current section
Files
lib/llm_composer/http_client.ex
defmodule LlmComposer.HttpClient do
@moduledoc """
Helper mod for setup the Tesla http client and its options
"""
alias LlmComposer.Helpers
@default_timeout 50_000
@spec client(binary(), keyword()) :: Tesla.Client.t()
def client(base_url, opts \\ []) do
base_url
|> middlewares(opts)
|> Tesla.client(adapter(opts))
end
@spec adapter(keyword()) :: term()
defp adapter(opts) do
timeout = get_timeout(opts)
configured = Application.get_env(:llm_composer, :tesla_adapter, Tesla.Adapter.Mint)
case configured do
Tesla.Adapter.Mint ->
{Tesla.Adapter.Mint, [timeout: timeout]}
{Tesla.Adapter.Mint, adapter_opts} when is_list(adapter_opts) ->
{Tesla.Adapter.Mint, Keyword.put_new(adapter_opts, :timeout, timeout)}
other ->
other
end
end
@spec middlewares(binary(), keyword()) :: list(term())
defp middlewares(base_url, opts) do
stream = Keyword.get(opts, :stream_response)
json_engine = Helpers.json_engine()
resp = [
{
Tesla.Middleware.BaseUrl,
base_url
},
{Tesla.Middleware.JSON, engine: json_engine}
]
cond do
stream ->
resp ++ Keyword.get(opts, :sse_middleware, [{Tesla.Middleware.SSE, only: :data}])
retries_disabled?(opts) ->
resp ++
[
{Tesla.Middleware.Timeout,
[
timeout: get_timeout(opts)
]}
]
true ->
resp ++
[
{Tesla.Middleware.Retry, retry_opts(opts)},
{Tesla.Middleware.Timeout,
[
timeout: get_timeout(opts)
]}
]
end
end
@spec retries_disabled?(keyword()) :: boolean()
defp retries_disabled?(opts) do
skip_config = Application.get_env(:llm_composer, :skip_retries, false)
# Only the explicit skip flag disables retries. Let Tesla handle other retry options
Keyword.get(opts, :skip_retries, skip_config)
end
@spec get_timeout(keyword()) :: non_neg_integer()
defp get_timeout(opts) do
case Keyword.get(opts, :timeout) do
nil -> Application.get_env(:llm_composer, :timeout) || @default_timeout
timeout -> timeout
end
end
@spec retry_opts(keyword()) :: keyword()
defp retry_opts(opts) do
config = Application.get_env(:llm_composer, :retry_opts, [])
req_opts = Keyword.get(opts, :retry_opts, [])
[]
|> Keyword.merge(config)
|> Keyword.merge(req_opts)
|> Keyword.put_new(:delay, 1_000)
|> Keyword.put_new(:max_delay, 10_000)
|> Keyword.put_new(:should_retry, &default_should_retry/1)
end
@spec default_should_retry(term()) :: boolean()
defp default_should_retry({:ok, %{status: status}}) when status in [429, 500, 503], do: true
defp default_should_retry({:error, :closed}), do: true
defp default_should_retry(_other), do: false
end