@@ -469,14 +469,19 @@ def get_account_id(self) -> str | None:
469469class Tools :
470470 """Container for Tool instances with lookup capabilities"""
471471
472- def __init__ (self , tools : list [StackOneTool ]) -> None :
472+ def __init__ (
473+ self ,
474+ tools : list [StackOneTool ],
475+ _semantic_client : SemanticSearchClient | None = None ,
476+ ) -> None :
473477 """Initialize Tools container
474478
475479 Args:
476480 tools: List of Tool instances to manage
477481 """
478482 self .tools = tools
479483 self ._tool_map = {tool .name : tool for tool in tools }
484+ self ._semantic_client = _semantic_client
480485
481486 def __getitem__ (self , index : int ) -> StackOneTool :
482487 return self .tools [index ]
@@ -559,58 +564,69 @@ def to_langchain(self) -> Sequence[BaseTool]:
559564
560565 def utility_tools (
561566 self ,
567+ search_method : str = "bm25" ,
562568 hybrid_alpha : float | None = None ,
563- semantic_client : SemanticSearchClient | None = None ,
564569 ) -> UtilityTools :
565570 """Return utility tools for tool discovery and execution
566571
567572 Utility tools enable dynamic tool discovery and execution based on natural language queries.
568- By default, uses local hybrid BM25 + TF-IDF search. When a semantic_client is provided,
569- uses cloud-based semantic search for higher accuracy on natural language queries.
573+ Choose the search method via ``search_method``:
574+
575+ - ``"bm25"`` (default) — local hybrid BM25 + TF-IDF search, no network calls.
576+ - ``"semantic"`` — cloud-based semantic vector search for higher accuracy on
577+ natural language queries. Requires tools fetched via ``StackOneToolSet``.
570578
571579 Args:
580+ search_method: Search backend to use. ``"bm25"`` for local search,
581+ ``"semantic"`` for cloud-based semantic search.
572582 hybrid_alpha: Weight for BM25 in hybrid search (0-1). Only used when
573- semantic_client is not provided. If not provided, uses DEFAULT_HYBRID_ALPHA (0.2),
574- which gives more weight to BM25 scoring.
575- semantic_client: Optional SemanticSearchClient instance. Pass
576- toolset.semantic_client to enable cloud-based semantic search.
583+ search_method is ``"bm25"``. If not provided, uses DEFAULT_HYBRID_ALPHA (0.2).
577584
578585 Returns:
579586 UtilityTools collection with search_tool and execute_tool accessors
580587
588+ Raises:
589+ StackOneError: If ``search_method="semantic"`` but tools were not created
590+ via ``StackOneToolSet`` (no semantic client available).
591+ ValueError: If ``search_method`` is not ``"bm25"`` or ``"semantic"``.
592+
581593 Note:
582594 This feature is in beta and may change in future versions
583595
584596 Example:
585- # Semantic search (pass semantic_client explicitly)
597+ # Semantic search
586598 toolset = StackOneToolSet()
587599 tools = toolset.fetch_tools()
588- utility = tools.utility_tools(semantic_client=toolset.semantic_client )
600+ utility = tools.utility_tools(search_method="semantic" )
589601 result = utility.search_tool.call(query="onboard new hire")
590602
591- # Local BM25+TF-IDF search (default, no semantic_client )
603+ # Local BM25+TF-IDF search (default)
592604 utility = tools.utility_tools()
593605 result = utility.search_tool.call(query="onboard new hire")
594606 """
595607 from stackone_ai .utility_tools import create_tool_execute
596608
597- if semantic_client is not None :
609+ if search_method == "semantic" :
610+ if self ._semantic_client is None :
611+ raise StackOneError (
612+ "Semantic search requires tools fetched via StackOneToolSet. "
613+ "Use toolset.fetch_tools() or toolset.search_tools() first."
614+ )
598615 from stackone_ai .utility_tools import create_semantic_tool_search
599616
600617 search_tool = create_semantic_tool_search (
601- semantic_client , available_connectors = self .get_connectors ()
618+ self . _semantic_client , available_connectors = self .get_connectors ()
602619 )
603- execute_tool = create_tool_execute ( self )
604- return UtilityTools ([ search_tool , execute_tool ])
620+ elif search_method == "bm25" :
621+ from stackone_ai . utility_tools import ToolIndex , create_tool_search
605622
606- # Default: local BM25+TF-IDF search
607- from stackone_ai .utility_tools import ToolIndex , create_tool_search
623+ index = ToolIndex (self .tools , hybrid_alpha = hybrid_alpha )
624+ search_tool = create_tool_search (index )
625+ else :
626+ raise ValueError (f"Unknown search_method: { search_method !r} . Use 'bm25' or 'semantic'." )
608627
609- index = ToolIndex (self .tools , hybrid_alpha = hybrid_alpha )
610- filter_tool = create_tool_search (index )
611628 execute_tool = create_tool_execute (self )
612-
613- return UtilityTools ([filter_tool , execute_tool ])
629+ return UtilityTools ([search_tool , execute_tool ])
614630
615631
616632class UtilityTools (Tools ):
0 commit comments