refactor: ai agent with toolbox and connection - #9735
Conversation
|
Azure Pipelines: Successfully started running 3 pipeline(s). 18 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
There was a problem hiding this comment.
Pull request overview
Refactors Foundry extensions to support source-controlled toolbox and connection definitions and integrate toolbox deployment into hosted-agent workflows.
Changes:
- Adds toolbox and connection definition models, file handling, commands, and cloud deployment.
- Integrates toolbox references and MCP endpoints into agent deployment.
- Migrates shared project context ownership to
azure.ai.projectswith legacy fallback.
Reviewed changes
Copilot reviewed 61 out of 62 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
cli/azd/extensions/azure.ai.toolboxes/schemas/azure.ai.toolbox.json |
Expands toolbox configuration schema. |
cli/azd/extensions/azure.ai.toolboxes/internal/foundry/projectctx/types.go |
Updates project-context ownership documentation. |
cli/azd/extensions/azure.ai.toolboxes/internal/foundry/projectctx/store.go |
Adds canonical and legacy context lookup. |
cli/azd/extensions/azure.ai.toolboxes/internal/foundry/projectctx/store_test.go |
Tests context lookup precedence. |
cli/azd/extensions/azure.ai.toolboxes/internal/foundry/projectctx/resolver.go |
Documents the canonical config path. |
cli/azd/extensions/azure.ai.toolboxes/internal/foundry/connections/types.go |
Retains connection category definitions. |
cli/azd/extensions/azure.ai.toolboxes/internal/foundry/connections/client.go |
Removes the duplicated connection client. |
cli/azd/extensions/azure.ai.toolboxes/internal/definition/file.go |
Adds strict definition loading and saving. |
cli/azd/extensions/azure.ai.toolboxes/internal/definition/definition.go |
Defines toolbox configuration types. |
cli/azd/extensions/azure.ai.toolboxes/internal/definition/definition_test.go |
Tests definition mutation and validation. |
cli/azd/extensions/azure.ai.toolboxes/internal/foundry/toolboxes/cloud/types.go |
Defines toolbox cloud API models. |
cli/azd/extensions/azure.ai.toolboxes/internal/foundry/toolboxes/cloud/client.go |
Adds the toolbox data-plane client. |
cli/azd/extensions/azure.ai.toolboxes/internal/foundry/toolboxes/cloud/client_test.go |
Tests toolbox API requests. |
cli/azd/extensions/azure.ai.toolboxes/internal/foundry/toolboxes/cloud/deploy.go |
Translates and deploys toolbox definitions. |
cli/azd/extensions/azure.ai.toolboxes/internal/foundry/toolboxes/cloud/deploy_test.go |
Tests deployment translation. |
cli/azd/extensions/azure.ai.toolboxes/internal/output/format.go |
Adds structured output handling. |
cli/azd/extensions/azure.ai.toolboxes/internal/cmd/toolbox_create.go |
Adds toolbox definition creation. |
cli/azd/extensions/azure.ai.toolboxes/internal/cmd/toolbox_files.go |
Resolves toolbox definition files. |
cli/azd/extensions/azure.ai.toolboxes/internal/cmd/toolbox_add_connection.go |
Adds connection references to toolboxes. |
cli/azd/extensions/azure.ai.toolboxes/internal/cmd/toolbox_add_skill.go |
Adds skill references to toolboxes. |
cli/azd/extensions/azure.ai.toolboxes/internal/cmd/toolbox_deploy.go |
Adds toolbox deployment. |
cli/azd/extensions/azure.ai.toolboxes/internal/cmd/toolbox_deploy_test.go |
Tests toolbox deployment commands. |
cli/azd/extensions/azure.ai.toolboxes/internal/cmd/toolbox_show.go |
Updates toolbox display and MCP URLs. |
cli/azd/extensions/azure.ai.toolboxes/internal/cmd/root.go |
Registers the new toolbox commands. |
cli/azd/extensions/azure.ai.toolboxes/internal/cmd/root_test.go |
Tests toolbox command registration. |
cli/azd/extensions/azure.ai.agents/schemas/Agent.json |
Adds toolbox references to agents. |
cli/azd/extensions/azure.ai.agents/internal/project/models/agent_tools.go |
Models agent toolbox tools. |
cli/azd/extensions/azure.ai.agents/internal/project/agent_definition.go |
Parses toolbox configuration. |
cli/azd/extensions/azure.ai.agents/internal/project/service_target_agent.go |
Integrates toolbox dependencies. |
cli/azd/extensions/azure.ai.agents/internal/project/tools.go |
Translates toolbox references. |
cli/azd/extensions/azure.ai.agents/internal/project/tools_test.go |
Tests toolbox tool translation. |
cli/azd/extensions/azure.ai.agents/internal/project/direct_deploy.go |
Adds standalone hosted-agent deployment. |
cli/azd/extensions/azure.ai.agents/internal/project/direct_deploy_test.go |
Tests direct deployment preparation. |
cli/azd/extensions/azure.ai.agents/internal/cmd/deploy.go |
Orchestrates agent and toolbox deployment. |
cli/azd/extensions/azure.ai.agents/internal/cmd/deploy_test.go |
Tests deployment orchestration. |
cli/azd/extensions/azure.ai.agents/internal/foundry/projectctx/store.go |
Migrates project-context storage. |
cli/azd/extensions/azure.ai.agents/internal/foundry/projectctx/store_test.go |
Tests context migration behavior. |
cli/azd/extensions/azure.ai.agents/internal/version/version.go |
Updates the agent extension version. |
cli/azd/extensions/azure.ai.agents/go.mod |
Updates agent dependencies. |
cli/azd/extensions/azure.ai.agents/go.sum |
Updates agent dependency checksums. |
cli/azd/extensions/azure.ai.agents/extension.yaml |
Adds the toolbox extension dependency. |
cli/azd/extensions/azure.ai.projects/extension.yaml |
Updates extension integration metadata. |
cli/azd/extensions/azure.ai.connections/schemas/azure.ai.connection.json |
Expands connection configuration fields. |
cli/azd/extensions/azure.ai.connections/internal/definition/file.go |
Adds strict connection file handling. |
cli/azd/extensions/azure.ai.connections/internal/definition/definition.go |
Defines connection configuration types. |
cli/azd/extensions/azure.ai.connections/internal/definition/definition_test.go |
Tests connection definitions. |
cli/azd/extensions/azure.ai.connections/internal/cmd/connection_create.go |
Adds connection definition creation. |
cli/azd/extensions/azure.ai.connections/internal/cmd/connection_create_test.go |
Tests connection creation. |
cli/azd/extensions/azure.ai.connections/internal/cmd/root.go |
Registers connection commands. |
cli/azd/extensions/azure.ai.connections/internal/cmd/root_test.go |
Tests command registration. |
cli/azd/extensions/azure.ai.connections/internal/project/service_target_connection.go |
Refactors connection service behavior. |
cli/azd/extensions/azure.ai.connections/internal/version/version.go |
Updates the connection extension version. |
cli/azd/extensions/azure.ai.connections/go.mod |
Updates connection dependencies. |
cli/azd/extensions/azure.ai.connections/go.sum |
Updates connection dependency checksums. |
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 61 out of 62 changed files in this pull request and generated no new comments.
Suppressed comments (5)
Previously missed (4) — in code that hasn't changed since the last review.
cli/azd/extensions/azure.ai.connections/internal/cmd/connection_deploy.go:117
- OAuth scopes bypass the environment expansion applied to every other OAuth field. A definition such as
scopes: ["${GITHUB_SCOPE}"]is sent literally, contradicting the deploy contract and causing OAuth authorization to request the wrong scope. Expand each scope before assigning it to the create flags.
scopes: slices.Clone(input.Scopes),
cli/azd/extensions/azure.ai.agents/internal/cmd/deploy.go:178
- An unpinned reference without a sibling
toolbox.yamlreturns onlyTOOLBOX_NAME, even though an omitted version means the existing toolbox's default version. The toolbox reference itself is not included in the agent API request, so the workload receives neither a version nor an MCP endpoint and cannot use the referenced toolbox automatically. Resolve the existing default through the toolbox extension's machine-readableshowcontract, or fail with an actionable error.
toolboxPath := filepath.Join(filepath.Dir(agentDefinitionPath), "toolbox.yaml")
if _, err := os.Stat(toolboxPath); err != nil {
if os.IsNotExist(err) {
return environment, nil
}
cli/azd/extensions/azure.ai.agents/internal/project/direct_deploy.go:225
- Prioritize the azd credential in this chain. The command directs users to authenticate with
azd auth login, and the existing agent paths useAzureDeveloperCLICredential; if Azure CLI is also logged in as another principal, it can obtain the first token successfully and a later service authorization failure will not fall through to azd. Appending the azd credential first preserves the documented authentication behavior while retaining Azure CLI as fallback.
credentials := make([]azcore.TokenCredential, 0, 2)
if azureCLIError == nil {
credentials = append(credentials, azureCLI)
}
if azdError == nil {
cli/azd/extensions/azure.ai.agents/internal/cmd/deploy.go:164
- The environment map omits the established name-scoped endpoint key. Agent initialization writes
TOOLBOX_<NAME>_MCP_ENDPOINTintoagent.yaml(internal/cmd/init.go:4345-4359), but both branches here only provideTOOLBOX_ENDPOINT; preparation therefore resolves the generated name-scoped placeholder to an empty value. Setenvkey.ToolboxMCPEndpoint(name)to the resolved endpoint in both the pinned and deployed branches.
environment := map[string]string{"TOOLBOX_NAME": name}
cli/azd/extensions/azure.ai.agents/internal/cmd/deploy.go:109
- This deploys the sibling toolbox before any full agent validation, code-directory check, or packaging occurs. For example, an invalid
agent.yamlor missing--codedirectory still creates an immutable toolbox version before the agent deployment fails. Run the local agent/code preflight before this remote mutation to avoid orphan versions and version churn on retries.
environment, err := deployAgentToolboxDependency(
ctx, runner, resolved.Endpoint, definitionPath, toolbox,
)
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 88 out of 89 changed files in this pull request and generated 2 comments.
Suppressed comments (4)
Previously missed (2) — in code that hasn't changed since the last review.
cli/azd/extensions/azure.ai.toolboxes/extension.yaml:13
- This range points to the already-published beta.4, which does not contain the new
connection showidcontract. The resolver then substitutes the short name asproject_connection_id, producing an invalid toolbox request. Require the next Connections release that actually contains this contract, and update the ownership test accordingly.
cli/azd/extensions/azure.ai.agents/internal/project/agent_definition.go:130 - Inline
azure.yamlcannot populate this field becauselanguageis core-owned and stored inServiceConfig.Language, whileagentDefinitionFromStructreceives onlyAdditionalProperties. Unlikeimage, nosvc.GetLanguage()value is threaded into conversion, solanguage: pythonis silently dropped. Pass the core field into the conversion or avoid advertising it for inline services.
Language string `json:"language,omitempty"`
cli/azd/extensions/azure.ai.agents/extension.yaml:18
- These ranges reference the already-published Connections beta.4 and Toolboxes beta.5, neither of which contains the new JSON
idcontract ortoolbox deploycommand invoked by Agent deployment. The declared dependencies therefore do not enforce the required runtime contracts. Point them at the releases containing this PR and update the manifest test.
- id: azure.ai.connections
version: "~1.0.0-beta.4"
- id: azure.ai.toolboxes
version: "~1.0.0-beta.5"
cli/azd/extensions/azure.ai.agents/internal/cmd/deploy.go:194
- An unpinned reference without a sibling
toolbox.yamlsucceeds with onlyTOOLBOX_NAME; it never resolves the toolbox's default version or MCP endpoint. This contradicts the reference contract and deploys an agent withoutTOOLBOX_VERSION/TOOLBOX_ENDPOINT. Resolve the existing toolbox through the Toolbox JSON contract, or return an actionable error requiring a version or sibling definition.
toolboxPath := filepath.Join(filepath.Dir(agentDefinitionPath), "toolbox.yaml")
if _, err := os.Stat(toolboxPath); err != nil {
if os.IsNotExist(err) {
return environment, nil
}
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 90 out of 91 changed files in this pull request and generated no new comments.
Suppressed comments (4)
Previously missed (1) — in code that hasn't changed since the last review.
cli/azd/extensions/azure.ai.toolboxes/extension.yaml:13
1.0.0-beta.4is already published without the newconnection show --output jsonidfield consumed by this PR. Existing beta.4 installations satisfy this dependency and are not guaranteed to upgrade, leaving the resolver with the connection name instead of the ARM ID required forproject_connection_id. Depend on the first Connections release containing the new JSON contract and publish it before Toolboxes.
cli/azd/extensions/azure.ai.agents/internal/project/service_target_agent.go:1373
- This only adds the toolbox to dependency validation; it never adds
TOOLBOX_NAME,TOOLBOX_VERSION, orTOOLBOX_ENDPOINTto the environment passed toCreateAgentAPIRequestFromDefinition(that environment is built later fromserviceConfig.GetEnvironment()and the legacy list). Consequently, anazure.yamlagent using the newtoolbox:field can deploy after its toolbox but the hosted container receives none of the toolbox coordinates. Resolve the reference here (using the pinned version orTOOLBOX_<NAME>_MCP_ENDPOINT) and merge the three generic variables into the request environment, matching standalone deploy.
addAgentToolboxDependency(serviceTargetConfig, agentDef.Toolbox)
cli/azd/extensions/azure.ai.agents/internal/cmd/deploy.go:194
- An unpinned reference without a sibling
toolbox.yamlreturns onlyTOOLBOX_NAME; unlike the sibling and pinned branches, it leaves both version and endpoint unresolved. The deployed agent therefore cannot consume the referenced existing toolbox through the documentedTOOLBOX_ENDPOINTcontract. Queryazd ai toolbox show <name> --output jsonhere to resolve the default version and endpoint (or return an actionable error).
toolboxPath := filepath.Join(filepath.Dir(agentDefinitionPath), "toolbox.yaml")
if _, err := os.Stat(toolboxPath); err != nil {
if os.IsNotExist(err) {
return environment, nil
}
cli/azd/extensions/azure.ai.agents/extension.yaml:18
1.0.0-beta.5is already published incli/azd/extensions/registry.json, before this PR adds thetoolbox deployJSON contract invoked by standalone agent deployment. A machine with that version installed satisfies this range, so the nested command fails as unknown instead of upgrading. Set the minimum to the first toolbox release containingdeployand release Toolboxes before Agents.
- id: azure.ai.toolboxes
version: "~1.0.0-beta.5"
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 90 out of 91 changed files in this pull request and generated 2 comments.
Suppressed comments (1)
cli/azd/extensions/azure.ai.connections/internal/cmd/connection_deploy.go:163
- This rejects the canonical composed shape for
CustomKeyscredentials. The same schema is used by standalone andazure.yamldefinitions, and existing synthesis fixtures usecredentials.keys.<name>; here thekeysobject fails the string assertion before deployment. Please preserve/expand the nested credential object (and translatekeystocustomKeys) so the sameconnection.yamlworks in both deployment paths.
📋 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
Copilot reviewed 95 out of 96 changed files in this pull request and generated 4 comments.
Suppressed comments (1)
cli/azd/extensions/azure.ai.connections/internal/cmd/connection_deploy.go:163
connection.yamlis also used as the canonical$refshape, whereCustomKeyscredentials are nested undercredentials.keys(for example in the synthesis fixtures). Herekeysis amap[string]any, so every such definition is rejected as “must be a string” before deployment. Handle the nestedkeysobject and expand each leaf value before populatingcustomKeys, so the same canonical file works in standalone and composed deployment.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 95 out of 96 changed files in this pull request and generated 2 comments.
Suppressed comments (3)
cli/azd/extensions/azure.ai.agents/internal/project/service_target_agent.go:1476
This adds the Toolbox only to dependency validation. The composed azd deploy path still builds the Hosted Agent environment in prepareDeploy without reading agentDef.Toolbox, so unlike standalone deploy it never injects TOOLBOX_NAME, TOOLBOX_VERSION, or TOOLBOX_ENDPOINT. Agents using the new reference through azure.yaml therefore start without the advertised Toolbox environment.
addAgentToolboxDependency(serviceTargetConfig, agentDef.Toolbox)
cli/azd/extensions/azure.ai.agents/internal/cmd/agent_definition_edit.go:72
Reject kind: prompt-voice before mutating the file. The schema and ValidateAgentDefinition explicitly prohibit a hosted-agent toolbox reference for prompt-voice agents, but this command currently turns a valid voice definition into one that cannot be deployed.
root, err := agentDefinitionMapping(&document)
if err != nil {
return err
}
cli/azd/extensions/azure.ai.toolboxes/internal/cmd/toolbox_connection_resolver.go:104
Do not substitute the connection name when the JSON contract omits id. project_connection_id is populated from this value and requires the ARM resource ID, so this fallback converts an incomplete sibling-extension response into a malformed Toolbox request. Treat a blank ID as an incomplete descriptor instead.
azure.ai.connections PR buildNote This is an unsigned development build. Install it only if you trust this PR. Install the extension: azd ext install "https://azuresdkartifacts.z5.web.core.windows.net/azd/extensions/pr/9735/azure-ai-connections.zip"
|
azure.ai.projects PR buildNote This is an unsigned development build. Install it only if you trust this PR. Install the extension: azd ext install "https://azuresdkartifacts.z5.web.core.windows.net/azd/extensions/pr/9735/azure-ai-projects.zip"
|
azure.ai.toolboxes PR buildNote This is an unsigned development build. Install it only if you trust this PR. Install the extension: azd ext install "https://azuresdkartifacts.z5.web.core.windows.net/azd/extensions/pr/9735/azure-ai-toolboxes.zip"
|
Summary
Refactors the Foundry AI extensions so that each extension owns the full lifecycle of its resource:
azure.ai.connectionsowns Connection definitions and deployment.azure.ai.toolboxesowns Toolbox composition and version deployment.azure.ai.agentsowns Agent composition and orchestrates its dependencies.The local YAML definitions are now the source of truth.
addcommands update local definitions, whiledeploycommands apply them to an existing Foundry project.Changes
Connections
connection.yamldefinition model with strict YAML/JSON loading and atomic writes.azd ai connection deploy [path].idtoconnection show --output json.showoutput unless--show-credentialsis explicitly requested.azure.ai.projects, with a legacy fallback.Toolboxes
toolbox.yamldefinition model for connections, skills, tools, policies, and metadata.azd ai toolbox add connectionazd ai toolbox add skillazd ai toolbox deploy [path], which creates a new immutable Toolbox version.azd ai connection show --output jsoncontract.azure.yamldeployments.azure.ai.connectionsas a manifest dependency.Agents
azd ai agent add toolboxfor updating a localagent.yaml.azd ai agent deploy [path]for source-code Hosted Agent deployment without requiringazure.yaml.toolbox.yamlbefore the Agent when the Toolbox reference is unpinned.Schemas and compatibility
azure.ai.projects.azure.yamldeployment behavior.Architecture
The resulting dependency graph is:
Project -> Connection -> Toolbox -> Agent
Cross-extension coordination uses machine-readable CLI contracts instead of duplicating sibling resource clients:
azd ai connection show --output json.azd ai toolbox deploy --output json.