feat(agents): native Activity protocol support (use-case profiles, digital-worker init/deploy)#8753
feat(agents): native Activity protocol support (use-case profiles, digital-worker init/deploy)#8753Hameedkunkanoor wants to merge 3 commits into
Conversation
Make activity_protocol a first-class protocol so hosted activity agents deploy
end-to-end with azd provision + azd deploy (no custom scripts/hooks):
- Send Foundry-Features AgentEndpoints header on CreateAgent/PatchAgent so the
agent_endpoint (protocols + authorization_schemes) is honored by the service.
- Auto-inject the activity endpoint protocol + BotServiceRbac auth scheme for
activity agents when not declared in agent.yaml.
- Inject BlueprintReference from MAIB_NAME; normalize activity->activity_protocol.
- Resolve agent name from AGENT_{serviceKey}_NAME in postdeploy (fixes 404 when
agent.yaml name differs from the azure.yaml service name).
- Add native M365 registration (best-effort): post-provision OAuth2 grants +
blueprint owner; post-deploy digital-worker publish + Teams backend config.
- Add unit tests for the new behavior.
…, and onboarding next-steps Builds on native activity-protocol support with use-case profiles and end-to-end azd init/provision/deploy for digital workers. - agent_yaml: add ActivityConfig.use_case (simple|digital_worker), ActivityProfile, IsActivityProtocol(), and ResolveActivityProfile(hasBlueprintEnv). Profile gates activity-endpoint injection, BotServiceRbac, blueprint reference, and M365 provision/publish. - service_target_agent: resolve the activity profile in prepareDeploy and gate blueprint/BotServiceRbac injection on it; ensureActivityEndpointDefaults takes the profile; append a visible digital-worker onboarding next-steps note (admin-center approval, blueprint ID, Teams instance) to the deploy artifact so it surfaces in azd deploy output. - listen.go: digitalWorkerEnvUpdate preprovision hook sets ENABLE_DIGITAL_WORKER and AGENT_NAME so the starter-template infra provisions MAIB + Bot Service; gate M365 provision/publish on the per-service profile. - init.go/init_from_code.go: add --activity-use-case flag and AZD_AI_STARTER_TEMPLATE override; round-trip activity use_case from manifest into agent.yaml; accept both 'activity' and 'activity_protocol' names. - Tests: new activity_profile_test.go; updated profile-aware endpoint/deploy-note tests and fixed map_test call sites. go vet + go test ./... green.
Add CHANGELOG entry for native Activity-protocol support (#8753).
There was a problem hiding this comment.
Pull request overview
This PR extends the azure.ai.agents azd extension to support Foundry’s Activity protocol end-to-end (including M365 “digital worker” scenarios) across azd ai agent init → azd provision → azd deploy, including endpoint/protocol normalization, blueprint wiring, and best-effort M365 onboarding steps.
Changes:
- Add Activity protocol support end-to-end: wire-level feature header, protocol name normalization (
activity↔activity_protocol), endpoint display/config output, and default endpoint injection (incl. BotServiceRbac for digital workers). - Introduce
activity.use_caseprofiles (simplevsdigital_worker) and propagate/use them across init/provision/deploy flows (including setting infra-driving env vars and printing onboarding next steps). - Add best-effort M365 registration/publish + Teams backend configuration logic with unit tests.
Reviewed changes
Copilot reviewed 20 out of 20 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| cli/azd/extensions/azure.ai.agents/version.txt | Bump extension version. |
| cli/azd/extensions/azure.ai.agents/extension.yaml | Keep extension manifest version in sync with version.txt. |
| cli/azd/extensions/azure.ai.agents/CHANGELOG.md | Add release notes describing Activity protocol + use-case profiles changes. |
| cli/azd/extensions/azure.ai.agents/internal/project/service_target_agent.go | Inject Activity endpoint defaults, blueprint reference injection, protocol display normalization, and deploy “next steps” note augmentation. |
| cli/azd/extensions/azure.ai.agents/internal/project/service_target_agent_test.go | Add/adjust tests for activity endpoint display, artifacts, endpoint defaults, and deploy note next steps. |
| cli/azd/extensions/azure.ai.agents/internal/project/m365_registration.go | Add best-effort Graph/AzureML/Teams calls for blueprint provisioning and digital-worker publish flows. |
| cli/azd/extensions/azure.ai.agents/internal/project/m365_registration_test.go | Add unit tests for the internal authenticated HTTP client helpers. |
| cli/azd/extensions/azure.ai.agents/internal/pkg/agents/agent_yaml/yaml.go | Add activity config, activity.use_case resolution, and blueprint reference schema + helpers. |
| cli/azd/extensions/azure.ai.agents/internal/pkg/agents/agent_yaml/map.go | Normalize activity protocol for API requests and map blueprint references into CreateAgent requests. |
| cli/azd/extensions/azure.ai.agents/internal/pkg/agents/agent_yaml/map_test.go | Add tests for activity protocol normalization and blueprint reference mapping. |
| cli/azd/extensions/azure.ai.agents/internal/pkg/agents/agent_yaml/activity_profile_test.go | Add test coverage for activity protocol detection and profile resolution. |
| cli/azd/extensions/azure.ai.agents/internal/pkg/agents/agent_api/operations.go | Set Foundry feature header for Create/Patch to ensure agent_endpoint fields are honored. |
| cli/azd/extensions/azure.ai.agents/internal/pkg/agents/agent_api/operations_test.go | Add test ensuring PatchAgent sets the AgentEndpoints feature header. |
| cli/azd/extensions/azure.ai.agents/internal/pkg/agents/agent_api/models.go | Extend CreateAgentVersionRequest with blueprint_reference. |
| cli/azd/extensions/azure.ai.agents/internal/cmd/listen.go | Hook M365 provisioning/publish into lifecycle handlers and set digital-worker infra-driving env vars. |
| cli/azd/extensions/azure.ai.agents/internal/cmd/invoke.go | Clarify Activity protocol is not invocable; point users to endpoint show. |
| cli/azd/extensions/azure.ai.agents/internal/cmd/init.go | Add --activity-use-case and starter-template override via AZD_AI_STARTER_TEMPLATE. |
| cli/azd/extensions/azure.ai.agents/internal/cmd/init_from_code.go | Add activity protocol support to init-from-code flow, including activity-only skip of model prompts and profile recording. |
| cli/azd/extensions/azure.ai.agents/internal/cmd/init_from_code_test.go | Add tests for activity protocol selection/normalization and activity-only gating helpers. |
| cli/azd/extensions/azure.ai.agents/internal/cmd/helpers.go | Improve invocation error suggestion text for non-invocable protocols. |
| apiProtocol := agent_api.AgentProtocol(protocol.Protocol) | ||
| if apiProtocol == "activity" { | ||
| apiProtocol = agent_api.AgentProtocolActivityProtocol | ||
| } | ||
| protocolVersions = append(protocolVersions, agent_api.ProtocolVersionRecord{ |
| // Resolve the activity deployment profile. The use case comes from | ||
| // agent.yaml's activity.use_case when set; otherwise it falls back to the | ||
| // environment (a provisioned blueprint/MAIB implies a digital worker). | ||
| hasBlueprintEnv := azdEnv["MAIB_NAME"] != "" || azdEnv["AGENT_IDENTITY_BLUEPRINT_ID"] != "" | ||
| activityProfile := agentDef.ResolveActivityProfile(hasBlueprintEnv) |
| if versionObj.AgentGUID != "" { | ||
| if def, ok := loadContainerAgentForService(args.Project, svc); ok && | ||
| def.ResolveActivityProfile(hasBlueprintEnv).M365Publish { | ||
| agentGUIDs[agentName] = versionObj.AgentGUID | ||
| } | ||
| } |
| // Template defaults to the published starter. AZD_AI_STARTER_TEMPLATE allows | ||
| // pointing at a local clone or fork for testing infra changes before they | ||
| // land upstream (azd init -t accepts a local directory path). | ||
| starterTemplate := "Azure-Samples/azd-ai-starter-basic" | ||
| if override := os.Getenv("AZD_AI_STARTER_TEMPLATE"); override != "" { | ||
| starterTemplate = override |
|
Hi @@Hameedkunkanoor. Thank you for your interest in helping to improve the Azure Developer CLI experience and for your contribution. We've noticed that there hasn't been recent engagement on this pull request. If this is still an active work stream, please let us know by pushing some changes or leaving a comment. Otherwise, we'll close this out in 7 days. |
jongio
left a comment
There was a problem hiding this comment.
Reviewed the full +1921/-37 changeset. The overall approach is solid: the ActivityProfile resolution pattern (use_case from agent.yaml with env-var fallback) and the best-effort M365 registration design are well-structured. Two items worth addressing:
- Protocol normalization in
CreateHostedAgentAPIRequestuses a case-sensitive exact match while every other activity-protocol check in this PR uses case-insensitive comparison. This creates an inconsistency for edge-case inputs. agentDefDeclaresActivityis defined but never called (the deploy path usesactivityProfile.IsActivityinstead).
Also noting: the PR has merge conflicts that will need resolution before merge.
| if len(hostedAgent.Protocols) > 0 { | ||
| for _, protocol := range hostedAgent.Protocols { | ||
| apiProtocol := agent_api.AgentProtocol(protocol.Protocol) | ||
| if apiProtocol == "activity" { |
There was a problem hiding this comment.
This check is case-sensitive (== "activity"), but the sibling function normalizeDisplayProtocol (in service_target_agent.go) uses strings.EqualFold, and IsActivityProtocol() (in yaml.go) uses strings.ToLower. If a user writes protocol: Activity (capitalized) in agent.yaml, this branch won't fire, sending the literal string "Activity" to the API instead of normalizing it to activity_protocol.
Consider aligning with the other helpers:
| if apiProtocol == "activity" { | |
| if strings.EqualFold(string(apiProtocol), "activity") { |
(You'd need to import strings if it isn't already imported in this file.)
| // agentDefDeclaresActivity reports whether the agent definition declares the | ||
| // activity protocol. agent.yaml may use either the endpoint-level name | ||
| // "activity" or the canonical definition-level name "activity_protocol". | ||
| func agentDefDeclaresActivity(agentDef agent_yaml.ContainerAgent) bool { |
There was a problem hiding this comment.
This function is defined but never called anywhere in the codebase. The deploy path uses activityProfile.IsActivity (from ResolveActivityProfile) instead. If it's intended for future use, consider adding a //nolint:unused annotation or a TODO; otherwise removing it keeps the surface area clean.
Summary
Adds native Activity-protocol support to the
azure.ai.agentsextension, so activity agents (including M365 "digital workers") work end-to-end withazd ai agent init→azd provision→azd deploywithout external scripts.What's included
Native activity protocol (commit 1)
Foundry-Features: HostedAgents=V1Preview,AgentEndpoints=V1Previewon CreateAgent/PatchAgent so the agent endpoint patch (protocols + authorization_schemes) is accepted.protocols: [activity]andauthorization_schemes: [BotServiceRbac]for activity agents (additive; does not override user config).activity↔ internalactivity_protocolwire value inmap.go.m365_registration.go: best-effort M365 onboarding (OAuth2 grants for MCP/APEX, blueprint owner, digital-worker publish, Teams backend config) wired into the postprovision/postdeploy hooks.Use-case profiles + init + onboarding next-steps (commit 2)
agent.yamlgainsactivity.use_case(simple|digital_worker).ResolveActivityProfilegates activity-endpoint injection, BotServiceRbac, blueprint reference, and M365 provision/publish.azd ai agent initround-tripsuse_casefrom the manifest; adds--activity-use-caseand anAZD_AI_STARTER_TEMPLATEoverride. The preprovision hook setsENABLE_DIGITAL_WORKER+AGENT_NAMEso the starter template provisions the MAIB + Bot Service.azd deploynow prints the digital-worker onboarding next steps (M365 admin-center approval, blueprint ID, Teams instance) in the visible deploy summary.Testing
go vet ./...clean.go test ./...green across all packages (cmd, project, agent_yaml, nextstep, doctor, ...).