diff --git a/agent_simulation_client.go b/agent_simulation_client.go new file mode 100644 index 00000000..a81d83ae --- /dev/null +++ b/agent_simulation_client.go @@ -0,0 +1,141 @@ +// Copyright 2025 LiveKit, Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package lksdk + +import ( + "context" + "net/http" + + "github.com/twitchtv/twirp" + + "github.com/livekit/protocol/livekit" +) + +type AgentSimulationClient struct { + simulationClient livekit.AgentSimulation + authBase +} + +func NewAgentSimulationClient(url string, apiKey string, apiSecret string, opts ...twirp.ClientOption) *AgentSimulationClient { + client := livekit.NewAgentSimulationProtobufClient(url, &http.Client{}, opts...) + return &AgentSimulationClient{ + simulationClient: client, + authBase: authBase{apiKey, apiSecret}, + } +} + +func (c *AgentSimulationClient) CreateSimulationRun(ctx context.Context, req *livekit.SimulationRun_Create_Request) (*livekit.SimulationRun_Create_Response, error) { + ctx, err := c.withAuth(ctx, withAgentGrant{SimulationAdmin: true}) + if err != nil { + return nil, err + } + return c.simulationClient.CreateSimulationRun(ctx, req) +} + +func (c *AgentSimulationClient) ConfirmSimulationSourceUpload(ctx context.Context, req *livekit.SimulationRun_ConfirmSourceUpload_Request) (*livekit.SimulationRun_ConfirmSourceUpload_Response, error) { + ctx, err := c.withAuth(ctx, withAgentGrant{SimulationAdmin: true}) + if err != nil { + return nil, err + } + return c.simulationClient.ConfirmSimulationSourceUpload(ctx, req) +} + +func (c *AgentSimulationClient) GetSimulationRun(ctx context.Context, req *livekit.SimulationRun_Get_Request) (*livekit.SimulationRun_Get_Response, error) { + ctx, err := c.withAuth(ctx, withAgentGrant{SimulationAdmin: true}) + if err != nil { + return nil, err + } + return c.simulationClient.GetSimulationRun(ctx, req) +} + +func (c *AgentSimulationClient) ListSimulationRuns(ctx context.Context, req *livekit.SimulationRun_List_Request) (*livekit.SimulationRun_List_Response, error) { + ctx, err := c.withAuth(ctx, withAgentGrant{SimulationAdmin: true}) + if err != nil { + return nil, err + } + return c.simulationClient.ListSimulationRuns(ctx, req) +} + +func (c *AgentSimulationClient) CancelSimulationRun(ctx context.Context, req *livekit.SimulationRun_Cancel_Request) (*livekit.SimulationRun_Cancel_Response, error) { + ctx, err := c.withAuth(ctx, withAgentGrant{SimulationAdmin: true}) + if err != nil { + return nil, err + } + return c.simulationClient.CancelSimulationRun(ctx, req) +} + +func (c *AgentSimulationClient) CreateScenario(ctx context.Context, req *livekit.Scenario_Create_Request) (*livekit.Scenario_Create_Response, error) { + ctx, err := c.withAuth(ctx, withAgentGrant{SimulationAdmin: true}) + if err != nil { + return nil, err + } + return c.simulationClient.CreateScenario(ctx, req) +} + +func (c *AgentSimulationClient) CreateScenarioFromSession(ctx context.Context, req *livekit.Scenario_CreateFromSession_Request) (*livekit.Scenario_CreateFromSession_Response, error) { + ctx, err := c.withAuth(ctx, withAgentGrant{SimulationAdmin: true}) + if err != nil { + return nil, err + } + return c.simulationClient.CreateScenarioFromSession(ctx, req) +} + +func (c *AgentSimulationClient) DeleteScenario(ctx context.Context, req *livekit.Scenario_Delete_Request) (*livekit.Scenario_Delete_Response, error) { + ctx, err := c.withAuth(ctx, withAgentGrant{SimulationAdmin: true}) + if err != nil { + return nil, err + } + return c.simulationClient.DeleteScenario(ctx, req) +} + +func (c *AgentSimulationClient) UpdateScenario(ctx context.Context, req *livekit.Scenario_Update_Request) (*livekit.Scenario_Update_Response, error) { + ctx, err := c.withAuth(ctx, withAgentGrant{SimulationAdmin: true}) + if err != nil { + return nil, err + } + return c.simulationClient.UpdateScenario(ctx, req) +} + +func (c *AgentSimulationClient) CreateScenarioGroup(ctx context.Context, req *livekit.ScenarioGroup_Create_Request) (*livekit.ScenarioGroup_Create_Response, error) { + ctx, err := c.withAuth(ctx, withAgentGrant{SimulationAdmin: true}) + if err != nil { + return nil, err + } + return c.simulationClient.CreateScenarioGroup(ctx, req) +} + +func (c *AgentSimulationClient) DeleteScenarioGroup(ctx context.Context, req *livekit.ScenarioGroup_Delete_Request) (*livekit.ScenarioGroup_Delete_Response, error) { + ctx, err := c.withAuth(ctx, withAgentGrant{SimulationAdmin: true}) + if err != nil { + return nil, err + } + return c.simulationClient.DeleteScenarioGroup(ctx, req) +} + +func (c *AgentSimulationClient) ListScenarioGroups(ctx context.Context, req *livekit.ScenarioGroup_List_Request) (*livekit.ScenarioGroup_List_Response, error) { + ctx, err := c.withAuth(ctx, withAgentGrant{SimulationAdmin: true}) + if err != nil { + return nil, err + } + return c.simulationClient.ListScenarioGroups(ctx, req) +} + +func (c *AgentSimulationClient) ListScenarios(ctx context.Context, req *livekit.Scenario_List_Request) (*livekit.Scenario_List_Response, error) { + ctx, err := c.withAuth(ctx, withAgentGrant{SimulationAdmin: true}) + if err != nil { + return nil, err + } + return c.simulationClient.ListScenarios(ctx, req) +} diff --git a/go.mod b/go.mod index 1cb7c844..fd14396a 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,7 @@ require ( github.com/livekit/mageutil v0.0.0-20250511045019-0f1ff63f7731 github.com/livekit/media-sdk v0.0.0-20251106223430-dd8f5e0de2cf github.com/livekit/mediatransportutil v0.0.0-20251128105421-19c7a7b81c22 - github.com/livekit/protocol v1.45.1 + github.com/livekit/protocol v1.45.2-0.20260403151849-8a360e8d0221 github.com/magefile/mage v1.15.0 github.com/moby/buildkit v0.26.2 github.com/moby/patternmatcher v0.6.0 @@ -60,7 +60,7 @@ require ( github.com/frostbyte73/core v0.1.1 github.com/fsnotify/fsnotify v1.9.0 // indirect github.com/gammazero/deque v1.2.1 - github.com/go-jose/go-jose/v3 v3.0.4 // indirect + github.com/go-jose/go-jose/v3 v3.0.5 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-viper/mapstructure/v2 v2.4.0 // indirect github.com/gofrs/flock v0.13.0 // indirect diff --git a/go.sum b/go.sum index d2e67699..1f0e91ca 100644 --- a/go.sum +++ b/go.sum @@ -101,8 +101,8 @@ github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= github.com/gammazero/deque v1.2.1 h1:9fnQVFCCZ9/NOc7ccTNqzoKd1tCWOqeI05/lPqFPMGQ= github.com/gammazero/deque v1.2.1/go.mod h1:5nSFkzVm+afG9+gy0VIowlqVAW4N8zNcMne+CMQVD2g= -github.com/go-jose/go-jose/v3 v3.0.4 h1:Wp5HA7bLQcKnf6YYao/4kpRpVMp/yf6+pJKV8WFSaNY= -github.com/go-jose/go-jose/v3 v3.0.4/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= +github.com/go-jose/go-jose/v3 v3.0.5 h1:BLLJWbC4nMZOfuPVxoZIxeYsn6Nl2r1fITaJ78UQlVQ= +github.com/go-jose/go-jose/v3 v3.0.5/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -159,8 +159,8 @@ github.com/livekit/media-sdk v0.0.0-20251106223430-dd8f5e0de2cf h1:gvun6axx2Mrh8 github.com/livekit/media-sdk v0.0.0-20251106223430-dd8f5e0de2cf/go.mod h1:7ssWiG+U4xnbvLih9WiZbhQP6zIKMjgXdUtIE1bm/E8= github.com/livekit/mediatransportutil v0.0.0-20251128105421-19c7a7b81c22 h1:dzCBxOGLLWVtQhL7OYK2EGN+5Q+23Mq/jfz4vQisirA= github.com/livekit/mediatransportutil v0.0.0-20251128105421-19c7a7b81c22/go.mod h1:mSNtYzSf6iY9xM3UX42VEI+STHvMgHmrYzEHPcdhB8A= -github.com/livekit/protocol v1.45.1 h1:4cbynsPZW32gS2z6nUWfAfr4YaTUwZSKUiLpSpjX+lQ= -github.com/livekit/protocol v1.45.1/go.mod h1:63AUi0vQak6Y6gPqSBHLc+ExYTUwEqF/m4b2IRW1iO0= +github.com/livekit/protocol v1.45.2-0.20260403151849-8a360e8d0221 h1:loe7h+z1kOu/ojprFTYSZBbJVly7gdZgQ/ewElGeLPo= +github.com/livekit/protocol v1.45.2-0.20260403151849-8a360e8d0221/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/magefile/mage v1.15.0 h1:BvGheCMAsG3bWUDbZ8AyXXpCNwU9u5CB6sM+HNb9HYg= diff --git a/pkg/cloudagents/tar.go b/pkg/cloudagents/tar.go index d0434a40..e73d1857 100644 --- a/pkg/cloudagents/tar.go +++ b/pkg/cloudagents/tar.go @@ -28,7 +28,7 @@ import ( "github.com/moby/patternmatcher" ) -func createSourceTarball( +func CreateSourceTarball( directory fs.FS, excludeFiles []string, w io.Writer, diff --git a/pkg/cloudagents/upload.go b/pkg/cloudagents/upload.go index 4b957c89..8e9db21a 100644 --- a/pkg/cloudagents/upload.go +++ b/pkg/cloudagents/upload.go @@ -55,11 +55,11 @@ func uploadSource( excludeFiles []string, ) error { var buf bytes.Buffer - if err := createSourceTarball(directory, excludeFiles, &buf); err != nil { + if err := CreateSourceTarball(directory, excludeFiles, &buf); err != nil { return fmt.Errorf("failed to sanitize source: %w", err) } if presignedPostRequest != nil { - if err := multipartUpload(presignedPostRequest.Url, presignedPostRequest.Values, &buf); err != nil { + if err := MultipartUpload(presignedPostRequest.Url, presignedPostRequest.Values, &buf); err != nil { return fmt.Errorf("multipart upload failed: %w", err) } } else { @@ -89,7 +89,7 @@ func upload(presignedUrl string, buf *bytes.Buffer) error { return nil } -func multipartUpload(presignedURL string, fields map[string]string, buf *bytes.Buffer) error { +func MultipartUpload(presignedURL string, fields map[string]string, buf *bytes.Buffer) error { var b bytes.Buffer w := multipart.NewWriter(&b) fileName, ok := fields["key"]