Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion cli/azd/cmd/middleware/extensions.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,13 @@ func (m *ExtensionsMiddleware) Run(ctx context.Context, next NextFn) (*actions.A
allEnv = append(allEnv, "FORCE_COLOR=1")
}

args := []string{"listen"}
if debugEnabled, _ := m.options.Flags.GetBool("debug"); debugEnabled {
Comment thread
JeffreyCA marked this conversation as resolved.
args = append(args, "--debug")
}

options := &extensions.InvokeOptions{
Args: []string{"listen"},
Args: args,
Env: allEnv,
StdIn: ext.StdIn(),
StdOut: ext.StdOut(),
Expand Down
29 changes: 29 additions & 0 deletions cli/azd/extensions/azure.ai.agents/internal/cmd/listen.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,19 @@ import (
"fmt"
"os"
"path/filepath"
"strconv"
"strings"
"time"

"azureaiagent/internal/pkg/agents/agent_yaml"
"azureaiagent/internal/pkg/azure"
"azureaiagent/internal/project"

azcorelog "github.com/Azure/azure-sdk-for-go/sdk/azcore/log"
"github.com/azure/azure-dev/cli/azd/pkg/azdext"
"github.com/braydonk/yaml"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"google.golang.org/protobuf/types/known/structpb"
)

Expand All @@ -29,6 +34,20 @@ func newListenCommand() *cobra.Command {
// Create a new context that includes the AZD access token.
ctx := azdext.WithAccessToken(cmd.Context())

if isDebug(cmd.Flags()) {
currentDate := time.Now().Format("2006-01-02")
logFileName := fmt.Sprintf("azd-ai-agents-%s.log", currentDate)

logFile, err := os.OpenFile(logFileName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644)
if err != nil {
logFile = os.Stderr
}
azcorelog.SetListener(func(event azcorelog.Event, msg string) {
msg = azure.ConnectionStringJSONRegex.ReplaceAllString(msg, `${1}"REDACTED"`)
fmt.Fprintf(logFile, "[%s] %s: %s\n", time.Now().Format(time.RFC3339), event, msg)
})
}

// Create a new AZD client.
azdClient, err := azdext.NewAzdClient()
if err != nil {
Expand Down Expand Up @@ -315,3 +334,13 @@ func populateContainerSettings(ctx context.Context, azdClient *azdext.AzdClient,

return nil
}

// isDebug checks if debug mode is enabled via --debug flag or AZD_EXT_DEBUG environment variable
func isDebug(flags *pflag.FlagSet) bool {
if debugFlag, err := flags.GetBool("debug"); err == nil && debugFlag {
return true
}

debug, _ := strconv.ParseBool(os.Getenv("AZD_EXT_DEBUG"))
return debug
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"io"
"net/http"
"net/url"
"os"
"strconv"

"azureaiagent/internal/version"
Expand All @@ -34,6 +33,9 @@ func NewAgentClient(endpoint string, cred azcore.TokenCredential) *AgentClient {
userAgent := fmt.Sprintf("azd-ext-azure-ai-agents/%s", version.Version)

clientOptions := &policy.ClientOptions{
Logging: policy.LogOptions{
IncludeBody: true,
},
PerCallPolicies: []policy.Policy{
runtime.NewBearerTokenPolicy(cred, []string{"https://ai.azure.com/.default"}, nil),
azsdk.NewMsCorrelationPolicy(),
Expand Down Expand Up @@ -104,8 +106,6 @@ func (c *AgentClient) CreateAgent(ctx context.Context, request *CreateAgentReque
return nil, fmt.Errorf("failed to set request body: %w", err)
}

c.logRequest("POST", url, payload)

resp, err := c.pipeline.Do(req)
if err != nil {
return nil, fmt.Errorf("HTTP request failed: %w", err)
Expand All @@ -126,7 +126,6 @@ func (c *AgentClient) CreateAgent(ctx context.Context, request *CreateAgentReque
return nil, fmt.Errorf("failed to parse response: %w", err)
}

c.logResponse(body)
return &agent, nil
}

Expand All @@ -148,8 +147,6 @@ func (c *AgentClient) UpdateAgent(ctx context.Context, agentName string, request
return nil, fmt.Errorf("failed to set request body: %w", err)
}

c.logRequest("POST", url, payload)

resp, err := c.pipeline.Do(req)
if err != nil {
return nil, fmt.Errorf("HTTP request failed: %w", err)
Expand All @@ -170,7 +167,6 @@ func (c *AgentClient) UpdateAgent(ctx context.Context, agentName string, request
return nil, fmt.Errorf("failed to parse response: %w", err)
}

c.logResponse(body)
return &agent, nil
}

Expand Down Expand Up @@ -284,8 +280,6 @@ func (c *AgentClient) CreateAgentVersion(ctx context.Context, agentName string,
return nil, fmt.Errorf("failed to set request body: %w", err)
}

c.logRequest("POST", url, payload)

resp, err := c.pipeline.Do(req)
if err != nil {
return nil, fmt.Errorf("HTTP request failed: %w", err)
Expand All @@ -306,7 +300,6 @@ func (c *AgentClient) CreateAgentVersion(ctx context.Context, agentName string,
return nil, fmt.Errorf("failed to parse response: %w", err)
}

c.logResponse(body)
return &agentVersion, nil
}

Expand Down Expand Up @@ -579,8 +572,6 @@ func (c *AgentClient) StartAgentContainer(ctx context.Context, agentName, agentV
return nil, fmt.Errorf("failed to set request body: %w", err)
}

c.logRequest("POST", url, payload)

resp, err := c.pipeline.Do(req)
if err != nil {
return nil, fmt.Errorf("HTTP request failed: %w", err)
Expand All @@ -606,7 +597,6 @@ func (c *AgentClient) StartAgentContainer(ctx context.Context, agentName, agentV
Body: operation,
}

c.logResponse(body)
return result, nil
}

Expand Down Expand Up @@ -809,31 +799,3 @@ func (c *AgentClient) GetAgentContainerOperation(ctx context.Context, agentName,

return &operation, nil
}

// Helper methods

// logRequest logs the request details to stderr for debugging
func (c *AgentClient) logRequest(method, url string, payload []byte) {
fmt.Fprintf(os.Stderr, "%s %s\n", method, url)
if len(payload) > 0 {
var prettyPayload interface{}
if err := json.Unmarshal(payload, &prettyPayload); err == nil {
prettyJSON, _ := json.MarshalIndent(prettyPayload, "", " ")
fmt.Fprintf(os.Stderr, "Payload:\n%s\n", string(prettyJSON))
} else {
fmt.Fprintf(os.Stderr, "Payload: %s\n", string(payload))
}
}
}

// logResponse logs the response body to stderr for debugging
func (c *AgentClient) logResponse(body []byte) {
fmt.Fprintln(os.Stderr, "Response:")
var jsonResponse interface{}
if err := json.Unmarshal(body, &jsonResponse); err == nil {
prettyJSON, _ := json.MarshalIndent(jsonResponse, "", " ")
fmt.Fprintln(os.Stderr, string(prettyJSON))
} else {
fmt.Fprintln(os.Stderr, string(body))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package azure

import "regexp"

var ConnectionStringJSONRegex = regexp.MustCompile(`("[\w]*(?:CONNECTION_STRING|ConnectionString)":\s*)"[^"]*"`)
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,10 @@ func (p *AgentServiceTargetProvider) createAgent(
azdEnv map[string]string,
) (*agent_api.AgentVersionObject, error) {
// Create agent client
agentClient := agent_api.NewAgentClient(azdEnv["AZURE_AI_PROJECT_ENDPOINT"], p.credential)
agentClient := agent_api.NewAgentClient(
azdEnv["AZURE_AI_PROJECT_ENDPOINT"],
p.credential,
)

// Use constant API version
const apiVersion = "2025-05-15-preview"
Expand Down Expand Up @@ -725,7 +728,10 @@ func (p *AgentServiceTargetProvider) startAgentContainer(
fmt.Fprintln(os.Stderr)

// Create agent client
agentClient := agent_api.NewAgentClient(azdEnv["AZURE_AI_PROJECT_ENDPOINT"], p.credential)
agentClient := agent_api.NewAgentClient(
azdEnv["AZURE_AI_PROJECT_ENDPOINT"],
p.credential,
)

var minReplicas, maxReplicas *int32
if foundryAgentConfig.Container != nil && foundryAgentConfig.Container.Scale != nil {
Expand Down
Loading