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
18 changes: 12 additions & 6 deletions cmd/root/acp.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,39 @@ import (
"github.com/spf13/cobra"

"github.com/docker/cagent/pkg/acp"
"github.com/docker/cagent/pkg/config"
"github.com/docker/cagent/pkg/telemetry"
)

type acpFlags struct {
runConfig config.RuntimeConfig
}

func newACPCmd() *cobra.Command {
var flags acpFlags

cmd := &cobra.Command{
Use: "acp <agent-file>",
Short: "Start an ACP (Agent Client Protocol) server",
Long: `Start an ACP server that exposes the agent via the Agent Client Protocol`,
Args: cobra.ExactArgs(1),
RunE: runACPCommand,
RunE: flags.runACPCommand,
}

addGatewayFlags(cmd)
addRuntimeConfigFlags(cmd)
addRuntimeConfigFlags(cmd, &flags.runConfig)

return cmd
}

func runACPCommand(cmd *cobra.Command, args []string) error {
func (f *acpFlags) runACPCommand(cmd *cobra.Command, args []string) error {
telemetry.TrackCommand("acp", args)

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

slog.Debug("Starting ACP server", "agent_file", agentFilename, "debug_mode", debugMode)
slog.Debug("Starting ACP server", "agent_file", agentFilename)

acpAgent := acp.NewAgent(agentFilename, runConfig)
acpAgent := acp.NewAgent(agentFilename, f.runConfig)
conn := acpsdk.NewAgentSideConnection(acpAgent, cmd.OutOrStdout(), cmd.InOrStdin())
conn.SetLogger(slog.Default())
acpAgent.SetAgentConnection(conn)
Expand Down
12 changes: 7 additions & 5 deletions cmd/root/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/spf13/cobra"

"github.com/docker/cagent/pkg/config"
"github.com/docker/cagent/pkg/server"
"github.com/docker/cagent/pkg/session"
"github.com/docker/cagent/pkg/teamloader"
Expand All @@ -18,6 +19,7 @@ import (
type apiFlags struct {
listenAddr string
sessionDB string
runConfig config.RuntimeConfig
}

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

cmd.PersistentFlags().StringVarP(&flags.listenAddr, "listen", "l", ":8080", "Address to listen on")
cmd.PersistentFlags().StringVarP(&flags.sessionDB, "session-db", "s", "session.db", "Path to the session database")
addGatewayFlags(cmd)
addRuntimeConfigFlags(cmd)

addRuntimeConfigFlags(cmd, &flags.runConfig)

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

slog.Debug("Starting server", "agents", agentsPath, "debug_mode", debugMode)
slog.Debug("Starting server", "agents", agentsPath)

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

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

s, err := server.New(sessionStore, runConfig, teams, opts...)
s, err := server.New(sessionStore, f.runConfig, teams, opts...)
if err != nil {
return fmt.Errorf("failed to create server: %w", err)
}
Expand Down
15 changes: 12 additions & 3 deletions cmd/root/debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,18 @@ import (

"github.com/spf13/cobra"

"github.com/docker/cagent/pkg/config"
"github.com/docker/cagent/pkg/teamloader"
"github.com/docker/cagent/pkg/telemetry"
)

type debugFlags struct {
runConfig config.RuntimeConfig
}

func newDebugCmd() *cobra.Command {
var flags debugFlags

cmd := &cobra.Command{
Use: "debug",
}
Expand All @@ -18,20 +25,22 @@ func newDebugCmd() *cobra.Command {
Use: "toolsets <agent-name>",
Short: "Debug the toolsets of an agent",
Args: cobra.ExactArgs(1),
RunE: runDebugToolsetsCommand,
RunE: flags.runDebugToolsetsCommand,
})

addRuntimeConfigFlags(cmd, &flags.runConfig)

return cmd
}

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

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

slog.Info("Loading agent", "agent", agentFilename)
team, err := teamloader.Load(ctx, agentFilename, runConfig)
team, err := teamloader.Load(ctx, agentFilename, f.runConfig)
if err != nil {
return err
}
Expand Down
16 changes: 11 additions & 5 deletions cmd/root/eval.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,35 @@ import (

"github.com/spf13/cobra"

"github.com/docker/cagent/pkg/config"
"github.com/docker/cagent/pkg/evaluation"
"github.com/docker/cagent/pkg/teamloader"
"github.com/docker/cagent/pkg/telemetry"
)

type evalFlags struct {
runConfig config.RuntimeConfig
}

func newEvalCmd() *cobra.Command {
var flags evalFlags

cmd := &cobra.Command{
Use: "eval <agent-name> <eval-dir>",
Short: "Run evaluations for an agent",
Args: cobra.ExactArgs(2),
RunE: runEvalCommand,
RunE: flags.runEvalCommand,
}

addGatewayFlags(cmd)
addRuntimeConfigFlags(cmd)
addRuntimeConfigFlags(cmd, &flags.runConfig)

return cmd
}

func runEvalCommand(cmd *cobra.Command, args []string) error {
func (f *evalFlags) runEvalCommand(cmd *cobra.Command, args []string) error {
telemetry.TrackCommand("eval", args)

agents, err := teamloader.Load(cmd.Context(), args[0], runConfig)
agents, err := teamloader.Load(cmd.Context(), args[0], f.runConfig)
if err != nil {
return err
}
Expand Down
5 changes: 2 additions & 3 deletions cmd/root/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,15 @@ func newExecCmd() *cobra.Command {
RunE: flags.runExecCommand,
}

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

addGatewayFlags(cmd)
addRuntimeConfigFlags(cmd)
addRuntimeConfigFlags(cmd, &flags.runConfig)

return cmd
}
Expand Down
5 changes: 2 additions & 3 deletions cmd/root/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,8 @@ import (
"github.com/docker/cagent/pkg/config"
)

var runConfig config.RuntimeConfig

func addRuntimeConfigFlags(cmd *cobra.Command) {
func addRuntimeConfigFlags(cmd *cobra.Command, runConfig *config.RuntimeConfig) {
addGatewayFlags(cmd, runConfig)
cmd.PersistentFlags().StringSliceVar(&runConfig.EnvFiles, "env-from-file", nil, "Set environment variables from file")
cmd.PersistentFlags().StringVar(&runConfig.RedirectURI, "redirect-uri", "", "Set the redirect URI for OAuth2 flows")
cmd.PersistentFlags().BoolVar(&runConfig.GlobalCodeMode, "code-mode-tools", false, "Provide a single tool to call other tools via Javascript")
Expand Down
8 changes: 5 additions & 3 deletions cmd/root/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"strings"

"github.com/spf13/cobra"

"github.com/docker/cagent/pkg/config"
)

const (
Expand All @@ -19,8 +21,6 @@ type gatewayConfig struct {
mainGateway string
}

var gwConfig gatewayConfig

func canonize(endpoint string) string {
return strings.TrimSpace(strings.TrimSuffix(endpoint, "/"))
}
Expand All @@ -31,7 +31,9 @@ func logEnvvarShadowing(flagValue, varName, flagName string) {
}
}

func addGatewayFlags(cmd *cobra.Command) {
func addGatewayFlags(cmd *cobra.Command, runConfig *config.RuntimeConfig) {
var gwConfig gatewayConfig

cmd.PersistentFlags().StringVar(&gwConfig.mainGateway, flagGateway, "", "Set the gateway address to use for models and tool calls")
cmd.PersistentFlags().StringVar(&runConfig.ModelsGateway, flagModelsGateway, "", "Set the models gateway address")

Expand Down
7 changes: 2 additions & 5 deletions cmd/root/gateway_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,10 +107,6 @@ func TestGatewayLogic(t *testing.T) {
t.Setenv(key, value)
}

// Reset global variables
runConfig = config.RuntimeConfig{}
gwConfig = gatewayConfig{}

// Create a test command with gateway flags
cmd := &cobra.Command{
Use: "test",
Expand All @@ -121,7 +117,8 @@ func TestGatewayLogic(t *testing.T) {
}

// Add gateway flags (this is the actual function being tested)
addGatewayFlags(cmd)
runConfig := config.RuntimeConfig{}
addGatewayFlags(cmd, &runConfig)

// Set command arguments and execute
cmd.SetArgs(tt.args)
Expand Down
10 changes: 7 additions & 3 deletions cmd/root/new.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/spf13/cobra"

"github.com/docker/cagent/pkg/cli"
"github.com/docker/cagent/pkg/config"
"github.com/docker/cagent/pkg/creator"
"github.com/docker/cagent/pkg/input"
"github.com/docker/cagent/pkg/runtime"
Expand All @@ -18,6 +19,7 @@ type newFlags struct {
modelParam string
maxTokensParam int
maxIterationsParam int
runConfig config.RuntimeConfig
}

func newNewCmd() *cobra.Command {
Expand All @@ -29,11 +31,13 @@ func newNewCmd() *cobra.Command {
Long: `Create a new agent configuration by asking questions and generating a YAML file`,
RunE: flags.runNewCommand,
}
addGatewayFlags(cmd)

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")
cmd.PersistentFlags().IntVar(&flags.maxTokensParam, "max-tokens", 0, "Override max_tokens for the selected model (0 = default)")
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)")

addRuntimeConfigFlags(cmd, &flags.runConfig)

return cmd
}

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

events, rt, err := creator.StreamCreateAgent(ctx, ".", prompt, runConfig, modelProvider, model, f.maxTokensParam, f.maxIterationsParam)
events, rt, err := creator.StreamCreateAgent(ctx, ".", prompt, f.runConfig, modelProvider, model, f.maxTokensParam, f.maxIterationsParam)
if err != nil {
return err
}
Expand Down
1 change: 0 additions & 1 deletion cmd/root/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ func (e RuntimeError) Unwrap() error {
}

var (
agentName string
debugMode bool
enableOtel bool
logFilePath string
Expand Down
Loading
Loading