Skip to content

Commit c6ababb

Browse files
authored
Merge pull request #700 from dgageot/remove-more-global-state
Remove more global state
2 parents 965d676 + a8df2d8 commit c6ababb

11 files changed

Lines changed: 75 additions & 49 deletions

File tree

cmd/root/acp.go

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,33 +7,39 @@ import (
77
"github.com/spf13/cobra"
88

99
"github.com/docker/cagent/pkg/acp"
10+
"github.com/docker/cagent/pkg/config"
1011
"github.com/docker/cagent/pkg/telemetry"
1112
)
1213

14+
type acpFlags struct {
15+
runConfig config.RuntimeConfig
16+
}
17+
1318
func newACPCmd() *cobra.Command {
19+
var flags acpFlags
20+
1421
cmd := &cobra.Command{
1522
Use: "acp <agent-file>",
1623
Short: "Start an ACP (Agent Client Protocol) server",
1724
Long: `Start an ACP server that exposes the agent via the Agent Client Protocol`,
1825
Args: cobra.ExactArgs(1),
19-
RunE: runACPCommand,
26+
RunE: flags.runACPCommand,
2027
}
2128

22-
addGatewayFlags(cmd)
23-
addRuntimeConfigFlags(cmd)
29+
addRuntimeConfigFlags(cmd, &flags.runConfig)
2430

2531
return cmd
2632
}
2733

28-
func runACPCommand(cmd *cobra.Command, args []string) error {
34+
func (f *acpFlags) runACPCommand(cmd *cobra.Command, args []string) error {
2935
telemetry.TrackCommand("acp", args)
3036

3137
ctx := cmd.Context()
3238
agentFilename := args[0]
3339

34-
slog.Debug("Starting ACP server", "agent_file", agentFilename, "debug_mode", debugMode)
40+
slog.Debug("Starting ACP server", "agent_file", agentFilename)
3541

36-
acpAgent := acp.NewAgent(agentFilename, runConfig)
42+
acpAgent := acp.NewAgent(agentFilename, f.runConfig)
3743
conn := acpsdk.NewAgentSideConnection(acpAgent, cmd.OutOrStdout(), cmd.InOrStdin())
3844
conn.SetLogger(slog.Default())
3945
acpAgent.SetAgentConnection(conn)

cmd/root/api.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99

1010
"github.com/spf13/cobra"
1111

12+
"github.com/docker/cagent/pkg/config"
1213
"github.com/docker/cagent/pkg/server"
1314
"github.com/docker/cagent/pkg/session"
1415
"github.com/docker/cagent/pkg/teamloader"
@@ -18,6 +19,7 @@ import (
1819
type apiFlags struct {
1920
listenAddr string
2021
sessionDB string
22+
runConfig config.RuntimeConfig
2123
}
2224

2325
func newAPICmd() *cobra.Command {
@@ -33,8 +35,8 @@ func newAPICmd() *cobra.Command {
3335

3436
cmd.PersistentFlags().StringVarP(&flags.listenAddr, "listen", "l", ":8080", "Address to listen on")
3537
cmd.PersistentFlags().StringVarP(&flags.sessionDB, "session-db", "s", "session.db", "Path to the session database")
36-
addGatewayFlags(cmd)
37-
addRuntimeConfigFlags(cmd)
38+
39+
addRuntimeConfigFlags(cmd, &flags.runConfig)
3840

3941
return cmd
4042
}
@@ -63,7 +65,7 @@ func (f *apiFlags) runAPICommand(cmd *cobra.Command, args []string) error {
6365
slog.Info("Listening on " + f.listenAddr)
6466
}
6567

66-
slog.Debug("Starting server", "agents", agentsPath, "debug_mode", debugMode)
68+
slog.Debug("Starting server", "agents", agentsPath)
6769

6870
sessionStore, err := session.NewSQLiteSessionStore(f.sessionDB)
6971
if err != nil {
@@ -82,7 +84,7 @@ func (f *apiFlags) runAPICommand(cmd *cobra.Command, args []string) error {
8284
opts = append(opts, server.WithAgentsDir(filepath.Dir(agentsPath)))
8385
}
8486

85-
teams, err := teamloader.LoadTeams(ctx, agentsPath, runConfig)
87+
teams, err := teamloader.LoadTeams(ctx, agentsPath, f.runConfig)
8688
if err != nil {
8789
return fmt.Errorf("failed to load teams: %w", err)
8890
}
@@ -94,7 +96,7 @@ func (f *apiFlags) runAPICommand(cmd *cobra.Command, args []string) error {
9496
}
9597
}()
9698

97-
s, err := server.New(sessionStore, runConfig, teams, opts...)
99+
s, err := server.New(sessionStore, f.runConfig, teams, opts...)
98100
if err != nil {
99101
return fmt.Errorf("failed to create server: %w", err)
100102
}

cmd/root/debug.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,18 @@ import (
55

66
"github.com/spf13/cobra"
77

8+
"github.com/docker/cagent/pkg/config"
89
"github.com/docker/cagent/pkg/teamloader"
910
"github.com/docker/cagent/pkg/telemetry"
1011
)
1112

13+
type debugFlags struct {
14+
runConfig config.RuntimeConfig
15+
}
16+
1217
func newDebugCmd() *cobra.Command {
18+
var flags debugFlags
19+
1320
cmd := &cobra.Command{
1421
Use: "debug",
1522
}
@@ -18,20 +25,22 @@ func newDebugCmd() *cobra.Command {
1825
Use: "toolsets <agent-name>",
1926
Short: "Debug the toolsets of an agent",
2027
Args: cobra.ExactArgs(1),
21-
RunE: runDebugToolsetsCommand,
28+
RunE: flags.runDebugToolsetsCommand,
2229
})
2330

31+
addRuntimeConfigFlags(cmd, &flags.runConfig)
32+
2433
return cmd
2534
}
2635

27-
func runDebugToolsetsCommand(cmd *cobra.Command, args []string) error {
36+
func (f *debugFlags) runDebugToolsetsCommand(cmd *cobra.Command, args []string) error {
2837
telemetry.TrackCommand("debug", append([]string{"toolsets"}, args...))
2938

3039
ctx := cmd.Context()
3140
agentFilename := args[0]
3241

3342
slog.Info("Loading agent", "agent", agentFilename)
34-
team, err := teamloader.Load(ctx, agentFilename, runConfig)
43+
team, err := teamloader.Load(ctx, agentFilename, f.runConfig)
3544
if err != nil {
3645
return err
3746
}

cmd/root/eval.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,35 @@ import (
55

66
"github.com/spf13/cobra"
77

8+
"github.com/docker/cagent/pkg/config"
89
"github.com/docker/cagent/pkg/evaluation"
910
"github.com/docker/cagent/pkg/teamloader"
1011
"github.com/docker/cagent/pkg/telemetry"
1112
)
1213

14+
type evalFlags struct {
15+
runConfig config.RuntimeConfig
16+
}
17+
1318
func newEvalCmd() *cobra.Command {
19+
var flags evalFlags
20+
1421
cmd := &cobra.Command{
1522
Use: "eval <agent-name> <eval-dir>",
1623
Short: "Run evaluations for an agent",
1724
Args: cobra.ExactArgs(2),
18-
RunE: runEvalCommand,
25+
RunE: flags.runEvalCommand,
1926
}
2027

21-
addGatewayFlags(cmd)
22-
addRuntimeConfigFlags(cmd)
28+
addRuntimeConfigFlags(cmd, &flags.runConfig)
2329

2430
return cmd
2531
}
2632

27-
func runEvalCommand(cmd *cobra.Command, args []string) error {
33+
func (f *evalFlags) runEvalCommand(cmd *cobra.Command, args []string) error {
2834
telemetry.TrackCommand("eval", args)
2935

30-
agents, err := teamloader.Load(cmd.Context(), args[0], runConfig)
36+
agents, err := teamloader.Load(cmd.Context(), args[0], f.runConfig)
3137
if err != nil {
3238
return err
3339
}

cmd/root/exec.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,15 @@ func newExecCmd() *cobra.Command {
1717
RunE: flags.runExecCommand,
1818
}
1919

20-
cmd.PersistentFlags().StringVarP(&agentName, "agent", "a", "root", "Name of the agent to run")
20+
cmd.PersistentFlags().StringVarP(&flags.agentName, "agent", "a", "root", "Name of the agent to run")
2121
cmd.PersistentFlags().StringVar(&flags.workingDir, "working-dir", "", "Set the working directory for the session (applies to tools and relative paths)")
2222
cmd.PersistentFlags().BoolVar(&flags.autoApprove, "yolo", false, "Automatically approve all tool calls without prompting")
2323
cmd.PersistentFlags().StringVar(&flags.attachmentPath, "attach", "", "Attach an image file to the message")
2424
cmd.PersistentFlags().StringArrayVar(&flags.modelOverrides, "model", nil, "Override agent model: [agent=]provider/model (repeatable)")
2525
cmd.PersistentFlags().BoolVar(&flags.dryRun, "dry-run", false, "Initialize the agent without executing anything")
2626
_ = cmd.PersistentFlags().MarkHidden("dry-run")
2727

28-
addGatewayFlags(cmd)
29-
addRuntimeConfigFlags(cmd)
28+
addRuntimeConfigFlags(cmd, &flags.runConfig)
3029

3130
return cmd
3231
}

cmd/root/flags.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@ import (
66
"github.com/docker/cagent/pkg/config"
77
)
88

9-
var runConfig config.RuntimeConfig
10-
11-
func addRuntimeConfigFlags(cmd *cobra.Command) {
9+
func addRuntimeConfigFlags(cmd *cobra.Command, runConfig *config.RuntimeConfig) {
10+
addGatewayFlags(cmd, runConfig)
1211
cmd.PersistentFlags().StringSliceVar(&runConfig.EnvFiles, "env-from-file", nil, "Set environment variables from file")
1312
cmd.PersistentFlags().StringVar(&runConfig.RedirectURI, "redirect-uri", "", "Set the redirect URI for OAuth2 flows")
1413
cmd.PersistentFlags().BoolVar(&runConfig.GlobalCodeMode, "code-mode-tools", false, "Provide a single tool to call other tools via Javascript")

cmd/root/gateway.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66
"strings"
77

88
"github.com/spf13/cobra"
9+
10+
"github.com/docker/cagent/pkg/config"
911
)
1012

1113
const (
@@ -19,8 +21,6 @@ type gatewayConfig struct {
1921
mainGateway string
2022
}
2123

22-
var gwConfig gatewayConfig
23-
2424
func canonize(endpoint string) string {
2525
return strings.TrimSpace(strings.TrimSuffix(endpoint, "/"))
2626
}
@@ -31,7 +31,9 @@ func logEnvvarShadowing(flagValue, varName, flagName string) {
3131
}
3232
}
3333

34-
func addGatewayFlags(cmd *cobra.Command) {
34+
func addGatewayFlags(cmd *cobra.Command, runConfig *config.RuntimeConfig) {
35+
var gwConfig gatewayConfig
36+
3537
cmd.PersistentFlags().StringVar(&gwConfig.mainGateway, flagGateway, "", "Set the gateway address to use for models and tool calls")
3638
cmd.PersistentFlags().StringVar(&runConfig.ModelsGateway, flagModelsGateway, "", "Set the models gateway address")
3739

cmd/root/gateway_test.go

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -107,10 +107,6 @@ func TestGatewayLogic(t *testing.T) {
107107
t.Setenv(key, value)
108108
}
109109

110-
// Reset global variables
111-
runConfig = config.RuntimeConfig{}
112-
gwConfig = gatewayConfig{}
113-
114110
// Create a test command with gateway flags
115111
cmd := &cobra.Command{
116112
Use: "test",
@@ -121,7 +117,8 @@ func TestGatewayLogic(t *testing.T) {
121117
}
122118

123119
// Add gateway flags (this is the actual function being tested)
124-
addGatewayFlags(cmd)
120+
runConfig := config.RuntimeConfig{}
121+
addGatewayFlags(cmd, &runConfig)
125122

126123
// Set command arguments and execute
127124
cmd.SetArgs(tt.args)

cmd/root/new.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/spf13/cobra"
99

1010
"github.com/docker/cagent/pkg/cli"
11+
"github.com/docker/cagent/pkg/config"
1112
"github.com/docker/cagent/pkg/creator"
1213
"github.com/docker/cagent/pkg/input"
1314
"github.com/docker/cagent/pkg/runtime"
@@ -18,6 +19,7 @@ type newFlags struct {
1819
modelParam string
1920
maxTokensParam int
2021
maxIterationsParam int
22+
runConfig config.RuntimeConfig
2123
}
2224

2325
func newNewCmd() *cobra.Command {
@@ -29,11 +31,13 @@ func newNewCmd() *cobra.Command {
2931
Long: `Create a new agent configuration by asking questions and generating a YAML file`,
3032
RunE: flags.runNewCommand,
3133
}
32-
addGatewayFlags(cmd)
34+
3335
cmd.PersistentFlags().StringVar(&flags.modelParam, "model", "", "Model to use, optionally as provider/model where provider is one of: anthropic, openai, google, dmr. If omitted, provider is auto-selected based on available credentials or gateway")
3436
cmd.PersistentFlags().IntVar(&flags.maxTokensParam, "max-tokens", 0, "Override max_tokens for the selected model (0 = default)")
3537
cmd.PersistentFlags().IntVar(&flags.maxIterationsParam, "max-iterations", 0, "Maximum number of agentic loop iterations to prevent infinite loops (default: 20 for DMR, unlimited for other providers)")
3638

39+
addRuntimeConfigFlags(cmd, &flags.runConfig)
40+
3741
return cmd
3842
}
3943

@@ -61,7 +65,7 @@ func (f *newFlags) runNewCommand(cmd *cobra.Command, args []string) error {
6165
if derivedProvider != "" {
6266
modelProvider = derivedProvider
6367
} else {
64-
if runConfig.ModelsGateway == "" {
68+
if f.runConfig.ModelsGateway == "" {
6569
// Prefer Anthropic, then OpenAI, then Google based on available API keys
6670
// default to DMR if no provider credentials are found
6771
switch {
@@ -105,7 +109,7 @@ func (f *newFlags) runNewCommand(cmd *cobra.Command, args []string) error {
105109
out.Println()
106110
}
107111

108-
events, rt, err := creator.StreamCreateAgent(ctx, ".", prompt, runConfig, modelProvider, model, f.maxTokensParam, f.maxIterationsParam)
112+
events, rt, err := creator.StreamCreateAgent(ctx, ".", prompt, f.runConfig, modelProvider, model, f.maxTokensParam, f.maxIterationsParam)
109113
if err != nil {
110114
return err
111115
}

cmd/root/root.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ func (e RuntimeError) Unwrap() error {
3333
}
3434

3535
var (
36-
agentName string
3736
debugMode bool
3837
enableOtel bool
3938
logFilePath string

0 commit comments

Comments
 (0)