Skip to content

Commit 5941c2c

Browse files
committed
Move where startupCommand is stored. Move where we store the conversation details
Signed-off-by: trangevi <trangevi@microsoft.com>
1 parent f92eda7 commit 5941c2c

File tree

6 files changed

+60
-52
lines changed

6 files changed

+60
-52
lines changed

cli/azd/extensions/azure.ai.agents/internal/cmd/helpers.go

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"strings"
1515

1616
"azureaiagent/internal/exterrors"
17+
projectpkg "azureaiagent/internal/project"
1718

1819
"github.com/azure/azure-dev/cli/azd/pkg/azdext"
1920
)
@@ -34,14 +35,22 @@ type AgentLocalContext struct {
3435
}
3536

3637
// resolveConfigPath returns the full path to the .foundry-agent.json file
37-
// in the azd project root directory.
38-
func resolveConfigPath(ctx context.Context, azdClient *azdext.AzdClient) string {
38+
// in the current azd environment directory (<project root>/.azure/<env name>/).
39+
func resolveConfigPath(ctx context.Context, azdClient *azdext.AzdClient) (string, error) {
3940
projectResponse, err := azdClient.Project().Get(ctx, &azdext.EmptyRequest{})
4041
if err != nil || projectResponse.Project == nil {
41-
return ConfigFile
42+
return "", fmt.Errorf("failed to get project config: %w", err)
4243
}
4344

44-
return filepath.Join(projectResponse.Project.Path, ConfigFile)
45+
envResponse, err := azdClient.Environment().GetCurrent(ctx, &azdext.EmptyRequest{})
46+
if err != nil {
47+
return "", fmt.Errorf("failed to get current environment: %w", err)
48+
}
49+
if envResponse.Environment == nil || envResponse.Environment.Name == "" {
50+
return "", fmt.Errorf("no current environment set; run 'azd env select' or 'azd init' first")
51+
}
52+
53+
return filepath.Join(projectResponse.Project.Path, ".azure", envResponse.Environment.Name, ConfigFile), nil
4554
}
4655

4756
// loadLocalContext reads the .foundry-agent.json state file.
@@ -74,7 +83,10 @@ func resolveSessionID(ctx context.Context, azdClient *azdext.AzdClient, agentNam
7483
if explicit != "" {
7584
return explicit, nil
7685
}
77-
configPath := resolveConfigPath(ctx, azdClient)
86+
configPath, err := resolveConfigPath(ctx, azdClient)
87+
if err != nil {
88+
return "", err
89+
}
7890
agentCtx := loadLocalContext(configPath)
7991
if agentCtx.Sessions == nil {
8092
agentCtx.Sessions = make(map[string]string)
@@ -93,25 +105,31 @@ func resolveSessionID(ctx context.Context, azdClient *azdext.AzdClient, agentNam
93105
}
94106

95107
// resolveConversationID resolves or creates a Foundry conversation ID.
96-
// Returns empty string if creation fails (multi-turn memory disabled).
97-
func resolveConversationID(ctx context.Context, azdClient *azdext.AzdClient, agentName string, forceNew bool) string {
98-
configPath := resolveConfigPath(ctx, azdClient)
108+
// Returns empty string if no existing conversation is found or on error.
109+
func resolveConversationID(ctx context.Context, azdClient *azdext.AzdClient, agentName string, forceNew bool) (string, error) {
110+
configPath, err := resolveConfigPath(ctx, azdClient)
111+
if err != nil {
112+
return "", err
113+
}
99114
agentCtx := loadLocalContext(configPath)
100115
if agentCtx.Conversations == nil {
101116
agentCtx.Conversations = make(map[string]string)
102117
}
103118
if !forceNew {
104119
if convID, ok := agentCtx.Conversations[agentName]; ok {
105-
return convID
120+
return convID, nil
106121
}
107122
}
108123
// Conversation creation requires an API call — handled by the invoke command.
109-
return ""
124+
return "", nil
110125
}
111126

112127
// saveConversationID persists a conversation ID for an agent.
113128
func saveConversationID(ctx context.Context, azdClient *azdext.AzdClient, agentName, convID string) error {
114-
configPath := resolveConfigPath(ctx, azdClient)
129+
configPath, err := resolveConfigPath(ctx, azdClient)
130+
if err != nil {
131+
return err
132+
}
115133
agentCtx := loadLocalContext(configPath)
116134
if agentCtx.Conversations == nil {
117135
agentCtx.Conversations = make(map[string]string)
@@ -348,11 +366,10 @@ func resolveServiceRunContext(ctx context.Context, azdClient *azdext.AzdClient,
348366
projectDir := filepath.Join(project.Path, svc.RelativePath)
349367

350368
var startupCmd string
351-
if svc.AdditionalProperties != nil {
352-
if fields := svc.AdditionalProperties.GetFields(); fields != nil {
353-
if v, ok := fields["startupCommand"]; ok && v != nil {
354-
startupCmd = v.GetStringValue()
355-
}
369+
if svc.Config != nil {
370+
var agentConfig projectpkg.ServiceTargetAgentConfig
371+
if err := projectpkg.UnmarshalStruct(svc.Config, &agentConfig); err == nil {
372+
startupCmd = agentConfig.StartupCommand
356373
}
357374
}
358375

cli/azd/extensions/azure.ai.agents/internal/cmd/init.go

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1465,6 +1465,13 @@ func (a *InitAction) addToProject(ctx context.Context, targetDir string, agentMa
14651465
agentConfig.Deployments = a.deploymentDetails
14661466
agentConfig.Resources = resourceDetails
14671467

1468+
// Detect startup command from the project source directory
1469+
startupCmd, err := resolveStartupCommandForInit(ctx, a.azdClient, a.projectConfig.Path, targetDir, a.flags.NoPrompt)
1470+
if err != nil {
1471+
return err
1472+
}
1473+
agentConfig.StartupCommand = startupCmd
1474+
14681475
var agentConfigStruct *structpb.Struct
14691476
if agentConfigStruct, err = project.MarshalStruct(&agentConfig); err != nil {
14701477
return fmt.Errorf("failed to marshal agent config: %w", err)
@@ -1485,21 +1492,6 @@ func (a *InitAction) addToProject(ctx context.Context, targetDir string, agentMa
14851492
}
14861493
}
14871494

1488-
// Detect startup command from the project source directory
1489-
startupCmd, err := resolveStartupCommandForInit(ctx, a.azdClient, a.projectConfig.Path, targetDir, a.flags.NoPrompt)
1490-
if err != nil {
1491-
return err
1492-
}
1493-
if startupCmd != "" {
1494-
additionalProps, err := structpb.NewStruct(map[string]interface{}{
1495-
"startupCommand": startupCmd,
1496-
})
1497-
if err != nil {
1498-
return fmt.Errorf("failed to create additional properties: %w", err)
1499-
}
1500-
serviceConfig.AdditionalProperties = additionalProps
1501-
}
1502-
15031495
req := &azdext.AddServiceRequest{Service: serviceConfig}
15041496

15051497
if _, err := a.azdClient.Project().AddService(ctx, req); err != nil {

cli/azd/extensions/azure.ai.agents/internal/cmd/init_from_code.go

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1275,8 +1275,14 @@ func (a *InitFromCodeAction) addToProject(ctx context.Context, targetDir string,
12751275

12761276
agentConfig.Deployments = a.deploymentDetails
12771277

1278+
// Detect startup command from the project source directory
1279+
startupCmd, err := resolveStartupCommandForInit(ctx, a.azdClient, a.projectConfig.Path, targetDir, a.flags.NoPrompt)
1280+
if err != nil {
1281+
return err
1282+
}
1283+
agentConfig.StartupCommand = startupCmd
1284+
12781285
var agentConfigStruct *structpb.Struct
1279-
var err error
12801286
if agentConfigStruct, err = project.MarshalStruct(&agentConfig); err != nil {
12811287
return fmt.Errorf("failed to marshal agent config: %w", err)
12821288
}
@@ -1294,21 +1300,6 @@ func (a *InitFromCodeAction) addToProject(ctx context.Context, targetDir string,
12941300
RemoteBuild: true,
12951301
}
12961302

1297-
// Detect startup command from the project source directory
1298-
startupCmd, err := resolveStartupCommandForInit(ctx, a.azdClient, a.projectConfig.Path, targetDir, a.flags.NoPrompt)
1299-
if err != nil {
1300-
return err
1301-
}
1302-
if startupCmd != "" {
1303-
additionalProps, err := structpb.NewStruct(map[string]interface{}{
1304-
"startupCommand": startupCmd,
1305-
})
1306-
if err != nil {
1307-
return fmt.Errorf("failed to create additional properties: %w", err)
1308-
}
1309-
serviceConfig.AdditionalProperties = additionalProps
1310-
}
1311-
13121303
req := &azdext.AddServiceRequest{Service: serviceConfig}
13131304

13141305
if _, err := a.azdClient.Project().AddService(ctx, req); err != nil {

cli/azd/extensions/azure.ai.agents/internal/cmd/invoke.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,10 @@ func (a *InvokeAction) invokeRemote(ctx context.Context) error {
206206
body["session_id"] = sid
207207

208208
// Conversation ID — enables multi-turn memory via Foundry Conversations API
209-
convID := resolveConversationID(ctx, azdClient, name, a.flags.newSession)
209+
convID, err := resolveConversationID(ctx, azdClient, name, a.flags.newSession)
210+
if err != nil {
211+
return err
212+
}
210213
if convID == "" {
211214
// Create a new conversation
212215
newConvID, err := createConversation(ctx, endpoint)

cli/azd/extensions/azure.ai.agents/internal/project/config.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,11 @@ const (
2121

2222
// ServiceTargetAgentConfig provides custom configuration for the Azure AI Service target
2323
type ServiceTargetAgentConfig struct {
24-
Environment map[string]string `json:"env,omitempty"`
25-
Container *ContainerSettings `json:"container,omitempty"`
26-
Deployments []Deployment `json:"deployments,omitempty"`
27-
Resources []Resource `json:"resources,omitempty"`
24+
Environment map[string]string `json:"env,omitempty"`
25+
Container *ContainerSettings `json:"container,omitempty"`
26+
Deployments []Deployment `json:"deployments,omitempty"`
27+
Resources []Resource `json:"resources,omitempty"`
28+
StartupCommand string `json:"startupCommand,omitempty"`
2829
}
2930

3031
// ContainerSettings provides container configuration for the Azure AI Service target

cli/azd/extensions/azure.ai.agents/schemas/azure.ai.agent.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@
2323
"type": "array",
2424
"description": "List of external resources for agent execution.",
2525
"items": { "$ref": "#/definitions/Resource" }
26+
},
27+
"startupCommand": {
28+
"type": "string",
29+
"description": "Command to start the agent server (e.g., 'python main.py'). Used by 'azd ai agent run' for local development."
2630
}
2731
},
2832
"additionalProperties": false,

0 commit comments

Comments
 (0)