defmodule SyntropyWeb.RuntimeViewHelpers do @moduledoc false alias Syntropy.ClusterInfo @spec strategy_options() :: [{String.t(), String.t()}] def strategy_options do [ {"Single", "single"}, {"Parallel", "parallel"}, {"All", "all"}, {"Auto", "auto"} ] end @spec parse_strategy(String.t()) :: :single | :parallel | :all | :auto def parse_strategy("single"), do: :single def parse_strategy("all"), do: :all def parse_strategy("auto"), do: :auto def parse_strategy(_strategy), do: :parallel @spec format_event_payload(map()) :: String.t() def format_event_payload(%{id: "task_submitted", payload: payload}) do "[#{payload_value(payload, :strategy, "unknown")}] #{payload_value(payload, :prompt, "")}" end def format_event_payload(%{id: "task_started", payload: payload}) do selected_agents = payload |> Map.get(:selected_agents, []) |> Enum.map(&format_agent_ref/1) resolved_mode = payload_value(payload, :resolved_mode, "parallel") if selected_agents == [] do "#{resolved_mode}: " <> Enum.join(payload_value(payload, :selected_agent_ids, []), ", ") else "#{resolved_mode}: " <> Enum.join(selected_agents, ", ") end end def format_event_payload(%{id: "agent_selected", payload: payload}) do [ payload_value(payload, :agent_name, "agent"), "(#{format_agent_ref(payload)})", "(##{payload_value(payload, :rank, "?")})", "rel #{format_score(payload_value(payload, :relevance, 0.0))}", "pos #{format_score(payload_value(payload, :position, 0.0))}", "cap #{format_score(payload_value(payload, :capacity, 0.0))}", "total #{format_score(payload_value(payload, :composite, 0.0))}" ] |> Enum.join(" ") end def format_event_payload(%{id: "agent_thought", payload: payload}) do header = "#{payload_value(payload, :agent_name, "agent")} (#{payload_value(payload, :perspective, "unknown")}) · #{format_agent_ref(payload)}" case payload_value(payload, :thought_preview, "") do "" -> header preview -> "#{header} · #{preview}" end end def format_event_payload(%{id: "ordering_recomputed", payload: payload}) do Enum.join(payload_value(payload, :ranked_agent_ids, []), " > ") end def format_event_payload(%{id: "task_completed", payload: payload}) do suffix = if payload_value(payload, :used_temporary_join, false), do: " + temporary join", else: "" "#{payload_value(payload, :thought_count, 0)} thoughts#{suffix}" end def format_event_payload(%{id: "task_failed", payload: payload}) do payload_value(payload, :reason, "unknown failure") end def format_event_payload(%{id: "structural_recommendation_created", payload: payload}) do candidate_agents = payload |> Map.get(:candidate_agents, []) |> Enum.map(&format_agent_ref/1) kind = payload_value(payload, :kind, "recommendation") if candidate_agents == [] do "#{kind}: " <> Enum.join(payload_value(payload, :candidate_agent_ids, []), " + ") else "#{kind}: " <> Enum.join(candidate_agents, " + ") end end def format_event_payload(%{id: "structural_recommendation_approved", payload: payload}) do "#{payload_value(payload, :proposal_id, "proposal")} -> #{payload_value(payload, :final_status, "approved")}" end def format_event_payload(%{id: "structural_recommendation_rejected", payload: payload}) do "#{payload_value(payload, :proposal_id, "proposal")} -> #{payload_value(payload, :final_status, "rejected")}" end def format_event_payload(%{id: "structural_recommendation_applied", payload: payload}) do "#{payload_value(payload, :proposal_id, "proposal")} -> #{payload_value(payload, :applied_agent_id, "agent")}" end def format_event_payload(_event), do: "event" @spec format_task_error(term()) :: String.t() def format_task_error(:no_agents) do "No agents are loaded yet. Deploy agents from the Operations page to start the lattice." end def format_task_error(:no_successful_thoughts) do "No selected agents produced a usable thought. Check provider readiness and retry." end def format_task_error(:agent_busy) do "An agent is already working on a task. Wait for the current run to finish and retry." end def format_task_error(:quota_exceeded) do "The fair-use token budget for the rolling 30-day window is exhausted. Raise the budget or wait for the window to move." end def format_task_error({:provider_http_error, provider, status, _body}) do "#{provider_label(provider)} returned HTTP #{status}." end def format_task_error({:provider_request_failed, provider, _reason}) do "#{provider_label(provider)} request failed." end def format_task_error({:invalid_provider_result, _other}) do "The configured provider returned an invalid completion payload." end def format_task_error({:error, reason}), do: format_task_error(reason) def format_task_error(reason) when is_binary(reason), do: reason def format_task_error(reason), do: inspect(reason) @spec node_id_for(map() | nil) :: String.t() def node_id_for(nil), do: Syntropy.node_id() def node_id_for(%{} = value), do: payload_value(value, :node_id, "local") @spec pending_recommendations([map()]) :: [map()] def pending_recommendations(recommendations) do Enum.filter(recommendations, &(&1.status == "pending_approval")) end @spec format_score(number()) :: String.t() def format_score(score) when is_integer(score) do score |> Kernel.*(1.0) |> format_score() end def format_score(score) when is_float(score) do :erlang.float_to_binary(score, decimals: 3) end @spec ordered_connections(map()) :: [map()] def ordered_connections(%{connections: connections} = agent) when is_map(connections) do connections |> Enum.sort_by(fn {target_id, _value} -> target_id end) |> Enum.map(fn {target_id, connection} -> %{ target_agent_id: connection_target_id(agent, target_id), weight: connection.weight, interactions: connection.interactions } end) end def ordered_connections(%{connections: connections} = agent) when is_list(connections) do connections |> Enum.map(fn connection -> Map.put( connection, :target_agent_id, connection_target_id(agent, connection.target_agent_id) ) end) |> Enum.sort_by(& &1.target_agent_id) end @spec format_timestamp(DateTime.t() | nil) :: String.t() def format_timestamp(nil), do: "live" def format_timestamp(%DateTime{} = timestamp) do timestamp |> DateTime.to_iso8601() |> String.replace("T", " ") |> String.replace("Z", " UTC") end @spec chip_class(String.t()) :: String.t() def chip_class(status) do "status-chip #{chip_modifier(status)}" end @spec humanize_status(String.t()) :: String.t() def humanize_status("not_ready"), do: "not ready" def humanize_status("pending_approval"), do: "pending approval" def humanize_status(status), do: status defp chip_modifier("ready"), do: "status-chip--ok" defp chip_modifier("ok"), do: "status-chip--ok" defp chip_modifier("seeded"), do: "status-chip--info" defp chip_modifier("mock"), do: "status-chip--info" defp chip_modifier("openai"), do: "status-chip--info" defp chip_modifier("ollama"), do: "status-chip--info" defp chip_modifier("local"), do: "status-chip--info" defp chip_modifier("degraded"), do: "status-chip--warn" defp chip_modifier("forming"), do: "status-chip--warn" defp chip_modifier("not_ready"), do: "status-chip--warn" defp chip_modifier("unavailable"), do: "status-chip--warn" defp chip_modifier("empty"), do: "status-chip--warn" defp chip_modifier("disabled"), do: "status-chip--muted" defp chip_modifier(_status), do: "status-chip--muted" defp provider_label(provider) when is_atom(provider), do: provider |> Atom.to_string() |> provider_label() defp provider_label("openai"), do: "OpenAI" defp provider_label("ollama"), do: "Ollama" defp provider_label(provider) when is_binary(provider), do: String.capitalize(provider) defp format_agent_ref(%{runtime_id: runtime_id, node_id: node_id}) do "#{runtime_id} @ #{node_id}" end defp format_agent_ref(%{id: id, node_id: node_id}) do "#{id} @ #{node_id}" end defp format_agent_ref(%{} = payload) do runtime_id = payload_value(payload, :runtime_id) node_id = payload_value(payload, :node_id, "local") id = payload_value(payload, :id, "agent") if is_binary(runtime_id) and runtime_id != "" do "#{runtime_id} @ #{node_id}" else "#{id} @ #{node_id}" end end defp connection_target_id(%{} = agent, target_id) when is_binary(target_id) do cond do String.contains?(target_id, "::") -> target_id explicit_runtime_id?(agent) -> ClusterInfo.runtime_id(target_id, node_id_for(agent)) true -> target_id end end defp explicit_runtime_id?(agent) do case payload_value(agent, :runtime_id) do runtime_id when is_binary(runtime_id) and runtime_id != "" -> true _other -> false end end defp payload_value(payload, key, default \\ nil) when is_map(payload) do string_key = Atom.to_string(key) cond do Map.has_key?(payload, key) -> Map.get(payload, key) Map.has_key?(payload, string_key) -> Map.get(payload, string_key) true -> default end end end