Skip to content

fix: run interactive Azure context setup in unified azure.yaml adoption path#8933

Merged
trangevi merged 9 commits into
mainfrom
trangevi/issue-8922-azd-ai-agent-init-m-azure-yaml-skips-int-c30848
Jul 2, 2026
Merged

fix: run interactive Azure context setup in unified azure.yaml adoption path#8933
trangevi merged 9 commits into
mainfrom
trangevi/issue-8922-azd-ai-agent-init-m-azure-yaml-skips-int-c30848

Conversation

@trangevi

@trangevi trangevi commented Jul 1, 2026

Copy link
Copy Markdown
Member

Motivation

When azd ai agent init -m <azure.yaml> points at a unified Foundry azure.yaml, the command scaffolds the project but returns early without running subscription selection, Foundry project setup, or model deployment verification. Users are left with an environment that cannot provision without manual configuration.

Approach

This PR adds interactive environment setup to the unified azure.yaml adoption path (runInitFromAzureYaml):

Subscription and Foundry project setup:
Extracts the shared subscription + Foundry project selection logic from configureModelChoice's !hasModelResources branch into a standalone configureFoundryProject helper. Both the agent-manifest path and the unified azure.yaml adoption path now call this helper, eliminating duplication and ensuring the adoption path runs the same interactive flow.

Model deployment verification:
After project selection, parses model deployments from the azure.yaml and verifies each one against the selected Foundry project's existing deployments. For each declared deployment, the user can:

  • Use an existing matching deployment -- removes it from azure.yaml (no provisioning needed)
  • Deploy as specified -- keeps it in azure.yaml for provisioning (only shown when the existing deployment differs from what's declared)
  • Choose a different model -- full catalog browse or pick another existing deployment
  • Skip -- removes from azure.yaml entirely

When creating a new project (no existing deployments to compare against), the user is still shown the model details and asked to confirm, change, or skip.

The first selected deployment is persisted as AZURE_AI_MODEL_DEPLOYMENT_NAME (same env var as the manifest path).

Flag support:

  • --model-deployment <name>: auto-selects the named existing deployment without prompting (errors if not found)
  • --model <name>: pre-selects the model in the catalog prompt when choosing a different model
  • --project <id>: already supported via configureFoundryProject
  • --no-prompt: auto-uses existing matches and auto-deploys unmatched models

Key design decisions

  • configureFoundryProject returns a foundryProjectSetupResult with Credential and FoundryProjectInfo, allowing callers to chain dependent operations (like listing deployments).
  • YAML parsing uses typed structs with explicit yaml tags on project.Deployment rather than map[string]any, so field mapping is a compile-time contract.
  • verifyAzureYamlDeployments returns kept entries with their originating service name preserved, plus a modified flag -- eliminates the previous length-only rewrite guard and non-deterministic service assignment.
  • When the user picks an existing deployment via "Choose a different model", it's only added to referencedDeployments (not kept in azure.yaml) since it doesn't need provisioning.
  • The azure.yaml is updated via SetServiceConfigValue with path deployments -- same mechanism used by setServiceUses for the uses: field.

Files changed

  • init_foundry_project_setup.go (new) -- extracted configureFoundryProject helper
  • init.go -- refactored !hasModelResources branch to delegate to the helper
  • init_adopt.go -- wired setup + verification into runInitFromAzureYaml; deployment parsing, verification, UX improvements
  • init_adopt_test.go -- unit tests for foundryDeployments parser
  • project/config.go -- added yaml struct tags to Deployment types

Fixes: #8922

trangevi and others added 5 commits July 1, 2026 15:38
…on path

When 'azd ai agent init -m <azure.yaml>' points at a unified Foundry
azure.yaml, the adoption path now runs subscription selection and
Foundry project configuration (existing vs new) after scaffolding,
matching the agent-manifest flow.

Extracts the shared subscription + Foundry project selection logic from
configureModelChoice's !hasModelResources branch into a standalone
configureFoundryProject helper. Both the adoption path and the
agent-manifest path now call this helper, eliminating duplication.

Fixes #8922

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…project

After selecting a Foundry project, the adoption path now checks each model
deployment declared in the azure.yaml against existing deployments in the
project. For each deployment, the user can:

- Use an existing matching deployment (removes it from azure.yaml)
- Deploy as specified (keeps it for provisioning)
- Choose a different model (full catalog + deployment prompt)
- Skip (removes from azure.yaml)

The first selected deployment's name is persisted as
AZURE_AI_MODEL_DEPLOYMENT_NAME (same env var as the manifest path).

In --no-prompt mode, existing matches are auto-used and unmatched models
are auto-deployed.

Closes #8922

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Tests cover:
- foundryDeployments: single/multiple deployments, missing sections,
  non-project hosts, empty/malformed content, partial fields
- stringField: correct type, wrong type, missing, empty
- intField: int, float64, wrong type, missing

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace map[string]any manual extraction with typed structs
(azureYamlServices, azureYamlService) that unmarshal directly into
project.Deployment. This gives strong typing at parse time and removes
the stringField/intField helpers.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Makes the YAML field mapping an explicit contract rather than relying
on yaml.v3's lowercase-field-name fallback behavior.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions github-actions Bot added the ext-agents azure.ai.agents extension label Jul 1, 2026
…ion path

When --model-deployment is provided, auto-select the named deployment from
the Foundry project without interactive prompts (error if not found).
When --model is provided, pre-select it as the default in the catalog
prompt when the user chooses a different model.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@trangevi trangevi marked this pull request as ready for review July 1, 2026 23:52
@trangevi trangevi requested a review from JeffreyCA as a code owner July 1, 2026 23:52
Copilot AI review requested due to automatic review settings July 1, 2026 23:52
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown

📋 Prioritization Note

Thanks for the contribution! The linked issue isn't in the current milestone yet.
Thank you for logging this issue; our team is reviewing it. If you need urgent prioritization, tag @RickWinter and @kristenwomack to let us know.

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.

Pull request overview

This PR fixes issue #8922, where azd ai agent init -m <azure.yaml> pointed at a unified Foundry azure.yaml scaffolded the project but returned early without running any interactive Azure setup (subscription selection, Foundry project selection, model verification), leaving an environment that could not provision. It wires the interactive setup into the unified adoption path (runInitFromAzureYaml) so it matches the agent-manifest flow.

Changes:

  • Extracts the shared subscription + Foundry project selection logic out of configureModelChoice's !hasModelResources branch into a new reusable configureFoundryProject helper (returning Credential + FoundryProject), and delegates to it from init.go.
  • Adds a model-deployment verification phase to the adoption path: parses deployments from azure.yaml, compares them against the selected project's existing deployments, and lets the user use-existing / deploy / choose-different / skip (auto-resolved under --no-prompt), rewriting azure.yaml and persisting AZURE_AI_MODEL_DEPLOYMENT_NAME.
  • Adds explicit yaml struct tags to project.Deployment/DeploymentModel/DeploymentSku and a table-driven test for the new foundryDeployments parser.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
cli/azd/extensions/azure.ai.agents/internal/project/config.go Adds yaml tags to Deployment types (additive; matches yaml.v3 default lowercasing).
cli/azd/extensions/azure.ai.agents/internal/cmd/init.go Refactors the !hasModelResources branch to delegate to configureFoundryProject.
cli/azd/extensions/azure.ai.agents/internal/cmd/init_foundry_project_setup.go New file; the extracted configureFoundryProject helper (project-id / deferred / no-prompt / interactive modes).
cli/azd/extensions/azure.ai.agents/internal/cmd/init_adopt.go Wires subscription/Foundry setup and deployment verification into runInitFromAzureYaml; adds parsing, prompting, and azure.yaml rewrite logic.
cli/azd/extensions/azure.ai.agents/internal/cmd/init_adopt_test.go Tests for foundryDeployments; adds two skipped placeholder stubs for removed helpers.

Key findings:

  • Critical: the "rewrite azure.yaml" guard compares only list lengths (init_adopt.go:747). The "Choose a different model" flow replaces a deployment without changing the count, so a single-model manifest where the user swaps the model never gets rewritten — provisioning keeps the original model while AZURE_AI_MODEL_DEPLOYMENT_NAME points at the new one.
  • Nit: two always-skipped placeholder tests for removed helpers add no coverage and should be deleted.

Comment thread cli/azd/extensions/azure.ai.agents/internal/cmd/init_adopt.go Outdated
Comment thread cli/azd/extensions/azure.ai.agents/internal/cmd/init_adopt_test.go Outdated

@jongio jongio left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

The extraction of configureFoundryProject is a clean refactor that removes real duplication. The deployment verification flow for the adoption path is well-structured and the typed YAML parsing is a good choice over map[string]any. Two issues to address before merging.

  1. The azure.yaml rewrite guard has a logic gap when the user swaps a model (count stays the same but content changes).
  2. Non-deterministic service assignment for replacement deployments that don't match any original entry.

Comment thread cli/azd/extensions/azure.ai.agents/internal/cmd/init_adopt.go Outdated
Comment thread cli/azd/extensions/azure.ai.agents/internal/cmd/init_adopt.go Outdated
Comment thread cli/azd/extensions/azure.ai.agents/internal/cmd/init_adopt_test.go Outdated
Comment thread cli/azd/extensions/azure.ai.agents/internal/cmd/init_adopt.go Outdated
trangevi and others added 2 commits July 2, 2026 10:16
- Fix azure.yaml rewrite guard: use a 'modified' flag instead of
  length-only comparison, so model swaps via 'Choose a different model'
  correctly trigger a rewrite.
- Fix non-deterministic service assignment: return keptEntries with
  ServiceName preserved from the original entry, eliminating the
  map-iteration fallback.
- Fix deferred project path: return deploymentsToKeep as
  referencedDeployments when AZURE_AI_PROJECT_ID is empty, so
  AZURE_AI_MODEL_DEPLOYMENT_NAME is still written.
- Delete always-skipped TestStringField and TestIntField stubs.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Show model details and prompt for confirmation even when creating a
  new project (no early return on empty AZURE_AI_PROJECT_ID).
- Skip redundant 'Deploy as specified' option when an exact match exists.
- Skip intermediate catalog/existing prompt when no deployments exist.
- Use context-appropriate messaging (no 'not found in project' when
  there is no project yet).
- Remove deployment from azure.yaml when user picks an existing one
  via 'Choose a different model' (no provisioning needed).
- Update 'matching deployments' message for clarity.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

@jongio jongio left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Both issues from my prior review are addressed:

  1. The length-only rewrite guard is replaced by a modified flag set at each decision point. Cleaner than the content comparison I suggested.
  2. Non-deterministic service assignment is eliminated by returning []foundryDeploymentEntry with ServiceName preserved from the original entry.

The --model-deployment and --model flag wiring, isExisting distinction in promptAlternativeDeployment, and the exact-match check for hiding redundant "Deploy as specified" are all solid additions.

@trangevi trangevi merged commit 9f00a66 into main Jul 2, 2026
27 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ext-agents azure.ai.agents extension

Projects

None yet

Development

Successfully merging this pull request may close these issues.

azd ai agent init -m <azure.yaml> skips interactive environment setup (subscription, Foundry project, model)

5 participants