Skip to content

Commit 4d704ab

Browse files
committed
Document the semantic search feature in the python files and example
1 parent 521339b commit 4d704ab

File tree

2 files changed

+133
-1
lines changed

2 files changed

+133
-1
lines changed

examples/semantic_search_example.py

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,46 @@
1010
discovers scheduling, event, and organization management tools from natural
1111
language queries.
1212
13+
14+
How Semantic Search Works (Overview)
15+
=====================================
16+
17+
The SDK provides three paths for semantic tool discovery, each with a different
18+
trade-off between speed, filtering, and completeness:
19+
20+
1. search_tools(query) — Full discovery (recommended for agent frameworks)
21+
22+
This is the method you should use when integrating with OpenAI, LangChain,
23+
CrewAI, or any other agent framework. It works in these steps:
24+
25+
a) Fetch ALL tools from the user's linked accounts via MCP
26+
b) Extract the set of available connectors (e.g. {bamboohr, calendly})
27+
c) Query the semantic search API with the natural language query
28+
d) Filter results to only connectors the user has access to
29+
e) Deduplicate across API versions (keep highest score per action)
30+
f) Match results back to the fetched tool definitions
31+
g) Return a Tools collection sorted by relevance score
32+
33+
Key point: tools are fetched first, semantic search runs second, and only
34+
the intersection (tools the user has AND that match the query) is returned.
35+
If the semantic API is unavailable, the SDK falls back to local BM25+TF-IDF
36+
search automatically.
37+
38+
2. search_action_names(query) — Lightweight preview
39+
40+
Queries the semantic API directly and returns metadata (name, connector,
41+
score, description) without fetching full tool definitions. Useful for
42+
inspecting results before committing to a full fetch. When account_ids are
43+
provided, results are filtered to the user's available connectors.
44+
45+
3. utility_tools(semantic_client=...) — Agent-loop pattern
46+
47+
Creates tool_search and tool_execute utility tools that agents can call
48+
inside an agentic loop. The agent searches, inspects, and executes tools
49+
dynamically. Note: utility tool search queries the full backend catalog
50+
(all connectors), not just the user's linked accounts.
51+
52+
1353
This example is runnable with the following command:
1454
```bash
1555
uv run examples/semantic_search_example.py

stackone_ai/semantic_search.py

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,96 @@
1-
"""Semantic search client for StackOne action search API."""
1+
"""Semantic search client for StackOne action search API.
2+
3+
How Semantic Search Works
4+
=========================
5+
6+
The SDK provides three ways to discover tools using semantic search.
7+
Each path trades off between speed, filtering, and completeness.
8+
9+
1. ``search_tools(query)`` — Full tool discovery (recommended for agent frameworks)
10+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11+
12+
This is the primary method used when integrating with OpenAI, LangChain, or CrewAI.
13+
The internal flow is:
14+
15+
::
16+
17+
User query (e.g. "create an employee")
18+
19+
20+
┌─────────────────────────────────────────────────────┐
21+
│ Step 1: Fetch ALL tools from linked accounts via MCP │
22+
│ (uses account_ids to scope the request) │
23+
└────────────────────────┬────────────────────────────┘
24+
25+
26+
┌─────────────────────────────────────────────────────┐
27+
│ Step 2: Extract available connectors from the │
28+
│ fetched tools (e.g. {bamboohr, hibob}) │
29+
└────────────────────────┬────────────────────────────┘
30+
31+
32+
┌─────────────────────────────────────────────────────┐
33+
│ Step 3: Query the semantic search API (/actions/ │
34+
│ search) with the natural language query │
35+
└────────────────────────┬────────────────────────────┘
36+
37+
38+
┌─────────────────────────────────────────────────────┐
39+
│ Step 4: Filter results — keep only connectors the │
40+
│ user has access to + apply min_score cutoff │
41+
│ │
42+
│ If not enough results, make per-connector │
43+
│ fallback queries for missing connectors │
44+
└────────────────────────┬────────────────────────────┘
45+
46+
47+
┌─────────────────────────────────────────────────────┐
48+
│ Step 5: Deduplicate by normalized action name │
49+
│ (strips API version suffixes, keeps highest │
50+
│ scoring version of each action) │
51+
└────────────────────────┬────────────────────────────┘
52+
53+
54+
┌─────────────────────────────────────────────────────┐
55+
│ Step 6: Match semantic results back to the fetched │
56+
│ tool definitions from Step 1 │
57+
│ Return Tools sorted by relevance score │
58+
└─────────────────────────────────────────────────────┘
59+
60+
Key point: tools are fetched first, semantic search runs second, and only
61+
tools that exist in the user's linked accounts AND match the semantic query
62+
are returned. This prevents suggesting tools the user cannot execute.
63+
64+
If the semantic API is unavailable, the SDK falls back to a local
65+
BM25 + TF-IDF hybrid search over the fetched tools (unless
66+
``fallback_to_local=False``).
67+
68+
69+
2. ``search_action_names(query)`` — Lightweight discovery
70+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
71+
72+
Queries the semantic API directly and returns action name metadata
73+
(name, connector, score, description) **without** fetching full tool
74+
definitions. This is useful for previewing results before committing
75+
to a full fetch.
76+
77+
When ``account_ids`` are provided, tools are fetched only to determine
78+
available connectors — results are then filtered to those connectors.
79+
Without ``account_ids``, results come from the full StackOne catalog.
80+
81+
82+
3. ``utility_tools(semantic_client=...)`` — Agent-loop search + execute
83+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
84+
85+
Creates a ``tool_search`` utility tool that agents can call inside a
86+
loop. The agent searches for tools, inspects results, then calls
87+
``tool_execute`` to run the chosen tool. When ``semantic_client`` is
88+
passed, ``tool_search`` uses cloud-based semantic vectors instead of
89+
local BM25 + TF-IDF.
90+
91+
Note: utility tool search queries the **full backend catalog** (all
92+
connectors), not just the ones in the user's linked accounts.
93+
"""
294

395
from __future__ import annotations
496

0 commit comments

Comments
 (0)