Current section

Files

Jump to
hyper_llm lib providers open_ai.ex
Raw

lib/providers/open_ai.ex

defmodule HyperLLM.Provider.OpenAI do
@behaviour HyperLLM.Provider
@moduledoc """
Provider implementation for OpenAI.
https://platform.openai.com/docs/api-reference/chat
## Configuration
`api_key` - The API key for the OpenAI API.
congfig :hyper_llm,
openai: [
api_key: "sk-..."
]
"""
@models [
"gpt-3.5-turbo",
"gpt-3.5-turbo-0125",
"gpt-3.5-turbo-1106",
"gpt-3.5-turbo-instruct",
"gpt-4-turbo",
"gpt-4-turbo-2024-04-09",
"gpt-4-turbo-preview",
"gpt-4-0125-preview",
"gpt-4-1106-preview",
"gpt-4",
"gpt-4-0613",
"gpt-4-0314",
"gpt-4o-2024-11-20",
"gpt-4o-2024-08-06",
"gpt-4o-2024-05-13",
"gpt-4o-mini",
"gpt-4o-mini-2024-07-18",
"o1",
"o1-2024-12-17",
"o1-mini",
"o1-mini-2024-09-12",
"o1-preview",
"o1-preview-2024-09-12",
"o3-mini",
"o3-mini-2025-01-31"
]
@doc """
See `HyperLLM.Chat.completion/3` for more information.
"""
@spec completion(HyperLLM.Provider.completion_params(), HyperLLM.Provider.completion_config()) ::
{:ok, binary()} | {:error, binary()}
@impl HyperLLM.Provider
def completion(params, config \\ []) do
if !Map.has_key?(params, :messages) do
raise ArgumentError, ":messages are required in params"
end
if !Map.has_key?(params, :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, "OpenAI API key is invalid"}
%{status: 404} ->
{:error, "OpenAI API not found"}
%{status: 500} ->
{:error, "OpenAI Server error"}
_ ->
{:error, "Unknown error"}
end
end
@impl true
@doc """
Check if a model is supported by the provider.
Supported Models:
#{Enum.map_join(@models, "\n", &"* #{&1}")}
"""
def model_supported?(model) when model in @models, do: true
def model_supported?(_), do: false
defp request(url, opts) do
api_key = HyperLLM.config!(:openai, :api_key)
req =
Req.new(
auth: {:bearer, api_key},
base_url: "https://api.openai.com/v1",
headers: [
{"OpenAI-Beta", "assistants=v2"}
],
url: url
)
Req.run(req, opts)
end
end