diff --git a/cmd/lk/agent.go b/cmd/lk/agent.go index fe373a56..4b0afc5e 100644 --- a/cmd/lk/agent.go +++ b/cmd/lk/agent.go @@ -117,6 +117,14 @@ var ( Hidden: true, } + agentNameFlag = func(required bool) *cli.StringFlag { + return &cli.StringFlag{ + Name: "name", + Usage: "Name of the agent. Needs to be unique within the project. Will be used when dispatching agent to rooms", + Required: required, + } + } + AgentCommands = []*cli.Command{ { Name: "agent", @@ -166,6 +174,7 @@ var ( Flags: []cli.Flag{ regionFlag, installFlag, + agentNameFlag(false), }, ArgsUsage: "[AGENT-NAME]", DisableSliceFlagSeparator: true, @@ -176,6 +185,7 @@ var ( Action: createAgent, Before: createAgentClient, Flags: []cli.Flag{ + agentNameFlag(true), secretsFlag, secretsFileFlag, secretsMountFlag, @@ -254,6 +264,7 @@ var ( Before: createAgentClient, Action: updateAgent, Flags: []cli.Flag{ + agentNameFlag(false), secretsFlag, secretsFileFlag, secretsMountFlag, @@ -452,7 +463,10 @@ func initAgent(ctx context.Context, cmd *cli.Command) error { logger.Debugw("Initializing agent project", "working-dir", workingDir) - appName = cmd.Args().First() + appName = cmd.String("name") + if appName == "" { + appName = cmd.Args().First() + } if appName == "" { appName = project.Name } @@ -572,6 +586,16 @@ func createAgent(ctx context.Context, cmd *cli.Command) error { return err } + // --name: required on `lk agent create`, optional on `init` (falls back to [AGENT-NAME] or project name). + agentName := cmd.String("name") + if agentName == "" && cmd.Name == "init" { + if n := cmd.Args().First(); n != "" { + agentName = n + } else { + agentName = project.Name + } + } + settingsMap, err := getClientSettings(ctx, cmd.Bool("silent")) if err != nil { return err @@ -588,7 +612,7 @@ func createAgent(ctx context.Context, cmd *cli.Command) error { buildContext, cancel := context.WithTimeout(ctx, buildTimeout) defer cancel() regions := []string{region} - agentID, err := agentsClient.RegisterAgent(buildContext, secrets, regions) + agentID, err := agentsClient.RegisterAgent(buildContext, agentName, secrets, regions) if err != nil { if twerr, ok := err.(twirp.Error); ok { return fmt.Errorf("unable to create agent: %s", twerr.Msg()) @@ -596,6 +620,7 @@ func createAgent(ctx context.Context, cmd *cli.Command) error { return fmt.Errorf("unable to create agent: %w", err) } lkConfig.Agent.ID = agentID + lkConfig.Agent.Name = agentName if err := lkConfig.SaveTOMLFile(workingDir, tomlFilename); err != nil { return err } @@ -631,7 +656,7 @@ func createAgent(ctx context.Context, cmd *cli.Command) error { regions := []string{region} excludeFiles := []string{fmt.Sprintf("**/%s", config.LiveKitTOMLFile)} - resp, err := agentsClient.CreateAgent(buildContext, os.DirFS(workingDir), secrets, regions, excludeFiles, os.Stderr) + resp, err := agentsClient.CreateAgent(buildContext, agentName, os.DirFS(workingDir), secrets, regions, excludeFiles, os.Stderr) if err != nil { if errors.Is(err, context.DeadlineExceeded) { return fmt.Errorf("build timed out possibly due to large image size") @@ -643,6 +668,11 @@ func createAgent(ctx context.Context, cmd *cli.Command) error { } lkConfig.Agent.ID = resp.AgentId + if n := resp.GetAgentName(); n != "" { + lkConfig.Agent.Name = n + } else if agentName != "" { + lkConfig.Agent.Name = agentName + } if err := lkConfig.SaveTOMLFile(workingDir, tomlFilename); err != nil { return err } @@ -665,7 +695,7 @@ func createAgent(ctx context.Context, cmd *cli.Command) error { return err } else if viewLogs { fmt.Println("Tailing runtime logs...safe to exit at any time") - return agentsClient.StreamLogs(ctx, "deploy", lkConfig.Agent.ID, os.Stdout, resp.ServerRegions[0]) + return agentsClient.StreamLogs(ctx, "deploy", lkConfig.Agent.ID, "", os.Stdout, resp.ServerRegions[0]) } } return nil @@ -737,7 +767,8 @@ func createAgentConfig(ctx context.Context, cmd *cli.Command) error { agent := response.Agents[0] lkConfig := config.NewLiveKitTOML(matches[1]) lkConfig.Agent = &config.LiveKitTOMLAgentConfig{ - ID: agent.AgentId, + ID: agent.AgentId, + Name: agent.GetAgentName(), } if err := lkConfig.SaveTOMLFile(workingDir, tomlFilename); err != nil { @@ -935,6 +966,9 @@ func updateAgent(ctx context.Context, cmd *cli.Command) error { req := &lkproto.UpdateAgentRequest{ AgentId: lkConfig.Agent.ID, } + if n := cmd.String("name"); n != "" { + req.AgentName = n + } secrets, err := requireSecrets(ctx, cmd, false, true) if err != nil { @@ -958,8 +992,11 @@ func updateAgent(ctx context.Context, cmd *cli.Command) error { } if resp.Success { + if req.AgentName != "" { + lkConfig.Agent.Name = req.AgentName + } fmt.Printf("Updated agent [%s]\n", util.Accented(lkConfig.Agent.ID)) - err = lkConfig.SaveTOMLFile("", tomlFilename) + err = lkConfig.SaveTOMLFile(workingDir, tomlFilename) return err } @@ -1014,8 +1051,8 @@ func getLogs(ctx context.Context, cmd *cli.Command) error { if len(response.Agents) == 0 { return fmt.Errorf("no agent deployments found") } - - return agentsClient.StreamLogs(ctx, cmd.String("log-type"), agentID, os.Stdout, response.Agents[0].AgentDeployments[0].ServerRegion) + d := response.Agents[0].AgentDeployments[0] + return agentsClient.StreamLogs(ctx, cmd.String("log-type"), agentID, d.GetEnvironment(), os.Stdout, d.GetServerRegion()) } func deleteAgent(ctx context.Context, cmd *cli.Command) error { diff --git a/go.mod b/go.mod index 56a7e907..e13ba72b 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/google/go-containerregistry v0.20.6 github.com/google/go-querystring v1.2.0 github.com/joho/godotenv v1.5.1 - github.com/livekit/protocol v1.45.4-0.20260417173102-5d4f88f73b7c + github.com/livekit/protocol v1.45.5-0.20260423163244-347de5a2ef78 github.com/livekit/server-sdk-go/v2 v2.16.2 github.com/mattn/go-isatty v0.0.21 github.com/moby/patternmatcher v0.6.1 @@ -23,7 +23,7 @@ require ( github.com/pelletier/go-toml v1.9.5 github.com/pion/rtcp v1.2.16 github.com/pion/rtp v1.10.1 - github.com/pion/webrtc/v4 v4.2.9 + github.com/pion/webrtc/v4 v4.2.11 github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c github.com/pkg/errors v0.9.1 github.com/stretchr/testify v1.11.1 @@ -37,6 +37,10 @@ require ( k8s.io/apimachinery v0.34.1 ) +replace github.com/livekit/server-sdk-go/v2 => ../server-sdk-go + +replace github.com/livekit/protocol => ../protocol + require ( buf.build/gen/go/bufbuild/protovalidate/protocolbuffers/go v1.36.11-20260209202127-80ab13bee0bf.1 // indirect buf.build/go/protovalidate v1.1.3 // indirect @@ -189,12 +193,12 @@ require ( github.com/pierrec/lz4/v4 v4.1.26 // indirect github.com/pion/datachannel v1.6.0 // indirect github.com/pion/dtls/v3 v3.1.2 // indirect - github.com/pion/ice/v4 v4.2.1 // indirect + github.com/pion/ice/v4 v4.2.2 // indirect github.com/pion/interceptor v0.1.44 // indirect github.com/pion/logging v0.2.4 // indirect github.com/pion/mdns/v2 v2.1.0 // indirect github.com/pion/randutil v0.1.0 // indirect - github.com/pion/sctp v1.9.3 // indirect + github.com/pion/sctp v1.9.4 // indirect github.com/pion/sdp/v3 v3.0.18 // indirect github.com/pion/srtp/v3 v3.0.10 // indirect github.com/pion/stun/v3 v3.1.1 // indirect diff --git a/go.sum b/go.sum index 7edf7b3b..ead1db9c 100644 --- a/go.sum +++ b/go.sum @@ -366,12 +366,8 @@ github.com/livekit/mageutil v0.0.0-20250511045019-0f1ff63f7731 h1:9x+U2HGLrSw5AT github.com/livekit/mageutil v0.0.0-20250511045019-0f1ff63f7731/go.mod h1:Rs3MhFwutWhGwmY1VQsygw28z5bWcnEYmS1OG9OxjOQ= github.com/livekit/mediatransportutil v0.0.0-20260309115634-0e2e24b36ee8 h1:coWig9fKxdb/nwOaIoGUUAogso12GblAJh/9SA9hcxk= github.com/livekit/mediatransportutil v0.0.0-20260309115634-0e2e24b36ee8/go.mod h1:RCd46PT+6sEztld6XpkCrG1xskb0u3SqxIjy4G897Ss= -github.com/livekit/protocol v1.45.4-0.20260417173102-5d4f88f73b7c h1:TusqCkqnqw/9B6BVJhFjFI8D/1Zy6z4oBsk1ehbpZIc= -github.com/livekit/protocol v1.45.4-0.20260417173102-5d4f88f73b7c/go.mod h1:e6QdWDkfot+M2nRh0eitJUS0ZLuwvKCsfiz2pWWSG3s= github.com/livekit/psrpc v0.7.1 h1:ms37az0QTD3UXIWuUC5D/SkmKOlRMVRsI261eBWu/Vw= github.com/livekit/psrpc v0.7.1/go.mod h1:bZ4iHFQptTkbPnB0LasvRNu/OBYXEu1NA6O5BMFo9kk= -github.com/livekit/server-sdk-go/v2 v2.16.2 h1:eQe24cka3X+5zUivezyL72nwtAJTWFXgibeiyJ/Jm+Y= -github.com/livekit/server-sdk-go/v2 v2.16.2/go.mod h1:/HOUG9AXJeCbMCdtw0dr37AB+3xXUlj/OLeXS/0p7rA= github.com/lucasb-eyer/go-colorful v1.4.0 h1:UtrWVfLdarDgc44HcS7pYloGHJUjHV/4FwW4TvVgFr4= github.com/lucasb-eyer/go-colorful v1.4.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/magefile/mage v1.17.0 h1:dS4tkq997Ism03akafC8509iqDjeE7TNTexI25Y7sXM= @@ -452,8 +448,8 @@ github.com/pion/datachannel v1.6.0 h1:XecBlj+cvsxhAMZWFfFcPyUaDZtd7IJvrXqlXD/53i github.com/pion/datachannel v1.6.0/go.mod h1:ur+wzYF8mWdC+Mkis5Thosk+u/VOL287apDNEbFpsIk= github.com/pion/dtls/v3 v3.1.2 h1:gqEdOUXLtCGW+afsBLO0LtDD8GnuBBjEy6HRtyofZTc= github.com/pion/dtls/v3 v3.1.2/go.mod h1:Hw/igcX4pdY69z1Hgv5x7wJFrUkdgHwAn/Q/uo7YHRo= -github.com/pion/ice/v4 v4.2.1 h1:XPRYXaLiFq3LFDG7a7bMrmr3mFr27G/gtXN3v/TVfxY= -github.com/pion/ice/v4 v4.2.1/go.mod h1:2quLV1S5v1tAx3VvAJaH//KGitRXvo4RKlX6D3tnN+c= +github.com/pion/ice/v4 v4.2.2 h1:dQJzzcgTFHDYyV3BoCfjPeX+JEtr58BWPi4PGyo6Vjg= +github.com/pion/ice/v4 v4.2.2/go.mod h1:2quLV1S5v1tAx3VvAJaH//KGitRXvo4RKlX6D3tnN+c= github.com/pion/interceptor v0.1.44 h1:sNlZwM8dWXU9JQAkJh8xrarC0Etn8Oolcniukmuy0/I= github.com/pion/interceptor v0.1.44/go.mod h1:4atVlBkcgXuUP+ykQF0qOCGU2j7pQzX2ofvPRFsY5RY= github.com/pion/logging v0.2.4 h1:tTew+7cmQ+Mc1pTBLKH2puKsOvhm32dROumOZ655zB8= @@ -466,8 +462,8 @@ github.com/pion/rtcp v1.2.16 h1:fk1B1dNW4hsI78XUCljZJlC4kZOPk67mNRuQ0fcEkSo= github.com/pion/rtcp v1.2.16/go.mod h1:/as7VKfYbs5NIb4h6muQ35kQF/J0ZVNz2Z3xKoCBYOo= github.com/pion/rtp v1.10.1 h1:xP1prZcCTUuhO2c83XtxyOHJteISg6o8iPsE2acaMtA= github.com/pion/rtp v1.10.1/go.mod h1:rF5nS1GqbR7H/TCpKwylzeq6yDM+MM6k+On5EgeThEM= -github.com/pion/sctp v1.9.3 h1:tjuOX9K/U4udMR2I7QDqr4sLE0tFzegtou7OF4a7p8A= -github.com/pion/sctp v1.9.3/go.mod h1:N20Dq6LY+JvJDAh9VVh1JELngb2rQ8dPgds5yBWiPgw= +github.com/pion/sctp v1.9.4 h1:cMxEu0F5tbP4qH07bKf1Zjf4rUih9LIo0qQt424e258= +github.com/pion/sctp v1.9.4/go.mod h1:N20Dq6LY+JvJDAh9VVh1JELngb2rQ8dPgds5yBWiPgw= github.com/pion/sdp/v3 v3.0.18 h1:l0bAXazKHpepazVdp+tPYnrsy9dfh7ZbT8DxesH5ZnI= github.com/pion/sdp/v3 v3.0.18/go.mod h1:ZREGo6A9ZygQ9XkqAj5xYCQtQpif0i6Pa81HOiAdqQ8= github.com/pion/srtp/v3 v3.0.10 h1:tFirkpBb3XccP5VEXLi50GqXhv5SKPxqrdlhDCJlZrQ= @@ -480,8 +476,8 @@ github.com/pion/transport/v4 v4.0.1 h1:sdROELU6BZ63Ab7FrOLn13M6YdJLY20wldXW2Cu2k github.com/pion/transport/v4 v4.0.1/go.mod h1:nEuEA4AD5lPdcIegQDpVLgNoDGreqM/YqmEx3ovP4jM= github.com/pion/turn/v4 v4.1.4 h1:EU11yMXKIsK43FhcUnjLlrhE4nboHZq+TXBIi3QpcxQ= github.com/pion/turn/v4 v4.1.4/go.mod h1:ES1DXVFKnOhuDkqn9hn5VJlSWmZPaRJLyBXoOeO/BmQ= -github.com/pion/webrtc/v4 v4.2.9 h1:DZIh1HAhPIL3RvwEDFsmL5hfPSLEpxsQk9/Jir2vkJE= -github.com/pion/webrtc/v4 v4.2.9/go.mod h1:9EmLZve0H76eTzf8v2FmchZ6tcBXtDgpfTEu+drW6SY= +github.com/pion/webrtc/v4 v4.2.11 h1:QUX1QZKlNIn4O7U5JxLPGP0sV5RTncZkzu9SPR3jVNU= +github.com/pion/webrtc/v4 v4.2.11/go.mod h1:s/rAiyy77GyRFrZMx+Ls6aua26dIBPudH8/ZHYbIRWY= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= diff --git a/pkg/config/livekit.go b/pkg/config/livekit.go index 5fd1d44c..1fa8e836 100644 --- a/pkg/config/livekit.go +++ b/pkg/config/livekit.go @@ -51,7 +51,8 @@ type LiveKitTOMLProjectConfig struct { } type LiveKitTOMLAgentConfig struct { - ID string `toml:"id"` + ID string `toml:"id"` + Name string `toml:"name"` } func NewLiveKitTOML(forSubdomain string) *LiveKitTOML {