@@ -8,6 +8,8 @@ use std::time::Instant;
88use tracing:: { debug, info} ;
99use uuid:: Uuid ;
1010
11+ use crate :: services:: embedding:: model_state_label;
12+
1113use super :: meta_tool_common:: {
1214 build_installed_server_meta_maps, build_server_readiness_map, caller_resolution,
1315 is_query_empty, text_result,
@@ -141,6 +143,7 @@ impl MetaTool for SearchToolsTool {
141143
142144 let fingerprint = feature_set_ids_fingerprint ( & resolved. feature_set_ids ) ;
143145
146+ let server_id_set = server_id_filter. is_some ( ) ;
144147 info ! (
145148 query_id = %query_id,
146149 session_id = ?call. session_id,
@@ -150,15 +153,22 @@ impl MetaTool for SearchToolsTool {
150153 limit,
151154 is_browse,
152155 include_inactive,
156+ scope_all,
157+ server_id_set,
153158 "[search] call entry"
154159 ) ;
155160 if let Some ( query) = effective_query {
156161 debug ! ( query_id = %query_id, query, "[search] query text" ) ;
157162 }
158163
164+ let readiness_started = Instant :: now ( ) ;
159165 let readiness_map = build_server_readiness_map ( & call, & space_id, & resolved) . await ?;
166+ let readiness_ms = readiness_started. elapsed ( ) . as_millis ( ) as u64 ;
167+
168+ let installed_meta_started = Instant :: now ( ) ;
160169 let ( server_display_names, prefilled_params_by_server) =
161170 build_installed_server_meta_maps ( & call, & space_id) . await ?;
171+ let installed_meta_ms = installed_meta_started. elapsed ( ) . as_millis ( ) as u64 ;
162172
163173 let mut index_cache_hit = false ;
164174 let active_index_started = Instant :: now ( ) ;
@@ -255,10 +265,13 @@ impl MetaTool for SearchToolsTool {
255265 ) ;
256266 }
257267
258- let hydrate_ms = if effective_query. is_some ( ) {
259- hydrate_active_embeddings ( & call, query_id. as_str ( ) , active_index. as_slice ( ) ) . await ?
268+ let ( hydrate_ms, hydrated_missing_count) = if effective_query. is_some ( ) {
269+ let hydrate =
270+ hydrate_active_embeddings ( & call, query_id. as_str ( ) , active_index. as_slice ( ) )
271+ . await ?;
272+ ( hydrate. hydrate_ms , hydrate. hydrated_missing_count )
260273 } else {
261- 0
274+ ( 0 , 0 )
262275 } ;
263276
264277 let hybrid = effective_query. map ( |_| crate :: services:: tool_discovery:: SearchContext {
@@ -284,6 +297,8 @@ impl MetaTool for SearchToolsTool {
284297 is_browse,
285298 ) ;
286299 let rank_ms = rank_started. elapsed ( ) . as_millis ( ) as u64 ;
300+ // Prefer live model state so browse / lexical-only calls still report readiness.
301+ let embedding_state = model_state_label ( & call. ctx . embeddings . state ( ) ) ;
287302
288303 let top_qualified_name = result
289304 . tools
@@ -293,6 +308,8 @@ impl MetaTool for SearchToolsTool {
293308 . unwrap_or ( "" ) ;
294309
295310 let post_started = Instant :: now ( ) ;
311+ let mut zero_result_inactive_preview = false ;
312+ let mut zero_result_catalog_scan = false ;
296313 let mut payload = json ! ( {
297314 "tools" : result. tools,
298315 "next_cursor" : result. next_cursor,
@@ -310,7 +327,7 @@ impl MetaTool for SearchToolsTool {
310327 }
311328
312329 if !include_inactive && result. total == 0 && effective_query. is_some ( ) {
313- let inactive_started = Instant :: now ( ) ;
330+ zero_result_inactive_preview = true ;
314331 let inactive = call
315332 . ctx
316333 . feature_service
@@ -364,18 +381,17 @@ impl MetaTool for SearchToolsTool {
364381 the bindable_feature_set_id shown on each preview entry to activate them."
365382 ) ;
366383 }
367- inactive_widen_ms = inactive_started. elapsed ( ) . as_millis ( ) as u64 ;
368384 debug ! (
369385 query_id = %query_id,
370386 ready_inactive_preview = payload
371387 . get( "inactive_preview" )
372388 . and_then( |v| v. as_array( ) )
373389 . map( |a| a. len( ) )
374390 . unwrap_or( 0 ) ,
375- inactive_widen_ms,
376391 "[search] zero-result inactive preview"
377392 ) ;
378393 } else if include_inactive && result. total == 0 {
394+ zero_result_catalog_scan = true ;
379395 let catalog = call
380396 . ctx
381397 . tool_discovery
@@ -409,6 +425,8 @@ impl MetaTool for SearchToolsTool {
409425
410426 let total_ms = started. elapsed ( ) . as_millis ( ) as u64 ;
411427 let accounted_ms = resolve_ms
428+ + readiness_ms
429+ + installed_meta_ms
412430 + active_index_ms
413431 + index_clone_ms
414432 + inactive_widen_ms
@@ -423,21 +441,44 @@ impl MetaTool for SearchToolsTool {
423441 returned = result. tools. len( ) ,
424442 top_qualified_name,
425443 top_fused_score = ?result. top_fused_score,
444+ index_cache_hit,
445+ include_inactive,
446+ scope_all,
447+ server_id_set,
448+ inactive_tool_count,
449+ zero_result_inactive_preview,
450+ zero_result_catalog_scan,
451+ embedding_state,
452+ hydrated_missing_count,
426453 total_ms,
427454 "[search] result summary"
428455 ) ;
429456 info ! (
430457 query_id = %query_id,
431458 resolve_ms,
459+ readiness_ms,
460+ installed_meta_ms,
432461 active_index_ms,
462+ index_cache_hit,
433463 index_clone_ms,
434464 inactive_widen_ms,
435465 hydrate_ms,
466+ hydrated_missing_count,
436467 rank_ms,
468+ rank_lexical_ms = result. rank_lexical_ms,
469+ rank_embed_query_ms = result. rank_embed_query_ms,
470+ rank_semantic_ms = result. rank_semantic_ms,
471+ embedding_state,
437472 post_ms,
438473 accounted_ms,
439474 unaccounted_ms = total_ms. saturating_sub( accounted_ms) ,
440475 merged_index = index. len( ) ,
476+ include_inactive,
477+ scope_all,
478+ server_id_set,
479+ inactive_tool_count,
480+ zero_result_inactive_preview,
481+ zero_result_catalog_scan,
441482 "[search] timing breakdown"
442483 ) ;
443484
0 commit comments