Skip to content

feat(agents): deploy using an existing acr image#8104

Open
huimiu wants to merge 9 commits intoAzure:mainfrom
huimiu:hui/existing-image
Open

feat(agents): deploy using an existing acr image#8104
huimiu wants to merge 9 commits intoAzure:mainfrom
huimiu:hui/existing-image

Conversation

@huimiu
Copy link
Copy Markdown
Member

@huimiu huimiu commented May 8, 2026

#7988
This pull request adds support for using pre-built container images when deploying hosted agents, allowing users to skip Dockerfile builds and pushes if an image is specified in agent.yaml. The implementation prompts the user to choose between using the pre-built image or building a new one, and this decision is cached per deployment.

  • Added an Image field to the ContainerAgent struct, allowing users to specify a pre-built container image in agent.yaml. If set, this image is used for deployment instead of building from a Dockerfile.
  • Updated the deployment logic to prompt the user when a pre-built image is present, caching the decision and skipping build/publish steps if the pre-built image is chosen.
  • Implemented helper methods to manage user choice and image resolution from agent.yaml.

Test

  • Build it for me by dafault:
    image
  • Deploying:
    image
  • Deploying (no prompt):
    image

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds support in the azure.ai.agents azd extension for deploying hosted/container agents using a pre-built container image specified in agent.yaml, optionally skipping Dockerfile-based build/package/publish steps.

Changes:

  • Introduces an image field on agent_yaml.ContainerAgent and wires it through hosted-agent API request mapping.
  • Updates hosted-agent deployment flow to prompt once per deploy whether to use the configured pre-built image vs. building/publishing, and uses that choice to skip package/publish and resolve the final image URL.
  • Adds unit tests covering image parsing, prompt caching, and package/publish skipping behavior.

Reviewed changes

Copilot reviewed 6 out of 6 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/service_target_agent.go Adds pre-built image selection/caching and uses it to skip package/publish and resolve deploy image URL.
cli/azd/extensions/azure.ai.agents/internal/project/service_target_agent_test.go Adds prompt-service stubs and tests for pre-built image behavior in package/publish and helper methods.
cli/azd/extensions/azure.ai.agents/internal/pkg/agents/agent_yaml/yaml.go Adds Image field to ContainerAgent YAML/JSON model and documents intended behavior.
cli/azd/extensions/azure.ai.agents/internal/pkg/agents/agent_yaml/parse_test.go Adds parse/round-trip coverage for the new image field in manifest/template YAML.
cli/azd/extensions/azure.ai.agents/internal/pkg/agents/agent_yaml/map.go Defaults hosted-agent image URL from agent.yaml (still allowing buildConfig override) and updates error messaging.
cli/azd/extensions/azure.ai.agents/internal/pkg/agents/agent_yaml/map_test.go Adds tests validating agent image usage and buildConfig override precedence.

Comment thread cli/azd/extensions/azure.ai.agents/internal/project/service_target_agent.go Outdated
Comment thread cli/azd/extensions/azure.ai.agents/internal/pkg/agents/agent_yaml/yaml.go Outdated
huimiu and others added 2 commits May 8, 2026 17:48
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

@wbreza wbreza left a comment

Choose a reason for hiding this comment

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

Code Review — PR #8104

Overall: ✅ Well-structured PR — no blockers. Caching logic is correct, image priority works properly, and test coverage is solid for happy paths.

Findings

🟡 Medium

M1 — getPreBuiltImageURL silently swallows parse errors (service_target_agent.go ~lines 638–649)
Returns "" on both file-read and YAML-unmarshal errors. If agent.yaml exists but has a syntax error around the image: field, the pre-built image prompt is silently skipped with no user indication. Other paths in the same file (Deploy flow) properly propagate parse errors.
Suggestion: Distinguish "file not found" (acceptable silent empty) from "file exists but parse failed" (should warn or propagate).

M2 — Missing test for prompt cancellation/error path (service_target_agent_test.go)
shouldUsePreBuiltImage wraps prompt errors with exterrors.FromPrompt(...), but this path is untested. Should verify error propagates and cache stays nil for retries.

M3 — Missing complementary test cases (service_target_agent_test.go)
No test for Publish proceeding normally when user chose Dockerfile (usePreBuiltImage = false), and no test for getPreBuiltImageURL with malformed YAML.

🔵 Low

L1 — Redundant YAML re-read (service_target_agent.go)
getPreBuiltImageURL independently reads and parses agent.yaml; the Deploy flow re-reads it. Could accept the parsed struct or cache the parse result to avoid TOCTOU inconsistency.

L2 — Implicit non-interactive behavior (service_target_agent.go)
When running with --no-prompt, Prompt().Select() may default to pre-built (index 0) or error. The intended CI/CD behavior should be documented.

L3 — No empty-endpoint guard (service_target_agent.go)
registerAgentEnvironmentVariables doesn't guard against empty AZURE_AI_PROJECT_ENDPOINT, though the deploy path validates it upstream.

What Looks Good 👍

  • Caching pattern (*bool tri-state) is correct and idiomatic
  • Image priority (YAML image > published artifact) works properly
  • Prompt UX displays actual image URL with sensible default
  • YAML/JSON tags follow existing conventions
  • Solid test coverage for parse, caching, and skip behaviors

Comment thread cli/azd/extensions/azure.ai.agents/internal/project/service_target_agent.go Outdated
Comment thread cli/azd/extensions/azure.ai.agents/internal/project/service_target_agent.go Outdated
func (p *AgentServiceTargetProvider) shouldUsePreBuiltImage(
ctx context.Context,
) (bool, error) {
// Return cached decision if already prompted
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.

@therealjohn, do we actually want this cached? Without some way to detect underlying code changes, this could possibly lead to unexpected behavior, or multiple deployments when a user realizes they won't be prompted again.

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.

Safer for now to not cache it - but provide a way to --no-prompt so an agent can deploy or CI/CD can work.

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.

Worth noting: the prompt default is index 0 (pre-built image). In --no-prompt mode, the host returns the default, so CI/CD would silently use the pre-built image instead of building. If "build" is the safer CI default, swap the choice order or set defaultIndex to 1.

Copy link
Copy Markdown
Member Author

@huimiu huimiu May 9, 2026

Choose a reason for hiding this comment

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

Thanks for catching this. I've updated the prompt so that:

In both interactive and non-interactive (AZD_NO_PROMPT=true) mode, build from Dockerfile is always the default, interactive mode prompts the user to explicitly opt into the pre-built image, while non-interactive mode skips the prompt entirely and always builds.

Copy link
Copy Markdown
Member

@jongio jongio left a comment

Choose a reason for hiding this comment

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

One test gap I didn't see covered in existing feedback:

TestShouldUsePreBuiltImage_PromptsForConfiguredImage exercises the "build" path (index 1) but not the pre-built path (index 0). The feature's happy path through the prompt isn't tested - only via preset caching in TestShouldUsePreBuiltImage_CachesDecision.

Comment thread cli/azd/extensions/azure.ai.agents/internal/project/service_target_agent_test.go Outdated
@huimiu huimiu requested review from jongio, therealjohn and trangevi May 9, 2026 08:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants