Skip to content

Commit b80451e

Browse files
committed
docs: describe fetchTools() arguments and empty account ids as they now work
execute()'s docstring and the README still described the removed flat, prefixed param style; they now use the wording Python adopted. The migration guide warns that an empty accountId throws, including a set but empty STACKONE_ACCOUNT_ID, and the README's dryRun snippet checks getTool().
1 parent a8ea52f commit b80451e

3 files changed

Lines changed: 9 additions & 6 deletions

File tree

‎MIGRATION.md‎

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,10 +195,12 @@ await toolset.execute('linear_list_comments', { headers: { 'x-request-id': 'abc'
195195
// 2.x: STACKONE_ACCOUNT_ID picked up implicitly
196196
const toolset = new StackOneToolSet();
197197

198-
// 3.0
199-
const toolset = new StackOneToolSet({ accountId: process.env.STACKONE_ACCOUNT_ID });
198+
// 3.0: `|| undefined`, so a variable that is set but empty means "discover", not an error
199+
const toolset = new StackOneToolSet({ accountId: process.env.STACKONE_ACCOUNT_ID || undefined });
200200
```
201201

202+
**An empty account id throws.** `accountId: ''`, or an empty string in `accountIds`, `execute.accountIds`, `setAccounts()` or a call's `accountIds`, now throws `ToolSetConfigError`. In 2.x an empty `accountId` fell back to `STACKONE_ACCOUNT_ID` or discovery; in 3.0 that would silently widen the toolset to every active account. So `accountId: process.env.STACKONE_ACCOUNT_ID` throws when the variable is set but empty (`STACKONE_ACCOUNT_ID=` in a `.env` file, for example): pass `process.env.STACKONE_ACCOUNT_ID || undefined`, as above.
203+
202204
**Listings are merged in sorted account order.** When two accounts serve the same tool name, `getTool()` returns the first one listed — now the one on the lowest account id, where 2.x followed the order you passed. A warning names the clashing tools. Pass `accountIds` to choose the account yourself.
203205

204206
**`fetchTools()` returns fresh tool instances on every call**, never the cached `Tools`, so `setAccountId()` on one tool no longer changes what later callers get. An account whose listing fails is skipped with a warning, unless every account fails.

‎README.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,7 +306,7 @@ const result = await toolset.execute(best.action_id, best.example_request, {
306306
});
307307
```
308308

309-
- `execute()` takes the nested envelope an action's `example_request` shows: `{ path, query, body }`. (Tools from `fetchTools()` take the flat, prefixed arguments their own schema names, such as `path_id`.)
309+
- `execute()` takes the nested envelope an action's `example_request` shows: `{ path, query, body }`. (A `fetchTools()` tool takes the keys its own served schema names instead: read them from `tool.parameters.properties`.)
310310
- The connector is the longest one whose name prefixes the action id, so `browser_linkedin_*` actions are not routed to `browser`.
311311
- `action_id` is always the one you pass: an `action_id` inside `args` — for example, one a prompt-injected model put there — is ignored.
312312
- Each hit carries the `session_id` of the search that found it, when the server issued one. Pass it back as `sessionId` to link the calls together.
@@ -439,7 +439,7 @@ const toolset = new StackOneToolSet();
439439
const tools = await toolset.fetchTools();
440440
const employeeTool = tools.getTool('workday_list_workers');
441441

442-
const dryRunResult = await employeeTool.execute({ query: { limit: 5 } }, { dryRun: true });
442+
const dryRunResult = await employeeTool?.execute({ query: { limit: 5 } }, { dryRun: true });
443443

444444
console.log(dryRunResult);
445445
// {

‎src/toolsets.ts‎

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -827,8 +827,9 @@ export class StackOneToolSet {
827827
*
828828
* Always runs through the connector's `*_execute_action` meta tool, so `args` is the nested
829829
* envelope every action's `example_request` shows — `{ query: {...}, path: {...}, body: {...} }`.
830-
* The flat, prefixed form belongs to `fetchTools()` tools, whose own served schema names the
831-
* keys. The connector is the longest one whose name prefixes `actionId`, and `actionId` is
830+
* A `fetchTools()` tool takes the keys its own served schema names instead; routing by whether
831+
* an id happened to be in the catalog would make the argument shape depend on something the
832+
* caller cannot see. The connector is the longest one whose name prefixes `actionId`, and `actionId` is
832833
* pinned last, so a model-supplied `action_id` in `args` cannot replace it.
833834
*
834835
* `args.headers` is forwarded to the action: `*_execute_action` serves `headers` as an open

0 commit comments

Comments
 (0)