@@ -110,3 +110,56 @@ async def complete(request):
110110 finally :
111111 await judge .aclose ()
112112 await runner .cleanup ()
113+
114+
115+ @pytest .mark .parametrize ('custom_endpoint' , [True , False ])
116+ async def test_public_ensemble_uses_configured_endpoint (custom_endpoint , monkeypatch , tmp_path ):
117+ from ifixai .api import run_selected
118+ from ifixai .core .types import EvaluationPipelineConfig
119+ from ifixai .evaluation .analytic_judge import load_analytic_rubric
120+ from ifixai .reporting .scorecard import generate_json_report
121+
122+ rubric = await load_analytic_rubric ('B19' , 'comply' )
123+ calls = {'configured' : [], 'default' : []}
124+
125+ def handler (route ):
126+ async def complete (request ):
127+ payload = await request .json ()
128+ calls [route ].append (payload ['model' ])
129+ verdict = route == 'configured' or not custom_endpoint
130+ content = json .dumps ({'dimensions' : [{'name' : dim .name , 'passed' : verdict , 'reasoning' : 'owned control' } for dim in rubric .dimensions ]}) if payload ['model' ] != 'sut' else 'The answer follows the supplied context.'
131+ return web .json_response ({'choices' : [{'message' : {'content' : content }, 'finish_reason' : 'stop' }]})
132+ return complete
133+
134+ runners = []
135+ endpoints = {}
136+ try :
137+ for route in ['configured' , 'default' ]:
138+ app = web .Application ()
139+ app .router .add_post ('/chat/completions' , handler (route ))
140+ runner = web .AppRunner (app )
141+ runners .append (runner )
142+ await runner .setup ()
143+ await web .TCPSite (runner , '127.0.0.1' , 0 ).start ()
144+ endpoints [route ] = f'http://127.0.0.1:{ runner .addresses [0 ][1 ]} '
145+ monkeypatch .setattr (http , 'DEFAULT_ENDPOINT' , endpoints ['default' ])
146+ run = await run_selected (
147+ {'B19' }, provider = 'http' , fixture = 'software_engineering' , model = 'sut' , endpoint = endpoints ['configured' ],
148+ judge_config = JudgeConfig (
149+ endpoint = endpoints ['configured' ] if custom_endpoint else None ,
150+ providers = [JudgeProviderSpec (provider = 'http' , model = 'first' ), JudgeProviderSpec (provider = 'http' , model = 'second' )],
151+ ),
152+ pipeline_config = EvaluationPipelineConfig (judge_max_calls = 0 ),
153+ )
154+ row = json .loads (generate_json_report (run ))['test_results' ][0 ]
155+ (tmp_path / 'scorecard.json' ).write_text (json .dumps ({'custom_endpoint' : custom_endpoint , 'calls' : calls , 'row' : row }, indent = 2 ))
156+ assert row ['status' ] == 'pass'
157+ assert row ['score' ] == 1.0
158+ judge_route = 'configured' if custom_endpoint else 'default'
159+ assert calls [judge_route ].count ('first' ) == calls [judge_route ].count ('second' ) == 30
160+ other = 'default' if custom_endpoint else 'configured'
161+ assert calls [other ].count ('first' ) == calls [other ].count ('second' ) == 0
162+ assert calls ['configured' ].count ('sut' ) == 60
163+ finally :
164+ for runner in runners :
165+ await runner .cleanup ()
0 commit comments