diff --git a/cli/azd/extensions/azure.ai.agents/cspell.yaml b/cli/azd/extensions/azure.ai.agents/cspell.yaml index 2e39297a71c..d320543e169 100644 --- a/cli/azd/extensions/azure.ai.agents/cspell.yaml +++ b/cli/azd/extensions/azure.ai.agents/cspell.yaml @@ -1,4 +1,8 @@ import: ../../.vscode/cspell.yaml +overrides: + - filename: ["internal/helpformat/*.go", "internal/cmd/root.go"] + words: + - helpformat words: # Connection commands - tavily diff --git a/cli/azd/extensions/azure.ai.agents/go.mod b/cli/azd/extensions/azure.ai.agents/go.mod index 48f58491684..411edf676dd 100644 --- a/cli/azd/extensions/azure.ai.agents/go.mod +++ b/cli/azd/extensions/azure.ai.agents/go.mod @@ -57,6 +57,7 @@ require ( github.com/aymerick/douceur v0.2.0 // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect github.com/blang/semver/v4 v4.0.0 // indirect + github.com/bradleyjkemp/cupaloy/v2 v2.8.0 // indirect github.com/buger/goterm v1.0.4 // indirect github.com/buger/jsonparser v1.1.2 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect diff --git a/cli/azd/extensions/azure.ai.agents/go.sum b/cli/azd/extensions/azure.ai.agents/go.sum index 7b8fabb44f5..7d643a148c3 100644 --- a/cli/azd/extensions/azure.ai.agents/go.sum +++ b/cli/azd/extensions/azure.ai.agents/go.sum @@ -233,6 +233,7 @@ github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/add.go b/cli/azd/extensions/azure.ai.agents/internal/cmd/add.go index 3e30bc9c873..519194f6985 100644 --- a/cli/azd/extensions/azure.ai.agents/internal/cmd/add.go +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/add.go @@ -31,6 +31,8 @@ func newAgentDependencyCommand( cmd := &cobra.Command{ Use: dependencyType + " ", Short: fmt.Sprintf("Manage %s service dependencies for an agent.", dependencyType), + Example: fmt.Sprintf(` # Attach an existing %s service to an agent + azd ai agent %s add --agent `, dependencyType, dependencyType), } cmd.AddCommand(newAgentAddDependencyCommand(extCtx, dependencyType, expectedHost)) return cmd @@ -45,7 +47,14 @@ func newAgentAddDependencyCommand( cmd := &cobra.Command{ Use: "add ", Short: fmt.Sprintf("Add a %s service dependency to an agent service.", dependencyType), - Args: cobra.ExactArgs(1), + Long: fmt.Sprintf(`Add a %s service dependency to an agent service. + +Both services must already be declared in azure.yaml. This adds a uses entry +to the agent service; it does not create the dependency resource. +Use --agent to identify the agent service to update.`, dependencyType), + Example: fmt.Sprintf(` # Attach an existing %s service to an agent + azd ai agent %s add --agent `, dependencyType, dependencyType), + Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { agentServiceName, dependencyServiceName := normalizeAgentDependencyNames(flags.agent, args[0]) azdClient, err := azdext.NewAzdClient() diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/code.go b/cli/azd/extensions/azure.ai.agents/internal/cmd/code.go index af914c13f5a..216d6c35de0 100644 --- a/cli/azd/extensions/azure.ai.agents/internal/cmd/code.go +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/code.go @@ -23,6 +23,8 @@ func newCodeCommand(extCtx *azdext.ExtensionContext) *cobra.Command { Use: "code", Short: "Manage agent source code. (Preview)", Long: `Commands for managing the source code of code-based hosted agents.`, + Example: ` # Download the deployed agent source code + azd ai agent code download`, } cmd.AddCommand(newCodeDownloadCommand(extCtx)) diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/doctor.go b/cli/azd/extensions/azure.ai.agents/internal/cmd/doctor.go index d8e18a70cfe..6fa6b8b517f 100644 --- a/cli/azd/extensions/azure.ai.agents/internal/cmd/doctor.go +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/doctor.go @@ -37,7 +37,7 @@ reporting on each one and (when all checks pass) suggesting the next command to run. Use this when you have lost terminal context or hit a confusing error and want a complete picture of the project's state. -Exit codes: +Exit Codes: 0 — at least one check passed and no checks failed 1 — any check failed 2 — all checks were skipped (e.g. preconditions unmet)`, diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/eval.go b/cli/azd/extensions/azure.ai.agents/internal/cmd/eval.go index b8794c49ed3..647fdb087ab 100644 --- a/cli/azd/extensions/azure.ai.agents/internal/cmd/eval.go +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/eval.go @@ -121,12 +121,11 @@ func newEvalCommand(extCtx *azdext.ExtensionContext) *cobra.Command { Short: "Create and run quick evals for an agent.", Long: `Create and run quick evals for an agent. -Subcommands: - generate Generate an eval config and dataset from a hosted agent - run Execute an evaluation run from eval.yaml - update Update an existing eval configuration - list List evaluations for the current project - show Show details of an evaluation run`, +Generate an eval config and dataset, run evaluations, and inspect the results. +Use 'azd ai agent eval update' to upload changes to local evaluators and datasets.`, + Example: ` # Generate an eval suite and run it + azd ai agent eval generate + azd ai agent eval run`, } cmd.AddCommand(newEvalGenerateCommand(extCtx)) diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/eval_list.go b/cli/azd/extensions/azure.ai.agents/internal/cmd/eval_list.go index 1f4b7d91ca7..6e7424ec8a9 100644 --- a/cli/azd/extensions/azure.ai.agents/internal/cmd/eval_list.go +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/eval_list.go @@ -32,7 +32,9 @@ func newEvalListCommand(extCtx *azdext.ExtensionContext) *cobra.Command { cmd := &cobra.Command{ Use: "list", Short: "List evaluations for the current project.", - Args: cobra.NoArgs, + Example: ` # List the five most recent evaluations + azd ai agent eval list --limit 5`, + Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { ctx := azdext.WithAccessToken(cmd.Context()) logCleanup := setupDebugLogging(cmd.Flags()) diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/eval_run.go b/cli/azd/extensions/azure.ai.agents/internal/cmd/eval_run.go index 333224a923e..51e8c01002b 100644 --- a/cli/azd/extensions/azure.ai.agents/internal/cmd/eval_run.go +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/eval_run.go @@ -39,7 +39,12 @@ func newEvalRunCommand(extCtx *azdext.ExtensionContext) *cobra.Command { cmd := &cobra.Command{ Use: "run", Short: "Execute an evaluation run from eval.yaml.", - Args: cobra.NoArgs, + Example: ` # Run the evaluation configured in eval.yaml + azd ai agent eval run + + # Start a run without waiting for results + azd ai agent eval run --no-wait`, + Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { ctx := azdext.WithAccessToken(cmd.Context()) logCleanup := setupDebugLogging(cmd.Flags()) diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/eval_show.go b/cli/azd/extensions/azure.ai.agents/internal/cmd/eval_show.go index f841b7e0245..85b2d6cdf87 100644 --- a/cli/azd/extensions/azure.ai.agents/internal/cmd/eval_show.go +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/eval_show.go @@ -37,6 +37,11 @@ func newEvalShowCommand(extCtx *azdext.ExtensionContext) *cobra.Command { Long: `Show an eval definition, run history, or run details. If eval-id is omitted, the most recent eval from the current environment is used.`, + Example: ` # Show the most recent evaluation in the current environment + azd ai agent eval show + + # Show a specific evaluation + azd ai agent eval show `, Args: cobra.MaximumNArgs(1), RunE: func(cmd *cobra.Command, args []string) error { ctx := azdext.WithAccessToken(cmd.Context()) diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/eval_update.go b/cli/azd/extensions/azure.ai.agents/internal/cmd/eval_update.go index 0faf4ea1e39..a6efe71bab2 100644 --- a/cli/azd/extensions/azure.ai.agents/internal/cmd/eval_update.go +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/eval_update.go @@ -43,6 +43,8 @@ The version fields in the config are updated after successful uploads. In interactive mode, you will be prompted for each asset type that has local changes. Use --dataset-only or --evaluator-only to skip prompts.`, + Example: ` # Upload changes to the local dataset + azd ai agent eval update --dataset-only`, Args: cobra.NoArgs, RunE: func(cmd *cobra.Command, args []string) error { ctx := azdext.WithAccessToken(cmd.Context()) diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/files.go b/cli/azd/extensions/azure.ai.agents/internal/cmd/files.go index 419f91888a0..ed090ebf245 100644 --- a/cli/azd/extensions/azure.ai.agents/internal/cmd/files.go +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/files.go @@ -44,6 +44,8 @@ from the last invoke session, or can be overridden with --session-id. For agents configured with header-based isolation, pass --user-identity on each file operation.`, + Example: ` # List files in the current hosted agent session + azd ai agent files list`, } cmd.AddCommand(newFilesUploadCommand(extCtx)) diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/help.go b/cli/azd/extensions/azure.ai.agents/internal/cmd/help.go new file mode 100644 index 00000000000..450eeb89386 --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/help.go @@ -0,0 +1,32 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package cmd + +const agentHelpFooter = `Environments & Environment Variables: + An azd environment is a named deployment configuration, such as dev or prod. + Its values are stored locally in .azure//.env. + Use 'azd env new ' to create one, 'azd env select ' to change the + default, or --environment (-e) to select one for a command. + + Use 'azd env set ' to save a value and 'azd env get-values' to + inspect the selected environment. Values can include secrets; do not share + the output or commit .azure to source control. + + FOUNDRY_PROJECT_ENDPOINT identifies the Foundry project. Init records it + when you select an existing project; generated azure.yaml files reference + it as ${FOUNDRY_PROJECT_ENDPOINT} to keep configuration portable. + Deploy records AGENT__NAME, AGENT__VERSION and + AGENT__PROJECT_ENDPOINT so commands can resolve deployed agents. + is the service name in uppercase with spaces and hyphens replaced + by underscores (for example, my-agent becomes MY_AGENT). + + For hosted agent runtime settings, use the service-level env mapping in + azure.yaml. Reference environment values with ${VARIABLE_NAME}; setting an + azd environment value alone does not forward every value to the agent. + Use 'azd ai agent run' for local development and 'azd deploy' to apply changes + to the deployed agent. + +Learn More: + Agent documentation: https://aka.ms/azd-ai-agent-docs + Environment commands: 'azd env --help'` diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/help_test.go b/cli/azd/extensions/azure.ai.agents/internal/cmd/help_test.go new file mode 100644 index 00000000000..0970195046d --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/help_test.go @@ -0,0 +1,104 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package cmd + +import ( + "bytes" + "strings" + "testing" + + "github.com/azure/azure-dev/cli/azd/pkg/output" + "github.com/azure/azure-dev/cli/azd/test/snapshot" + "github.com/fatih/color" + "github.com/spf13/cobra" + "github.com/spf13/pflag" + "github.com/stretchr/testify/require" +) + +func TestAgentHelp(t *testing.T) { + t.Setenv("NO_COLOR", "1") + previous := color.NoColor + color.NoColor = true + t.Cleanup(func() { color.NoColor = previous }) + + var walk func(*cobra.Command, []string) + walk = func(command *cobra.Command, path []string) { + name := strings.Join(path, "_") + if name == "" { + name = "root" + } + t.Run(name, func(t *testing.T) { + root := NewRootCommand() + var buf bytes.Buffer + root.SetOut(&buf) + root.SetErr(&buf) + root.SetArgs(append(append([]string{}, path...), "--help")) + require.NoError(t, root.Execute()) + text := buf.String() + require.NotContains(t, text, "\x1b") + require.Contains(t, text, "\nUsage\n azd ai agent") + require.Contains(t, text, "\nGlobal Flags\n") + require.Contains(t, text, "\nExamples\n") + require.Equal(t, 1, strings.Count(text, "\nExamples\n")) + require.NotContains(t, text, "\nUsage:") + require.NotContains(t, text, "\nFlags:") + require.NotContains(t, text, "\nSubcommands:") + if len(path) == 0 { + require.Contains(t, text, "Environments & Environment Variables\n") + require.Contains(t, text, ".azure//.env") + require.Contains(t, text, "${FOUNDRY_PROJECT_ENDPOINT}") + require.Contains(t, text, "AGENT__NAME") + require.Contains(t, text, "AGENT__VERSION") + require.Contains(t, text, "AGENT__PROJECT_ENDPOINT") + } else { + require.NotContains(t, text, "Environments & Environment Variables") + require.NotContains(t, text, bannerArt) + } + command.Flags().VisitAll(func(flag *pflag.Flag) { + if !flag.Hidden && flag.Deprecated == "" { + require.Contains(t, text, "--"+flag.Name) + } + }) + // Ignore trailing terminal padding (including the banner), but keep + // indentation, internal whitespace and line breaks in snapshots. + lines := strings.Split(text, "\n") + for i, line := range lines { + lines[i] = strings.TrimRight(line, " \t\r") + } + snapshot.SnapshotT(t, strings.TrimRight(strings.Join(lines, "\n"), "\n")) + }) + for _, child := range command.Commands() { + if child.IsAvailableCommand() { + walk(child, append(append([]string{}, path...), child.Name())) + } + } + } + walk(NewRootCommand(), nil) +} + +func TestAgentHelpColor(t *testing.T) { + previous := color.NoColor + color.NoColor = false + t.Cleanup(func() { color.NoColor = previous }) + + for _, path := range [][]string{nil, {"init"}, {"invoke"}, {"files", "list"}, {"optimize"}, {"eval", "show"}} { + t.Run(strings.Join(path, "_"), func(t *testing.T) { + root := NewRootCommand() + var buf bytes.Buffer + root.SetOut(&buf) + root.SetErr(&buf) + root.SetArgs(append(append([]string{}, path...), "--help")) + require.NoError(t, root.Execute()) + text := buf.String() + require.Contains(t, text, output.WithBold("%s", output.WithUnderline("Usage"))) + require.Contains(t, text, output.WithBold("%s", output.WithUnderline("Examples"))) + require.Contains(t, text, output.WithHighLightFormat("%s", "--environment")) + require.Contains(t, text, "\x1b[94m") + if len(path) == 0 { + require.Contains(t, text, + output.WithBold("%s", output.WithUnderline("Environments & Environment Variables"))) + } + }) + } +} diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/init.go b/cli/azd/extensions/azure.ai.agents/internal/cmd/init.go index e1586a6a469..ed9f5aa487a 100644 --- a/cli/azd/extensions/azure.ai.agents/internal/cmd/init.go +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/init.go @@ -1251,6 +1251,7 @@ func newInitCommand(extCtx *azdext.ExtensionContext) *cobra.Command { Short: fmt.Sprintf("Initialize a new prompt, hosted, or voice agent project. %s", color.YellowString("(Preview)")), Long: `Initialize a new prompt, hosted, or voice agent project. +Manifests: When -m points at a sample's unified azure.yaml (a project manifest that declares services with host: azure.ai.project / azure.ai.agent / ...), that azure.yaml is adopted as the project manifest and its referenced files are @@ -1259,6 +1260,7 @@ project's azure.yaml is generated from it. An agent manifest that declares kind: prompt scaffolds a prompt agent (or a managed agent when it also declares a harness), carrying over its model, instructions, skills, and tools. +Voice Agents: Use --kind prompt-voice to initialize a managed prompt voice agent without source code or container scaffolding. The managed model defaults to gpt-realtime and does not require a model deployment. @@ -1283,6 +1285,7 @@ Configure advanced settings in azure.yaml. Run 'azd provision' and 'azd deploy' to deploy voice services, then connect to the voice WebSocket endpoint with a Voice Live client. +Agent Names: The agent name written to agent.yaml is the Foundry agent identity. Foundry agents are unique by name within a project, so deploying with an existing name creates a new version of that existing agent instead of a separate agent. @@ -1290,6 +1293,7 @@ creates a new version of that existing agent instead of a separate agent. Use --agent-name to choose a unique Foundry agent name when initializing from a reusable sample or manifest. +File Exclusions: A default .agentignore file is generated to control which files are excluded from code-deploy ZIP packaging (uses .gitignore syntax).`, Example: ` # Adopt a sample's unified azure.yaml as the project manifest diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/invocations.go b/cli/azd/extensions/azure.ai.agents/internal/cmd/invocations.go index 50db424f14c..c4abd2a5569 100644 --- a/cli/azd/extensions/azure.ai.agents/internal/cmd/invocations.go +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/invocations.go @@ -48,6 +48,8 @@ and service results depend on the protocol; unsupported operations are rejected. When --id is omitted, use the latest ID saved for the selected agent and protocol. Explicit IDs do not change the saved selection.`, + Example: ` # Show the current invocation result + azd ai agent invocations show`, } cmd.AddCommand(newInvocationsShowCommand(extCtx)) cmd.AddCommand(newInvocationsFollowCommand(extCtx)) diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/invoke.go b/cli/azd/extensions/azure.ai.agents/internal/cmd/invoke.go index b41f396a578..d02060aac68 100644 --- a/cli/azd/extensions/azure.ai.agents/internal/cmd/invoke.go +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/invoke.go @@ -93,6 +93,7 @@ func newInvokeCommand(extCtx *azdext.ExtensionContext) *cobra.Command { Short: "Send a message to your prompt or hosted agent.", Long: `Send a message to your prompt or hosted agent. +Invocation Target: By default the agent is invoked remotely on Foundry. When a single argument is provided it is treated as the message and the agent name is auto-detected from azure.yaml. With two arguments the first is the @@ -104,21 +105,25 @@ redeploying or bypassed with --protocol. Otherwise the agent definition is used. If neither identifies exactly one invocable protocol, pass --protocol explicitly. +Voice Agents: For prompt voice agents and hosted voice wrappers, open your agent in the Microsoft Foundry portal at https://ai.azure.com to try it. For programmatic voice access, use the voice WebSocket endpoint shown by 'azd show' or 'azd ai agent show' with a Voice Live client. Text invoke is for HTTP-based hosted agent protocols such as responses, invocations, and a2a. +Request Body: Use --input-file/-f to send the contents of a file as the request body instead of a positional message argument. This is useful for structured or large payloads with the invocations protocol, or for sending a complete JSON-RPC request with the a2a protocol. +Local Development: Use --local to target a locally running agent (started via 'azd ai agent run') instead of Foundry. The a2a protocol is remote-only and cannot be used with --local. +Sessions & Identity: Sessions are persisted per-agent — consecutive invokes reuse the same session automatically. Pass --new-session to force a reset. @@ -139,12 +144,14 @@ x-client-* header family to the agent; other header names are rejected, and the flag is not supported with the a2a protocol (which does not propagate x-client-* headers). For identity headers use --user-identity or --call-id. +Response Output: Use --output raw (or -o raw) to dump the unmodified server response (status line, headers, and body verbatim) to stdout. Useful for debugging server behavior and inspecting response headers (for example, the agent version header). Friendly summary lines like "Session:" and "Invocation:" are suppressed in raw mode. +Platform Latency: Remote Hosted Agent Responses and Invocations requests include platform latency diagnostics by default. A compact summary is shown after a successful invocation when the service returns timing headers. Use --debug-latency=false to disable collection @@ -154,6 +161,7 @@ Explicit --debug-latency=true is rejected for these routes; omit the flag or use --debug-latency=false. Raw output includes the returned headers without a formatted latency summary. +Long-running Invocations: Use --long-running with the Responses protocol to start work that continues running in the service if this command disconnects. The command remains attached until the work finishes. Add --no-wait to return after azd receives the Response ID. @@ -208,8 +216,8 @@ This option does not provide crash recovery or automatic reconnection.`, # Invoke a deployed agent from any directory using the endpoint URL shown by 'azd ai agent show' azd ai agent invoke \ - --agent-endpoint https://.services.ai.azure.com/api/projects//agents//endpoint/protocols/openai/responses?api-version=v1 \ - "Hello!"`, + --agent-endpoint https://.services.ai.azure.com/api/projects//agents//endpoint/protocols/openai/responses?api-version=v1 \ + "Hello!"`, Args: cobra.RangeArgs(0, 2), RunE: func(cmd *cobra.Command, args []string) error { ctx := azdext.WithAccessToken(cmd.Context()) diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/root.go b/cli/azd/extensions/azure.ai.agents/internal/cmd/root.go index 55d36c8ea89..9de99a60752 100644 --- a/cli/azd/extensions/azure.ai.agents/internal/cmd/root.go +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/root.go @@ -6,6 +6,8 @@ package cmd import ( "fmt" + "azureaiagent/internal/helpformat" + "github.com/azure/azure-dev/cli/azd/pkg/azdext" "github.com/fatih/color" "github.com/spf13/cobra" @@ -21,6 +23,12 @@ func NewRootCommand() *cobra.Command { ), }) rootCmd.SilenceUsage = true + rootCmd.Example = ` # Initialize and deploy an agent project + azd ai agent init + azd up + + # Send a message to a deployed prompt or hosted agent + azd ai agent invoke "Hello"` rootCmd.SilenceErrors = true rootCmd.CompletionOptions.DisableDefaultCmd = true telemetryReporter := newAgentContextReporter() @@ -93,5 +101,7 @@ func NewRootCommand() *cobra.Command { rootCmd.AddCommand(newEvalCommand(extCtx)) rootCmd.AddCommand(newOptimizeCommand(extCtx)) + helpformat.Install(rootCmd, "azd ai", agentHelpFooter) + return rootCmd } diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/sample.go b/cli/azd/extensions/azure.ai.agents/internal/cmd/sample.go index a7e2aeaeb61..f8d15534725 100644 --- a/cli/azd/extensions/azure.ai.agents/internal/cmd/sample.go +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/sample.go @@ -26,6 +26,8 @@ The catalog is the same source the interactive ` + "`azd ai agent init`" + ` pic Subcommands emit machine-readable JSON or human-readable text so coding agents and humans can both discover manifests and repos to feed back into ` + "`azd ai agent init -m `" + ` or ` + "`azd init -t `" + `.`, + Example: ` # Browse samples before initializing an agent + azd ai agent sample list`, } cmd.AddCommand(newSampleListCommand(extCtx)) diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/session.go b/cli/azd/extensions/azure.ai.agents/internal/cmd/session.go index 1da41a0c1c7..38617412dce 100644 --- a/cli/azd/extensions/azure.ai.agents/internal/cmd/session.go +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/session.go @@ -48,6 +48,8 @@ multiple azure.ai.agent services. For agents configured with header-based isolation, pass --user-identity on each session operation.`, + Example: ` # List sessions for the deployed hosted agent + azd ai agent sessions list`, } cmd.AddCommand(newSessionCreateCommand(extCtx)) diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-code.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-code.snap new file mode 100644 index 00000000000..12f2ea2908b --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-code.snap @@ -0,0 +1,21 @@ +Commands for managing the source code of code-based hosted agents. + +Usage + azd ai agent code [command] + +Available Commands + download : Download agent source code from Foundry. (Preview) + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for code + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (default "default") + +Examples + Download the deployed agent source code + azd ai agent code download + +Use azd ai agent code [command] --help to view examples and more information about a specific command. diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-code_download.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-code_download.snap new file mode 100644 index 00000000000..b0cf00e15bc --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-code_download.snap @@ -0,0 +1,36 @@ +Download the source code of a code-based hosted agent. + +Downloads the deployed source code as a zip archive and extracts it to +the output directory. Use --zip to save the raw zip file instead. + +The [service] argument identifies the azd service whose agent name is resolved +from the azd environment. When omitted, the default agent service is used. + +Usage + azd ai agent code download [service] [flags] + +Flags + -d, --dest string : Destination path (default: .// or ./.zip) + -v, --version string : Agent version to download (default: latest) + --zip : Save as zip file instead of extracting + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for download + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (default "default") + +Examples + Download latest version (extracts to ./my-agent/) + azd ai agent code download my-agent + + Download a specific version + azd ai agent code download my-agent --version 3 + + Save as zip file without extracting + azd ai agent code download my-agent --zip + + Download to a custom directory + azd ai agent code download my-agent --dest ./backup diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-connection.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-connection.snap new file mode 100644 index 00000000000..a6d97aed630 --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-connection.snap @@ -0,0 +1,21 @@ +Manage connection service dependencies for an agent. + +Usage + azd ai agent connection [command] + +Available Commands + add : Add a connection service dependency to an agent service. + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for connection + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (default "default") + +Examples + Attach an existing connection service to an agent + azd ai agent connection add --agent + +Use azd ai agent connection [command] --help to view examples and more information about a specific command. diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-connection_add.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-connection_add.snap new file mode 100644 index 00000000000..8d871983352 --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-connection_add.snap @@ -0,0 +1,23 @@ +Add a connection service dependency to an agent service. + +Both services must already be declared in azure.yaml. This adds a uses entry +to the agent service; it does not create the dependency resource. +Use --agent to identify the agent service to update. + +Usage + azd ai agent connection add [flags] + +Flags + --agent string : Agent service name in azure.yaml. + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for add + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (supported: json, table) (default "table") + +Examples + Attach an existing connection service to an agent + azd ai agent connection add --agent diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-delete.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-delete.snap new file mode 100644 index 00000000000..3cc41f2718c --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-delete.snap @@ -0,0 +1,43 @@ +Delete a prompt, hosted, or voice agent and all of its versions. + +For hosted agents, --version deletes only that version. Prompt agents do not +support version deletion and are always deleted as a whole. + +If the agent has active sessions, deletion will fail unless --force is passed. +Use --force to terminate active sessions and delete the agent. In no-prompt +mode, --force is also required as explicit consent for deletion. + +The agent name is resolved from the azd environment when omitted. + +For voice agents with telephony bindings, delete the bindings through the +agent-scoped telephony API before deleting the agent. Agent deletion does not +guarantee binding cleanup. Deleting a hosted voice wrapper does not delete its +hosted target. + +Usage + azd ai agent delete [name] [flags] + +Flags + --force : Force deletion even if the agent has active sessions; required as consent in no-prompt mode + --version string : Delete a specific version only (the agent itself remains) + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for delete + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (supported: json, none) (default "none") + +Examples + Delete agent (auto-resolves name from azure.yaml) + azd ai agent delete + + Delete a specific agent by name + azd ai agent delete my-agent + + Delete a specific hosted-agent version only + azd ai agent delete my-agent --version 2 + + Force-delete even if active sessions exist + azd ai agent delete my-agent --force diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-doctor.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-doctor.snap new file mode 100644 index 00000000000..87d50b4817c --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-doctor.snap @@ -0,0 +1,30 @@ +Diagnose problems with an azd ai agent project. + +Runs a sequence of local and remote checks against the current azd project, +reporting on each one and (when all checks pass) suggesting the next +command to run. Use this when you have lost terminal context or hit a +confusing error and want a complete picture of the project's state. + +Exit Codes + 0 — at least one check passed and no checks failed + 1 — any check failed + 2 — all checks were skipped (e.g. preconditions unmet) + +Usage + azd ai agent doctor [flags] + +Flags + --local-only : Skip remote (network-dependent) checks. Useful when offline, behind a proxy, or for a fast local triage. + --unredacted : Show raw principal IDs, scope ARNs, and UPNs in the report. + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for doctor + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (default "default") + +Examples + Run the full check suite + azd ai agent doctor diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-endpoint.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-endpoint.snap new file mode 100644 index 00000000000..6621170c945 --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-endpoint.snap @@ -0,0 +1,22 @@ +Manage agent endpoint and card configuration. + +Usage + azd ai agent endpoint [command] + +Available Commands + show : Show the current endpoint and card configuration of an agent. + update : Update an agent's endpoint and card configuration without deploying a new version. + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for endpoint + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (default "default") + +Examples + Inspect the deployed endpoint configuration + azd ai agent endpoint show + +Use azd ai agent endpoint [command] --help to view examples and more information about a specific command. diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-endpoint_show.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-endpoint_show.snap new file mode 100644 index 00000000000..5c29dc638da --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-endpoint_show.snap @@ -0,0 +1,25 @@ +Show the current endpoint and card configuration of an agent. + +Displays protocols, version selector (traffic split), authorization schemes, +and agent card (A2A discovery) as configured on the live agent. + +Usage + azd ai agent endpoint show [name] [flags] + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for show + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (supported: json, table) (default "table") + +Examples + Show endpoint config (auto-resolves from azure.yaml) + azd ai agent endpoint show + + Show for a specific agent service + azd ai agent endpoint show my-agent + + Output as JSON + azd ai agent endpoint show --output json diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-endpoint_update.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-endpoint_update.snap new file mode 100644 index 00000000000..c817b7f332b --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-endpoint_update.snap @@ -0,0 +1,28 @@ +Update an agent's endpoint and card configuration without deploying a new version. + +This command reads the agentEndpoint and agentCard fields from the azure.ai.agent +service in azure.yaml, or agent_endpoint and agent_card from a legacy agent.yaml, +and patches the existing agent with those values. No new agent version is created. + +The agent must already exist (i.e., it must have been previously deployed). + +Usage + azd ai agent endpoint update [name] [flags] + +Flags + --force : Skip confirmation prompts for breaking changes + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for update + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (default "default") + +Examples + Update endpoint/card for the default agent service + azd ai agent endpoint update + + Update a specific agent service + azd ai agent endpoint update my-agent diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-eval.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-eval.snap new file mode 100644 index 00000000000..ddada0cb4c0 --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-eval.snap @@ -0,0 +1,29 @@ +Create and run quick evals for an agent. + +Generate an eval config and dataset, run evaluations, and inspect the results. +Use 'azd ai agent eval update' to upload changes to local evaluators and datasets. + +Usage + azd ai agent eval [command] + +Available Commands + generate : Generate a local eval suite for a deployed agent. + list : List evaluations for the current project. + run : Execute an evaluation run from eval.yaml. + show : Show an eval definition, run history, or run details. + update : Update evaluators and datasets from local files. + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for eval + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (default "default") + +Examples + Generate an eval suite and run it + azd ai agent eval generate + azd ai agent eval run + +Use azd ai agent eval [command] --help to view examples and more information about a specific command. diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-eval_generate.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-eval_generate.snap new file mode 100644 index 00000000000..5c5268c0eaf --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-eval_generate.snap @@ -0,0 +1,37 @@ +Generate a local eval suite for a deployed agent. + +By default, this command submits dataset and evaluator generation jobs, waits for +completion, downloads review artifacts, and writes eval.yaml at +the agent project root. Use --no-wait to write pending operation IDs and return. + +Usage + azd ai agent eval generate [flags] + +Flags + --agent string : Agent service name from azure.yaml, or Foundry agent name outside a project + --dataset string : Existing local file or registered dataset name to use for evaluation (instead of generating a new dataset) + --eval-model string : Model used for evaluation and generation + --evaluator stringArray : Built-in or custom evaluator name + -g, --gen-instruction string : Agent instruction used for dataset and evaluator generation + --gen-instruction-file string : Path to a file containing the agent instruction + --max-samples int : Number of samples to generate (15-1000) (default 15) + --name string : Name for the eval suite + --no-wait : Submit generation jobs and return immediately + --out-file string : Eval config path (default "eval.yaml") + -p, --project-endpoint string : Microsoft Foundry project endpoint URL + --reset-defaults : Overwrite an existing eval config + --trace-days int : Include agent traces from the last N days for evaluator generation (0 = no traces) + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for generate + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (default "default") + +Examples + azd ai agent eval generate + azd ai agent eval generate --gen-instruction "This agent handles restaurant reservations." --eval-model gpt-4o --max-samples 50 + azd ai agent eval generate --gen-instruction-file ./instructions.md --eval-model gpt-4o + azd ai agent eval generate --dataset ./tests/golden.jsonl --evaluator builtin.intent_resolution diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-eval_list.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-eval_list.snap new file mode 100644 index 00000000000..78bbd47ac30 --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-eval_list.snap @@ -0,0 +1,20 @@ +List evaluations for the current project. + +Usage + azd ai agent eval list [flags] + +Flags + --limit int : Maximum number of evals to return (default 10) + -p, --project-endpoint string : Microsoft Foundry project endpoint URL + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for list + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (default "default") + +Examples + List the five most recent evaluations + azd ai agent eval list --limit 5 diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-eval_run.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-eval_run.snap new file mode 100644 index 00000000000..ac5f5ed7139 --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-eval_run.snap @@ -0,0 +1,26 @@ +Execute an evaluation run from eval.yaml. + +Usage + azd ai agent eval run [flags] + +Flags + --agent string : Agent service name from azure.yaml, or Foundry agent name outside a project + --config string : Local eval config YAML (default "eval.yaml") + --name string : Name for the eval run (defaults to eval config name) + --no-wait : Start the run and return immediately without waiting for results + -p, --project-endpoint string : Microsoft Foundry project endpoint URL + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for run + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (default "default") + +Examples + Run the evaluation configured in eval.yaml + azd ai agent eval run + + Start a run without waiting for results + azd ai agent eval run --no-wait diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-eval_show.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-eval_show.snap new file mode 100644 index 00000000000..0b5562431c1 --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-eval_show.snap @@ -0,0 +1,27 @@ +Show an eval definition, run history, or run details. + +If eval-id is omitted, the most recent eval from the current environment is used. + +Usage + azd ai agent eval show [eval-id] [flags] + +Flags + --eval-run-id string : Show details for a specific eval run + --limit int : Maximum number of runs to show (default 20) + -O, --out-file string : Export full run results to a JSON file + -p, --project-endpoint string : Microsoft Foundry project endpoint URL + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for show + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (default "default") + +Examples + Show the most recent evaluation in the current environment + azd ai agent eval show + + Show a specific evaluation + azd ai agent eval show diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-eval_update.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-eval_update.snap new file mode 100644 index 00000000000..8f63b03dfc3 --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-eval_update.snap @@ -0,0 +1,29 @@ +Reads the eval config and uploads new versions for: + - Evaluators with a local_uri (rubric dimensions file) + - Datasets with a local_uri (JSONL data directory) +The version fields in the config are updated after successful uploads. + +In interactive mode, you will be prompted for each asset type that has +local changes. Use --dataset-only or --evaluator-only to skip prompts. + +Usage + azd ai agent eval update [flags] + +Flags + --agent string : Agent service name from azure.yaml, or Foundry agent name outside a project + --config string : Local eval config YAML (default "eval.yaml") + --dataset-only : Only update the dataset + --evaluator-only : Only update evaluators + -p, --project-endpoint string : Microsoft Foundry project endpoint URL + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for update + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (default "default") + +Examples + Upload changes to the local dataset + azd ai agent eval update --dataset-only diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-files.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-files.snap new file mode 100644 index 00000000000..80ee1af9710 --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-files.snap @@ -0,0 +1,37 @@ +Manage files in a hosted agent session. + +Upload, download, list, and delete files in the session-scoped filesystem +of a hosted agent. This is useful for debugging, seeding data, and agent setup. + +Agent details (name, endpoint) are automatically resolved from the +azd environment. Use --agent-name to select a specific agent when the project +has multiple azure.ai.agent services. The session ID is automatically resolved +from the last invoke session, or can be overridden with --session-id. + +For agents configured with header-based isolation, pass --user-identity +on each file operation. + +Usage + azd ai agent files [command] + +Available Commands + delete : Delete a file or directory from a hosted agent session. + download : Download a file from a hosted agent session. + list : List files in a hosted agent session. + mkdir : Create a directory in a hosted agent session. + stat : Get file or directory metadata in a hosted agent session. + upload : Upload a file to a hosted agent session. + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for files + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (default "default") + +Examples + List files in the current hosted agent session + azd ai agent files list + +Use azd ai agent files [command] --help to view examples and more information about a specific command. diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-files_delete.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-files_delete.snap new file mode 100644 index 00000000000..d32a3069786 --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-files_delete.snap @@ -0,0 +1,37 @@ +Delete a file or directory from a hosted agent session. + +Deletes the specified file or directory from the session's filesystem. +Use --recursive to delete directories and their contents. + +Agent details are automatically resolved from the azd environment. + +Usage + azd ai agent files delete [file] [flags] + +Aliases + delete, remove, rm + +Flags + -n, --agent-name string : Agent name (matches azure.yaml service name; auto-detected when only one exists) + -f, --file string : Remote file or directory path to delete + --recursive : Recursively delete directories and their contents + -s, --session-id string : Session ID override (defaults to last invoke session) + --user-identity string : User identity header value (sent as x-agent-user-id for local invocations and x-ms-user-identity for remote requests) + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for delete + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (default "default") + +Examples + Delete a file (agent auto-detected) + azd ai agent files delete /data/old-file.csv + + Delete a directory recursively + azd ai agent files delete /data/temp --recursive + + Delete with flags + azd ai agent files delete --file /data/old-file.csv --session-id diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-files_download.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-files_download.snap new file mode 100644 index 00000000000..fe1544a3880 --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-files_download.snap @@ -0,0 +1,35 @@ +Download a file from a hosted agent session. + +Downloads a file from the specified remote path in the session's +filesystem and saves it locally. If --target-path is not provided, +the local path defaults to the basename of the remote file. + +Agent details are automatically resolved from the azd environment. + +Usage + azd ai agent files download [file] [flags] + +Flags + -n, --agent-name string : Agent name (matches azure.yaml service name; auto-detected when only one exists) + -f, --file string : Remote file path to download + -s, --session-id string : Session ID override (defaults to last invoke session) + -t, --target-path string : Local destination path (defaults to remote filename) + --user-identity string : User identity header value (sent as x-agent-user-id for local invocations and x-ms-user-identity for remote requests) + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for download + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (default "default") + +Examples + Download a file (local path defaults to remote filename) + azd ai agent files download /data/output.csv + + Download to a specific local path + azd ai agent files download /data/output.csv --target-path ./output.csv + + Download with flags + azd ai agent files download --file /data/output.csv --session-id diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-files_list.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-files_list.snap new file mode 100644 index 00000000000..99cab68070b --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-files_list.snap @@ -0,0 +1,38 @@ +List files in a hosted agent session. + +Lists files and directories at the specified path in the session's filesystem. +When no path is provided, lists the root directory. + +Agent details are automatically resolved from the azd environment. + +Usage + azd ai agent files list [remote-path] [flags] + +Aliases + list, ls + +Flags + -n, --agent-name string : Agent name (matches azure.yaml service name; auto-detected when only one exists) + -s, --session-id string : Session ID override (defaults to last invoke session) + --user-identity string : User identity header value (sent as x-agent-user-id for local invocations and x-ms-user-identity for remote requests) + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for list + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (supported: json, table) (default "json") + +Examples + List files in the root directory (agent auto-detected) + azd ai agent files list + + List files in a specific directory + azd ai agent files list /data + + List files in table format + azd ai agent files list /data --output table + + List with explicit session + azd ai agent files list --session-id diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-files_mkdir.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-files_mkdir.snap new file mode 100644 index 00000000000..7afadb265f3 --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-files_mkdir.snap @@ -0,0 +1,30 @@ +Create a directory in a hosted agent session. + +Creates the specified directory in the session's filesystem. +Parent directories are created as needed. + +Agent details are automatically resolved from the azd environment. + +Usage + azd ai agent files mkdir [dir] [flags] + +Flags + -n, --agent-name string : Agent name (matches azure.yaml service name; auto-detected when only one exists) + -d, --dir string : Remote directory path to create + -s, --session-id string : Session ID override (defaults to last invoke session) + --user-identity string : User identity header value (sent as x-agent-user-id for local invocations and x-ms-user-identity for remote requests) + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for mkdir + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (default "default") + +Examples + Create a directory (agent auto-detected) + azd ai agent files mkdir /data/output + + Create with flags + azd ai agent files mkdir --dir /data/output --session-id diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-files_stat.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-files_stat.snap new file mode 100644 index 00000000000..df0226d3319 --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-files_stat.snap @@ -0,0 +1,31 @@ +Get file or directory metadata in a hosted agent session. + +Returns metadata about the specified file or directory in the session's filesystem. + +Agent details are automatically resolved from the azd environment. + +Usage + azd ai agent files stat [flags] + +Flags + -n, --agent-name string : Agent name (matches azure.yaml service name; auto-detected when only one exists) + -s, --session-id string : Session ID override (defaults to last invoke session) + --user-identity string : User identity header value (sent as x-agent-user-id for local invocations and x-ms-user-identity for remote requests) + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for stat + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (supported: json, table) (default "json") + +Examples + Get metadata for a file + azd ai agent files stat /data/output.csv + + Get metadata in table format + azd ai agent files stat /data/output.csv --output table + + Get metadata with explicit session + azd ai agent files stat /data/output.csv --session-id diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-files_upload.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-files_upload.snap new file mode 100644 index 00000000000..0b613d361b4 --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-files_upload.snap @@ -0,0 +1,44 @@ +Upload a file to a hosted agent session. + +Reads a local file and uploads it to the specified remote path +in the session's filesystem. If --target-path is not provided, +the remote path defaults to the local filename. + +Positional arguments mirror 'azd ai agent invoke [agent] [message]'. With two +arguments the first is the agent name and the second is the file to upload. +With a single argument it is the agent name when --file/-f already supplies the +file, otherwise it is the file itself. The agent is auto-detected from +azure.yaml when not provided. + +Agent details are automatically resolved from the azd environment. + +Usage + azd ai agent files upload [agent] [file] [flags] + +Flags + -n, --agent-name string : Agent name (matches azure.yaml service name; auto-detected when only one exists) + -f, --file string : Local file path to upload + -s, --session-id string : Session ID override (defaults to last invoke session) + -t, --target-path string : Remote destination path (defaults to local filename) + --user-identity string : User identity header value (sent as x-agent-user-id for local invocations and x-ms-user-identity for remote requests) + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for upload + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (default "default") + +Examples + Upload a file (agent auto-detected, remote path defaults to filename) + azd ai agent files upload ./data/input.csv + + Upload a file to a specific agent + azd ai agent files upload my-agent ./data/input.csv + + Upload to a specific remote path + azd ai agent files upload ./input.csv --target-path /data/input.csv + + Upload using flags + azd ai agent files upload --file ./input.csv --agent-name my-agent diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-init.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-init.snap new file mode 100644 index 00000000000..c21b263488c --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-init.snap @@ -0,0 +1,121 @@ +Initialize a new prompt, hosted, or voice agent project. + +Manifests +When -m points at a sample's unified azure.yaml (a project manifest that +declares services with host: azure.ai.project / azure.ai.agent / ...), that +azure.yaml is adopted as the project manifest and its referenced files are +placed at the project root. When -m points at an agent manifest instead, the +project's azure.yaml is generated from it. An agent manifest that declares +kind: prompt scaffolds a prompt agent (or a managed agent when it also declares +a harness), carrying over its model, instructions, skills, and tools. + +Voice Agents +Use --kind prompt-voice to initialize a managed prompt voice agent without +source code or container scaffolding. +The managed model defaults to gpt-realtime and does not require a model deployment. +--voice sets the output voice only when creating a new prompt voice agent through +--kind prompt-voice or the interactive voice option. +Edit azure.yaml to customize existing voice settings. + +New prompt voice initialization does not use source directories or code/container +settings. Explicit --src (including a positional directory), --protocol, +--deploy-mode, --runtime, --entry-point, and --dep-resolution are rejected on +the voice path. Use --model for the managed voice model; --model-deployment and +prompt-only or registry options are not supported by this voice initialization. + +Prompt voice services support modelType: managed or self_deployed (bring your own model +deployment), audio input/output, structured inputs, tools, greeting, avatar, +handoff, and telephony bindings (acs or twilio). Hosted voice wrappers use +conversationEngine.type: hosted_agent and conversationEngine.name to reference +the hosted target service in azure.yaml. The old modelType: hosted_agent and +targetAgent settings are not supported; use conversationEngine instead. Initialize from a sample +azure.yaml containing both the hosted target and the voice wrapper. +Configure advanced settings in azure.yaml. +Run 'azd provision' and 'azd deploy' to deploy voice services, then connect to +the voice WebSocket endpoint with a Voice Live client. + +Agent Names +The agent name written to agent.yaml is the Foundry agent identity. Foundry +agents are unique by name within a project, so deploying with an existing name +creates a new version of that existing agent instead of a separate agent. + +Use --agent-name to choose a unique Foundry agent name when initializing from +a reusable sample or manifest. + +File Exclusions +A default .agentignore file is generated to control which files are excluded +from code-deploy ZIP packaging (uses .gitignore syntax). + +Usage + azd ai agent init [] [-m ] [--src ] [flags] + +Flags + --acr-connection string : Foundry Azure Container Registry connection name to use for an existing project; incompatible with code deploy, --image, and prompt-voice agents + --agent-name string : Foundry agent name to write to azure.yaml. Reusing a name creates a new version of the existing agent. + --dep-resolution string : Dependency resolution for code deploy: 'remote_build' or 'bundled'. Defaults to 'remote_build'. + --deploy-mode string : Deployment mode: 'container' (Docker image) or 'code' (ZIP upload). Defaults to 'code' for Python/.NET projects in --no-prompt. + --description string : Prompt-agent description to write to azure.yaml. Used as the agent's human-readable summary. + --entry-point string : Entry point file for code deploy (e.g., 'app.py', 'MyAgent.dll'). Required with --deploy-mode code --no-prompt. + --force : Overwrite existing agent definitions or an input manifest inside the generated src tree without prompting. Required together with --no-prompt when init would otherwise need overwrite confirmation. + --image string : Pre-built container image URL (e.g., 'myacr.azurecr.io/agent:v1'). When set without --manifest, skips template/language selection, code scaffolding, Dockerfile generation, and ACR setup, and requires --agent-name. Incompatible with --deploy-mode code. + --infra string[="bicep"] : Eject infrastructure-as-code from azure.yaml. Existing infrastructure is preserved and Foundry files are generated as a separate infra/foundry layer. A bare --infra ejects Bicep; --infra=terraform ejects Terraform and sets the Foundry layer provider to terraform; Bicep keeps the microsoft.foundry provider. --infra=bicep is explicit Bicep. When azure.yaml already declares a Foundry project service, runs as a standalone eject and skips the init prompts; otherwise init runs first and the eject follows it. + --instructions string : System instructions for a prompt agent, including one using --harness. Written to azure.yaml; not supported for hosted agents. + --kind string : Agent runtime to initialize: 'hosted' (bring your own code/container), 'prompt' (model + instructions; Foundry runs the agent), or 'prompt-voice' (a declarative voice agent; use --model for the speech-to-speech model and --voice for the output voice agent). When omitted, when --manifest is supplied, the manifest determines the runtime and --kind is ignored; otherwise the hosted runtime is used. With --no-prompt, 'prompt' requires --agent-name and either --model or --model-deployment (unless supplied by --manifest). + -m, --manifest string : Path or URI to an agent manifest (hosted or 'kind: prompt'), or to a sample's unified azure.yaml to adopt as the project manifest + --model string : For hosted and prompt agents, name of the AI model to deploy. Defaults to 'gpt-5.4-mini' during interactive model selection; required to deploy a new model with --no-prompt. If --model-deployment is also provided, --model-deployment takes precedence. For new managed prompt voice agents, selects the service-hosted model (default: gpt-realtime); no model deployment is created. + -d, --model-deployment string : Name of an existing model deployment to use from the Foundry project. Only used when paired with an existing Foundry project, either via --project-id or interactive prompts + -p, --project-id string : Existing Microsoft Foundry Project Id to initialize your azd environment with + --protocol strings : Protocols supported by the agent (responses, invocations, invocations_ws, activity). Can be specified multiple times. + --rai-policy string : Responsible AI policy for a prompt or managed agent: 'none' to inherit the account's default content filters, a policy name on the selected Foundry account, or a policy's full ARM resource ID. The policy must already exist; azd attaches it, it does not create it. When omitted, you are prompted to pick from the policies on the account; with --no-prompt no policy is attached. Ignored for hosted agents and when --manifest already declares policies. + --registry-connection string : Name or ID of an existing Foundry project connection used to pull a private pre-built container image. Requires a pre-built image and is incompatible with code deploy. + --runtime string : Runtime for code deploy (e.g., 'python_3_13', 'python_3_14', 'dotnet_10'). Required with --deploy-mode code --no-prompt. + -s, --src string : Directory to download the agent definition to (defaults to 'src/') + --voice string : Output voice for new prompt voice agents (--kind prompt-voice or the interactive voice option). Rejected for other init flows. For existing voice services, edit azure.yaml. Example: en-US-Ava:DragonHDLatestNeural. + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for init + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (default "default") + +Examples + Adopt a sample's unified azure.yaml as the project manifest + azd ai agent init -m ./azure.yaml + azd ai agent init -m https://github.com/Azure-Samples//blob/main/azure.yaml + + Initialize from an agent manifest + azd ai agent init -m ./agent.manifest.yaml + + Initialize from a manifest with a unique Foundry agent name + azd ai agent init -m ./agent.manifest.yaml --agent-name my-unique-agent + + Initialize from local agent code + azd ai agent init --src ./src/my-agent --agent-name my-unique-agent + + Initialize a managed prompt voice agent + azd ai agent init --kind prompt-voice --agent-name support-voice + + Initialize a prompt voice agent with an explicit realtime model and voice + azd ai agent init --kind prompt-voice --agent-name support-voice \ + --model gpt-realtime --voice en-US-Ava:DragonHDLatestNeural + + Non-interactive code deploy (CI/CD) + azd ai agent init --no-prompt --project-id "" \ + --deploy-mode code --runtime python_3_13 --entry-point app.py + + Non-interactive prompt agent against an existing Foundry project + azd ai agent init --no-prompt --kind prompt --agent-name my-agent \ + --project-id "" --model-deployment gpt-4.1-mini + + Non-interactive prompt agent from a prompt agent template + azd ai agent init --no-prompt -m ./agent.yaml --project-id "" + + Bring your own pre-built image (no template/language selection, Dockerfile, or ACR setup) + azd ai agent init --no-prompt --agent-name my-agent \ + --image myacr.azurecr.io/agents/my-agent:v1 + + Use an existing Foundry connection for a private pre-built image + azd ai agent init --no-prompt --agent-name my-agent --project-id "" \ + --image registry.example.com/agents/my-agent:v1 --registry-connection production-registry diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-invocations.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-invocations.snap new file mode 100644 index 00000000000..4e31a609ce2 --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-invocations.snap @@ -0,0 +1,30 @@ +Inspect and manage work created by 'azd ai agent invoke'. + +The protocol is inferred from the selected agent or --agent-endpoint. +Use --protocol when the agent supports multiple protocols. Available operations +and service results depend on the protocol; unsupported operations are rejected. + +When --id is omitted, use the latest ID saved for the selected agent and +protocol. Explicit IDs do not change the saved selection. + +Usage + azd ai agent invocations [command] + +Available Commands + cancel : Request cancellation of an invocation. + follow : Replay and follow invocation output. + show : Show the service result for an invocation. + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for invocations + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (default "default") + +Examples + Show the current invocation result + azd ai agent invocations show + +Use azd ai agent invocations [command] --help to view examples and more information about a specific command. diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-invocations_cancel.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-invocations_cancel.snap new file mode 100644 index 00000000000..85be9855bc0 --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-invocations_cancel.snap @@ -0,0 +1,26 @@ +Request cancellation of an invocation. + +Usage + azd ai agent invocations cancel [flags] + +Flags + --agent-endpoint string : Full protocol endpoint URL of a deployed agent + -n, --agent-name string : Agent name (matches azure.yaml service name; auto-detected when only one exists) + --id string : Service-assigned ID; defaults to the current ID for the agent and protocol + -p, --protocol string : Protocol to use: responses, invocations, or a2a (inferred from agent; operation support varies) + --user-identity string : User identity header value (sent as x-agent-user-id for local invocations and x-ms-user-identity for remote requests) + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for cancel + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (supported: default) (default "default") + +Examples + Use the current ID for the selected agent and protocol + azd ai agent invocations cancel + + Target a Responses resource explicitly + azd ai agent invocations cancel --protocol responses --id diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-invocations_follow.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-invocations_follow.snap new file mode 100644 index 00000000000..ab283436a0c --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-invocations_follow.snap @@ -0,0 +1,26 @@ +Replay and follow invocation output. + +Usage + azd ai agent invocations follow [flags] + +Flags + --agent-endpoint string : Full protocol endpoint URL of a deployed agent + -n, --agent-name string : Agent name (matches azure.yaml service name; auto-detected when only one exists) + --id string : Service-assigned ID; defaults to the current ID for the agent and protocol + -p, --protocol string : Protocol to use: responses, invocations, or a2a (inferred from agent; operation support varies) + --user-identity string : User identity header value (sent as x-agent-user-id for local invocations and x-ms-user-identity for remote requests) + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for follow + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (supported: default) (default "default") + +Examples + Use the current ID for the selected agent and protocol + azd ai agent invocations follow + + Target a Responses resource explicitly + azd ai agent invocations follow --protocol responses --id diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-invocations_show.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-invocations_show.snap new file mode 100644 index 00000000000..40619a83722 --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-invocations_show.snap @@ -0,0 +1,26 @@ +Show the service result for an invocation. + +Usage + azd ai agent invocations show [flags] + +Flags + --agent-endpoint string : Full protocol endpoint URL of a deployed agent + -n, --agent-name string : Agent name (matches azure.yaml service name; auto-detected when only one exists) + --id string : Service-assigned ID; defaults to the current ID for the agent and protocol + -p, --protocol string : Protocol to use: responses, invocations, or a2a (inferred from agent; operation support varies) + --user-identity string : User identity header value (sent as x-agent-user-id for local invocations and x-ms-user-identity for remote requests) + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for show + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (supported: json, table) (default "json") + +Examples + Use the current ID for the selected agent and protocol + azd ai agent invocations show + + Target a Responses resource explicitly + azd ai agent invocations show --protocol responses --id diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-invoke.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-invoke.snap new file mode 100644 index 00000000000..ec8ed9dbaa7 --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-invoke.snap @@ -0,0 +1,159 @@ +Send a message to your prompt or hosted agent. + +Invocation Target +By default the agent is invoked remotely on Foundry. When a single +argument is provided it is treated as the message and the agent name +is auto-detected from azure.yaml. With two arguments the first is the +agent name and the second is the message. + +When --protocol is omitted, complete deployed endpoint data is used when +available. Endpoint data created by an older extension must be refreshed by +redeploying or bypassed with --protocol. Otherwise the agent definition is +used. If neither identifies exactly one invocable protocol, pass --protocol +explicitly. + +Voice Agents +For prompt voice agents and hosted voice wrappers, open your agent in the +Microsoft Foundry portal at https://ai.azure.com to try it. +For programmatic voice access, use the voice WebSocket endpoint shown by 'azd show' or +'azd ai agent show' with a Voice Live client. Text invoke is for HTTP-based +hosted agent protocols such as responses, invocations, and a2a. + +Request Body +Use --input-file/-f to send the contents of a file as the request body +instead of a positional message argument. This is useful for structured +or large payloads with the invocations protocol, or for sending a complete +JSON-RPC request with the a2a protocol. + +Local Development +Use --local to target a locally running agent (started via 'azd ai agent run') +instead of Foundry. The a2a protocol is remote-only and cannot be used with +--local. + +Sessions & Identity +Sessions are persisted per-agent — consecutive invokes reuse the same +session automatically. Pass --new-session to force a reset. + +Use --version to invoke a specific deployed agent version. When provided, +azd creates or reuses a hosted agent session backed by that version. + +For agents configured with header-based isolation, pass --user-identity +on each invoke. Locally it is sent as the x-agent-user-id header; for +remote invokes it is sent as the x-ms-user-identity header. + +Use --call-id to send a call ID with a local invoke. It is sent as the +x-agent-foundry-call-id header and applies only to local invocations; it is +ignored for remote requests. + +Use --client-header to send custom x-client-* request headers in "Name: Value" +format (repeatable). The responses and invocations protocols forward the +x-client-* header family to the agent; other header names are rejected, and +the flag is not supported with the a2a protocol (which does not propagate +x-client-* headers). For identity headers use --user-identity or --call-id. + +Response Output +Use --output raw (or -o raw) to dump the unmodified server response (status +line, headers, and body verbatim) to stdout. Useful for debugging server +behavior and inspecting response headers (for example, the agent version +header). Friendly summary lines like "Session:" and "Invocation:" are +suppressed in raw mode. + +Platform Latency +Remote Hosted Agent Responses and Invocations requests include platform latency diagnostics +by default. A compact summary is shown after a successful invocation when the +service returns timing headers. Use --debug-latency=false to disable collection +and the summary. This is independent of the global --debug logging flag. +Local, prompt-agent, and a2a invokes do not collect platform latency. +Explicit --debug-latency=true is rejected for these routes; omit the flag +or use --debug-latency=false. +Raw output includes the returned headers without a formatted latency summary. + +Long-running Invocations +Use --long-running with the Responses protocol to start work that continues running in +the service if this command disconnects. The command remains attached until the work +finishes. Add --no-wait to return after azd receives the Response ID. +This option does not provide crash recovery or automatic reconnection. + +Usage + azd ai agent invoke [name] [message] [flags] + +Flags + --agent-endpoint string : Full endpoint URL of a deployed agent (run 'azd ai agent show' to see it). Invokes without requiring an azd project; protocol is derived from the URL. + --call-id string : Call ID header value (sent as x-agent-foundry-call-id for local invocations only; ignored for remote requests) + --client-header stringArray : Custom x-client-* request header in "Name: Value" format (repeatable). The responses and invocations protocols forward the x-client-* header family to the agent; other header names are rejected and the flag is not supported with a2a. + --conversation-id string : Explicit conversation ID override + --debug-latency : Collect and show platform latency for remote responses/invocations; use --debug-latency=false to disable (default true) + -f, --input-file string : Path to a file whose contents are sent as the request body + -l, --local : Invoke on localhost instead of Foundry + --long-running : Continue service-side execution after disconnection; remain attached unless --no-wait is specified + --new-conversation : Force a new conversation (discard saved one) + --new-session : Force a new session (discard saved one) + --no-wait : Return after receiving the service-assigned ID; requires --long-running + --port int : Local server port (default 8088) + -p, --protocol string : Protocol to use: responses, invocations, or a2a. Auto-detected from deployment data or the agent definition; pass --protocol when it cannot be determined. + -s, --session-id string : Explicit session ID override + -t, --timeout int : Request timeout in seconds (0 for no timeout) (default 1800) + --user-identity string : User identity header value (sent as x-agent-user-id for local invocations and x-ms-user-identity for remote requests) + --version string : Agent version to invoke (creates or reuses a session backed by that version) + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for invoke + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (supported: default, raw) (default "default") + +Examples + Invoke the remote agent on Foundry (auto-detects agent from azure.yaml) + azd ai agent invoke "Hello!" + + Invoke a specific remote agent by name + azd ai agent invoke my-agent "Hello!" + + Invoke using a specific protocol + azd ai agent invoke --protocol invocations "Hello!" + + Invoke a deployed agent over the a2a protocol + azd ai agent invoke --protocol a2a "Hello!" + + Invoke the a2a protocol with a complete JSON-RPC request from a file + azd ai agent invoke --protocol a2a -f a2a-request.json + + Invoke with a file as the request body + azd ai agent invoke -f request.json + + Invoke a named agent with a file body + azd ai agent invoke my-agent -f request.json + + Invoke locally (agent must be running via 'azd ai agent run') + azd ai agent invoke --local "Hello!" + + Invoke a specific agent locally (useful in multi-agent projects) + azd ai agent invoke my-agent --local "Hello!" + + Start background work and remain attached until it finishes + azd ai agent invoke --long-running "Run the long task" + + Start background work and return after its Response ID is received + azd ai agent invoke --long-running --no-wait "Run the long task" + + Start a new session (discard conversation history) + azd ai agent invoke --new-session "Hello!" + + Invoke a specific deployed agent version + azd ai agent invoke --version 3 "Hello!" + + Dump the raw server response (status line, headers, body) for debugging + azd ai agent invoke --output raw "Hello!" + + Disable platform latency diagnostics + azd ai agent invoke --debug-latency=false "Hello!" + + Send custom x-client-* headers (repeatable) + azd ai agent invoke --client-header "x-client-request-id: abc123" --client-header "x-client-tenant: contoso" "Hello!" + + Invoke a deployed agent from any directory using the endpoint URL shown by 'azd ai agent show' + azd ai agent invoke \ + --agent-endpoint https://.services.ai.azure.com/api/projects//agents//endpoint/protocols/openai/responses?api-version=v1 \ + "Hello!" diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-monitor.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-monitor.snap new file mode 100644 index 00000000000..3e50f055460 --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-monitor.snap @@ -0,0 +1,57 @@ +Monitor logs from a hosted agent. + +Streams console output (stdout/stderr) or system events from an agent session. +A session ID is required — it is auto-resolved from the last invocation, or you can +specify one explicitly with --session-id. +Use --follow to stream logs in real-time, or omit it to fetch recent logs and exit. +This is useful for troubleshooting agent issues or monitoring agent behavior. + +When run from an azd project, the agent name and version are resolved from the +azure.yaml service configuration and current azd environment. Optionally specify +the service name as a positional argument when multiple agent services exist. + +Outside an azd project, the positional value is treated as the hosted agent name. +The Foundry project endpoint is resolved from the global project context configured +by azd ai project set, or from FOUNDRY_PROJECT_ENDPOINT. + +For agents configured with header-based isolation, pass --user-identity +when streaming session logs. + +Usage + azd ai agent monitor [name] [flags] + +Flags + -f, --follow : Stream logs in real-time + --raw : Print the raw SSE stream without formatting + -s, --session-id string : Session ID to stream logs for + -l, --tail int : Number of trailing log lines to fetch (1-300) (default 50) + -t, --type string : Type of logs: 'console' (stdout/stderr) or 'system' (container events) (default "console") + --user-identity string : User identity header value (sent as x-agent-user-id for local invocations and x-ms-user-identity for remote requests) + --utc : Display timestamps in UTC instead of local time + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for monitor + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (default "default") + +Examples + Monitor session logs (auto-resolves session from last invocation) + azd ai agent monitor + + Monitor logs for a specific agent service + azd ai agent monitor my-agent + + Monitor a hosted agent outside an azd project + azd ai agent monitor my-agent --session-id + + Stream logs for a specific session + azd ai agent monitor --session-id + + Stream session logs in real-time + azd ai agent monitor --session-id --follow + + Fetch system event logs + azd ai agent monitor --type system diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-optimize.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-optimize.snap new file mode 100644 index 00000000000..351aa9018eb --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-optimize.snap @@ -0,0 +1,54 @@ +Evaluate and optimize AI agents — baseline scoring and iterative improvement. + +When run without a subcommand, submits an optimization job. +Use --config for a custom YAML spec, or just provide the agent name to use sensible defaults. + +Usage + azd ai agent optimize [agent-name] [flags] + azd ai agent optimize [command] + +Available Commands + apply : Apply optimized candidate configuration locally to your azd project. + cancel : Cancel a running optimization job. + deploy : Deploy a winning optimization candidate as a new agent version via the API. + list : List recent optimization runs. + status : Check the status of an optimization job. + +Flags + -a, --agent string : Agent service name from azure.yaml, or Foundry agent name outside a project + -c, --config string : Path to YAML config file (optional — values are prompted interactively if omitted) + -d, --dataset string : Existing local file or registered dataset name + --endpoint string : Optimization service endpoint (for local dev) + -m, --eval-model string : Model for evaluation (required) + --evaluator stringArray : Built-in or custom evaluator name (repeatable; required when not set in config) + --max-candidates int : Maximum number of optimization candidates to generate (must be >= 1; default: 5) + --no-wait : Submit job and return immediately without waiting for completion + --optimize-model string : Model for optimization reasoning (gpt-5 family recommended; required) + --poll-interval int : Polling interval in seconds (default 10) + -p, --project-endpoint string : Foundry project endpoint URL + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for optimize + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (default "default") + +Examples + Optimize (auto-detect agent from azd project) + azd ai agent optimize + + Optimize a specific agent + azd ai agent optimize my-agent + + Full control via config file + azd ai agent optimize --config spec.yaml + + Subcommands + azd ai agent optimize status --watch + azd ai agent optimize list + azd ai agent optimize cancel + azd ai agent optimize deploy --candidate + +Use azd ai agent optimize [command] --help to view examples and more information about a specific command. diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-optimize_apply.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-optimize_apply.snap new file mode 100644 index 00000000000..29f7347daaa --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-optimize_apply.snap @@ -0,0 +1,40 @@ +Download the optimized configuration and skill files from an optimization +candidate and write them into your local azd project under .agent_configs/. + +For managed prompt agents, this also updates the model and instructions +in the azure.yaml service definition, including the deprecated config section. +Candidates must contain a non-empty model and instructions. Function tools are +updated only when their names match existing function tools. Omitted fields, +including nested parameter fields, are preserved. Supplied arrays and explicit +null optional fields replace previous values. +Functions are saved in flat format. Other tools and tool order are preserved; +new tools are not added. Missing, null, or empty candidate tools leave tools +unchanged. Malformed candidate tools are rejected before writing configuration. +Optimized prompt-agent skills are not supported. +Referenced definitions ($ref) must be inlined or updated manually. +Prompt apply also requires AGENT_DEFINITION_PATH to be unset or empty and a +service name without dots. + +After applying, run 'azd deploy' to deploy the optimized agent version. + +Usage + azd ai agent optimize apply [flags] + +Flags + --agent string : Agent service name from azure.yaml (auto-detected if only one exists) + --candidate string : Candidate ID from optimization results (required) + --endpoint string : Optimization service endpoint (for local dev) + -p, --project-endpoint string : Foundry project endpoint URL + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for apply + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (default "default") + +Examples + Apply candidate config locally, then deploy + azd ai agent optimize apply --candidate candidate_abc123 + azd deploy diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-optimize_cancel.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-optimize_cancel.snap new file mode 100644 index 00000000000..ee241a43569 --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-optimize_cancel.snap @@ -0,0 +1,22 @@ +Cancel a running optimization or evaluation job by its operation ID. + +Only jobs in a non-terminal state (pending, running) can be cancelled. + +Usage + azd ai agent optimize cancel [flags] + +Flags + --endpoint string : Optimization service endpoint (for local dev) + -p, --project-endpoint string : Foundry project endpoint URL + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for cancel + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (default "default") + +Examples + Cancel a running job + azd ai agent optimize cancel opt_abc123 diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-optimize_deploy.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-optimize_deploy.snap new file mode 100644 index 00000000000..53652e759fd --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-optimize_deploy.snap @@ -0,0 +1,28 @@ +Deploy an optimization candidate directly via the Foundry agent API. + +This creates a new agent version with the optimized configuration applied. +Use 'optimize apply' instead if you want to localize the config into your azd project first. + +Usage + azd ai agent optimize deploy [agent-name] [flags] + +Flags + --agent string : Agent service name from azure.yaml, or Foundry agent name outside a project + --candidate string : Candidate ID from optimization results (required) + --endpoint string : Optimization service endpoint (for local dev) + -p, --project-endpoint string : Foundry project endpoint URL + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for deploy + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (default "default") + +Examples + Deploy candidate directly + azd ai agent optimize deploy --candidate candidate_abc123 --agent my-agent + + Deploy with explicit endpoint + azd ai agent optimize deploy --candidate candidate_abc123 --agent my-agent --project-endpoint https://... diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-optimize_list.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-optimize_list.snap new file mode 100644 index 00000000000..41b73bf1b31 --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-optimize_list.snap @@ -0,0 +1,30 @@ +List recent optimization and evaluation runs. + +Use --status to filter by job status and --limit to control page size. + +Usage + azd ai agent optimize list [flags] + +Flags + --endpoint string : Optimization service endpoint (for local dev) + --limit int : Maximum number of results (default 20) + -p, --project-endpoint string : Foundry project endpoint URL + --status string : Filter by status (pending/running/completed/failed/cancelled) + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for list + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (default "default") + +Examples + List all recent runs + azd ai agent optimize list + + List only completed runs + azd ai agent optimize list --status completed + + Show last 5 runs + azd ai agent optimize list --limit 5 diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-optimize_status.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-optimize_status.snap new file mode 100644 index 00000000000..421f3cac9a2 --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-optimize_status.snap @@ -0,0 +1,31 @@ +Check the status of an optimization job by its operation ID. + +If no operation ID is provided, uses the last optimization job from this project. +Use --watch to poll until the job completes. + +Usage + azd ai agent optimize status [operation-id] [flags] + +Flags + --endpoint string : Optimization service endpoint (for local dev) + --poll-interval int : Polling interval in seconds (default 10) + -p, --project-endpoint string : Foundry project endpoint URL + --watch : Poll until job completes + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for status + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (supported: json, table) (default "table") + +Examples + Check last job status (auto-resolved) + azd ai agent optimize status + + Check specific job status + azd ai agent optimize status opt_abc123 + + Watch until complete + azd ai agent optimize status opt_abc123 --watch diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-pack.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-pack.snap new file mode 100644 index 00000000000..0e95144938f --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-pack.snap @@ -0,0 +1,37 @@ +Build a Teams app package (appPackage.zip) for a deployed Activity (Teams) agent. + +The Microsoft 365 service assembles the package (manifest, icons, and a bot entry +bound to the agent's instance identity) from the agent and the Azure Bot created +during 'azd deploy'. The package is written next to the agent source (or to +--output-dir) so you can sideload it in Teams. + +This command requires the agent to have been deployed first ('azd deploy'). Unlike +the best-effort packaging done during deploy, any failure here (tenant policy, +permissions, service outage) is reported as a command failure. + +Usage + azd ai agent pack [name] [flags] + +Flags + --app-version string : Version stamped into the Teams app manifest. If specified, it overrides activity.publish.appVersion in azure.yaml; otherwise azd uses the azure.yaml value, and falls back to 1.0.0. + --display-name string : Display name for the Teams app. If specified, it overrides activity.publish.agentDisplayName in azure.yaml; otherwise azd uses the azure.yaml value, and falls back to the agent name. + --output-dir string : Directory to write appPackage.zip to (defaults to the agent source directory) + --scope string : Publish scope for the package (personal: per-user sideload (no admin approval required); shared: shareable link distribution (no tenant-admin approval required); tenant: organization-wide catalog (requires IT-admin approval)) + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for pack + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (default "default") + +Examples + Pack the agent resolved from azure.yaml (personal scope) + azd ai agent pack + + Pack a specific agent for shareable-link distribution + azd ai agent pack my-agent --scope shared + + Pack with a custom display name and output directory + azd ai agent pack --display-name "Contoso Helper" --output-dir ./dist diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-publish.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-publish.snap new file mode 100644 index 00000000000..de62dc1e1d4 --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-publish.snap @@ -0,0 +1,51 @@ +Publish a deployed Activity (Teams) agent as a Teams app. + +The Microsoft 365 service builds the Teams app package server-side (the same package +'azd ai agent pack' produces) and publishes it to the Microsoft 365 store under the +requested scope, then returns the published title id and Teams app id. + +Scopes + shared shareable-link distribution (no tenant-admin approval required) + tenant organization-wide catalog (requires IT-admin approval) + +If --scope is specified, it overrides activity.publish.publishScope in azure.yaml. +When omitted, azd uses the value from azure.yaml; if no value is configured, +Digital Workers default to tenant and simple activity agents default to shared. +Digital Worker publish supports tenant scope only (alias: org). + +personal is not supported here: per-user install is a Teams client action, not a +store publish. For local testing, run azd ai agent pack and sideload with +atk install --scope personal. + +This command requires the agent to have been deployed first ('azd deploy'). Any +failure (tenant policy, permissions, service outage) is reported as a command +failure rather than silently skipped. + +Usage + azd ai agent publish [name] [flags] + +Flags + --access-boundary stringArray : Digital Worker access boundary. Repeat to select multiple developer boundaries. + --app-version string : Version stamped into the Teams app manifest. If specified, it overrides activity.publish.appVersion in azure.yaml; otherwise azd uses the azure.yaml value, and falls back to 1.0.0. + --clear-access-boundaries : Clear all existing Digital Worker access boundaries. + --display-name string : Display name for the Teams app. If specified, it overrides activity.publish.agentDisplayName in azure.yaml; otherwise azd uses the azure.yaml value, and falls back to the agent name. + --optional-permission-scope stringArray : Digital Worker permission in = form. Repeat to select multiple scopes. + --scope string : Microsoft 365 publish scope (shared: shareable link distribution (no tenant-admin approval required); tenant: organization-wide catalog (requires IT-admin approval; alias: org); Digital Workers require tenant) + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for publish + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (supported: json, none) (default "none") + +Examples + Publish using the configured digital-worker scope (or shared for simple activity) + azd ai agent publish + + Explicitly override the configured scope for a specific agent + azd ai agent publish my-agent --scope tenant + + Publish organization-wide (requires IT-admin approval) + azd ai agent publish --scope tenant diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-root.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-root.snap new file mode 100644 index 00000000000..ec092365999 --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-root.snap @@ -0,0 +1,83 @@ + +███████╗ ██████╗ ██╗ ██╗███╗ ██╗██████╗ ██████╗ ██╗ ██╗ +██╔════╝██╔═══██╗██║ ██║████╗ ██║██╔══██╗██╔══██╗╚██╗ ██╔╝ +█████╗ ██║ ██║██║ ██║██╔██╗ ██║██║ ██║██████╔╝ ╚████╔╝ +██╔══╝ ██║ ██║██║ ██║██║╚██╗██║██║ ██║██╔══██╗ ╚██╔╝ +██║ ╚██████╔╝╚██████╔╝██║ ╚████║██████╔╝██║ ██║ ██║ +╚═╝ ╚═════╝ ╚═════╝ ╚═╝ ╚═══╝╚═════╝ ╚═╝ ╚═╝ ╚═╝ + +vdev +Visit the docs at https://aka.ms/azd-ai-agent-docs + +Ship prompt, hosted, and voice agents with Microsoft Foundry from your terminal. (Preview) + +Usage + azd ai agent [command] + +Available Commands + code : Manage agent source code. (Preview) + connection : Manage connection service dependencies for an agent. + delete : Delete a prompt, hosted, or voice agent. + doctor : Diagnose problems with an azd ai agent project. + endpoint : Manage agent endpoint and card configuration. + eval : Create and run quick evals for an agent. + files : Manage files in a hosted agent session. + init : Initialize a new prompt, hosted, or voice agent project. (Preview) + invocations : Inspect and manage work created by invoking an agent. + invoke : Send a message to your prompt or hosted agent. + monitor : Monitor logs from a hosted agent. + optimize : Evaluate and optimize AI agents. + pack : Build a ready-to-sideload Teams app package for an activity agent. + publish : Publish an activity agent as a Teams app to the Microsoft 365 store. + run : Run your agent locally for development. + sample : Browse the curated catalog of agent samples and azd templates. + sessions : Manage sessions for a hosted agent endpoint. + show : Show the status of a prompt, hosted, or voice agent. + toolbox : Manage toolbox service dependencies for an agent. + version : Prints the version of the application + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for agent + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (default "default") + +Examples + Initialize and deploy an agent project + azd ai agent init + azd up + + Send a message to a deployed prompt or hosted agent + azd ai agent invoke "Hello" + +Use azd ai agent [command] --help to view examples and more information about a specific command. + +Environments & Environment Variables + An azd environment is a named deployment configuration, such as dev or prod. + Its values are stored locally in .azure//.env. + Use 'azd env new ' to create one, 'azd env select ' to change the + default, or --environment (-e) to select one for a command. + + Use 'azd env set ' to save a value and 'azd env get-values' to + inspect the selected environment. Values can include secrets; do not share + the output or commit .azure to source control. + + FOUNDRY_PROJECT_ENDPOINT identifies the Foundry project. Init records it + when you select an existing project; generated azure.yaml files reference + it as ${FOUNDRY_PROJECT_ENDPOINT} to keep configuration portable. + Deploy records AGENT__NAME, AGENT__VERSION and + AGENT__PROJECT_ENDPOINT so commands can resolve deployed agents. + is the service name in uppercase with spaces and hyphens replaced + by underscores (for example, my-agent becomes MY_AGENT). + + For hosted agent runtime settings, use the service-level env mapping in + azure.yaml. Reference environment values with ${VARIABLE_NAME}; setting an + azd environment value alone does not forward every value to the agent. + Use 'azd ai agent run' for local development and 'azd deploy' to apply changes + to the deployed agent. + +Learn More + Agent documentation: https://aka.ms/azd-ai-agent-docs + Environment commands: 'azd env --help' diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-run.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-run.snap new file mode 100644 index 00000000000..74e3c06b0bd --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-run.snap @@ -0,0 +1,52 @@ +Run your agent locally for development. + +Detects the project type (Python, .NET, Node.js), installs dependencies, +and starts the agent server in the foreground. Press Ctrl+C to stop. + +Optionally specify the agent service name (from azure.yaml) as a +positional argument. When omitted, the single agent service is used. + +The startup command is read from the startupCommand property of the +agent service in azure.yaml. If not set, it is auto-detected from the +project type. Use --start-command to override both. + +By default, this also opens a local client after the agent starts listening: +Agent Inspector for responses/invocations agents, or the Microsoft 365 Agents +Playground for activity agents. Use --no-client to skip this. + +Usage + azd ai agent run [name] [flags] + +Flags + --channel string : Channel for the Microsoft 365 Agents Playground (activity-protocol agents only) (default "emulator") + --inspector-port int : Port the Agent Inspector UI listens on (default: 8087) + --no-client : Do not open the local client (Agent Inspector or Playground) + -p, --port int : Port to listen on (default 8088) + -c, --start-command string : Explicit startup command (overrides azure.yaml and auto-detection) + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for run + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (default "default") + +Examples + Start the agent in the current directory + azd ai agent run + + Start a specific agent by name + azd ai agent run my-agent + + Start on a custom port + azd ai agent run --port 9090 + + Start a second agent with its own Agent Inspector UI port + azd ai agent run --port 9091 --inspector-port 9002 + + Start without opening a local client + azd ai agent run --no-client + + Start with an explicit command + azd ai agent run --start-command "python app.py" diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-sample.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-sample.snap new file mode 100644 index 00000000000..41a7407e009 --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-sample.snap @@ -0,0 +1,26 @@ +Browse the curated catalog of agent samples and azd templates. + +The catalog is the same source the interactive `azd ai agent init` picker uses. +Subcommands emit machine-readable JSON or human-readable text so coding agents +and humans can both discover manifests and repos to feed back into +`azd ai agent init -m ` or `azd init -t `. + +Usage + azd ai agent sample [command] + +Available Commands + list : List available agent samples that can be used with `azd ai agent init -m`. + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for sample + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (default "default") + +Examples + Browse samples before initializing an agent + azd ai agent sample list + +Use azd ai agent sample [command] --help to view examples and more information about a specific command. diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-sample_list.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-sample_list.snap new file mode 100644 index 00000000000..af60834d8c4 --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-sample_list.snap @@ -0,0 +1,43 @@ +List available agent samples from the curated catalog. + +Each entry includes the manifest URL or repo URL that can be passed back into +`azd ai agent init -m ` (for agent manifests) or `azd init -t ` +(for full azd template repositories), and a ready-to-execute `initCommand` +string so coding agents don't have to compose flags. + +The catalog is fetched from the same source the interactive template picker uses. + +Usage + azd ai agent sample list [flags] + +Aliases + list, ls + +Flags + --featured-only : Only include samples tagged 'featured' (the curated starter list). + --language string : Filter by language token. Supported values: python, dotnetCsharp. + --type string : Filter by template type. Supported values: agent, azd, azure.yaml. + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for list + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (supported: json, text) (default "text") + +Examples + List all samples in the default text format + azd ai agent sample list + + List as JSON for programmatic consumption + azd ai agent sample list --output json + + Only Python samples + azd ai agent sample list --language python + + Only featured (curated) samples as JSON + azd ai agent sample list --featured-only --output json + + Only agent-manifest samples (ready for -m) + azd ai agent sample list --type agent diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-sessions.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-sessions.snap new file mode 100644 index 00000000000..f5a0d7999ff --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-sessions.snap @@ -0,0 +1,36 @@ +Manage sessions for a hosted agent endpoint. + +Create, show, stop, list, and delete hosted agent sessions. +Sessions provide persistent compute and filesystem state for +hosted agent invocations. + +Agent details are automatically resolved from the azd environment. +Use --agent-name to select a specific agent when the project has +multiple azure.ai.agent services. + +For agents configured with header-based isolation, pass --user-identity +on each session operation. + +Usage + azd ai agent sessions [command] + +Available Commands + create : Create a new session for a hosted agent. + delete : Delete a session. + list : List sessions for a hosted agent. + show : Show details of a session. + stop : Stop a running session. + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for sessions + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (default "default") + +Examples + List sessions for the deployed hosted agent + azd ai agent sessions list + +Use azd ai agent sessions [command] --help to view examples and more information about a specific command. diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-sessions_create.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-sessions_create.snap new file mode 100644 index 00000000000..e6b62e8356f --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-sessions_create.snap @@ -0,0 +1,44 @@ +Create a new session for a hosted agent endpoint. + +Provisions a session with a persistent filesystem. The session +is ready for invocations once the command completes. + +The agent name is auto-detected when only one azure.ai.agent service exists +in azure.yaml. The version defaults to the deployed agent version from the +azd environment (AGENT_{SERVICE}_VERSION) when omitted. + +Positional arguments can be used instead of flags: + azd ai agent sessions create [agent-name] [version] + +Usage + azd ai agent sessions create [agent-name] [version] [flags] + +Flags + -n, --agent-name string : Agent name (matches azure.yaml service name; auto-detected when only one exists) + --session-id string : Optional caller-provided session ID (auto-generated if omitted) + --user-identity string : User identity header value (sent as x-agent-user-id for local invocations and x-ms-user-identity for remote requests) + --version string : Agent version to back the session (auto-resolved from azd environment if omitted) + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for create + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (supported: json, table) (default "json") + +Examples + Create a session (auto-detect agent, latest version) + azd ai agent sessions create + + Create a session for a specific agent + azd ai agent sessions create my-agent + + Create a session backed by agent version 3 + azd ai agent sessions create my-agent 3 + + Create with flags + azd ai agent sessions create --agent-name my-agent --version 3 + + Create with a specific session ID + azd ai agent sessions create --session-id my-session diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-sessions_delete.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-sessions_delete.snap new file mode 100644 index 00000000000..fc9886d29a2 --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-sessions_delete.snap @@ -0,0 +1,23 @@ +Delete a hosted agent session synchronously. + +Terminates the hosted agent session and deletes the persistent filesystem +volume. Returns once cleanup is complete. + +Usage + azd ai agent sessions delete [flags] + +Flags + -n, --agent-name string : Agent name (matches azure.yaml service name; auto-detected when only one exists) + --user-identity string : User identity header value (sent as x-agent-user-id for local invocations and x-ms-user-identity for remote requests) + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for delete + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (default "default") + +Examples + Delete a session + azd ai agent sessions delete my-session diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-sessions_list.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-sessions_list.snap new file mode 100644 index 00000000000..49c37011b24 --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-sessions_list.snap @@ -0,0 +1,30 @@ +List sessions for a hosted agent endpoint. + +Returns a paged list of sessions with their status, version, and timestamps. + +Usage + azd ai agent sessions list [flags] + +Flags + -n, --agent-name string : Agent name (matches azure.yaml service name; auto-detected when only one exists) + --limit int32 : Maximum number of sessions to return + --pagination-token string : Continuation token from a previous list response + --user-identity string : User identity header value (sent as x-agent-user-id for local invocations and x-ms-user-identity for remote requests) + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for list + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (supported: json, table) (default "json") + +Examples + List all sessions + azd ai agent sessions list + + List with a page size limit + azd ai agent sessions list --limit 10 + + List in table format + azd ai agent sessions list --output table diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-sessions_show.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-sessions_show.snap new file mode 100644 index 00000000000..eb2f196cc0f --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-sessions_show.snap @@ -0,0 +1,26 @@ +Show details of a hosted agent session. + +Retrieves the current status, version indicator, and timestamps for the +specified session. + +Usage + azd ai agent sessions show [flags] + +Flags + -n, --agent-name string : Agent name (matches azure.yaml service name; auto-detected when only one exists) + --user-identity string : User identity header value (sent as x-agent-user-id for local invocations and x-ms-user-identity for remote requests) + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for show + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (supported: json, table) (default "json") + +Examples + Show session details + azd ai agent sessions show my-session + + Show in table format + azd ai agent sessions show my-session --output table diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-sessions_stop.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-sessions_stop.snap new file mode 100644 index 00000000000..d23fe084ee4 --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-sessions_stop.snap @@ -0,0 +1,25 @@ +Stop a running hosted agent session. + +Terminates the session's running compute while preserving its persistent +filesystem volume. Unlike 'delete', the session is retained and can be +resumed by a subsequent invocation. Returns once the session is stopped. +Stopping a session that is already stopped succeeds without error. + +Usage + azd ai agent sessions stop [flags] + +Flags + -n, --agent-name string : Agent name (matches azure.yaml service name; auto-detected when only one exists) + --user-identity string : User identity header value (sent as x-agent-user-id for local invocations and x-ms-user-identity for remote requests) + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for stop + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (default "default") + +Examples + Stop a session + azd ai agent sessions stop my-session diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-show.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-show.snap new file mode 100644 index 00000000000..d860ae60f07 --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-show.snap @@ -0,0 +1,26 @@ +Show the status of a prompt, hosted, or voice agent. + +The agent name and version are resolved automatically from the azure.yaml service +configuration and the current azd environment. Optionally specify the service name +(from azure.yaml) as a positional argument when multiple agent services exist. + +Usage + azd ai agent show [name] [flags] + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for show + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (supported: json, table) (default "table") + +Examples + Show status (auto-resolves from azure.yaml) + azd ai agent show + + Show status for a specific agent service + azd ai agent show my-agent + + Show status as JSON + azd ai agent show --output json diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-toolbox.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-toolbox.snap new file mode 100644 index 00000000000..559486d2fe1 --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-toolbox.snap @@ -0,0 +1,21 @@ +Manage toolbox service dependencies for an agent. + +Usage + azd ai agent toolbox [command] + +Available Commands + add : Add a toolbox service dependency to an agent service. + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for toolbox + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (default "default") + +Examples + Attach an existing toolbox service to an agent + azd ai agent toolbox add --agent + +Use azd ai agent toolbox [command] --help to view examples and more information about a specific command. diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-toolbox_add.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-toolbox_add.snap new file mode 100644 index 00000000000..be0fed30633 --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-toolbox_add.snap @@ -0,0 +1,23 @@ +Add a toolbox service dependency to an agent service. + +Both services must already be declared in azure.yaml. This adds a uses entry +to the agent service; it does not create the dependency resource. +Use --agent to identify the agent service to update. + +Usage + azd ai agent toolbox add [flags] + +Flags + --agent string : Agent service name in azure.yaml. + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for add + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (supported: json, table) (default "table") + +Examples + Attach an existing toolbox service to an agent + azd ai agent toolbox add --agent diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-version.snap b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-version.snap new file mode 100644 index 00000000000..95506a11bb1 --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/testdata/TestAgentHelp-version.snap @@ -0,0 +1,16 @@ +Prints the version of the application + +Usage + azd ai agent version [flags] + +Global Flags + -C, --cwd string : Sets the current working directory + --debug : Enables debug and diagnostics logging + -e, --environment string : The name of the environment to use + -h, --help : help for version + --no-prompt : Runs without prompts. Uses existing values; fails if any required value or decision cannot be resolved automatically. + -o, --output string : The output format (default "default") + +Examples + Show the installed agent extension version + azd ai agent version diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/update.go b/cli/azd/extensions/azure.ai.agents/internal/cmd/update.go index 46f35772e2e..f505042de9b 100644 --- a/cli/azd/extensions/azure.ai.agents/internal/cmd/update.go +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/update.go @@ -24,6 +24,8 @@ func newEndpointCommand(extCtx *azdext.ExtensionContext) *cobra.Command { cmd := &cobra.Command{ Use: "endpoint", Short: "Manage agent endpoint and card configuration.", + Example: ` # Inspect the deployed endpoint configuration + azd ai agent endpoint show`, } cmd.AddCommand(newEndpointShowCommand(extCtx)) diff --git a/cli/azd/extensions/azure.ai.agents/internal/cmd/version.go b/cli/azd/extensions/azure.ai.agents/internal/cmd/version.go index b0cc4888c51..25c40c12404 100644 --- a/cli/azd/extensions/azure.ai.agents/internal/cmd/version.go +++ b/cli/azd/extensions/azure.ai.agents/internal/cmd/version.go @@ -15,6 +15,8 @@ func newVersionCommand() *cobra.Command { return &cobra.Command{ Use: "version", Short: "Prints the version of the application", + Example: ` # Show the installed agent extension version + azd ai agent version`, Run: func(cmd *cobra.Command, args []string) { fmt.Printf("Version: %s\nCommit: %s\nBuild Date: %s\n", version.Version, version.Commit, version.BuildDate) }, diff --git a/cli/azd/extensions/azure.ai.agents/internal/helpformat/helpformat.go b/cli/azd/extensions/azure.ai.agents/internal/helpformat/helpformat.go new file mode 100644 index 00000000000..29cf433c0f3 --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/helpformat/helpformat.go @@ -0,0 +1,218 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +// Package helpformat applies core azd help conventions to the agent command tree. +package helpformat + +import ( + "fmt" + "regexp" + "strings" + "sync" + + "github.com/azure/azure-dev/cli/azd/pkg/output" + "github.com/spf13/cobra" + "github.com/spf13/pflag" +) + +const ( + prefixAnnotation = "agent-help.command-prefix" + footerAnnotation = "agent-help.footer" + + helpTemplate = `{{agentHelpDescription .}}{{.UsageString}}` + usageTemplate = `{{agentHelpHeading "Usage"}} +{{agentHelpUsage .}} +{{if .Aliases}} +{{agentHelpHeading "Aliases"}} + {{.NameAndAliases}} +{{end}}{{if .HasAvailableSubCommands}} +{{agentHelpHeading "Available Commands"}} +{{agentHelpCommands .}}{{end}}{{with agentHelpLocalFlags .}} +{{agentHelpHeading "Flags"}} +{{.}}{{end}}{{with agentHelpGlobalFlags .}} +{{agentHelpHeading "Global Flags"}} +{{.}}{{end}}{{with .Example}} +{{agentHelpHeading "Examples"}} +{{agentHelpExamples .}} +{{end}}{{if .HasAvailableSubCommands}} +Use {{agentHelpText (printf "%s [command] --help" (agentHelpPath .))}} ` + + `to view examples and more information about a specific command. +{{end}}{{with agentHelpFooter .}} +{{.}} +{{end}}` +) + +var ( + registerOnce sync.Once + // Match whole tokens without splitting quoted values or shell continuations. + tokenPattern = regexp.MustCompile( + "`azd[^`\\r\\n]+`|'azd[^'\\r\\n]+'|https?://[^\\s`'\"]+|" + + `--[a-z][a-z0-9-]*|\B-[A-Za-z]\b|<[A-Za-z][^<>\r\n]*>|\[[A-Za-z][^\[\]\r\n]*\]`, + ) + flagRowPattern = regexp.MustCompile(`^( +)((?:-[A-Za-z0-9], )?--\S.*?)( {2,})(\S.*)$`) + headingPattern = regexp.MustCompile(`^[A-Z][A-Za-z-]*(?: (?:[A-Z][A-Za-z-]*|&)){0,5}:$`) +) + +// Install configures inherited help templates without replacing the SDK's +// UsageFunc, which applies per-command flag defaults and allowed values. +// commandPrefix is the host namespace, for example "azd ai". +// footer is plain text displayed only on the root command. +func Install(root *cobra.Command, commandPrefix, footer string) { + registerOnce.Do(func() { + cobra.AddTemplateFuncs(map[string]any{ + "agentHelpHeading": heading, + "agentHelpText": styleCommandText, + "agentHelpPath": commandPath, + "agentHelpDescription": description, + "agentHelpUsage": usage, + "agentHelpCommands": commands, + "agentHelpLocalFlags": func(cmd *cobra.Command) string { return flags(cmd, false) }, + "agentHelpGlobalFlags": func(cmd *cobra.Command) string { return flags(cmd, true) }, + "agentHelpExamples": examples, + "agentHelpFooter": func(cmd *cobra.Command) string { + return sections(cmd.Annotations[footerAnnotation]) + }, + }) + }) + if root.Annotations == nil { + root.Annotations = map[string]string{} + } + root.Annotations[prefixAnnotation] = commandPrefix + root.Annotations[footerAnnotation] = footer + root.SetHelpTemplate(helpTemplate) + root.SetUsageTemplate(usageTemplate) +} + +func heading(title string) string { + return output.WithBold("%s", output.WithUnderline("%s", title)) +} + +func commandPath(cmd *cobra.Command) string { + prefix := cmd.Root().Annotations[prefixAnnotation] + return strings.TrimSpace(prefix + " " + cmd.CommandPath()) +} + +func description(cmd *cobra.Command) string { + text := cmd.Long + if text == "" { + text = cmd.Short + } + return sections(strings.TrimSpace(text)) + "\n\n" +} + +func usage(cmd *cobra.Command) string { + var lines []string + if cmd.Runnable() { + line := commandPath(cmd) + strings.TrimPrefix(cmd.UseLine(), cmd.CommandPath()) + lines = append(lines, " "+styleCommandText(line)) + } + if cmd.HasAvailableSubCommands() { + lines = append(lines, " "+styleCommandText(commandPath(cmd)+" [command]")) + } + return strings.Join(lines, "\n") +} + +func commands(cmd *cobra.Command) string { + width := 0 + for _, child := range cmd.Commands() { + if child.IsAvailableCommand() { + width = max(width, len(child.Name())) + } + } + var b strings.Builder + for _, child := range cmd.Commands() { + if child.IsAvailableCommand() { + fmt.Fprintf(&b, " %s%s : %s\n", + output.WithHighLightFormat("%s", child.Name()), + strings.Repeat(" ", width-len(child.Name())), styleText(child.Short)) + } + } + return b.String() +} + +func flags(cmd *cobra.Command, global bool) string { + selected := pflag.NewFlagSet("", pflag.ContinueOnError) + if global { + selected.AddFlagSet(cmd.InheritedFlags()) + } + cmd.LocalFlags().VisitAll(func(flag *pflag.Flag) { + // Persistent root flags are local to Cobra but global to azd users. + isGlobal := flag.Name == "help" || flag.Name == "docs" || + cmd.PersistentFlags().Lookup(flag.Name) != nil + if isGlobal == global { + selected.AddFlag(flag) + } + }) + // Let pflag retain value types, optional values, defaults and multiline + // descriptions. Compute alignment before adding color escapes. + lines := strings.Split(strings.TrimSuffix(selected.FlagUsages(), "\n"), "\n") + width := 0 + for _, line := range lines { + if parts := flagRowPattern.FindStringSubmatch(line); parts != nil { + width = max(width, len(parts[1])+len(parts[2])) + } + } + for i, line := range lines { + if parts := flagRowPattern.FindStringSubmatch(line); parts != nil { + padding := strings.Repeat(" ", width-len(parts[1])-len(parts[2])) + lines[i] = parts[1] + styleText(parts[2]) + padding + " : " + styleText(parts[4]) + } else { + lines[i] = styleText(line) + } + } + text := strings.Join(lines, "\n") + if text == "" { + return "" + } + return text + "\n" +} + +func examples(text string) string { + lines := strings.Split(strings.TrimSpace(text), "\n") + for i, line := range lines { + trimmed := strings.TrimSpace(line) + switch { + case trimmed == "": + lines[i] = "" + case strings.HasPrefix(trimmed, "# "): + lines[i] = " " + styleText(strings.TrimPrefix(trimmed, "# ")) + default: + // Keep indentation, quotes and newlines intact for copy/paste. + lines[i] = " " + styleCommandText(line) + if i == 0 { + lines[i] = " " + styleCommandText(line) + } + } + } + return strings.Join(lines, "\n") +} + +// sections recognizes standalone title lines, not prose introducing a list. +func sections(text string) string { + lines := strings.Split(text, "\n") + for i, line := range lines { + if (i == 0 || lines[i-1] == "") && headingPattern.MatchString(line) { + lines[i] = heading(strings.TrimSuffix(line, ":")) + } else { + lines[i] = styleText(line) + } + } + return strings.Join(lines, "\n") +} + +func styleCommandText(text string) string { + return output.WithHighLightFormat("%s", styleText(text)) +} + +func styleText(text string) string { + return tokenPattern.ReplaceAllStringFunc(text, func(token string) string { + switch { + case strings.HasPrefix(token, "https://"), strings.HasPrefix(token, "http://"): + return output.WithLinkFormat("%s", token) + case strings.HasPrefix(token, "<"), strings.HasPrefix(token, "["): + return output.WithWarningFormat("%s", token) + default: + return output.WithHighLightFormat("%s", token) + } + }) +} diff --git a/cli/azd/extensions/azure.ai.agents/internal/helpformat/helpformat_test.go b/cli/azd/extensions/azure.ai.agents/internal/helpformat/helpformat_test.go new file mode 100644 index 00000000000..c07971b8d4b --- /dev/null +++ b/cli/azd/extensions/azure.ai.agents/internal/helpformat/helpformat_test.go @@ -0,0 +1,155 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + +package helpformat + +import ( + "bytes" + "testing" + + "github.com/azure/azure-dev/cli/azd/pkg/azdext" + "github.com/azure/azure-dev/cli/azd/pkg/output" + "github.com/fatih/color" + "github.com/spf13/cobra" + "github.com/stretchr/testify/require" +) + +func setColor(t *testing.T, enabled bool) { + t.Helper() + previous := color.NoColor + color.NoColor = !enabled + t.Cleanup(func() { color.NoColor = previous }) +} + +func renderHelp(t *testing.T, cmd *cobra.Command) string { + t.Helper() + var buf bytes.Buffer + cmd.SetOut(&buf) + cmd.SetErr(&buf) + cmd.InitDefaultHelpFlag() + require.NoError(t, cmd.Help()) + return buf.String() +} + +func TestHelpPreservesSDKFlagOptions(t *testing.T) { + setColor(t, false) + root, _ := azdext.NewExtensionRootCommand(azdext.ExtensionCommandOptions{Name: "agent"}) + child := &cobra.Command{Use: "show [name]", Run: func(*cobra.Command, []string) {}} + root.AddCommand(child) + child.Flags().String("label", "50% ready", "The `label` to use") + child.Flags().String("infra", "", "Infrastructure provider") + child.Flags().Lookup("infra").NoOptDefVal = "bicep" + child.Flags().Bool("hidden", false, "Hidden flag") + require.NoError(t, child.Flags().MarkHidden("hidden")) + azdext.RegisterFlagOptions(child, azdext.FlagOptions{ + Name: "output", Default: "json", AllowedValues: []string{"json", "table"}, + }) + Install(root, "azd ai", "") + + text := renderHelp(t, child) + require.Contains(t, text, "azd ai agent show [name] [flags]") + require.Contains(t, text, `--label label`) + require.Contains(t, text, `(default "50% ready")`) + require.Contains(t, text, `--infra string[="bicep"]`) + require.Contains(t, text, "supported: json, table") + require.Contains(t, text, `(default "json")`) + require.NotContains(t, text, "--hidden") + require.NotContains(t, text, "\x1b") + require.Equal(t, "default", root.PersistentFlags().Lookup("output").DefValue) + require.NotContains(t, renderHelp(t, root), "supported: json, table") +} + +func TestHelpTemplatesReadLiveState(t *testing.T) { + setColor(t, false) + root := &cobra.Command{Use: "agent [options]", Short: "Agent commands"} + Install(root, "azd ai", "More Information:\n ${VARIABLE} and ${{ secrets.VALUE }}") + child := &cobra.Command{ + Use: "optimize [name]", Aliases: []string{"opt"}, Run: func(*cobra.Command, []string) {}, + Long: "Optimize an agent.\n\nReads the config and uploads new versions for:\n - Datasets", + } + child.AddCommand(&cobra.Command{Use: "status", Short: "Show status", Run: func(*cobra.Command, []string) {}}) + root.AddCommand(child, &cobra.Command{Use: "hidden", Hidden: true, Run: func(*cobra.Command, []string) {}}) + root.PersistentFlags().StringP("environment", "e", "", "The environment") + + text := renderHelp(t, root) + require.Contains(t, text, "Usage\n azd ai agent [command]\n") + require.NotContains(t, text, "[options]") + require.NotContains(t, text, "\nFlags\n") + require.Contains(t, text, "\nGlobal Flags\n") + require.Contains(t, text, "--environment") + require.Contains(t, text, "${VARIABLE} and ${{ secrets.VALUE }}") + require.NotContains(t, text, "hidden") + childHelp := renderHelp(t, child) + require.Contains(t, childHelp, "azd ai agent optimize [name] [flags]\n azd ai agent optimize [command]") + require.Contains(t, childHelp, "Aliases\n optimize, opt") + require.Contains(t, childHelp, "Reads the config and uploads new versions for:") + require.NotContains(t, childHelp, "More Information") + require.NotContains(t, childHelp, "\nFlags\n") +} + +func TestHelpColorAtRenderTime(t *testing.T) { + setColor(t, false) + root := &cobra.Command{Use: "agent", Short: "Agent commands"} + child := &cobra.Command{Use: "show ", Run: func(*cobra.Command, []string) {}} + root.AddCommand(child) + child.Flags().String("name", "", "The name") + Install(root, "azd ai", "") + require.NotContains(t, renderHelp(t, child), "\x1b") + + color.NoColor = false + text := renderHelp(t, child) + require.Contains(t, text, heading("Usage")) + require.Contains(t, text, output.WithHighLightFormat("%s", "--name")) + require.Contains(t, text, output.WithWarningFormat("%s", "")) + require.Contains(t, renderHelp(t, root), output.WithHighLightFormat("%s", "show")) + + color.NoColor = true + require.NotContains(t, renderHelp(t, child), "\x1b") +} + +func TestExamplesPreserveShellText(t *testing.T) { + setColor(t, false) + for _, tt := range []struct { + name string + raw string + want string + }{ + { + name: "captions and separate commands", + raw: " # Apply and deploy\n azd ai agent optimize apply --candidate \n azd deploy", + want: " Apply and deploy\n azd ai agent optimize apply --candidate \n azd deploy", + }, + { + name: "no captions", + raw: " azd ai agent eval generate\n azd ai agent eval run", + want: " azd ai agent eval generate\n azd ai agent eval run", + }, + { + name: "multiline quoting and templates", + raw: " # Initialize\n azd ai agent init \\\n --instructions \"Keep two spaces: ${{ secrets.VALUE }}\"", + want: " Initialize\n azd ai agent init \\\n --instructions \"Keep two spaces: ${{ secrets.VALUE }}\"", + }, + { + name: "repeated captions", + raw: " # Show\n azd ai agent show\n\n # Show\n azd ai agent show other", + want: " Show\n azd ai agent show\n\n Show\n azd ai agent show other", + }, + } { + t.Run(tt.name, func(t *testing.T) { + require.Equal(t, tt.want, examples(tt.raw)) + }) + } +} + +func TestSectionsAndInlineTokens(t *testing.T) { + setColor(t, true) + text := sections("Voice Agents:\nUse --voice with 'azd ai agent init'.\n\n" + + "Long-running Invocations:\nSee https://example.com and .\n\n" + + "Reads the config and uploads new versions for:\n - Datasets") + require.Contains(t, text, heading("Voice Agents")) + require.Contains(t, text, heading("Long-running Invocations")) + require.Contains(t, text, output.WithHighLightFormat("%s", "--voice")) + require.Contains(t, text, output.WithHighLightFormat("%s", "'azd ai agent init'")) + require.Contains(t, text, output.WithLinkFormat("%s", "https://example.com")) + require.Contains(t, text, "Reads the config and uploads new versions for:") +} diff --git a/cli/azd/extensions/azure.ai.agents/tests/cli-interactive-tester-scenarios/tier0/0.02-help-root.yaml b/cli/azd/extensions/azure.ai.agents/tests/cli-interactive-tester-scenarios/tier0/0.02-help-root.yaml index 2ea5aae8eaa..2ec4ad282cd 100644 --- a/cli/azd/extensions/azure.ai.agents/tests/cli-interactive-tester-scenarios/tier0/0.02-help-root.yaml +++ b/cli/azd/extensions/azure.ai.agents/tests/cli-interactive-tester-scenarios/tier0/0.02-help-root.yaml @@ -5,9 +5,11 @@ cwd: "/tmp" tags: ["tier:0", "cmd:help", "parallel-safe"] goals: - - "Wait for the help output to render (it includes an ASCII-art banner and a 'Usage:' section)." + - "Wait for the help output to render (it includes an ASCII-art banner and a 'Usage' section)." - "Confirm the 'Available Commands' list includes: code, delete, doctor, endpoint, eval, files, init, invocations, invoke, monitor, optimize, pack, publish, run, sample, sessions, show, version." - "Confirm the global flags are listed: --cwd/-C, --debug, --environment/-e, --no-prompt, --output/-o." + - "Confirm the Environments & Environment Variables section explains .azure//.env, azd env new/select/set/get-values, FOUNDRY_PROJECT_ENDPOINT, AGENT_ deployment values, and the service-level env mapping for runtime settings." + - "Compare root, init, and files list help: headings should be consistently bold and underlined, command examples and flags highlighted, and usage paths start with azd ai agent. With NO_COLOR=1, the same content must remain readable without escape sequences." - "Confirm the root description mentions hosted and voice agents, and the init, show, and delete command summaries mention voice agents." - "Run 'azd ai agent init --help'; confirm --kind and --voice are visible, --kind prompt-voice is demonstrated, and voice settings are described in azure.yaml with azd provision and azd deploy as the deployment workflow." - "Confirm init help states --voice is rejected for other init flows and directs existing voice settings to azure.yaml; voice deployment uses azd provision and azd deploy."