Execution Models: Nested vs Flat-prefixed
Relevant source files
The following files were used as context for generating this wiki page:
The StackOne AI SDK provides two distinct execution surfaces for performing actions on SaaS platforms. These surfaces differ in their architectural approach, the structure of the arguments they accept, and how they interact with the StackOne API. The SDK exposes these actions through either a Nested Envelope model or a Flat-prefixed model to balance the needs of natural-language discovery and strict framework binding.
Sources: CLAUDE.md:31-33, README.md:144-150
Architectural Comparison
The project organizes tool execution based on the ToolMode, which determines how tools are listed and invoked.
| Feature | Nested Envelope Model | Flat-prefixed Model |
|---|---|---|
| Tool Mode | search_execute | individual (Server Default) |
| Primary Surface | toolset.search() + toolset.execute() | toolset.fetch_tools() + tool.execute() |
| API Endpoint | Meta-tools over MCP tools/call | Per-action tools over /actions/rpc |
| Argument Shape | Structured (e.g., {"body": {...}}) | Flat keys (e.g., body_variables) |
| Use Case | Dynamic discovery of hundreds of tools | Binding fixed tools to LLM frameworks |
Sources: CLAUDE.md:19-27, CLAUDE.md:31-40, README.md:150, stackone_ai/types.py:19-27
Execution Flow Logic
The SDK determines how to route parameters by inspecting the provided arguments and the served schema. For RPC-based calls, the SDK splits supplied arguments into the appropriate envelope buckets (path, query, headers, body).
This diagram illustrates how the StackOneRpcTool handles various input shapes to construct the final API payload.
Sources: stackone_ai/tools.py:734-776
Nested Envelope Model
The Nested model is primarily used when an agent needs to discover actions at runtime using natural language. It reduces the context window size by utilizing meta-tools (*_search_actions and *_execute_action) rather than listing every individual action to the model.
Key Characteristics
- Discovery: Uses
toolset.search("query")to find actions based on similarity scores. - Envelope Structure: Arguments must match the structured envelope required by the RPC server, grouping parameters by their location.
- Example:
{"body": {"variables": {"first": 25}}}.
Sources: CLAUDE.md:35-36, README.md:153-154, tests/test_fetch_tools.py:610-618
Meta-Tool Interaction
In the search_execute mode, the SDK communicates with the MCP endpoint using meta-tools. These tools facilitate a two-step process: ranking actions for a query and executing a specific action by its ID.
Flat-prefixed Model
The Flat-prefixed model is the default mode for the StackOne MCP server. It lists one individual tool per action, which is ideal for binding a filtered set of tools to model frameworks like OpenAI Functions, LangChain, or Pydantic AI.
Key Characteristics
- Mapping: Parameter names are prefixed with their target location (e.g.,
path_,query_,body_,headers_). - Internal Logic: The SDK uses the
_FLAT_ENVELOPE_KEY_PATTERNregex (^(path|query|body|headers)_(.+)$) to identify and bucket parameters. - Precedence: Flat-prefixed keys always take precedence over nested or bare keys during parameter splitting to ensure deterministic wire bodies.
Sources: CLAUDE.md:37-40, stackone_ai/tools.py:73-77, stackone_ai/tools.py:734-776
Parameter Splitting Mechanism
The function _split_envelope_params handles the transformation of flat arguments into the structured RPC envelope.
- Schema Awareness: It checks if the served schema uses prefixed names. If bare names are found, prefix detection is disabled to prevent mis-routing body fields (e.g.,
path_to_file). - Three-Pass Assignment:
- Pass 1: Identifies
location_fieldmatches (e.g.,query_limit). - Pass 2: Identifies nested containers (e.g., a
bodyobject). - Pass 3: Assigns bare keys to the
bodybucket.
- Pass 1: Identifies
Sources: stackone_ai/tools.py:734-780, tests/test_tool_calling.py:284-307
Summary of Usage Patterns
| surface | Argument Example | Implementation Class |
|---|---|---|
toolset.execute() | {"body": {"variables": {"id": 1}}} | StackOneMcpTool |
tool.execute() | {"body_variables": {"id": 1}} | StackOneRpcTool |
Sources: CLAUDE.md:31-45, README.md:153-156
The SDK ensures compatibility by allowing fetch_tools() individual tools to accept nested envelopes, whereas passing flat keys to the global toolset.execute() may result in the server dropping those arguments if they do not match the expected schema.
Sources: CLAUDE.md:41-45