Skip to content

Normalize command result shapes to object-root *CommandResult records#3058

Draft
vcolin7 wants to merge 22 commits into
vcolin7/output-schema-infrafrom
vcolin7/result-shape-normalization
Draft

Normalize command result shapes to object-root *CommandResult records#3058
vcolin7 wants to merge 22 commits into
vcolin7/output-schema-infrafrom
vcolin7/result-shape-normalization

Conversation

@vcolin7

@vcolin7 vcolin7 commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

PR 3 of the input/output schema modernization series (follows #2995 "Modernize inputSchema" and #3000 "outputSchema + structuredContent infrastructure"). This PR is stacked on vcolin7/output-schema-infra — please review with that as the base.

Why: PR 4+ will attach ResultTypeInfo (i.e. outputSchema + structuredContent) uniformly across every namespace. That only works cleanly if every command's payload root is already a well-formed object. Today a number of commands emit bare JSON arrays, raw scalars/strings, loosely-named records, or several different record types depending on state — none of which can have an object outputSchema attached uniformly. This PR fixes the result shapes so PR 4 becomes a mechanical wiring pass.

Approach (shape-only): for every command, make ResponseResult.Create(...) emit a single {Resource}{Operation}CommandResult record whose JSON root is an object, by one of:

  • Consolidate — collapse N different result records into one record with optional/nullable fields (3a).
  • Wrap — nest a bare array / scalar / external model under a *CommandResult object root (3b).
  • Rename — rename output-preserving records to the *CommandResult convention.

Every new/changed record is registered in its source-gen *JsonContext ([JsonSerializable(...)]) for AOT safety. This PR intentionally does not wire ResultTypeInfo/SetResult (that is PR 4) and excludes App Configuration, which was migrated in PR 2 as the pilot and is the reference template.

Where a shape necessarily changed (bare array/scalar/object → object root) that is an intentional, user-facing output change and is captured in the changelog entries.

Tools normalized

Toolset / Area Command(s) Change Output shape changed? Commit
Compute vm get, vmss get Consolidate multiple records → one *CommandResult w/ optional fields No 447a29b17
Event Hubs namespace get Consolidate multi-record result → single *CommandResult No c3c7c4dc5
Managed Lustre importjob get, autoimportjob get, autoexportjob get Consolidate job results → single *CommandResult records No e344db853
Managed Lustre remaining commands Rename result records → *CommandResult No fd7d5af73
SQL server get (+ others) Wrap bare array → { servers: [...] }; rename records Yes (server get) 60ed90764
Search index query Wrap bare array → { results: [...] } Yes 7f1c9a189
Storage blob upload Rename BlobUploadResultBlobUploadCommandResult No 53240007c
Advisor recommendation apply (+ others) Wrap bare array → { rules: [...] } Yes 90836e140
Functions language list, project get Single-element array → single object Yes 327d30985
Best Practices Azure / General / Terraform / WAF get Bare string array → { bestPractices: [...] } / { guidance: [...] } Yes 0a6941721
Monitor orchestrator (×4), resource/workspace log query, entity get-health (7 cmds) Raw string / array / object → object-root wrappers ({result}/{results}/{health}) Yes fb210099d
Core group list Rename result record → *CommandResult No a01c5c7fc
AzureIsv (Datadog) monitoredresources list Rename result record → *CommandResult No 417a8899c
App Service multiple Rename result records → *CommandResult No f5ac53f19
Confidential Ledger multiple Rename result records → *CommandResult No a43f19435
Azure Terraform multiple Rename result records → *CommandResult No ea27a2e9e
Extension multiple Rename result records → *CommandResult No 95026f8c4
File Shares informational commands Rename result records → *CommandResult No 38e7b3107
Cloud Architect design Rename result record → DesignCommandResult No 91f8e4830
Fabric Docs best-practices, workload/platform APIs, definition Bare array / string / object → object-root wrappers Yes 93abe9c09
Fabric OneLake shortcut get/create/list, data-access role get/create/list, settings get Bare object / list → object-root wrappers ({shortcut}/{shortcuts,...}/{role}/{roles,...}/{settings}) Yes 03d564ddc

Changelog entries added in ac6893be2 (6 Azure + 4 Fabric Breaking Changes).

Intentionally not touched

  • Passthrough (left as ResultTypeInfo == null): service start, plugin telemetry — intentionally payload-free / raw passthrough.
  • Deferred to PR 4 allow-list: tools list (emits a bare-array results payload that is a hard CLI wire contract consumed by eng/scripts/New-ToolsListFile.ps1, Update-AzCommandsMetadata.ps1, and the ToolDescriptionEvaluator scripts — wrapping it would break them); the shared SreAgent result types (SreAgentInvestigationResult, SreAgentThreadOperationResult, ScheduledTaskOperationResult, SreAgentTextResult), which are already object-root service DTOs / two-generic TResult and auto-wire in PR 4 with zero output churn.
  • App Configuration: already normalized in PR 2 (pilot / reference template).

Verification

  • ./eng/scripts/Build-Local.ps1 -VerifyNpx: all 3 servers (Azure, Fabric, Template) build + package AOT-safe; npx ... tools list smoke test passes for Azure and Fabric (status 200), confirming all source-gen JsonContext registrations resolve.
  • Affected unit tests updated to assert the new result shapes.

GitHub issue number?

N/A — part of the input/output schema modernization series (see #2995, #3000). No standalone tracking issue.

Pre-merge Checklist

  • Required for All PRs
    • Read contribution guidelines
    • PR title clearly describes the change
    • Commit history is clean with descriptive messages (cleanup guide) — one commit per toolset / logical group
    • Added comprehensive tests for new/modified functionality — existing unit tests updated to assert the new result shapes (shape-only refactor; no new behavior)
    • Created a changelog entry if the change falls among the following: new feature, bug fix, UI/UX update, breaking change, or updated dependencies. Follow the changelog entry guide — 6 Azure + 4 Fabric Breaking Changes entries
  • For MCP tool changes: — N/A: cross-cutting result-shape refactor; no tool is added, renamed, or has its command/option surface or description changed
    • One tool per PR: This PR adds or modifies only one MCP tool for faster review cycles — N/A (infrastructure refactor spanning many toolsets)
    • Updated servers/Azure.Mcp.Server/README.md and/or servers/Fabric.Mcp.Server/README.md documentation — N/A (no tool surface change)
    • Validate README.md changes running the script ./eng/scripts/Process-PackageReadMe.ps1. See Package README — N/A
    • For new or modified tool descriptions, ran ToolDescriptionEvaluator and obtained a score of 0.4 or more and a top 3 ranking for all related test prompts — N/A (no description changes)
    • For tools with new names, including new tools or renamed tools, update consolidated-tools.json — N/A (no tool-name changes; only internal result-record renames)
    • For renamed tools, follow the Tool Rename Checklist and tag the PR with the breaking-change label — N/A (no tool renames)
    • For new tools associated with Azure services or publicly available tools/APIs/products, add URL to documentation in the PR description — N/A
  • Extra steps for Azure MCP Server tool changes: — N/A: result output shape only; no command/option surface change
    • Updated command list in servers/Azure.Mcp.Server/docs/azmcp-commands.md — N/A
    • Ran ./eng/scripts/Update-AzCommandsMetadata.ps1 to update tool metadata in azmcp-commands.md (required for CI) — N/A
    • Updated test prompts in servers/Azure.Mcp.Server/docs/e2eTestPrompts.md — N/A
    • 👉 For Community (non-Microsoft team member) PRs: — N/A
      • Security review: Reviewed code for security vulnerabilities, malicious code, or suspicious activities before running tests (crypto mining, spam, data exfiltration, etc.)
      • Manual tests run: added comment /azp run mcp - pullrequest - live to run Live Test Pipeline

Invoking Livetests

Copilot submitted PRs are not trustworthy by default. Users with write access to the repo need to validate the contents of this PR before leaving a comment with the text /azp run mcp - pullrequest - live. This will trigger the necessary livetest workflows to complete required validation.

vcolin7 added 22 commits July 15, 2026 16:51
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
1 pipeline(s) were filtered out due to trigger conditions.
There may be pipelines that require an authorized user to comment /azp run to run.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant