defmodule ArcanaWeb.InfoLive do @moduledoc """ LiveView for displaying Arcana configuration info. """ use Phoenix.LiveView import ArcanaWeb.DashboardComponents @impl true def mount(_params, session, socket) do repo = get_repo_from_session(session) {:ok, socket |> assign(repo: repo) |> assign(config_info: get_config_info()) |> assign(stats: nil)} end @impl true def handle_params(_params, _uri, socket) do {:noreply, load_data(socket)} end defp load_data(socket) do repo = socket.assigns.repo socket |> assign(stats: load_stats(repo)) end defp get_config_info do %{ repo: Application.get_env(:arcana, :repo), llm: format_llm_config(Application.get_env(:arcana, :llm)), embedding: format_embedding_config(Application.get_env(:arcana, :embedder, :local)), reranker: format_reranker_config(Application.get_env(:arcana, :reranker)), raw: %{ embedder: redact_config(Application.get_env(:arcana, :embedder, :local)), llm: redact_config(Application.get_env(:arcana, :llm)), reranker: redact_config(Application.get_env(:arcana, :reranker)) } } end defp redact_config(nil), do: nil defp redact_config(val) when is_atom(val), do: val defp redact_config(fun) when is_function(fun), do: "#Function<...>" defp redact_config({module, opts}) when is_atom(module), do: {module, redact_sensitive(opts)} defp redact_config(other), do: redact_sensitive(other) defp format_llm_config(nil), do: %{configured: false} defp format_llm_config(llm) when is_function(llm) do %{configured: true, type: "Function"} end defp format_llm_config(llm) do case llm do %{__struct__: module} = struct -> %{ configured: true, type: module |> Module.split() |> List.last(), model: Map.get(struct, :model, "unknown") } _ -> %{configured: true, type: redact_sensitive(llm)} end end defp format_embedding_config(:local), do: %{type: :local, model: "BAAI/bge-small-en-v1.5"} defp format_embedding_config(:openai), do: %{type: :openai, model: "text-embedding-3-small"} defp format_embedding_config({:local, opts}) do %{type: :local, model: Keyword.get(opts, :model, "BAAI/bge-small-en-v1.5")} end defp format_embedding_config({:openai, opts}) do %{type: :openai, model: Keyword.get(opts, :model, "text-embedding-3-small")} end defp format_embedding_config({:custom, _fun}), do: %{type: :custom} defp format_embedding_config({:custom, _fun, _opts}), do: %{type: :custom} defp format_embedding_config({module, opts}) when is_atom(module) and is_list(opts) do %{type: :custom_module, module: module, opts: redact_sensitive(opts)} end defp format_embedding_config(module) when is_atom(module) do %{type: :custom_module, module: module} end defp format_embedding_config(other), do: %{type: :unknown, raw: inspect(other)} defp format_reranker_config(nil), do: %{module: Arcana.Reranker.LLM, configured: false} defp format_reranker_config(module) when is_atom(module), do: %{module: module, configured: true} defp format_reranker_config({module, opts}) when is_atom(module) and is_list(opts) do %{module: module, opts: redact_sensitive(opts), configured: true} end defp format_reranker_config(fun) when is_function(fun) do %{type: :function, configured: true} end defp format_reranker_config(other), do: %{type: :unknown, raw: redact_sensitive(other), configured: true} @sensitive_keys [:api_key, :api_secret, :secret_key, :access_key, :token, :password] defp redact_sensitive(opts) when is_list(opts) do for {k, v} <- opts do if k in @sensitive_keys, do: {k, "[REDACTED]"}, else: {k, v} end end defp redact_sensitive(%{} = map) do for {k, v} <- map, into: %{} do if k in @sensitive_keys, do: {k, "[REDACTED]"}, else: {k, v} end end defp redact_sensitive(other), do: inspect(other) @impl true def render(assigns) do ~H""" <.dashboard_layout stats={@stats} current_tab={:info}>

Info

View current Arcana configuration including embedding, LLM, and chunking settings.

Repository

<%= inspect(@config_info.repo) %>

Embedding

<%= @config_info.embedding.type %>
<%= if @config_info.embedding[:model] do %>
<%= @config_info.embedding.model %>
<% end %> <%= if @config_info.embedding[:module] do %>
<%= inspect(@config_info.embedding.module) %>
<% end %>

LLM

<%= if @config_info.llm.configured do %>
<%= @config_info.llm.type %>
<%= if @config_info.llm[:model] do %>
<%= @config_info.llm.model %>
<% end %> <% else %>
Not configured
<% end %>

Reranker

<%= inspect(@config_info.reranker[:module] || @config_info.reranker[:type]) %>
<%= if @config_info.reranker[:opts] do %>
<%= inspect(@config_info.reranker.opts) %>
<% end %>
<%= if @config_info.reranker.configured, do: "Configured", else: "Default" %>

Raw Configuration

config :arcana,
    repo: <%= inspect(@config_info.repo) %>,
    embedder: <%= inspect(@config_info.raw.embedder) %>,
    llm: <%= inspect(@config_info.raw.llm) %>,
    reranker: <%= inspect(@config_info.raw.reranker) || "Arcana.Reranker.LLM (default)" %>
""" end end