@@ -31,32 +31,22 @@ import (
3131 "github.com/urfave/cli/v3"
3232
3333 "github.com/livekit/livekit-cli/v2/pkg/agentfs"
34+ "github.com/livekit/livekit-cli/v2/pkg/config"
3435 "github.com/livekit/livekit-cli/v2/pkg/util"
3536 lkproto "github.com/livekit/protocol/livekit"
3637 "github.com/livekit/protocol/logger"
3738 lksdk "github.com/livekit/server-sdk-go/v2"
3839)
3940
4041const (
41- clientDefaults_CPU = "1"
42- clientDefaults_Replicas = 1
43- clientDefaults_MaxReplicas = 10
44- cloudAgentsBetaSignupURL = "https://forms.gle/GkGNNTiMt2qyfnu78"
42+ cloudAgentsBetaSignupURL = "https://forms.gle/GkGNNTiMt2qyfnu78"
4543)
4644
4745var (
48- tomlFlag = & cli.StringFlag {
49- Name : "toml" ,
50- Usage : "TOML `FILE` to use in the working directory" ,
51- Value : agentfs .AgentTOMLFile ,
52- Destination : & tomlFilename ,
53- Required : false ,
54- }
55-
5646 nameFlag = func (required bool ) * cli.StringFlag {
5747 return & cli.StringFlag {
5848 Name : "name" ,
59- Usage : fmt .Sprintf ("`NAME` of the agent. If unset, and the %s file is present, will use the name found there." , agentfs . AgentTOMLFile ),
49+ Usage : fmt .Sprintf ("`NAME` of the agent. If unset, and the %s file is present, will use the name found there." , config . LiveKitTOMLFile ),
6050 Required : required ,
6151 }
6252 }
@@ -108,18 +98,16 @@ var (
10898 Required : false ,
10999 Value : false ,
110100 },
111- tomlFlag ,
112101 },
113102 ArgsUsage : "[working-dir]" ,
114103 },
115104 {
116105 Name : "config" ,
117- Usage : fmt .Sprintf ("Creates a %s in the working directory for an existing agent." , agentfs . AgentTOMLFile ),
106+ Usage : fmt .Sprintf ("Creates a %s in the working directory for an existing agent." , config . LiveKitTOMLFile ),
118107 Before : createAgentClient ,
119108 Action : createAgentConfig ,
120109 Flags : []cli.Flag {
121110 nameFlag (false ),
122- tomlFlag ,
123111 },
124112 ArgsUsage : "[working-dir]" ,
125113 },
@@ -131,7 +119,6 @@ var (
131119 Flags : []cli.Flag {
132120 secretsFlag ,
133121 secretsFileFlag ,
134- tomlFlag ,
135122 },
136123 ArgsUsage : "[working-dir]" ,
137124 },
@@ -142,7 +129,6 @@ var (
142129 Action : getAgentStatus ,
143130 Flags : []cli.Flag {
144131 nameFlag (false ),
145- tomlFlag ,
146132 },
147133 ArgsUsage : "[working-dir]" ,
148134 },
@@ -154,7 +140,6 @@ var (
154140 Flags : []cli.Flag {
155141 secretsFlag ,
156142 secretsFileFlag ,
157- tomlFlag ,
158143 },
159144 ArgsUsage : "[working-dir]" ,
160145 },
@@ -171,7 +156,6 @@ var (
171156 Required : true ,
172157 },
173158 nameFlag (false ),
174- tomlFlag ,
175159 },
176160 ArgsUsage : "[working-dir]" ,
177161 },
@@ -184,7 +168,6 @@ var (
184168 Flags : []cli.Flag {
185169 nameFlag (false ),
186170 logTypeFlag ,
187- tomlFlag ,
188171 },
189172 ArgsUsage : "[working-dir]" ,
190173 },
@@ -196,7 +179,6 @@ var (
196179 Aliases : []string {"destroy" },
197180 Flags : []cli.Flag {
198181 nameFlag (false ),
199- tomlFlag ,
200182 },
201183 ArgsUsage : "[working-dir]" ,
202184 },
@@ -207,7 +189,6 @@ var (
207189 Action : listAgentVersions ,
208190 Flags : []cli.Flag {
209191 nameFlag (false ),
210- tomlFlag ,
211192 },
212193 ArgsUsage : "[working-dir]" ,
213194 },
@@ -227,7 +208,6 @@ var (
227208 Action : listAgentSecrets ,
228209 Flags : []cli.Flag {
229210 nameFlag (false ),
230- tomlFlag ,
231211 },
232212 ArgsUsage : "[working-dir]" ,
233213 },
@@ -240,7 +220,6 @@ var (
240220 secretsFlag ,
241221 secretsFileFlag ,
242222 nameFlag (false ),
243- tomlFlag ,
244223 & cli.BoolFlag {
245224 Name : "overwrite" ,
246225 Usage : "If set, will overwrite existing secrets" ,
@@ -255,8 +234,6 @@ var (
255234 }
256235 subdomainPattern = regexp .MustCompile (`^(?:https?|wss?)://([^.]+)\.` )
257236 agentsClient * lksdk.AgentClient
258- tomlFilename = agentfs .AgentTOMLFile
259- workingDir = "."
260237 ignoredSecrets = []string {
261238 "LIVEKIT_API_KEY" ,
262239 "LIVEKIT_API_SECRET" ,
@@ -266,7 +243,7 @@ var (
266243
267244func createAgentClient (ctx context.Context , cmd * cli.Command ) (context.Context , error ) {
268245 var err error
269- var agentConfig * agentfs. AgentTOML
246+ var lkConfig * config. LiveKitTOML
270247
271248 if _ , err := requireProject (ctx , cmd ); err != nil {
272249 return ctx , err
@@ -277,14 +254,17 @@ func createAgentClient(ctx context.Context, cmd *cli.Command) (context.Context,
277254 }
278255
279256 // Verify that the project and agent config match, if it exists.
280- agentConfig , configExists , err := agentfs .LoadTomlFile (workingDir , tomlFilename )
257+ lkConfig , configExists , err := config .LoadTomlFile (workingDir , tomlFilename )
258+ if err != nil {
259+ fmt .Println (err .Error ())
260+ }
281261 if configExists {
282262 projectSubdomainMatch := subdomainPattern .FindStringSubmatch (project .URL )
283263 if len (projectSubdomainMatch ) < 2 {
284264 return nil , fmt .Errorf ("invalid project URL [%s]" , project .URL )
285265 }
286- if projectSubdomainMatch [1 ] != agentConfig . ProjectSubdomain {
287- return nil , fmt .Errorf ("project does not match agent subdomain [%s]" , agentConfig . ProjectSubdomain )
266+ if projectSubdomainMatch [1 ] != lkConfig . Project . Subdomain {
267+ return nil , fmt .Errorf ("project does not match agent subdomain [%s]" , lkConfig . Project . Subdomain )
288268 }
289269 } else {
290270 if ! errors .Is (err , os .ErrNotExist ) {
@@ -320,18 +300,18 @@ func createAgent(ctx context.Context, cmd *cli.Command) error {
320300 }
321301
322302 logger .Debugw ("Creating agent" , "working-dir" , workingDir )
323- agentConfig , configExists , err := agentfs .LoadTomlFile (workingDir , tomlFilename )
303+ lkConfig , configExists , err := config .LoadTomlFile (workingDir , tomlFilename )
324304 if err != nil && configExists {
325305 return err
326306 }
327307
328308 name := cmd .String ("name" )
329309 silent := cmd .Bool ("silent" )
330310
331- if configExists {
311+ if configExists && lkConfig . Agent != nil {
332312 // If name was set via command line, it must match the name in the config.
333- if name != "" && agentConfig .Name != name {
334- return fmt .Errorf ("agent name passed in command line: [%s] does not match name in [%s]: [%s]" , name , tomlFilename , agentConfig .Name )
313+ if name != "" && lkConfig . Agent .Name != name {
314+ return fmt .Errorf ("agent name passed in command line: [%s] does not match name in [%s]: [%s]" , name , tomlFilename , lkConfig . Agent .Name )
335315 }
336316
337317 if ! silent {
@@ -359,30 +339,25 @@ func createAgent(ctx context.Context, cmd *cli.Command) error {
359339 }
360340 defer f .Close ()
361341
362- agentConfig = & agentfs.AgentTOML {
363- ProjectSubdomain : subdomainMatches [1 ],
364- Name : name ,
365- CPU : clientDefaults_CPU ,
366- Replicas : clientDefaults_Replicas ,
367- MaxReplicas : clientDefaults_MaxReplicas ,
368- }
342+ lkConfig = config .NewLiveKitTOML (subdomainMatches [1 ]).
343+ WithDefaultAgent (name )
369344
370345 encoder := toml .NewEncoder (f )
371- if err := encoder .Encode (agentConfig ); err != nil {
346+ if err := encoder .Encode (lkConfig ); err != nil {
372347 return fmt .Errorf ("error encoding TOML: %w" , err )
373348 }
374349 fmt .Printf ("Creating config file [%s]\n " , util .Accented (tomlFilename ))
375350 }
376351
377352 if name == "" {
378- if agentConfig .Name == "" {
353+ if lkConfig . Agent .Name == "" {
379354 return fmt .Errorf ("name is required" )
380355 }
381356 } else {
382- agentConfig .Name = name
357+ lkConfig . Agent .Name = name
383358 }
384359 if ! silent {
385- fmt .Printf ("Creating agent [%s]\n " , util .Accented (agentConfig .Name ))
360+ fmt .Printf ("Creating agent [%s]\n " , util .Accented (lkConfig . Agent .Name ))
386361 }
387362
388363 secrets , err := requireSecrets (ctx , cmd , true , false )
@@ -395,11 +370,11 @@ func createAgent(ctx context.Context, cmd *cli.Command) error {
395370 }
396371
397372 req := & lkproto.CreateAgentRequest {
398- AgentName : agentConfig .Name ,
373+ AgentName : lkConfig . Agent .Name ,
399374 Secrets : secrets ,
400- Replicas : int32 (agentConfig .Replicas ),
401- MaxReplicas : int32 (agentConfig .MaxReplicas ),
402- CpuReq : string (agentConfig .CPU ),
375+ Replicas : int32 (lkConfig . Agent .Replicas ),
376+ MaxReplicas : int32 (lkConfig . Agent .MaxReplicas ),
377+ CpuReq : string (lkConfig . Agent .CPU ),
403378 }
404379
405380 resp , err := agentsClient .CreateAgent (ctx , req )
@@ -412,13 +387,13 @@ func createAgent(ctx context.Context, cmd *cli.Command) error {
412387 return err
413388 }
414389
415- err = agentfs .UploadTarball (workingDir , resp .PresignedUrl , []string {agentfs . AgentTOMLFile })
390+ err = agentfs .UploadTarball (workingDir , resp .PresignedUrl , []string {config . LiveKitTOMLFile })
416391 if err != nil {
417392 return err
418393 }
419394
420395 fmt .Printf ("Created agent [%s] with ID [%s]\n " , util .Accented (resp .AgentName ), util .Accented (resp .AgentId ))
421- err = agentfs .Build (ctx , resp .AgentId , agentConfig .Name , "deploy" , project )
396+ err = agentfs .Build (ctx , resp .AgentId , lkConfig . Agent .Name , "deploy" , project )
422397 if err != nil {
423398 return err
424399 }
@@ -439,7 +414,7 @@ func createAgent(ctx context.Context, cmd *cli.Command) error {
439414 return err
440415 } else if viewLogs {
441416 fmt .Println ("Tailing logs...safe to exit at any time" )
442- return agentfs .LogHelper (ctx , "" , agentConfig .Name , "deploy" , project )
417+ return agentfs .LogHelper (ctx , "" , lkConfig . Agent .Name , "deploy" , project )
443418 }
444419 }
445420 return nil
@@ -502,12 +477,12 @@ func createAgentConfig(ctx context.Context, cmd *cli.Command) error {
502477
503478 agent := response .Agents [0 ]
504479 regionAgent := agent .AgentDeployments [0 ]
505- agentConfig := & agentfs. AgentTOML {
506- ProjectSubdomain : matches [ 1 ],
507- Name : agent .AgentName ,
508- CPU : agentfs .CPUString (regionAgent .CpuReq ),
509- Replicas : int (regionAgent .Replicas ),
510- MaxReplicas : int (regionAgent .MaxReplicas ),
480+ lkConfig := config . NewLiveKitTOML ( matches [ 1 ])
481+ lkConfig . Agent = & config. LiveKitTOMLAgentConfig {
482+ Name : agent .AgentName ,
483+ CPU : config .CPUString (regionAgent .CpuReq ),
484+ Replicas : int (regionAgent .Replicas ),
485+ MaxReplicas : int (regionAgent .MaxReplicas ),
511486 }
512487
513488 f , err := os .Create (tomlFilename )
@@ -516,7 +491,7 @@ func createAgentConfig(ctx context.Context, cmd *cli.Command) error {
516491 }
517492 defer f .Close ()
518493
519- if err := toml .NewEncoder (f ).Encode (agentConfig ); err != nil {
494+ if err := toml .NewEncoder (f ).Encode (lkConfig ); err != nil {
520495 return fmt .Errorf ("error encoding TOML: %w" , err )
521496 }
522497
@@ -525,19 +500,22 @@ func createAgentConfig(ctx context.Context, cmd *cli.Command) error {
525500}
526501
527502func deployAgent (ctx context.Context , cmd * cli.Command ) error {
528- agentConfig , configExists , err := agentfs .LoadTomlFile (workingDir , tomlFilename )
503+ lkConfig , configExists , err := config .LoadTomlFile (workingDir , tomlFilename )
529504 if err != nil && configExists {
530505 return err
531506 }
532507 if ! configExists {
533508 return fmt .Errorf ("config file [%s] required to update agent" , util .Accented (tomlFilename ))
534509 }
510+ if ! lkConfig .HasAgent () {
511+ return fmt .Errorf ("no agent config found in [%s]" , tomlFilename )
512+ }
535513
536514 req := & lkproto.DeployAgentRequest {
537- AgentName : agentConfig .Name ,
538- Replicas : int32 (agentConfig .Replicas ),
539- CpuReq : string (agentConfig .CPU ),
540- MaxReplicas : int32 (agentConfig .MaxReplicas ),
515+ AgentName : lkConfig . Agent .Name ,
516+ Replicas : int32 (lkConfig . Agent .Replicas ),
517+ CpuReq : string (lkConfig . Agent .CPU ),
518+ MaxReplicas : int32 (lkConfig . Agent .MaxReplicas ),
541519 }
542520
543521 secrets , err := requireSecrets (ctx , cmd , false , true )
@@ -563,13 +541,13 @@ func deployAgent(ctx context.Context, cmd *cli.Command) error {
563541 }
564542
565543 presignedUrl := resp .PresignedUrl
566- err = agentfs .UploadTarball (workingDir , presignedUrl , []string {agentfs . AgentTOMLFile })
544+ err = agentfs .UploadTarball (workingDir , presignedUrl , []string {config . LiveKitTOMLFile })
567545 if err != nil {
568546 return err
569547 }
570548
571549 fmt .Printf ("Updated agent [%s]\n " , util .Accented (resp .AgentId ))
572- err = agentfs .Build (ctx , resp .AgentId , agentConfig .Name , "update" , project )
550+ err = agentfs .Build (ctx , resp .AgentId , lkConfig . Agent .Name , "update" , project )
573551 if err != nil {
574552 return err
575553 }
@@ -638,19 +616,22 @@ func getAgentStatus(ctx context.Context, cmd *cli.Command) error {
638616}
639617
640618func updateAgent (ctx context.Context , cmd * cli.Command ) error {
641- agentConfig , configExists , err := agentfs .LoadTomlFile (workingDir , tomlFilename )
619+ lkConfig , configExists , err := config .LoadTomlFile (workingDir , tomlFilename )
642620 if err != nil && configExists {
643621 return err
644622 }
645623 if ! configExists {
646624 return fmt .Errorf ("config file [%s] required to update agent" , tomlFilename )
647625 }
626+ if ! lkConfig .HasAgent () {
627+ return fmt .Errorf ("no agent config found in [%s]" , tomlFilename )
628+ }
648629
649630 req := & lkproto.UpdateAgentRequest {
650- AgentName : agentConfig .Name ,
651- Replicas : int32 (agentConfig .Replicas ),
652- CpuReq : string (agentConfig .CPU ),
653- MaxReplicas : int32 (agentConfig .MaxReplicas ),
631+ AgentName : lkConfig . Agent .Name ,
632+ Replicas : int32 (lkConfig . Agent .Replicas ),
633+ CpuReq : string (lkConfig . Agent .CPU ),
634+ MaxReplicas : int32 (lkConfig . Agent .MaxReplicas ),
654635 }
655636
656637 secrets , err := requireSecrets (ctx , cmd , false , true )
@@ -672,7 +653,7 @@ func updateAgent(ctx context.Context, cmd *cli.Command) error {
672653 }
673654
674655 if resp .Success {
675- fmt .Printf ("Updated agent [%s]\n " , util .Accented (agentConfig .Name ))
656+ fmt .Printf ("Updated agent [%s]\n " , util .Accented (lkConfig . Agent .Name ))
676657 return nil
677658 }
678659
@@ -920,15 +901,18 @@ func updateAgentSecrets(ctx context.Context, cmd *cli.Command) error {
920901func getAgentName (cmd * cli.Command , agentDir string , tomlFileName string ) (string , error ) {
921902 agentName := cmd .String ("name" )
922903 if agentName == "" {
923- agentConfig , configExists , err := agentfs .LoadTomlFile (agentDir , tomlFileName )
904+ lkConfig , configExists , err := config .LoadTomlFile (agentDir , tomlFileName )
924905 if err != nil && configExists {
925906 return "" , err
926907 }
927908 if ! configExists {
928909 return "" , fmt .Errorf ("config file [%s] required to update agent" , tomlFileName )
929910 }
911+ if ! lkConfig .HasAgent () {
912+ return "" , fmt .Errorf ("no agent config found in [%s]" , tomlFileName )
913+ }
930914
931- agentName = agentConfig .Name
915+ agentName = lkConfig . Agent .Name
932916 }
933917
934918 if agentName == "" {
0 commit comments