Skip to content

Commit 6ad4b42

Browse files
authored
feat(agents): support uv and other python project detection/setup (#623)
* feat(agents): support uv python project detection and auto setup * feat(agents): filter dockerignore files from entrypoint match * fix(agents): better project type detection in python projects * feat(agents): support more robust sdk version checking * chore(agents): remove todos * chore: update deps
1 parent 02ed901 commit 6ad4b42

File tree

14 files changed

+1297
-696
lines changed

14 files changed

+1297
-696
lines changed

cmd/lk/agent.go

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,12 @@ var (
8282
Hidden: true,
8383
}
8484

85+
skipSDKCheckFlag = &cli.BoolFlag{
86+
Name: "skip-sdk-check",
87+
Required: false,
88+
Hidden: true,
89+
}
90+
8591
AgentCommands = []*cli.Command{
8692
{
8793
Name: "agent",
@@ -98,6 +104,7 @@ var (
98104
secretsFileFlag,
99105
silentFlag,
100106
regionFlag,
107+
skipSDKCheckFlag,
101108
},
102109
// NOTE: since secrets may contain commas, or indeed any special character we might want to treat as a flag separator,
103110
// we disable it entirely here and require multiple --secrets flags to be used.
@@ -369,15 +376,22 @@ func createAgent(ctx context.Context, cmd *cli.Command) error {
369376
return err
370377
}
371378

372-
if err := requireDockerfile(ctx, cmd, workingDir, settingsMap); err != nil {
379+
projectType, err := agentfs.DetectProjectType(workingDir)
380+
if err != nil {
381+
return fmt.Errorf("unable to determine project type: %w, please use a supported project type, or create your own Dockerfile in the current directory", err)
382+
}
383+
384+
if err := requireDockerfile(ctx, cmd, workingDir, projectType, settingsMap); err != nil {
373385
return err
374386
}
375387

376-
// TODO (steveyoon): disable check SDK version until we add support for uv and lockfile generation
377-
// https://github.com/livekit/livekit-cli/pull/618/files
378-
// if err := agentfs.CheckSDKVersion(workingDir, settingsMap); err != nil {
379-
// return err
380-
// }
388+
if err := agentfs.CheckSDKVersion(workingDir, projectType, settingsMap); err != nil {
389+
if cmd.Bool("skip-sdk-check") {
390+
fmt.Printf("Error checking SDK version: %v, skipping...\n", err)
391+
} else {
392+
return err
393+
}
394+
}
381395

382396
req := &lkproto.CreateAgentRequest{
383397
Secrets: secrets,
@@ -525,6 +539,24 @@ func deployAgent(ctx context.Context, cmd *cli.Command) error {
525539
req.Secrets = secrets
526540
}
527541

542+
projectType, err := agentfs.DetectProjectType(workingDir)
543+
if err != nil {
544+
return fmt.Errorf("unable to determine project type: %w, please use a supported project type, or create your own Dockerfile in the current directory", err)
545+
}
546+
547+
settingsMap, err := getClientSettings(ctx, cmd.Bool("silent"))
548+
if err != nil {
549+
return err
550+
}
551+
552+
if err := agentfs.CheckSDKVersion(workingDir, projectType, settingsMap); err != nil {
553+
if cmd.Bool("skip-sdk-check") {
554+
fmt.Printf("Error checking SDK version: %v, skipping...\n", err)
555+
} else {
556+
return err
557+
}
558+
}
559+
528560
resp, err := agentsClient.DeployAgent(ctx, req)
529561
if err != nil {
530562
if twerr, ok := err.(twirp.Error); ok {
@@ -1084,7 +1116,7 @@ func requireSecrets(_ context.Context, cmd *cli.Command, required, lazy bool) ([
10841116
return secretsSlice, nil
10851117
}
10861118

1087-
func requireDockerfile(ctx context.Context, cmd *cli.Command, workingDir string, settingsMap map[string]string) error {
1119+
func requireDockerfile(_ context.Context, cmd *cli.Command, workingDir string, projectType agentfs.ProjectType, settingsMap map[string]string) error {
10881120
dockerfileExists, err := agentfs.HasDockerfile(workingDir)
10891121
if err != nil {
10901122
return err
@@ -1096,7 +1128,7 @@ func requireDockerfile(ctx context.Context, cmd *cli.Command, workingDir string,
10961128
if err := util.Await(
10971129
"Creating Dockerfile...",
10981130
func() {
1099-
innerErr = agentfs.CreateDockerfile(workingDir, settingsMap)
1131+
innerErr = agentfs.CreateDockerfile(workingDir, projectType, settingsMap)
11001132
},
11011133
); err != nil {
11021134
return err
@@ -1106,7 +1138,7 @@ func requireDockerfile(ctx context.Context, cmd *cli.Command, workingDir string,
11061138
}
11071139
fmt.Println("Created [" + util.Accented("Dockerfile") + "]")
11081140
} else {
1109-
if err := agentfs.CreateDockerfile(workingDir, settingsMap); err != nil {
1141+
if err := agentfs.CreateDockerfile(workingDir, projectType, settingsMap); err != nil {
11101142
return err
11111143
}
11121144
}

go.mod

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
11
module github.com/livekit/livekit-cli/v2
22

3-
go 1.24.3
3+
go 1.24.4
4+
5+
toolchain go1.24.6
46

57
require (
68
github.com/BurntSushi/toml v1.5.0
79
github.com/Masterminds/semver/v3 v3.4.0
810
github.com/charmbracelet/huh v0.7.0
911
github.com/charmbracelet/huh/spinner v0.0.0-20250602115108-fe12c0e929d3
10-
github.com/charmbracelet/lipgloss v1.1.0
12+
github.com/charmbracelet/lipgloss v1.1.1-0.20250404203927-76690c660834
1113
github.com/frostbyte73/core v0.1.1
1214
github.com/go-logr/logr v1.4.3
1315
github.com/go-task/task/v3 v3.44.1
14-
github.com/google/osv-scanner v1.9.2
1516
github.com/joho/godotenv v1.5.1
16-
github.com/livekit/protocol v1.39.4-0.20250806031641-1edabe8e86df
17-
github.com/livekit/server-sdk-go/v2 v2.9.3-0.20250806083916-a2f01818f35f
17+
github.com/livekit/protocol v1.39.4-0.20250721114233-52633eee694f
18+
github.com/livekit/server-sdk-go/v2 v2.9.2
1819
github.com/moby/buildkit v0.22.0
20+
github.com/moby/patternmatcher v0.6.0
1921
github.com/pion/rtcp v1.2.15
2022
github.com/pion/rtp v1.8.21
2123
github.com/pion/webrtc/v4 v4.1.3
@@ -24,7 +26,7 @@ require (
2426
github.com/schollz/progressbar/v3 v3.18.0
2527
github.com/stretchr/testify v1.10.0
2628
github.com/twitchtv/twirp v8.1.3+incompatible
27-
github.com/urfave/cli/v3 v3.3.3
29+
github.com/urfave/cli/v3 v3.3.8
2830
go.uber.org/atomic v1.11.0
2931
golang.org/x/sync v0.16.0
3032
golang.org/x/time v0.11.0
@@ -42,8 +44,10 @@ require (
4244
github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 // indirect
4345
github.com/Ladicle/tabwriter v1.0.0 // indirect
4446
github.com/Microsoft/go-winio v0.6.2 // indirect
47+
github.com/Microsoft/hcsshim v0.13.0 // indirect
4548
github.com/ProtonMail/go-crypto v1.3.0 // indirect
4649
github.com/alecthomas/chroma/v2 v2.19.0 // indirect
50+
github.com/anchore/go-struct-converter v0.0.0-20230627203149-c72ef8859ca9 // indirect
4751
github.com/antlr4-go/antlr/v4 v4.13.1 // indirect
4852
github.com/atotto/clipboard v0.1.4 // indirect
4953
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
@@ -54,15 +58,15 @@ require (
5458
github.com/cespare/xxhash/v2 v2.3.0 // indirect
5559
github.com/chainguard-dev/git-urls v1.0.2 // indirect
5660
github.com/charmbracelet/bubbles v0.21.0 // indirect
57-
github.com/charmbracelet/bubbletea v1.3.4 // indirect
61+
github.com/charmbracelet/bubbletea v1.3.5 // indirect
5862
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect
5963
github.com/charmbracelet/x/ansi v0.8.0 // indirect
6064
github.com/charmbracelet/x/cellbuf v0.0.13 // indirect
6165
github.com/charmbracelet/x/exp/strings v0.0.0-20240809174237-9ab0ca04ce0c // indirect
6266
github.com/charmbracelet/x/term v0.2.1 // indirect
6367
github.com/cloudflare/circl v1.6.1 // indirect
6468
github.com/containerd/console v1.0.4 // indirect
65-
github.com/containerd/containerd/api v1.8.0 // indirect
69+
github.com/containerd/containerd/api v1.9.0 // indirect
6670
github.com/containerd/containerd/v2 v2.0.5 // indirect
6771
github.com/containerd/continuity v0.4.5 // indirect
6872
github.com/containerd/errdefs v1.0.0 // indirect
@@ -77,6 +81,8 @@ require (
7781
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
7882
github.com/distribution/reference v0.6.0 // indirect
7983
github.com/dlclark/regexp2 v1.11.5 // indirect
84+
github.com/docker/cli v28.2.2+incompatible // indirect
85+
github.com/docker/docker v28.2.2+incompatible // indirect
8086
github.com/dominikbraun/graph v0.23.0 // indirect
8187
github.com/dustin/go-humanize v1.0.1 // indirect
8288
github.com/elliotchance/orderedmap/v3 v3.1.0 // indirect
@@ -104,7 +110,7 @@ require (
104110
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
105111
github.com/google/uuid v1.6.0 // indirect
106112
github.com/gorilla/websocket v1.5.3 // indirect
107-
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect
113+
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 // indirect
108114
github.com/hashicorp/errwrap v1.1.0 // indirect
109115
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
110116
github.com/hashicorp/go-multierror v1.1.1 // indirect
@@ -118,7 +124,7 @@ require (
118124
github.com/lithammer/shortuuid/v4 v4.2.0 // indirect
119125
github.com/livekit/mageutil v0.0.0-20250511045019-0f1ff63f7731 // indirect
120126
github.com/livekit/mediatransportutil v0.0.0-20250519131108-fb90f5acfded // indirect
121-
github.com/livekit/psrpc v0.6.1-0.20250726180611-3915e005e741 // indirect
127+
github.com/livekit/psrpc v0.6.1-0.20250511053145-465289d72c3c // indirect
122128
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
123129
github.com/magefile/mage v1.15.0 // indirect
124130
github.com/mattn/go-colorable v0.1.14 // indirect
@@ -129,19 +135,19 @@ require (
129135
github.com/mitchellh/hashstructure/v2 v2.0.2 // indirect
130136
github.com/moby/docker-image-spec v1.3.1 // indirect
131137
github.com/moby/locker v1.0.1 // indirect
132-
github.com/moby/patternmatcher v0.6.0 // indirect
133138
github.com/moby/sys/signal v0.7.1 // indirect
134139
github.com/morikuni/aec v1.0.0 // indirect
135140
github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
136141
github.com/muesli/cancelreader v0.2.2 // indirect
137142
github.com/muesli/termenv v0.16.0 // indirect
138143
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
139-
github.com/nats-io/nats.go v1.44.0 // indirect
144+
github.com/nats-io/nats.go v1.43.0 // indirect
140145
github.com/nats-io/nkeys v0.4.11 // indirect
141146
github.com/nats-io/nuid v1.0.1 // indirect
142147
github.com/opencontainers/go-digest v1.0.0 // indirect
143148
github.com/opencontainers/image-spec v1.1.1 // indirect
144-
github.com/package-url/packageurl-go v0.1.3 // indirect
149+
github.com/opencontainers/runtime-spec v1.2.1 // indirect
150+
github.com/opencontainers/selinux v1.12.0 // indirect
145151
github.com/pion/datachannel v1.5.10 // indirect
146152
github.com/pion/dtls/v3 v3.0.6 // indirect
147153
github.com/pion/ice/v4 v4.0.10 // indirect
@@ -163,14 +169,15 @@ require (
163169
github.com/prometheus/common v0.64.0 // indirect
164170
github.com/prometheus/procfs v0.16.1 // indirect
165171
github.com/puzpuzpuz/xsync/v3 v3.5.1 // indirect
166-
github.com/redis/go-redis/v9 v9.12.0 // indirect
172+
github.com/redis/go-redis/v9 v9.11.0 // indirect
167173
github.com/rivo/uniseg v0.4.7 // indirect
168174
github.com/sajari/fuzzy v1.0.0 // indirect
169175
github.com/secure-systems-lab/go-securesystemslib v0.4.0 // indirect
170176
github.com/sergi/go-diff v1.4.0 // indirect
171177
github.com/shibumi/go-pathspec v1.3.0 // indirect
172178
github.com/sirupsen/logrus v1.9.3 // indirect
173179
github.com/skeema/knownhosts v1.3.1 // indirect
180+
github.com/spdx/tools-golang v0.5.5 // indirect
174181
github.com/stoewer/go-strcase v1.3.1 // indirect
175182
github.com/stretchr/objx v0.5.2 // indirect
176183
github.com/tonistiigi/fsutil v0.0.0-20250417144416-3f76f8130144 // indirect
@@ -185,26 +192,25 @@ require (
185192
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
186193
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.56.0 // indirect
187194
go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.56.0 // indirect
188-
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 // indirect
189-
go.opentelemetry.io/otel v1.37.0 // indirect
190-
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 // indirect
191-
go.opentelemetry.io/otel/metric v1.37.0 // indirect
195+
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.61.0 // indirect
196+
go.opentelemetry.io/otel v1.36.0 // indirect
197+
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 // indirect
198+
go.opentelemetry.io/otel/metric v1.36.0 // indirect
192199
go.opentelemetry.io/otel/sdk v1.36.0 // indirect
193-
go.opentelemetry.io/otel/trace v1.37.0 // indirect
194-
go.opentelemetry.io/proto/otlp v1.3.1 // indirect
200+
go.opentelemetry.io/otel/trace v1.36.0 // indirect
201+
go.opentelemetry.io/proto/otlp v1.5.0 // indirect
195202
go.uber.org/multierr v1.11.0 // indirect
196203
go.uber.org/zap v1.27.0 // indirect
197204
go.uber.org/zap/exp v0.3.0 // indirect
198205
golang.org/x/crypto v0.40.0 // indirect
199206
golang.org/x/exp v0.0.0-20250718183923-645b1fa84792 // indirect
200-
golang.org/x/mod v0.26.0 // indirect
201207
golang.org/x/net v0.42.0 // indirect
202208
golang.org/x/sys v0.34.0 // indirect
203209
golang.org/x/term v0.33.0 // indirect
204210
golang.org/x/text v0.27.0 // indirect
205-
google.golang.org/genproto/googleapis/api v0.0.0-20250804133106-a7a43d27e69b // indirect
206-
google.golang.org/genproto/googleapis/rpc v0.0.0-20250804133106-a7a43d27e69b // indirect
207-
google.golang.org/grpc v1.74.2 // indirect
211+
google.golang.org/genproto/googleapis/api v0.0.0-20250721164621-a45f3dfb1074 // indirect
212+
google.golang.org/genproto/googleapis/rpc v0.0.0-20250721164621-a45f3dfb1074 // indirect
213+
google.golang.org/grpc v1.73.0 // indirect
208214
gopkg.in/inf.v0 v0.9.1 // indirect
209215
gopkg.in/warnings.v0 v0.1.2 // indirect
210216
mvdan.cc/sh/v3 v3.12.0 // indirect

0 commit comments

Comments
 (0)