defmodule ElixirAiWeb.AiProvidersLive do
use ElixirAiWeb, :live_component
import ElixirAiWeb.FormComponents
alias ElixirAi.AiProvider
def update(assigns, socket) do
if connected?(socket) do
Phoenix.PubSub.subscribe(ElixirAi.PubSub, "ai_providers")
end
{:ok,
socket
|> assign(assigns)
|> assign_new(:providers, fn -> AiProvider.all() end)
|> assign_new(:show_form, fn -> false end)
|> assign_new(
:form_data,
fn ->
%{
"name" => "",
"model_name" => "",
"api_token" => "",
"completions_url" => "https://api.openai.com/v1/chat/completions"
}
end
)
|> assign_new(:error, fn -> nil end)}
end
def render(assigns) do
~H"""
AI Providers
<%= if @show_form do %>
<% end %>
<%= if @error do %>
{@error}
<% end %>
<%= if @providers == [] do %>
- No providers configured yet.
<% end %>
<%= for provider <- @providers do %>
-
{provider.name}
Model: {provider.model_name}
Endpoint: {provider.completions_url}
Token: {String.slice(provider.api_token || "", 0..7)}***
<% end %>
"""
end
def handle_event("toggle_form", _params, socket) do
{:noreply, assign(socket, show_form: !socket.assigns.show_form, error: nil)}
end
def handle_event("create_provider", params, socket) do
name = String.trim(params["name"])
model_name = String.trim(params["model_name"])
api_token = String.trim(params["api_token"])
completions_url = String.trim(params["completions_url"])
cond do
name == "" ->
{:noreply, assign(socket, error: "Provider name can't be blank")}
model_name == "" ->
{:noreply, assign(socket, error: "Model name can't be blank")}
api_token == "" ->
{:noreply, assign(socket, error: "API token can't be blank")}
completions_url == "" ->
{:noreply, assign(socket, error: "Completions URL can't be blank")}
true ->
attrs = %{
name: name,
model_name: model_name,
api_token: api_token,
completions_url: completions_url
}
case AiProvider.create(attrs) do
:ok ->
{:noreply,
socket
|> assign(show_form: false)
|> assign(
form_data: %{
"name" => "",
"model_name" => "",
"api_token" => "",
"completions_url" => "https://api.openai.com/v1/chat/completions"
}
)
|> assign(error: nil)}
{:error, :already_exists} ->
{:noreply, assign(socket, error: "A provider with that name already exists")}
_ ->
{:noreply, assign(socket, error: "Failed to create provider")}
end
end
end
def handle_info({:provider_added, _attrs}, socket) do
{:noreply, assign(socket, providers: AiProvider.all())}
end
end