Packages
llm_composer
0.16.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/providers/bedrock.ex
if Code.ensure_loaded?(ExAws) do
defmodule LlmComposer.Providers.Bedrock do
@moduledoc """
Provider implementation for Amazon Bedrock.
Handles chat completion requests through Amazon Bedrock Converse API. Any
Bedrock compatible model can be used. To specify any model-specific options for
the request, you can pass them in the `request_params` option and they will
be merged into the base request that is prepared.
"""
@behaviour LlmComposer.Provider
alias LlmComposer.Message
alias LlmComposer.ProviderResponse
alias LlmComposer.Providers.Utils
@impl LlmComposer.Provider
def name, do: :bedrock
@impl LlmComposer.Provider
@doc """
Reference: https://docs.aws.amazon.com/bedrock/latest/APIReference/API_runtime_Converse.html
"""
def run(messages, system_message, opts) do
model = Keyword.get(opts, :model)
if model do
messages
|> build_request(system_message, opts)
|> send_request(model)
|> handle_response()
|> wrap_response(opts)
else
{:error, :model_not_provided}
end
end
@spec build_request(list(Message.t()), Message.t(), keyword()) :: map()
defp build_request(messages, system_message, opts) do
base_request = %{
"messages" => Enum.map(messages, &format_message/1),
"system" => [format_message(system_message)]
}
req_params = Keyword.get(opts, :request_params, %{})
base_request
|> Utils.merge_request_params(req_params)
|> Utils.cleanup_body()
end
@spec send_request(map(), String.t()) :: {:ok, map()} | {:error, term()}
defp send_request(payload, model) do
operation = %ExAws.Operation.JSON{
data: payload,
headers: [{"Content-Type", "application/json"}],
http_method: :post,
path: "/model/#{model}/converse",
service: :"bedrock-runtime"
}
config = [service_override: :bedrock]
ExAws.request(operation, config)
end
@spec format_message(Message.t()) :: map()
defp format_message(%Message{type: :system, content: content}) do
%{"text" => content}
end
defp format_message(%Message{type: role, content: content}) when is_binary(content) do
%{"role" => Atom.to_string(role), "content" => [%{"text" => content}]}
end
defp format_message(%Message{type: role, content: content}) do
%{"role" => Atom.to_string(role), "content" => content}
end
@spec handle_response({:ok, map()} | {:error, map()}) :: {:ok, map()} | {:error, term}
defp handle_response({:ok, %{"output" => %{"message" => _message}} = response}) do
{:ok,
%{
response: response,
input_tokens: get_in(response, ["usage", "inputTokens"]),
output_tokens: get_in(response, ["usage", "outputTokens"])
}}
end
defp handle_response({:error, resp}) do
{:error, resp}
end
defp wrap_response(result, opts) do
result
|> ProviderResponse.Bedrock.new(opts)
|> ProviderResponse.to_llm_response(opts)
end
end
end