Skip to content

feat!: one search tool and one execute tool spanning the account scope (ENG-3175) - #231

Merged
willleeney merged 5 commits into
mainfrom
will/eng-3175-single-search-execute
Oct 29, 2026
Merged

willleeney merged 5 commits into
mainfrom
will/eng-3175-single-search-execute

Conversation

@willleeney

@willleeney willleeney commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Part of ENG-3175. Draft: depends on the server serving the trio to API keys (unified-cloud-api#9417 (merged)) and on StackOneHQ/sdk-conformance#9. Lands before the 3.0.0 release (#200), so the breaking change ships inside 3.0.0.

In search_execute mode the SDK now gives a model one stackone_search_actions and one stackone_execute_action (with stackone_list_accounts) across every account in scope, instead of one pair per account.

  • Listing: one MCP request for the whole scope, with the account ids as repeated x-account-id query parameters and recorded end users as repeated x-end-user-id. A failure raises; there is one request, so nothing to skip.
  • search(): one stackone_search_actions call. Hits are as served, with available_accounts; an action linked on two accounts is one hit, not two, and there is no account_id per hit.
  • execute(): one stackone_execute_action call. A single id in account_ids becomes stackone_account_id. An ambiguous action is refused by the server (StackOneAPIError), not the SDK.
  • Removed: the per-connector fan-out, connector-name parsing, cross-connector re-ranking, and the failed-account retry and provider-miss tracking in execute().
  • Pydantic AI: FunctionModel-driven Agent tests run a tool end to end against the mock MCP server in individual and search_execute modes. The example runs an agent in each mode. Removes a stale _build_tools mock.
  • README, MIGRATION and examples show available_accounts; vectors vendored from sdk-conformance@65e1286.

Checks: 850 tests pass; ruff and ty clean; the sdk-conformance suite passes.

Live (production API, Gemini 3.1 Pro, a Google Calendar account): Pydantic AI agents passed in both modes. Production still serves the per-account pair, so the trio itself was exercised only against mocks.

Follow-up once sdk-conformance merges: bump the pinned conformance ref (5f60cc0) and NODE_SDK_REF in CI.

Update: on the merged server (unified-cloud-api#9417)

Stu's #9417 is merged and replaces unified-cloud-api#9398. It takes the accounts as a comma-separated x-account-id, serves the trio for two or more, and serves the account's own pair (<provider>_<accountId>_search_actions / _execute_action) for one, capped at 50. So now:

  • Listing: one comma-separated x-account-id query value (sorted, deduped) instead of repeated parameters; end users stay repeated x-end-user-id.
  • One account: the served pair is presented as stackone_search_actions / stackone_execute_action. Served names are rewritten in descriptions, schemas, results and error text, and hits gain available_accounts and provider. A stackone_account_id or provider naming that account is dropped (null too); any other raises ToolArgumentsError (account-outside-scope, provider-outside-scope) before any call. No stackone_list_accounts is invented.
  • More than 50 accounts in scope: too-many-accounts config error before any request.

The full sdk-conformance suite passes against both SDK branches, cross-SDK wire equality included; so do the sdk / pydantic / adk smoke scripts.

…as the trio

search() and execute() call stackone_search_actions / stackone_execute_action once,
replacing the per-account meta-tool fan-out, connector parsing, re-ranking and the
failed-account retry in execute(). Hits carry available_accounts, not account_id.

WIP: shared vectors not yet re-vendored; README/MIGRATION/examples and the Pydantic AI
test still to do.
…vectors; document hits' available_accounts

Vendors sdk-conformance@65e1286's vectors, which drop the per-connector messages and
add trio-tool-not-served. A FunctionModel-driven Agent now runs a tool end to end
against the mock MCP server in individual and search_execute modes. README,
MIGRATION and the examples show search hits naming available_accounts rather than
account_id, and the Pydantic AI example runs a search_execute agent too.
…one-account pair as the trio's names (ENG-3175)
…ts matching PR (#389)

Both SDKs' conformance runs grade the pair together, and the new contract needs both on it.
The Node pin moves to its merge commit once #389 lands.
@willleeney
willleeney force-pushed the will/eng-3175-single-search-execute branch from 413aec2 to d76c266 Compare October 28, 2026 16:29
…packageManager

sdk-conformance moved to pnpm 11.17.0 (#12), and pnpm/action-setup refuses a version key that
disagrees with package_json_file. Each SDK checkout still runs its own pnpm 10.26.0: pnpm
switches to a project's packageManager version.
@willleeney
willleeney marked this pull request as ready for review October 29, 2026 09:06
Copilot AI balanced review requested due to automatic review settings October 29, 2026 09:06
@cubic-dev-ai

cubic-dev-ai Bot commented Oct 29, 2026

Copy link
Copy Markdown

Running ultrareview automatically — this PR appears to change a public API contract, where a missed bug can break the clients and integrations that depend on it, so a deeper multi-pass review is worth running. I'll post findings when complete.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing. Review the Copilot code review billing settings.

@willleeney
willleeney merged commit 691d13a into main Oct 29, 2026
13 of 14 checks passed
@willleeney
willleeney deleted the will/eng-3175-single-search-execute branch October 29, 2026 09:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants