Current section
Files
Jump to
Current section
Files
lib/providers/llama_cpp.ex
defmodule HyperLLM.Provider.LlamaCPP do
@behaviour HyperLLM.Provider
@moduledoc """
Provider implementation for LlamaCPP.
LlamaCPP server that implements the OpenAI API format.
https://github.com/ggerganov/llama.cpp/tree/master/examples/server
## Configuration
`api_key` - The API key for the LlamaCPP API (optional).
`base_url` - The base URL for the LlamaCPP API.
config :hyper_llm,
llama_cpp: [
api_key: "llamacpp",
base_url: "http://localhost:8080"
]
"""
@doc """
See `HyperLLM.Chat.completion/3` for more information.
"""
@impl HyperLLM.Provider
@spec completion(HyperLLM.Provider.completion_params(), HyperLLM.Provider.completion_config()) ::
{:ok, binary()} | {:error, binary()}
def completion(params, config) do
if !Map.has_key?(params, :messages) do
raise ArgumentError, ":messages are required in params"
end
if !Map.has_key?(config, :model) do
raise ArgumentError, ":model is required in config"
end
{_request, response} =
request("/chat/completions",
method: :post,
receive_timeout: Keyword.get(config, :receive_timeout, 30_000),
json: params
)
case response do
%{status: 200, body: body} ->
{:ok, body}
%{status: 400, body: body} ->
{:error, body.error.message}
%{status: 401} ->
{:error, "LlamaCPP API key is invalid"}
%{status: 404} ->
{:error, "LlamaCPP API not found"}
%{status: 500} ->
{:error, "LlamaCPP Server error"}
_ ->
{:error, "Unknown error"}
end
end
@impl true
@doc """
Check if a model is supported by the provider.
All models are supported as they are loaded into the server directly.
"""
def model_supported?(_), do: true
defp request(url, opts) do
api_key = HyperLLM.config!(:llama_cpp, :api_key)
base_url = HyperLLM.config(:llama_cpp, :base_url, "http://localhost:8080")
req =
Req.new(
auth: {:bearer, api_key},
base_url: base_url,
url: url
)
Req.run(req, opts)
end
end