Skip to content

feat: non-DW blueprint setup and config-free provisioning via --agent-name#365

Merged
sellakumaran merged 71 commits into
mainfrom
users/sellak/nondw
Apr 20, 2026
Merged

feat: non-DW blueprint setup and config-free provisioning via --agent-name#365
sellakumaran merged 71 commits into
mainfrom
users/sellak/nondw

Conversation

@sellakumaran

Copy link
Copy Markdown
Contributor

Summary

Adds the full Standard agent (non-AI Teammate) setup path and config-free provisioning
via --agent-name, so developers can provision a blueprint, agent identity, and Agent
Registry entry without a pre-existing a365.config.json.

What changed

  • a365 setup all --agent-name <name>: end-to-end Standard agent provisioning with
    no config file required — resolves client app by well-known display name "Agent 365 CLI"
  • Agent identity creation: new step in the Standard setup path using delegated flow
    (AgentIdentity.Create.All). Agent ID Developer role is sufficient — blueprint client
    credentials are not required
  • Non-admin setup: Principal-scoped permission grants let non-admin developers complete
    setup without Global Administrator for every step
  • Auth fix: corrected double-slash scope URL (https://graph.microsoft.com//.default)
    that caused WAM IncorrectConfiguration in cross-tenant scenarios
  • Permissions: replaced Application.ReadWrite.All with AgentIdentityBlueprintPrincipal.Create
    for blueprint SP creation per Agent ID team guidance — ReadWrite.All is higher privilege
    than needed
  • Docs: a365-setup-instructions.md and custom-client-app-registration.md updated
    to reflect the Standard vs AI Teammate setup paths and revised permission list

Test plan

  • a365 setup all --agent-name <name> --dry-run — verify plan output
  • a365 setup all --agent-name <name> in a non-admin dev tenant — verify blueprint,
    identity (<name> Identity), and registry entry (<name> Agent) created correctly
  • Admin consent PowerShell script generated and consent URL surfaced in output
  • dotnet test — 1344 passing, 16 skipped

sellakumaran and others added 30 commits March 16, 2026 16:35
…dmin consent detection

- FederatedCredentialService: fix FIC creation/deletion to use Application.ReadWrite.All
  delegated scope so non-admin app owners can manage their own blueprint credentials

- GraphApiService: add IsCurrentUserAdminAsync using Directory.Read.All (already consented)
  to detect admin role without a separate consent requirement; avoids circular dependency
  with RoleManagement.Read.Directory

- BlueprintSubcommand: non-admin users now skip browser consent immediately and receive
  actionable consent URLs (blueprint app + optional client app) instead of a 60-second timeout

- ClientAppValidator: add self-healing auto-provision for missing client app permissions;
  EnsurePermissionsConfiguredAsync patches requiredResourceAccess and extends existing
  OAuth2 grant scopes without requiring manual intervention

- AuthenticationConstants: remove RoleManagement.Read.Directory from RequiredClientAppPermissions;
  Directory.Read.All is sufficient for transitive role membership lookup

- SetupResults: add AdminConsentUrl, FederatedCredentialConfigured, FederatedCredentialError
  fields to support recovery guidance in setup summary

- AllSubcommand: track FIC status and admin consent URL in setup results; improve endpoint
  registration error messages with failure reason detail

- SetupHelpers: update DisplaySetupSummary recovery section to show admin consent URL
  when available instead of generic retry instruction

- RequirementsSubcommand/InfrastructureSubcommand: remove Agent365ServiceRoleCheck;
  clean up prerequisite runner usage

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Introduces BatchPermissionsOrchestrator with a three-phase flow so
admin consent is attempted exactly once in 'setup all'. Standalone
permission commands (mcp, bot, custom) are refactored as thin
spec-builders delegating to the orchestrator. Blueprint consent is
deferred via BlueprintCreationOptions(DeferConsent: true).

Phase 1 resolves all service principals once (no retry for blueprint SP
— Agent Blueprint SPs are not queryable via standard Graph endpoint).
Phase 2 sets OAuth2 grants and inheritable permissions; 403 responses
are caught silently and treated as insufficient role without logging an
error. Phase 3 checks for existing consent before opening a browser and
returns a consolidated URL for non-admins.

requiredResourceAccess is not updated — it is not supported for Agent
Blueprints.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix dead command reference in recovery guidance (a365 setup admin -> a365 setup all)
- Fix mermaid diagram language tag typo in design.md (mermard -> mermaid)
- Fix XML doc for IsCurrentUserAdminAsync to reference Directory.Read.All scope
- Fix AuthenticationConstants comment to reference IsCurrentUserAgentIdAdminAsync
- Fix BatchPermissionsOrchestrator comment incorrectly claiming Phase 1 updates requiredResourceAccess
- Remove unused executor parameter from GetRequirementChecks and GetConfigRequirementChecks
- Add debug logging in ReadMcpScopesAsync when no scopes found
- Replace per-resource permission flags in setup all summary with batch phase fields
- Remove separator lines from setup summary to align with az cli output conventions
- Remove FIC from completed steps (only surfaces on failure)
- Add JWT token inspection and force-refresh retry for endpoint registration role errors

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…mination

PowerShell Connect-MgGraph cached tokens by (tenant + clientId + scopes) with
no user identity in the key. On shared machines, sellakdev's cached session was
silently reused when sellak (Global Admin) ran cleanup, causing 403 on blueprint
DELETE because the token belonged to the wrong user.

Fixes:
- MicrosoftGraphTokenProvider: MSAL/WAM is now primary; PowerShell is fallback.
  WAM token cache is keyed by HomeAccountId (user identity), preventing cross-user
  contamination. On Windows, WAM authenticates via the OS broker without a browser,
  making it compatible with Conditional Access Policies (fixes #294).
- AgentBlueprintService: DELETE uses AgentIdentityBlueprint.DeleteRestore.All scope
  and the correct URL pattern (/beta/applications/microsoft.graph.agentIdentityBlueprint/{id})
- AuthenticationConstants: add ApplicationReadWriteAllScope, DirectoryReadAllScope constants
- FederatedCredentialService: replace magic strings with constants
- GraphApiService: HasDirectoryRoleAsync accepts delegatedScope parameter; agent-admin
  check uses RoleManagement.Read.Directory (lower privilege)
- Tests: add MsalTokenAcquirerOverride seam; add 3 new tests for MSAL-primary path

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- GraphApiService: IsCurrentUserAgentIdAdminAsync now uses Directory.Read.All
  (already consented) instead of RoleManagement.Read.Directory (not consented),
  fixing silent false-negative for Agent ID Admin role detection
- AuthenticationConstants: fix RoleManagementReadDirectoryScope doc (was
  incorrectly referencing IsCurrentUserAdminAsync); fix AgentIdentityBlueprintAddRemoveCredsAllScope
  doc to reflect it is not yet used (FIC still uses Application.ReadWrite.All)
- BatchPermissionsOrchestrator: fix duplicate XML summary block; add empty-scope
  filtering before Phase 1/2/3 to prevent HTTP 400 on non-MCP projects
- FederatedCredentialService: fix misleading 403 error message — directs user to
  check blueprint ownership, not to acquire GA/Agent ID Admin role
- RequirementsSubcommand: remove unused executor parameter from CreateCommand
- BotConfigurator: remove dead TryDecodeJwtPayload method
- CHANGELOG: correct FIC scope entry (Application.ReadWrite.All, not AddRemoveCreds.All);
  narrow per-user isolation claim to Graph token path only

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Changelog now uses Keep a Changelog format. Added early App Service token validation for `a365 deploy`. Enhanced manifest handling and upload instructions for `a365 publish`. Switched to MSAL/WAM for user-isolated Graph token acquisition. `a365 cleanup` uses correct Graph scope and supports Global Admins. `a365 setup all` surfaces admin consent URLs and requests consent once for all resources. Improved device code/MSAL fallbacks for macOS/Linux, admin consent polling, and exception handling for missing config files.
- Thread az account user as login hint through MsalBrowserCredential so
  WAM/MSAL selects the correct account instead of defaulting to the
  Windows primary account
- Include userId in AuthenticationService file cache key to prevent
  cross-user token reuse on shared machines
- Add 401 retry with forceRefresh in BotConfigurator create and delete
  endpoint paths (previously only retried on 'Invalid roles' 400)
- Remove interpretive error message on ATG 'Invalid roles' — log raw
  API message only
- Add debug log lines for ATG cache key and current user resolution

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…Hint parameter

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- BatchPermissionsOrchestrator: consent check now loops all resolved
  specs before returning granted=true (was checking only the first)
- BatchPermissionsOrchestrator: use AuthenticationConstants.DirectoryReadAllScope
  constant instead of hard-coded string literal
- PermissionsSubcommand: log message now reflects actual consent outcome
  ("configured successfully" vs "configured; admin consent required")
- InfrastructureSubcommandTests: replace Substitute.For<ILogger> with
  TestLogger that captures log entries; add proper assertions for
  warning (role assignment failure) and info (role already exists) paths

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ment, and client secret

Issue 1 (FIXED): WAM ignores login hint — picks OS default account instead of az-logged-in user
- MsalBrowserCredential: use WithAccount(account) when MSAL cache has a match for the login hint;
  fall back to WithPrompt(SelectAccount) when hint is set but account not in cache
- InteractiveGraphAuthService: resolve login hint via `az account show` before constructing
  MsalBrowserCredential, ensuring Graph client uses the correct user identity

Issue 2 (FIXED): Owner assignment fails with Directory.AccessAsUser.All in token
- BlueprintSubcommand: skip post-creation owner verification when owners@odata.bind was set
  during blueprint creation; ownership is set atomically and the post-check token carries
  Directory.AccessAsUser.All which the Agent Blueprint API explicitly rejects

Issue 3 (RESOLVED): Authorization.ReadWrite scope not found on Messaging Bot API
- Resolved as a symptom of Issue 1; with the correct user authenticated all inheritable
  permissions configure successfully with no errors

Issue 4 (IN PROGRESS): Client secret creation fails for Agent ID Admin
- AuthenticationConstants: add AgentIdentityBlueprintReadWriteAllScope constant; add
  AgentIdentityBlueprint.AddRemoveCreds.All to RequiredClientAppPermissions
- BlueprintSubcommand: use specific AgentIdentityBlueprint.ReadWrite.All scope for addPassword
  to avoid Directory.AccessAsUser.All bundling from .default; add retry on 404 to handle
  Entra eventual consistency after new blueprint creation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add loginHint to MSAL token flow to target Azure CLI user, preventing use of incorrect OS account. Resolve and pass login hint when creating Agent Blueprint secrets. Make ResolveAzLoginHintAsync internal for broader use. Default IMicrosoftGraphTokenProvider to browser/WAM auth. Update comments for scope and login hint usage.
…ss-user reuse

AcquireMsalGraphTokenAsync for the blueprint creation httpClient was called
without a login hint, causing WAM to silently return a cached token for the
OS default account instead of the az-logged-in user. This resulted in
Authorization_RequestDenied for identifier URI update and service principal
creation when AgentIdentityBlueprint.* scopes were present in the token.

Resolves the missing Service Principal for newly created blueprints.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…portal guidance

- Include loginHint in MicrosoftGraphTokenProvider cache key to prevent cross-user token reuse
- Downgrade speculative auth dialog messages from LogInformation to LogDebug
- Update non-Windows log message to reflect that browser or device code may appear
- Correct FederatedCredentialService remediation message to reference the right Entra portal blade

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… check, RoleCheckResult tri-state

- Fix consent URL to include only Microsoft Graph scopes (AADSTS500011/650053 fix)
- Add guard: skip Phase 3 when no Graph scopes in config (AADSTS900144 fix)
- Wrap SP creation in retry with exponential backoff for Entra replication lag
- Add RoleCheckResult tri-state enum (HasRole, DoesNotHaveRole, Unknown)
- Replace HasDirectoryRoleAsync with CheckDirectoryRoleAsync using transitiveMemberOf
- Add UserReadScope, GlobalAdminRoleTemplateId, AgentIdAdminRoleTemplateId constants
- Remove duplicate diagnostic role-check calls from AllSubcommand
- Convert AgentBlueprintService line 179 string literal to constant
- Remove redundant noisy log messages from InteractiveGraphAuthService
- Add tests for IsCurrentUserAdminAsync (HasRole, DoesNotHaveRole, Unknown)
- Update BatchPermissionsOrchestratorTests for RoleCheckResult

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ents)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ants

- Add AdminSubcommand that creates AllPrincipals oauth2PermissionGrants
  for all configured resources, completing the GA-only step after setup all
- Add --yes/-y flag to skip confirmation prompt (az CLI convention)
- Add DisplayAdminConsentPreview showing blueprint, tenant, and per-resource
  scopes before executing; uses WARNING: prefix for tenant-wide impact
- Add BatchPermissionsOrchestrator.GrantAdminPermissionsAsync for Phase 2b
  (AllPrincipals grants only, separate from Phase 2a inheritable permissions)
- Add AzCliHelper consolidating az account show + JSON parse (DRY fix)
- Wire InvocationContext into AdminSubcommand.SetHandler to propagate
  CancellationToken from Ctrl+C rather than CancellationToken.None
- Remove unused blueprintService and clientAppValidator from AdminSubcommand
- Fix GetMgGraphAccessTokenAsync NSubstitute mocks (missing 6th loginHint arg)
- Add guard in ConfigureBotPermissionsAsync for empty AgentBlueprintId
- Update PermissionsSubcommand test: missing manifest returns true because
  McpServersMetadata.Read.All is always seeded before manifest is read

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Consent URL generation (setup all, non-GA path):
- Populate resourceConsents[].consentUrl in a365.generated.config.json
  for all 5 resources when the current user lacks the GA role
- Terminal output now shows resource names and file path instead of
  printing raw encoded URLs; find them under resourceConsents[].consentUrl
- Fix \u0026 encoding: use JavaScriptEncoder.UnsafeRelaxedJsonEscaping so
  consent URLs in the JSON file keep literal '&' for direct copy-paste
- Remove duplicate admin consent warning from Warnings section (Next Steps
  block already covers it); remove orphaned config folder hint line

SP creation reliability:
- Extend retry predicate to catch 403 Forbidden in addition to 400 BadRequest
  (Agent Blueprint replication lag can surface as either status code)
- Increase maxRetries 8->10, baseDelaySeconds 5->8 for longer replication window
- LogWarning -> LogError after all retries exhausted
- Surface SP creation failure in SetupResults.Warnings when
  AgentBlueprintServicePrincipalObjectId is null after blueprint step

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Use scope constants for admin consent URL generation; ensure scopes are percent-encoded and joined with %20, not raw ampersands
- Add unit tests for consent URL construction and config population
- Enhance retry logic for service principal creation: distinguish transient 403 errors and retry only for replication lag
- Add async retry helper overload for operations needing async predicates
- Make GraphApiService login hint resolution injectable for test isolation
- Update tests to use full mocks and no-op login hint resolvers, preventing real CLI processes
- Use relaxed JSON encoder for config serialization to preserve literal '&' in URLs
- Update comments and docs for clarity
…, and tests

- Fix Task.Delay missing CancellationToken (AllSubcommand)
- Fix Environment.Exit -> ExceptionHandler.ExitWithCleanup (AdminSubcommand)
- Fix pipe buffer deadlock in AzCliHelper by reading stderr concurrently
- Fix GA role detection: use DirectoryReadAllScope for transitiveMemberOf query
- Fix blueprint auth message: remove incorrect 'Global Administrator' requirement
- Add combined single adminconsent URL as Option 2 in Next Steps output
- Add BuildCombinedConsentUrl helper and SetupResults.CombinedConsentUrl property
- Add unit tests for BuildCombinedConsentUrl in SetupHelpersConsentUrlTests
- Update pr-code-reviewer.md with anti-patterns 7-9 (Task.Delay, stderr deadlock, Environment.Exit)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add optional injectable parameters (commandRunner, loginHintResolver,
executor, retryDelayMsOverride) to production code with backward-
compatible defaults so tests can bypass real az/pwsh process spawns,
HTTPS calls, and Task.Delay waits. All production call sites are
unaffected when the parameters are omitted.

Also fixes a behavioral bug in BatchPermissionsOrchestrator: when
Phase 1 auth fails the admin-check now defaults to DoesNotHaveRole
instead of Unknown, preventing a spurious browser open and poll.
GrantAdminConsentAsync logs a distinct message distinguishing auth
failure from a confirmed non-GA-role result.

EnsureAppServicePlanExistsAsync gains a CancellationToken parameter
so Ctrl+C can cancel the plan-verification retry loop.

Test suite: 1224 tests, 0 failures, ~6 s (down from ~32 s).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Pass login hint (UPN/email) to all token acquisition calls to ensure correct account selection, especially with WAM on Windows.
- Always include a fixed, registered redirect URI in admin consent URLs to prevent AADSTS500113; encode all scope values and assert encoding in tests.
- Suppress exception details from console output; log full details to file only. Update tests to assert this behavior.
- Demote many internal log messages to LogDebug for cleaner CLI output.
- Temporarily disable blueprint messaging endpoint registration in CLI; direct users to Teams Developer Portal.
- Clarify setup summary output, separating completed, pending, and failed steps.
- Update copilot-instructions.md to require `because:` clauses for non-obvious test assertions and flag tests changed to match implementation.
- Improve exception handling in Program.cs for startup errors.
- Minor log message and formatting improvements throughout.
- Cache 'az account show' result process-wide in AzCliHelper.ResolveLoginHintAsync
  using a volatile Task<string?>? field. All services that resolve the login hint
  share one subprocess call per CLI invocation. Expected savings: ~60-80s.

- Cache 'az account get-access-token' result process-wide in AzCliHelper.AcquireAzCliTokenAsync
  using ConcurrentDictionary<string, Task<string?>> keyed by (resource, tenantId).
  ClientAppValidator, GraphApiService, and DelegatedConsentService all share one token
  acquisition per key. Expected savings: ~40s.

- Remove GraphApiService instance-level 5-min TTL cache (AzCliTokenCacheDuration,
  _cachedAzCliToken fields) — superseded by the process-level cache, which is shared
  across all GraphApiService instances and therefore more effective.

- CAE and forced re-auth paths call AzCliHelper.InvalidateAzCliTokenCache() before
  re-acquiring so stale tokens are never served from cache after revocation.

- Both caches use injectable test seams (LoginHintResolverOverride,
  AzCliTokenAcquirerOverride) so unit tests never spawn real az processes.
  Tests updated accordingly; GraphApiServiceTokenCacheTests rewritten to assert
  process-level caching behavior including the cross-instance scenario.
Eliminate slow az CLI subprocesses in infra and client app validation by
introducing ArmApiService and refactoring ClientAppValidator to use
GraphApiService for all Graph calls. All resource, RBAC, and app
registration checks now use direct HTTP, falling back to az CLI only
if needed.

Performance impact:
- a365 setup all: 8m12s -> 2m12s (6-minute reduction)
- Per-check latency: 15-35s -> ~0.5s (ARM) / ~200ms (Graph)
- Test suite: ~3 minutes -> 7 seconds (1230 tests)

Also:
- Removes token-in-CLI-arg security risk in ClientAppValidator
- Adds AzCliHelper process-level caches for login hint and token
  acquisition, shared across all services in a single CLI invocation
- CR fixes: CancellationToken from InvocationContext, IDisposable on
  ArmApiService, InvalidateLoginHintCache for production login path
- Test classes pre-warm AzCliHelper token cache; GraphApiService
  instances use loginHintResolver injection to bypass az subprocesses
- Review skill updated with anti-pattern for test performance regressions
Introduce --field/-f to query single config fields from static or generated config.
Standardize generated config to use "messagingEndpoint" (not "botMessagingEndpoint") and update all code/tests accordingly.
Add TryGetConfigField helper and unit tests.
Ensure backward compatibility by migrating legacy keys in MergeDynamicProperties.
Harden consent URLs, fix resource leaks, improve tests

- Replace hardcoded OAuth2 `state` in admin consent URLs with random GUIDs for CSRF protection; centralize URL construction in `SetupHelpers.BuildAdminConsentUrl`
- Dispose overwritten `JsonDocument` in `FederatedCredentialService` to prevent resource leaks
- Improve retry logic to propagate cancellation immediately on user-initiated cancel (Ctrl+C)
- Remove unused CLI option variable (`verbose`) to avoid dead code
- Enhance tests: assert random state in consent URLs and add `because:` documentation to clarify test requirements
Fix ARM API error handling, exit cleanup, and test isolation

- Replace direct Environment.Exit calls with ExceptionHandler.ExitWithCleanup for proper shutdown and cleanup.
- Update ARM API existence methods to return null (not false) for non-404 errors (e.g., 401/403/5xx), ensuring callers fall back to az CLI and don't misinterpret auth errors as missing resources.
- Add unit tests for 401 handling in ARM existence checks.
- Isolate AzCliHelper token cache in tests using xUnit collection and IDisposable to prevent parallel test interference and slow subprocess spawns.
- Clarify comments on [JsonIgnore] usage in Agent365Config.
- Update PR review rules to require reporting on ARM bool? existence method pattern in test-related PRs.
Adds --aiteammate false support to setup all and publish commands,
implementing the Agent Identity Blueprint pattern for Custom Engine Agents:
- Setup: creates blueprint in Entra, assigns Graph + Agent 365 Tools
  delegated permissions, provisions blueprint SP with consent, and
  registers agent instance via POST /beta/agentRegistry/agentInstances
- Publish: re-registers agent instance independently of setup
- SetupContext refactor: bundles mutable step state and services to
  eliminate scattered locals across the DW orchestration steps
- NonDwBlueprintSetupOrchestrator, NonDwSetupOrchestrator (app-based,
  dry-run only — Phase B deferred), GraphApiService.RegisterAgentInstanceAsync
- Config: AiTeammate, UseBlueprint, IsNonDwBlueprint, AgentInstanceId fields

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add --agent-instance-only flag to 'setup all' for non-DW blueprints, allowing direct agent instance registration without re-running requirements or blueprint steps.
- Prompt for missing admin consent on required permissions during non-DW setup, with interactive grant support.
- Update summary output to distinguish recovery actions for agent instance vs. messaging endpoint.
- Support agent instance deletion in cleanup for non-DW blueprints, using new GraphApiService.DeleteAgentInstanceAsync.
- Enhance GraphApiService with robust agent instance registration and deletion, including retry logic and detailed logging.
- Extend ClientAppValidator with methods for consent gap detection and granting.
- Add Azure CLI app ID and .default scope to AuthenticationConstants; require AgentInstance.ReadWrite.All.
- Add AzCliHelper method to acquire Graph tokens by scope, ensuring fresh tokens after consent/role changes.
- Update SetupContext, SetupResults, and command registration to support new flows and improved UX.
- Move agent identity creation logic to GraphApiService for reuse and robustness; now used by both CLI and instance runner
- Cleanup deletes agent identity if AgenticAppId is present (data-driven, not flag-based)
- Admin setup auto-detects required OAuth2 grants and attempts agent instance registration for non-DW blueprints, with improved role guidance
- Standardize log messages for clarity; remove bracketed status tags ([SUCCESS], [WARN], etc.)
- Improve OAuth2 grant robustness and error reporting; handle partial failures with actionable warnings
- Add exponential backoff for blueprint client secret propagation (AADSTS7000215)
- Update tests and help text to match new flows and output
- Enhance documentation and recovery guidance for both DW and non-DW flows
Integrates main branch changes (non-admin setup flow, a365 setup admin command,
GraphApiConstants URL constants, AzCliHelper ArgumentList injection safety,
retry improvements, AzCliTokenCache reset for tests) with branch additions
(non-DW blueprint setup, agent instance registration, NonDwBlueprintSetupOrchestrator).

Key merge decisions:
- URL hardcoding replaced with GraphApiConstants constants (from main)
- AzCliHelper rewrites to use ArgumentList for shell-injection safety (from main)
- OAuth2 grant retry with exponential backoff for Directory_ObjectNotFound (from main)
- BotConfigurator 'Invalid roles' retry block (from main)
- addPassword retry kept on NotFound || Forbidden for owner propagation lag (from branch)
- Non-DW methods in GraphApiService, A365CreateInstanceRunner retained (from branch)
- hasActionRequired includes ClientSecretManualActionRequired (from main)
- [OK]/[FAILED]/[WARN] log prefixes in SetupHelpers (from main)
- Fix NonDwBlueprintSetupOrchestratorExecuteTests to pass graphBaseUrl null arg

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Major rewrite and expansion of a365-observability-instructions.md:
  - Clarifies usage, adds .NET helper files for agentType=3, and details scope hierarchy and instrumentation requirements.
  - Formalizes required post-setup summary output.
- CLI: Requirements subcommand now accepts requirementsChecksOverride for easier unit testing; command wiring updated accordingly.
- GraphApiService: Enhanced error logging for failed DELETE requests with status code and error details.
- Tests: SetupCommandTests and AgentBlueprintServiceTests updated to avoid real subprocesses by injecting empty or no-op requirement checks and login hint resolvers.
- Minor formatting and clarity improvements in test files.
Copilot AI review requested due to automatic review settings April 20, 2026 00:37

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

Comment thread src/Microsoft.Agents.A365.DevTools.Cli/Program.cs
Comment thread src/Microsoft.Agents.A365.DevTools.Cli/Commands/CreateInstanceCommand.cs Outdated
- Add code review checks for unconditional success logs and startup network calls
- Refine a365-observability-instructions.md: clarify package install, add explicit instrumentation prompt, and note on recording responses
- Update a365-setup-instructions.md: conditional final message and observability opt-in prompt
- Fix CreateInstanceCommand: gate success log on all grant outcomes
- In Program.cs, skip client app ID pre-resolution for help/version
- Make messagingEndpoint optional at config-validation time; add test
- Remove messagingEndpoint placeholder from AllSubcommand.cs

These changes improve correctness, user experience, and developer guidance.
@sellakumaran
sellakumaran enabled auto-merge (squash) April 20, 2026 02:17
ajmfehr
ajmfehr previously approved these changes Apr 20, 2026
@sellakumaran
sellakumaran disabled auto-merge April 20, 2026 17:07
Required-field validation now lives solely in Agent365Config.Validate(), with ConfigService.ValidateAsync() delegating to it and only performing format checks when fields are present. messagingEndpoint is now optional when needDeployment is false. Tests updated to include new required fields and expect camelCase error messages. Documentation updated to reflect the new validation pattern and reviewer guidance.
Copilot AI review requested due to automatic review settings April 20, 2026 17:38

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

Comment thread src/Microsoft.Agents.A365.DevTools.Cli/Program.cs
Comment thread src/Microsoft.Agents.A365.DevTools.Cli/Services/ConfigService.cs
Added logic to prefix ACR names with 'a' if they do not start with a letter, complying with Azure requirements. Updated JSON parsing to allow trailing commas for more robust config file handling.
ajmfehr
ajmfehr previously approved these changes Apr 20, 2026
gwharris7
gwharris7 previously approved these changes Apr 20, 2026
Copilot AI review requested due to automatic review settings April 20, 2026 18:42
@Sunil-Garg
Sunil-Garg dismissed stale reviews from gwharris7 and ajmfehr via e4e71d7 April 20, 2026 18:42
@sellakumaran
sellakumaran enabled auto-merge (squash) April 20, 2026 18:47

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

@sellakumaran
sellakumaran disabled auto-merge April 20, 2026 19:37
@sellakumaran
sellakumaran merged commit 9ab6516 into main Apr 20, 2026
12 checks passed
@sellakumaran
sellakumaran deleted the users/sellak/nondw branch April 20, 2026 19:48
sellakumaran added a commit that referenced this pull request Apr 23, 2026
Reconciles the Teams Graph migration with main's Azure App Service infra
removal (#379), non-DW --agent-name flow (#365), managerApplications
attribute (#372), MCP V2 audience support (#373), and related changes.

Key resolutions:
- BotConfigurator.cs modify/delete: kept the delete; main's changes to
  it (making Location optional in the ABS payload) don't apply to Teams
  Graph.
- --m365 opt-in flag, TeamsGraphBackendConfigurator, SkippedDueToRollout,
  and rollout-cutoff date preserved intact.
- ExecuteAllCleanupAsync no longer takes a configurator; --agent-name
  /--tenant-id/--yes flags from main and their bootstrap config path
  preserved.
- UpdateEndpointAsync kept in simplified clear-then-set form; obsolete
  ABS regression test (Step 1/Step 1.5 pattern) removed.
- SetupHelpers.RegisterBlueprintMessagingEndpointAsync kept in its
  simplified form returning EndpointRegistrationResult; endpoint-name
  length check dropped.
- SetupContext renamed to use backendConfigurator; matching test-only
  callers updated.

Tests: 1316 passed, 0 failed, 13 skipped.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
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