@@ -60,67 +60,78 @@ impl ProjectIndexer {
6060 let graph = CodeGraph :: new ( ) ?;
6161 #[ cfg( feature = "embeddings" ) ]
6262 let embedder = {
63- use codegraph_vector:: embeddings:: generator:: {
64- AdvancedEmbeddingGenerator , EmbeddingEngineConfig , LocalDeviceTypeCompat ,
65- LocalEmbeddingConfigCompat , LocalPoolingCompat ,
66- } ;
6763 use codegraph_vector:: EmbeddingGenerator ;
6864 // If local requested via env, override local config from CLI flags
6965 let provider = std:: env:: var ( "CODEGRAPH_EMBEDDING_PROVIDER" )
7066 . unwrap_or_default ( )
7167 . to_lowercase ( ) ;
7268 if provider == "local" {
73- let mut cfg = EmbeddingEngineConfig :: default ( ) ;
74- cfg. prefer_local_first = true ;
75- let device = match config
76- . device
77- . as_deref ( )
78- . unwrap_or ( "" )
79- . to_lowercase ( )
80- . as_str ( )
69+ #[ cfg( feature = "embeddings-local" ) ]
8170 {
82- "metal" => LocalDeviceTypeCompat :: Metal ,
83- d if d. starts_with ( "cuda:" ) => {
84- let id = d. trim_start_matches ( "cuda:" ) . parse :: < usize > ( ) . unwrap_or ( 0 ) ;
85- LocalDeviceTypeCompat :: Cuda ( id)
86- }
87- _ => LocalDeviceTypeCompat :: Cpu ,
88- } ;
89- let model_name = std:: env:: var ( "CODEGRAPH_LOCAL_MODEL" )
90- . unwrap_or_else ( |_| "sentence-transformers/all-MiniLM-L6-v2" . to_string ( ) ) ;
91- cfg. local = Some ( LocalEmbeddingConfigCompat {
92- model_name,
93- device,
94- cache_dir : None ,
95- max_sequence_length : config. max_seq_len . max ( 32 ) ,
96- pooling_strategy : LocalPoolingCompat :: Mean ,
97- } ) ;
98- // Try to construct advanced engine; fall back to simple generator on error
99- match AdvancedEmbeddingGenerator :: new ( cfg) . await {
100- Ok ( engine) => {
101- if !engine. has_provider ( ) {
71+ use codegraph_vector:: embeddings:: generator:: {
72+ AdvancedEmbeddingGenerator , EmbeddingEngineConfig , LocalDeviceTypeCompat ,
73+ LocalEmbeddingConfigCompat , LocalPoolingCompat ,
74+ } ;
75+ let mut cfg = EmbeddingEngineConfig :: default ( ) ;
76+ cfg. prefer_local_first = true ;
77+ let device = match config
78+ . device
79+ . as_deref ( )
80+ . unwrap_or ( "" )
81+ . to_lowercase ( )
82+ . as_str ( )
83+ {
84+ "metal" => LocalDeviceTypeCompat :: Metal ,
85+ d if d. starts_with ( "cuda:" ) => {
86+ let id = d. trim_start_matches ( "cuda:" ) . parse :: < usize > ( ) . unwrap_or ( 0 ) ;
87+ LocalDeviceTypeCompat :: Cuda ( id)
88+ }
89+ _ => LocalDeviceTypeCompat :: Cpu ,
90+ } ;
91+ let model_name = std:: env:: var ( "CODEGRAPH_LOCAL_MODEL" )
92+ . unwrap_or_else ( |_| "sentence-transformers/all-MiniLM-L6-v2" . to_string ( ) ) ;
93+ cfg. local = Some ( LocalEmbeddingConfigCompat {
94+ model_name,
95+ device,
96+ cache_dir : None ,
97+ max_sequence_length : config. max_seq_len . max ( 32 ) ,
98+ pooling_strategy : LocalPoolingCompat :: Mean ,
99+ } ) ;
100+ // Try to construct advanced engine; fall back to simple generator on error
101+ match AdvancedEmbeddingGenerator :: new ( cfg) . await {
102+ Ok ( engine) => {
103+ if !engine. has_provider ( ) {
104+ return Err ( anyhow:: anyhow!(
105+ "Local embedding provider constructed without a backend. Ensure the model is BERT-compatible with safetensors and try --device metal or --device cpu"
106+ ) ) ;
107+ }
108+ let mut g = EmbeddingGenerator :: default ( ) ;
109+ g. set_advanced_engine ( std:: sync:: Arc :: new ( engine) ) ;
110+ tracing:: info!(
111+ target: "codegraph_mcp::indexer" ,
112+ "Active embeddings: Local (device: {}, max_seq_len: {}, batch_size: {})" ,
113+ config. device. as_deref( ) . unwrap_or( "cpu" ) ,
114+ config. max_seq_len,
115+ config. batch_size
116+ ) ;
117+ g
118+ }
119+ Err ( e) => {
102120 return Err ( anyhow:: anyhow!(
103- "Local embedding provider constructed without a backend. Ensure the model is BERT-compatible with safetensors and try --device metal or --device cpu"
121+ "Failed to initialize local embedding provider: {}" ,
122+ e
104123 ) ) ;
105124 }
106- let mut g = EmbeddingGenerator :: default ( ) ;
107- g. set_advanced_engine ( std:: sync:: Arc :: new ( engine) ) ;
108- tracing:: info!(
109- target: "codegraph_mcp::indexer" ,
110- "Active embeddings: Local (device: {}, max_seq_len: {}, batch_size: {})" ,
111- config. device. as_deref( ) . unwrap_or( "cpu" ) ,
112- config. max_seq_len,
113- config. batch_size
114- ) ;
115- g
116- }
117- Err ( e) => {
118- return Err ( anyhow:: anyhow!(
119- "Failed to initialize local embedding provider: {}" ,
120- e
121- ) ) ;
122125 }
123126 }
127+ #[ cfg( not( feature = "embeddings-local" ) ) ]
128+ {
129+ tracing:: warn!(
130+ target: "codegraph_mcp::indexer" ,
131+ "CODEGRAPH_EMBEDDING_PROVIDER=local requested but the 'embeddings-local' feature is not enabled; using auto provider"
132+ ) ;
133+ EmbeddingGenerator :: with_auto_from_env ( ) . await
134+ }
124135 } else {
125136 let g = EmbeddingGenerator :: with_auto_from_env ( ) . await ;
126137 tracing:: info!(
0 commit comments