fix(agents): resolve remote invoke name from inline service config#9114
fix(agents): resolve remote invoke name from inline service config#9114glharper wants to merge 1 commit into
Conversation
Brownfield init against an existing Foundry project writes the hosted agent name inline in the azure.ai.agent service, but does not populate the deployed AGENT_<SERVICE>_NAME environment output. Remote invoke only consulted that env value, so an otherwise valid unified azure.yaml service resolved with an empty agent name and failed with the misleading "agent name is required" error. Seed AgentServiceInfo.AgentName from the inline/config-nested hosted-agent definition, then let AGENT_<SERVICE>_NAME override it after deployment. Do not fall back to the azure.yaml service key because the service and deployed agent names may intentionally differ. Adds regression coverage for pre-deploy/brownfield inline-name resolution and for deployed environment output retaining precedence. Fixes #9109 Co-authored-by: Copilot <[email protected]> Copilot-Session: ea5e8124-350f-4420-b3dc-f88011b2aa74
📋 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
Fixes brownfield remote agent invocation by resolving the deployed agent name from inline service configuration.
Changes:
- Uses inline hosted-agent names before deployment outputs exist.
- Preserves environment output precedence.
- Adds regression tests for both resolution paths.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
internal/cmd/helpers.go |
Adds inline agent-name fallback resolution. |
internal/cmd/helpers_test.go |
Tests fallback and deployed-name precedence. |
There was a problem hiding this comment.
Verified the fix locally. Seeding the agent name from the inline hosted-agent definition before reading AGENT_<SERVICE>_NAME correctly fixes brownfield pre-deploy remote invoke, and the environment output still wins once it exists since it's applied after. All callers already guard on a non-empty AgentName, so no downstream regression. Both regression tests pass here.
trangevi
left a comment
There was a problem hiding this comment.
This feels like the wrong fix to me. If I understand what we're doing correctly, we're resolving the agent name from the azure.yaml, because the env var that we populate at deployment time doesn't exist. This means we haven't deployed yet, which also means we shouldn't be able to invoke that agent. Adding handling which allows a user to invoke against a previously existing deployed agent just because the names match has the potential to lead to unexpected confusion due to different code, protocols, etc.
In the case where a user has an azure.yaml without the corresponding env var, we should probably fail invoke, saying that the agent doesn't appear to have been deployed yet.
If the claim in the corresponding work item is that users should be able to invoke agents in existing projects by redefining the agent in the local azure.yaml, I don't think that's correct. They can already invoke without the need for an azd project at all, we added that support, I don't think we should introduce this potential logic split.
|
I traced the remote invoke path to sanity-check @trangevi's concern about invoking before deploy. The endpoint isn't gated on deploy. In project mode, The thing is, that capability already exists without this PR. So the real question isn't "should undeployed agents be invokable", since the explicit-name and If we do want a guard, the cleaner spot is a pre-invoke "not deployed / agent not found" check that applies to all three name-resolution paths, so the behavior stays consistent regardless of how the agent name is supplied. |
What
Remote
azd ai agent invokefailed after initializing a unifiedazure.yamlagainst an existing (brownfield) Foundry project, even though theazure.ai.agentservice and its agent name were declared inline.The command failed with the misleading fallback error that an agent name was required.
Root cause
resolveAgentServiceFromProjectpopulatedAgentServiceInfo.AgentNameonly from the deployed environment output:That output is written after deployment. Brownfield init writes the hosted-agent definition — including its
name— inline on theazure.ai.agentservice, but does not create the deploy output. Therefore explicit-protocol remote invoke (--protocol invocationsin the repro) resolved the service successfully but left the target agent name empty.Using the
azure.yamlservice key as a fallback would be unsafe because the service key and deployed agent name may intentionally differ.Fix
project.AgentDefinitionFromService).AGENT_<SERVICE>_NAME; when present, it overrides the inline definition because it reflects the resource actually deployed.This lets remote invoke work immediately for the reported brownfield/unified configuration while preserving deployed-name precedence after
azd deploy.Tests
TestResolveAgentServiceFromProject_UsesInlineNameBeforeDeployreproduces the issue: service key differs from the inline agent name and noAGENT_<SERVICE>_NAMEexists. The inline name is resolved.TestResolveAgentServiceFromProject_EnvironmentNameWinsverifies deployed environment output remains authoritative when it differs from the inline definition.Validation
go build ./...go test ./... -count=1(all extension packages)go vet ./...gofmtcleangolangci-lint run ./internal/cmd/...— 0 issuescspell— 0 issuesNo
CHANGELOG.mdentry is included; extension changelog entries are added during the release process.Fixes #9109