Skip to content

feat(azure.ai.agents): support digital worker workflows - #9610

Open
Huajie Zhang (jayzhang) wants to merge 14 commits into
mainfrom
huajie/digitalworker
Open

feat(azure.ai.agents): support digital worker workflows#9610
Huajie Zhang (jayzhang) wants to merge 14 commits into
mainfrom
huajie/digitalworker

Conversation

@jayzhang

@jayzhang Huajie Zhang (jayzhang) commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

Summary

Add end-to-end Digital Worker support to the azure.ai.agents extension, from activity profile validation and deployment identity persistence through Microsoft 365 packaging and publishing.

The user-facing command changes are centered on:

  • azd ai agent pack
  • azd ai agent publish

azd ai agent pack

  • Package deployed simple Activity agents through the Microsoft 365 zip API.
  • Support personal, shared, and tenant scopes, including the org alias for tenant.
  • Preserve user-owned app packages and require a deployed agent before packaging.
  • Direct Digital Worker projects to azd ai agent publish, because their Microsoft 365 flow requires blueprint and agentic-user-template metadata rather than a sideload package.

azd ai agent publish

  • Publish simple Activity agents and Digital Workers through the Microsoft 365 publish API.
  • Use the stable API for simple agents and 2025-11-15-preview for Digital Workers.
  • Send Digital Worker metadata including PublishAsAutopilot, agentic user template settings, and the persisted blueprint client ID.
  • Resolve publish scope in this order:
    1. Explicit --scope
    2. activity.publish.publishScope from azure.yaml
    3. shared for simple Activity agents
    4. tenant for Digital Workers when config is omitted
  • Enforce tenant-only scope for Digital Worker publish. Reject shared and personal with actionable guidance.
  • Log the final publish URL and JSON request body under --debug.
  • Surface malformed or incomplete publish responses instead of reporting false success.

Publish follow-up guidance

The command distinguishes publish guidance by agent type and scope:

Agent type Scope Post-publish guidance
Simple Activity agent Shared Return the install link. Users can add the app directly, subject to tenant app-installation policies.
Simple Activity agent Tenant Do not return an install link before approval. Direct the tenant admin to the Microsoft 365 requested-agents page.
Digital Worker Tenant Do not return an install link before approval. Explain that tenant approval and template activation may be required before users can create personal instances.

JSON output follows the same model:

  • Simple + Shared: deepLink
  • Simple + Tenant: approvalLink
  • Digital Worker + Tenant: approvalLink

Tenant approval URL: https://admin.cloud.microsoft/?#/agents/all/requested

Digital Worker configuration and deployment

  • Add activity.useCase support for simple and digital_worker.
  • Validate Digital Worker publish configuration, including publishAsAutopilot, publishScope, and the agentic-user template.
  • Preserve existing endpoint protocols and authorization schemes while adding Activity protocol support.
  • Skip Azure Bot resolution for Digital Workers.
  • Require the deployed Digital Worker version to return a blueprint client ID.
  • Persist the blueprint client ID in the azd environment for later publish requests.

Validation

  • Added coverage for Activity profile validation and endpoint composition.
  • Added deployment tests for blueprint client ID persistence and Digital Worker environment behavior.
  • Added package/publish scope and request-payload tests.
  • Added HTTP client tests for API versions, URLs, payloads, malformed responses, and debug logging.
  • Added output tests for Simple/Digital Worker and Shared/Tenant behavior covered by each flow.
  • Ran:
    • go test ./internal/cmd ./internal/project
    • go build ./...
    • git diff --check

Fixes #9615

Add Digital Worker-specific Microsoft 365 publish payloads, scope
resolution, request diagnostics, and actionable publish results.

Authored-by: GitHub Copilot for VS Code
Model: GitHub Copilot
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Tailor publish results for simple and Digital Worker agents across
shared and tenant scopes, including install, activation, and admin
approval guidance.

Authored-by: GitHub Copilot for VS Code
Model: GitHub Copilot
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
Successfully started running 1 pipeline(s).
20 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 Digital Worker deployment and Microsoft 365 publishing support to the azure.ai.agents extension.

Changes:

  • Adds Digital Worker configuration, validation, and blueprint persistence.
  • Extends pack/publish requests, scopes, API versions, and guidance.
  • Adds unit coverage for deployment, publishing, and output behavior.

Reviewed changes

Copilot reviewed 15 out of 15 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
internal/project/service_target_agent.go Persists Digital Worker blueprint identity.
internal/project/service_target_agent_test.go Tests blueprint persistence.
internal/project/config.go Defines Digital Worker configuration.
internal/project/activity_profile.go Resolves and validates use cases.
internal/project/activity_profile_test.go Tests profile validation.
internal/pkg/envkey/envkey.go Adds blueprint environment key.
internal/pkg/envkey/envkey_test.go Tests the new key.
internal/pkg/agents/agent_api/microsoft365.go Adds preview publishing payload and logging.
internal/pkg/agents/agent_api/microsoft365_test.go Tests Digital Worker API requests.
internal/cmd/teams_pack.go Builds Digital Worker publishing context and payloads.
internal/cmd/teams_pack_test.go Tests metadata and API-version selection.
internal/cmd/publish.go Adds scope resolution and tailored results.
internal/cmd/publish_test.go Tests scopes and output combinations.
internal/cmd/pack.go Redirects Digital Workers to publish.
internal/cmd/listen_activity_test.go Changes setup-guide expectations.

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread cli/azd/extensions/azure.ai.agents/internal/project/config.go
Comment thread cli/azd/extensions/azure.ai.agents/internal/cmd/publish.go
Comment thread cli/azd/extensions/azure.ai.agents/internal/cmd/teams_pack.go Outdated
Comment thread cli/azd/extensions/azure.ai.agents/internal/cmd/listen_activity_test.go Outdated
Copilot AI review requested due to automatic review settings August 18, 2026 06:51

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 17 out of 17 changed files in this pull request and generated 5 comments.

Suppressed comments (2)

cli/azd/extensions/azure.ai.agents/internal/project/activity_profile.go:95

  • azd-code-reviewer: This only checks that publishScope is non-empty, so values such as personal or typo pass deployment validation and fail later during publish. Enforce the same shared/tenant set declared by the schema and README.
		if strings.TrimSpace(settings.Publish.PublishScope) == "" {
			return ActivityProfile{}, fmt.Errorf("activity.publish.publishScope is required for digital_worker")
		}

cli/azd/extensions/azure.ai.agents/internal/cmd/listen_activity_test.go:115

  • azd-code-reviewer: The new name says no guide is created, but the test requires the guide to exist and verifies its bot name. Rename it so failures and test listings describe the behavior being exercised.
func TestNoTeamsSetupGuideCreated(t *testing.T) {

Comment thread cli/azd/extensions/azure.ai.agents/internal/cmd/publish.go
Comment thread cli/azd/extensions/azure.ai.agents/internal/cmd/teams_pack_test.go Outdated
Comment thread cli/azd/extensions/azure.ai.agents/internal/project/activity_profile.go Outdated
Comment thread cli/azd/extensions/azure.ai.agents/internal/project/service_target_agent.go Outdated
@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 Rick Winter (@RickWinter) and Kristen Womack (@kristenwomack) to let us know.

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 17 out of 17 changed files in this pull request and generated 1 comment.

Suppressed comments (5)

cli/azd/extensions/azure.ai.agents/internal/cmd/publish.go:130

  • [azd-code-reviewer] Omitting --display-name now sends the literal "Agent" for a simple Activity agent because this call no longer supplies packCtx.agentName and the builder has no agent-name input. That regresses the documented default at line 93. Preserve configured Digital Worker metadata, but fall back to the deployed agent name when neither source supplies a name.
		agentName:         packCtx.agentName,

cli/azd/extensions/azure.ai.agents/internal/cmd/teams_pack_test.go:132

  • [azd-code-reviewer] This assertion contradicts both the input and the documented precedence: displayName is explicitly "CLI Overridden", so the builder correctly keeps it instead of the configured "DW Helper". The test will fail as written.
	if req.AgentDisplayName != "CLI Overridden" {
		t.Errorf("AgentDisplayName = %q, want CLI Overridden", req.AgentDisplayName)

cli/azd/extensions/azure.ai.agents/schemas/azure.ai.agent.json:183

  • [azd-code-reviewer] The schema currently accepts publishAsAutopilot: false, but runtime validation rejects it for every Digital Worker. This lets editor/schema validation report a configuration as valid only for azd deploy to fail. Constrain the schema to the required value.
        "publishAsAutopilot": { "type": "boolean" },

cli/azd/extensions/azure.ai.agents/internal/cmd/pack.go:102

  • [azd-code-reviewer] This Digital Worker guard runs only after resolveTeamsPackContext has required the deployment name, version, and blueprint ID. An undeployed Digital Worker therefore gets told to run azd deploy before packaging, but rerunning pack after deployment only reaches this rejection. Detect the use case before deployment-specific resolution so pack always directs Digital Workers straight to publish.
	if packCtx.activityProfile.UseCase == project.ActivityUseCaseDigitalWorker {

cli/azd/extensions/azure.ai.agents/internal/cmd/publish.go:53

  • [azd-code-reviewer] The new Digital Worker shared flow can require tenant-admin template activation, as the post-publish guidance below explains, so no tenant-admin approval required is now misleading for this command. Qualify this as the simple-agent behavior and mention that Digital Workers may require activation approval.
	shared    shareable-link distribution (no tenant-admin approval required)

Copilot AI review requested due to automatic review settings August 18, 2026 07:11

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 17 out of 17 changed files in this pull request and generated no new comments.

Suppressed comments (6)

cli/azd/extensions/azure.ai.agents/internal/project/activity_profile.go:70

  • This settings-aware resolver is not used by the preprovision and postdeploy Activity hooks. Both still call ResolveActivityProfile, which always classifies Activity agents as simple: preprovision therefore persists an Azure Bot name for Digital Workers, and postdeploy can run the simple zip/setup flow when identity values are present or stale. Load the service settings in those hooks and skip bot/package handling when the resolved use case is digital_worker.
// ResolveActivityProfileWithSettings derives and validates the Activity use
// case configured on the azd service. A missing setting preserves the existing
// simple Activity behavior.
func ResolveActivityProfileWithSettings(

cli/azd/extensions/azure.ai.agents/schemas/azure.ai.agent.json:163

  • The Digital Worker conditional only requires publishAsAutopilot to be present, so false passes schema validation even though ResolveActivityProfileWithSettings always rejects it. Constrain this value to true here so editor/schema validation matches deploy-time validation.
              "publish": {
                "required": ["publishAsAutopilot", "publishScope", "agenticUserTemplate"]
              }

cli/azd/extensions/azure.ai.agents/internal/project/service_target_agent.go:3265

  • A missing blueprint is an expected deployment dependency failure, but this plain error reaches the host unclassified and without retry guidance. The equivalent simple-Activity identity check at service_target_agent.go:1442-1449 returns exterrors.Dependency; use the same structured pattern here, as required by cli/azd/extensions/azure.ai.agents/AGENTS.md:73-111.
		if blueprint == nil || strings.TrimSpace(blueprint.ClientID) == "" {
			return fmt.Errorf("Digital Worker agent version is missing Blueprint client ID")

cli/azd/extensions/azure.ai.agents/internal/cmd/publish.go:168

  • The documented precedence applies activity.publish.publishScope before the simple-agent shared fallback, but this helper returns configuration only for Digital Workers. A simple Activity service configured with publishScope: tenant is silently published as shared. Read the scope from activitySettings.Publish regardless of use case; keep digitalWorkerPublishConfig only for Digital Worker payload metadata.
	if !flags.scopeSet {
		if publish := digitalWorkerPublishConfig(packCtx); publish != nil && strings.TrimSpace(publish.PublishScope) != "" {
			scopeValue = publish.PublishScope
		} else {
			scopeValue = "shared"
		}

cli/azd/extensions/azure.ai.agents/internal/cmd/listen_activity_test.go:115

  • This test creates the setup guide, reads it, and verifies its contents, so the new name states the opposite behavior. Rename it to describe the bot-name assertion.
func TestNoTeamsSetupGuideCreated(t *testing.T) {

cli/azd/extensions/azure.ai.agents/internal/cmd/pack.go:107

  • The Digital Worker rejection runs only after resolveTeamsPackContext has required a selected environment, deployed name/version, and persisted blueprint ID. An undeployed Digital Worker therefore gets told to deploy first even though packing will still be rejected afterward. Detect this use case before deployment-state resolution so pack immediately directs the user to publish.
	if packCtx.activityProfile.UseCase == project.ActivityUseCaseDigitalWorker {
		return exterrors.Validation(
			exterrors.CodeInvalidPublishScope,
			"digital_worker agents cannot be packed into a Microsoft Teams zip package",
			"use 'azd ai agent publish' for digital_worker; zip packaging is only for the simple Activity agent flow",
		)

Copilot AI review requested due to automatic review settings August 18, 2026 07:27

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 18 out of 18 changed files in this pull request and generated no new comments.

Suppressed comments (3)

cli/azd/extensions/azure.ai.agents/internal/cmd/teams_pack.go:136

  • Root $ref services lose their Digital Worker settings here. LoadAgentDefinition resolves the include into a temporary struct, but LoadServiceTargetAgentConfig reads the unchanged service; unlike deploy's resolver, this command never calls ResolveServiceConfigInPlace. Pack/publish then classify the referenced Digital Worker as simple and look for a Bot ARM ID/use the stable API instead of sending the blueprint payload. Resolve the effective service config before loading these settings and add a root-$ref regression test.
	serviceTargetConfig, err := project.LoadServiceTargetAgentConfig(svc)
	if err != nil {
		return nil, exterrors.Validation(
			exterrors.CodeInvalidServiceConfig,
			fmt.Sprintf("failed to parse service target config: %s", err),
			"check the activity configuration in azure.yaml",
		)
	}
	activityProfile, err := project.ResolveActivityProfileWithSettings(ca, serviceTargetConfig.Activity)

cli/azd/extensions/azure.ai.agents/internal/cmd/publish.go:181

  • For a Digital Worker, this validator tells the user to run azd ai agent pack, but PackAction explicitly rejects Digital Workers and redirects back to publish (pack.go:102-107). Thus publish --scope personal produces circular guidance. Return Digital Worker-specific guidance to choose shared or tenant, while retaining pack/sideload guidance for simple agents.
	if err := validatePublishScope(scope); err != nil {
		return teamsPackScope{}, err

cli/azd/extensions/azure.ai.agents/internal/cmd/listen.go:410

  • Digital Workers still enter the preprovision bot-name path. provisionActivityBotNames calls the settings-blind ResolveActivityProfile(agent).IsActivity, so it persists AGENT_*_BOT_NAME for every Digital Worker before this postdeploy gate runs. The real deployment environment therefore retains a name for a bot that is never created, despite the new unit test expecting no bot keys. Update preprovision to load the Activity settings and use ResolveActivityProfileWithSettings, then cover the full lifecycle path.
	activityProfile, profileErr := resolveServiceActivityProfile(svc, args.Project.Path)
	if profileErr != nil {
		log.Printf("postdeploy: skipping Teams setup for %s: %v", svc.Name, profileErr)
	} else if activityProfile.IsActivity && activityProfile.UseCase == project.ActivityUseCaseSimple {

Copilot AI review requested due to automatic review settings August 19, 2026 03: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 18 out of 18 changed files in this pull request and generated no new comments.

Suppressed comments (7)

cli/azd/extensions/azure.ai.agents/internal/cmd/publish.go:200

  • [azd-code-reviewer] This rejects shared for Digital Workers, but the PR contract and linked issue require both shared and tenant distribution, and the schema/README also accept shared. It also makes the documented Digital Worker + Shared follow-up guidance unreachable. Allow shared here and add the dedicated shared guidance and tests instead of rejecting it.
	if scope.flag == "tenant" {
		return nil
	}
	return exterrors.Validation(
		exterrors.CodeInvalidPublishScope,

cli/azd/extensions/azure.ai.agents/internal/project/activity_profile.go:95

  • [azd-code-reviewer] This only rejects an empty scope, so values such as personal or a typo pass deployment validation even though the schema permits only shared and tenant; the project then fails later at publish time. Validate the enum here so invalid configuration fails before deployment.
		if strings.TrimSpace(settings.Publish.PublishScope) == "" {
			return ActivityProfile{}, fmt.Errorf("activity.publish.publishScope is required for digital_worker")
		}

cli/azd/extensions/azure.ai.agents/internal/cmd/listen.go:492

  • [azd-code-reviewer] The settings-aware resolver is still not applied during preprovision: activity_bot_provision.go:50 calls ResolveActivityProfile, which classifies every Activity agent as simple and persists AGENT_*_BOT_NAME for Digital Workers. Use the service settings there and skip the simple-bot path for digital_worker, otherwise a normal azd up does not actually skip Azure Bot resolution as described.
	config, err := project.LoadServiceTargetAgentConfig(svc)
	if err != nil {
		return project.ActivityProfile{}, err
	}
	return project.ResolveActivityProfileWithSettings(agent, config.Activity)

cli/azd/extensions/azure.ai.agents/internal/cmd/pack.go:106

  • [azd-code-reviewer] This check runs only after resolveTeamsPackContext has required deployment state and a persisted blueprint ID. Consequently, an undeployed Digital Worker running pack is told to deploy first rather than being directed immediately to publish, contrary to the command's intended behavior. Resolve the activity profile before deployment-dependent packaging state and reject Digital Workers at that point.
	if packCtx.activityProfile.UseCase == project.ActivityUseCaseDigitalWorker {
		return exterrors.Validation(
			exterrors.CodeInvalidPublishScope,
			"digital_worker agents cannot be packed into a Microsoft Teams zip package",
			"use 'azd ai agent publish' for digital_worker; zip packaging is only for the simple Activity agent flow",

cli/azd/extensions/azure.ai.agents/internal/cmd/listen_activity_test.go:178

  • [azd-code-reviewer] The test name states that no setup guide is created, but the test creates the guide, reads it, and asserts its contents. Rename it to describe the behavior being verified.
func TestNoTeamsSetupGuideCreated(t *testing.T) {

cli/azd/extensions/azure.ai.agents/internal/cmd/teams_pack_test.go:90

  • [azd-code-reviewer] The repository's Go 1.26 convention requires new(value) instead of introducing a temporary solely to take its address. Inline this pointer as new(true) so go fix does not rewrite the test.
		CanRespondWithoutMention: &canRespond,

cli/azd/extensions/azure.ai.agents/internal/cmd/publish.go:169

  • [azd-code-reviewer] Scope precedence consults digitalWorkerPublishConfig, which always returns nil for simple Activity agents. As a result, a simple agent's configured activity.publish.publishScope: tenant is silently ignored and falls back to shared, contrary to the stated explicit flag → configured value → simple default order. Read the configured scope from activitySettings for both use cases while keeping Digital Worker-only payload metadata separate.

This issue also appears on line 196 of the same file.

	if !flags.scopeSet {
		if publish := digitalWorkerPublishConfig(packCtx); publish != nil && strings.TrimSpace(publish.PublishScope) != "" {
			scopeValue = publish.PublishScope
		} else if packCtx.activityProfile.UseCase == project.ActivityUseCaseDigitalWorker {
			scopeValue = "tenant"

Comment thread cli/azd/extensions/azure.ai.agents/internal/project/activity_profile.go Outdated
Copilot AI review requested due to automatic review settings August 19, 2026 08: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 18 out of 18 changed files in this pull request and generated 2 comments.

Suppressed comments (3)

cli/azd/extensions/azure.ai.agents/README.md:59

  • azd-code-reviewer: This says Digital Workers accept shared, but the schema permits only tenant and both profile and publish validation reject shared. Following the README therefore causes deployment or publish to fail; document tenant-only scope and the org CLI alias instead.
`publishScope` accepts `tenant` or `shared`; an explicit
`azd ai agent publish --scope <scope>` overrides the configured value. Use
`--display-name` and `--app-version` to override the corresponding configured
publish metadata for one command invocation.

cli/azd/extensions/azure.ai.agents/schemas/azure.ai.agent.json:183

  • azd-code-reviewer: The schema accepts publishAsAutopilot: false, but runtime validation rejects that value for every Digital Worker. Encode the required value in the schema so editor/doc validation catches the invalid configuration before deploy.
        "publishAsAutopilot": { "type": "boolean" },

cli/azd/extensions/azure.ai.agents/internal/project/activity_profile.go:95

  • azd-code-reviewer: This makes the advertised Digital Worker scope fallback unreachable. Both deploy and resolveTeamsPackContext call this validation before resolvePublishScope, so omitting activity.publish.publishScope fails here instead of defaulting to tenant; the schema also requires the field. Either allow omission here and in the schema, or remove the tenant-default behavior from the command and PR contract.
		if strings.TrimSpace(settings.Publish.PublishScope) == "" {
			return ActivityProfile{}, fmt.Errorf("activity.publish.publishScope is required for digital_worker")
		}

Comment thread cli/azd/extensions/azure.ai.agents/internal/cmd/teams_pack.go Outdated
Comment thread cli/azd/extensions/azure.ai.agents/internal/cmd/listen.go Outdated
Copilot AI review requested due to automatic review settings August 19, 2026 09:14

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 18 out of 18 changed files in this pull request and generated 2 comments.

Suppressed comments (4)

cli/azd/extensions/azure.ai.agents/README.md:57

  • The command and schema enforce tenant-only Digital Worker publishing, so stating that shared is accepted sends users toward configuration that validation rejects. Document tenant as the only Digital Worker scope and mention org only as the CLI alias if desired.
`publishScope` accepts `tenant` or `shared`; an explicit
`azd ai agent publish --scope <scope>` overrides the configured value. Use

cli/azd/extensions/azure.ai.agents/README.md:49

  • This says publishScope is mandatory, but the command help and PR contract say omission defaults Digital Workers to tenant. Update this requirement once the schema/runtime validation permits omission.

This issue also appears on line 56 of the same file.

`digital_worker` requires `publishAsAutopilot`, `publishScope`, and an
`agenticUserTemplate` with `id`, `file`, `schemaVersion`, and
`communicationProtocol`. The Agent Identity Blueprint ID is generated during
deployment and added to the publish request automatically.

cli/azd/extensions/azure.ai.agents/internal/project/service_target_agent.go:3290

  • This user-visible deployment failure escapes as an unclassified plain error. The extension convention classifies failures at orchestration boundaries, and the nearby missing instance-identity branch uses exterrors.Dependency (service_target_agent.go:1445-1452). Return the same structured dependency error here so users receive retry guidance and stable telemetry.
		if blueprint == nil || strings.TrimSpace(blueprint.ClientID) == "" {
			return fmt.Errorf("Digital Worker agent version is missing Blueprint client ID")

cli/azd/extensions/azure.ai.agents/internal/cmd/listen_activity_test.go:215

  • The renamed test still calls writeTeamsSetupGuide, reads the resulting file, and verifies its contents, so TestNoTeamsSetupGuideCreated states the opposite of the behavior under test. Keep the original write-oriented name.
func TestNoTeamsSetupGuideCreated(t *testing.T) {

Comment thread cli/azd/extensions/azure.ai.agents/schemas/azure.ai.agent.json Outdated
Comment thread cli/azd/extensions/azure.ai.agents/internal/project/activity_profile.go Outdated
Copilot AI review requested due to automatic review settings August 19, 2026 11:58

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 18 out of 18 changed files in this pull request and generated no new comments.

Suppressed comments (4)

cli/azd/extensions/azure.ai.agents/internal/project/activity_profile.go:95

  • azd-code-reviewer: This check makes the documented Digital Worker fallback to tenant unreachable. resolveTeamsPackContext runs this validator before resolvePublishScope, and the schema also requires publishScope, so omitted configuration fails instead of reaching the default. Either allow omission here and in the schema, or remove the claimed fallback.
		if strings.TrimSpace(settings.Publish.PublishScope) == "" {
			return ActivityProfile{}, fmt.Errorf("activity.publish.publishScope is required for digital_worker")
		}

cli/azd/extensions/azure.ai.agents/internal/cmd/publish.go:173

  • azd-code-reviewer: This branch only reads digitalWorkerPublishConfig, which deliberately returns nil for simple Activity agents. A schema-valid simple configuration with activity.publish.publishScope: tenant is therefore ignored and silently falls back to shared, contrary to the documented scope precedence. Read the activity publish settings for both use cases, then retain the tenant-only validation for Digital Workers.
		if publish := digitalWorkerPublishConfig(packCtx); publish != nil && strings.TrimSpace(publish.PublishScope) != "" {
			scopeValue = publish.PublishScope

cli/azd/extensions/azure.ai.agents/README.md:59

  • azd-code-reviewer: This says shared is accepted for Digital Workers, but the schema permits only tenant and runtime validation rejects shared. Users following this documentation cannot validate or deploy the configuration. Document tenant-only scope, with org only as a CLI flag alias.
`publishScope` accepts `tenant` or `shared`; an explicit
`azd ai agent publish --scope <scope>` overrides the configured value. Use
`--display-name` and `--app-version` to override the corresponding configured
publish metadata for one command invocation.

cli/azd/extensions/azure.ai.agents/internal/cmd/pack.go:107

  • azd-code-reviewer: This redirect is reached only after resolveTeamsPackContext has required a deployed agent name/version and, for a Digital Worker, a persisted blueprint client ID. An undeployed Digital Worker therefore receives “run azd deploy first” even though packing is never supported, instead of being directed to publish. Resolve the activity use case before deployment-only context, or split context resolution so pack rejects Digital Workers immediately.
	if packCtx.activityProfile.UseCase == project.ActivityUseCaseDigitalWorker {
		return exterrors.Validation(
			exterrors.CodeInvalidPublishScope,
			"digital_worker agents cannot be packed into a Microsoft Teams zip package",
			"use 'azd ai agent publish' for digital_worker; zip packaging is only for the simple Activity agent flow",
		)

Copilot AI review requested due to automatic review settings August 19, 2026 12:11

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 18 out of 18 changed files in this pull request and generated no new comments.

Suppressed comments (5)

cli/azd/extensions/azure.ai.agents/README.md:57

  • azd-code-reviewer: shared is rejected for Digital Workers by the schema and validateDigitalWorkerPublishScope, so this instruction leads users to a configuration that cannot validate or publish. Document tenant as the only accepted scope.
`publishScope` accepts `tenant` or `shared`; an explicit
`azd ai agent publish --scope <scope>` overrides the configured value. Use

cli/azd/extensions/azure.ai.agents/README.md:49

  • azd-code-reviewer: This documents publishScope as required, but both ResolveActivityProfileWithSettings and resolvePublishScope allow it to be omitted and default a Digital Worker to tenant. Update the requirements so users do not think they must configure an optional field.

This issue also appears on line 56 of the same file.

`digital_worker` requires `publishAsAutopilot`, `publishScope`, and an
`agenticUserTemplate` with `id`, `file`, `schemaVersion`, and
`communicationProtocol`. The Agent Identity Blueprint ID is generated during
deployment and added to the publish request automatically.

cli/azd/extensions/azure.ai.agents/schemas/azure.ai.agent.json:183

  • azd-code-reviewer: The schema currently accepts publishAsAutopilot: false, while ResolveActivityProfileWithSettings guarantees that configuration will fail deployment. Encode the runtime contract here so editor/schema validation catches the error earlier.
        "publishAsAutopilot": { "type": "boolean" },

cli/azd/extensions/azure.ai.agents/internal/cmd/listen_activity_test.go:215

  • azd-code-reviewer: The test name says no guide is created, but the test calls writeTeamsSetupGuide, reads the generated file, and verifies its contents. Rename it to describe the behavior it actually protects.
func TestNoTeamsSetupGuideCreated(t *testing.T) {

cli/azd/extensions/azure.ai.agents/internal/cmd/pack.go:106

  • azd-code-reviewer: This Digital Worker guard runs only after resolveTeamsPackContext has required a selected environment, deployed version, persisted blueprint ID, endpoint, and credential. As a result, an undeployed Digital Worker invoking pack gets deploy/auth prerequisite errors instead of the promised direction to azd ai agent publish. Resolve the activity profile and reject Digital Workers before deployment-specific context is loaded.
	if packCtx.activityProfile.UseCase == project.ActivityUseCaseDigitalWorker {
		return exterrors.Validation(
			exterrors.CodeInvalidPublishScope,
			"digital_worker agents cannot be packed into a Microsoft Teams zip package",
			"use 'azd ai agent publish' for digital_worker; zip packaging is only for the simple Activity agent flow",

"github.com/spf13/cobra"
)

const tenantAgentApprovalURL = "https://admin.cloud.microsoft/?#/agents/all/requested"

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.

Is this likely to ever change? Should it be an aka.ms link?

cmd.Flags().StringVar(&flags.appVersion, "app-version", "1.0.0",
"Version stamped into the Teams app manifest")
cmd.Flags().StringVar(&flags.appVersion, "app-version", "",
"Version stamped into the Teams app manifest (defaults to the configured value or 1.0.0)")

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.

Why did you remove the default from the flag if the comment still says it defaults to that value?

return project.ResolveActivityProfileWithSettings(agent, config.Activity)
}

func resolveEffectiveAgentServiceConfig(

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.

What does "effective" service mean?


// Microsoft365DigitalWorkerAPIVersion is the project data-plane API version
// used by the Digital Worker publish flow.
const Microsoft365DigitalWorkerAPIVersion = "2025-11-15-preview"

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.

Why is this different? Everything has been moving away from date based api versions

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.

Add Digital Worker support to the azure.ai.agents extension

4 participants