Packages
llm_composer
0.5.1
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/llm_response.ex
defmodule LlmComposer.LlmResponse do
@moduledoc """
Module to parse and easily handle llm responses.
"""
alias LlmComposer.FunctionCall
alias LlmComposer.Message
@llm_models [:open_ai, :ollama, :open_router, :bedrock]
@type t() :: %__MODULE__{
actions: [[FunctionCall.t()]] | [FunctionCall.t()],
input_tokens: pos_integer() | nil,
main_response: Message.t(),
output_tokens: pos_integer() | nil,
previous_response: map() | nil,
raw: map(),
status: :ok | :error
}
defstruct [
:actions,
:main_response,
:input_tokens,
:output_tokens,
:previous_response,
:raw,
:status
]
@type model_response :: Tesla.Env.result()
@spec new(nil | model_response, atom()) :: {:ok, t()} | {:error, term()}
def new(nil, _model), do: {:error, :no_llm_response}
def new({:error, %{body: body}}, model) when model in @llm_models do
{:error, body}
end
def new({:error, resp}, model) when model in @llm_models do
{:error, resp}
end
def new(
{status,
%{actions: actions, response: %{"choices" => [first_choice | _]} = raw_response}},
llm_model
)
when llm_model in [:open_ai, :open_router] do
main_response = get_in(first_choice, ["message"])
response =
main_response["role"]
|> String.to_existing_atom()
|> Message.new(main_response["content"], %{original: main_response})
{:ok,
%__MODULE__{
actions: actions,
input_tokens: get_in(raw_response, ["usage", "prompt_tokens"]),
output_tokens: get_in(raw_response, ["usage", "completion_tokens"]),
main_response: response,
raw: raw_response,
status: status
}}
end
def new(
{status, %{actions: actions, response: %{"message" => message} = raw_response}},
:ollama
) do
response =
message["role"]
|> String.to_existing_atom()
|> Message.new(message["content"], %{original: message})
{:ok,
%__MODULE__{
actions: actions,
main_response: response,
raw: raw_response,
status: status
}}
end
def new({status, %{actions: actions, response: response}}, :bedrock) do
[%{"text" => message_content}] = response["output"]["message"]["content"]
role = String.to_existing_atom(response["output"]["message"]["role"])
{:ok,
%__MODULE__{
actions: actions,
input_tokens: response["usage"]["inputTokens"],
output_tokens: response["usage"]["outputTokens"],
main_response:
Message.new(role, message_content, %{original: response["output"]["message"]}),
raw: response,
status: status
}}
end
end