def METHOD_NAME(
    inputs: Optional[Sequence[Union[Mapping, Tuple[Text, Text]]]] = None
) -> Callable[[Sequence[AbstractAgent]], None]:
    """Creates an interaction functor."""
    if inputs is None:
        inputs = tuple()
    interactions = []
    for params in inputs:
        if isinstance(params, Mapping):
            net_params = params["net"]
            action_params = params["interaction"]
        else:
            net_params, action_params = params
        if isinstance(net_params, Text):
            net_params = {"name": net_params}
        if isinstance(action_params, Text):
            action_params = {"name": action_params}
        net = INTERACTION_NETS[net_params["name"]]
        interaction = AGENT_INTERACTIONS[action_params["name"]]
        interactions.append(((net, net_params), (interaction, action_params)))
    def compute_interactions(agents: Sequence[AbstractAgent]) -> None:
        """Applies interaction net and agent interaction functions.
        If a network is found with no interactions, an error is raised.
        """
        from logging import getLogger
        for (net, net_params), (interaction, interaction_params) in interactions:
            nparams = {k: v for k, v in net_params.items() if k != "name"}
            sets = net(agents, **nparams)
            if len(sets) == 0:
                raise NoInteractionsFound
            getLogger(__name__).info(
                f"Net {net_params['name']} of {len(sets)} interactions interacting "
                f"via {interaction_params['name']}"
            )
            iparams = {k: v for k, v in interaction_params.items() if k != "name"}
            for agents in sets:
                interaction(*agents, **iparams)
    return compute_interactions