diff --git a/.changeset/agent-threads.md b/.changeset/agent-threads.md new file mode 100644 index 000000000..9f16bfd2a --- /dev/null +++ b/.changeset/agent-threads.md @@ -0,0 +1,8 @@ +--- +"github.com/livekit/protocol": minor +"@livekit/protocol": minor +--- + +Agent threads, the durable conversation an agent has with a person across channels (`agent/livekit_agent_thread.proto`): `AgentThread` (the thread, its items as `ChatContext.ChatItem`) and `AgentTask` (background work an agent runs in it); the conversation tables in `livekit/agent/thread_schema_v1.sql`; `auth.AgentThreadGrant` under the `agentThread` claim (list and create by scope, read, write and delete by thread id, or every thread of the project with `all`); the `AT_` (thread) and `AST_` (agent stream) id prefixes in `utils/guid`. + +The agent-db and thread services are internal gRPC in cloud-protocol, so `AgentDBService` and its Twirp code are removed; the public API is public-api-server. A database lives in its project's data region: `AgentDB.CreateRequest.region` is removed, `DumpRequest`/`DumpResponse` are now `ExportRequest`/`ExportResponse`, and AgentDB times are `google.protobuf.Timestamp` / `Duration`. A batch answers one result per statement, tagged with its 0-based `statement` index on `Columns`, `ColumnBatch` and `ExecResult`. diff --git a/auth/accesstoken.go b/auth/accesstoken.go index 5cc7de68d..ae8cba0aa 100644 --- a/auth/accesstoken.go +++ b/auth/accesstoken.go @@ -114,6 +114,11 @@ func (t *AccessToken) SetAgentEndpointGrant(grant *AgentEndpointGrant) *AccessTo return t } +func (t *AccessToken) SetAgentThreadGrant(grant *AgentThreadGrant) *AccessToken { + t.grant.AgentThread = grant + return t +} + func (t *AccessToken) SetMetadata(md string) *AccessToken { t.grant.Metadata = md return t diff --git a/auth/accesstoken_test.go b/auth/accesstoken_test.go index 4a2e7ec45..d4574c9de 100644 --- a/auth/accesstoken_test.go +++ b/auth/accesstoken_test.go @@ -245,6 +245,30 @@ func TestAgentEndpointGrantRoundTrip(t *testing.T) { require.Equal(t, grant, decoded.AgentEndpoint) } +func TestAgentThreadGrantRoundTrip(t *testing.T) { + t.Parallel() + + apiKey, secret := apiKeypair() + grant := &AgentThreadGrant{Scope: "user-1", ThreadIDs: []string{"AT_1"}, Read: true, Write: true} + raw, err := NewAccessToken(apiKey, secret). + SetAgentThreadGrant(grant). + SetValidFor(time.Minute). + ToJWT() + require.NoError(t, err) + + // the claim keys are camelCase + claims := decodeClaims(t, raw) + require.Contains(t, claims, `"agentThread"`) + require.Contains(t, claims, `"scope"`) + require.Contains(t, claims, `"threadIds"`) + + v, err := ParseAPIToken(raw) + require.NoError(t, err) + _, decoded, err := v.Verify(secret) + require.NoError(t, err) + require.Equal(t, grant, decoded.AgentThread) +} + func decodeClaims(t *testing.T, raw string) string { t.Helper() parts := strings.Split(raw, ".") diff --git a/auth/grants.go b/auth/grants.go index 4f56ad57a..fd052ff84 100644 --- a/auth/grants.go +++ b/auth/grants.go @@ -169,6 +169,7 @@ type ClaimGrants struct { Inference *InferenceGrant `json:"inference,omitempty"` Observability *ObservabilityGrant `json:"observability,omitempty"` AgentEndpoint *AgentEndpointGrant `json:"agentEndpoint,omitempty"` + AgentThread *AgentThreadGrant `json:"agentThread,omitempty"` // Room configuration to use if this participant initiates the room RoomConfig *RoomConfiguration `json:"roomConfig,omitempty"` // Cloud-only, config preset to use @@ -216,6 +217,7 @@ func (c *ClaimGrants) Clone() *ClaimGrants { clone.Inference = c.Inference.Clone() clone.Observability = c.Observability.Clone() clone.AgentEndpoint = c.AgentEndpoint.Clone() + clone.AgentThread = c.AgentThread.Clone() clone.Attributes = maps.Clone(c.Attributes) clone.RoomConfig = c.RoomConfig.Clone() if len(c.KindDetails) > 0 { @@ -239,6 +241,7 @@ func (c *ClaimGrants) MarshalLogObject(e zapcore.ObjectEncoder) error { e.AddObject("Inference", c.Inference) e.AddObject("Observability", c.Observability) e.AddObject("AgentEndpoint", c.AgentEndpoint) + e.AddObject("AgentThread", c.AgentThread) e.AddObject("RoomConfig", logger.Proto((*livekit.RoomConfiguration)(c.RoomConfig))) e.AddString("RoomPreset", c.RoomPreset) return nil @@ -712,6 +715,93 @@ func (s *AgentEndpointGrant) MarshalLogObject(e zapcore.ObjectEncoder) error { // ------------------------------------------------------------------ +// AgentThreadGrant gives a token access to threads, across the project's +// agents: list and create within Scope, and read, write and delete the threads +// in ThreadIDs. All extends it to every thread and scope of the project; the +// action flags still apply. It grants thread data only; which endpoints a token +// may call is agentEndpoint's. +type AgentThreadGrant struct { + All bool `json:"all,omitempty"` + Scope string `json:"scope,omitempty"` + ThreadIDs []string `json:"threadIds,omitempty"` + List bool `json:"list,omitempty"` + Create bool `json:"create,omitempty"` + Write bool `json:"write,omitempty"` + Read bool `json:"read,omitempty"` + Delete bool `json:"delete,omitempty"` +} + +// CanCreate reports whether the holder may create threads in scope. A scoped +// grant creates only in its own scope. +func (s *AgentThreadGrant) CanCreate(scope string) bool { + return s != nil && s.Create && s.inScope(scope) +} + +// CanList reports whether the holder may list the threads of scope. +func (s *AgentThreadGrant) CanList(scope string) bool { + return s != nil && s.List && s.inScope(scope) +} + +// CanUpdate reports whether the holder may change any thread's attributes and +// idle TTL, which only a project-wide grant may. +func (s *AgentThreadGrant) CanUpdate() bool { + return s != nil && s.All && s.Write +} + +// CanRead reports whether the holder may read threadID. +func (s *AgentThreadGrant) CanRead(threadID string) bool { + return s != nil && s.Read && s.includes(threadID) +} + +// CanWrite reports whether the holder may send to threadID. +func (s *AgentThreadGrant) CanWrite(threadID string) bool { + return s != nil && s.Write && s.includes(threadID) +} + +// CanDelete reports whether the holder may delete threadID. +func (s *AgentThreadGrant) CanDelete(threadID string) bool { + return s != nil && s.Delete && s.includes(threadID) +} + +func (s *AgentThreadGrant) inScope(scope string) bool { + return s.All || (s.Scope != "" && s.Scope == scope) +} + +func (s *AgentThreadGrant) includes(threadID string) bool { + return threadID != "" && (s.All || slices.Contains(s.ThreadIDs, threadID)) +} + +func (s *AgentThreadGrant) Clone() *AgentThreadGrant { + if s == nil { + return nil + } + + clone := *s + if len(s.ThreadIDs) > 0 { + clone.ThreadIDs = append([]string{}, s.ThreadIDs...) + } + + return &clone +} + +func (s *AgentThreadGrant) MarshalLogObject(e zapcore.ObjectEncoder) error { + if s == nil { + return nil + } + + e.AddBool("All", s.All) + e.AddString("Scope", s.Scope) + zap.Strings("ThreadIDs", s.ThreadIDs).AddTo(e) + e.AddBool("List", s.List) + e.AddBool("Create", s.Create) + e.AddBool("Write", s.Write) + e.AddBool("Read", s.Read) + e.AddBool("Delete", s.Delete) + return nil +} + +// ------------------------------------------------------------------ + func sourceToString(source livekit.TrackSource) string { return strings.ToLower(source.String()) } diff --git a/auth/grants_test.go b/auth/grants_test.go index 8755a3c2e..b490e46df 100644 --- a/auth/grants_test.go +++ b/auth/grants_test.go @@ -36,6 +36,7 @@ func TestGrants(t *testing.T) { require.Same(t, grants.Inference, clone.Inference) require.Same(t, grants.SIP, clone.SIP) require.Same(t, grants.AgentEndpoint, clone.AgentEndpoint) + require.Same(t, grants.AgentThread, clone.AgentThread) require.True(t, reflect.DeepEqual(grants, clone)) require.True(t, reflect.DeepEqual(grants.Video, clone.Video)) }) @@ -65,6 +66,9 @@ func TestGrants(t *testing.T) { // require AgentEndpoint require.Same(t, grants.AgentEndpoint, clone.AgentEndpoint) require.True(t, reflect.DeepEqual(grants.AgentEndpoint, clone.AgentEndpoint)) + // require AgentThread + require.Same(t, grants.AgentThread, clone.AgentThread) + require.True(t, reflect.DeepEqual(grants.AgentThread, clone.AgentThread)) }) t.Run("clone with video", func(t *testing.T) { @@ -524,3 +528,55 @@ func TestAgentEndpointGrantCloneIndependent(t *testing.T) { require.True(t, grants.AgentEndpoint.Call) require.Equal(t, "a", grants.AgentEndpoint.AgentName) } + +func TestAgentThreadGrantChecks(t *testing.T) { + t.Parallel() + + // Scope covers list and create only; read, write and delete need the id. + g := &AgentThreadGrant{Scope: "u1", ThreadIDs: []string{"AT_1"}, List: true, Create: true, Read: true} + require.True(t, g.CanRead("AT_1")) + require.False(t, g.CanRead("AT_2")) + require.False(t, g.CanRead("")) + require.False(t, g.CanWrite("AT_1")) + require.False(t, g.CanDelete("AT_1")) + require.True(t, g.CanList("u1")) + require.False(t, g.CanList("u2")) + require.False(t, g.CanList("")) + require.True(t, g.CanCreate("u1")) + require.False(t, g.CanCreate("u2")) + require.False(t, g.CanUpdate()) + + idsOnly := &AgentThreadGrant{ThreadIDs: []string{"AT_4"}, Create: true, Write: true} + require.True(t, idsOnly.CanWrite("AT_4")) + require.False(t, idsOnly.CanCreate("")) + + // All covers every thread and scope, still gated by the action flags. + all := &AgentThreadGrant{All: true, Read: true, List: true} + require.True(t, all.CanRead("AT_9")) + require.True(t, all.CanList("any")) + require.False(t, all.CanRead("")) + require.False(t, all.CanDelete("AT_9")) + require.False(t, all.CanCreate("any")) + require.False(t, all.CanUpdate()) + require.True(t, (&AgentThreadGrant{All: true, Write: true}).CanUpdate()) + + var none *AgentThreadGrant + require.False(t, none.CanRead("AT_1")) + require.False(t, none.CanCreate("u1")) + require.False(t, none.CanUpdate()) +} + +func TestAgentThreadGrantCloneIndependent(t *testing.T) { + t.Parallel() + + grants := &ClaimGrants{AgentThread: &AgentThreadGrant{Scope: "u1", ThreadIDs: []string{"AT_1"}, Write: true}} + clone := grants.Clone() + require.NotSame(t, grants.AgentThread, clone.AgentThread) + require.True(t, reflect.DeepEqual(grants.AgentThread, clone.AgentThread)) + + clone.AgentThread.Write = false + clone.AgentThread.ThreadIDs[0] = "AT_2" + clone.AgentThread.ThreadIDs = append(clone.AgentThread.ThreadIDs, "AT_3") + require.True(t, grants.AgentThread.Write) + require.Equal(t, []string{"AT_1"}, grants.AgentThread.ThreadIDs) +} diff --git a/livekit/agent/livekit_agent_thread.pb.go b/livekit/agent/livekit_agent_thread.pb.go new file mode 100644 index 000000000..4b4b7a670 --- /dev/null +++ b/livekit/agent/livekit_agent_thread.pb.go @@ -0,0 +1,1193 @@ +// Copyright 2026 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. + +// AgentThread: the durable conversation between an agent and a person, across +// channels and over time. Identified by an "AT_" id. Holds a scope, attributes, +// an idle TTL and the AgentDB database created with it. Served by +// cloud-protocol's AgentThreads. The conversation inside follows thread_schema_v1.sql, shared +// by the agents framework, which writes it, and the platform, which reads it. + +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.36.12 +// protoc v7.35.1 +// source: agent/livekit_agent_thread.proto + +package agent + +import ( + _ "github.com/livekit/protocol/livekit/logger" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + durationpb "google.golang.org/protobuf/types/known/durationpb" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" + sync "sync" + unsafe "unsafe" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +// A task is never UNSPECIFIED. +type AgentTask_Status int32 + +const ( + AgentTask_UNSPECIFIED AgentTask_Status = 0 + AgentTask_RUNNING AgentTask_Status = 1 + AgentTask_COMPLETED AgentTask_Status = 2 + AgentTask_FAILED AgentTask_Status = 3 + AgentTask_CANCELED AgentTask_Status = 4 +) + +// Enum value maps for AgentTask_Status. +var ( + AgentTask_Status_name = map[int32]string{ + 0: "UNSPECIFIED", + 1: "RUNNING", + 2: "COMPLETED", + 3: "FAILED", + 4: "CANCELED", + } + AgentTask_Status_value = map[string]int32{ + "UNSPECIFIED": 0, + "RUNNING": 1, + "COMPLETED": 2, + "FAILED": 3, + "CANCELED": 4, + } +) + +func (x AgentTask_Status) Enum() *AgentTask_Status { + p := new(AgentTask_Status) + *p = x + return p +} + +func (x AgentTask_Status) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (AgentTask_Status) Descriptor() protoreflect.EnumDescriptor { + return file_agent_livekit_agent_thread_proto_enumTypes[0].Descriptor() +} + +func (AgentTask_Status) Type() protoreflect.EnumType { + return &file_agent_livekit_agent_thread_proto_enumTypes[0] +} + +func (x AgentTask_Status) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use AgentTask_Status.Descriptor instead. +func (AgentTask_Status) EnumDescriptor() ([]byte, []int) { + return file_agent_livekit_agent_thread_proto_rawDescGZIP(), []int{1, 0} +} + +type AgentThread struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AgentThread) Reset() { + *x = AgentThread{} + mi := &file_agent_livekit_agent_thread_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgentThread) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgentThread) ProtoMessage() {} + +func (x *AgentThread) ProtoReflect() protoreflect.Message { + mi := &file_agent_livekit_agent_thread_proto_msgTypes[0] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AgentThread.ProtoReflect.Descriptor instead. +func (*AgentThread) Descriptor() ([]byte, []int) { + return file_agent_livekit_agent_thread_proto_rawDescGZIP(), []int{0} +} + +// AgentTask: background work an agent runs within a thread, such as a booking +// that takes minutes. +type AgentTask struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AgentTask) Reset() { + *x = AgentTask{} + mi := &file_agent_livekit_agent_thread_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgentTask) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgentTask) ProtoMessage() {} + +func (x *AgentTask) ProtoReflect() protoreflect.Message { + mi := &file_agent_livekit_agent_thread_proto_msgTypes[1] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AgentTask.ProtoReflect.Descriptor instead. +func (*AgentTask) Descriptor() ([]byte, []int) { + return file_agent_livekit_agent_thread_proto_rawDescGZIP(), []int{1} +} + +type AgentThread_CreateRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + // Groups threads, e.g. by user: an application-defined value, typically the + // user's identity. An AgentThreadGrant is scoped by it. + Scope string `protobuf:"bytes,1,opt,name=scope,proto3" json:"scope,omitempty"` + Attributes map[string]string `protobuf:"bytes,2,rep,name=attributes,proto3" json:"attributes,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + // Unset takes the server default. + IdleTtl *durationpb.Duration `protobuf:"bytes,3,opt,name=idle_ttl,json=idleTtl,proto3" json:"idle_ttl,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AgentThread_CreateRequest) Reset() { + *x = AgentThread_CreateRequest{} + mi := &file_agent_livekit_agent_thread_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgentThread_CreateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgentThread_CreateRequest) ProtoMessage() {} + +func (x *AgentThread_CreateRequest) ProtoReflect() protoreflect.Message { + mi := &file_agent_livekit_agent_thread_proto_msgTypes[2] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AgentThread_CreateRequest.ProtoReflect.Descriptor instead. +func (*AgentThread_CreateRequest) Descriptor() ([]byte, []int) { + return file_agent_livekit_agent_thread_proto_rawDescGZIP(), []int{0, 0} +} + +func (x *AgentThread_CreateRequest) GetScope() string { + if x != nil { + return x.Scope + } + return "" +} + +func (x *AgentThread_CreateRequest) GetAttributes() map[string]string { + if x != nil { + return x.Attributes + } + return nil +} + +func (x *AgentThread_CreateRequest) GetIdleTtl() *durationpb.Duration { + if x != nil { + return x.IdleTtl + } + return nil +} + +type AgentThread_GetRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + ThreadId string `protobuf:"bytes,1,opt,name=thread_id,json=threadId,proto3" json:"thread_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AgentThread_GetRequest) Reset() { + *x = AgentThread_GetRequest{} + mi := &file_agent_livekit_agent_thread_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgentThread_GetRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgentThread_GetRequest) ProtoMessage() {} + +func (x *AgentThread_GetRequest) ProtoReflect() protoreflect.Message { + mi := &file_agent_livekit_agent_thread_proto_msgTypes[3] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AgentThread_GetRequest.ProtoReflect.Descriptor instead. +func (*AgentThread_GetRequest) Descriptor() ([]byte, []int) { + return file_agent_livekit_agent_thread_proto_rawDescGZIP(), []int{0, 1} +} + +func (x *AgentThread_GetRequest) GetThreadId() string { + if x != nil { + return x.ThreadId + } + return "" +} + +// The threads of one scope, newest first. +type AgentThread_ListRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + Scope string `protobuf:"bytes,1,opt,name=scope,proto3" json:"scope,omitempty"` + // Cursor from the previous ListResponse; empty for the first page. + Before string `protobuf:"bytes,2,opt,name=before,proto3" json:"before,omitempty"` + Limit int32 `protobuf:"varint,3,opt,name=limit,proto3" json:"limit,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AgentThread_ListRequest) Reset() { + *x = AgentThread_ListRequest{} + mi := &file_agent_livekit_agent_thread_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgentThread_ListRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgentThread_ListRequest) ProtoMessage() {} + +func (x *AgentThread_ListRequest) ProtoReflect() protoreflect.Message { + mi := &file_agent_livekit_agent_thread_proto_msgTypes[4] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AgentThread_ListRequest.ProtoReflect.Descriptor instead. +func (*AgentThread_ListRequest) Descriptor() ([]byte, []int) { + return file_agent_livekit_agent_thread_proto_rawDescGZIP(), []int{0, 2} +} + +func (x *AgentThread_ListRequest) GetScope() string { + if x != nil { + return x.Scope + } + return "" +} + +func (x *AgentThread_ListRequest) GetBefore() string { + if x != nil { + return x.Before + } + return "" +} + +func (x *AgentThread_ListRequest) GetLimit() int32 { + if x != nil { + return x.Limit + } + return 0 +} + +type AgentThread_ListResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Threads []*AgentThread_Thread `protobuf:"bytes,1,rep,name=threads,proto3" json:"threads,omitempty"` + // Empty at the end. + Before string `protobuf:"bytes,2,opt,name=before,proto3" json:"before,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AgentThread_ListResponse) Reset() { + *x = AgentThread_ListResponse{} + mi := &file_agent_livekit_agent_thread_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgentThread_ListResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgentThread_ListResponse) ProtoMessage() {} + +func (x *AgentThread_ListResponse) ProtoReflect() protoreflect.Message { + mi := &file_agent_livekit_agent_thread_proto_msgTypes[5] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AgentThread_ListResponse.ProtoReflect.Descriptor instead. +func (*AgentThread_ListResponse) Descriptor() ([]byte, []int) { + return file_agent_livekit_agent_thread_proto_rawDescGZIP(), []int{0, 3} +} + +func (x *AgentThread_ListResponse) GetThreads() []*AgentThread_Thread { + if x != nil { + return x.Threads + } + return nil +} + +func (x *AgentThread_ListResponse) GetBefore() string { + if x != nil { + return x.Before + } + return "" +} + +type AgentThread_UpdateRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + ThreadId string `protobuf:"bytes,1,opt,name=thread_id,json=threadId,proto3" json:"thread_id,omitempty"` + // Added to the existing attributes; an empty value deletes the entry. + Attributes map[string]string `protobuf:"bytes,2,rep,name=attributes,proto3" json:"attributes,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + IdleTtl *durationpb.Duration `protobuf:"bytes,3,opt,name=idle_ttl,json=idleTtl,proto3" json:"idle_ttl,omitempty"` // Every update counts as activity and pushes expires_at out by idle_ttl. + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AgentThread_UpdateRequest) Reset() { + *x = AgentThread_UpdateRequest{} + mi := &file_agent_livekit_agent_thread_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgentThread_UpdateRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgentThread_UpdateRequest) ProtoMessage() {} + +func (x *AgentThread_UpdateRequest) ProtoReflect() protoreflect.Message { + mi := &file_agent_livekit_agent_thread_proto_msgTypes[6] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AgentThread_UpdateRequest.ProtoReflect.Descriptor instead. +func (*AgentThread_UpdateRequest) Descriptor() ([]byte, []int) { + return file_agent_livekit_agent_thread_proto_rawDescGZIP(), []int{0, 4} +} + +func (x *AgentThread_UpdateRequest) GetThreadId() string { + if x != nil { + return x.ThreadId + } + return "" +} + +func (x *AgentThread_UpdateRequest) GetAttributes() map[string]string { + if x != nil { + return x.Attributes + } + return nil +} + +func (x *AgentThread_UpdateRequest) GetIdleTtl() *durationpb.Duration { + if x != nil { + return x.IdleTtl + } + return nil +} + +type AgentThread_DeleteRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + ThreadId string `protobuf:"bytes,1,opt,name=thread_id,json=threadId,proto3" json:"thread_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AgentThread_DeleteRequest) Reset() { + *x = AgentThread_DeleteRequest{} + mi := &file_agent_livekit_agent_thread_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgentThread_DeleteRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgentThread_DeleteRequest) ProtoMessage() {} + +func (x *AgentThread_DeleteRequest) ProtoReflect() protoreflect.Message { + mi := &file_agent_livekit_agent_thread_proto_msgTypes[7] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AgentThread_DeleteRequest.ProtoReflect.Descriptor instead. +func (*AgentThread_DeleteRequest) Descriptor() ([]byte, []int) { + return file_agent_livekit_agent_thread_proto_rawDescGZIP(), []int{0, 5} +} + +func (x *AgentThread_DeleteRequest) GetThreadId() string { + if x != nil { + return x.ThreadId + } + return "" +} + +type AgentThread_DeleteResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AgentThread_DeleteResponse) Reset() { + *x = AgentThread_DeleteResponse{} + mi := &file_agent_livekit_agent_thread_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgentThread_DeleteResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgentThread_DeleteResponse) ProtoMessage() {} + +func (x *AgentThread_DeleteResponse) ProtoReflect() protoreflect.Message { + mi := &file_agent_livekit_agent_thread_proto_msgTypes[8] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AgentThread_DeleteResponse.ProtoReflect.Descriptor instead. +func (*AgentThread_DeleteResponse) Descriptor() ([]byte, []int) { + return file_agent_livekit_agent_thread_proto_rawDescGZIP(), []int{0, 6} +} + +// The thread's chat items, oldest first. +type AgentThread_GetItemsRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + ThreadId string `protobuf:"bytes,1,opt,name=thread_id,json=threadId,proto3" json:"thread_id,omitempty"` + // One agent's items; empty for every agent's. + Agent string `protobuf:"bytes,2,opt,name=agent,proto3" json:"agent,omitempty"` + // Cursor from the previous GetItemsResponse; empty for the first page. + After string `protobuf:"bytes,3,opt,name=after,proto3" json:"after,omitempty"` + Limit int32 `protobuf:"varint,4,opt,name=limit,proto3" json:"limit,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AgentThread_GetItemsRequest) Reset() { + *x = AgentThread_GetItemsRequest{} + mi := &file_agent_livekit_agent_thread_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgentThread_GetItemsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgentThread_GetItemsRequest) ProtoMessage() {} + +func (x *AgentThread_GetItemsRequest) ProtoReflect() protoreflect.Message { + mi := &file_agent_livekit_agent_thread_proto_msgTypes[9] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AgentThread_GetItemsRequest.ProtoReflect.Descriptor instead. +func (*AgentThread_GetItemsRequest) Descriptor() ([]byte, []int) { + return file_agent_livekit_agent_thread_proto_rawDescGZIP(), []int{0, 7} +} + +func (x *AgentThread_GetItemsRequest) GetThreadId() string { + if x != nil { + return x.ThreadId + } + return "" +} + +func (x *AgentThread_GetItemsRequest) GetAgent() string { + if x != nil { + return x.Agent + } + return "" +} + +func (x *AgentThread_GetItemsRequest) GetAfter() string { + if x != nil { + return x.After + } + return "" +} + +func (x *AgentThread_GetItemsRequest) GetLimit() int32 { + if x != nil { + return x.Limit + } + return 0 +} + +type AgentThread_GetItemsResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Items []*AgentThread_Item `protobuf:"bytes,1,rep,name=items,proto3" json:"items,omitempty"` + // Empty at the end. + After string `protobuf:"bytes,2,opt,name=after,proto3" json:"after,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AgentThread_GetItemsResponse) Reset() { + *x = AgentThread_GetItemsResponse{} + mi := &file_agent_livekit_agent_thread_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgentThread_GetItemsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgentThread_GetItemsResponse) ProtoMessage() {} + +func (x *AgentThread_GetItemsResponse) ProtoReflect() protoreflect.Message { + mi := &file_agent_livekit_agent_thread_proto_msgTypes[10] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AgentThread_GetItemsResponse.ProtoReflect.Descriptor instead. +func (*AgentThread_GetItemsResponse) Descriptor() ([]byte, []int) { + return file_agent_livekit_agent_thread_proto_rawDescGZIP(), []int{0, 8} +} + +func (x *AgentThread_GetItemsResponse) GetItems() []*AgentThread_Item { + if x != nil { + return x.Items + } + return nil +} + +func (x *AgentThread_GetItemsResponse) GetAfter() string { + if x != nil { + return x.After + } + return "" +} + +// One chat item of an agent. Stored as the JSON of +// ChatContext.ChatItem (items.payload in thread_schema_v1.sql). +type AgentThread_Item struct { + state protoimpl.MessageState `protogen:"open.v1"` + Agent string `protobuf:"bytes,1,opt,name=agent,proto3" json:"agent,omitempty"` + // Position in the agent's history. + Seq int64 `protobuf:"varint,2,opt,name=seq,proto3" json:"seq,omitempty"` + // The A2A message the item came from. + MessageId string `protobuf:"bytes,3,opt,name=message_id,json=messageId,proto3" json:"message_id,omitempty"` + Item *ChatContext_ChatItem `protobuf:"bytes,4,opt,name=item,proto3" json:"item,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AgentThread_Item) Reset() { + *x = AgentThread_Item{} + mi := &file_agent_livekit_agent_thread_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgentThread_Item) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgentThread_Item) ProtoMessage() {} + +func (x *AgentThread_Item) ProtoReflect() protoreflect.Message { + mi := &file_agent_livekit_agent_thread_proto_msgTypes[11] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AgentThread_Item.ProtoReflect.Descriptor instead. +func (*AgentThread_Item) Descriptor() ([]byte, []int) { + return file_agent_livekit_agent_thread_proto_rawDescGZIP(), []int{0, 9} +} + +func (x *AgentThread_Item) GetAgent() string { + if x != nil { + return x.Agent + } + return "" +} + +func (x *AgentThread_Item) GetSeq() int64 { + if x != nil { + return x.Seq + } + return 0 +} + +func (x *AgentThread_Item) GetMessageId() string { + if x != nil { + return x.MessageId + } + return "" +} + +func (x *AgentThread_Item) GetItem() *ChatContext_ChatItem { + if x != nil { + return x.Item + } + return nil +} + +type AgentThread_Thread struct { + state protoimpl.MessageState `protogen:"open.v1"` + ThreadId string `protobuf:"bytes,1,opt,name=thread_id,json=threadId,proto3" json:"thread_id,omitempty"` + Scope string `protobuf:"bytes,2,opt,name=scope,proto3" json:"scope,omitempty"` + Attributes map[string]string `protobuf:"bytes,3,rep,name=attributes,proto3" json:"attributes,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + LastActive *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=last_active,json=lastActive,proto3" json:"last_active,omitempty"` + // last_active + idle_ttl; every update pushes it out. The thread and its + // database are deleted once it passes. + ExpiresAt *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=expires_at,json=expiresAt,proto3" json:"expires_at,omitempty"` + IdleTtl *durationpb.Duration `protobuf:"bytes,7,opt,name=idle_ttl,json=idleTtl,proto3" json:"idle_ttl,omitempty"` + // The thread's database ("DB_..."), created with the thread. + DatabaseId string `protobuf:"bytes,8,opt,name=database_id,json=databaseId,proto3" json:"database_id,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AgentThread_Thread) Reset() { + *x = AgentThread_Thread{} + mi := &file_agent_livekit_agent_thread_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgentThread_Thread) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgentThread_Thread) ProtoMessage() {} + +func (x *AgentThread_Thread) ProtoReflect() protoreflect.Message { + mi := &file_agent_livekit_agent_thread_proto_msgTypes[12] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AgentThread_Thread.ProtoReflect.Descriptor instead. +func (*AgentThread_Thread) Descriptor() ([]byte, []int) { + return file_agent_livekit_agent_thread_proto_rawDescGZIP(), []int{0, 10} +} + +func (x *AgentThread_Thread) GetThreadId() string { + if x != nil { + return x.ThreadId + } + return "" +} + +func (x *AgentThread_Thread) GetScope() string { + if x != nil { + return x.Scope + } + return "" +} + +func (x *AgentThread_Thread) GetAttributes() map[string]string { + if x != nil { + return x.Attributes + } + return nil +} + +func (x *AgentThread_Thread) GetCreatedAt() *timestamppb.Timestamp { + if x != nil { + return x.CreatedAt + } + return nil +} + +func (x *AgentThread_Thread) GetLastActive() *timestamppb.Timestamp { + if x != nil { + return x.LastActive + } + return nil +} + +func (x *AgentThread_Thread) GetExpiresAt() *timestamppb.Timestamp { + if x != nil { + return x.ExpiresAt + } + return nil +} + +func (x *AgentThread_Thread) GetIdleTtl() *durationpb.Duration { + if x != nil { + return x.IdleTtl + } + return nil +} + +func (x *AgentThread_Thread) GetDatabaseId() string { + if x != nil { + return x.DatabaseId + } + return "" +} + +// A thread's tasks, oldest first. +type AgentTask_GetTasksRequest struct { + state protoimpl.MessageState `protogen:"open.v1"` + ThreadId string `protobuf:"bytes,1,opt,name=thread_id,json=threadId,proto3" json:"thread_id,omitempty"` + // Unset for every status. + Status *AgentTask_Status `protobuf:"varint,2,opt,name=status,proto3,enum=livekit.agent.AgentTask_Status,oneof" json:"status,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AgentTask_GetTasksRequest) Reset() { + *x = AgentTask_GetTasksRequest{} + mi := &file_agent_livekit_agent_thread_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgentTask_GetTasksRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgentTask_GetTasksRequest) ProtoMessage() {} + +func (x *AgentTask_GetTasksRequest) ProtoReflect() protoreflect.Message { + mi := &file_agent_livekit_agent_thread_proto_msgTypes[16] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AgentTask_GetTasksRequest.ProtoReflect.Descriptor instead. +func (*AgentTask_GetTasksRequest) Descriptor() ([]byte, []int) { + return file_agent_livekit_agent_thread_proto_rawDescGZIP(), []int{1, 0} +} + +func (x *AgentTask_GetTasksRequest) GetThreadId() string { + if x != nil { + return x.ThreadId + } + return "" +} + +func (x *AgentTask_GetTasksRequest) GetStatus() AgentTask_Status { + if x != nil && x.Status != nil { + return *x.Status + } + return AgentTask_UNSPECIFIED +} + +type AgentTask_GetTasksResponse struct { + state protoimpl.MessageState `protogen:"open.v1"` + Tasks []*AgentTask_Task `protobuf:"bytes,1,rep,name=tasks,proto3" json:"tasks,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AgentTask_GetTasksResponse) Reset() { + *x = AgentTask_GetTasksResponse{} + mi := &file_agent_livekit_agent_thread_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgentTask_GetTasksResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgentTask_GetTasksResponse) ProtoMessage() {} + +func (x *AgentTask_GetTasksResponse) ProtoReflect() protoreflect.Message { + mi := &file_agent_livekit_agent_thread_proto_msgTypes[17] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AgentTask_GetTasksResponse.ProtoReflect.Descriptor instead. +func (*AgentTask_GetTasksResponse) Descriptor() ([]byte, []int) { + return file_agent_livekit_agent_thread_proto_rawDescGZIP(), []int{1, 1} +} + +func (x *AgentTask_GetTasksResponse) GetTasks() []*AgentTask_Task { + if x != nil { + return x.Tasks + } + return nil +} + +type AgentTask_Task struct { + state protoimpl.MessageState `protogen:"open.v1"` + TaskId string `protobuf:"bytes,1,opt,name=task_id,json=taskId,proto3" json:"task_id,omitempty"` + ThreadId string `protobuf:"bytes,2,opt,name=thread_id,json=threadId,proto3" json:"thread_id,omitempty"` + // The task's name, as the agent defines it. + Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` + Status AgentTask_Status `protobuf:"varint,4,opt,name=status,proto3,enum=livekit.agent.AgentTask_Status" json:"status,omitempty"` + UpdatedAt *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=updated_at,json=updatedAt,proto3" json:"updated_at,omitempty"` + unknownFields protoimpl.UnknownFields + sizeCache protoimpl.SizeCache +} + +func (x *AgentTask_Task) Reset() { + *x = AgentTask_Task{} + mi := &file_agent_livekit_agent_thread_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) +} + +func (x *AgentTask_Task) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*AgentTask_Task) ProtoMessage() {} + +func (x *AgentTask_Task) ProtoReflect() protoreflect.Message { + mi := &file_agent_livekit_agent_thread_proto_msgTypes[18] + if x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use AgentTask_Task.ProtoReflect.Descriptor instead. +func (*AgentTask_Task) Descriptor() ([]byte, []int) { + return file_agent_livekit_agent_thread_proto_rawDescGZIP(), []int{1, 2} +} + +func (x *AgentTask_Task) GetTaskId() string { + if x != nil { + return x.TaskId + } + return "" +} + +func (x *AgentTask_Task) GetThreadId() string { + if x != nil { + return x.ThreadId + } + return "" +} + +func (x *AgentTask_Task) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *AgentTask_Task) GetStatus() AgentTask_Status { + if x != nil { + return x.Status + } + return AgentTask_UNSPECIFIED +} + +func (x *AgentTask_Task) GetUpdatedAt() *timestamppb.Timestamp { + if x != nil { + return x.UpdatedAt + } + return nil +} + +var File_agent_livekit_agent_thread_proto protoreflect.FileDescriptor + +const file_agent_livekit_agent_thread_proto_rawDesc = "" + + "\n" + + " agent/livekit_agent_thread.proto\x12\rlivekit.agent\x1a\x1egoogle/protobuf/duration.proto\x1a\x1fgoogle/protobuf/timestamp.proto\x1a!agent/livekit_agent_session.proto\x1a\x14logger/options.proto\"\xbf\r\n" + + "\vAgentThread\x1a\xfe\x01\n" + + "\rCreateRequest\x12\x19\n" + + "\x05scope\x18\x01 \x01(\tB\x03\xc0P\x01R\x05scope\x12]\n" + + "\n" + + "attributes\x18\x02 \x03(\v28.livekit.agent.AgentThread.CreateRequest.AttributesEntryB\x03\xc0P\x01R\n" + + "attributes\x124\n" + + "\bidle_ttl\x18\x03 \x01(\v2\x19.google.protobuf.DurationR\aidleTtl\x1a=\n" + + "\x0fAttributesEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\x1a6\n" + + "\n" + + "GetRequest\x12(\n" + + "\tthread_id\x18\x01 \x01(\tB\v\xbaP\bthreadIDR\bthreadId\x1aV\n" + + "\vListRequest\x12\x19\n" + + "\x05scope\x18\x01 \x01(\tB\x03\xc0P\x01R\x05scope\x12\x16\n" + + "\x06before\x18\x02 \x01(\tR\x06before\x12\x14\n" + + "\x05limit\x18\x03 \x01(\x05R\x05limit\x1ac\n" + + "\fListResponse\x12;\n" + + "\athreads\x18\x01 \x03(\v2!.livekit.agent.AgentThread.ThreadR\athreads\x12\x16\n" + + "\x06before\x18\x02 \x01(\tR\x06before\x1a\x8d\x02\n" + + "\rUpdateRequest\x12(\n" + + "\tthread_id\x18\x01 \x01(\tB\v\xbaP\bthreadIDR\bthreadId\x12]\n" + + "\n" + + "attributes\x18\x02 \x03(\v28.livekit.agent.AgentThread.UpdateRequest.AttributesEntryB\x03\xc0P\x01R\n" + + "attributes\x124\n" + + "\bidle_ttl\x18\x03 \x01(\v2\x19.google.protobuf.DurationR\aidleTtl\x1a=\n" + + "\x0fAttributesEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\x1a9\n" + + "\rDeleteRequest\x12(\n" + + "\tthread_id\x18\x01 \x01(\tB\v\xbaP\bthreadIDR\bthreadId\x1a\x10\n" + + "\x0eDeleteResponse\x1a}\n" + + "\x0fGetItemsRequest\x12(\n" + + "\tthread_id\x18\x01 \x01(\tB\v\xbaP\bthreadIDR\bthreadId\x12\x14\n" + + "\x05agent\x18\x02 \x01(\tR\x05agent\x12\x14\n" + + "\x05after\x18\x03 \x01(\tR\x05after\x12\x14\n" + + "\x05limit\x18\x04 \x01(\x05R\x05limit\x1a_\n" + + "\x10GetItemsResponse\x125\n" + + "\x05items\x18\x01 \x03(\v2\x1f.livekit.agent.AgentThread.ItemR\x05items\x12\x14\n" + + "\x05after\x18\x02 \x01(\tR\x05after\x1a\x8b\x01\n" + + "\x04Item\x12\x14\n" + + "\x05agent\x18\x01 \x01(\tR\x05agent\x12\x10\n" + + "\x03seq\x18\x02 \x01(\x03R\x03seq\x12\x1d\n" + + "\n" + + "message_id\x18\x03 \x01(\tR\tmessageId\x12<\n" + + "\x04item\x18\x04 \x01(\v2#.livekit.agent.ChatContext.ChatItemB\x03\xc0P\x01R\x04item\x1a\xee\x03\n" + + "\x06Thread\x12(\n" + + "\tthread_id\x18\x01 \x01(\tB\v\xbaP\bthreadIDR\bthreadId\x12\x19\n" + + "\x05scope\x18\x02 \x01(\tB\x03\xc0P\x01R\x05scope\x12V\n" + + "\n" + + "attributes\x18\x03 \x03(\v21.livekit.agent.AgentThread.Thread.AttributesEntryB\x03\xc0P\x01R\n" + + "attributes\x129\n" + + "\n" + + "created_at\x18\x04 \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x12;\n" + + "\vlast_active\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\n" + + "lastActive\x129\n" + + "\n" + + "expires_at\x18\x06 \x01(\v2\x1a.google.protobuf.TimestampR\texpiresAt\x124\n" + + "\bidle_ttl\x18\a \x01(\v2\x19.google.protobuf.DurationR\aidleTtl\x12\x1f\n" + + "\vdatabase_id\x18\b \x01(\tR\n" + + "databaseId\x1a=\n" + + "\x0fAttributesEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"\x80\x04\n" + + "\tAgentTask\x1a\x84\x01\n" + + "\x0fGetTasksRequest\x12(\n" + + "\tthread_id\x18\x01 \x01(\tB\v\xbaP\bthreadIDR\bthreadId\x12<\n" + + "\x06status\x18\x02 \x01(\x0e2\x1f.livekit.agent.AgentTask.StatusH\x00R\x06status\x88\x01\x01B\t\n" + + "\a_status\x1aG\n" + + "\x10GetTasksResponse\x123\n" + + "\x05tasks\x18\x01 \x03(\v2\x1d.livekit.agent.AgentTask.TaskR\x05tasks\x1a\xd1\x01\n" + + "\x04Task\x12\x17\n" + + "\atask_id\x18\x01 \x01(\tR\x06taskId\x12(\n" + + "\tthread_id\x18\x02 \x01(\tB\v\xbaP\bthreadIDR\bthreadId\x12\x12\n" + + "\x04name\x18\x03 \x01(\tR\x04name\x127\n" + + "\x06status\x18\x04 \x01(\x0e2\x1f.livekit.agent.AgentTask.StatusR\x06status\x129\n" + + "\n" + + "updated_at\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampR\tupdatedAt\"O\n" + + "\x06Status\x12\x0f\n" + + "\vUNSPECIFIED\x10\x00\x12\v\n" + + "\aRUNNING\x10\x01\x12\r\n" + + "\tCOMPLETED\x10\x02\x12\n" + + "\n" + + "\x06FAILED\x10\x03\x12\f\n" + + "\bCANCELED\x10\x04B+Z)github.com/livekit/protocol/livekit/agentb\x06proto3" + +var ( + file_agent_livekit_agent_thread_proto_rawDescOnce sync.Once + file_agent_livekit_agent_thread_proto_rawDescData []byte +) + +func file_agent_livekit_agent_thread_proto_rawDescGZIP() []byte { + file_agent_livekit_agent_thread_proto_rawDescOnce.Do(func() { + file_agent_livekit_agent_thread_proto_rawDescData = protoimpl.X.CompressGZIP(unsafe.Slice(unsafe.StringData(file_agent_livekit_agent_thread_proto_rawDesc), len(file_agent_livekit_agent_thread_proto_rawDesc))) + }) + return file_agent_livekit_agent_thread_proto_rawDescData +} + +var file_agent_livekit_agent_thread_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_agent_livekit_agent_thread_proto_msgTypes = make([]protoimpl.MessageInfo, 19) +var file_agent_livekit_agent_thread_proto_goTypes = []any{ + (AgentTask_Status)(0), // 0: livekit.agent.AgentTask.Status + (*AgentThread)(nil), // 1: livekit.agent.AgentThread + (*AgentTask)(nil), // 2: livekit.agent.AgentTask + (*AgentThread_CreateRequest)(nil), // 3: livekit.agent.AgentThread.CreateRequest + (*AgentThread_GetRequest)(nil), // 4: livekit.agent.AgentThread.GetRequest + (*AgentThread_ListRequest)(nil), // 5: livekit.agent.AgentThread.ListRequest + (*AgentThread_ListResponse)(nil), // 6: livekit.agent.AgentThread.ListResponse + (*AgentThread_UpdateRequest)(nil), // 7: livekit.agent.AgentThread.UpdateRequest + (*AgentThread_DeleteRequest)(nil), // 8: livekit.agent.AgentThread.DeleteRequest + (*AgentThread_DeleteResponse)(nil), // 9: livekit.agent.AgentThread.DeleteResponse + (*AgentThread_GetItemsRequest)(nil), // 10: livekit.agent.AgentThread.GetItemsRequest + (*AgentThread_GetItemsResponse)(nil), // 11: livekit.agent.AgentThread.GetItemsResponse + (*AgentThread_Item)(nil), // 12: livekit.agent.AgentThread.Item + (*AgentThread_Thread)(nil), // 13: livekit.agent.AgentThread.Thread + nil, // 14: livekit.agent.AgentThread.CreateRequest.AttributesEntry + nil, // 15: livekit.agent.AgentThread.UpdateRequest.AttributesEntry + nil, // 16: livekit.agent.AgentThread.Thread.AttributesEntry + (*AgentTask_GetTasksRequest)(nil), // 17: livekit.agent.AgentTask.GetTasksRequest + (*AgentTask_GetTasksResponse)(nil), // 18: livekit.agent.AgentTask.GetTasksResponse + (*AgentTask_Task)(nil), // 19: livekit.agent.AgentTask.Task + (*durationpb.Duration)(nil), // 20: google.protobuf.Duration + (*ChatContext_ChatItem)(nil), // 21: livekit.agent.ChatContext.ChatItem + (*timestamppb.Timestamp)(nil), // 22: google.protobuf.Timestamp +} +var file_agent_livekit_agent_thread_proto_depIdxs = []int32{ + 14, // 0: livekit.agent.AgentThread.CreateRequest.attributes:type_name -> livekit.agent.AgentThread.CreateRequest.AttributesEntry + 20, // 1: livekit.agent.AgentThread.CreateRequest.idle_ttl:type_name -> google.protobuf.Duration + 13, // 2: livekit.agent.AgentThread.ListResponse.threads:type_name -> livekit.agent.AgentThread.Thread + 15, // 3: livekit.agent.AgentThread.UpdateRequest.attributes:type_name -> livekit.agent.AgentThread.UpdateRequest.AttributesEntry + 20, // 4: livekit.agent.AgentThread.UpdateRequest.idle_ttl:type_name -> google.protobuf.Duration + 12, // 5: livekit.agent.AgentThread.GetItemsResponse.items:type_name -> livekit.agent.AgentThread.Item + 21, // 6: livekit.agent.AgentThread.Item.item:type_name -> livekit.agent.ChatContext.ChatItem + 16, // 7: livekit.agent.AgentThread.Thread.attributes:type_name -> livekit.agent.AgentThread.Thread.AttributesEntry + 22, // 8: livekit.agent.AgentThread.Thread.created_at:type_name -> google.protobuf.Timestamp + 22, // 9: livekit.agent.AgentThread.Thread.last_active:type_name -> google.protobuf.Timestamp + 22, // 10: livekit.agent.AgentThread.Thread.expires_at:type_name -> google.protobuf.Timestamp + 20, // 11: livekit.agent.AgentThread.Thread.idle_ttl:type_name -> google.protobuf.Duration + 0, // 12: livekit.agent.AgentTask.GetTasksRequest.status:type_name -> livekit.agent.AgentTask.Status + 19, // 13: livekit.agent.AgentTask.GetTasksResponse.tasks:type_name -> livekit.agent.AgentTask.Task + 0, // 14: livekit.agent.AgentTask.Task.status:type_name -> livekit.agent.AgentTask.Status + 22, // 15: livekit.agent.AgentTask.Task.updated_at:type_name -> google.protobuf.Timestamp + 16, // [16:16] is the sub-list for method output_type + 16, // [16:16] is the sub-list for method input_type + 16, // [16:16] is the sub-list for extension type_name + 16, // [16:16] is the sub-list for extension extendee + 0, // [0:16] is the sub-list for field type_name +} + +func init() { file_agent_livekit_agent_thread_proto_init() } +func file_agent_livekit_agent_thread_proto_init() { + if File_agent_livekit_agent_thread_proto != nil { + return + } + file_agent_livekit_agent_session_proto_init() + file_agent_livekit_agent_thread_proto_msgTypes[16].OneofWrappers = []any{} + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: unsafe.Slice(unsafe.StringData(file_agent_livekit_agent_thread_proto_rawDesc), len(file_agent_livekit_agent_thread_proto_rawDesc)), + NumEnums: 1, + NumMessages: 19, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_agent_livekit_agent_thread_proto_goTypes, + DependencyIndexes: file_agent_livekit_agent_thread_proto_depIdxs, + EnumInfos: file_agent_livekit_agent_thread_proto_enumTypes, + MessageInfos: file_agent_livekit_agent_thread_proto_msgTypes, + }.Build() + File_agent_livekit_agent_thread_proto = out.File + file_agent_livekit_agent_thread_proto_goTypes = nil + file_agent_livekit_agent_thread_proto_depIdxs = nil +} diff --git a/livekit/agent/thread_schema.go b/livekit/agent/thread_schema.go new file mode 100644 index 000000000..4b709c405 --- /dev/null +++ b/livekit/agent/thread_schema.go @@ -0,0 +1,57 @@ +// Copyright 2026 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 agent + +import _ "embed" + +// ThreadSchemaVersion is the newest conversation schema a thread's database +// can hold. +const ThreadSchemaVersion = 1 + +// ThreadSchemaV1 creates version 1 of the conversation schema, one statement +// per ";" (comments hold none). +// +//go:embed thread_schema_v1.sql +var ThreadSchemaV1 string + +// taskStatuses maps the values of tasks.status (A2A task states) to +// AgentTask.Status: a task not yet finished is running, a rejected one failed. +var taskStatuses = map[string]AgentTask_Status{ + "submitted": AgentTask_RUNNING, + "working": AgentTask_RUNNING, + "input-required": AgentTask_RUNNING, + "completed": AgentTask_COMPLETED, + "failed": AgentTask_FAILED, + "rejected": AgentTask_FAILED, + "canceled": AgentTask_CANCELED, +} + +// TaskStatus is the AgentTask.Status of a tasks.status value. +func TaskStatus(state string) (AgentTask_Status, bool) { + status, ok := taskStatuses[state] + return status, ok +} + +// TaskStates are the tasks.status values of an AgentTask.Status. +func TaskStates(status AgentTask_Status) []string { + var states []string + for state, s := range taskStatuses { + if s == status { + states = append(states, state) + } + } + return states +} + diff --git a/livekit/agent/thread_schema_test.go b/livekit/agent/thread_schema_test.go new file mode 100644 index 000000000..861f73f2c --- /dev/null +++ b/livekit/agent/thread_schema_test.go @@ -0,0 +1,27 @@ +// Copyright 2026 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 agent + +import "testing" + +// Every AgentTask.Status must be reachable from a stored state, or a filter on +// it would silently match nothing. +func TestEveryTaskStatusHasStates(t *testing.T) { + for value := range AgentTask_Status_name { + if value != 0 && len(TaskStates(AgentTask_Status(value))) == 0 { + t.Errorf("%s has no tasks.status value", AgentTask_Status(value)) + } + } +} diff --git a/livekit/agent/thread_schema_v1.sql b/livekit/agent/thread_schema_v1.sql new file mode 100644 index 000000000..4f354d1b3 --- /dev/null +++ b/livekit/agent/thread_schema_v1.sql @@ -0,0 +1,86 @@ +-- Tables inside a thread's database. The agents framework creates and writes +-- them (lk-agents-storage, statements/sql.rs). A lane is one registered +-- agent's part of the thread, named after the agent, across every channel. Two +-- agents in one thread, through a delegation, are two lanes. +-- +-- Every column says who reads it: +-- [platform] agent-db's threads service: AgentThreads.GetThreadItems and +-- GetThreadTasks. Changing it breaks the platform API. +-- [a2a] the framework's A2A methods (message/send, message/stream, +-- tasks/get, tasks/list, tasks/cancel), rebuilt into A2A objects. +-- [framework] the framework's own run loop only, free to change with it. + +CREATE TABLE schema_version ( + version INTEGER NOT NULL -- [framework] compared to its own version on open +); + +-- One chat item per row. +CREATE TABLE items ( + id TEXT PRIMARY KEY, -- [framework] the item's id, its upsert key + lane TEXT NOT NULL, -- [platform, framework] + seq INTEGER NOT NULL, -- [platform, framework] position in the lane + message_id TEXT, -- [platform, framework] the A2A messageId it came from, for idempotency + payload JSONB NOT NULL -- [platform, framework] livekit.agent.ChatContext.ChatItem as protobuf JSON +); +CREATE INDEX items_lane_seq ON items (lane, seq); +CREATE UNIQUE INDEX items_lane_message ON items (lane, message_id) WHERE message_id IS NOT NULL; + +-- One A2A task per row: the task of an incoming message, or a background +-- AgentTask (name set). The A2A Task is id = task_id, contextId = the thread +-- id, status = (status, status_message, updated_at), plus the fields of data. +CREATE TABLE tasks ( + task_id TEXT PRIMARY KEY, -- [platform, a2a, framework] + lane TEXT NOT NULL, -- [framework] + seq INTEGER NOT NULL, -- [framework] submission order in the lane + name TEXT, -- [platform, framework] the AgentTask class + message_id TEXT, -- [framework] the A2A messageId that created it, for idempotency + status TEXT NOT NULL, -- [platform, a2a, framework] A2A TaskState (agent.TaskStatus maps it), working when a new run finds it means its worker was lost + status_message JSONB, -- [a2a] A2A Message + updated_at INTEGER NOT NULL, -- [platform, a2a, framework] + data JSONB NOT NULL, -- [a2a] A2A Task fields: history, artifacts, metadata + internal JSONB -- [framework] AgentTask arguments and pending question, to resume it +); +CREATE INDEX tasks_lane_seq ON tasks (lane, seq); +CREATE INDEX tasks_lane_status ON tasks (lane, status, seq); +CREATE UNIQUE INDEX tasks_lane_message ON tasks (lane, message_id) WHERE message_id IS NOT NULL; + +-- One row per lane: one worker runs a lane at a time. +CREATE TABLE lanes ( + lane TEXT PRIMARY KEY, -- [framework] + version INTEGER NOT NULL, -- [framework] fencing version, bumped by every commit + state JSONB, -- [framework] the agent's typed state + agent_stack JSONB, -- [framework] who is speaking + lease_holder TEXT, -- [framework] + lease_token TEXT, -- [framework] + lease_until INTEGER NOT NULL DEFAULT 0, -- [framework] + waiter TEXT, -- [framework] a worker waiting to interrupt the run + drained_id INTEGER NOT NULL DEFAULT 0 -- [framework] the last inbox row a run consumed +); + +-- The run journal, append-only: every AgentSession event, plus run_started and +-- run_ended. +CREATE TABLE events ( + id INTEGER PRIMARY KEY, -- [framework] insertion order + ts_ms INTEGER NOT NULL, -- [framework] + lane TEXT NOT NULL, -- [framework] + run_id TEXT NOT NULL, -- [framework] + type TEXT NOT NULL, -- [framework] + payload JSONB NOT NULL -- [framework] +); +CREATE INDEX events_lane_id ON events (lane, id); +CREATE INDEX events_lane_run ON events (lane, run_id); + +-- Messages that arrived while the lane was running, drained by the next run. +-- Ids are compared to lanes.drained_id, so the newest row is never deleted +-- (SQLite would hand its id out again). +CREATE TABLE inbox ( + id INTEGER PRIMARY KEY, -- [framework] arrival order + lane TEXT NOT NULL, -- [framework] + task_id TEXT NOT NULL, -- [framework] + message_id TEXT NOT NULL, -- [framework] the A2A messageId, for idempotency + message JSONB NOT NULL, -- [framework] the A2A message + received_at INTEGER NOT NULL -- [framework] +); +CREATE INDEX inbox_lane_id ON inbox (lane, id); +CREATE INDEX inbox_lane_task ON inbox (lane, task_id); +CREATE UNIQUE INDEX inbox_lane_message ON inbox (lane, message_id); diff --git a/livekit/livekit_agent_simulation.twirp.go b/livekit/livekit_agent_simulation.twirp.go index eea1bf242..bf112d0f6 100644 --- a/livekit/livekit_agent_simulation.twirp.go +++ b/livekit/livekit_agent_simulation.twirp.go @@ -2176,7 +2176,7 @@ func (s *agentSimulationServer) serveCreateScenarioFromSessionProtobuf(ctx conte } func (s *agentSimulationServer) ServiceDescriptor() ([]byte, int) { - return twirpFileDescriptor10, 0 + return twirpFileDescriptor9, 0 } func (s *agentSimulationServer) ProtocGenTwirpVersion() string { @@ -2190,7 +2190,7 @@ func (s *agentSimulationServer) PathPrefix() string { return baseServicePath(s.pathPrefix, "livekit", "AgentSimulation") } -var twirpFileDescriptor10 = []byte{ +var twirpFileDescriptor9 = []byte{ // 4045 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7a, 0x4b, 0x6f, 0x1c, 0x49, 0x72, 0xbf, 0xfa, 0xdd, 0x1d, 0xcd, 0x7e, 0x30, 0xf9, 0x50, 0xab, 0x34, 0x1a, 0x69, 0x34, 0xa3, diff --git a/livekit/livekit_agentdb.pb.go b/livekit/livekit_agentdb.pb.go index 5411c2488..7828f7161 100644 --- a/livekit/livekit_agentdb.pb.go +++ b/livekit/livekit_agentdb.pb.go @@ -12,6 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. +// AgentDB: per-agent SQLite databases. Each lives in its project's data region +// on object storage, with one writer at a time. Queries run over the WebSocket +// data plane (AgentDB.Wire); lifecycle is cloud-protocol's AgentDB service. + // Code generated by protoc-gen-go. DO NOT EDIT. // versions: // protoc-gen-go v1.36.12 @@ -23,6 +27,8 @@ package livekit import ( protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + durationpb "google.golang.org/protobuf/types/known/durationpb" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" reflect "reflect" sync "sync" unsafe "unsafe" @@ -172,11 +178,10 @@ func (*AgentDB) Descriptor() ([]byte, []int) { } type AgentDB_CreateRequest struct { - state protoimpl.MessageState `protogen:"open.v1"` - Region string `protobuf:"bytes,1,opt,name=region,proto3" json:"region,omitempty"` - // Unset: never expires, and expires_at is then 0 everywhere. + state protoimpl.MessageState `protogen:"open.v1"` + // Unset: never expires, and expires_at is then unset everywhere. // Otherwise clamped to the server cap, and never extended. - TtlSeconds int64 `protobuf:"varint,2,opt,name=ttl_seconds,json=ttlSeconds,proto3" json:"ttl_seconds,omitempty"` + Ttl *durationpb.Duration `protobuf:"bytes,1,opt,name=ttl,proto3" json:"ttl,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -211,24 +216,17 @@ func (*AgentDB_CreateRequest) Descriptor() ([]byte, []int) { return file_livekit_agentdb_proto_rawDescGZIP(), []int{0, 0} } -func (x *AgentDB_CreateRequest) GetRegion() string { +func (x *AgentDB_CreateRequest) GetTtl() *durationpb.Duration { if x != nil { - return x.Region + return x.Ttl } - return "" -} - -func (x *AgentDB_CreateRequest) GetTtlSeconds() int64 { - if x != nil { - return x.TtlSeconds - } - return 0 + return nil } type AgentDB_CreateResponse struct { state protoimpl.MessageState `protogen:"open.v1"` DatabaseId string `protobuf:"bytes,1,opt,name=database_id,json=databaseId,proto3" json:"database_id,omitempty"` // "DB_..." - ExpiresAt int64 `protobuf:"varint,2,opt,name=expires_at,json=expiresAt,proto3" json:"expires_at,omitempty"` + ExpiresAt *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=expires_at,json=expiresAt,proto3" json:"expires_at,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -270,11 +268,11 @@ func (x *AgentDB_CreateResponse) GetDatabaseId() string { return "" } -func (x *AgentDB_CreateResponse) GetExpiresAt() int64 { +func (x *AgentDB_CreateResponse) GetExpiresAt() *timestamppb.Timestamp { if x != nil { return x.ExpiresAt } - return 0 + return nil } type AgentDB_GetRequest struct { @@ -430,8 +428,8 @@ type AgentDB_AgentDatabase struct { state protoimpl.MessageState `protogen:"open.v1"` DatabaseId string `protobuf:"bytes,1,opt,name=database_id,json=databaseId,proto3" json:"database_id,omitempty"` Region string `protobuf:"bytes,2,opt,name=region,proto3" json:"region,omitempty"` - CreatedAt int64 `protobuf:"varint,3,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` - ExpiresAt int64 `protobuf:"varint,4,opt,name=expires_at,json=expiresAt,proto3" json:"expires_at,omitempty"` + CreatedAt *timestamppb.Timestamp `protobuf:"bytes,3,opt,name=created_at,json=createdAt,proto3" json:"created_at,omitempty"` + ExpiresAt *timestamppb.Timestamp `protobuf:"bytes,4,opt,name=expires_at,json=expiresAt,proto3" json:"expires_at,omitempty"` Tip int64 `protobuf:"varint,5,opt,name=tip,proto3" json:"tip,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache @@ -481,18 +479,18 @@ func (x *AgentDB_AgentDatabase) GetRegion() string { return "" } -func (x *AgentDB_AgentDatabase) GetCreatedAt() int64 { +func (x *AgentDB_AgentDatabase) GetCreatedAt() *timestamppb.Timestamp { if x != nil { return x.CreatedAt } - return 0 + return nil } -func (x *AgentDB_AgentDatabase) GetExpiresAt() int64 { +func (x *AgentDB_AgentDatabase) GetExpiresAt() *timestamppb.Timestamp { if x != nil { return x.ExpiresAt } - return 0 + return nil } func (x *AgentDB_AgentDatabase) GetTip() int64 { @@ -582,27 +580,27 @@ func (*AgentDB_DeleteResponse) Descriptor() ([]byte, []int) { return file_livekit_agentdb_proto_rawDescGZIP(), []int{0, 7} } -type AgentDB_DumpRequest struct { +type AgentDB_ExportRequest struct { state protoimpl.MessageState `protogen:"open.v1"` DatabaseId string `protobuf:"bytes,1,opt,name=database_id,json=databaseId,proto3" json:"database_id,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *AgentDB_DumpRequest) Reset() { - *x = AgentDB_DumpRequest{} +func (x *AgentDB_ExportRequest) Reset() { + *x = AgentDB_ExportRequest{} mi := &file_livekit_agentdb_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *AgentDB_DumpRequest) String() string { +func (x *AgentDB_ExportRequest) String() string { return protoimpl.X.MessageStringOf(x) } -func (*AgentDB_DumpRequest) ProtoMessage() {} +func (*AgentDB_ExportRequest) ProtoMessage() {} -func (x *AgentDB_DumpRequest) ProtoReflect() protoreflect.Message { +func (x *AgentDB_ExportRequest) ProtoReflect() protoreflect.Message { mi := &file_livekit_agentdb_proto_msgTypes[9] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -614,41 +612,41 @@ func (x *AgentDB_DumpRequest) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use AgentDB_DumpRequest.ProtoReflect.Descriptor instead. -func (*AgentDB_DumpRequest) Descriptor() ([]byte, []int) { +// Deprecated: Use AgentDB_ExportRequest.ProtoReflect.Descriptor instead. +func (*AgentDB_ExportRequest) Descriptor() ([]byte, []int) { return file_livekit_agentdb_proto_rawDescGZIP(), []int{0, 8} } -func (x *AgentDB_DumpRequest) GetDatabaseId() string { +func (x *AgentDB_ExportRequest) GetDatabaseId() string { if x != nil { return x.DatabaseId } return "" } -type AgentDB_DumpResponse struct { +type AgentDB_ExportResponse struct { state protoimpl.MessageState `protogen:"open.v1"` DownloadUrl string `protobuf:"bytes,1,opt,name=download_url,json=downloadUrl,proto3" json:"download_url,omitempty"` // pre-authenticated object-storage URL - ExpiresAt int64 `protobuf:"varint,2,opt,name=expires_at,json=expiresAt,proto3" json:"expires_at,omitempty"` // of the URL, not the database - Tip int64 `protobuf:"varint,3,opt,name=tip,proto3" json:"tip,omitempty"` // what the dump is consistent at + ExpiresAt *timestamppb.Timestamp `protobuf:"bytes,2,opt,name=expires_at,json=expiresAt,proto3" json:"expires_at,omitempty"` // of the URL, not the database + Tip int64 `protobuf:"varint,3,opt,name=tip,proto3" json:"tip,omitempty"` // what the export is consistent at unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } -func (x *AgentDB_DumpResponse) Reset() { - *x = AgentDB_DumpResponse{} +func (x *AgentDB_ExportResponse) Reset() { + *x = AgentDB_ExportResponse{} mi := &file_livekit_agentdb_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } -func (x *AgentDB_DumpResponse) String() string { +func (x *AgentDB_ExportResponse) String() string { return protoimpl.X.MessageStringOf(x) } -func (*AgentDB_DumpResponse) ProtoMessage() {} +func (*AgentDB_ExportResponse) ProtoMessage() {} -func (x *AgentDB_DumpResponse) ProtoReflect() protoreflect.Message { +func (x *AgentDB_ExportResponse) ProtoReflect() protoreflect.Message { mi := &file_livekit_agentdb_proto_msgTypes[10] if x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) @@ -660,26 +658,26 @@ func (x *AgentDB_DumpResponse) ProtoReflect() protoreflect.Message { return mi.MessageOf(x) } -// Deprecated: Use AgentDB_DumpResponse.ProtoReflect.Descriptor instead. -func (*AgentDB_DumpResponse) Descriptor() ([]byte, []int) { +// Deprecated: Use AgentDB_ExportResponse.ProtoReflect.Descriptor instead. +func (*AgentDB_ExportResponse) Descriptor() ([]byte, []int) { return file_livekit_agentdb_proto_rawDescGZIP(), []int{0, 9} } -func (x *AgentDB_DumpResponse) GetDownloadUrl() string { +func (x *AgentDB_ExportResponse) GetDownloadUrl() string { if x != nil { return x.DownloadUrl } return "" } -func (x *AgentDB_DumpResponse) GetExpiresAt() int64 { +func (x *AgentDB_ExportResponse) GetExpiresAt() *timestamppb.Timestamp { if x != nil { return x.ExpiresAt } - return 0 + return nil } -func (x *AgentDB_DumpResponse) GetTip() int64 { +func (x *AgentDB_ExportResponse) GetTip() int64 { if x != nil { return x.Tip } @@ -896,7 +894,7 @@ type AgentDB_Wire_ClientMessage_Query struct { } type AgentDB_Wire_ClientMessage_Batch struct { - Batch *AgentDB_Wire_Batch `protobuf:"bytes,5,opt,name=batch,proto3,oneof"` + Batch *AgentDB_Wire_Batch `protobuf:"bytes,5,opt,name=batch,proto3,oneof"` // answers one result per statement, then Done } type AgentDB_Wire_ClientMessage_Begin struct { @@ -1304,9 +1302,15 @@ func (x *AgentDB_Wire_Statement) GetLang() AgentDB_Wire_QueryLang { return AgentDB_Wire_SQL } +// Applied atomically, in order, and answered with one result per +// statement, in order: Columns then ColumnBatch frames for a statement +// that returns rows, one ExecResult for one that does not, each tagged +// with the statement's 0-based index, then a single Done for the whole +// batch. A statement that returns no rows still sends its Columns. Credit +// paces the ColumnBatch frames of the batch as a whole. type AgentDB_Wire_Batch struct { state protoimpl.MessageState `protogen:"open.v1"` - Statements []*AgentDB_Wire_Statement `protobuf:"bytes,1,rep,name=statements,proto3" json:"statements,omitempty"` // applied atomically, in order + Statements []*AgentDB_Wire_Statement `protobuf:"bytes,1,rep,name=statements,proto3" json:"statements,omitempty"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -1747,6 +1751,7 @@ func (x *AgentDB_Wire_HelloOk) GetPingTimeoutMs() uint32 { type AgentDB_Wire_Columns struct { state protoimpl.MessageState `protogen:"open.v1"` Names []string `protobuf:"bytes,1,rep,name=names,proto3" json:"names,omitempty"` + Statement uint32 `protobuf:"varint,2,opt,name=statement,proto3" json:"statement,omitempty"` // index within a Batch; 0 and unused for a Query unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -1788,6 +1793,13 @@ func (x *AgentDB_Wire_Columns) GetNames() []string { return nil } +func (x *AgentDB_Wire_Columns) GetStatement() uint32 { + if x != nil { + return x.Statement + } + return 0 +} + // Values are typed per row, as SQLite types them, so a column may mix // classes: walk `types` and take the next entry from the matching array. Text // and blobs are concatenated with one exclusive end offset each, so value i @@ -1889,6 +1901,7 @@ type AgentDB_Wire_ColumnBatch struct { state protoimpl.MessageState `protogen:"open.v1"` Columns []*AgentDB_Wire_Column `protobuf:"bytes,1,rep,name=columns,proto3" json:"columns,omitempty"` // one per name in Columns Rows uint32 `protobuf:"varint,2,opt,name=rows,proto3" json:"rows,omitempty"` + Statement uint32 `protobuf:"varint,3,opt,name=statement,proto3" json:"statement,omitempty"` // index within a Batch; 0 and unused for a Query unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -1937,11 +1950,19 @@ func (x *AgentDB_Wire_ColumnBatch) GetRows() uint32 { return 0 } +func (x *AgentDB_Wire_ColumnBatch) GetStatement() uint32 { + if x != nil { + return x.Statement + } + return 0 +} + type AgentDB_Wire_ExecResult struct { state protoimpl.MessageState `protogen:"open.v1"` RowsAffected int64 `protobuf:"varint,1,opt,name=rows_affected,json=rowsAffected,proto3" json:"rows_affected,omitempty"` LastInsertId int64 `protobuf:"varint,2,opt,name=last_insert_id,json=lastInsertId,proto3" json:"last_insert_id,omitempty"` Tip int64 `protobuf:"varint,3,opt,name=tip,proto3" json:"tip,omitempty"` + Statement uint32 `protobuf:"varint,4,opt,name=statement,proto3" json:"statement,omitempty"` // index within a Batch; 0 and unused for an Exec unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -1997,6 +2018,13 @@ func (x *AgentDB_Wire_ExecResult) GetTip() int64 { return 0 } +func (x *AgentDB_Wire_ExecResult) GetStatement() uint32 { + if x != nil { + return x.Statement + } + return 0 +} + type AgentDB_Wire_Done struct { state protoimpl.MessageState `protogen:"open.v1"` Tip int64 `protobuf:"varint,1,opt,name=tip,proto3" json:"tip,omitempty"` // the snapshot the query ran at @@ -2105,17 +2133,15 @@ var File_livekit_agentdb_proto protoreflect.FileDescriptor const file_livekit_agentdb_proto_rawDesc = "" + "\n" + - "\x15livekit_agentdb.proto\x12\alivekit\"\xd8\x19\n" + - "\aAgentDB\x1aH\n" + - "\rCreateRequest\x12\x16\n" + - "\x06region\x18\x01 \x01(\tR\x06region\x12\x1f\n" + - "\vttl_seconds\x18\x02 \x01(\x03R\n" + - "ttlSeconds\x1aP\n" + + "\x15livekit_agentdb.proto\x12\alivekit\x1a\x1egoogle/protobuf/duration.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"\x9c\x1b\n" + + "\aAgentDB\x1a<\n" + + "\rCreateRequest\x12+\n" + + "\x03ttl\x18\x01 \x01(\v2\x19.google.protobuf.DurationR\x03ttl\x1al\n" + "\x0eCreateResponse\x12\x1f\n" + "\vdatabase_id\x18\x01 \x01(\tR\n" + - "databaseId\x12\x1d\n" + + "databaseId\x129\n" + "\n" + - "expires_at\x18\x02 \x01(\x03R\texpiresAt\x1a-\n" + + "expires_at\x18\x02 \x01(\v2\x1a.google.protobuf.TimestampR\texpiresAt\x1a-\n" + "\n" + "GetRequest\x12\x1f\n" + "\vdatabase_id\x18\x01 \x01(\tR\n" + @@ -2126,28 +2152,28 @@ const file_livekit_agentdb_proto_rawDesc = "" + "page_token\x18\x02 \x01(\tR\tpageToken\x1at\n" + "\fListResponse\x12<\n" + "\tdatabases\x18\x01 \x03(\v2\x1e.livekit.AgentDB.AgentDatabaseR\tdatabases\x12&\n" + - "\x0fnext_page_token\x18\x02 \x01(\tR\rnextPageToken\x1a\x98\x01\n" + + "\x0fnext_page_token\x18\x02 \x01(\tR\rnextPageToken\x1a\xd0\x01\n" + "\rAgentDatabase\x12\x1f\n" + "\vdatabase_id\x18\x01 \x01(\tR\n" + "databaseId\x12\x16\n" + - "\x06region\x18\x02 \x01(\tR\x06region\x12\x1d\n" + + "\x06region\x18\x02 \x01(\tR\x06region\x129\n" + "\n" + - "created_at\x18\x03 \x01(\x03R\tcreatedAt\x12\x1d\n" + + "created_at\x18\x03 \x01(\v2\x1a.google.protobuf.TimestampR\tcreatedAt\x129\n" + "\n" + - "expires_at\x18\x04 \x01(\x03R\texpiresAt\x12\x10\n" + + "expires_at\x18\x04 \x01(\v2\x1a.google.protobuf.TimestampR\texpiresAt\x12\x10\n" + "\x03tip\x18\x05 \x01(\x03R\x03tip\x1a0\n" + "\rDeleteRequest\x12\x1f\n" + "\vdatabase_id\x18\x01 \x01(\tR\n" + "databaseId\x1a\x10\n" + - "\x0eDeleteResponse\x1a.\n" + - "\vDumpRequest\x12\x1f\n" + + "\x0eDeleteResponse\x1a0\n" + + "\rExportRequest\x12\x1f\n" + "\vdatabase_id\x18\x01 \x01(\tR\n" + - "databaseId\x1ab\n" + - "\fDumpResponse\x12!\n" + - "\fdownload_url\x18\x01 \x01(\tR\vdownloadUrl\x12\x1d\n" + + "databaseId\x1a\x80\x01\n" + + "\x0eExportResponse\x12!\n" + + "\fdownload_url\x18\x01 \x01(\tR\vdownloadUrl\x129\n" + "\n" + - "expires_at\x18\x02 \x01(\x03R\texpiresAt\x12\x10\n" + - "\x03tip\x18\x03 \x01(\x03R\x03tip\x1a\xcd\x13\n" + + "expires_at\x18\x02 \x01(\v2\x1a.google.protobuf.TimestampR\texpiresAt\x12\x10\n" + + "\x03tip\x18\x03 \x01(\x03R\x03tip\x1a\xa8\x14\n" + "\x04Wire\x1a\xe0\x04\n" + "\rClientMessage\x12\x1d\n" + "\n" + @@ -2213,9 +2239,10 @@ const file_livekit_agentdb_proto_rawDesc = "" + "\aHelloOk\x12\x10\n" + "\x03tip\x18\x01 \x01(\x03R\x03tip\x12(\n" + "\x10ping_interval_ms\x18\x02 \x01(\rR\x0epingIntervalMs\x12&\n" + - "\x0fping_timeout_ms\x18\x03 \x01(\rR\rpingTimeoutMs\x1a\x1f\n" + + "\x0fping_timeout_ms\x18\x03 \x01(\rR\rpingTimeoutMs\x1a=\n" + "\aColumns\x12\x14\n" + - "\x05names\x18\x01 \x03(\tR\x05names\x1a\xc0\x01\n" + + "\x05names\x18\x01 \x03(\tR\x05names\x12\x1c\n" + + "\tstatement\x18\x02 \x01(\rR\tstatement\x1a\xc0\x01\n" + "\x06Column\x12\x14\n" + "\x05types\x18\x01 \x01(\fR\x05types\x12\x12\n" + "\x04ints\x18\x02 \x03(\x12R\x04ints\x12\x18\n" + @@ -2223,15 +2250,17 @@ const file_livekit_agentdb_proto_rawDesc = "" + "\ttext_data\x18\x04 \x01(\fR\btextData\x12\x1b\n" + "\ttext_ends\x18\x05 \x03(\rR\btextEnds\x12\x1b\n" + "\tblob_data\x18\x06 \x01(\fR\bblobData\x12\x1b\n" + - "\tblob_ends\x18\a \x03(\rR\bblobEnds\x1aY\n" + + "\tblob_ends\x18\a \x03(\rR\bblobEnds\x1aw\n" + "\vColumnBatch\x126\n" + "\acolumns\x18\x01 \x03(\v2\x1c.livekit.AgentDB.Wire.ColumnR\acolumns\x12\x12\n" + - "\x04rows\x18\x02 \x01(\rR\x04rows\x1ai\n" + + "\x04rows\x18\x02 \x01(\rR\x04rows\x12\x1c\n" + + "\tstatement\x18\x03 \x01(\rR\tstatement\x1a\x87\x01\n" + "\n" + "ExecResult\x12#\n" + "\rrows_affected\x18\x01 \x01(\x03R\frowsAffected\x12$\n" + "\x0elast_insert_id\x18\x02 \x01(\x03R\flastInsertId\x12\x10\n" + - "\x03tip\x18\x03 \x01(\x03R\x03tip\x1a7\n" + + "\x03tip\x18\x03 \x01(\x03R\x03tip\x12\x1c\n" + + "\tstatement\x18\x04 \x01(\rR\tstatement\x1a7\n" + "\x04Done\x12\x10\n" + "\x03tip\x18\x01 \x01(\x03R\x03tip\x12\x1d\n" + "\n" + @@ -2247,13 +2276,7 @@ const file_livekit_agentdb_proto_rawDesc = "" + "\n" + "\x06DOUBLE\x10\x02\x12\b\n" + "\x04TEXT\x10\x03\x12\b\n" + - "\x04BLOB\x10\x042\x9d\x03\n" + - "\x0eAgentDBService\x12Q\n" + - "\x0eCreateDatabase\x12\x1e.livekit.AgentDB.CreateRequest\x1a\x1f.livekit.AgentDB.CreateResponse\x12J\n" + - "\vGetDatabase\x12\x1b.livekit.AgentDB.GetRequest\x1a\x1e.livekit.AgentDB.AgentDatabase\x12L\n" + - "\rListDatabases\x12\x1c.livekit.AgentDB.ListRequest\x1a\x1d.livekit.AgentDB.ListResponse\x12Q\n" + - "\x0eDeleteDatabase\x12\x1e.livekit.AgentDB.DeleteRequest\x1a\x1f.livekit.AgentDB.DeleteResponse\x12K\n" + - "\fDumpDatabase\x12\x1c.livekit.AgentDB.DumpRequest\x1a\x1d.livekit.AgentDB.DumpResponseBFZ#github.com/livekit/protocol/livekit\xaa\x02\rLiveKit.Proto\xea\x02\x0eLiveKit::Protob\x06proto3" + "\x04BLOB\x10\x04BFZ#github.com/livekit/protocol/livekit\xaa\x02\rLiveKit.Proto\xea\x02\x0eLiveKit::Protob\x06proto3" var ( file_livekit_agentdb_proto_rawDescOnce sync.Once @@ -2281,8 +2304,8 @@ var file_livekit_agentdb_proto_goTypes = []any{ (*AgentDB_AgentDatabase)(nil), // 8: livekit.AgentDB.AgentDatabase (*AgentDB_DeleteRequest)(nil), // 9: livekit.AgentDB.DeleteRequest (*AgentDB_DeleteResponse)(nil), // 10: livekit.AgentDB.DeleteResponse - (*AgentDB_DumpRequest)(nil), // 11: livekit.AgentDB.DumpRequest - (*AgentDB_DumpResponse)(nil), // 12: livekit.AgentDB.DumpResponse + (*AgentDB_ExportRequest)(nil), // 11: livekit.AgentDB.ExportRequest + (*AgentDB_ExportResponse)(nil), // 12: livekit.AgentDB.ExportResponse (*AgentDB_Wire)(nil), // 13: livekit.AgentDB.Wire (*AgentDB_Wire_ClientMessage)(nil), // 14: livekit.AgentDB.Wire.ClientMessage (*AgentDB_Wire_ServerMessage)(nil), // 15: livekit.AgentDB.Wire.ServerMessage @@ -2304,45 +2327,42 @@ var file_livekit_agentdb_proto_goTypes = []any{ (*AgentDB_Wire_ExecResult)(nil), // 31: livekit.AgentDB.Wire.ExecResult (*AgentDB_Wire_Done)(nil), // 32: livekit.AgentDB.Wire.Done (*AgentDB_Wire_Error)(nil), // 33: livekit.AgentDB.Wire.Error + (*durationpb.Duration)(nil), // 34: google.protobuf.Duration + (*timestamppb.Timestamp)(nil), // 35: google.protobuf.Timestamp } var file_livekit_agentdb_proto_depIdxs = []int32{ - 8, // 0: livekit.AgentDB.ListResponse.databases:type_name -> livekit.AgentDB.AgentDatabase - 26, // 1: livekit.AgentDB.Wire.ClientMessage.hello:type_name -> livekit.AgentDB.Wire.Hello - 17, // 2: livekit.AgentDB.Wire.ClientMessage.exec:type_name -> livekit.AgentDB.Wire.Statement - 17, // 3: livekit.AgentDB.Wire.ClientMessage.query:type_name -> livekit.AgentDB.Wire.Statement - 18, // 4: livekit.AgentDB.Wire.ClientMessage.batch:type_name -> livekit.AgentDB.Wire.Batch - 19, // 5: livekit.AgentDB.Wire.ClientMessage.begin:type_name -> livekit.AgentDB.Wire.Begin - 20, // 6: livekit.AgentDB.Wire.ClientMessage.commit:type_name -> livekit.AgentDB.Wire.Commit - 21, // 7: livekit.AgentDB.Wire.ClientMessage.rollback:type_name -> livekit.AgentDB.Wire.Rollback - 22, // 8: livekit.AgentDB.Wire.ClientMessage.cancel:type_name -> livekit.AgentDB.Wire.Cancel - 23, // 9: livekit.AgentDB.Wire.ClientMessage.credit:type_name -> livekit.AgentDB.Wire.Credit - 24, // 10: livekit.AgentDB.Wire.ClientMessage.ping:type_name -> livekit.AgentDB.Wire.Ping - 27, // 11: livekit.AgentDB.Wire.ServerMessage.hello_ok:type_name -> livekit.AgentDB.Wire.HelloOk - 28, // 12: livekit.AgentDB.Wire.ServerMessage.columns:type_name -> livekit.AgentDB.Wire.Columns - 30, // 13: livekit.AgentDB.Wire.ServerMessage.column_batch:type_name -> livekit.AgentDB.Wire.ColumnBatch - 31, // 14: livekit.AgentDB.Wire.ServerMessage.exec_result:type_name -> livekit.AgentDB.Wire.ExecResult - 32, // 15: livekit.AgentDB.Wire.ServerMessage.done:type_name -> livekit.AgentDB.Wire.Done - 33, // 16: livekit.AgentDB.Wire.ServerMessage.error:type_name -> livekit.AgentDB.Wire.Error - 25, // 17: livekit.AgentDB.Wire.ServerMessage.pong:type_name -> livekit.AgentDB.Wire.Pong - 16, // 18: livekit.AgentDB.Wire.Statement.params:type_name -> livekit.AgentDB.Wire.Value - 0, // 19: livekit.AgentDB.Wire.Statement.lang:type_name -> livekit.AgentDB.Wire.QueryLang - 17, // 20: livekit.AgentDB.Wire.Batch.statements:type_name -> livekit.AgentDB.Wire.Statement - 29, // 21: livekit.AgentDB.Wire.ColumnBatch.columns:type_name -> livekit.AgentDB.Wire.Column - 3, // 22: livekit.AgentDBService.CreateDatabase:input_type -> livekit.AgentDB.CreateRequest - 5, // 23: livekit.AgentDBService.GetDatabase:input_type -> livekit.AgentDB.GetRequest - 6, // 24: livekit.AgentDBService.ListDatabases:input_type -> livekit.AgentDB.ListRequest - 9, // 25: livekit.AgentDBService.DeleteDatabase:input_type -> livekit.AgentDB.DeleteRequest - 11, // 26: livekit.AgentDBService.DumpDatabase:input_type -> livekit.AgentDB.DumpRequest - 4, // 27: livekit.AgentDBService.CreateDatabase:output_type -> livekit.AgentDB.CreateResponse - 8, // 28: livekit.AgentDBService.GetDatabase:output_type -> livekit.AgentDB.AgentDatabase - 7, // 29: livekit.AgentDBService.ListDatabases:output_type -> livekit.AgentDB.ListResponse - 10, // 30: livekit.AgentDBService.DeleteDatabase:output_type -> livekit.AgentDB.DeleteResponse - 12, // 31: livekit.AgentDBService.DumpDatabase:output_type -> livekit.AgentDB.DumpResponse - 27, // [27:32] is the sub-list for method output_type - 22, // [22:27] is the sub-list for method input_type - 22, // [22:22] is the sub-list for extension type_name - 22, // [22:22] is the sub-list for extension extendee - 0, // [0:22] is the sub-list for field type_name + 34, // 0: livekit.AgentDB.CreateRequest.ttl:type_name -> google.protobuf.Duration + 35, // 1: livekit.AgentDB.CreateResponse.expires_at:type_name -> google.protobuf.Timestamp + 8, // 2: livekit.AgentDB.ListResponse.databases:type_name -> livekit.AgentDB.AgentDatabase + 35, // 3: livekit.AgentDB.AgentDatabase.created_at:type_name -> google.protobuf.Timestamp + 35, // 4: livekit.AgentDB.AgentDatabase.expires_at:type_name -> google.protobuf.Timestamp + 35, // 5: livekit.AgentDB.ExportResponse.expires_at:type_name -> google.protobuf.Timestamp + 26, // 6: livekit.AgentDB.Wire.ClientMessage.hello:type_name -> livekit.AgentDB.Wire.Hello + 17, // 7: livekit.AgentDB.Wire.ClientMessage.exec:type_name -> livekit.AgentDB.Wire.Statement + 17, // 8: livekit.AgentDB.Wire.ClientMessage.query:type_name -> livekit.AgentDB.Wire.Statement + 18, // 9: livekit.AgentDB.Wire.ClientMessage.batch:type_name -> livekit.AgentDB.Wire.Batch + 19, // 10: livekit.AgentDB.Wire.ClientMessage.begin:type_name -> livekit.AgentDB.Wire.Begin + 20, // 11: livekit.AgentDB.Wire.ClientMessage.commit:type_name -> livekit.AgentDB.Wire.Commit + 21, // 12: livekit.AgentDB.Wire.ClientMessage.rollback:type_name -> livekit.AgentDB.Wire.Rollback + 22, // 13: livekit.AgentDB.Wire.ClientMessage.cancel:type_name -> livekit.AgentDB.Wire.Cancel + 23, // 14: livekit.AgentDB.Wire.ClientMessage.credit:type_name -> livekit.AgentDB.Wire.Credit + 24, // 15: livekit.AgentDB.Wire.ClientMessage.ping:type_name -> livekit.AgentDB.Wire.Ping + 27, // 16: livekit.AgentDB.Wire.ServerMessage.hello_ok:type_name -> livekit.AgentDB.Wire.HelloOk + 28, // 17: livekit.AgentDB.Wire.ServerMessage.columns:type_name -> livekit.AgentDB.Wire.Columns + 30, // 18: livekit.AgentDB.Wire.ServerMessage.column_batch:type_name -> livekit.AgentDB.Wire.ColumnBatch + 31, // 19: livekit.AgentDB.Wire.ServerMessage.exec_result:type_name -> livekit.AgentDB.Wire.ExecResult + 32, // 20: livekit.AgentDB.Wire.ServerMessage.done:type_name -> livekit.AgentDB.Wire.Done + 33, // 21: livekit.AgentDB.Wire.ServerMessage.error:type_name -> livekit.AgentDB.Wire.Error + 25, // 22: livekit.AgentDB.Wire.ServerMessage.pong:type_name -> livekit.AgentDB.Wire.Pong + 16, // 23: livekit.AgentDB.Wire.Statement.params:type_name -> livekit.AgentDB.Wire.Value + 0, // 24: livekit.AgentDB.Wire.Statement.lang:type_name -> livekit.AgentDB.Wire.QueryLang + 17, // 25: livekit.AgentDB.Wire.Batch.statements:type_name -> livekit.AgentDB.Wire.Statement + 29, // 26: livekit.AgentDB.Wire.ColumnBatch.columns:type_name -> livekit.AgentDB.Wire.Column + 27, // [27:27] is the sub-list for method output_type + 27, // [27:27] is the sub-list for method input_type + 27, // [27:27] is the sub-list for extension type_name + 27, // [27:27] is the sub-list for extension extendee + 0, // [0:27] is the sub-list for field type_name } func init() { file_livekit_agentdb_proto_init() } @@ -2386,7 +2406,7 @@ func file_livekit_agentdb_proto_init() { NumEnums: 2, NumMessages: 32, NumExtensions: 0, - NumServices: 1, + NumServices: 0, }, GoTypes: file_livekit_agentdb_proto_goTypes, DependencyIndexes: file_livekit_agentdb_proto_depIdxs, diff --git a/livekit/livekit_agentdb.twirp.go b/livekit/livekit_agentdb.twirp.go deleted file mode 100644 index 9c7625944..000000000 --- a/livekit/livekit_agentdb.twirp.go +++ /dev/null @@ -1,1736 +0,0 @@ -// Code generated by protoc-gen-twirp v8.1.3, DO NOT EDIT. -// source: livekit_agentdb.proto - -package livekit - -import context "context" -import fmt "fmt" -import http "net/http" -import io "io" -import json "encoding/json" -import strconv "strconv" -import strings "strings" - -import protojson "google.golang.org/protobuf/encoding/protojson" -import proto "google.golang.org/protobuf/proto" -import twirp "github.com/twitchtv/twirp" -import ctxsetters "github.com/twitchtv/twirp/ctxsetters" - -// Version compatibility assertion. -// If the constant is not defined in the package, that likely means -// the package needs to be updated to work with this generated code. -// See https://twitchtv.github.io/twirp/docs/version_matrix.html -const _ = twirp.TwirpPackageMinVersion_8_1_0 - -// ======================== -// AgentDBService Interface -// ======================== - -// AgentDBService is the lifecycle and export API for SQLite databases; queries -// run over the data plane below. The project comes from the access token. -type AgentDBService interface { - CreateDatabase(context.Context, *AgentDB_CreateRequest) (*AgentDB_CreateResponse, error) - - GetDatabase(context.Context, *AgentDB_GetRequest) (*AgentDB_AgentDatabase, error) - - ListDatabases(context.Context, *AgentDB_ListRequest) (*AgentDB_ListResponse, error) - - // Deletes the stored data, not just the metadata. - DeleteDatabase(context.Context, *AgentDB_DeleteRequest) (*AgentDB_DeleteResponse, error) - - // Exports a consistent SQLite file as a time-limited download URL. - DumpDatabase(context.Context, *AgentDB_DumpRequest) (*AgentDB_DumpResponse, error) -} - -// ============================== -// AgentDBService Protobuf Client -// ============================== - -type agentDBServiceProtobufClient struct { - client HTTPClient - urls [5]string - interceptor twirp.Interceptor - opts twirp.ClientOptions -} - -// NewAgentDBServiceProtobufClient creates a Protobuf client that implements the AgentDBService interface. -// It communicates using Protobuf and can be configured with a custom HTTPClient. -func NewAgentDBServiceProtobufClient(baseURL string, client HTTPClient, opts ...twirp.ClientOption) AgentDBService { - if c, ok := client.(*http.Client); ok { - client = withoutRedirects(c) - } - - clientOpts := twirp.ClientOptions{} - for _, o := range opts { - o(&clientOpts) - } - - // Using ReadOpt allows backwards and forwards compatibility with new options in the future - literalURLs := false - _ = clientOpts.ReadOpt("literalURLs", &literalURLs) - var pathPrefix string - if ok := clientOpts.ReadOpt("pathPrefix", &pathPrefix); !ok { - pathPrefix = "/twirp" // default prefix - } - - // Build method URLs: []/./ - serviceURL := sanitizeBaseURL(baseURL) - serviceURL += baseServicePath(pathPrefix, "livekit", "AgentDBService") - urls := [5]string{ - serviceURL + "CreateDatabase", - serviceURL + "GetDatabase", - serviceURL + "ListDatabases", - serviceURL + "DeleteDatabase", - serviceURL + "DumpDatabase", - } - - return &agentDBServiceProtobufClient{ - client: client, - urls: urls, - interceptor: twirp.ChainInterceptors(clientOpts.Interceptors...), - opts: clientOpts, - } -} - -func (c *agentDBServiceProtobufClient) CreateDatabase(ctx context.Context, in *AgentDB_CreateRequest) (*AgentDB_CreateResponse, error) { - ctx = ctxsetters.WithPackageName(ctx, "livekit") - ctx = ctxsetters.WithServiceName(ctx, "AgentDBService") - ctx = ctxsetters.WithMethodName(ctx, "CreateDatabase") - caller := c.callCreateDatabase - if c.interceptor != nil { - caller = func(ctx context.Context, req *AgentDB_CreateRequest) (*AgentDB_CreateResponse, error) { - resp, err := c.interceptor( - func(ctx context.Context, req interface{}) (interface{}, error) { - typedReq, ok := req.(*AgentDB_CreateRequest) - if !ok { - return nil, twirp.InternalError("failed type assertion req.(*AgentDB_CreateRequest) when calling interceptor") - } - return c.callCreateDatabase(ctx, typedReq) - }, - )(ctx, req) - if resp != nil { - typedResp, ok := resp.(*AgentDB_CreateResponse) - if !ok { - return nil, twirp.InternalError("failed type assertion resp.(*AgentDB_CreateResponse) when calling interceptor") - } - return typedResp, err - } - return nil, err - } - } - return caller(ctx, in) -} - -func (c *agentDBServiceProtobufClient) callCreateDatabase(ctx context.Context, in *AgentDB_CreateRequest) (*AgentDB_CreateResponse, error) { - out := new(AgentDB_CreateResponse) - ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[0], in, out) - if err != nil { - twerr, ok := err.(twirp.Error) - if !ok { - twerr = twirp.InternalErrorWith(err) - } - callClientError(ctx, c.opts.Hooks, twerr) - return nil, err - } - - callClientResponseReceived(ctx, c.opts.Hooks) - - return out, nil -} - -func (c *agentDBServiceProtobufClient) GetDatabase(ctx context.Context, in *AgentDB_GetRequest) (*AgentDB_AgentDatabase, error) { - ctx = ctxsetters.WithPackageName(ctx, "livekit") - ctx = ctxsetters.WithServiceName(ctx, "AgentDBService") - ctx = ctxsetters.WithMethodName(ctx, "GetDatabase") - caller := c.callGetDatabase - if c.interceptor != nil { - caller = func(ctx context.Context, req *AgentDB_GetRequest) (*AgentDB_AgentDatabase, error) { - resp, err := c.interceptor( - func(ctx context.Context, req interface{}) (interface{}, error) { - typedReq, ok := req.(*AgentDB_GetRequest) - if !ok { - return nil, twirp.InternalError("failed type assertion req.(*AgentDB_GetRequest) when calling interceptor") - } - return c.callGetDatabase(ctx, typedReq) - }, - )(ctx, req) - if resp != nil { - typedResp, ok := resp.(*AgentDB_AgentDatabase) - if !ok { - return nil, twirp.InternalError("failed type assertion resp.(*AgentDB_AgentDatabase) when calling interceptor") - } - return typedResp, err - } - return nil, err - } - } - return caller(ctx, in) -} - -func (c *agentDBServiceProtobufClient) callGetDatabase(ctx context.Context, in *AgentDB_GetRequest) (*AgentDB_AgentDatabase, error) { - out := new(AgentDB_AgentDatabase) - ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[1], in, out) - if err != nil { - twerr, ok := err.(twirp.Error) - if !ok { - twerr = twirp.InternalErrorWith(err) - } - callClientError(ctx, c.opts.Hooks, twerr) - return nil, err - } - - callClientResponseReceived(ctx, c.opts.Hooks) - - return out, nil -} - -func (c *agentDBServiceProtobufClient) ListDatabases(ctx context.Context, in *AgentDB_ListRequest) (*AgentDB_ListResponse, error) { - ctx = ctxsetters.WithPackageName(ctx, "livekit") - ctx = ctxsetters.WithServiceName(ctx, "AgentDBService") - ctx = ctxsetters.WithMethodName(ctx, "ListDatabases") - caller := c.callListDatabases - if c.interceptor != nil { - caller = func(ctx context.Context, req *AgentDB_ListRequest) (*AgentDB_ListResponse, error) { - resp, err := c.interceptor( - func(ctx context.Context, req interface{}) (interface{}, error) { - typedReq, ok := req.(*AgentDB_ListRequest) - if !ok { - return nil, twirp.InternalError("failed type assertion req.(*AgentDB_ListRequest) when calling interceptor") - } - return c.callListDatabases(ctx, typedReq) - }, - )(ctx, req) - if resp != nil { - typedResp, ok := resp.(*AgentDB_ListResponse) - if !ok { - return nil, twirp.InternalError("failed type assertion resp.(*AgentDB_ListResponse) when calling interceptor") - } - return typedResp, err - } - return nil, err - } - } - return caller(ctx, in) -} - -func (c *agentDBServiceProtobufClient) callListDatabases(ctx context.Context, in *AgentDB_ListRequest) (*AgentDB_ListResponse, error) { - out := new(AgentDB_ListResponse) - ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[2], in, out) - if err != nil { - twerr, ok := err.(twirp.Error) - if !ok { - twerr = twirp.InternalErrorWith(err) - } - callClientError(ctx, c.opts.Hooks, twerr) - return nil, err - } - - callClientResponseReceived(ctx, c.opts.Hooks) - - return out, nil -} - -func (c *agentDBServiceProtobufClient) DeleteDatabase(ctx context.Context, in *AgentDB_DeleteRequest) (*AgentDB_DeleteResponse, error) { - ctx = ctxsetters.WithPackageName(ctx, "livekit") - ctx = ctxsetters.WithServiceName(ctx, "AgentDBService") - ctx = ctxsetters.WithMethodName(ctx, "DeleteDatabase") - caller := c.callDeleteDatabase - if c.interceptor != nil { - caller = func(ctx context.Context, req *AgentDB_DeleteRequest) (*AgentDB_DeleteResponse, error) { - resp, err := c.interceptor( - func(ctx context.Context, req interface{}) (interface{}, error) { - typedReq, ok := req.(*AgentDB_DeleteRequest) - if !ok { - return nil, twirp.InternalError("failed type assertion req.(*AgentDB_DeleteRequest) when calling interceptor") - } - return c.callDeleteDatabase(ctx, typedReq) - }, - )(ctx, req) - if resp != nil { - typedResp, ok := resp.(*AgentDB_DeleteResponse) - if !ok { - return nil, twirp.InternalError("failed type assertion resp.(*AgentDB_DeleteResponse) when calling interceptor") - } - return typedResp, err - } - return nil, err - } - } - return caller(ctx, in) -} - -func (c *agentDBServiceProtobufClient) callDeleteDatabase(ctx context.Context, in *AgentDB_DeleteRequest) (*AgentDB_DeleteResponse, error) { - out := new(AgentDB_DeleteResponse) - ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[3], in, out) - if err != nil { - twerr, ok := err.(twirp.Error) - if !ok { - twerr = twirp.InternalErrorWith(err) - } - callClientError(ctx, c.opts.Hooks, twerr) - return nil, err - } - - callClientResponseReceived(ctx, c.opts.Hooks) - - return out, nil -} - -func (c *agentDBServiceProtobufClient) DumpDatabase(ctx context.Context, in *AgentDB_DumpRequest) (*AgentDB_DumpResponse, error) { - ctx = ctxsetters.WithPackageName(ctx, "livekit") - ctx = ctxsetters.WithServiceName(ctx, "AgentDBService") - ctx = ctxsetters.WithMethodName(ctx, "DumpDatabase") - caller := c.callDumpDatabase - if c.interceptor != nil { - caller = func(ctx context.Context, req *AgentDB_DumpRequest) (*AgentDB_DumpResponse, error) { - resp, err := c.interceptor( - func(ctx context.Context, req interface{}) (interface{}, error) { - typedReq, ok := req.(*AgentDB_DumpRequest) - if !ok { - return nil, twirp.InternalError("failed type assertion req.(*AgentDB_DumpRequest) when calling interceptor") - } - return c.callDumpDatabase(ctx, typedReq) - }, - )(ctx, req) - if resp != nil { - typedResp, ok := resp.(*AgentDB_DumpResponse) - if !ok { - return nil, twirp.InternalError("failed type assertion resp.(*AgentDB_DumpResponse) when calling interceptor") - } - return typedResp, err - } - return nil, err - } - } - return caller(ctx, in) -} - -func (c *agentDBServiceProtobufClient) callDumpDatabase(ctx context.Context, in *AgentDB_DumpRequest) (*AgentDB_DumpResponse, error) { - out := new(AgentDB_DumpResponse) - ctx, err := doProtobufRequest(ctx, c.client, c.opts.Hooks, c.urls[4], in, out) - if err != nil { - twerr, ok := err.(twirp.Error) - if !ok { - twerr = twirp.InternalErrorWith(err) - } - callClientError(ctx, c.opts.Hooks, twerr) - return nil, err - } - - callClientResponseReceived(ctx, c.opts.Hooks) - - return out, nil -} - -// ========================== -// AgentDBService JSON Client -// ========================== - -type agentDBServiceJSONClient struct { - client HTTPClient - urls [5]string - interceptor twirp.Interceptor - opts twirp.ClientOptions -} - -// NewAgentDBServiceJSONClient creates a JSON client that implements the AgentDBService interface. -// It communicates using JSON and can be configured with a custom HTTPClient. -func NewAgentDBServiceJSONClient(baseURL string, client HTTPClient, opts ...twirp.ClientOption) AgentDBService { - if c, ok := client.(*http.Client); ok { - client = withoutRedirects(c) - } - - clientOpts := twirp.ClientOptions{} - for _, o := range opts { - o(&clientOpts) - } - - // Using ReadOpt allows backwards and forwards compatibility with new options in the future - literalURLs := false - _ = clientOpts.ReadOpt("literalURLs", &literalURLs) - var pathPrefix string - if ok := clientOpts.ReadOpt("pathPrefix", &pathPrefix); !ok { - pathPrefix = "/twirp" // default prefix - } - - // Build method URLs: []/./ - serviceURL := sanitizeBaseURL(baseURL) - serviceURL += baseServicePath(pathPrefix, "livekit", "AgentDBService") - urls := [5]string{ - serviceURL + "CreateDatabase", - serviceURL + "GetDatabase", - serviceURL + "ListDatabases", - serviceURL + "DeleteDatabase", - serviceURL + "DumpDatabase", - } - - return &agentDBServiceJSONClient{ - client: client, - urls: urls, - interceptor: twirp.ChainInterceptors(clientOpts.Interceptors...), - opts: clientOpts, - } -} - -func (c *agentDBServiceJSONClient) CreateDatabase(ctx context.Context, in *AgentDB_CreateRequest) (*AgentDB_CreateResponse, error) { - ctx = ctxsetters.WithPackageName(ctx, "livekit") - ctx = ctxsetters.WithServiceName(ctx, "AgentDBService") - ctx = ctxsetters.WithMethodName(ctx, "CreateDatabase") - caller := c.callCreateDatabase - if c.interceptor != nil { - caller = func(ctx context.Context, req *AgentDB_CreateRequest) (*AgentDB_CreateResponse, error) { - resp, err := c.interceptor( - func(ctx context.Context, req interface{}) (interface{}, error) { - typedReq, ok := req.(*AgentDB_CreateRequest) - if !ok { - return nil, twirp.InternalError("failed type assertion req.(*AgentDB_CreateRequest) when calling interceptor") - } - return c.callCreateDatabase(ctx, typedReq) - }, - )(ctx, req) - if resp != nil { - typedResp, ok := resp.(*AgentDB_CreateResponse) - if !ok { - return nil, twirp.InternalError("failed type assertion resp.(*AgentDB_CreateResponse) when calling interceptor") - } - return typedResp, err - } - return nil, err - } - } - return caller(ctx, in) -} - -func (c *agentDBServiceJSONClient) callCreateDatabase(ctx context.Context, in *AgentDB_CreateRequest) (*AgentDB_CreateResponse, error) { - out := new(AgentDB_CreateResponse) - ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[0], in, out) - if err != nil { - twerr, ok := err.(twirp.Error) - if !ok { - twerr = twirp.InternalErrorWith(err) - } - callClientError(ctx, c.opts.Hooks, twerr) - return nil, err - } - - callClientResponseReceived(ctx, c.opts.Hooks) - - return out, nil -} - -func (c *agentDBServiceJSONClient) GetDatabase(ctx context.Context, in *AgentDB_GetRequest) (*AgentDB_AgentDatabase, error) { - ctx = ctxsetters.WithPackageName(ctx, "livekit") - ctx = ctxsetters.WithServiceName(ctx, "AgentDBService") - ctx = ctxsetters.WithMethodName(ctx, "GetDatabase") - caller := c.callGetDatabase - if c.interceptor != nil { - caller = func(ctx context.Context, req *AgentDB_GetRequest) (*AgentDB_AgentDatabase, error) { - resp, err := c.interceptor( - func(ctx context.Context, req interface{}) (interface{}, error) { - typedReq, ok := req.(*AgentDB_GetRequest) - if !ok { - return nil, twirp.InternalError("failed type assertion req.(*AgentDB_GetRequest) when calling interceptor") - } - return c.callGetDatabase(ctx, typedReq) - }, - )(ctx, req) - if resp != nil { - typedResp, ok := resp.(*AgentDB_AgentDatabase) - if !ok { - return nil, twirp.InternalError("failed type assertion resp.(*AgentDB_AgentDatabase) when calling interceptor") - } - return typedResp, err - } - return nil, err - } - } - return caller(ctx, in) -} - -func (c *agentDBServiceJSONClient) callGetDatabase(ctx context.Context, in *AgentDB_GetRequest) (*AgentDB_AgentDatabase, error) { - out := new(AgentDB_AgentDatabase) - ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[1], in, out) - if err != nil { - twerr, ok := err.(twirp.Error) - if !ok { - twerr = twirp.InternalErrorWith(err) - } - callClientError(ctx, c.opts.Hooks, twerr) - return nil, err - } - - callClientResponseReceived(ctx, c.opts.Hooks) - - return out, nil -} - -func (c *agentDBServiceJSONClient) ListDatabases(ctx context.Context, in *AgentDB_ListRequest) (*AgentDB_ListResponse, error) { - ctx = ctxsetters.WithPackageName(ctx, "livekit") - ctx = ctxsetters.WithServiceName(ctx, "AgentDBService") - ctx = ctxsetters.WithMethodName(ctx, "ListDatabases") - caller := c.callListDatabases - if c.interceptor != nil { - caller = func(ctx context.Context, req *AgentDB_ListRequest) (*AgentDB_ListResponse, error) { - resp, err := c.interceptor( - func(ctx context.Context, req interface{}) (interface{}, error) { - typedReq, ok := req.(*AgentDB_ListRequest) - if !ok { - return nil, twirp.InternalError("failed type assertion req.(*AgentDB_ListRequest) when calling interceptor") - } - return c.callListDatabases(ctx, typedReq) - }, - )(ctx, req) - if resp != nil { - typedResp, ok := resp.(*AgentDB_ListResponse) - if !ok { - return nil, twirp.InternalError("failed type assertion resp.(*AgentDB_ListResponse) when calling interceptor") - } - return typedResp, err - } - return nil, err - } - } - return caller(ctx, in) -} - -func (c *agentDBServiceJSONClient) callListDatabases(ctx context.Context, in *AgentDB_ListRequest) (*AgentDB_ListResponse, error) { - out := new(AgentDB_ListResponse) - ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[2], in, out) - if err != nil { - twerr, ok := err.(twirp.Error) - if !ok { - twerr = twirp.InternalErrorWith(err) - } - callClientError(ctx, c.opts.Hooks, twerr) - return nil, err - } - - callClientResponseReceived(ctx, c.opts.Hooks) - - return out, nil -} - -func (c *agentDBServiceJSONClient) DeleteDatabase(ctx context.Context, in *AgentDB_DeleteRequest) (*AgentDB_DeleteResponse, error) { - ctx = ctxsetters.WithPackageName(ctx, "livekit") - ctx = ctxsetters.WithServiceName(ctx, "AgentDBService") - ctx = ctxsetters.WithMethodName(ctx, "DeleteDatabase") - caller := c.callDeleteDatabase - if c.interceptor != nil { - caller = func(ctx context.Context, req *AgentDB_DeleteRequest) (*AgentDB_DeleteResponse, error) { - resp, err := c.interceptor( - func(ctx context.Context, req interface{}) (interface{}, error) { - typedReq, ok := req.(*AgentDB_DeleteRequest) - if !ok { - return nil, twirp.InternalError("failed type assertion req.(*AgentDB_DeleteRequest) when calling interceptor") - } - return c.callDeleteDatabase(ctx, typedReq) - }, - )(ctx, req) - if resp != nil { - typedResp, ok := resp.(*AgentDB_DeleteResponse) - if !ok { - return nil, twirp.InternalError("failed type assertion resp.(*AgentDB_DeleteResponse) when calling interceptor") - } - return typedResp, err - } - return nil, err - } - } - return caller(ctx, in) -} - -func (c *agentDBServiceJSONClient) callDeleteDatabase(ctx context.Context, in *AgentDB_DeleteRequest) (*AgentDB_DeleteResponse, error) { - out := new(AgentDB_DeleteResponse) - ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[3], in, out) - if err != nil { - twerr, ok := err.(twirp.Error) - if !ok { - twerr = twirp.InternalErrorWith(err) - } - callClientError(ctx, c.opts.Hooks, twerr) - return nil, err - } - - callClientResponseReceived(ctx, c.opts.Hooks) - - return out, nil -} - -func (c *agentDBServiceJSONClient) DumpDatabase(ctx context.Context, in *AgentDB_DumpRequest) (*AgentDB_DumpResponse, error) { - ctx = ctxsetters.WithPackageName(ctx, "livekit") - ctx = ctxsetters.WithServiceName(ctx, "AgentDBService") - ctx = ctxsetters.WithMethodName(ctx, "DumpDatabase") - caller := c.callDumpDatabase - if c.interceptor != nil { - caller = func(ctx context.Context, req *AgentDB_DumpRequest) (*AgentDB_DumpResponse, error) { - resp, err := c.interceptor( - func(ctx context.Context, req interface{}) (interface{}, error) { - typedReq, ok := req.(*AgentDB_DumpRequest) - if !ok { - return nil, twirp.InternalError("failed type assertion req.(*AgentDB_DumpRequest) when calling interceptor") - } - return c.callDumpDatabase(ctx, typedReq) - }, - )(ctx, req) - if resp != nil { - typedResp, ok := resp.(*AgentDB_DumpResponse) - if !ok { - return nil, twirp.InternalError("failed type assertion resp.(*AgentDB_DumpResponse) when calling interceptor") - } - return typedResp, err - } - return nil, err - } - } - return caller(ctx, in) -} - -func (c *agentDBServiceJSONClient) callDumpDatabase(ctx context.Context, in *AgentDB_DumpRequest) (*AgentDB_DumpResponse, error) { - out := new(AgentDB_DumpResponse) - ctx, err := doJSONRequest(ctx, c.client, c.opts.Hooks, c.urls[4], in, out) - if err != nil { - twerr, ok := err.(twirp.Error) - if !ok { - twerr = twirp.InternalErrorWith(err) - } - callClientError(ctx, c.opts.Hooks, twerr) - return nil, err - } - - callClientResponseReceived(ctx, c.opts.Hooks) - - return out, nil -} - -// ============================= -// AgentDBService Server Handler -// ============================= - -type agentDBServiceServer struct { - AgentDBService - interceptor twirp.Interceptor - hooks *twirp.ServerHooks - pathPrefix string // prefix for routing - jsonSkipDefaults bool // do not include unpopulated fields (default values) in the response - jsonCamelCase bool // JSON fields are serialized as lowerCamelCase rather than keeping the original proto names -} - -// NewAgentDBServiceServer builds a TwirpServer that can be used as an http.Handler to handle -// HTTP requests that are routed to the right method in the provided svc implementation. -// The opts are twirp.ServerOption modifiers, for example twirp.WithServerHooks(hooks). -func NewAgentDBServiceServer(svc AgentDBService, opts ...interface{}) TwirpServer { - serverOpts := newServerOpts(opts) - - // Using ReadOpt allows backwards and forwards compatibility with new options in the future - jsonSkipDefaults := false - _ = serverOpts.ReadOpt("jsonSkipDefaults", &jsonSkipDefaults) - jsonCamelCase := false - _ = serverOpts.ReadOpt("jsonCamelCase", &jsonCamelCase) - var pathPrefix string - if ok := serverOpts.ReadOpt("pathPrefix", &pathPrefix); !ok { - pathPrefix = "/twirp" // default prefix - } - - return &agentDBServiceServer{ - AgentDBService: svc, - hooks: serverOpts.Hooks, - interceptor: twirp.ChainInterceptors(serverOpts.Interceptors...), - pathPrefix: pathPrefix, - jsonSkipDefaults: jsonSkipDefaults, - jsonCamelCase: jsonCamelCase, - } -} - -// writeError writes an HTTP response with a valid Twirp error format, and triggers hooks. -// If err is not a twirp.Error, it will get wrapped with twirp.InternalErrorWith(err) -func (s *agentDBServiceServer) writeError(ctx context.Context, resp http.ResponseWriter, err error) { - writeError(ctx, resp, err, s.hooks) -} - -// handleRequestBodyError is used to handle error when the twirp server cannot read request -func (s *agentDBServiceServer) handleRequestBodyError(ctx context.Context, resp http.ResponseWriter, msg string, err error) { - if context.Canceled == ctx.Err() { - s.writeError(ctx, resp, twirp.NewError(twirp.Canceled, "failed to read request: context canceled")) - return - } - if context.DeadlineExceeded == ctx.Err() { - s.writeError(ctx, resp, twirp.NewError(twirp.DeadlineExceeded, "failed to read request: deadline exceeded")) - return - } - s.writeError(ctx, resp, twirp.WrapError(malformedRequestError(msg), err)) -} - -// AgentDBServicePathPrefix is a convenience constant that may identify URL paths. -// Should be used with caution, it only matches routes generated by Twirp Go clients, -// with the default "/twirp" prefix and default CamelCase service and method names. -// More info: https://twitchtv.github.io/twirp/docs/routing.html -const AgentDBServicePathPrefix = "/twirp/livekit.AgentDBService/" - -func (s *agentDBServiceServer) ServeHTTP(resp http.ResponseWriter, req *http.Request) { - ctx := req.Context() - ctx = ctxsetters.WithPackageName(ctx, "livekit") - ctx = ctxsetters.WithServiceName(ctx, "AgentDBService") - ctx = ctxsetters.WithResponseWriter(ctx, resp) - - var err error - ctx, err = callRequestReceived(ctx, s.hooks) - if err != nil { - s.writeError(ctx, resp, err) - return - } - - if req.Method != "POST" { - msg := fmt.Sprintf("unsupported method %q (only POST is allowed)", req.Method) - s.writeError(ctx, resp, badRouteError(msg, req.Method, req.URL.Path)) - return - } - - // Verify path format: []/./ - prefix, pkgService, method := parseTwirpPath(req.URL.Path) - if pkgService != "livekit.AgentDBService" { - msg := fmt.Sprintf("no handler for path %q", req.URL.Path) - s.writeError(ctx, resp, badRouteError(msg, req.Method, req.URL.Path)) - return - } - if prefix != s.pathPrefix { - msg := fmt.Sprintf("invalid path prefix %q, expected %q, on path %q", prefix, s.pathPrefix, req.URL.Path) - s.writeError(ctx, resp, badRouteError(msg, req.Method, req.URL.Path)) - return - } - - switch method { - case "CreateDatabase": - s.serveCreateDatabase(ctx, resp, req) - return - case "GetDatabase": - s.serveGetDatabase(ctx, resp, req) - return - case "ListDatabases": - s.serveListDatabases(ctx, resp, req) - return - case "DeleteDatabase": - s.serveDeleteDatabase(ctx, resp, req) - return - case "DumpDatabase": - s.serveDumpDatabase(ctx, resp, req) - return - default: - msg := fmt.Sprintf("no handler for path %q", req.URL.Path) - s.writeError(ctx, resp, badRouteError(msg, req.Method, req.URL.Path)) - return - } -} - -func (s *agentDBServiceServer) serveCreateDatabase(ctx context.Context, resp http.ResponseWriter, req *http.Request) { - header := req.Header.Get("Content-Type") - i := strings.Index(header, ";") - if i == -1 { - i = len(header) - } - switch strings.TrimSpace(strings.ToLower(header[:i])) { - case "application/json": - s.serveCreateDatabaseJSON(ctx, resp, req) - case "application/protobuf": - s.serveCreateDatabaseProtobuf(ctx, resp, req) - default: - msg := fmt.Sprintf("unexpected Content-Type: %q", req.Header.Get("Content-Type")) - twerr := badRouteError(msg, req.Method, req.URL.Path) - s.writeError(ctx, resp, twerr) - } -} - -func (s *agentDBServiceServer) serveCreateDatabaseJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) { - var err error - ctx = ctxsetters.WithMethodName(ctx, "CreateDatabase") - ctx, err = callRequestRouted(ctx, s.hooks) - if err != nil { - s.writeError(ctx, resp, err) - return - } - - d := json.NewDecoder(req.Body) - rawReqBody := json.RawMessage{} - if err := d.Decode(&rawReqBody); err != nil { - s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err) - return - } - reqContent := new(AgentDB_CreateRequest) - unmarshaler := protojson.UnmarshalOptions{DiscardUnknown: true} - if err = unmarshaler.Unmarshal(rawReqBody, reqContent); err != nil { - s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err) - return - } - - handler := s.AgentDBService.CreateDatabase - if s.interceptor != nil { - handler = func(ctx context.Context, req *AgentDB_CreateRequest) (*AgentDB_CreateResponse, error) { - resp, err := s.interceptor( - func(ctx context.Context, req interface{}) (interface{}, error) { - typedReq, ok := req.(*AgentDB_CreateRequest) - if !ok { - return nil, twirp.InternalError("failed type assertion req.(*AgentDB_CreateRequest) when calling interceptor") - } - return s.AgentDBService.CreateDatabase(ctx, typedReq) - }, - )(ctx, req) - if resp != nil { - typedResp, ok := resp.(*AgentDB_CreateResponse) - if !ok { - return nil, twirp.InternalError("failed type assertion resp.(*AgentDB_CreateResponse) when calling interceptor") - } - return typedResp, err - } - return nil, err - } - } - - // Call service method - var respContent *AgentDB_CreateResponse - func() { - defer ensurePanicResponses(ctx, resp, s.hooks) - respContent, err = handler(ctx, reqContent) - }() - - if err != nil { - s.writeError(ctx, resp, err) - return - } - if respContent == nil { - s.writeError(ctx, resp, twirp.InternalError("received a nil *AgentDB_CreateResponse and nil error while calling CreateDatabase. nil responses are not supported")) - return - } - - ctx = callResponsePrepared(ctx, s.hooks) - - marshaler := &protojson.MarshalOptions{UseProtoNames: !s.jsonCamelCase, EmitUnpopulated: !s.jsonSkipDefaults} - respBytes, err := marshaler.Marshal(respContent) - if err != nil { - s.writeError(ctx, resp, wrapInternal(err, "failed to marshal json response")) - return - } - - ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK) - resp.Header().Set("Content-Type", "application/json") - resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes))) - resp.WriteHeader(http.StatusOK) - - if n, err := resp.Write(respBytes); err != nil { - msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error()) - twerr := twirp.NewError(twirp.Unknown, msg) - ctx = callError(ctx, s.hooks, twerr) - } - callResponseSent(ctx, s.hooks) -} - -func (s *agentDBServiceServer) serveCreateDatabaseProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) { - var err error - ctx = ctxsetters.WithMethodName(ctx, "CreateDatabase") - ctx, err = callRequestRouted(ctx, s.hooks) - if err != nil { - s.writeError(ctx, resp, err) - return - } - - buf, err := io.ReadAll(req.Body) - if err != nil { - s.handleRequestBodyError(ctx, resp, "failed to read request body", err) - return - } - reqContent := new(AgentDB_CreateRequest) - if err = proto.Unmarshal(buf, reqContent); err != nil { - s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded")) - return - } - - handler := s.AgentDBService.CreateDatabase - if s.interceptor != nil { - handler = func(ctx context.Context, req *AgentDB_CreateRequest) (*AgentDB_CreateResponse, error) { - resp, err := s.interceptor( - func(ctx context.Context, req interface{}) (interface{}, error) { - typedReq, ok := req.(*AgentDB_CreateRequest) - if !ok { - return nil, twirp.InternalError("failed type assertion req.(*AgentDB_CreateRequest) when calling interceptor") - } - return s.AgentDBService.CreateDatabase(ctx, typedReq) - }, - )(ctx, req) - if resp != nil { - typedResp, ok := resp.(*AgentDB_CreateResponse) - if !ok { - return nil, twirp.InternalError("failed type assertion resp.(*AgentDB_CreateResponse) when calling interceptor") - } - return typedResp, err - } - return nil, err - } - } - - // Call service method - var respContent *AgentDB_CreateResponse - func() { - defer ensurePanicResponses(ctx, resp, s.hooks) - respContent, err = handler(ctx, reqContent) - }() - - if err != nil { - s.writeError(ctx, resp, err) - return - } - if respContent == nil { - s.writeError(ctx, resp, twirp.InternalError("received a nil *AgentDB_CreateResponse and nil error while calling CreateDatabase. nil responses are not supported")) - return - } - - ctx = callResponsePrepared(ctx, s.hooks) - - respBytes, err := proto.Marshal(respContent) - if err != nil { - s.writeError(ctx, resp, wrapInternal(err, "failed to marshal proto response")) - return - } - - ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK) - resp.Header().Set("Content-Type", "application/protobuf") - resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes))) - resp.WriteHeader(http.StatusOK) - if n, err := resp.Write(respBytes); err != nil { - msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error()) - twerr := twirp.NewError(twirp.Unknown, msg) - ctx = callError(ctx, s.hooks, twerr) - } - callResponseSent(ctx, s.hooks) -} - -func (s *agentDBServiceServer) serveGetDatabase(ctx context.Context, resp http.ResponseWriter, req *http.Request) { - header := req.Header.Get("Content-Type") - i := strings.Index(header, ";") - if i == -1 { - i = len(header) - } - switch strings.TrimSpace(strings.ToLower(header[:i])) { - case "application/json": - s.serveGetDatabaseJSON(ctx, resp, req) - case "application/protobuf": - s.serveGetDatabaseProtobuf(ctx, resp, req) - default: - msg := fmt.Sprintf("unexpected Content-Type: %q", req.Header.Get("Content-Type")) - twerr := badRouteError(msg, req.Method, req.URL.Path) - s.writeError(ctx, resp, twerr) - } -} - -func (s *agentDBServiceServer) serveGetDatabaseJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) { - var err error - ctx = ctxsetters.WithMethodName(ctx, "GetDatabase") - ctx, err = callRequestRouted(ctx, s.hooks) - if err != nil { - s.writeError(ctx, resp, err) - return - } - - d := json.NewDecoder(req.Body) - rawReqBody := json.RawMessage{} - if err := d.Decode(&rawReqBody); err != nil { - s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err) - return - } - reqContent := new(AgentDB_GetRequest) - unmarshaler := protojson.UnmarshalOptions{DiscardUnknown: true} - if err = unmarshaler.Unmarshal(rawReqBody, reqContent); err != nil { - s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err) - return - } - - handler := s.AgentDBService.GetDatabase - if s.interceptor != nil { - handler = func(ctx context.Context, req *AgentDB_GetRequest) (*AgentDB_AgentDatabase, error) { - resp, err := s.interceptor( - func(ctx context.Context, req interface{}) (interface{}, error) { - typedReq, ok := req.(*AgentDB_GetRequest) - if !ok { - return nil, twirp.InternalError("failed type assertion req.(*AgentDB_GetRequest) when calling interceptor") - } - return s.AgentDBService.GetDatabase(ctx, typedReq) - }, - )(ctx, req) - if resp != nil { - typedResp, ok := resp.(*AgentDB_AgentDatabase) - if !ok { - return nil, twirp.InternalError("failed type assertion resp.(*AgentDB_AgentDatabase) when calling interceptor") - } - return typedResp, err - } - return nil, err - } - } - - // Call service method - var respContent *AgentDB_AgentDatabase - func() { - defer ensurePanicResponses(ctx, resp, s.hooks) - respContent, err = handler(ctx, reqContent) - }() - - if err != nil { - s.writeError(ctx, resp, err) - return - } - if respContent == nil { - s.writeError(ctx, resp, twirp.InternalError("received a nil *AgentDB_AgentDatabase and nil error while calling GetDatabase. nil responses are not supported")) - return - } - - ctx = callResponsePrepared(ctx, s.hooks) - - marshaler := &protojson.MarshalOptions{UseProtoNames: !s.jsonCamelCase, EmitUnpopulated: !s.jsonSkipDefaults} - respBytes, err := marshaler.Marshal(respContent) - if err != nil { - s.writeError(ctx, resp, wrapInternal(err, "failed to marshal json response")) - return - } - - ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK) - resp.Header().Set("Content-Type", "application/json") - resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes))) - resp.WriteHeader(http.StatusOK) - - if n, err := resp.Write(respBytes); err != nil { - msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error()) - twerr := twirp.NewError(twirp.Unknown, msg) - ctx = callError(ctx, s.hooks, twerr) - } - callResponseSent(ctx, s.hooks) -} - -func (s *agentDBServiceServer) serveGetDatabaseProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) { - var err error - ctx = ctxsetters.WithMethodName(ctx, "GetDatabase") - ctx, err = callRequestRouted(ctx, s.hooks) - if err != nil { - s.writeError(ctx, resp, err) - return - } - - buf, err := io.ReadAll(req.Body) - if err != nil { - s.handleRequestBodyError(ctx, resp, "failed to read request body", err) - return - } - reqContent := new(AgentDB_GetRequest) - if err = proto.Unmarshal(buf, reqContent); err != nil { - s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded")) - return - } - - handler := s.AgentDBService.GetDatabase - if s.interceptor != nil { - handler = func(ctx context.Context, req *AgentDB_GetRequest) (*AgentDB_AgentDatabase, error) { - resp, err := s.interceptor( - func(ctx context.Context, req interface{}) (interface{}, error) { - typedReq, ok := req.(*AgentDB_GetRequest) - if !ok { - return nil, twirp.InternalError("failed type assertion req.(*AgentDB_GetRequest) when calling interceptor") - } - return s.AgentDBService.GetDatabase(ctx, typedReq) - }, - )(ctx, req) - if resp != nil { - typedResp, ok := resp.(*AgentDB_AgentDatabase) - if !ok { - return nil, twirp.InternalError("failed type assertion resp.(*AgentDB_AgentDatabase) when calling interceptor") - } - return typedResp, err - } - return nil, err - } - } - - // Call service method - var respContent *AgentDB_AgentDatabase - func() { - defer ensurePanicResponses(ctx, resp, s.hooks) - respContent, err = handler(ctx, reqContent) - }() - - if err != nil { - s.writeError(ctx, resp, err) - return - } - if respContent == nil { - s.writeError(ctx, resp, twirp.InternalError("received a nil *AgentDB_AgentDatabase and nil error while calling GetDatabase. nil responses are not supported")) - return - } - - ctx = callResponsePrepared(ctx, s.hooks) - - respBytes, err := proto.Marshal(respContent) - if err != nil { - s.writeError(ctx, resp, wrapInternal(err, "failed to marshal proto response")) - return - } - - ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK) - resp.Header().Set("Content-Type", "application/protobuf") - resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes))) - resp.WriteHeader(http.StatusOK) - if n, err := resp.Write(respBytes); err != nil { - msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error()) - twerr := twirp.NewError(twirp.Unknown, msg) - ctx = callError(ctx, s.hooks, twerr) - } - callResponseSent(ctx, s.hooks) -} - -func (s *agentDBServiceServer) serveListDatabases(ctx context.Context, resp http.ResponseWriter, req *http.Request) { - header := req.Header.Get("Content-Type") - i := strings.Index(header, ";") - if i == -1 { - i = len(header) - } - switch strings.TrimSpace(strings.ToLower(header[:i])) { - case "application/json": - s.serveListDatabasesJSON(ctx, resp, req) - case "application/protobuf": - s.serveListDatabasesProtobuf(ctx, resp, req) - default: - msg := fmt.Sprintf("unexpected Content-Type: %q", req.Header.Get("Content-Type")) - twerr := badRouteError(msg, req.Method, req.URL.Path) - s.writeError(ctx, resp, twerr) - } -} - -func (s *agentDBServiceServer) serveListDatabasesJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) { - var err error - ctx = ctxsetters.WithMethodName(ctx, "ListDatabases") - ctx, err = callRequestRouted(ctx, s.hooks) - if err != nil { - s.writeError(ctx, resp, err) - return - } - - d := json.NewDecoder(req.Body) - rawReqBody := json.RawMessage{} - if err := d.Decode(&rawReqBody); err != nil { - s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err) - return - } - reqContent := new(AgentDB_ListRequest) - unmarshaler := protojson.UnmarshalOptions{DiscardUnknown: true} - if err = unmarshaler.Unmarshal(rawReqBody, reqContent); err != nil { - s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err) - return - } - - handler := s.AgentDBService.ListDatabases - if s.interceptor != nil { - handler = func(ctx context.Context, req *AgentDB_ListRequest) (*AgentDB_ListResponse, error) { - resp, err := s.interceptor( - func(ctx context.Context, req interface{}) (interface{}, error) { - typedReq, ok := req.(*AgentDB_ListRequest) - if !ok { - return nil, twirp.InternalError("failed type assertion req.(*AgentDB_ListRequest) when calling interceptor") - } - return s.AgentDBService.ListDatabases(ctx, typedReq) - }, - )(ctx, req) - if resp != nil { - typedResp, ok := resp.(*AgentDB_ListResponse) - if !ok { - return nil, twirp.InternalError("failed type assertion resp.(*AgentDB_ListResponse) when calling interceptor") - } - return typedResp, err - } - return nil, err - } - } - - // Call service method - var respContent *AgentDB_ListResponse - func() { - defer ensurePanicResponses(ctx, resp, s.hooks) - respContent, err = handler(ctx, reqContent) - }() - - if err != nil { - s.writeError(ctx, resp, err) - return - } - if respContent == nil { - s.writeError(ctx, resp, twirp.InternalError("received a nil *AgentDB_ListResponse and nil error while calling ListDatabases. nil responses are not supported")) - return - } - - ctx = callResponsePrepared(ctx, s.hooks) - - marshaler := &protojson.MarshalOptions{UseProtoNames: !s.jsonCamelCase, EmitUnpopulated: !s.jsonSkipDefaults} - respBytes, err := marshaler.Marshal(respContent) - if err != nil { - s.writeError(ctx, resp, wrapInternal(err, "failed to marshal json response")) - return - } - - ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK) - resp.Header().Set("Content-Type", "application/json") - resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes))) - resp.WriteHeader(http.StatusOK) - - if n, err := resp.Write(respBytes); err != nil { - msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error()) - twerr := twirp.NewError(twirp.Unknown, msg) - ctx = callError(ctx, s.hooks, twerr) - } - callResponseSent(ctx, s.hooks) -} - -func (s *agentDBServiceServer) serveListDatabasesProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) { - var err error - ctx = ctxsetters.WithMethodName(ctx, "ListDatabases") - ctx, err = callRequestRouted(ctx, s.hooks) - if err != nil { - s.writeError(ctx, resp, err) - return - } - - buf, err := io.ReadAll(req.Body) - if err != nil { - s.handleRequestBodyError(ctx, resp, "failed to read request body", err) - return - } - reqContent := new(AgentDB_ListRequest) - if err = proto.Unmarshal(buf, reqContent); err != nil { - s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded")) - return - } - - handler := s.AgentDBService.ListDatabases - if s.interceptor != nil { - handler = func(ctx context.Context, req *AgentDB_ListRequest) (*AgentDB_ListResponse, error) { - resp, err := s.interceptor( - func(ctx context.Context, req interface{}) (interface{}, error) { - typedReq, ok := req.(*AgentDB_ListRequest) - if !ok { - return nil, twirp.InternalError("failed type assertion req.(*AgentDB_ListRequest) when calling interceptor") - } - return s.AgentDBService.ListDatabases(ctx, typedReq) - }, - )(ctx, req) - if resp != nil { - typedResp, ok := resp.(*AgentDB_ListResponse) - if !ok { - return nil, twirp.InternalError("failed type assertion resp.(*AgentDB_ListResponse) when calling interceptor") - } - return typedResp, err - } - return nil, err - } - } - - // Call service method - var respContent *AgentDB_ListResponse - func() { - defer ensurePanicResponses(ctx, resp, s.hooks) - respContent, err = handler(ctx, reqContent) - }() - - if err != nil { - s.writeError(ctx, resp, err) - return - } - if respContent == nil { - s.writeError(ctx, resp, twirp.InternalError("received a nil *AgentDB_ListResponse and nil error while calling ListDatabases. nil responses are not supported")) - return - } - - ctx = callResponsePrepared(ctx, s.hooks) - - respBytes, err := proto.Marshal(respContent) - if err != nil { - s.writeError(ctx, resp, wrapInternal(err, "failed to marshal proto response")) - return - } - - ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK) - resp.Header().Set("Content-Type", "application/protobuf") - resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes))) - resp.WriteHeader(http.StatusOK) - if n, err := resp.Write(respBytes); err != nil { - msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error()) - twerr := twirp.NewError(twirp.Unknown, msg) - ctx = callError(ctx, s.hooks, twerr) - } - callResponseSent(ctx, s.hooks) -} - -func (s *agentDBServiceServer) serveDeleteDatabase(ctx context.Context, resp http.ResponseWriter, req *http.Request) { - header := req.Header.Get("Content-Type") - i := strings.Index(header, ";") - if i == -1 { - i = len(header) - } - switch strings.TrimSpace(strings.ToLower(header[:i])) { - case "application/json": - s.serveDeleteDatabaseJSON(ctx, resp, req) - case "application/protobuf": - s.serveDeleteDatabaseProtobuf(ctx, resp, req) - default: - msg := fmt.Sprintf("unexpected Content-Type: %q", req.Header.Get("Content-Type")) - twerr := badRouteError(msg, req.Method, req.URL.Path) - s.writeError(ctx, resp, twerr) - } -} - -func (s *agentDBServiceServer) serveDeleteDatabaseJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) { - var err error - ctx = ctxsetters.WithMethodName(ctx, "DeleteDatabase") - ctx, err = callRequestRouted(ctx, s.hooks) - if err != nil { - s.writeError(ctx, resp, err) - return - } - - d := json.NewDecoder(req.Body) - rawReqBody := json.RawMessage{} - if err := d.Decode(&rawReqBody); err != nil { - s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err) - return - } - reqContent := new(AgentDB_DeleteRequest) - unmarshaler := protojson.UnmarshalOptions{DiscardUnknown: true} - if err = unmarshaler.Unmarshal(rawReqBody, reqContent); err != nil { - s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err) - return - } - - handler := s.AgentDBService.DeleteDatabase - if s.interceptor != nil { - handler = func(ctx context.Context, req *AgentDB_DeleteRequest) (*AgentDB_DeleteResponse, error) { - resp, err := s.interceptor( - func(ctx context.Context, req interface{}) (interface{}, error) { - typedReq, ok := req.(*AgentDB_DeleteRequest) - if !ok { - return nil, twirp.InternalError("failed type assertion req.(*AgentDB_DeleteRequest) when calling interceptor") - } - return s.AgentDBService.DeleteDatabase(ctx, typedReq) - }, - )(ctx, req) - if resp != nil { - typedResp, ok := resp.(*AgentDB_DeleteResponse) - if !ok { - return nil, twirp.InternalError("failed type assertion resp.(*AgentDB_DeleteResponse) when calling interceptor") - } - return typedResp, err - } - return nil, err - } - } - - // Call service method - var respContent *AgentDB_DeleteResponse - func() { - defer ensurePanicResponses(ctx, resp, s.hooks) - respContent, err = handler(ctx, reqContent) - }() - - if err != nil { - s.writeError(ctx, resp, err) - return - } - if respContent == nil { - s.writeError(ctx, resp, twirp.InternalError("received a nil *AgentDB_DeleteResponse and nil error while calling DeleteDatabase. nil responses are not supported")) - return - } - - ctx = callResponsePrepared(ctx, s.hooks) - - marshaler := &protojson.MarshalOptions{UseProtoNames: !s.jsonCamelCase, EmitUnpopulated: !s.jsonSkipDefaults} - respBytes, err := marshaler.Marshal(respContent) - if err != nil { - s.writeError(ctx, resp, wrapInternal(err, "failed to marshal json response")) - return - } - - ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK) - resp.Header().Set("Content-Type", "application/json") - resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes))) - resp.WriteHeader(http.StatusOK) - - if n, err := resp.Write(respBytes); err != nil { - msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error()) - twerr := twirp.NewError(twirp.Unknown, msg) - ctx = callError(ctx, s.hooks, twerr) - } - callResponseSent(ctx, s.hooks) -} - -func (s *agentDBServiceServer) serveDeleteDatabaseProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) { - var err error - ctx = ctxsetters.WithMethodName(ctx, "DeleteDatabase") - ctx, err = callRequestRouted(ctx, s.hooks) - if err != nil { - s.writeError(ctx, resp, err) - return - } - - buf, err := io.ReadAll(req.Body) - if err != nil { - s.handleRequestBodyError(ctx, resp, "failed to read request body", err) - return - } - reqContent := new(AgentDB_DeleteRequest) - if err = proto.Unmarshal(buf, reqContent); err != nil { - s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded")) - return - } - - handler := s.AgentDBService.DeleteDatabase - if s.interceptor != nil { - handler = func(ctx context.Context, req *AgentDB_DeleteRequest) (*AgentDB_DeleteResponse, error) { - resp, err := s.interceptor( - func(ctx context.Context, req interface{}) (interface{}, error) { - typedReq, ok := req.(*AgentDB_DeleteRequest) - if !ok { - return nil, twirp.InternalError("failed type assertion req.(*AgentDB_DeleteRequest) when calling interceptor") - } - return s.AgentDBService.DeleteDatabase(ctx, typedReq) - }, - )(ctx, req) - if resp != nil { - typedResp, ok := resp.(*AgentDB_DeleteResponse) - if !ok { - return nil, twirp.InternalError("failed type assertion resp.(*AgentDB_DeleteResponse) when calling interceptor") - } - return typedResp, err - } - return nil, err - } - } - - // Call service method - var respContent *AgentDB_DeleteResponse - func() { - defer ensurePanicResponses(ctx, resp, s.hooks) - respContent, err = handler(ctx, reqContent) - }() - - if err != nil { - s.writeError(ctx, resp, err) - return - } - if respContent == nil { - s.writeError(ctx, resp, twirp.InternalError("received a nil *AgentDB_DeleteResponse and nil error while calling DeleteDatabase. nil responses are not supported")) - return - } - - ctx = callResponsePrepared(ctx, s.hooks) - - respBytes, err := proto.Marshal(respContent) - if err != nil { - s.writeError(ctx, resp, wrapInternal(err, "failed to marshal proto response")) - return - } - - ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK) - resp.Header().Set("Content-Type", "application/protobuf") - resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes))) - resp.WriteHeader(http.StatusOK) - if n, err := resp.Write(respBytes); err != nil { - msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error()) - twerr := twirp.NewError(twirp.Unknown, msg) - ctx = callError(ctx, s.hooks, twerr) - } - callResponseSent(ctx, s.hooks) -} - -func (s *agentDBServiceServer) serveDumpDatabase(ctx context.Context, resp http.ResponseWriter, req *http.Request) { - header := req.Header.Get("Content-Type") - i := strings.Index(header, ";") - if i == -1 { - i = len(header) - } - switch strings.TrimSpace(strings.ToLower(header[:i])) { - case "application/json": - s.serveDumpDatabaseJSON(ctx, resp, req) - case "application/protobuf": - s.serveDumpDatabaseProtobuf(ctx, resp, req) - default: - msg := fmt.Sprintf("unexpected Content-Type: %q", req.Header.Get("Content-Type")) - twerr := badRouteError(msg, req.Method, req.URL.Path) - s.writeError(ctx, resp, twerr) - } -} - -func (s *agentDBServiceServer) serveDumpDatabaseJSON(ctx context.Context, resp http.ResponseWriter, req *http.Request) { - var err error - ctx = ctxsetters.WithMethodName(ctx, "DumpDatabase") - ctx, err = callRequestRouted(ctx, s.hooks) - if err != nil { - s.writeError(ctx, resp, err) - return - } - - d := json.NewDecoder(req.Body) - rawReqBody := json.RawMessage{} - if err := d.Decode(&rawReqBody); err != nil { - s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err) - return - } - reqContent := new(AgentDB_DumpRequest) - unmarshaler := protojson.UnmarshalOptions{DiscardUnknown: true} - if err = unmarshaler.Unmarshal(rawReqBody, reqContent); err != nil { - s.handleRequestBodyError(ctx, resp, "the json request could not be decoded", err) - return - } - - handler := s.AgentDBService.DumpDatabase - if s.interceptor != nil { - handler = func(ctx context.Context, req *AgentDB_DumpRequest) (*AgentDB_DumpResponse, error) { - resp, err := s.interceptor( - func(ctx context.Context, req interface{}) (interface{}, error) { - typedReq, ok := req.(*AgentDB_DumpRequest) - if !ok { - return nil, twirp.InternalError("failed type assertion req.(*AgentDB_DumpRequest) when calling interceptor") - } - return s.AgentDBService.DumpDatabase(ctx, typedReq) - }, - )(ctx, req) - if resp != nil { - typedResp, ok := resp.(*AgentDB_DumpResponse) - if !ok { - return nil, twirp.InternalError("failed type assertion resp.(*AgentDB_DumpResponse) when calling interceptor") - } - return typedResp, err - } - return nil, err - } - } - - // Call service method - var respContent *AgentDB_DumpResponse - func() { - defer ensurePanicResponses(ctx, resp, s.hooks) - respContent, err = handler(ctx, reqContent) - }() - - if err != nil { - s.writeError(ctx, resp, err) - return - } - if respContent == nil { - s.writeError(ctx, resp, twirp.InternalError("received a nil *AgentDB_DumpResponse and nil error while calling DumpDatabase. nil responses are not supported")) - return - } - - ctx = callResponsePrepared(ctx, s.hooks) - - marshaler := &protojson.MarshalOptions{UseProtoNames: !s.jsonCamelCase, EmitUnpopulated: !s.jsonSkipDefaults} - respBytes, err := marshaler.Marshal(respContent) - if err != nil { - s.writeError(ctx, resp, wrapInternal(err, "failed to marshal json response")) - return - } - - ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK) - resp.Header().Set("Content-Type", "application/json") - resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes))) - resp.WriteHeader(http.StatusOK) - - if n, err := resp.Write(respBytes); err != nil { - msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error()) - twerr := twirp.NewError(twirp.Unknown, msg) - ctx = callError(ctx, s.hooks, twerr) - } - callResponseSent(ctx, s.hooks) -} - -func (s *agentDBServiceServer) serveDumpDatabaseProtobuf(ctx context.Context, resp http.ResponseWriter, req *http.Request) { - var err error - ctx = ctxsetters.WithMethodName(ctx, "DumpDatabase") - ctx, err = callRequestRouted(ctx, s.hooks) - if err != nil { - s.writeError(ctx, resp, err) - return - } - - buf, err := io.ReadAll(req.Body) - if err != nil { - s.handleRequestBodyError(ctx, resp, "failed to read request body", err) - return - } - reqContent := new(AgentDB_DumpRequest) - if err = proto.Unmarshal(buf, reqContent); err != nil { - s.writeError(ctx, resp, malformedRequestError("the protobuf request could not be decoded")) - return - } - - handler := s.AgentDBService.DumpDatabase - if s.interceptor != nil { - handler = func(ctx context.Context, req *AgentDB_DumpRequest) (*AgentDB_DumpResponse, error) { - resp, err := s.interceptor( - func(ctx context.Context, req interface{}) (interface{}, error) { - typedReq, ok := req.(*AgentDB_DumpRequest) - if !ok { - return nil, twirp.InternalError("failed type assertion req.(*AgentDB_DumpRequest) when calling interceptor") - } - return s.AgentDBService.DumpDatabase(ctx, typedReq) - }, - )(ctx, req) - if resp != nil { - typedResp, ok := resp.(*AgentDB_DumpResponse) - if !ok { - return nil, twirp.InternalError("failed type assertion resp.(*AgentDB_DumpResponse) when calling interceptor") - } - return typedResp, err - } - return nil, err - } - } - - // Call service method - var respContent *AgentDB_DumpResponse - func() { - defer ensurePanicResponses(ctx, resp, s.hooks) - respContent, err = handler(ctx, reqContent) - }() - - if err != nil { - s.writeError(ctx, resp, err) - return - } - if respContent == nil { - s.writeError(ctx, resp, twirp.InternalError("received a nil *AgentDB_DumpResponse and nil error while calling DumpDatabase. nil responses are not supported")) - return - } - - ctx = callResponsePrepared(ctx, s.hooks) - - respBytes, err := proto.Marshal(respContent) - if err != nil { - s.writeError(ctx, resp, wrapInternal(err, "failed to marshal proto response")) - return - } - - ctx = ctxsetters.WithStatusCode(ctx, http.StatusOK) - resp.Header().Set("Content-Type", "application/protobuf") - resp.Header().Set("Content-Length", strconv.Itoa(len(respBytes))) - resp.WriteHeader(http.StatusOK) - if n, err := resp.Write(respBytes); err != nil { - msg := fmt.Sprintf("failed to write response, %d of %d bytes written: %s", n, len(respBytes), err.Error()) - twerr := twirp.NewError(twirp.Unknown, msg) - ctx = callError(ctx, s.hooks, twerr) - } - callResponseSent(ctx, s.hooks) -} - -func (s *agentDBServiceServer) ServiceDescriptor() ([]byte, int) { - return twirpFileDescriptor2, 0 -} - -func (s *agentDBServiceServer) ProtocGenTwirpVersion() string { - return "v8.1.3" -} - -// PathPrefix returns the base service path, in the form: "//./" -// that is everything in a Twirp route except for the . This can be used for routing, -// for example to identify the requests that are targeted to this service in a mux. -func (s *agentDBServiceServer) PathPrefix() string { - return baseServicePath(s.pathPrefix, "livekit", "AgentDBService") -} - -var twirpFileDescriptor2 = []byte{ - // 1513 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x57, 0xcb, 0x6e, 0xdb, 0x46, - 0x17, 0x96, 0x4c, 0xea, 0xc2, 0x23, 0xc9, 0xbf, 0x30, 0xf9, 0x1b, 0xa8, 0x4c, 0x1c, 0x3b, 0x4e, - 0x51, 0xb8, 0x8b, 0x3a, 0x81, 0x8d, 0x24, 0x68, 0x10, 0xa4, 0xb0, 0x6c, 0x27, 0x72, 0x23, 0x27, - 0xf6, 0xd8, 0xe9, 0x6d, 0x51, 0x82, 0x22, 0x27, 0x32, 0x61, 0x8a, 0x54, 0xc8, 0x91, 0xe3, 0xe4, - 0x05, 0xfa, 0x0a, 0xdd, 0xf4, 0x05, 0xfa, 0x02, 0xdd, 0xf6, 0x05, 0xba, 0x2d, 0xba, 0xec, 0xba, - 0x4f, 0x51, 0x9c, 0x33, 0x43, 0xca, 0x8e, 0x2e, 0xce, 0x8a, 0x33, 0x67, 0xbe, 0x6f, 0x2e, 0xe7, - 0x7c, 0x73, 0xe6, 0x10, 0x3e, 0x09, 0x83, 0x33, 0x71, 0x1a, 0x48, 0xc7, 0xed, 0x8b, 0x48, 0xfa, - 0xbd, 0xf5, 0x61, 0x12, 0xcb, 0x98, 0x55, 0xb4, 0x79, 0xf5, 0xef, 0x4f, 0xa1, 0xb2, 0x85, 0x43, - 0x3b, 0x6d, 0xbb, 0x03, 0x8d, 0xed, 0x44, 0xb8, 0x52, 0x70, 0xf1, 0x66, 0x24, 0x52, 0xc9, 0xae, - 0x43, 0x39, 0x11, 0xfd, 0x20, 0x8e, 0x5a, 0xc5, 0x95, 0xe2, 0x9a, 0xc5, 0x75, 0x8f, 0x2d, 0x43, - 0x4d, 0xca, 0xd0, 0x49, 0x85, 0x17, 0x47, 0x7e, 0xda, 0x5a, 0x58, 0x29, 0xae, 0x19, 0x1c, 0xa4, - 0x0c, 0x8f, 0x94, 0xc5, 0x3e, 0x80, 0xc5, 0x6c, 0xa6, 0x74, 0x18, 0x47, 0xa9, 0x40, 0x8a, 0xef, - 0x4a, 0xb7, 0xe7, 0xa6, 0xc2, 0x09, 0x7c, 0x3d, 0x1f, 0x64, 0xa6, 0x3d, 0x9f, 0x2d, 0x01, 0x88, - 0xf3, 0x61, 0x90, 0x88, 0xd4, 0x71, 0xa5, 0x9e, 0xd2, 0xd2, 0x96, 0x2d, 0x69, 0x7f, 0x09, 0xf0, - 0x4c, 0xc8, 0x6c, 0x63, 0x57, 0xcd, 0x66, 0xef, 0x41, 0xad, 0x1b, 0xa4, 0x39, 0xfe, 0x06, 0x58, - 0x43, 0xb7, 0x2f, 0x9c, 0x34, 0x78, 0x2f, 0x08, 0x5d, 0xe2, 0x55, 0x34, 0x1c, 0x05, 0xef, 0x05, - 0xae, 0x4c, 0x83, 0x32, 0x3e, 0x15, 0x11, 0xad, 0x6c, 0x71, 0x82, 0x1f, 0xa3, 0xc1, 0x96, 0x50, - 0x57, 0x53, 0xe9, 0x93, 0x3c, 0x06, 0x2b, 0x5b, 0x28, 0x6d, 0x15, 0x57, 0x8c, 0xb5, 0xda, 0xc6, - 0xad, 0x75, 0xed, 0xce, 0x75, 0xed, 0x4a, 0xfd, 0xd5, 0x30, 0x3e, 0x26, 0xb0, 0xcf, 0xe1, 0x7f, - 0x91, 0x38, 0x97, 0xce, 0xc4, 0x8a, 0x0d, 0x34, 0x1f, 0xe4, 0xab, 0xfe, 0x52, 0x84, 0xc6, 0xa5, - 0x49, 0xae, 0xf6, 0xe0, 0x38, 0x5a, 0x0b, 0x97, 0xa2, 0xb5, 0x04, 0xe0, 0x51, 0x30, 0x7c, 0xf4, - 0xac, 0xa1, 0x3c, 0xab, 0x2d, 0x5b, 0xf2, 0x03, 0xc7, 0x9b, 0x1f, 0x38, 0x9e, 0x35, 0xc1, 0x90, - 0xc1, 0xb0, 0x55, 0x22, 0x3b, 0x36, 0xed, 0x7b, 0xd0, 0xd8, 0x11, 0xa1, 0x18, 0xcb, 0xe4, 0xca, - 0x68, 0x34, 0x61, 0x31, 0x63, 0x28, 0x27, 0xda, 0xeb, 0x50, 0xdb, 0x19, 0x0d, 0x86, 0x1f, 0x3d, - 0x43, 0x0f, 0xea, 0x0a, 0xaf, 0x83, 0x70, 0x1b, 0xea, 0x7e, 0xfc, 0x36, 0x0a, 0x63, 0xd7, 0x77, - 0x46, 0x49, 0xa8, 0x19, 0xb5, 0xcc, 0xf6, 0x2a, 0x09, 0xaf, 0x10, 0x54, 0x76, 0x2e, 0x63, 0x7c, - 0xae, 0x3f, 0xaf, 0x81, 0xf9, 0x5d, 0x90, 0x08, 0xfb, 0x1f, 0x13, 0x1a, 0xdb, 0x61, 0x20, 0x22, - 0xb9, 0x2f, 0xd2, 0xd4, 0xed, 0x93, 0x44, 0x12, 0xb5, 0xd5, 0x6c, 0x7b, 0x0d, 0x6e, 0x69, 0xcb, - 0x9e, 0xcf, 0x36, 0xa1, 0x74, 0x22, 0xc2, 0x30, 0xa6, 0x55, 0x6a, 0x1b, 0x37, 0x26, 0xe4, 0x80, - 0xd3, 0xae, 0x77, 0x10, 0xd2, 0x29, 0x70, 0x85, 0x65, 0xf7, 0xc1, 0x14, 0xe7, 0xc2, 0xa3, 0x1d, - 0xd4, 0x36, 0x96, 0xa7, 0x73, 0x8e, 0xa4, 0x2b, 0xc5, 0x40, 0x44, 0xb2, 0x53, 0xe0, 0x04, 0x67, - 0x0f, 0xa1, 0xf4, 0x66, 0x24, 0x92, 0x77, 0x14, 0xa9, 0x8f, 0xe2, 0x29, 0x3c, 0x6e, 0xb2, 0xe7, - 0x4a, 0xef, 0x84, 0x42, 0x39, 0x73, 0x93, 0x6d, 0x84, 0x20, 0x89, 0xb0, 0x44, 0x12, 0xfd, 0x20, - 0x6a, 0x95, 0xe7, 0x92, 0x10, 0x42, 0x24, 0x6c, 0xb0, 0x07, 0x50, 0xf6, 0xe2, 0xc1, 0x20, 0x90, - 0xad, 0x0a, 0xb1, 0x6e, 0x4e, 0x67, 0x6d, 0x13, 0xa6, 0x53, 0xe0, 0x1a, 0xcd, 0x1e, 0x43, 0x35, - 0x89, 0xc3, 0xb0, 0xe7, 0x7a, 0xa7, 0xad, 0x2a, 0x31, 0x6f, 0x4d, 0x67, 0x72, 0x8d, 0xea, 0x14, - 0x78, 0xce, 0xa0, 0x55, 0xdd, 0xc8, 0x13, 0x61, 0xcb, 0x9a, 0xbb, 0x2a, 0x61, 0x68, 0x55, 0x6a, - 0x11, 0x2f, 0x11, 0x7e, 0x20, 0x5b, 0x30, 0x97, 0x47, 0x18, 0xe2, 0x51, 0x8b, 0xdd, 0x03, 0x73, - 0x18, 0x44, 0xfd, 0x56, 0x8d, 0x58, 0xf6, 0x74, 0xd6, 0x41, 0x10, 0xf5, 0x31, 0x74, 0x88, 0x6c, - 0x5b, 0x50, 0x19, 0x28, 0x41, 0xd9, 0x7f, 0x19, 0xd0, 0x38, 0x12, 0xc9, 0x99, 0x48, 0x3e, 0x52, - 0x62, 0x8f, 0xa0, 0x4a, 0xb2, 0x71, 0xe2, 0x53, 0xad, 0xb2, 0xa5, 0x39, 0x2a, 0x7b, 0x89, 0xae, - 0xa9, 0x9c, 0xa8, 0x26, 0xfb, 0x0a, 0x2a, 0x5e, 0x1c, 0x8e, 0x06, 0x51, 0xaa, 0xc5, 0xb6, 0x34, - 0x2b, 0x20, 0x04, 0x42, 0xaa, 0xc6, 0xb3, 0xa7, 0x50, 0x57, 0x4d, 0x47, 0x69, 0x47, 0x89, 0xee, - 0xf6, 0x3c, 0x7e, 0xa6, 0xa0, 0x9a, 0x37, 0xee, 0xb2, 0x6d, 0xa8, 0xa1, 0x7a, 0x9d, 0x44, 0xa4, - 0xa3, 0x50, 0x6a, 0x09, 0xae, 0x4c, 0x9f, 0x66, 0xf7, 0x5c, 0x78, 0x9c, 0x70, 0x9d, 0x02, 0x07, - 0x91, 0xf7, 0xd0, 0xe3, 0x7e, 0x1c, 0x09, 0xad, 0xc5, 0x19, 0x1e, 0xdf, 0x89, 0x23, 0x81, 0x1e, - 0x47, 0x24, 0xca, 0x57, 0x24, 0x49, 0x9c, 0x68, 0x21, 0xce, 0x90, 0xef, 0x2e, 0x42, 0x50, 0xbe, - 0x84, 0xa5, 0xc0, 0xc6, 0x51, 0x5f, 0x4b, 0x70, 0x56, 0x60, 0x63, 0x1d, 0xd8, 0xf8, 0x72, 0x60, - 0x7f, 0x2f, 0x42, 0xe9, 0x5b, 0x37, 0x1c, 0x61, 0xbe, 0x86, 0x68, 0x14, 0x86, 0xce, 0x19, 0xf6, - 0x28, 0xa0, 0xd5, 0x4e, 0x81, 0x5b, 0x68, 0x53, 0x80, 0x25, 0xb0, 0x82, 0x48, 0xea, 0x71, 0xca, - 0x4f, 0xa8, 0xe7, 0x20, 0x92, 0x6a, 0xf8, 0x0e, 0xa6, 0xb8, 0x51, 0x2f, 0x14, 0x1a, 0x81, 0xa1, - 0x2b, 0xa2, 0x5f, 0x95, 0x35, 0x5f, 0x44, 0xe2, 0x73, 0xa2, 0x20, 0x18, 0x1d, 0x0b, 0x17, 0x41, - 0x5b, 0x0e, 0xe8, 0x85, 0x71, 0x4f, 0x03, 0xd0, 0xef, 0x75, 0x04, 0xa0, 0x8d, 0x00, 0xed, 0x0a, - 0x94, 0x68, 0xcc, 0xfe, 0xb9, 0x08, 0x56, 0x9e, 0x36, 0x30, 0x3d, 0xa6, 0x6f, 0xb2, 0xbc, 0x8a, - 0x4d, 0xb6, 0x09, 0xe5, 0xa1, 0x9b, 0xb8, 0x03, 0x7c, 0xef, 0x8d, 0xd9, 0xce, 0xa4, 0x59, 0xb9, - 0x86, 0xb2, 0x4d, 0x30, 0x43, 0x37, 0xea, 0xd3, 0xe6, 0x17, 0x67, 0x25, 0xab, 0x43, 0xcc, 0x4f, - 0x5d, 0x37, 0xea, 0x73, 0x02, 0xdb, 0x1d, 0x28, 0x29, 0xd5, 0x7c, 0x0d, 0x90, 0x66, 0x3b, 0xca, - 0xde, 0xda, 0xab, 0x12, 0x1e, 0xbf, 0x40, 0xb1, 0x2b, 0x50, 0xa2, 0xdc, 0x64, 0x57, 0xa1, 0xac, - 0xd2, 0x8d, 0x0d, 0x50, 0xcd, 0xd2, 0x07, 0x59, 0x29, 0x09, 0xd8, 0xab, 0x50, 0x56, 0x17, 0x9c, - 0xb5, 0xa0, 0x42, 0x52, 0xa7, 0xc7, 0x1d, 0x2f, 0x61, 0xd6, 0xb5, 0xbf, 0x00, 0x13, 0xaf, 0x33, - 0xbe, 0x3d, 0x32, 0x18, 0x88, 0x54, 0xba, 0x83, 0xa1, 0x33, 0x50, 0x30, 0x83, 0xd7, 0x72, 0xdb, - 0x7e, 0x6a, 0xff, 0x04, 0x26, 0x0a, 0x84, 0x6d, 0xc2, 0xf5, 0xd0, 0x4d, 0xa5, 0x83, 0xd7, 0xdf, - 0x99, 0x42, 0xba, 0x86, 0xa3, 0x38, 0xe9, 0xf1, 0x98, 0x3c, 0x31, 0xff, 0xc2, 0xe4, 0xfc, 0x4f, - 0xa0, 0x44, 0xf7, 0x9c, 0xfd, 0x1f, 0x4a, 0xaa, 0x88, 0x50, 0x81, 0x52, 0x9d, 0x0f, 0x9f, 0xd3, - 0x85, 0x89, 0xe7, 0x74, 0x00, 0x15, 0x9d, 0x27, 0xb2, 0x77, 0xb0, 0x98, 0xbf, 0x83, 0x6c, 0x0d, - 0x9a, 0xb4, 0xdf, 0x20, 0x92, 0x22, 0x39, 0x73, 0xc3, 0x6c, 0x0f, 0x0d, 0xbe, 0x88, 0xf6, 0x3d, - 0x6d, 0xde, 0xa7, 0x62, 0x26, 0x3f, 0x59, 0x3c, 0x92, 0x08, 0x34, 0x08, 0xd8, 0x18, 0xea, 0x33, - 0xc5, 0x23, 0xb9, 0x9f, 0xda, 0xcb, 0x50, 0xd1, 0xb9, 0x05, 0x37, 0x1c, 0xb9, 0x03, 0x5d, 0x39, - 0x59, 0x5c, 0x75, 0xec, 0x3f, 0x8a, 0x18, 0x1f, 0x44, 0xd0, 0x89, 0xde, 0x0d, 0xb5, 0xf7, 0xeb, - 0x5c, 0x75, 0x18, 0x03, 0x33, 0x40, 0x0d, 0xa0, 0xf4, 0x18, 0xa7, 0x36, 0x46, 0x4a, 0x5d, 0x05, - 0x5c, 0xd5, 0x58, 0x2b, 0xf2, 0xac, 0x8b, 0xe5, 0x1e, 0xdd, 0x0a, 0x3c, 0x31, 0x5d, 0x8a, 0x3a, - 0xaf, 0xa2, 0x01, 0x6b, 0xa9, 0x7c, 0x50, 0x60, 0xe9, 0x5a, 0x5a, 0x31, 0xd6, 0x1a, 0x6a, 0x70, - 0x37, 0xf2, 0x89, 0x49, 0xd7, 0x85, 0x98, 0x65, 0xc5, 0x44, 0x43, 0xc6, 0xa4, 0x41, 0x62, 0x56, - 0x14, 0x13, 0x0d, 0xc8, 0xb4, 0x7f, 0x80, 0xda, 0x85, 0xfc, 0xc7, 0x1e, 0x8c, 0x73, 0xae, 0xd2, - 0xed, 0xcd, 0x79, 0x39, 0x73, 0x9c, 0x70, 0x19, 0x98, 0x49, 0xfc, 0x36, 0x73, 0x38, 0xb5, 0xed, - 0x00, 0x60, 0x9c, 0x13, 0xd9, 0x1d, 0x68, 0xa0, 0xd5, 0x71, 0x5f, 0xbf, 0x16, 0x9e, 0x14, 0xbe, - 0x0e, 0x5d, 0x1d, 0x8d, 0x5b, 0xda, 0xc6, 0x3e, 0x83, 0x45, 0x12, 0x5e, 0x10, 0xa5, 0x22, 0x91, - 0x99, 0x08, 0x0c, 0x5e, 0x47, 0xeb, 0x1e, 0x19, 0xf7, 0xfc, 0x29, 0x35, 0xd0, 0x43, 0x30, 0x31, - 0x81, 0x4e, 0x51, 0xc5, 0x12, 0x80, 0x8c, 0xa5, 0x1b, 0x3a, 0xf9, 0xf6, 0x4c, 0x6e, 0x91, 0x85, - 0xe3, 0x1e, 0xef, 0x43, 0x89, 0xd2, 0x28, 0x1e, 0xc0, 0x8b, 0x7d, 0xa1, 0x05, 0x49, 0x6d, 0x8c, - 0x94, 0xce, 0x8f, 0x5a, 0x8b, 0x59, 0x77, 0xd5, 0x06, 0x2b, 0xbf, 0xfd, 0xac, 0x02, 0xc6, 0xd1, - 0x61, 0xb7, 0x59, 0x58, 0x35, 0xab, 0xc5, 0x66, 0x71, 0xf5, 0x09, 0x58, 0x94, 0x4c, 0x8e, 0xdf, - 0x0d, 0x05, 0xab, 0x82, 0xf9, 0xe2, 0x55, 0xb7, 0xdb, 0x2c, 0x20, 0x6a, 0xef, 0xc5, 0x71, 0xb3, - 0xc8, 0x00, 0xca, 0x3b, 0x2f, 0x5f, 0xb5, 0xbb, 0xbb, 0xcd, 0x05, 0x1c, 0x3e, 0xde, 0xfd, 0xfe, - 0xb8, 0x69, 0x60, 0xab, 0xdd, 0x7d, 0xd9, 0x6e, 0x9a, 0x1b, 0xbf, 0x1a, 0xb0, 0xa8, 0x7d, 0x8d, - 0x4f, 0x6d, 0xe0, 0x09, 0x76, 0x98, 0xfd, 0x97, 0xe4, 0x55, 0xf5, 0x64, 0x85, 0x71, 0xe9, 0x17, - 0xc8, 0x5e, 0x9e, 0x39, 0xae, 0x2b, 0xd1, 0x6f, 0xa0, 0xf6, 0x4c, 0x8c, 0xab, 0xf4, 0xc9, 0xac, - 0x38, 0xfe, 0x6d, 0xb1, 0xaf, 0xf8, 0x4f, 0x60, 0x5d, 0x68, 0xe0, 0xaf, 0xc6, 0x4e, 0xfe, 0xb7, - 0x30, 0x29, 0x9a, 0x0b, 0x7f, 0x35, 0xf6, 0xd2, 0x8c, 0x51, 0xbd, 0xb3, 0xc3, 0xac, 0xea, 0x9e, - 0x73, 0xd8, 0x4b, 0x85, 0xfc, 0x94, 0xc3, 0x5e, 0x2e, 0xdb, 0xd9, 0x73, 0x55, 0x86, 0xe7, 0x13, - 0x4e, 0xee, 0xef, 0x42, 0x55, 0x3f, 0x65, 0x7f, 0x17, 0x6b, 0xf8, 0xf6, 0xd3, 0x1f, 0xef, 0xf4, - 0x03, 0x79, 0x32, 0xea, 0xad, 0x7b, 0xf1, 0xe0, 0xae, 0x86, 0xde, 0xa5, 0xff, 0x53, 0x2f, 0x0e, - 0x33, 0xc3, 0x6f, 0x0b, 0x8d, 0x6e, 0x70, 0x26, 0x9e, 0x07, 0x72, 0xfd, 0x00, 0x87, 0xfe, 0x5d, - 0x58, 0xd4, 0xfd, 0x47, 0x8f, 0xc8, 0xd0, 0x2b, 0x13, 0x65, 0xf3, 0xbf, 0x00, 0x00, 0x00, 0xff, - 0xff, 0xc5, 0x9a, 0x43, 0xe8, 0xeb, 0x0e, 0x00, 0x00, -} diff --git a/livekit/livekit_cloud_agent.twirp.go b/livekit/livekit_cloud_agent.twirp.go index 689ae25bc..27ce9a912 100644 --- a/livekit/livekit_cloud_agent.twirp.go +++ b/livekit/livekit_cloud_agent.twirp.go @@ -5245,7 +5245,7 @@ func (s *cloudAgentServer) serveGetPrivateLinkStatusProtobuf(ctx context.Context } func (s *cloudAgentServer) ServiceDescriptor() ([]byte, int) { - return twirpFileDescriptor7, 0 + return twirpFileDescriptor6, 0 } func (s *cloudAgentServer) ProtocGenTwirpVersion() string { @@ -5259,7 +5259,7 @@ func (s *cloudAgentServer) PathPrefix() string { return baseServicePath(s.pathPrefix, "livekit", "CloudAgent") } -var twirpFileDescriptor7 = []byte{ +var twirpFileDescriptor6 = []byte{ // 2600 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x5a, 0x5d, 0x6f, 0x1b, 0x4b, 0xf9, 0xcf, 0xfa, 0x2d, 0xf6, 0xe3, 0xb8, 0x71, 0x26, 0x69, 0xea, 0x38, 0x49, 0x9b, 0x6c, 0xdb, diff --git a/livekit/livekit_connector.twirp.go b/livekit/livekit_connector.twirp.go index 472bc090a..d88f01c00 100644 --- a/livekit/livekit_connector.twirp.go +++ b/livekit/livekit_connector.twirp.go @@ -1618,7 +1618,7 @@ func (s *connectorServer) serveConnectTwilioCallProtobuf(ctx context.Context, re } func (s *connectorServer) ServiceDescriptor() ([]byte, int) { - return twirpFileDescriptor9, 0 + return twirpFileDescriptor8, 0 } func (s *connectorServer) ProtocGenTwirpVersion() string { @@ -1632,7 +1632,7 @@ func (s *connectorServer) PathPrefix() string { return baseServicePath(s.pathPrefix, "livekit", "Connector") } -var twirpFileDescriptor9 = []byte{ +var twirpFileDescriptor8 = []byte{ // 313 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x92, 0x41, 0x4b, 0xf3, 0x30, 0x1c, 0xc6, 0xdf, 0xb7, 0xc2, 0xd4, 0xbf, 0x4e, 0x6b, 0x04, 0x85, 0x1e, 0x64, 0x5b, 0x45, 0xc1, diff --git a/livekit/livekit_egress.twirp.go b/livekit/livekit_egress.twirp.go index a13f58701..acfc9cfad 100644 --- a/livekit/livekit_egress.twirp.go +++ b/livekit/livekit_egress.twirp.go @@ -3018,7 +3018,7 @@ func (s *egressServer) serveStartTrackEgressProtobuf(ctx context.Context, resp h } func (s *egressServer) ServiceDescriptor() ([]byte, int) { - return twirpFileDescriptor3, 0 + return twirpFileDescriptor2, 0 } func (s *egressServer) ProtocGenTwirpVersion() string { @@ -3032,7 +3032,7 @@ func (s *egressServer) PathPrefix() string { return baseServicePath(s.pathPrefix, "livekit", "Egress") } -var twirpFileDescriptor3 = []byte{ +var twirpFileDescriptor2 = []byte{ // 4219 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x3b, 0x4b, 0x70, 0x1b, 0x5b, 0x56, 0xee, 0xd6, 0xff, 0xe8, 0xd7, 0xbe, 0x76, 0x1c, 0xc5, 0x99, 0x4c, 0x32, 0xca, 0xbc, 0x97, diff --git a/livekit/livekit_ingress.twirp.go b/livekit/livekit_ingress.twirp.go index acb4d95a2..fa7244522 100644 --- a/livekit/livekit_ingress.twirp.go +++ b/livekit/livekit_ingress.twirp.go @@ -1341,7 +1341,7 @@ func (s *ingressServer) serveDeleteIngressProtobuf(ctx context.Context, resp htt } func (s *ingressServer) ServiceDescriptor() ([]byte, int) { - return twirpFileDescriptor4, 0 + return twirpFileDescriptor3, 0 } func (s *ingressServer) ProtocGenTwirpVersion() string { @@ -1355,7 +1355,7 @@ func (s *ingressServer) PathPrefix() string { return baseServicePath(s.pathPrefix, "livekit", "Ingress") } -var twirpFileDescriptor4 = []byte{ +var twirpFileDescriptor3 = []byte{ // 1620 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0x4d, 0x6f, 0xdb, 0xcc, 0x11, 0x36, 0xf5, 0xad, 0x91, 0x25, 0x2b, 0x6b, 0xf9, 0x7d, 0x15, 0x7f, 0xb4, 0x82, 0x92, 0x22, diff --git a/livekit/livekit_phone_number.twirp.go b/livekit/livekit_phone_number.twirp.go index b1cdd5a54..786c5280e 100644 --- a/livekit/livekit_phone_number.twirp.go +++ b/livekit/livekit_phone_number.twirp.go @@ -1904,7 +1904,7 @@ func (s *phoneNumberServiceServer) serveReleasePhoneNumbersProtobuf(ctx context. } func (s *phoneNumberServiceServer) ServiceDescriptor() ([]byte, int) { - return twirpFileDescriptor8, 0 + return twirpFileDescriptor7, 0 } func (s *phoneNumberServiceServer) ProtocGenTwirpVersion() string { @@ -1918,7 +1918,7 @@ func (s *phoneNumberServiceServer) PathPrefix() string { return baseServicePath(s.pathPrefix, "livekit", "PhoneNumberService") } -var twirpFileDescriptor8 = []byte{ +var twirpFileDescriptor7 = []byte{ // 1393 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x57, 0xcf, 0x6e, 0xdb, 0x46, 0x13, 0xd7, 0x4a, 0xb6, 0x63, 0x8d, 0xfe, 0x58, 0xde, 0x38, 0x31, 0x4d, 0xc7, 0xb1, 0x4c, 0x7f, diff --git a/livekit/livekit_room.twirp.go b/livekit/livekit_room.twirp.go index 122269f8a..eae205ebf 100644 --- a/livekit/livekit_room.twirp.go +++ b/livekit/livekit_room.twirp.go @@ -4152,7 +4152,7 @@ func (s *roomServiceServer) servePerformRpcProtobuf(ctx context.Context, resp ht } func (s *roomServiceServer) ServiceDescriptor() ([]byte, int) { - return twirpFileDescriptor5, 0 + return twirpFileDescriptor4, 0 } func (s *roomServiceServer) ProtocGenTwirpVersion() string { @@ -4166,7 +4166,7 @@ func (s *roomServiceServer) PathPrefix() string { return baseServicePath(s.pathPrefix, "livekit", "RoomService") } -var twirpFileDescriptor5 = []byte{ +var twirpFileDescriptor4 = []byte{ // 1612 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x58, 0x5b, 0x6f, 0x13, 0xd7, 0x16, 0x3e, 0x4e, 0x6c, 0xc7, 0x5e, 0xce, 0xcd, 0x3b, 0x01, 0x26, 0x13, 0x2e, 0x66, 0xc2, 0x39, diff --git a/livekit/livekit_sip.twirp.go b/livekit/livekit_sip.twirp.go index d0c943eb9..04202ef10 100644 --- a/livekit/livekit_sip.twirp.go +++ b/livekit/livekit_sip.twirp.go @@ -4687,7 +4687,7 @@ func (s *sIPServer) serveTransferSIPParticipantProtobuf(ctx context.Context, res } func (s *sIPServer) ServiceDescriptor() ([]byte, int) { - return twirpFileDescriptor6, 0 + return twirpFileDescriptor5, 0 } func (s *sIPServer) ProtocGenTwirpVersion() string { @@ -4701,7 +4701,7 @@ func (s *sIPServer) PathPrefix() string { return baseServicePath(s.pathPrefix, "livekit", "SIP") } -var twirpFileDescriptor6 = []byte{ +var twirpFileDescriptor5 = []byte{ // 5979 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x3c, 0x5b, 0x8c, 0x23, 0xd9, 0x55, 0x53, 0x2e, 0x77, 0xb7, 0xfb, 0xba, 0xdb, 0x5d, 0x7d, 0xbb, 0xa7, 0xd7, 0xd3, 0xf3, 0x5c, diff --git a/magefile.go b/magefile.go index 5b42cfd6d..b55d1d004 100644 --- a/magefile.go +++ b/magefile.go @@ -60,7 +60,6 @@ func Proto() error { twirpProtoFiles := []string{ "cloud_replay.proto", "livekit_agent_dispatch.proto", - "livekit_agentdb.proto", "livekit_egress.proto", "livekit_ingress.proto", "livekit_room.proto", @@ -78,10 +77,12 @@ func Proto() error { "agent/livekit_agent_session.proto", "agent/livekit_agent_dev.proto", "agent/livekit_agent_inference.proto", + "agent/livekit_agent_thread.proto", } protoFiles := []string{ "livekit_agent.proto", + "livekit_agentdb.proto", "livekit_analytics.proto", "livekit_internal.proto", "livekit_models.proto", diff --git a/packages/javascript/src/index.d.ts b/packages/javascript/src/index.d.ts index 150b0958a..fb505f671 100644 --- a/packages/javascript/src/index.d.ts +++ b/packages/javascript/src/index.d.ts @@ -1,6 +1,7 @@ import { protoInt64, Timestamp } from "@bufbuild/protobuf"; export { protoInt64, Timestamp }; export * as AgentSession from "./gen/agent/livekit_agent_session_pb.js"; +export * as AgentThread from "./gen/agent/livekit_agent_thread_pb.js"; export * as AgentInference from "./gen/agent/livekit_agent_inference_pb.js"; export * as AgentText from "./gen/agent/livekit_agent_text_pb.js"; export * as AgentDev from "./gen/agent/livekit_agent_dev_pb.js"; diff --git a/packages/javascript/src/index.js b/packages/javascript/src/index.js index d1c654f8c..ef3f0a37c 100644 --- a/packages/javascript/src/index.js +++ b/packages/javascript/src/index.js @@ -2,6 +2,7 @@ import { protoInt64, Timestamp } from "@bufbuild/protobuf"; export { protoInt64, Timestamp }; export * as AgentSession from "./gen/agent/livekit_agent_session_pb.js"; +export * as AgentThread from "./gen/agent/livekit_agent_thread_pb.js"; export * as AgentInference from "./gen/agent/livekit_agent_inference_pb.js"; export * as AgentText from "./gen/agent/livekit_agent_text_pb.js"; export * as AgentDev from "./gen/agent/livekit_agent_dev_pb.js"; diff --git a/protobufs/agent/livekit_agent_thread.proto b/protobufs/agent/livekit_agent_thread.proto new file mode 100644 index 000000000..971765e2a --- /dev/null +++ b/protobufs/agent/livekit_agent_thread.proto @@ -0,0 +1,147 @@ +// Copyright 2026 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. + +// AgentThread: the durable conversation between an agent and a person, across +// channels and over time. Identified by an "AT_" id. Holds a scope, attributes, +// an idle TTL and the AgentDB database created with it. Served by +// cloud-protocol's AgentThreads. The conversation inside follows thread_schema_v1.sql, shared +// by the agents framework, which writes it, and the platform, which reads it. + +syntax = "proto3"; + +package livekit.agent; + +option go_package = "github.com/livekit/protocol/livekit/agent"; + +import "google/protobuf/duration.proto"; +import "google/protobuf/timestamp.proto"; +import "agent/livekit_agent_session.proto"; +import "logger/options.proto"; + +message AgentThread { + message CreateRequest { + // Groups threads, e.g. by user: an application-defined value, typically the + // user's identity. An AgentThreadGrant is scoped by it. + string scope = 1 [(logger.sensitivity) = SENSITIVITY_PII]; + map attributes = 2 [(logger.sensitivity) = SENSITIVITY_PII]; + // Unset takes the server default. + google.protobuf.Duration idle_ttl = 3; + } + + message GetRequest { + string thread_id = 1 [(logger.name) = "threadID"]; + } + + // The threads of one scope, newest first. + message ListRequest { + string scope = 1 [(logger.sensitivity) = SENSITIVITY_PII]; + // Cursor from the previous ListResponse; empty for the first page. + string before = 2; + int32 limit = 3; + } + + message ListResponse { + repeated Thread threads = 1; + // Empty at the end. + string before = 2; + } + + message UpdateRequest { + string thread_id = 1 [(logger.name) = "threadID"]; + // Added to the existing attributes; an empty value deletes the entry. + map attributes = 2 [(logger.sensitivity) = SENSITIVITY_PII]; + google.protobuf.Duration idle_ttl = 3; + // Every update counts as activity and pushes expires_at out by idle_ttl. + } + + message DeleteRequest { + string thread_id = 1 [(logger.name) = "threadID"]; + } + + message DeleteResponse {} + + // The thread's chat items, oldest first. + message GetItemsRequest { + string thread_id = 1 [(logger.name) = "threadID"]; + // One agent's items; empty for every agent's. + string agent = 2; + // Cursor from the previous GetItemsResponse; empty for the first page. + string after = 3; + int32 limit = 4; + } + + message GetItemsResponse { + repeated Item items = 1; + // Empty at the end. + string after = 2; + } + + // One chat item of an agent. Stored as the JSON of + // ChatContext.ChatItem (items.payload in thread_schema_v1.sql). + message Item { + string agent = 1; + // Position in the agent's history. + int64 seq = 2; + // The A2A message the item came from. + string message_id = 3; + ChatContext.ChatItem item = 4 [(logger.sensitivity) = SENSITIVITY_PII]; + } + + message Thread { + string thread_id = 1 [(logger.name) = "threadID"]; + string scope = 2 [(logger.sensitivity) = SENSITIVITY_PII]; + map attributes = 3 [(logger.sensitivity) = SENSITIVITY_PII]; + google.protobuf.Timestamp created_at = 4; + google.protobuf.Timestamp last_active = 5; + // last_active + idle_ttl; every update pushes it out. The thread and its + // database are deleted once it passes. + google.protobuf.Timestamp expires_at = 6; + google.protobuf.Duration idle_ttl = 7; + // The thread's database ("DB_..."), created with the thread. + string database_id = 8; + } +} + +// AgentTask: background work an agent runs within a thread, such as a booking +// that takes minutes. +message AgentTask { + // A task is never UNSPECIFIED. + enum Status { + UNSPECIFIED = 0; + RUNNING = 1; + COMPLETED = 2; + FAILED = 3; + CANCELED = 4; + } + + // A thread's tasks, oldest first. + message GetTasksRequest { + string thread_id = 1 [(logger.name) = "threadID"]; + // Unset for every status. + optional Status status = 2; + } + + message GetTasksResponse { + repeated Task tasks = 1; + } + + message Task { + string task_id = 1; + string thread_id = 2 [(logger.name) = "threadID"]; + // The task's name, as the agent defines it. + string name = 3; + Status status = 4; + google.protobuf.Timestamp updated_at = 5; + } +} diff --git a/protobufs/livekit_agentdb.proto b/protobufs/livekit_agentdb.proto index db4a837af..a30be2c24 100644 --- a/protobufs/livekit_agentdb.proto +++ b/protobufs/livekit_agentdb.proto @@ -12,6 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +// AgentDB: per-agent SQLite databases. Each lives in its project's data region +// on object storage, with one writer at a time. Queries run over the WebSocket +// data plane (AgentDB.Wire); lifecycle is cloud-protocol's AgentDB service. syntax = "proto3"; @@ -21,31 +24,21 @@ option go_package = "github.com/livekit/protocol/livekit"; option csharp_namespace = "LiveKit.Proto"; option ruby_package = "LiveKit::Proto"; -// AgentDBService is the lifecycle and export API for SQLite databases; queries -// run over the data plane below. The project comes from the access token. -service AgentDBService { - rpc CreateDatabase(AgentDB.CreateRequest) returns (AgentDB.CreateResponse); - rpc GetDatabase(AgentDB.GetRequest) returns (AgentDB.AgentDatabase); - rpc ListDatabases(AgentDB.ListRequest) returns (AgentDB.ListResponse); - // Deletes the stored data, not just the metadata. - rpc DeleteDatabase(AgentDB.DeleteRequest) returns (AgentDB.DeleteResponse); - // Exports a consistent SQLite file as a time-limited download URL. - rpc DumpDatabase(AgentDB.DumpRequest) returns (AgentDB.DumpResponse); -} +import "google/protobuf/duration.proto"; +import "google/protobuf/timestamp.proto"; // Nested so that names like Value and Ping need not be unique across the // livekit package. `tip` throughout is the latest durable commit sequence. message AgentDB { message CreateRequest { - string region = 1; - // Unset: never expires, and expires_at is then 0 everywhere. + // Unset: never expires, and expires_at is then unset everywhere. // Otherwise clamped to the server cap, and never extended. - int64 ttl_seconds = 2; + google.protobuf.Duration ttl = 1; } message CreateResponse { string database_id = 1; // "DB_..." - int64 expires_at = 2; + google.protobuf.Timestamp expires_at = 2; } message GetRequest { @@ -66,8 +59,8 @@ message AgentDB { message AgentDatabase { string database_id = 1; string region = 2; - int64 created_at = 3; - int64 expires_at = 4; + google.protobuf.Timestamp created_at = 3; + google.protobuf.Timestamp expires_at = 4; int64 tip = 5; } @@ -77,14 +70,14 @@ message AgentDB { message DeleteResponse {} - message DumpRequest { + message ExportRequest { string database_id = 1; } - message DumpResponse { + message ExportResponse { string download_url = 1; // pre-authenticated object-storage URL - int64 expires_at = 2; // of the URL, not the database - int64 tip = 3; // what the dump is consistent at + google.protobuf.Timestamp expires_at = 2; // of the URL, not the database + int64 tip = 3; // what the export is consistent at } // Data plane: one WebSocket per database, one message per frame, correlated @@ -97,7 +90,7 @@ message AgentDB { Hello hello = 2; // must be first on the socket Statement exec = 3; // answers ExecResult Statement query = 4; // answers Columns + ColumnBatch* + Done - Batch batch = 5; + Batch batch = 5; // answers one result per statement, then Done Begin begin = 6; Commit commit = 7; Rollback rollback = 8; @@ -142,8 +135,14 @@ message AgentDB { QueryLang lang = 3; } + // Applied atomically, in order, and answered with one result per + // statement, in order: Columns then ColumnBatch frames for a statement + // that returns rows, one ExecResult for one that does not, each tagged + // with the statement's 0-based index, then a single Done for the whole + // batch. A statement that returns no rows still sends its Columns. Credit + // paces the ColumnBatch frames of the batch as a whole. message Batch { - repeated Statement statements = 1; // applied atomically, in order + repeated Statement statements = 1; } message Begin {} @@ -177,6 +176,7 @@ message AgentDB { message Columns { repeated string names = 1; + uint32 statement = 2; // index within a Batch; 0 and unused for a Query } enum ValueType { @@ -205,12 +205,14 @@ message AgentDB { message ColumnBatch { repeated Column columns = 1; // one per name in Columns uint32 rows = 2; + uint32 statement = 3; // index within a Batch; 0 and unused for a Query } message ExecResult { int64 rows_affected = 1; int64 last_insert_id = 2; int64 tip = 3; + uint32 statement = 4; // index within a Batch; 0 and unused for an Exec } message Done { diff --git a/utils/guid/id.go b/utils/guid/id.go index b01dd380f..bc7a7d0db 100644 --- a/utils/guid/id.go +++ b/utils/guid/id.go @@ -72,6 +72,8 @@ const ( PhoneNumberPrefix = "PN_" ScenarioPrefix = "SCN_" ScenarioGroupPrefix = "SCNG_" + AgentThreadPrefix = "AT_" + AgentStreamPrefix = "AST_" // ST_ is SIPTrunkPrefix ) const (