Files
elixirAI/lib/elixir_ai/data/ai_provider.ex
Alex Mickelson b2f53942a2
Some checks failed
CI/CD Pipeline / build (push) Failing after 4s
working on delete
2026-03-18 09:21:34 -06:00

166 lines
3.9 KiB
Elixir

defmodule ElixirAi.AiProvider do
alias ElixirAi.Data.DbHelpers
require Logger
import ElixirAi.PubsubTopics
defmodule AiProviderSchema do
defstruct [:id, :name, :model_name, :api_token, :completions_url]
def schema do
Zoi.object(%{
id: Zoi.optional(Zoi.string()),
name: Zoi.string(),
model_name: Zoi.string(),
api_token: Zoi.string(),
completions_url: Zoi.string()
})
end
def partial_schema do
Zoi.object(%{
id: Zoi.optional(Zoi.string()),
name: Zoi.string(),
model_name: Zoi.string()
})
end
end
def all do
sql = "SELECT id, name, model_name FROM ai_providers"
params = %{}
case DbHelpers.run_sql(sql, params, providers_topic(), AiProviderSchema.partial_schema()) do
{:error, _} ->
[]
rows ->
rows
|> Enum.map(fn row ->
row |> convert_uuid_to_string() |> then(&struct(AiProviderSchema, &1))
end)
|> tap(&Logger.debug("AiProvider.all() returning: #{inspect(&1)}"))
end
end
defp convert_uuid_to_string(%{id: id} = provider) when is_binary(id) do
%{provider | id: Ecto.UUID.cast!(id)}
end
defp convert_uuid_to_string(provider), do: provider
def create(attrs) do
now = DateTime.truncate(DateTime.utc_now(), :second)
sql = """
INSERT INTO ai_providers (
name,
model_name,
api_token,
completions_url,
inserted_at,
updated_at
) VALUES (
$(name),
$(model_name),
$(api_token),
$(completions_url),
$(inserted_at),
$(updated_at)
)
"""
params = %{
"name" => attrs.name,
"model_name" => attrs.model_name,
"api_token" => attrs.api_token,
"completions_url" => attrs.completions_url,
"inserted_at" => now,
"updated_at" => now
}
case DbHelpers.run_sql(sql, params, providers_topic()) do
{:error, :db_error} ->
{:error, :db_error}
_result ->
Logger.info(
"Provider created, broadcasting :provider_added message to topic #{providers_topic()}"
)
Phoenix.PubSub.broadcast(
ElixirAi.PubSub,
providers_topic(),
{:provider_added, attrs}
)
:ok
end
end
def find_by_name(name) do
sql = """
SELECT id, name, model_name, api_token, completions_url
FROM ai_providers
WHERE name = $(name)
LIMIT 1
"""
params = %{"name" => name}
case DbHelpers.run_sql(sql, params, providers_topic(), AiProviderSchema.schema()) do
{:error, _} -> {:error, :db_error}
[] -> {:error, :not_found}
[row | _] -> {:ok, row |> convert_uuid_to_string() |> then(&struct(AiProviderSchema, &1))}
end
end
def delete(id) do
sql = "DELETE FROM ai_providers WHERE id = $(id)::uuid"
params = %{"id" => id}
case DbHelpers.run_sql(sql, params, providers_topic()) do
{:error, :db_error} ->
{:error, :db_error}
_result ->
Logger.info(
"Provider deleted, broadcasting :provider_deleted message to topic #{providers_topic()}"
)
Phoenix.PubSub.broadcast(
ElixirAi.PubSub,
providers_topic(),
{:provider_deleted, id}
)
:ok
end
end
def ensure_default_provider do
sql = "SELECT COUNT(*) FROM ai_providers"
params = %{}
case DbHelpers.run_sql(sql, params, providers_topic()) do
{:error, :db_error} ->
{:error, :db_error}
rows ->
case rows do
[%{"count" => 0}] ->
attrs = %{
name: "default",
model_name: Application.fetch_env!(:elixir_ai, :ai_model),
api_token: Application.fetch_env!(:elixir_ai, :ai_token),
completions_url: Application.fetch_env!(:elixir_ai, :ai_endpoint)
}
create(attrs)
_ ->
:ok
end
end
end
end