@@ -842,12 +842,9 @@ def evaluate_pr_multiple(
842842) -> list [EvaluationResult ]:
843843 change_type = _classify_change_type (_bounded_diff_for_classification (diff ))
844844 runner = ComparisonRunner .from_environment (context , diff , model1 , model2 )
845- families = {_provider_family (provider ) for _ , provider , _ in runner .clients }
846- if len (runner .clients ) < 2 or len (families ) < 2 :
847- result = _fallback_evaluation (
848- "unverified: compare mode requires two cross-family verifier judges; "
849- f"available families: { ', ' .join (sorted (families )) or 'none' } ."
850- )
845+ is_valid , error_message = _validate_comparison_clients (runner .clients )
846+ if not is_valid :
847+ result = _fallback_evaluation (error_message )
851848 result .change_type = change_type
852849 return [result ]
853850 results : list [EvaluationResult ] = []
@@ -869,6 +866,47 @@ def _provider_family(provider: str) -> str:
869866 return label .split ("/" , 1 )[0 ].strip () or "unknown"
870867
871868
869+ def _get_provider_families (clients : list [tuple [object , str , str ]]) -> set [str ]:
870+ """Extract the set of unique provider families from a list of clients.
871+
872+ Args:
873+ clients: List of (client, provider, model) tuples.
874+
875+ Returns:
876+ Set of provider family names (e.g., {"openai", "anthropic"}).
877+ """
878+ return {_provider_family (provider ) for _ , provider , _ in clients }
879+
880+
881+ def _validate_comparison_clients (clients : list [tuple [object , str , str ]]) -> tuple [bool , str ]:
882+ """Validate that client list is sufficient for cross-family comparison.
883+
884+ Args:
885+ clients: List of (client, provider, model) tuples.
886+
887+ Returns:
888+ Tuple of (is_valid, error_message).
889+ is_valid is True if there are >= 2 clients from >= 2 different provider families.
890+ error_message describes the reason if validation fails.
891+ """
892+ families = _get_provider_families (clients )
893+ if len (clients ) < 2 :
894+ family_str = ", " .join (sorted (families )) or "none"
895+ return (
896+ False ,
897+ f"unverified: compare mode requires two cross-family verifier judges; "
898+ f"available families: { family_str } ." ,
899+ )
900+ if len (families ) < 2 :
901+ family_str = ", " .join (sorted (families )) or "none"
902+ return (
903+ False ,
904+ f"unverified: compare mode requires two cross-family verifier judges; "
905+ f"available families: { family_str } ." ,
906+ )
907+ return True , ""
908+
909+
872910def _normalize_text (text : str ) -> str :
873911 cleaned = re .sub (r"\s+" , " " , text .strip ().lower ())
874912 return cleaned
0 commit comments