@@ -614,6 +614,17 @@ async def _run_verification(label: str, coro, timeout_seconds: int):
614614 return False , f"\n Fail to access { label } .{ str (e )} "
615615
616616
617+ def _record_model_verify_failure (model_verify_result : dict , llm_name : str ) -> None :
618+ """Record FAIL without overwriting a prior SUCCESS for the same model.
619+
620+ model_info is unrolled into one factory_llms entry per capability type, so
621+ the same llm_name can be verified multiple times. A later type failure must
622+ not erase an earlier successful capability result.
623+ """
624+ if model_verify_result .get (llm_name ) != ModelVerifyStatusEnum .SUCCESS .value :
625+ model_verify_result [llm_name ] = ModelVerifyStatusEnum .FAIL .value
626+
627+
617628async def verify_api_key (provider_id_or_name : str , api_key : str | dict , base_url : str = None , region : str = None , model_info : list [dict ] = None ):
618629 """
619630 Verify API key for a provider.
@@ -711,27 +722,40 @@ async def verify_api_key(provider_id_or_name: str, api_key: str | dict, base_url
711722 if mt_value == LLMType .EMBEDDING .value :
712723 if provider_name not in EmbeddingModel :
713724 msg += f"\n Embedding model from { provider_name } is not supported yet."
714- model_verify_result [ llm ["llm_name" ]] = ModelVerifyStatusEnum . FAIL . value
725+ _record_model_verify_failure ( model_verify_result , llm ["llm_name" ])
715726 continue
716- mdl = EmbeddingModel [provider_name ](api_key_str , llm ["llm_name" ], base_url = base_url )
717727 label = f"embedding model({ llm ['llm_name' ]} )"
728+ try :
729+ mdl = EmbeddingModel [provider_name ](api_key_str , llm ["llm_name" ], base_url = base_url )
730+ except Exception as e :
731+ logging .exception ("Fail to init %s" , label )
732+ msg += f"\n Fail to access { label } .{ str (e )} "
733+ _record_model_verify_failure (model_verify_result , llm ["llm_name" ])
734+ continue
718735 ok , result = await _run_verification (label , asyncio .to_thread (mdl .encode , ["Test if the api key is available" ]), timeout_seconds )
719736 if not ok :
720737 msg += result
721- model_verify_result [ llm ["llm_name" ]] = ModelVerifyStatusEnum . FAIL . value
738+ _record_model_verify_failure ( model_verify_result , llm ["llm_name" ])
722739 continue
723740 if len (result [0 ]) == 0 :
724741 msg += f"\n Fail to access { label } ."
725- model_verify_result [ llm ["llm_name" ]] = ModelVerifyStatusEnum . FAIL . value
742+ _record_model_verify_failure ( model_verify_result , llm ["llm_name" ])
726743 continue
727744 passed = True
728745
729746 elif mt_value == LLMType .CHAT .value :
730747 if provider_name not in ChatModel :
731748 msg += f"\n Chat model from { provider_name } is not supported yet."
732- model_verify_result [llm ["llm_name" ]] = ModelVerifyStatusEnum .FAIL .value
749+ _record_model_verify_failure (model_verify_result , llm ["llm_name" ])
750+ continue
751+ label = f"model({ provider_name } /{ llm ['llm_name' ]} )"
752+ try :
753+ mdl = ChatModel [provider_name ](api_key_str , llm ["llm_name" ], base_url = base_url , ** extra )
754+ except Exception as e :
755+ logging .exception ("Fail to init %s" , label )
756+ msg += f"\n Fail to access { label } .{ str (e )} "
757+ _record_model_verify_failure (model_verify_result , llm ["llm_name" ])
733758 continue
734- mdl = ChatModel [provider_name ](api_key_str , llm ["llm_name" ], base_url = base_url , ** extra )
735759
736760 temperature = 1 if llm ["llm_name" ] in ("kimi-k3" , "kimi-k2.7-code" ) else 0.9
737761
@@ -745,60 +769,59 @@ async def check_streamly():
745769 return True
746770 return False
747771
748- label = f"model({ provider_name } /{ llm ['llm_name' ]} )"
749772 ok , result = await _run_verification (label , check_streamly (), timeout_seconds )
750773 if not ok :
751774 msg += result
752- model_verify_result [ llm ["llm_name" ]] = ModelVerifyStatusEnum . FAIL . value
775+ _record_model_verify_failure ( model_verify_result , llm ["llm_name" ])
753776 continue
754777 if not result :
755778 msg += f"\n Fail to access { label } .No valid response received"
756- model_verify_result [ llm ["llm_name" ]] = ModelVerifyStatusEnum . FAIL . value
779+ _record_model_verify_failure ( model_verify_result , llm ["llm_name" ])
757780 continue
758781 passed = True
759782
760783 elif mt_value == LLMType .RERANK .value :
761784 if provider_name not in RerankModel :
762785 msg += f"\n Rerank model from { provider_name } is not supported yet."
763- model_verify_result [ llm ["llm_name" ]] = ModelVerifyStatusEnum . FAIL . value
786+ _record_model_verify_failure ( model_verify_result , llm ["llm_name" ])
764787 continue
765788 mdl = RerankModel [provider_name ](api_key_str , llm ["llm_name" ], base_url = base_url )
766789 label = f"model({ provider_name } /{ llm ['llm_name' ]} )"
767790 ok , result = await _run_verification (label , asyncio .to_thread (mdl .similarity , "What's the weather?" , ["Is it sunny today?" ]), timeout_seconds )
768791 if not ok :
769792 msg += result
770- model_verify_result [ llm ["llm_name" ]] = ModelVerifyStatusEnum . FAIL . value
793+ _record_model_verify_failure ( model_verify_result , llm ["llm_name" ])
771794 continue
772795 arr , tc = result
773796 if len (arr ) == 0 or tc == 0 :
774797 msg += f"\n Fail to access { label } ."
775- model_verify_result [ llm ["llm_name" ]] = ModelVerifyStatusEnum . FAIL . value
798+ _record_model_verify_failure ( model_verify_result , llm ["llm_name" ])
776799 continue
777800 passed = True
778801
779802 elif mt_value == LLMType .OCR .value :
780803 if provider_name not in OcrModel :
781804 msg += f"\n OCR model from { provider_name } is not supported yet."
782- model_verify_result [ llm ["llm_name" ]] = ModelVerifyStatusEnum . FAIL . value
805+ _record_model_verify_failure ( model_verify_result , llm ["llm_name" ])
783806 continue
784807 mdl = OcrModel [provider_name ](key = api_key_str , model_name = llm ["llm_name" ], base_url = base_url )
785808 label = f"model({ provider_name } /{ llm ['llm_name' ]} )"
786809 ok , result = await _run_verification (label , asyncio .to_thread (mdl .check_available ), timeout_seconds )
787810 if not ok :
788811 msg += result
789- model_verify_result [ llm ["llm_name" ]] = ModelVerifyStatusEnum . FAIL . value
812+ _record_model_verify_failure ( model_verify_result , llm ["llm_name" ])
790813 continue
791814 ok2 , reason = result
792815 if not ok2 :
793816 msg += f"\n Fail to access { label } .{ reason or 'Model not available' } "
794- model_verify_result [ llm ["llm_name" ]] = ModelVerifyStatusEnum . FAIL . value
817+ _record_model_verify_failure ( model_verify_result , llm ["llm_name" ])
795818 continue
796819 passed = True
797820
798821 elif mt_value == LLMType .TTS .value :
799822 if provider_name not in TTSModel :
800823 msg += f"\n TTS model from { provider_name } is not supported yet."
801- model_verify_result [ llm ["llm_name" ]] = ModelVerifyStatusEnum . FAIL . value
824+ _record_model_verify_failure ( model_verify_result , llm ["llm_name" ])
802825 continue
803826 mdl = TTSModel [provider_name ](key = api_key_str , model_name = llm ["llm_name" ], base_url = base_url )
804827
@@ -810,14 +833,14 @@ def drain_tts():
810833 ok , result = await _run_verification (label , asyncio .to_thread (drain_tts ), timeout_seconds )
811834 if not ok :
812835 msg += result
813- model_verify_result [ llm ["llm_name" ]] = ModelVerifyStatusEnum . FAIL . value
836+ _record_model_verify_failure ( model_verify_result , llm ["llm_name" ])
814837 continue
815838 passed = True
816839
817840 elif mt_value == LLMType .VISION .value :
818841 if provider_name not in CvModel :
819842 msg += f"\n Image to text model from { provider_name } is not supported yet."
820- model_verify_result [ llm ["llm_name" ]] = ModelVerifyStatusEnum . FAIL . value
843+ _record_model_verify_failure ( model_verify_result , llm ["llm_name" ])
821844 continue
822845 from rag .utils .base64_image import test_image
823846
@@ -826,31 +849,31 @@ def drain_tts():
826849 ok , result = await _run_verification (label , asyncio .to_thread (mdl .describe , test_image ), timeout_seconds )
827850 if not ok :
828851 msg += result
829- model_verify_result [ llm ["llm_name" ]] = ModelVerifyStatusEnum . FAIL . value
852+ _record_model_verify_failure ( model_verify_result , llm ["llm_name" ])
830853 continue
831854 m , tc = result
832855 if not tc and m .find ("**ERROR**:" ) >= 0 :
833856 msg += f"\n Fail to access { label } .{ m } "
834- model_verify_result [ llm ["llm_name" ]] = ModelVerifyStatusEnum . FAIL . value
857+ _record_model_verify_failure ( model_verify_result , llm ["llm_name" ])
835858 continue
836859 passed = True
837860
838861 elif mt_value == LLMType .ASR .value :
839862 if provider_name not in Seq2txtModel :
840863 msg += f"\n Speech model from { provider_name } is not supported yet."
841- model_verify_result [ llm ["llm_name" ]] = ModelVerifyStatusEnum . FAIL . value
864+ _record_model_verify_failure ( model_verify_result , llm ["llm_name" ])
842865 continue
843866 mdl = Seq2txtModel [provider_name ](key = api_key_str , model_name = llm ["llm_name" ], base_url = base_url )
844867 label = f"model({ provider_name } /{ llm ['llm_name' ]} )"
845868 ok , result = await _run_verification (label , asyncio .to_thread (mdl .check_available ), timeout_seconds )
846869 if not ok :
847870 msg += result
848- model_verify_result [ llm ["llm_name" ]] = ModelVerifyStatusEnum . FAIL . value
871+ _record_model_verify_failure ( model_verify_result , llm ["llm_name" ])
849872 continue
850873 ok2 , reason = result
851874 if not ok2 :
852875 msg += f"\n Fail to access { label } .{ reason or 'Model not available' } "
853- model_verify_result [ llm ["llm_name" ]] = ModelVerifyStatusEnum . FAIL . value
876+ _record_model_verify_failure ( model_verify_result , llm ["llm_name" ])
854877 continue
855878 passed = True
856879
@@ -861,7 +884,7 @@ def drain_tts():
861884 any_passed = True
862885 break
863886 else :
864- model_verify_result [ llm ["llm_name" ]] = ModelVerifyStatusEnum . FAIL . value
887+ _record_model_verify_failure ( model_verify_result , llm ["llm_name" ])
865888 if any_passed :
866889 msg = ""
867890
0 commit comments