fix(agents): update container deploy schema to use protocol_versions and container_configuration#8829
Conversation
…and container_configuration Migrate container deploy API schema: - container_protocol_versions -> protocol_versions (unified with code deploy) - top-level image -> container_configuration.image UnmarshalJSON maintains backward compatibility by reading legacy fields (container_protocol_versions, top-level image) and migrating them to the new schema. Fixes #8828 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
📋 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
Updates the azure.ai.agents extension’s hosted/container agent wire schema to match the latest service TypeSpec by unifying protocol versions under protocol_versions and moving the container image under container_configuration.image, while keeping backward-compatible deserialization for legacy responses.
Changes:
- Introduces
ContainerConfigurationAPIand updatesHostedAgentDefinitionJSON serialization/deserialization to useprotocol_versions+container_configuration(with legacy-field migration on unmarshal). - Updates container deploy request construction and display logic to read/write
ContainerConfiguration.Image. - Updates unit tests to validate the new schema and legacy unmarshal behavior.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| cli/azd/extensions/azure.ai.agents/internal/project/service_target_agent.go | Displays hosted agent image from ContainerConfiguration.Image. |
| cli/azd/extensions/azure.ai.agents/internal/pkg/agents/agent_yaml/map.go | Builds container deploy requests using container_configuration.image. |
| cli/azd/extensions/azure.ai.agents/internal/pkg/agents/agent_yaml/map_test.go | Updates assertions to validate container image is set via ContainerConfiguration. |
| cli/azd/extensions/azure.ai.agents/internal/pkg/agents/agent_api/models.go | Adds ContainerConfigurationAPI, switches to protocol_versions, and migrates legacy fields on unmarshal. |
| cli/azd/extensions/azure.ai.agents/internal/pkg/agents/agent_api/models_test.go | Updates schema expectations and adds a legacy-unmarshal test. |
| cli/azd/extensions/azure.ai.agents/internal/cmd/optimize_deploy.go | Normalizes/migrates protocol versions to protocol_versions when cloning definitions. |
| cli/azd/extensions/azure.ai.agents/internal/cmd/optimize_deploy_test.go | Updates optimize deploy definition tests for the new schema/migration behavior. |
jongio
left a comment
There was a problem hiding this comment.
CI is failing: golangci-lint reports a gofmt error in optimize_deploy_test.go:124. The map literal in TestBuildDeployDefinition_NormalizesProtocolVersion mixes alignment styles (some keys padded, some not). Running gofmt -s -w . should fix it.
Beyond the formatting issue, one functional gap: normalizeProtocolVersions now migrates the legacy container_protocol_versions field to protocol_versions on raw maps, but there is no equivalent migration for the legacy top-level image field to container_configuration.image. Since AgentVersionObject.Definition is typed as any (line 299 of models.go), the service response is stored as a raw map[string]any that never passes through HostedAgentDefinition.UnmarshalJSON. If the service still returns the legacy schema, the optimize-deploy path will forward image unchanged in new version requests.
The overall approach (unifying to protocol_versions, removing custom MarshalJSON, adding backward-compat UnmarshalJSON) is solid and well-tested.
- Add normalizeContainerImage() to migrate legacy top-level 'image' to 'container_configuration.image' on raw maps (optimize-deploy path) - Guard displayAgentInfo against empty ContainerConfiguration.Image - Use JSON map parsing in test instead of string.Contains for schema validation - Add tests for normalizeContainerImage
jongio
left a comment
There was a problem hiding this comment.
My earlier inline concern about the optimize-deploy raw map path still applies: normalizeProtocolVersions migrates legacy container_protocol_versions to protocol_versions in buildDeployDefinition, but there is no equivalent for the legacy top-level image field to container_configuration.image. Since extractLatestDefinition produces a map[string]any (bypassing HostedAgentDefinition.UnmarshalJSON), any legacy image from the service response would pass through unchanged in new version requests.
If the service can still return old-schema responses for existing agent versions, consider adding a normalizeContainerConfiguration function alongside normalizeProtocolVersions. If the service has fully migrated all responses to the new schema, this can be safely ignored.
trangevi
left a comment
There was a problem hiding this comment.
Comment isn't blocking, but something to consider in addition to Jon's comments
Summary
Migrate container deploy API schema to match the latest service-side TypeSpec definition:
container_protocol_versions→protocol_versions(unified with code deploy)image→container_configuration.imageReference
Schema change is documented in the official REST API reference:
https://learn.microsoft.com/en-us/azure/foundry/agents/how-to/deploy-hosted-agent?pivots=rest#create-an-agent
The documented create-agent payload uses:
json { "definition": { "kind": "hosted", "container_configuration": { "image": "myacr.azurecr.io/my-agent:v1" }, "protocol_versions": [ {"protocol": "responses", "version": "1.0.0"} ], "cpu": "1", "memory": "2Gi" } }Changes
ContainerConfigurationAPIstruct, updatedHostedAgentDefinitionto useprotocol_versions(via struct tag) andcontainer_configurationfor container image. Removed customMarshalJSON. UpdatedUnmarshalJSONfor backward compat with legacy fields.ContainerConfigurationinstead of bareImage.normalizeProtocolVersionshandles both new and legacy field names. AddednormalizeContainerImageto migrate legacy top-levelimageon raw maps (service responses bypass UnmarshalJSON).ContainerConfiguration.Imagewith empty-string guard.Backward Compatibility
UnmarshalJSONstill reads legacy API responses that usecontainer_protocol_versionsand top-levelimage, migrating them to the new schema in memory. The optimize-deploy path also normalizes raw definition maps vianormalizeContainerImageandnormalizeProtocolVersions.Fixes #8828