Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
c7ad71f
Senamtic Search on action in Python AI SDK
shashi-stackone Feb 18, 2026
0210c1f
Filter tools based on the SDK auth config and connector
shashi-stackone Feb 18, 2026
b1105fa
Use the local benchmark from the ai-generations
shashi-stackone Feb 18, 2026
d49f52b
Add Semantinc search bench mark with local benchmarks
shashi-stackone Feb 18, 2026
680fa8e
Fix CI lint errors
shashi-stackone Feb 18, 2026
1ee842b
Fix the lint in the benchmark file
shashi-stackone Feb 18, 2026
d6fba69
Formalise the docs and code
shashi-stackone Feb 18, 2026
3eb0641
Keep semantic search minimal in the README
shashi-stackone Feb 18, 2026
fd37d93
Remove the old benchmark data
shashi-stackone Feb 18, 2026
f5ef955
implement PR feedback suggestions from cubic
shashi-stackone Feb 18, 2026
b7b522f
fix nullable in the semantic tool schema
shashi-stackone Feb 18, 2026
e9c6b86
limit override
shashi-stackone Feb 18, 2026
34e1ca6
handle per connector calls to avoid the guesswork
shashi-stackone Feb 18, 2026
82082cb
simplify utility_tools API by inferring semantic search from client p…
shashi-stackone Feb 18, 2026
8a74517
Benchmark update and PR suggestions
shashi-stackone Feb 18, 2026
85b0395
update the README gst
shashi-stackone Feb 18, 2026
79c762a
Note on the fetch tools for actions that user expect to discover
shashi-stackone Feb 18, 2026
6ee1adf
Update examples and improve the semantic seach
shashi-stackone Feb 18, 2026
7a65367
Fix ruff issues
shashi-stackone Feb 18, 2026
64a0a60
Document the semantic search feature in the python files and example
shashi-stackone Feb 18, 2026
4083642
Respect the backend results unless top_k specified explicitly, add py…
shashi-stackone Feb 18, 2026
b926db1
move the crewAI tools conversation back in the example
shashi-stackone Feb 18, 2026
d2dd2f5
CI Trigger
shashi-stackone Feb 18, 2026
719b391
Fix unit tests with updated top_k behavior
shashi-stackone Feb 18, 2026
b360b00
Update PR with correct approach mentioned in the PR comments
shashi-stackone Feb 18, 2026
7b77f33
Update example and remove unwated crewai examples
shashi-stackone Feb 18, 2026
bab931b
Remove the crewai reference from the README
shashi-stackone Feb 19, 2026
d62943d
fix(semantic-search): scope tool_search to user's linked connectors
shashi-stackone Feb 19, 2026
5eaa3c5
Fix the Ruff CI issue
shashi-stackone Feb 19, 2026
173121d
Add back creai intefration and test integration
shashi-stackone Feb 19, 2026
1e4cc9a
Remove the sematic search example from the tools
shashi-stackone Feb 19, 2026
f1db9f2
Merge branch 'main' into semantic_search
shashi-stackone Feb 19, 2026
a87fa00
Semantic Search
shashi-stackone Feb 19, 2026
c9c0358
Cubic suggestions
shashi-stackone Feb 19, 2026
71457af
Optinally support project_ids in the SDK search
shashi-stackone Feb 19, 2026
5bf1cc6
Update the client to use PR suggested client and use min_similarity f…
shashi-stackone Feb 23, 2026
9fe1e40
CI Fix
shashi-stackone Feb 23, 2026
010a275
Implement PR sugggestions and use the search and execute tools as sta…
shashi-stackone Feb 24, 2026
8137538
update example docs
shashi-stackone Feb 24, 2026
90d8aa3
Update SDK as per PR suggestions
shashi-stackone Feb 25, 2026
3d6000f
Fix available connector early return
shashi-stackone Feb 25, 2026
a0dd833
Fix semantic search creation in fetch tools
shashi-stackone Feb 26, 2026
86c9c64
Fix semantic search creation in fetch tools revert back to lazy
shashi-stackone Feb 26, 2026
ce3443c
get rid of the utility tools completely as discussed
shashi-stackone Feb 26, 2026
53828e5
Remove the reference of the semantic search
shashi-stackone Feb 27, 2026
b8b331a
Fix CI and lint issues
shashi-stackone Feb 27, 2026
f6920c8
Pass semantic Client to the toolset
shashi-stackone Feb 27, 2026
4785d87
Add the search modes for local, semantic and auto with example
shashi-stackone Mar 2, 2026
34c8bc9
Impement PR suggetion and add the salesforce example rather than hris…
shashi-stackone Mar 2, 2026
0bc6ee0
Remove unified categoried from the README and docs
shashi-stackone Mar 2, 2026
6017b44
Remove the unified category reference from CLAUDE.md
shashi-stackone Mar 2, 2026
bf508b0
Refactor duplicate use Stackone API url and update tests
shashi-stackone Mar 3, 2026
ea74fe2
Fix CI issues
shashi-stackone Mar 3, 2026
1f51bf0
CI Only: skip guard fix and the timeout handling
shashi-stackone Mar 3, 2026
d930406
CI Only: skip guard fix and the timeout handling
shashi-stackone Mar 3, 2026
741fdf6
CI Only: ruff E501
shashi-stackone Mar 3, 2026
4109108
refactor search to make it aligned to the defender and future
shashi-stackone Mar 5, 2026
4eddc74
Fix CI
shashi-stackone Mar 5, 2026
ff01d34
CI Only: Ruff fix on toolset.py
shashi-stackone Mar 5, 2026
8e8e2e3
Fix ty checks
shashi-stackone Mar 5, 2026
532ac23
Add topk example and add search default
shashi-stackone Mar 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 1 addition & 12 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,24 +51,13 @@ StackOne AI SDK is a Python library that provides a unified interface for access
- `Tools`: Container for managing multiple tools
- Format converters for different AI frameworks

3. **OpenAPI Parser** (`stackone_ai/specs/parser.py`): Spec conversion
- Converts OpenAPI specs to tool definitions
- Handles file upload detection (`format: binary` → `type: file`)
- Resolves schema references

### OpenAPI Specifications

All tool definitions are generated from OpenAPI specs in `stackone_ai/oas/`:

- `core.json`, `ats.json`, `crm.json`, `documents.json`, `hris.json`, `iam.json`, `lms.json`, `marketing.json`

## Key Development Patterns

### Tool Filtering

```python
# Use glob patterns for tool selection
tools = StackOneToolSet(include_tools=["hris_*", "!hris_create_*"])
tools = StackOneToolSet(include_tools=["bamboohr_*", "!bamboohr_create_*"])
```

### Authentication
Expand Down
79 changes: 57 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ StackOne AI provides a unified interface for accessing various SaaS tools throug
- **Tool Calling**: Direct method calling with `tool.call()` for intuitive usage
- **MCP-backed Dynamic Discovery**: Fetch tools at runtime via `fetch_tools()` with provider, action, and account filtering
- **Advanced Tool Filtering**:
- Glob pattern filtering with patterns like `"hris_*"` and exclusions `"!hris_delete_*"`
- Glob pattern filtering with patterns like `"salesforce_*"` and exclusions `"!*_delete_*"`
- Provider and action filtering
- Multi-account support
- **Utility Tools** (Beta): Dynamic tool discovery and execution based on natural language queries
- **Semantic Search**: AI-powered tool discovery using natural language queries
- **Search Tool**: Callable tool discovery for agent loops via `get_search_tool()`
- Integration with popular AI frameworks:
- OpenAI Functions
- LangChain Tools
Expand Down Expand Up @@ -58,10 +59,10 @@ toolset = StackOneToolSet() # Uses STACKONE_API_KEY env var
# Or explicitly: toolset = StackOneToolSet(api_key="your-api-key")

# Get HRIS-related tools with glob patterns
tools = toolset.fetch_tools(actions=["hris_*"], account_ids=["your-account-id"])
tools = toolset.fetch_tools(actions=["bamboohr_*"], account_ids=["your-account-id"])

# Use a specific tool with the call method
employee_tool = tools.get_tool("hris_get_employee")
employee_tool = tools.get_tool("bamboohr_get_employee")
# Call with keyword arguments
employee = employee_tool.call(id="employee-id")
# Or with traditional execute method
Expand Down Expand Up @@ -107,9 +108,9 @@ tools = toolset.fetch_tools(providers=["hibob"])
- **`account_ids`**: Filter tools by account IDs. Tools will be loaded for each specified account.
- **`providers`**: Filter by provider names (e.g., `["hibob", "bamboohr"]`). Case-insensitive matching.
- **`actions`**: Filter by action patterns with glob support:
- Exact match: `["hris_list_employees"]`
- Exact match: `["bamboohr_list_employees"]`
- Glob pattern: `["*_list_employees"]` matches all tools ending with `_list_employees`
- Provider prefix: `["hris_*"]` matches all HRIS tools
- Provider prefix: `["bamboohr_*"]` matches all BambooHR tools

## Implicit Feedback (Beta)

Expand Down Expand Up @@ -169,7 +170,7 @@ from stackone_ai import StackOneToolSet

# Initialize StackOne tools
toolset = StackOneToolSet()
tools = toolset.fetch_tools(actions=["hris_*"], account_ids=["your-account-id"])
tools = toolset.fetch_tools(actions=["bamboohr_*"], account_ids=["your-account-id"])

# Convert to LangChain format
langchain_tools = tools.to_langchain()
Expand Down Expand Up @@ -216,7 +217,7 @@ from stackone_ai.integrations.langgraph import to_tool_node, bind_model_with_too

# Prepare tools
toolset = StackOneToolSet()
tools = toolset.fetch_tools(actions=["hris_*"], account_ids=["your-account-id"])
tools = toolset.fetch_tools(actions=["bamboohr_*"], account_ids=["your-account-id"])
langchain_tools = tools.to_langchain()

class State(TypedDict):
Expand Down Expand Up @@ -254,7 +255,7 @@ from stackone_ai import StackOneToolSet

# Get tools and convert to LangChain format
toolset = StackOneToolSet()
tools = toolset.fetch_tools(actions=["hris_*"], account_ids=["your-account-id"])
tools = toolset.fetch_tools(actions=["bamboohr_*"], account_ids=["your-account-id"])
langchain_tools = tools.to_langchain()

# Create CrewAI agent with StackOne tools
Expand Down Expand Up @@ -296,7 +297,7 @@ feedback_tool = tools.get_tool("tool_feedback")
result = feedback_tool.call(
feedback="The HRIS tools are working great! Very fast response times.",
account_id="acc_123456",
tool_names=["hris_list_employees", "hris_get_employee"]
tool_names=["bamboohr_list_employees", "bamboohr_get_employee"]
)
```

Expand All @@ -305,26 +306,59 @@ result = feedback_tool.call(
- "Are you ok with sending feedback to StackOne? The LLM will take care of sending it."
- Only call the tool after the user explicitly agrees.

## Utility Tools (Beta)
## Search Tool

Utility tools enable dynamic tool discovery and execution without hardcoding tool names.
Search for tools using natural language queries. Works with both semantic (cloud) and local BM25+TF-IDF search.

### Basic Usage

```python
# Get utility tools for dynamic discovery
tools = toolset.fetch_tools(actions=["hris_*"])
utility_tools = tools.utility_tools()
# Get a callable search tool
toolset = StackOneToolSet()
all_tools = toolset.fetch_tools(account_ids=["your-account-id"])
search_tool = toolset.get_search_tool()

# Search for relevant tools using natural language
filter_tool = utility_tools.get_tool("tool_search")
results = filter_tool.call(query="manage employees", limit=5)
# Search for relevant tools — returns a Tools collection
tools = search_tool("manage employees", top_k=5)

# Execute discovered tools dynamically
execute_tool = utility_tools.get_tool("tool_execute")
result = execute_tool.call(toolName="hris_list_employees", params={"limit": 10})
# Execute a discovered tool directly
tools[0](limit=10)
```

## Semantic Search

Discover tools using natural language instead of exact names. Queries like "onboard new hire" resolve to the right actions even when the tool is called `bamboohr_create_employee`.

```python
from stackone_ai import StackOneToolSet

toolset = StackOneToolSet()

# Search by intent — returns Tools collection ready for any framework
tools = toolset.search_tools("manage employee records", account_ids=["your-account-id"], top_k=5)
openai_tools = tools.to_openai()

# Lightweight: inspect results without fetching full tool definitions
results = toolset.search_action_names("time off requests", top_k=5)
```

### Search Modes

Control which search backend `search_tools()` uses via the `search` parameter:

```python
# "auto" (default) — tries semantic search first, falls back to local
tools = toolset.search_tools("manage employees", search="auto")

# "semantic" — semantic API only, raises if unavailable
tools = toolset.search_tools("manage employees", search="semantic")

# "local" — local BM25+TF-IDF only, no semantic API call
tools = toolset.search_tools("manage employees", search="local")
```

Results are automatically scoped to connectors in your linked accounts. See [Semantic Search Example](examples/semantic_search_example.py) for `SearchTool` (`get_search_tool`) integration, OpenAI, and LangChain patterns.

## Examples

For more examples, check out the [examples/](examples/) directory:
Expand All @@ -334,7 +368,8 @@ For more examples, check out the [examples/](examples/) directory:
- [OpenAI Integration](examples/openai_integration.py)
- [LangChain Integration](examples/langchain_integration.py)
- [CrewAI Integration](examples/crewai_integration.py)
- [Utility Tools](examples/utility_tools_example.py)
- [Search Tool](examples/search_tool_example.py)
- [Semantic Search](examples/semantic_search_example.py)

## Development

Expand Down
Loading