Skip to content

Commit 089b601

Browse files
committed
Prepare for default agent
Signed-off-by: David Gageot <david.gageot@docker.com>
1 parent e89fada commit 089b601

4 files changed

Lines changed: 105 additions & 14 deletions

File tree

cmd/root/run.go

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,18 +86,21 @@ func (f *runExecFlags) runOrExec(ctx context.Context, out *cli.Printer, args []s
8686
var rt runtime.Runtime
8787
var sess *session.Session
8888
var err error
89-
if f.remoteAddress != "" {
90-
rt, sess, err = f.createRemoteRuntimeAndSession(ctx, args[0])
89+
switch {
90+
case f.remoteAddress != "":
91+
agentFileName = args[0]
92+
rt, sess, err = f.createRemoteRuntimeAndSession(ctx, agentFileName)
9193
if err != nil {
9294
return err
9395
}
94-
} else {
96+
97+
default:
9598
agentFileName, err = f.resolveAgentFile(ctx, out, args[0])
9699
if err != nil {
97100
return err
98101
}
99102

100-
t, err := f.loadAgents(ctx, agentFileName)
103+
t, err := f.loadAgentFrom(ctx, teamloader.NewFileSource(agentFileName))
101104
if err != nil {
102105
return err
103106
}
@@ -133,8 +136,8 @@ func (f *runExecFlags) resolveAgentFile(ctx context.Context, out *cli.Printer, a
133136
return agentfile.Resolve(ctx, out, agentFilename)
134137
}
135138

136-
func (f *runExecFlags) loadAgents(ctx context.Context, agentFilename string) (*team.Team, error) {
137-
t, err := teamloader.Load(ctx, agentFilename, f.runConfig, teamloader.WithModelOverrides(f.modelOverrides))
139+
func (f *runExecFlags) loadAgentFrom(ctx context.Context, source teamloader.AgentSource) (*team.Team, error) {
140+
t, err := teamloader.LoadFrom(ctx, source, f.runConfig, teamloader.WithModelOverrides(f.modelOverrides))
138141
if err != nil {
139142
return nil, err
140143
}

pkg/config/config.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,26 @@ import (
1919
func LoadConfig(path string, fs filesystem.FS) (*latest.Config, error) {
2020
data, err := fs.ReadFile(path)
2121
if err != nil {
22-
return nil, fmt.Errorf("reading config file: %w", err)
22+
return nil, fmt.Errorf("reading config file %s: %w", path, err)
2323
}
2424

25+
return LoadConfigBytes(data)
26+
}
27+
28+
func LoadConfigBytes(data []byte) (*latest.Config, error) {
2529
var raw struct {
2630
Version string `yaml:"version,omitempty"`
2731
}
2832
if err := yaml.UnmarshalWithOptions(data, &raw); err != nil {
29-
return nil, fmt.Errorf("looking for version in config file %s\n%s", path, yaml.FormatError(err, true, true))
33+
return nil, fmt.Errorf("looking for version in config file\n%s", yaml.FormatError(err, true, true))
3034
}
3135
if raw.Version == "" {
3236
raw.Version = latest.Version
3337
}
3438

3539
oldConfig, err := parseCurrentVersion(data, raw.Version)
3640
if err != nil {
37-
return nil, fmt.Errorf("parsing config file %s\n%s", path, yaml.FormatError(err, true, true))
41+
return nil, fmt.Errorf("parsing config file\n%s", yaml.FormatError(err, true, true))
3842
}
3943

4044
config, err := migrateToLatestConfig(oldConfig)

pkg/teamloader/sources.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package teamloader
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"path/filepath"
7+
)
8+
9+
type AgentSource interface {
10+
Name() string
11+
ParentDir() string
12+
Read() ([]byte, error)
13+
}
14+
15+
// fileSource is used to load an agent configuration from a YAML file.
16+
type fileSource struct {
17+
path string
18+
}
19+
20+
func NewFileSource(path string) AgentSource {
21+
return fileSource{
22+
path: path,
23+
}
24+
}
25+
26+
func (a fileSource) Name() string {
27+
return filepath.Base(a.path)
28+
}
29+
30+
func (a fileSource) ParentDir() string {
31+
return filepath.Dir(a.path)
32+
}
33+
34+
func (a fileSource) Read() ([]byte, error) {
35+
parentDir := a.ParentDir()
36+
fs, err := os.OpenRoot(parentDir)
37+
if err != nil {
38+
return nil, fmt.Errorf("opening filesystem %s: %w", parentDir, err)
39+
}
40+
41+
fileName := a.Name()
42+
data, err := fs.ReadFile(fileName)
43+
if err != nil {
44+
return nil, fmt.Errorf("reading config file %s: %w", fileName, err)
45+
}
46+
47+
return data, nil
48+
}
49+
50+
// bytesSource is used to load an agent configuration from a []byte.
51+
type bytesSource struct {
52+
workingDir string
53+
data []byte
54+
}
55+
56+
func NewBytesSource(workingDir string, data []byte) AgentSource {
57+
// TODO(dga): this is not perfect but ok for now
58+
if workingDir == "" {
59+
workingDir = "."
60+
}
61+
return bytesSource{
62+
workingDir: workingDir,
63+
data: data,
64+
}
65+
}
66+
67+
func (a bytesSource) Name() string {
68+
return ""
69+
}
70+
71+
func (a bytesSource) ParentDir() string {
72+
return a.workingDir
73+
}
74+
75+
func (a bytesSource) Read() ([]byte, error) {
76+
return a.data, nil
77+
}

pkg/teamloader/teamloader.go

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,14 @@ func WithToolsetRegistry(registry *ToolsetRegistry) Opt {
9595
}
9696
}
9797

98+
// Load loads an agent team from the given file path.
99+
// Prefers LoadFrom for more control over the source.
98100
func Load(ctx context.Context, p string, runtimeConfig config.RuntimeConfig, opts ...Opt) (*team.Team, error) {
101+
return LoadFrom(ctx, NewFileSource(p), runtimeConfig, opts...)
102+
}
103+
104+
// LoadFrom loads an agent team from the given source
105+
func LoadFrom(ctx context.Context, source AgentSource, runtimeConfig config.RuntimeConfig, opts ...Opt) (*team.Team, error) {
99106
var loadOpts loadOptions
100107
loadOpts.toolsetRegistry = NewDefaultToolsetRegistry()
101108

@@ -105,8 +112,8 @@ func Load(ctx context.Context, p string, runtimeConfig config.RuntimeConfig, opt
105112
}
106113
}
107114

108-
fileName := filepath.Base(p)
109-
parentDir := filepath.Dir(p)
115+
fileName := source.Name()
116+
parentDir := source.ParentDir()
110117

111118
// Make env file paths absolute relative to the agent config file.
112119
var err error
@@ -127,12 +134,12 @@ func Load(ctx context.Context, p string, runtimeConfig config.RuntimeConfig, opt
127134
env := environment.NewMultiProvider(envFilesProviders, defaultEnvProvider)
128135

129136
// Load the agent's configuration
130-
fs, err := os.OpenRoot(parentDir)
137+
data, err := source.Read()
131138
if err != nil {
132-
return nil, fmt.Errorf("opening filesystem %s: %w", parentDir, err)
139+
return nil, fmt.Errorf("reading config file: %w", err)
133140
}
134141

135-
cfg, err := config.LoadConfig(fileName, fs)
142+
cfg, err := config.LoadConfigBytes(data)
136143
if err != nil {
137144
return nil, err
138145
}

0 commit comments

Comments
 (0)