Skip to content

feat(ai-agents): show command surfaces agent_endpoint via GetAgent#7938

Draft
antriksh30 wants to merge 1 commit intomainfrom
antriksh30/show-include-agent-endpoint
Draft

feat(ai-agents): show command surfaces agent_endpoint via GetAgent#7938
antriksh30 wants to merge 1 commit intomainfrom
antriksh30/show-include-agent-endpoint

Conversation

@antriksh30
Copy link
Copy Markdown
Contributor

@antriksh30 antriksh30 commented Apr 28, 2026

Updates azd ai agent show to surface the agent_endpoint block (protocols, authorization_schemes) which the per-version API route never returns.

Approach

  • Continue calling GetAgentVersion for the env-tracked version (preserves prior version-selection behavior).
  • Additionally call GetAgent to fetch the agent-level agent_endpoint and merge it into the JSON/table output.
  • If GetAgent fails, the command still succeeds with the version body alone (agent_endpoint is omitted from output).

@github-actions
Copy link
Copy Markdown

🔗 Linked Issue Required

Thanks for the contribution! Please link a GitHub issue to this PR by adding Fixes #123 to the description or using the sidebar.
No issue yet? Feel free to create one!

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the azd ai agent show extension command to retrieve full agent details (via GetAgent) so output can include the agent_endpoint details, with a fallback to GetAgentVersion when the requested version is not the latest.

Changes:

  • Add agent_endpoint (protocols, authorization schemes) to agent API models and round-trip tests.
  • Switch show action to call GetAgent first, falling back to GetAgentVersion when needed.
  • Extend JSON and table output to render the new endpoint information.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
cli/azd/extensions/azure.ai.agents/internal/pkg/agents/agent_api/models.go Adds agent_endpoint and related structs to the agent model.
cli/azd/extensions/azure.ai.agents/internal/pkg/agents/agent_api/models_test.go Extends model round-trip test coverage to include agent_endpoint.
cli/azd/extensions/azure.ai.agents/internal/cmd/show.go Uses GetAgent for show, merges endpoint info into JSON and table output, with fallback to GetAgentVersion.
cli/azd/extensions/azure.ai.agents/internal/cmd/show_test.go Updates tests for updated print function signatures.
Comments suppressed due to low confidence (1)

cli/azd/extensions/azure.ai.agents/internal/cmd/show.go:196

  • The command now surfaces agent_endpoint in JSON and table output, but the tests only validate that printing succeeds (no assertions that agent_endpoint fields are actually rendered). Add tests that capture stdout for printAgentVersionJSON/printAgentVersionTable and assert presence/format of Protocols and AuthorizationSchemes rows/fields to prevent regressions.
	jsonBytes, err := json.MarshalIndent(out, "", "  ")
	if err != nil {
		return fmt.Errorf("failed to marshal agent version to JSON: %w", err)
	}
	fmt.Println(string(jsonBytes))
	return nil
}

func printAgentVersionTable(version *agent_api.AgentVersionObject, endpoint *agent_api.AgentEndpointInfo) error {
	w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
	fmt.Fprintln(w, "FIELD\tVALUE")
	fmt.Fprintln(w, "-----\t-----")

	fmt.Fprintf(w, "ID\t%s\n", version.ID)
	fmt.Fprintf(w, "Name\t%s\n", version.Name)
	fmt.Fprintf(w, "Version\t%s\n", version.Version)
	if version.Status != "" {
		fmt.Fprintf(w, "Status\t%s\n", version.Status)
	}
	if version.Description != nil {
		fmt.Fprintf(w, "Description\t%s\n", *version.Description)
	}
	if version.CreatedAt != 0 {
		ts := time.Unix(version.CreatedAt, 0).UTC().Format(time.RFC3339)
		fmt.Fprintf(w, "Created At\t%s\n", ts)
	}
	if version.AgentGUID != "" {
		fmt.Fprintf(w, "Agent GUID\t%s\n", version.AgentGUID)
	}
	if version.InstanceIdentity != nil {
		fmt.Fprintf(w, "Instance Identity Principal ID\t%s\n", version.InstanceIdentity.PrincipalID)
		fmt.Fprintf(w, "Instance Identity Client ID\t%s\n", version.InstanceIdentity.ClientID)
	}
	if version.Blueprint != nil {
		fmt.Fprintf(w, "Blueprint Principal ID\t%s\n", version.Blueprint.PrincipalID)
		fmt.Fprintf(w, "Blueprint Client ID\t%s\n", version.Blueprint.ClientID)
	}
	if version.BlueprintReference != nil {
		fmt.Fprintf(w, "Blueprint Reference Type\t%s\n", version.BlueprintReference.Type)
		fmt.Fprintf(w, "Blueprint Reference ID\t%s\n", version.BlueprintReference.BlueprintID)
	}
	for k, v := range version.Metadata {
		fmt.Fprintf(w, "Metadata[%s]\t%s\n", k, v)
	}
	if endpoint != nil {
		if len(endpoint.Protocols) > 0 {
			fmt.Fprintf(w, "Endpoint Protocols\t%s\n", strings.Join(endpoint.Protocols, ", "))
		}
		for i, scheme := range endpoint.AuthorizationSchemes {
			label := fmt.Sprintf("Endpoint Auth[%d]", i)
			if scheme.IsolationKeySource != nil {
				fmt.Fprintf(w, "%s\t%s (isolation: %s)\n", label, scheme.Type, scheme.IsolationKeySource.Kind)
			} else {
				fmt.Fprintf(w, "%s\t%s\n", label, scheme.Type)
			}
		}
	}

	return w.Flush()
}

@antriksh30 antriksh30 force-pushed the antriksh30/show-include-agent-endpoint branch from ff8e0af to 7eba15b Compare April 28, 2026 11:48
@antriksh30 antriksh30 requested a review from Copilot April 28, 2026 11:49
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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

return fmt.Errorf("failed to get agent: %w", err)
}

version := &agent.Versions.Latest
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

show now calls GetAgent() and always prints agent.Versions.Latest, ignoring the version resolved from the azd environment (info.Version / a.Version). This also means the command can still fail earlier if AGENT_<SERVICE>_VERSION isn’t set even though the new API call doesn’t need it, and it can display a different version than the one tracked in the environment. Consider either (a) removing the environment-version requirement and treating show as “latest version”, or (b) keeping the previous behavior by selecting the env-tracked version (e.g., call GetAgentVersion for a.Version) while still using GetAgent only to retrieve agent_endpoint.

Suggested change
version := &agent.Versions.Latest
version, err := agentClient.GetAgentVersion(ctx, a.Name, a.Version, DefaultAgentAPIVersion)
if err != nil {
return fmt.Errorf("failed to get agent version: %w", err)
}

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Restored GetAgentVersion(a.Version) for the version body in cec7ef1. GetAgent is still called to fetch agent_endpoint (which the per-version route doesn't return). If GetAgent fails the command still succeeds with the version body alone.

Comment on lines 77 to 88
func TestPrintAgentVersionJSON(t *testing.T) {
version := &agent_api.AgentVersionObject{
Object: "agent.version",
ID: "ver-123",
Name: "my-agent",
Version: "1",
CreatedAt: 1735689600, // 2025-01-01T00:00:00Z
}

err := printAgentVersionJSON(version)
err := printAgentVersionJSON(version, nil)
require.NoError(t, err)
}
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests don’t currently assert the new agent_endpoint field in the JSON output. TestPrintAgentVersionJSON_Format marshals the version directly (not the agentShowOutput used by printAgentVersionJSON), and TestPrintAgentVersionJSON only checks for no error. Consider capturing stdout from printAgentVersionJSON(version, endpoint) and asserting that agent_endpoint is present and correctly shaped when a non-nil endpoint is provided.

Copilot generated this review using guidance from repository custom instructions.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added TestPrintAgentVersionJSON_WithEndpoint and TestPrintAgentVersionJSON_NilEndpointOmitsField in cec7ef1 — they capture stdout, unmarshal, and assert agent_endpoint shape (and that it's omitted when nil).

Comment on lines 166 to 170
}

err := printAgentVersionTable(version)
err := printAgentVersionTable(version, nil)
require.NoError(t, err)
}
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

printAgentVersionTable gained endpoint rows, but the table tests only assert the function returns no error and don’t verify the new rows render. Consider adding a test that passes a non-nil endpoint and captures stdout to assert the protocols/auth scheme lines are emitted (and remain stable).

Copilot generated this review using guidance from repository custom instructions.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added TestPrintAgentVersionTable_WithEndpoint in cec7ef1 — captures stdout and asserts the Endpoint Protocols, Endpoint Auth[i], and isolation: rows render as expected.

Switches �zd ai agent show from GetAgentVersion to GetAgent so the response includes the agent_endpoint block (protocols, authorization_schemes). Falls back to GetAgentVersion when the deployed version no longer matches the service's latest.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@antriksh30 antriksh30 force-pushed the antriksh30/show-include-agent-endpoint branch from 7eba15b to cec7ef1 Compare April 28, 2026 12:57
Copy link
Copy Markdown
Member

@jongio jongio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Solid approach - calling GetAgent for enrichment while keeping GetAgentVersion authoritative for the selected version is clean. A few suggestions to tighten debuggability and test coverage.

var endpoint *agent_api.AgentEndpointInfo
if agent, err := agentClient.GetAgent(ctx, a.Name, DefaultAgentAPIVersion); err == nil {
endpoint = agent.AgentEndpoint
}
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.

Consider logging the error in debug mode when GetAgent fails. Without it, users can't distinguish 'the agent has no endpoint' from 'the fetch failed silently'. Something like:

Suggested change
}
var endpoint *agent_api.AgentEndpointInfo
if agent, err := agentClient.GetAgent(ctx, a.Name, DefaultAgentAPIVersion); err == nil {
endpoint = agent.AgentEndpoint
} else {
log.Printf("show: GetAgent for %q: %v", a.Name, err)
}

This aligns with the log.Printf pattern used in helpers.go for non-blocking errors.

err := printAgentVersionJSON(version)
err := printAgentVersionJSON(version, nil)
require.NoError(t, err)
}
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.

The rendering tests are thorough. One gap: the key contract that show still succeeds when GetAgent fails (but fails when GetAgentVersion fails) doesn't have a direct test. If Run() is later refactored, this fallback behavior could regress without failing any test.

Worth adding a test that exercises Run() with a mocked/fake client where GetAgent returns an error and verifying the command still produces valid output.

_, err = io.Copy(&buf, r)
require.NoError(t, err)
require.NoError(t, runErr)
return buf.String()
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.

Nit: consider using .Cleanup to ensure stdout is restored even if the callback panics or a require trips early.

@JeffreyCA JeffreyCA added the ext-agents azure.ai.agents extension label May 5, 2026
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.

4 participants