Skip to content

Commit 11c0cd4

Browse files
committed
Remove duplication
Signed-off-by: David Gageot <david.gageot@docker.com>
1 parent ec1fa42 commit 11c0cd4

2 files changed

Lines changed: 15 additions & 136 deletions

File tree

cmd/root/exec.go

Lines changed: 4 additions & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,15 @@
11
package root
22

3-
import (
4-
"context"
5-
"fmt"
6-
"log/slog"
7-
"os"
8-
"path/filepath"
9-
"strings"
10-
"time"
11-
12-
"github.com/spf13/cobra"
13-
"go.opentelemetry.io/otel"
14-
15-
"github.com/docker/cagent/pkg/remote"
16-
"github.com/docker/cagent/pkg/runtime"
17-
"github.com/docker/cagent/pkg/session"
18-
"github.com/docker/cagent/pkg/teamloader"
19-
)
3+
import "github.com/spf13/cobra"
204

215
func NewExecCmd() *cobra.Command {
226
cmd := &cobra.Command{
237
Use: "exec <agent-name>",
248
Short: "Execute an agent",
259
Args: cobra.ExactArgs(1),
26-
RunE: execCommand,
10+
RunE: func(cmd *cobra.Command, args []string) error {
11+
return runCommand(cmd, args, true)
12+
},
2713
}
2814

2915
cmd.PersistentFlags().StringVarP(&agentName, "agent", "a", "root", "Name of the agent to run")
@@ -35,118 +21,3 @@ func NewExecCmd() *cobra.Command {
3521

3622
return cmd
3723
}
38-
39-
func execCommand(_ *cobra.Command, args []string) error {
40-
ctx := context.Background()
41-
42-
slog.Debug("Starting agent", "agent", agentName, "debug_mode", debugMode)
43-
44-
agentFilename := args[0]
45-
if !strings.Contains(agentFilename, "\n") {
46-
if abs, err := filepath.Abs(agentFilename); err == nil {
47-
agentFilename = abs
48-
}
49-
}
50-
51-
if enableOtel {
52-
shutdown, err := initOTelSDK(ctx)
53-
if err != nil {
54-
slog.Warn("Failed to initialize OpenTelemetry SDK", "error", err)
55-
} else if shutdown != nil {
56-
defer func() {
57-
shutdownCtx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
58-
defer cancel()
59-
if err := shutdown(shutdownCtx); err != nil {
60-
slog.Warn("Failed to shutdown OpenTelemetry SDK", "error", err)
61-
}
62-
}()
63-
slog.Debug("OpenTelemetry SDK initialized successfully")
64-
}
65-
}
66-
67-
// If working-dir was provided, validate and change process working directory
68-
if workingDir != "" {
69-
absWd, err := filepath.Abs(workingDir)
70-
if err != nil {
71-
return fmt.Errorf("invalid working directory: %w", err)
72-
}
73-
info, err := os.Stat(absWd)
74-
if err != nil || !info.IsDir() {
75-
return fmt.Errorf("working directory does not exist or is not a directory: %s", absWd)
76-
}
77-
if err := os.Chdir(absWd); err != nil {
78-
return fmt.Errorf("failed to change working directory: %w", err)
79-
}
80-
_ = os.Setenv("PWD", absWd)
81-
slog.Debug("Working directory set", "dir", absWd)
82-
}
83-
84-
// Determine how to obtain the agent definition
85-
ext := strings.ToLower(filepath.Ext(agentFilename))
86-
if ext == ".yaml" || ext == ".yml" {
87-
// Treat as local YAML file: resolve to absolute path so later chdir doesn't break it
88-
if !strings.Contains(agentFilename, "\n") {
89-
if abs, err := filepath.Abs(agentFilename); err == nil {
90-
agentFilename = abs
91-
}
92-
}
93-
if !fileExists(agentFilename) {
94-
return fmt.Errorf("agent file not found: %s", agentFilename)
95-
}
96-
} else {
97-
// Treat as an OCI image reference. Try local store first, otherwise pull then load.
98-
a, err := fromStore(agentFilename)
99-
if err != nil {
100-
fmt.Println("Pulling agent ", agentFilename)
101-
if _, pullErr := remote.Pull(agentFilename); pullErr != nil {
102-
return fmt.Errorf("failed to pull OCI image %s: %w", agentFilename, pullErr)
103-
}
104-
// Retry after pull
105-
a, err = fromStore(agentFilename)
106-
if err != nil {
107-
return fmt.Errorf("failed to load agent from store after pull: %w", err)
108-
}
109-
}
110-
111-
// Write the fetched content to a temporary YAML file
112-
tmpFile, err := os.CreateTemp("", "agentfile-*.yaml")
113-
if err != nil {
114-
return err
115-
}
116-
defer os.Remove(tmpFile.Name())
117-
if _, err := tmpFile.WriteString(a); err != nil {
118-
tmpFile.Close()
119-
return err
120-
}
121-
if err := tmpFile.Close(); err != nil {
122-
return err
123-
}
124-
agentFilename = tmpFile.Name()
125-
}
126-
127-
agents, err := teamloader.Load(ctx, agentFilename, runConfig)
128-
if err != nil {
129-
return err
130-
}
131-
defer func() {
132-
if err := agents.StopToolSets(); err != nil {
133-
slog.Error("Failed to stop tool sets", "error", err)
134-
}
135-
}()
136-
137-
tracer := otel.Tracer(APP_NAME)
138-
139-
rt, err := runtime.New(agents,
140-
runtime.WithCurrentAgent(agentName),
141-
runtime.WithAutoRunTools(autoApprove),
142-
runtime.WithTracer(tracer),
143-
)
144-
if err != nil {
145-
return fmt.Errorf("failed to create runtime: %w", err)
146-
}
147-
148-
sess := session.New()
149-
sess.Title = "Running agent"
150-
151-
return runWithoutTUI(ctx, agentFilename, rt, sess, []string{"exec", "Follow the default instructions"})
152-
}

cmd/root/run.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ func NewRunCmd() *cobra.Command {
4848
cagent run ./echo.yaml "INSTRUCTIONS"
4949
echo "INSTRUCTIONS" | cagent run ./echo.yaml -`,
5050
Args: cobra.RangeArgs(1, 2),
51-
RunE: runCommand,
51+
RunE: func(cmd *cobra.Command, args []string) error {
52+
return runCommand(cmd, args, false)
53+
},
5254
}
5355

5456
cmd.PersistentFlags().StringVarP(&agentName, "agent", "a", "root", "Name of the agent to run")
@@ -74,7 +76,7 @@ func NewTuiCmd() *cobra.Command {
7476
}
7577
}
7678

77-
func runCommand(_ *cobra.Command, args []string) error {
79+
func runCommand(_ *cobra.Command, args []string, exec bool) error {
7880
ctx := context.Background()
7981

8082
slog.Debug("Starting agent", "agent", agentName, "debug_mode", debugMode)
@@ -186,11 +188,17 @@ func runCommand(_ *cobra.Command, args []string) error {
186188
sess := session.New()
187189
sess.Title = "Running agent"
188190

189-
// Run without the TUI
191+
// For `cagent exec`
192+
if exec {
193+
return runWithoutTUI(ctx, agentFilename, rt, sess, []string{"exec", "Follow the default instructions"})
194+
}
195+
196+
// For `cagent run --tui=false`
190197
if !useTUI {
191198
return runWithoutTUI(ctx, agentFilename, rt, sess, args)
192199
}
193200

201+
// The default is to use the TUI
194202
var firstMessage *string
195203
if len(args) == 2 {
196204
// TODO: attachments

0 commit comments

Comments
 (0)