defmodule SyntropyWeb.Api.TaskJSON do @moduledoc false @spec task(map(), [String.t()]) :: map() def task(task, snapshot_ids \\ []) do %{ id: task.task_id, node_id: Map.get(task, :node_id, "local"), coordinator_node_id: Map.get(task, :coordinator_node_id, Map.get(task, :node_id, "local")), prompt: task.prompt, strategy: task.strategy, resolved_mode: task.resolved_mode, used_temporary_join: task.used_temporary_join, selected_agent_ids: task.selected_agent_ids, selected_agents: Map.get( task, :selected_agents, selected_agent_refs(task.selection_trace, task.selected_agent_ids) ), contributing_agent_ids: task.contributing_agent_ids, contributing_agents: Map.get( task, :contributing_agents, contributing_agent_refs(task.thoughts, task.contributing_agent_ids) ), thoughts: task.thoughts, thought_count: task.thought_count, synthesis: task.synthesis, selection_trace: task.selection_trace, recommendation_ids: task.recommendation_ids, snapshot_ids: snapshot_ids } end defp selected_agent_refs(selection_trace, fallback_ids) do case Enum.filter(selection_trace || [], & &1.selected) do [] -> agent_refs(fallback_ids) selected_entries -> Enum.map(selected_entries, &selection_trace_ref/1) end end defp contributing_agent_refs(thoughts, fallback_ids) do case thoughts || [] do [] -> agent_refs(fallback_ids) thought_entries -> Enum.map(thought_entries, fn thought -> %{ id: thought.agent_id, runtime_id: Map.get(thought, :runtime_id, thought.agent_id), node_id: Map.get(thought, :node_id, "local") } end) end end defp agent_refs(agent_ids) do Enum.map(agent_ids, fn agent_id -> case Syntropy.ClusterInfo.parse_runtime_id(agent_id) do {:ok, ref} -> ref :error -> %{id: agent_id, runtime_id: agent_id, node_id: "local"} end end) end defp selection_trace_ref(entry) do %{ id: entry.agent_id, runtime_id: Map.get(entry, :runtime_id, entry.agent_id), node_id: Map.get(entry, :node_id, "local") } end end