Skip to content

fix(agents): prompt for unified config env values#9212

Open
glharper wants to merge 7 commits into
mainfrom
glharper/9110-prompt-unified-env-vars
Open

fix(agents): prompt for unified config env values#9212
glharper wants to merge 7 commits into
mainfrom
glharper/9110-prompt-unified-env-vars

Conversation

@glharper

Copy link
Copy Markdown
Member

Summary

  • prompt for unset bare ${VAR} references in adopted Foundry service configuration during azd ai agent init
  • persist prompted values to the active azd environment and mask credential-like inputs
  • preserve existing values, ${VAR:-default}, Foundry ${{...}}, hook variables, and --no-prompt behavior

Testing

  • go test ./... -count=1
  • go build ./...
  • golangci-lint run ./internal/cmd/...

Fixes #9110

Prompt for unset bare ${VAR} references in adopted Foundry service configuration and persist the responses to the active azd environment. Preserve defaults, Foundry expressions, existing values, hook behavior, and --no-prompt execution.

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

Copilot-Session: b4617dfd-adfb-4b30-9222-477a041f8af9
Copilot AI review requested due to automatic review settings July 20, 2026 14:07
@github-actions

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.

@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
21 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

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

Adds prompting and persistence for missing environment references in adopted Foundry configurations.

Changes:

  • Detects bare ${VAR} references while excluding defaults, hooks, and escaped references.
  • Masks credential-like prompts and saves responses to the active environment.
  • Integrates the flow into unified azure.yaml adoption with tests.

Reviewed changes

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

File Description
init_env.go Implements reference discovery, prompting, and persistence.
init_env_test.go Tests detection, masking, persistence, and no-prompt behavior.
init_adopt.go Invokes environment configuration during adoption.

Comment thread cli/azd/extensions/azure.ai.agents/internal/cmd/init_env.go Outdated
Comment thread cli/azd/extensions/azure.ai.agents/internal/cmd/init_env.go Outdated
Co-authored-by: glharper <64209257+glharper@users.noreply.github.com>
Copilot AI review requested due to automatic review settings July 20, 2026 14:28

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

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

Comment thread cli/azd/extensions/azure.ai.agents/internal/cmd/init_env.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.

Traced the `` resolution through foundry.ResolveFileRefs (sibling keys overlay the loaded object) and confirmed the `${{...}}` masking is multiline-aware before the env-ref regex runs. Escape handling, `:-` default skipping, hooks exclusion, and secret-upgrade dedup all line up with the tests. Nothing blocking from me.

Comment thread cli/azd/extensions/azure.ai.agents/internal/cmd/init_env.go Outdated
Mask prompted values only when the reference appears under explicit credential or secret configuration. Avoid inferring sensitivity from arbitrary environment variable names while continuing to prompt for all unset Foundry references.

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

Copilot-Session: b4617dfd-adfb-4b30-9222-477a041f8af9
Copilot AI review requested due to automatic review settings July 20, 2026 22:05
@glharper
glharper requested a review from trangevi July 20, 2026 22:05

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

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

Comment thread cli/azd/extensions/azure.ai.agents/internal/cmd/init_env.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.

init_env.go:78 - the missing-value check reads from GetValues, which returns only persisted dotenv entries. Foundry expansion resolves unset refs from the process environment as well (synthesis/synthesizer.go maybeExpand falls back to os.LookupEnv). A var that is exported in the shell but absent from the azd env is treated as missing here, so we prompt for it and then persist a value that shadows the exported one. Mirroring the same dotenv-first, process-env fallback lookup (while still counting an explicitly empty dotenv entry as missing) avoids the spurious prompt. A process-env-only regression test would lock it in.

Use persisted azd values first and fall back to the process environment before prompting for unified Foundry references. Keep explicitly empty persisted values missing so users can replace them interactively.

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

Copilot-Session: b4617dfd-adfb-4b30-9222-477a041f8af9
Copilot AI review requested due to automatic review settings July 21, 2026 20:49

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

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

Comment thread cli/azd/extensions/azure.ai.agents/internal/cmd/init_env.go Outdated
Persist process-only values referenced by unified Foundry services into the active azd environment. This keeps providers that resolve only persisted values consistent while preserving explicit empty azd values as prompt-required.

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

Copilot-Session: b4617dfd-adfb-4b30-9222-477a041f8af9
Copilot AI review requested due to automatic review settings July 21, 2026 21:08

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

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

cli/azd/extensions/azure.ai.agents/internal/cmd/init_env.go:84

  • [azd-code-reviewer] An explicitly set but empty process variable is treated as resolved and persisted, even though this function treats an empty azd value as missing and the Foundry expander resolves the bare reference to an empty string. This leaves provisioning with the same unusable value instead of prompting. Require the process value to be non-empty and add the matching regression case.
		if value, ok := os.LookupEnv(reference.Name); ok {

Comment thread cli/azd/extensions/azure.ai.agents/internal/cmd/init_env.go

@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.

Non-blocking follow-up: reference discovery walks every scalar in a Foundry service, but deployments are copied verbatim by the synthesizer (deployments := svc.Deployments in synthesis/synthesizer.go, with no expandValue) and read raw by foundryDeployments in init_adopt.go. So a ${VAR} inside a deployment model or sku would get prompted and persisted here, then still reach verification and provisioning as a literal ${VAR}, so the persisted value is never used for that field. Connections, metadata, and network all go through the expander, so those references are handled correctly. Scoping discovery to the fields each provider actually expands would keep the prompt from implying a field is configured when it isn't.

Limit unified init environment discovery to the fields each Foundry provider actually expands, including deprecated nested agent, toolbox, and routine configuration. Treat empty process values as missing instead of persisting unusable values.

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

Copilot-Session: b4617dfd-adfb-4b30-9222-477a041f8af9

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

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (3)

cli/azd/extensions/azure.ai.agents/internal/cmd/init_env.go:32

  • [azd-code-reviewer] This scans the deprecated config.environmentVariables even when the inline agent definition is active. AgentDefinitionFromService/ServiceConfigProps select one shape (internal/project/agent_definition.go:182-228), so a stale ${VAR} in the ignored shape is still prompted for and persisted. Apply the same inline-versus-config precedence before traversing these paths.
		{"config", "environmentVariables", "*", "value"},

cli/azd/extensions/azure.ai.agents/internal/cmd/init_env.go:46

  • [azd-code-reviewer] Routine deployment uses config only when there are no inline additional properties (azure.ai.routines/internal/cmd/service_target.go:140-159), but discovery always scans this legacy path. A mixed/migrated service can therefore prompt for and persist a variable from configuration the provider ignores. Select the active routine shape first, then scan only its action.input.
		{"config", "action", "input"},

cli/azd/extensions/azure.ai.agents/internal/cmd/init_env.go:52

  • [azd-code-reviewer] Toolbox parsing similarly prefers any inline properties and falls back to config only when inline properties are empty (azure.ai.toolboxes/internal/cmd/service_target.go:304-323). Scanning both shapes makes stale legacy ${VAR} references trigger prompts even though deployment never reads them. Mirror the provider's shape precedence before scanning endpoint/tools.
		{"config", "endpoint"},
		{"config", "tools"},

@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 scoping change addresses my earlier follow-up: discovery now walks only the fields each Foundry provider expands (network on project and foundry, target/credentials/metadata on connection, endpoint/tools on toolbox, action input on routine, plus the deprecated config nesting). A ${VAR} inside a deployment model or sku no longer gets prompted and persisted as a value that provisioning never reads. The empty-process-value guard and the per-provider tests cover the cases I raised.

Mirror provider precedence when discovering environment references so inline agent, toolbox, and routine configuration suppresses stale deprecated config values. Preserve config fallback when no active inline shape exists.

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

Copilot-Session: b4617dfd-adfb-4b30-9222-477a041f8af9
Copilot AI review requested due to automatic review settings July 22, 2026 14:15
@glharper

Copy link
Copy Markdown
Member Author

Addressed the latest suppressed review findings in e1020e4 by mirroring each provider's active-shape precedence:

  • agents scan inline environment variables only when root kind marks an inline definition; otherwise they fall back to config.kind
  • routines and toolboxes scan inline fields whenever the service has additional inline properties; config: is scanned only when the provider would fall back to it
  • mixed/migrated services no longer prompt for stale variables in the ignored shape

Added regressions covering legacy config fallback and inline-over-stale-config precedence for all three providers.

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

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.

@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 precedence change lines up with each provider's inline-versus-config selection: agent discovery gates on a non-empty kind like AgentDefinitionFromService/structHasKind, and routine/toolbox gate on inline additional properties matching parseRoutineServiceConfig/parseToolboxServiceConfig (inline wins, config only when inline is empty). The azureYamlCoreServiceFields set matches the 18 serialized ServiceConfig keys, so a service with any real inline property is no longer scanned through its stale config: shape. The inline-wins and legacy-config-only tests cover it. Nothing blocking from me.

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 does not prompt for environment variables referenced by unified azure.yaml 

5 participants