@@ -923,6 +923,99 @@ def _fetch_agent_config_dict(
923923 )
924924
925925
926+ def _resolve_interactions_for_display (
927+ api_client : BaseApiClient ,
928+ dataset_list : list [types .EvaluationDataset ],
929+ ) -> list [types .EvaluationDataset ]:
930+ """Resolves interactions_data_source on EvalCases for display.
931+
932+ For each EvalCase that has ``interactions_data_source`` set but no
933+ ``agent_data``, fetches the Interaction and Agent config from the
934+ API, converts to AgentData, and populates it on the EvalCase so
935+ that ``show()`` can render the System Topology and Conversation
936+ Trace sections.
937+
938+ Args:
939+ api_client: The API client used to fetch interactions and agents.
940+ dataset_list: The original evaluation datasets.
941+
942+ Returns:
943+ A list of EvaluationDatasets with agent_data populated from
944+ resolved interactions.
945+ """
946+ resolved_datasets = []
947+ for dataset in dataset_list :
948+ if not dataset .eval_cases :
949+ resolved_datasets .append (dataset )
950+ continue
951+
952+ resolved_cases = []
953+ any_resolved = False
954+ for case in dataset .eval_cases :
955+ ids = case .interactions_data_source
956+ if ids and not case .agent_data :
957+ interaction_name = ids .interaction
958+ gemini_cfg = ids .gemini_agent_config
959+ agent_name = gemini_cfg .gemini_agent if gemini_cfg else None
960+
961+ if interaction_name :
962+ try :
963+ # Extract the interaction short ID from the resource
964+ # name; handles both full resource names and bare IDs.
965+ interaction_id = interaction_name .split ("/" )[- 1 ]
966+
967+ logger .info (
968+ "Fetching interaction %s for display." ,
969+ interaction_name ,
970+ )
971+ path = f"interactions/{ interaction_id } "
972+ response = api_client .request ("get" , path , {}, None )
973+ if not response .body :
974+ logger .warning (
975+ "Empty response fetching interaction %s." ,
976+ interaction_name ,
977+ )
978+ resolved_cases .append (case )
979+ continue
980+ interaction_dict = json .loads (response .body )
981+
982+ agent_data = _interaction_dict_to_agent_data (interaction_dict )
983+
984+ # Best-effort: fetch agent config (instruction,
985+ # tools, description) from the Agent API.
986+ agent_config = _fetch_agent_config_dict (
987+ api_client , agent_name or ""
988+ )
989+ agent_data .agents = {agent_config .agent_id : agent_config }
990+
991+ _merge_text_parts_in_agent_data (agent_data )
992+
993+ # Preserve all original EvalCase fields; only
994+ # update agent_data.
995+ resolved_cases .append (
996+ case .model_copy (update = {"agent_data" : agent_data })
997+ )
998+ any_resolved = True
999+ continue
1000+ except Exception as e : # pylint: disable=broad-exception-caught
1001+ logger .warning (
1002+ "Failed to resolve interaction %s for display: %s" ,
1003+ interaction_name ,
1004+ e ,
1005+ )
1006+
1007+ resolved_cases .append (case )
1008+
1009+ if any_resolved :
1010+ resolved_datasets .append (
1011+ dataset .model_copy (update = {"eval_cases" : resolved_cases })
1012+ )
1013+ else :
1014+ resolved_datasets .append (dataset )
1015+
1016+ return resolved_datasets
1017+
1018+
9261019def _add_evaluation_run_labels (
9271020 labels : Optional [dict [str , str ]] = None ,
9281021 agent : Optional [str ] = None ,
@@ -2245,6 +2338,11 @@ def _execute_evaluation( # type: ignore[no-untyped-def]
22452338 t2 = time .perf_counter ()
22462339 logger .info ("Evaluation took: %f seconds" , t2 - t1 )
22472340
2341+ # Resolve interactions_data_source to agent_data for display.
2342+ # This fetches Interaction trace data client-side so that show() can
2343+ # render the System Topology and Conversation Trace sections.
2344+ dataset_list = _resolve_interactions_for_display (api_client , dataset_list )
2345+
22482346 evaluation_result .evaluation_dataset = dataset_list
22492347 evaluation_result .agent_info = validated_agent_info
22502348
0 commit comments