|
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 | +""" |
2 | 94 |
|
3 | 95 | from __future__ import annotations |
4 | 96 |
|
|
0 commit comments