getMethod('selectAnalysisProfile'); analysisRoutingExpect('qwen', $select->invoke(null), 'missing model defaults to qwen'); analysisRoutingExpect('qwen', $select->invoke(null, 'qwen'), 'qwen is selected exactly'); analysisRoutingExpect('openai', $select->invoke(null, 'openai'), 'openai is selected exactly'); foreach (['', 'QWEN', 'OpenAI', ' qwen', 'openai ', 'gpt-5.6-sol', 'provider=openai'] as $invalid) { analysisRoutingExpect(null, $select->invoke(null, $invalid), "rejects invalid model {$invalid}"); } $analysis = $reflection->getMethod('analysis'); $parameters = $analysis->getParameters(); analysisRoutingExpect('qwen', $parameters[3]->getDefaultValue(), 'legacy internal call defaults to qwen'); analysisRoutingExpect( null, DiagnosisAiLogic::analysis(7, 0, [], 'gpt-5.6-sol'), 'public business logic rejects model names before loading a diagnosis' ); analysisRoutingExpect( 'AI模型仅支持qwen或openai', DiagnosisAiLogic::getError(), 'business logic returns a fixed non-secret invalid-model error' ); echo "Diagnosis AI analysis model selection: OK\n";