doc: design spec for azd ai agent toolbox direct commands#8160
Conversation
📋 Prioritization NoteThanks for the contribution! The linked issue isn't in the current milestone yet. |
There was a problem hiding this comment.
Pull request overview
Adds a new design specification document describing the proposed azd ai agent toolbox direct-command surface in the azure.ai.agents extension (design review only; no implementation).
Changes:
- Documents the planned toolbox CRUD command surface (
create|update|delete|show|list) plusconnectionandtagsubgroups. - Specifies data-plane API endpoints, request/response shapes, and CLI behaviors (including a local pending-toolbox record model).
- Outlines endpoint resolution, config storage shape, telemetry events, error codes, and a test plan.
Comments suppressed due to low confidence (1)
cli/azd/docs/design/azure-ai-toolbox-direct-commands.md:166
- The spec’s computed MCP consumption URL omits the toolbox version (
{projectEndpoint}/toolboxes/{name}/mcp?...). In the existing extension code, the MCP endpoint is version-scoped:/toolboxes/{name}/versions/{version}/mcp?api-version=v1(seeextensions/azure.ai.agents/internal/cmd/listen.go). If the service contract is versioned, this spec should reflect that soshowreturns a runnable URL.
1. `GET /toolboxes/{name}` for `default_version`.
2. `GET /toolboxes/{name}/versions/{version}` (or `default_version` when `--version` is absent) for the body.
3. Compute the toolbox's MCP consumption URL as `{projectEndpoint}/toolboxes/{name}/mcp?api-version=v1`.
4. Output:
jongio
left a comment
There was a problem hiding this comment.
Solid spec with clear API mapping, good test plan, and well-structured command surface. A few design gaps that'll bite during implementation:
Error code overloading: CodeInvalidToolbox is used for 6+ distinct failure modes (duplicate connection, unsupported category, empty tools, missing --index, missing connection, invalid version target). This makes telemetry useless for distinguishing root causes. Consider at least: CodeDuplicateConnection, CodeUnsupportedConnectionCategory, CodeEmptyToolsArray, CodeMissingIndex.
TOCTOU in shared write flow: Steps 2-5 (fetch default version, mutate, POST, PATCH) have a race window. Two concurrent connection add calls both fetch the same version, both POST, and the second creates a version missing the first's tool. Worth acknowledging as a known limitation or describing retry/conflict detection (e.g., conditional on the fetched version number).
Stale pending-record accumulation: Records are cleared by connection add or delete, but if a user runs create and never follows up (or the endpoint changes), pending records accumulate forever. Consider a TTL (e.g., 30 days) or a toolbox list --cleanup-stale hint.
Built-in tool interaction with last-tool guard: connection remove rejects when tools[] would be empty. But if removing the last connection-backed tool leaves only built-ins (which are "carried through unchanged"), is the result considered empty? The guard should clarify whether empty means zero total entries or zero connection-backed entries.
show on pending toolbox: create records locally, but show does GET /toolboxes/{name} which will 404 for a pending-only toolbox. Should show fall back to displaying the pending record metadata, or explicitly error with "toolbox is pending, run connection add first"?
|
@jongio Thanks for the review - all five are valid and the spec is updated.
|
jongio
left a comment
There was a problem hiding this comment.
Addresses all feedback from my prior review:
- Error codes split from the overloaded CodeInvalidToolbox into distinct codes (CodeDuplicateConnection, CodeDefaultVersionDelete, CodeOnlyVersionDelete, etc.) - telemetry can now distinguish root causes.
- TOCTOU race documented as a known limitation with clear user guidance (serialize calls, wait for service conditional-write support).
- Pending-record cleanup is user-driven via delete; list now surfaces CREATED so stale entries are visible.
- Built-in tool guard clarified: "zero entries (counting any built-ins carried through)."
- show on pending-only toolbox specified in new section 5.4.1 with both table and JSON output contracts.
Architecture simplification (extending FoundryToolboxClient directly rather than wrapping via composition) is a good call - less indirection, same one-way import graph.
Summary
This PR adds the design spec for the
azd ai agent toolboxdirect commands. This is for design review only and contains no implementation code.What's in this spec
Five top-level verbs for managing versioned toolboxes against a Foundry project:
toolbox create <name>: register a toolbox (pending tools until firstconnection add).toolbox update <name> --default-version <n>: retarget the active version.toolbox delete <name>: delete the whole toolbox or a single version via--version.toolbox show <name>: display metadata, version body, and the toolbox's MCP endpoint URL for runtime consumption.toolbox list: list toolboxes plus any local pending records for the resolved endpoint.Connection subgroup (
connection add | remove | list) that wraps the toolbox versions API. Every tool mutation is a full-tools[]POST to/toolboxes/{name}/versionsfollowed by aPATCH default_version; tool-entry shape is inferred from the project connection's ARMcategory(RemoteTool→mcp,CognitiveSearch→azure_ai_search).Tag subgroup (
tag set | remove | list) shipped as a Compatibility stub: toolboxes are not yet exposed as ARM resources, so the standard ARM resource-tag surface is unavailable. The CLI surface is final and activates without surface changes once the underlying API exists.Pending-toolbox config store:
createcannot POST because the service requires a non-emptytools[], so it records a local entry underextensions.ai-agents.pending-toolboxes.<endpointHash>.items.<name>. The firstconnection addpromotes the record to a real v1.Live-verified API surface (§ 4): every endpoint the spec relies on was probed against a live Foundry project, including the per-version delete guard, the MCP runtime endpoint, and the ARM connection lookup used by
connection add.Key design decisions for review
azure.ai.agentsextension atazd ai agent toolbox …. Files are isolated underinternal/cmd/toolbox*.goandinternal/pkg/toolbox/so a future move to a standaloneazure.ai.toolboxextension is a registration-only change.createdoes not POST (§ 5.1, Open Question 1): the service requires a non-emptytools[]. Two options were considered — auto-seed with a sentinel built-in, or defer the first POST until the firstconnection add. Current proposal: defer (pending-record model). Keepscreatenon-network and matches the "one command, one action" principle.updateis--default-versiononly (§ 5.2): the service only acceptsdefault_versionon PATCH. Description and tool edits must go throughconnection add/connection remove, which publish a new version.default_versionwhen sibling versions exist (400). When the default is the only remaining version the service deletes it and cascades to remove the parent toolbox; the CLI rejects this without--forceto avoid surprise destruction.code_interpreter,web_search,file_search,mcp, andazure_ai_searchside-by-side. Per issue Addazd ai toolbox create/update/show/list/delete(plusconnectionandtagsubcommands) to manage Foundry Toolboxes from any directory #8143, built-ins are wired on the agent rather than via toolboxes; the CLI does not author built-ins but carries them through unchanged during fetch-merge-POST.-pshort form (§ 5.1):-pis already taken onagent run/agent invoke. The canonical name is--project-endpoint, matching the project-context spec.Related
Feature: Add ai.toolbox commands for CRUD on Toolboxes in Foundry Projectdocs: design spec for azd ai connection direct commandsdoc: design spec for azd ai project context commands and endpoint resolution— the 5-level endpoint resolution cascade referenced in § 6 is owned by this spec.azd aiDirect Commands (CLI Surface for Foundry)