@@ -713,6 +713,153 @@ describe("CodeIndexConfigManager", () => {
713713 const result = await configManager . loadConfiguration ( )
714714 expect ( result . requiresRestart ) . toBe ( false )
715715 } )
716+
717+ describe ( "currentSearchMinScore priority system" , ( ) => {
718+ it ( "should return user-configured score when set" , async ( ) => {
719+ mockContextProxy . getGlobalState . mockReturnValue ( {
720+ codebaseIndexEnabled : true ,
721+ codebaseIndexQdrantUrl : "http://qdrant.local" ,
722+ codebaseIndexEmbedderProvider : "openai" ,
723+ codebaseIndexEmbedderModelId : "text-embedding-3-small" ,
724+ codebaseIndexSearchMinScore : 0.8 , // User setting
725+ } )
726+ mockContextProxy . getSecret . mockImplementation ( ( key : string ) => {
727+ if ( key === "codeIndexOpenAiKey" ) return "test-key"
728+ return undefined
729+ } )
730+
731+ await configManager . loadConfiguration ( )
732+ expect ( configManager . currentSearchMinScore ) . toBe ( 0.8 )
733+ } )
734+
735+ it ( "should fall back to model-specific threshold when user setting is undefined" , async ( ) => {
736+ mockContextProxy . getGlobalState . mockReturnValue ( {
737+ codebaseIndexEnabled : true ,
738+ codebaseIndexQdrantUrl : "http://qdrant.local" ,
739+ codebaseIndexEmbedderProvider : "ollama" ,
740+ codebaseIndexEmbedderModelId : "nomic-embed-code" ,
741+ // No codebaseIndexSearchMinScore - user hasn't configured it
742+ } )
743+
744+ await configManager . loadConfiguration ( )
745+ // nomic-embed-code has a specific threshold of 0.15
746+ expect ( configManager . currentSearchMinScore ) . toBe ( 0.15 )
747+ } )
748+
749+ it ( "should fall back to default SEARCH_MIN_SCORE when neither user setting nor model threshold exists" , async ( ) => {
750+ mockContextProxy . getGlobalState . mockReturnValue ( {
751+ codebaseIndexEnabled : true ,
752+ codebaseIndexQdrantUrl : "http://qdrant.local" ,
753+ codebaseIndexEmbedderProvider : "openai" ,
754+ codebaseIndexEmbedderModelId : "unknown-model" , // Model not in profiles
755+ // No codebaseIndexSearchMinScore
756+ } )
757+ mockContextProxy . getSecret . mockImplementation ( ( key : string ) => {
758+ if ( key === "codeIndexOpenAiKey" ) return "test-key"
759+ return undefined
760+ } )
761+
762+ await configManager . loadConfiguration ( )
763+ // Should fall back to default SEARCH_MIN_SCORE (0.4)
764+ expect ( configManager . currentSearchMinScore ) . toBe ( 0.4 )
765+ } )
766+
767+ it ( "should respect user setting of 0 (edge case)" , async ( ) => {
768+ mockContextProxy . getGlobalState . mockReturnValue ( {
769+ codebaseIndexEnabled : true ,
770+ codebaseIndexQdrantUrl : "http://qdrant.local" ,
771+ codebaseIndexEmbedderProvider : "ollama" ,
772+ codebaseIndexEmbedderModelId : "nomic-embed-code" ,
773+ codebaseIndexSearchMinScore : 0 , // User explicitly sets 0
774+ } )
775+
776+ await configManager . loadConfiguration ( )
777+ // Should return 0, not fall back to model threshold (0.15)
778+ expect ( configManager . currentSearchMinScore ) . toBe ( 0 )
779+ } )
780+
781+ it ( "should use model-specific threshold with openai-compatible provider" , async ( ) => {
782+ mockContextProxy . getGlobalState . mockImplementation ( ( key : string ) => {
783+ if ( key === "codebaseIndexConfig" ) {
784+ return {
785+ codebaseIndexEnabled : true ,
786+ codebaseIndexQdrantUrl : "http://qdrant.local" ,
787+ codebaseIndexEmbedderProvider : "openai-compatible" ,
788+ codebaseIndexEmbedderModelId : "nomic-embed-code" ,
789+ // No codebaseIndexSearchMinScore
790+ }
791+ }
792+ if ( key === "codebaseIndexOpenAiCompatibleBaseUrl" ) return "https://api.example.com/v1"
793+ return undefined
794+ } )
795+ mockContextProxy . getSecret . mockImplementation ( ( key : string ) => {
796+ if ( key === "codebaseIndexOpenAiCompatibleApiKey" ) return "test-api-key"
797+ return undefined
798+ } )
799+
800+ await configManager . loadConfiguration ( )
801+ // openai-compatible provider also has nomic-embed-code with 0.15 threshold
802+ expect ( configManager . currentSearchMinScore ) . toBe ( 0.15 )
803+ } )
804+
805+ it ( "should use default model ID when modelId is not specified" , async ( ) => {
806+ mockContextProxy . getGlobalState . mockReturnValue ( {
807+ codebaseIndexEnabled : true ,
808+ codebaseIndexQdrantUrl : "http://qdrant.local" ,
809+ codebaseIndexEmbedderProvider : "openai" ,
810+ // No modelId specified
811+ // No codebaseIndexSearchMinScore
812+ } )
813+ mockContextProxy . getSecret . mockImplementation ( ( key : string ) => {
814+ if ( key === "codeIndexOpenAiKey" ) return "test-key"
815+ return undefined
816+ } )
817+
818+ await configManager . loadConfiguration ( )
819+ // Should use default model (text-embedding-3-small) threshold (0.4)
820+ expect ( configManager . currentSearchMinScore ) . toBe ( 0.4 )
821+ } )
822+
823+ it ( "should handle priority correctly: user > model > default" , async ( ) => {
824+ // Test 1: User setting takes precedence
825+ mockContextProxy . getGlobalState . mockReturnValue ( {
826+ codebaseIndexEnabled : true ,
827+ codebaseIndexQdrantUrl : "http://qdrant.local" ,
828+ codebaseIndexEmbedderProvider : "ollama" ,
829+ codebaseIndexEmbedderModelId : "nomic-embed-code" , // Has 0.15 threshold
830+ codebaseIndexSearchMinScore : 0.9 , // User overrides
831+ } )
832+
833+ await configManager . loadConfiguration ( )
834+ expect ( configManager . currentSearchMinScore ) . toBe ( 0.9 ) // User setting wins
835+
836+ // Test 2: Model threshold when no user setting
837+ mockContextProxy . getGlobalState . mockReturnValue ( {
838+ codebaseIndexEnabled : true ,
839+ codebaseIndexQdrantUrl : "http://qdrant.local" ,
840+ codebaseIndexEmbedderProvider : "ollama" ,
841+ codebaseIndexEmbedderModelId : "nomic-embed-code" ,
842+ // No user setting
843+ } )
844+
845+ const newManager = new CodeIndexConfigManager ( mockContextProxy )
846+ await newManager . loadConfiguration ( )
847+ expect ( newManager . currentSearchMinScore ) . toBe ( 0.15 ) // Model threshold
848+
849+ // Test 3: Default when neither exists
850+ mockContextProxy . getGlobalState . mockReturnValue ( {
851+ codebaseIndexEnabled : true ,
852+ codebaseIndexQdrantUrl : "http://qdrant.local" ,
853+ codebaseIndexEmbedderProvider : "openai" ,
854+ codebaseIndexEmbedderModelId : "custom-unknown-model" ,
855+ // No user setting, unknown model
856+ } )
857+
858+ const anotherManager = new CodeIndexConfigManager ( mockContextProxy )
859+ await anotherManager . loadConfiguration ( )
860+ expect ( anotherManager . currentSearchMinScore ) . toBe ( 0.4 ) // Default
861+ } )
862+ } )
716863 } )
717864
718865 describe ( "empty/missing API key handling" , ( ) => {
0 commit comments