From 1f323aed5369f6137b31d826c0f566eb8e8f8146 Mon Sep 17 00:00:00 2001 From: cameron-carlin Date: Fri, 22 May 2026 10:01:08 +0100 Subject: [PATCH 1/2] fix(search): make ToolsetConfigError actionable and fix misleading docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The "Search is disabled" error pointed users at the right cause but didn't show the exact fix. Updated all 4 raise sites to suggest search={} or search={"method": "auto"} on the StackOneToolSet constructor. Also corrected 3 README examples and 3 docstring examples that called StackOneToolSet() with no args before invoking search APIs — every one of those would have raised the same error at runtime. No behavior change; default remains search=None (disabled). Co-Authored-By: Claude Opus 4.7 (1M context) --- README.md | 13 +++++++++---- stackone_ai/toolset.py | 21 +++++++++++++-------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 078ab63..a152edf 100644 --- a/README.md +++ b/README.md @@ -228,7 +228,10 @@ For the full catalog (or the meta search/execute tools), use the `.pydantic_ai() ```python toolset = StackOneToolSet() tools = toolset.pydantic_ai(account_ids=[os.environ["STACKONE_ACCOUNT_ID"]]) -# or pydantic_ai(mode="search_and_execute") for agent-driven discovery + +# For agent-driven discovery, enable search on the constructor: +# toolset = StackOneToolSet(search={"method": "auto"}) +# tools = toolset.pydantic_ai(mode="search_and_execute") ``` @@ -360,8 +363,8 @@ Search for tools using natural language queries. Works with both semantic (cloud ```python import os -# Get a callable search tool -toolset = StackOneToolSet() +# Get a callable search tool — search must be enabled on the toolset +toolset = StackOneToolSet(search={"method": "auto"}) account_id = os.getenv("STACKONE_ACCOUNT_ID") all_tools = toolset.fetch_tools(account_ids=[account_id]) search_tool = toolset.get_search_tool() @@ -381,7 +384,9 @@ Discover tools using natural language instead of exact names. Queries like "onbo import os from stackone_ai import StackOneToolSet -toolset = StackOneToolSet() +# Search must be enabled on the constructor — pass `search={}` for defaults, +# or set a backend / top_k explicitly. +toolset = StackOneToolSet(search={"method": "auto"}) # Search by intent — returns Tools collection ready for any framework account_id = os.getenv("STACKONE_ACCOUNT_ID") diff --git a/stackone_ai/toolset.py b/stackone_ai/toolset.py index 58caf60..6a204ed 100644 --- a/stackone_ai/toolset.py +++ b/stackone_ai/toolset.py @@ -645,13 +645,14 @@ def get_search_tool(self, *, search: SearchMode | None = None) -> SearchTool: Example:: - toolset = StackOneToolSet() + toolset = StackOneToolSet(search={"method": "auto"}) search_tool = toolset.get_search_tool() tools = search_tool("manage employee records", account_ids=["acc-123"]) """ if self._search_config is None: raise ToolsetConfigError( - "Search is disabled. Initialize StackOneToolSet with a search config to enable." + "Search is disabled. Pass search={} (or search={'method': 'auto'}) to " + "StackOneToolSet(...) to enable. See README 'Search Tools' for options." ) config: SearchConfig = {**self._search_config} @@ -664,7 +665,8 @@ def _build_tools(self, account_ids: list[str] | None = None) -> Tools: """Build tool_search + tool_execute tools scoped to this toolset.""" if self._search_config is None: raise ToolsetConfigError( - "Search is disabled. Initialize StackOneToolSet with a search config to enable." + "Search is disabled. Pass search={} (or search={'method': 'auto'}) to " + "StackOneToolSet(...) to enable. See README 'Search Tools' for options." ) if account_ids: @@ -713,8 +715,8 @@ def openai( toolset = StackOneToolSet() tools = toolset.openai() - # Meta tools for agent-driven discovery - toolset = StackOneToolSet() + # Meta tools for agent-driven discovery — search must be enabled + toolset = StackOneToolSet(search={"method": "auto"}) tools = toolset.openai(mode="search_and_execute") """ effective_account_ids = account_ids or ( @@ -783,7 +785,8 @@ def pydantic_ai( tools = toolset.pydantic_ai() agent = Agent("openai:gpt-5.4", tools=tools) - # Meta tools for agent-driven discovery + # Meta tools for agent-driven discovery — search must be enabled + toolset = StackOneToolSet(search={"method": "auto"}) tools = toolset.pydantic_ai(mode="search_and_execute") """ effective_account_ids = account_ids or ( @@ -929,7 +932,8 @@ def search_tools( """ if self._search_config is None: raise ToolsetConfigError( - "Search is disabled. Initialize StackOneToolSet with a search config to enable." + "Search is disabled. Pass search={} (or search={'method': 'auto'}) to " + "StackOneToolSet(...) to enable. See README 'Search Tools' for options." ) # Merge constructor defaults with per-call overrides @@ -1082,7 +1086,8 @@ def search_action_names( """ if self._search_config is None: raise ToolsetConfigError( - "Search is disabled. Initialize StackOneToolSet with search config to enable." + "Search is disabled. Pass search={} (or search={'method': 'auto'}) to " + "StackOneToolSet(...) to enable. See README 'Search Tools' for options." ) # Merge constructor defaults with per-call overrides From 1b7a8c64c98fec8861b64b6f29bff84eb22a84e2 Mon Sep 17 00:00:00 2001 From: cameron-carlin Date: Fri, 22 May 2026 10:09:17 +0100 Subject: [PATCH 2/2] fix(search): align error reference and fix Basic Usage snippet - Error message now references README section 'Search Tool' (singular), matching the actual heading at README.md:357. - Basic Usage snippet: add missing StackOneToolSet import, drop the unused fetch_tools line, and pass account_ids on the search call so the snippet runs as written. Addresses Copilot review on #188. Co-Authored-By: Claude Opus 4.7 (1M context) --- README.md | 6 +++--- stackone_ai/toolset.py | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index a152edf..d60cb62 100644 --- a/README.md +++ b/README.md @@ -362,15 +362,15 @@ Search for tools using natural language queries. Works with both semantic (cloud ```python import os +from stackone_ai import StackOneToolSet # Get a callable search tool — search must be enabled on the toolset toolset = StackOneToolSet(search={"method": "auto"}) account_id = os.getenv("STACKONE_ACCOUNT_ID") -all_tools = toolset.fetch_tools(account_ids=[account_id]) search_tool = toolset.get_search_tool() -# Search for relevant tools — returns a Tools collection -tools = search_tool("manage employees", top_k=5) +# Search for relevant tools — returns a Tools collection scoped to the account +tools = search_tool("manage employees", top_k=5, account_ids=[account_id]) # Execute a discovered tool directly tools[0](limit=10) diff --git a/stackone_ai/toolset.py b/stackone_ai/toolset.py index 6a204ed..fef9198 100644 --- a/stackone_ai/toolset.py +++ b/stackone_ai/toolset.py @@ -652,7 +652,7 @@ def get_search_tool(self, *, search: SearchMode | None = None) -> SearchTool: if self._search_config is None: raise ToolsetConfigError( "Search is disabled. Pass search={} (or search={'method': 'auto'}) to " - "StackOneToolSet(...) to enable. See README 'Search Tools' for options." + "StackOneToolSet(...) to enable. See README 'Search Tool' for options." ) config: SearchConfig = {**self._search_config} @@ -666,7 +666,7 @@ def _build_tools(self, account_ids: list[str] | None = None) -> Tools: if self._search_config is None: raise ToolsetConfigError( "Search is disabled. Pass search={} (or search={'method': 'auto'}) to " - "StackOneToolSet(...) to enable. See README 'Search Tools' for options." + "StackOneToolSet(...) to enable. See README 'Search Tool' for options." ) if account_ids: @@ -933,7 +933,7 @@ def search_tools( if self._search_config is None: raise ToolsetConfigError( "Search is disabled. Pass search={} (or search={'method': 'auto'}) to " - "StackOneToolSet(...) to enable. See README 'Search Tools' for options." + "StackOneToolSet(...) to enable. See README 'Search Tool' for options." ) # Merge constructor defaults with per-call overrides @@ -1087,7 +1087,7 @@ def search_action_names( if self._search_config is None: raise ToolsetConfigError( "Search is disabled. Pass search={} (or search={'method': 'auto'}) to " - "StackOneToolSet(...) to enable. See README 'Search Tools' for options." + "StackOneToolSet(...) to enable. See README 'Search Tool' for options." ) # Merge constructor defaults with per-call overrides