defmodule AgentSea.Crew.Delegation.BestMatch do @moduledoc """ Selects the agent whose role capabilities best fit the task. Prefers agents that can fully execute the task, breaking ties by capability score. Pure — uses the role on each `agent_ref`, no process calls. """ @behaviour AgentSea.Crew.Delegation alias AgentSea.Capability alias AgentSea.Crew.Delegation.Result @impl true def delegate(_task, [], _ctx), do: {:error, :no_agents} def delegate(task, agents, _ctx) do required = Map.get(task, :required_capabilities, []) ranked = agents |> Enum.map(fn agent -> {agent, Capability.match(role_capabilities(agent), required)} end) # can_execute (true sorts after false) then score, both descending |> Enum.sort_by(fn {_agent, m} -> {m.can_execute, m.score} end, :desc) [{best, match} | rest] = ranked {:ok, %Result{ selected_agent: best.name, confidence: match.score, reason: "best capability match (score #{Float.round(match.score, 2)})", alternatives: Enum.map(rest, fn {agent, _m} -> agent.name end) }} end defp role_capabilities(%{role: %AgentSea.Role{capabilities: caps}}), do: caps defp role_capabilities(_), do: [] end