77import json
88import os
99import threading
10- import warnings
1110from collections .abc import Coroutine
1211from dataclasses import dataclass
1312from importlib import metadata
1413from typing import Any , TypeVar
1514
16- from stackone_ai .constants import OAS_DIR
1715from stackone_ai .models import (
1816 ExecuteConfig ,
1917 ParameterLocation ,
2018 StackOneTool ,
2119 ToolParameters ,
2220 Tools ,
2321)
24- from stackone_ai .specs .parser import OpenAPIParser
2522
2623try :
2724 _SDK_VERSION = metadata .version ("stackone-ai" )
@@ -240,7 +237,7 @@ def __init__(
240237 Args:
241238 api_key: Optional API key. If not provided, will try to get from STACKONE_API_KEY env var
242239 account_id: Optional account ID
243- base_url: Optional base URL override for API requests. If not provided, uses the URL from the OAS
240+ base_url: Optional base URL override for API requests
244241
245242 Raises:
246243 ToolsetConfigError: If no API key is provided or found in environment
@@ -256,26 +253,6 @@ def __init__(
256253 self .base_url = base_url or DEFAULT_BASE_URL
257254 self ._account_ids : list [str ] = []
258255
259- def _parse_parameters (self , parameters : list [dict [str , Any ]]) -> dict [str , dict [str , str ]]:
260- """Parse OpenAPI parameters into tool properties
261-
262- Args:
263- parameters: List of OpenAPI parameter objects
264-
265- Returns:
266- Dict of parameter properties with name as key and schema details as value
267- """
268- properties : dict [str , dict [str , str ]] = {}
269- for param in parameters :
270- if param ["in" ] == "path" :
271- # Ensure we only include string values in the nested dict
272- param_schema = param ["schema" ]
273- properties [param ["name" ]] = {
274- "type" : str (param_schema ["type" ]),
275- "description" : str (param .get ("description" , "" )),
276- }
277- return properties
278-
279256 def _matches_filter (self , tool_name : str , filter_pattern : str | list [str ]) -> bool :
280257 """Check if a tool name matches the filter pattern
281258
@@ -465,83 +442,3 @@ def _normalize_schema_properties(self, schema: dict[str, Any]) -> dict[str, Any]
465442 normalized [str (name )] = prop
466443
467444 return normalized
468-
469- def get_tool (self , name : str , * , account_id : str | None = None ) -> StackOneTool | None :
470- """Get a specific tool by name
471-
472- Args:
473- name: Name of the tool to retrieve
474- account_id: Optional account ID override. If not provided, uses the one from initialization
475-
476- Returns:
477- The tool if found, None otherwise
478-
479- Raises:
480- ToolsetLoadError: If there is an error loading the tools
481- """
482- tools = self .get_tools (name , account_id = account_id )
483- return tools .get_tool (name )
484-
485- def get_tools (
486- self , filter_pattern : str | list [str ] | None = None , * , account_id : str | None = None
487- ) -> Tools :
488- """Get tools matching the specified filter pattern
489-
490- Args:
491- filter_pattern: Optional glob pattern or list of patterns to filter tools
492- (e.g. "hris_*", ["crm_*", "ats_*"])
493- account_id: Optional account ID override. If not provided, uses the one from initialization
494-
495- Returns:
496- Collection of tools matching the filter pattern
497-
498- Raises:
499- ToolsetLoadError: If there is an error loading the tools
500- """
501- if filter_pattern is None :
502- warnings .warn (
503- "No filter pattern provided. Loading all tools may exceed context windows in "
504- "AI applications." ,
505- UserWarning ,
506- stacklevel = 2 ,
507- )
508-
509- try :
510- all_tools : list [StackOneTool ] = []
511- effective_account_id = account_id or self .account_id
512-
513- # Load all available specs
514- for spec_file in OAS_DIR .glob ("*.json" ):
515- parser = OpenAPIParser (spec_file , base_url = self .base_url )
516- tool_definitions = parser .parse_tools ()
517-
518- # Create tools and filter if pattern is provided
519- for _ , tool_def in tool_definitions .items ():
520- if filter_pattern is None or self ._matches_filter (tool_def .execute .name , filter_pattern ):
521- tool = StackOneTool (
522- description = tool_def .description ,
523- parameters = tool_def .parameters ,
524- _execute_config = tool_def .execute ,
525- _api_key = self .api_key ,
526- _account_id = effective_account_id ,
527- )
528- all_tools .append (tool )
529-
530- # Add feedback collection meta tool
531- from .feedback import create_feedback_tool
532-
533- feedback_tool_name = "meta_collect_tool_feedback"
534- if filter_pattern is None or self ._matches_filter (feedback_tool_name , filter_pattern ):
535- feedback_tool = create_feedback_tool (
536- api_key = self .api_key ,
537- account_id = effective_account_id ,
538- base_url = self .base_url or "https://api.stackone.com" ,
539- )
540- all_tools .append (feedback_tool )
541-
542- return Tools (all_tools )
543-
544- except Exception as e :
545- if isinstance (e , ToolsetError ):
546- raise
547- raise ToolsetLoadError (f"Error loading tools: { e } " ) from e
0 commit comments