Fix azd ai agent init -m behavior when adding to existing projects#7645
Conversation
There was a problem hiding this comment.
Pull request overview
This PR improves the azd ai agent init -m experience when adding an agent to an existing azd project by making reuse of existing project state explicit, reusing an already-configured Foundry project from the azd environment, and preventing silent overwrites via collision detection.
Changes:
- Print a message when an existing azd project is detected and warn when
infra/scaffolding is missing. - Reuse
AZURE_AI_PROJECT_IDfrom the current azd environment to avoid re-prompting for Foundry project selection. - Detect collisions for auto-generated
src/<agent-name>andazure.yamlservice names; prompt (interactive) or auto-suffix (no-prompt) to avoid silent overwrites.
jongio
left a comment
There was a problem hiding this comment.
CI is failing: golangci-lint reports gosec G703: Path traversal via taint analysis on fileExists in helpers.go:380. The new resolveCollisions and nextAvailableName functions create a taint path through this function with manifest-derived names.
Quick fix: add //nolint:gosec // path is constructed from manifest name, not raw user input to fileExists in helpers.go - consistent with the existing nolint on MkdirAll (init.go:1245). Or, if you'd rather address the path-sanitization comment on the rename prompt first, that would also fix the taint chain.
…ion and improving project detection messages
jongio
left a comment
There was a problem hiding this comment.
Solid set of changes - the collision detection, env var reuse, and existing-project messaging all address the reported issues well. Input validation in validateRenameInput is thorough and the tests cover the important pure-function paths nicely.
Two things stood out: the rename flow doesn't re-verify that the user's freeform name is collision-free (the default suffix handles it in practice, but a determined user can still type an existing name), and a malformed AZURE_AI_PROJECT_ID env var produces a confusing error that references --project-id. Neither is blocking, but both are worth addressing.
Also noting the PR currently has merge conflicts that need resolution.
| )) | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
The user-provided rename name is format-validated by validateRenameInput, but it's never re-checked for collisions against existing directories or service names. If someone types a name that already exists, it'll silently proceed to overwrite - which is the exact scenario this collision detection is trying to prevent.
Consider re-checking fileExists(newDir) and a.projectConfig.Services after validation, and either looping the prompt or returning an error when the chosen name still collides. The default suggestion from nextAvailableName avoids this in practice, but freeform input isn't guarded.
| )) | ||
| } | ||
| } | ||
|
|
There was a problem hiding this comment.
When AZURE_AI_PROJECT_ID from the environment is malformed, the error at the extractProjectDetails call below says "invalid --project-id value" - but the user never passed --project-id. This'll send them debugging their CLI flags when the problem is in their azd environment.
Consider either (a) using a different error message when the value came from the environment (e.g., "invalid AZURE_AI_PROJECT_ID in environment: ..."), or (b) logging a warning and falling back to the prompt flow instead of hard-failing.
Fixes #7644.
Problem
When running azd ai agent init -m in a directory that already has an azure.yaml:
Changes
Existing project transparency — ensureProject() now prints "Found existing azd project at " when reusing an existing project, and warns if the infra/ directory is missing.
Reuse Foundry project from environment — configureModelChoice() checks for an existing AZURE_AI_PROJECT_ID in the azd environment before prompting. When found, it reuses the project (same behavior as --project-id), skipping the "Use existing / Create new Foundry project" prompt.
Collision detection — When the auto-computed src/ directory or azure.yaml service already exists: