mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
feat: add aibridgedserver pkg (#19902)
This commit is contained in:
@@ -641,7 +641,7 @@ GEN_FILES := \
|
||||
provisionersdk/proto/provisioner.pb.go \
|
||||
provisionerd/proto/provisionerd.pb.go \
|
||||
vpn/vpn.pb.go \
|
||||
aibridged/proto/aibridged.pb.go \
|
||||
enterprise/x/aibridged/proto/aibridged.pb.go \
|
||||
$(DB_GEN_FILES) \
|
||||
$(SITE_GEN_FILES) \
|
||||
coderd/rbac/object_gen.go \
|
||||
@@ -690,7 +690,7 @@ gen/mark-fresh:
|
||||
provisionersdk/proto/provisioner.pb.go \
|
||||
provisionerd/proto/provisionerd.pb.go \
|
||||
vpn/vpn.pb.go \
|
||||
aibridged/proto/aibridged.pb.go \
|
||||
enterprise/x/aibridged/proto/aibridged.pb.go \
|
||||
coderd/database/dump.sql \
|
||||
$(DB_GEN_FILES) \
|
||||
site/src/api/typesGenerated.ts \
|
||||
@@ -810,13 +810,13 @@ vpn/vpn.pb.go: vpn/vpn.proto
|
||||
--go_opt=paths=source_relative \
|
||||
./vpn/vpn.proto
|
||||
|
||||
aibridged/proto/aibridged.pb.go: aibridged/proto/aibridged.proto
|
||||
enterprise/x/aibridged/proto/aibridged.pb.go: enterprise/x/aibridged/proto/aibridged.proto
|
||||
protoc \
|
||||
--go_out=. \
|
||||
--go_opt=paths=source_relative \
|
||||
--go-drpc_out=. \
|
||||
--go-drpc_opt=paths=source_relative \
|
||||
./aibridged/proto/aibridged.proto
|
||||
./enterprise/x/aibridged/proto/aibridged.proto
|
||||
|
||||
site/src/api/typesGenerated.ts: site/node_modules/.installed $(wildcard scripts/apitypings/*) $(shell find ./codersdk $(FIND_EXCLUSIONS) -type f -name '*.go')
|
||||
# -C sets the directory for the go run command
|
||||
|
||||
Generated
+2
-1
@@ -990,7 +990,8 @@ CREATE TABLE aibridge_interceptions (
|
||||
initiator_id uuid NOT NULL,
|
||||
provider text NOT NULL,
|
||||
model text NOT NULL,
|
||||
started_at timestamp with time zone NOT NULL
|
||||
started_at timestamp with time zone NOT NULL,
|
||||
metadata jsonb
|
||||
);
|
||||
|
||||
COMMENT ON TABLE aibridge_interceptions IS 'Audit log of requests intercepted by AI Bridge';
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE aibridge_interceptions DROP COLUMN metadata;
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE aibridge_interceptions ADD COLUMN metadata JSONB DEFAULT NULL;
|
||||
@@ -3373,10 +3373,11 @@ func AllWorkspaceTransitionValues() []WorkspaceTransition {
|
||||
type AIBridgeInterception struct {
|
||||
ID uuid.UUID `db:"id" json:"id"`
|
||||
// Relates to a users record, but FK is elided for performance.
|
||||
InitiatorID uuid.UUID `db:"initiator_id" json:"initiator_id"`
|
||||
Provider string `db:"provider" json:"provider"`
|
||||
Model string `db:"model" json:"model"`
|
||||
StartedAt time.Time `db:"started_at" json:"started_at"`
|
||||
InitiatorID uuid.UUID `db:"initiator_id" json:"initiator_id"`
|
||||
Provider string `db:"provider" json:"provider"`
|
||||
Model string `db:"model" json:"model"`
|
||||
StartedAt time.Time `db:"started_at" json:"started_at"`
|
||||
Metadata pqtype.NullRawMessage `db:"metadata" json:"metadata"`
|
||||
}
|
||||
|
||||
// Audit log of tokens used by intercepted requests in AI Bridge
|
||||
|
||||
@@ -112,7 +112,7 @@ func (q *sqlQuerier) ActivityBumpWorkspace(ctx context.Context, arg ActivityBump
|
||||
}
|
||||
|
||||
const getAIBridgeInterceptionByID = `-- name: GetAIBridgeInterceptionByID :one
|
||||
SELECT id, initiator_id, provider, model, started_at FROM aibridge_interceptions WHERE id = $1::uuid
|
||||
SELECT id, initiator_id, provider, model, started_at, metadata FROM aibridge_interceptions WHERE id = $1::uuid
|
||||
`
|
||||
|
||||
func (q *sqlQuerier) GetAIBridgeInterceptionByID(ctx context.Context, id uuid.UUID) (AIBridgeInterception, error) {
|
||||
@@ -124,22 +124,24 @@ func (q *sqlQuerier) GetAIBridgeInterceptionByID(ctx context.Context, id uuid.UU
|
||||
&i.Provider,
|
||||
&i.Model,
|
||||
&i.StartedAt,
|
||||
&i.Metadata,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
const insertAIBridgeInterception = `-- name: InsertAIBridgeInterception :one
|
||||
INSERT INTO aibridge_interceptions (id, initiator_id, provider, model, started_at)
|
||||
VALUES ($1::uuid, $2::uuid, $3, $4, $5)
|
||||
RETURNING id, initiator_id, provider, model, started_at
|
||||
INSERT INTO aibridge_interceptions (id, initiator_id, provider, model, metadata, started_at)
|
||||
VALUES ($1::uuid, $2::uuid, $3, $4, COALESCE($5::jsonb, '{}'::jsonb), $6)
|
||||
RETURNING id, initiator_id, provider, model, started_at, metadata
|
||||
`
|
||||
|
||||
type InsertAIBridgeInterceptionParams struct {
|
||||
ID uuid.UUID `db:"id" json:"id"`
|
||||
InitiatorID uuid.UUID `db:"initiator_id" json:"initiator_id"`
|
||||
Provider string `db:"provider" json:"provider"`
|
||||
Model string `db:"model" json:"model"`
|
||||
StartedAt time.Time `db:"started_at" json:"started_at"`
|
||||
ID uuid.UUID `db:"id" json:"id"`
|
||||
InitiatorID uuid.UUID `db:"initiator_id" json:"initiator_id"`
|
||||
Provider string `db:"provider" json:"provider"`
|
||||
Model string `db:"model" json:"model"`
|
||||
Metadata json.RawMessage `db:"metadata" json:"metadata"`
|
||||
StartedAt time.Time `db:"started_at" json:"started_at"`
|
||||
}
|
||||
|
||||
func (q *sqlQuerier) InsertAIBridgeInterception(ctx context.Context, arg InsertAIBridgeInterceptionParams) (AIBridgeInterception, error) {
|
||||
@@ -148,6 +150,7 @@ func (q *sqlQuerier) InsertAIBridgeInterception(ctx context.Context, arg InsertA
|
||||
arg.InitiatorID,
|
||||
arg.Provider,
|
||||
arg.Model,
|
||||
arg.Metadata,
|
||||
arg.StartedAt,
|
||||
)
|
||||
var i AIBridgeInterception
|
||||
@@ -157,6 +160,7 @@ func (q *sqlQuerier) InsertAIBridgeInterception(ctx context.Context, arg InsertA
|
||||
&i.Provider,
|
||||
&i.Model,
|
||||
&i.StartedAt,
|
||||
&i.Metadata,
|
||||
)
|
||||
return i, err
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
-- name: InsertAIBridgeInterception :one
|
||||
INSERT INTO aibridge_interceptions (id, initiator_id, provider, model, started_at)
|
||||
VALUES (@id::uuid, @initiator_id::uuid, @provider, @model, @started_at)
|
||||
INSERT INTO aibridge_interceptions (id, initiator_id, provider, model, metadata, started_at)
|
||||
VALUES (@id::uuid, @initiator_id::uuid, @provider, @model, COALESCE(@metadata::jsonb, '{}'::jsonb), @started_at)
|
||||
RETURNING *;
|
||||
|
||||
-- name: InsertAIBridgeTokenUsage :exec
|
||||
|
||||
@@ -24,6 +24,9 @@ const (
|
||||
MCPServerName = "Coder"
|
||||
// MCPServerInstructions is the instructions text for the MCP server.
|
||||
MCPServerInstructions = "Coder MCP Server providing workspace and template management tools"
|
||||
|
||||
// Used in tests and aibridge.
|
||||
MCPEndpoint = "/api/experimental/mcp/http"
|
||||
)
|
||||
|
||||
// Server represents an MCP HTTP server instance
|
||||
|
||||
+11
-11
@@ -34,7 +34,7 @@ func TestMCPHTTP_E2E_ClientIntegration(t *testing.T) {
|
||||
_ = coderdtest.CreateFirstUser(t, coderClient)
|
||||
|
||||
// Create MCP client pointing to our endpoint
|
||||
mcpURL := api.AccessURL.String() + "/api/experimental/mcp/http"
|
||||
mcpURL := api.AccessURL.String() + mcpserver.MCPEndpoint
|
||||
|
||||
// Configure client with authentication headers using RFC 6750 Bearer token
|
||||
mcpClient, err := mcpclient.NewStreamableHttpClient(mcpURL,
|
||||
@@ -133,7 +133,7 @@ func TestMCPHTTP_E2E_UnauthenticatedAccess(t *testing.T) {
|
||||
defer cancel()
|
||||
|
||||
// Test direct HTTP request to verify 401 status code
|
||||
mcpURL := api.AccessURL.String() + "/api/experimental/mcp/http"
|
||||
mcpURL := api.AccessURL.String() + mcpserver.MCPEndpoint
|
||||
|
||||
// Make a POST request without authentication (MCP over HTTP uses POST)
|
||||
//nolint:gosec // Test code using controlled localhost URL
|
||||
@@ -197,7 +197,7 @@ func TestMCPHTTP_E2E_ToolWithWorkspace(t *testing.T) {
|
||||
workspace := coderdtest.CreateWorkspace(t, coderClient, template.ID)
|
||||
|
||||
// Create MCP client
|
||||
mcpURL := api.AccessURL.String() + "/api/experimental/mcp/http"
|
||||
mcpURL := api.AccessURL.String() + mcpserver.MCPEndpoint
|
||||
mcpClient, err := mcpclient.NewStreamableHttpClient(mcpURL,
|
||||
transport.WithHTTPHeaders(map[string]string{
|
||||
"Authorization": "Bearer " + coderClient.SessionToken(),
|
||||
@@ -280,7 +280,7 @@ func TestMCPHTTP_E2E_ErrorHandling(t *testing.T) {
|
||||
_ = coderdtest.CreateFirstUser(t, coderClient)
|
||||
|
||||
// Create MCP client
|
||||
mcpURL := api.AccessURL.String() + "/api/experimental/mcp/http"
|
||||
mcpURL := api.AccessURL.String() + mcpserver.MCPEndpoint
|
||||
mcpClient, err := mcpclient.NewStreamableHttpClient(mcpURL,
|
||||
transport.WithHTTPHeaders(map[string]string{
|
||||
"Authorization": "Bearer " + coderClient.SessionToken(),
|
||||
@@ -339,7 +339,7 @@ func TestMCPHTTP_E2E_ConcurrentRequests(t *testing.T) {
|
||||
_ = coderdtest.CreateFirstUser(t, coderClient)
|
||||
|
||||
// Create MCP client
|
||||
mcpURL := api.AccessURL.String() + "/api/experimental/mcp/http"
|
||||
mcpURL := api.AccessURL.String() + mcpserver.MCPEndpoint
|
||||
mcpClient, err := mcpclient.NewStreamableHttpClient(mcpURL,
|
||||
transport.WithHTTPHeaders(map[string]string{
|
||||
"Authorization": "Bearer " + coderClient.SessionToken(),
|
||||
@@ -410,7 +410,7 @@ func TestMCPHTTP_E2E_RFC6750_UnauthenticatedRequest(t *testing.T) {
|
||||
// Make a request without any authentication headers
|
||||
req := &http.Request{
|
||||
Method: "POST",
|
||||
URL: mustParseURL(t, api.AccessURL.String()+"/api/experimental/mcp/http"),
|
||||
URL: mustParseURL(t, api.AccessURL.String()+mcpserver.MCPEndpoint),
|
||||
Header: make(http.Header),
|
||||
}
|
||||
|
||||
@@ -493,7 +493,7 @@ func TestMCPHTTP_E2E_OAuth2_EndToEnd(t *testing.T) {
|
||||
// In a real OAuth2 flow, this would be an OAuth2 access token
|
||||
sessionToken := coderClient.SessionToken()
|
||||
|
||||
mcpURL := api.AccessURL.String() + "/api/experimental/mcp/http"
|
||||
mcpURL := api.AccessURL.String() + mcpserver.MCPEndpoint
|
||||
mcpClient, err := mcpclient.NewStreamableHttpClient(mcpURL,
|
||||
transport.WithHTTPHeaders(map[string]string{
|
||||
"Authorization": "Bearer " + sessionToken,
|
||||
@@ -640,7 +640,7 @@ func TestMCPHTTP_E2E_OAuth2_EndToEnd(t *testing.T) {
|
||||
t.Logf("Successfully obtained refresh token: %s...", refreshToken[:10])
|
||||
|
||||
// Step 3: Use access token to authenticate with MCP endpoint
|
||||
mcpURL := api.AccessURL.String() + "/api/experimental/mcp/http"
|
||||
mcpURL := api.AccessURL.String() + mcpserver.MCPEndpoint
|
||||
mcpClient, err := mcpclient.NewStreamableHttpClient(mcpURL,
|
||||
transport.WithHTTPHeaders(map[string]string{
|
||||
"Authorization": "Bearer " + accessToken,
|
||||
@@ -776,7 +776,7 @@ func TestMCPHTTP_E2E_OAuth2_EndToEnd(t *testing.T) {
|
||||
t.Parallel()
|
||||
req := &http.Request{
|
||||
Method: "POST",
|
||||
URL: mustParseURL(t, api.AccessURL.String()+"/api/experimental/mcp/http"),
|
||||
URL: mustParseURL(t, api.AccessURL.String()+mcpserver.MCPEndpoint),
|
||||
Header: map[string][]string{
|
||||
"Authorization": {"Bearer invalid_token_value"},
|
||||
"Content-Type": {"application/json"},
|
||||
@@ -805,7 +805,7 @@ func TestMCPHTTP_E2E_OAuth2_EndToEnd(t *testing.T) {
|
||||
t.Run("DynamicClientRegistrationWithMCPFlow", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
// Step 1: Attempt unauthenticated MCP access
|
||||
mcpURL := api.AccessURL.String() + "/api/experimental/mcp/http"
|
||||
mcpURL := api.AccessURL.String() + mcpserver.MCPEndpoint
|
||||
req := &http.Request{
|
||||
Method: "POST",
|
||||
URL: mustParseURL(t, mcpURL),
|
||||
@@ -1232,7 +1232,7 @@ func TestMCPHTTP_E2E_ChatGPTEndpoint(t *testing.T) {
|
||||
template := coderdtest.CreateTemplate(t, coderClient, user.OrganizationID, version.ID)
|
||||
|
||||
// Create MCP client pointing to the ChatGPT endpoint
|
||||
mcpURL := api.AccessURL.String() + "/api/experimental/mcp/http?toolset=chatgpt"
|
||||
mcpURL := api.AccessURL.String() + mcpserver.MCPEndpoint + "?toolset=chatgpt"
|
||||
|
||||
// Configure client with authentication headers using RFC 6750 Bearer token
|
||||
mcpClient, err := mcpclient.NewStreamableHttpClient(mcpURL,
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// versions:
|
||||
// protoc-gen-go v1.30.0
|
||||
// protoc v4.23.4
|
||||
// source: aibridged/proto/aibridged.proto
|
||||
// source: enterprise/x/aibridged/proto/aibridged.proto
|
||||
|
||||
package proto
|
||||
|
||||
@@ -38,7 +38,7 @@ type RecordInterceptionRequest struct {
|
||||
func (x *RecordInterceptionRequest) Reset() {
|
||||
*x = RecordInterceptionRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_aibridged_proto_aibridged_proto_msgTypes[0]
|
||||
mi := &file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[0]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -51,7 +51,7 @@ func (x *RecordInterceptionRequest) String() string {
|
||||
func (*RecordInterceptionRequest) ProtoMessage() {}
|
||||
|
||||
func (x *RecordInterceptionRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_aibridged_proto_aibridged_proto_msgTypes[0]
|
||||
mi := &file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[0]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -64,7 +64,7 @@ func (x *RecordInterceptionRequest) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use RecordInterceptionRequest.ProtoReflect.Descriptor instead.
|
||||
func (*RecordInterceptionRequest) Descriptor() ([]byte, []int) {
|
||||
return file_aibridged_proto_aibridged_proto_rawDescGZIP(), []int{0}
|
||||
return file_enterprise_x_aibridged_proto_aibridged_proto_rawDescGZIP(), []int{0}
|
||||
}
|
||||
|
||||
func (x *RecordInterceptionRequest) GetId() string {
|
||||
@@ -118,7 +118,7 @@ type RecordInterceptionResponse struct {
|
||||
func (x *RecordInterceptionResponse) Reset() {
|
||||
*x = RecordInterceptionResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_aibridged_proto_aibridged_proto_msgTypes[1]
|
||||
mi := &file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[1]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -131,7 +131,7 @@ func (x *RecordInterceptionResponse) String() string {
|
||||
func (*RecordInterceptionResponse) ProtoMessage() {}
|
||||
|
||||
func (x *RecordInterceptionResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_aibridged_proto_aibridged_proto_msgTypes[1]
|
||||
mi := &file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[1]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -144,7 +144,7 @@ func (x *RecordInterceptionResponse) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use RecordInterceptionResponse.ProtoReflect.Descriptor instead.
|
||||
func (*RecordInterceptionResponse) Descriptor() ([]byte, []int) {
|
||||
return file_aibridged_proto_aibridged_proto_rawDescGZIP(), []int{1}
|
||||
return file_enterprise_x_aibridged_proto_aibridged_proto_rawDescGZIP(), []int{1}
|
||||
}
|
||||
|
||||
type RecordTokenUsageRequest struct {
|
||||
@@ -163,7 +163,7 @@ type RecordTokenUsageRequest struct {
|
||||
func (x *RecordTokenUsageRequest) Reset() {
|
||||
*x = RecordTokenUsageRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_aibridged_proto_aibridged_proto_msgTypes[2]
|
||||
mi := &file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[2]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -176,7 +176,7 @@ func (x *RecordTokenUsageRequest) String() string {
|
||||
func (*RecordTokenUsageRequest) ProtoMessage() {}
|
||||
|
||||
func (x *RecordTokenUsageRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_aibridged_proto_aibridged_proto_msgTypes[2]
|
||||
mi := &file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[2]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -189,7 +189,7 @@ func (x *RecordTokenUsageRequest) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use RecordTokenUsageRequest.ProtoReflect.Descriptor instead.
|
||||
func (*RecordTokenUsageRequest) Descriptor() ([]byte, []int) {
|
||||
return file_aibridged_proto_aibridged_proto_rawDescGZIP(), []int{2}
|
||||
return file_enterprise_x_aibridged_proto_aibridged_proto_rawDescGZIP(), []int{2}
|
||||
}
|
||||
|
||||
func (x *RecordTokenUsageRequest) GetInterceptionId() string {
|
||||
@@ -243,7 +243,7 @@ type RecordTokenUsageResponse struct {
|
||||
func (x *RecordTokenUsageResponse) Reset() {
|
||||
*x = RecordTokenUsageResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_aibridged_proto_aibridged_proto_msgTypes[3]
|
||||
mi := &file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[3]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -256,7 +256,7 @@ func (x *RecordTokenUsageResponse) String() string {
|
||||
func (*RecordTokenUsageResponse) ProtoMessage() {}
|
||||
|
||||
func (x *RecordTokenUsageResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_aibridged_proto_aibridged_proto_msgTypes[3]
|
||||
mi := &file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[3]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -269,7 +269,7 @@ func (x *RecordTokenUsageResponse) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use RecordTokenUsageResponse.ProtoReflect.Descriptor instead.
|
||||
func (*RecordTokenUsageResponse) Descriptor() ([]byte, []int) {
|
||||
return file_aibridged_proto_aibridged_proto_rawDescGZIP(), []int{3}
|
||||
return file_enterprise_x_aibridged_proto_aibridged_proto_rawDescGZIP(), []int{3}
|
||||
}
|
||||
|
||||
type RecordPromptUsageRequest struct {
|
||||
@@ -287,7 +287,7 @@ type RecordPromptUsageRequest struct {
|
||||
func (x *RecordPromptUsageRequest) Reset() {
|
||||
*x = RecordPromptUsageRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_aibridged_proto_aibridged_proto_msgTypes[4]
|
||||
mi := &file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[4]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -300,7 +300,7 @@ func (x *RecordPromptUsageRequest) String() string {
|
||||
func (*RecordPromptUsageRequest) ProtoMessage() {}
|
||||
|
||||
func (x *RecordPromptUsageRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_aibridged_proto_aibridged_proto_msgTypes[4]
|
||||
mi := &file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[4]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -313,7 +313,7 @@ func (x *RecordPromptUsageRequest) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use RecordPromptUsageRequest.ProtoReflect.Descriptor instead.
|
||||
func (*RecordPromptUsageRequest) Descriptor() ([]byte, []int) {
|
||||
return file_aibridged_proto_aibridged_proto_rawDescGZIP(), []int{4}
|
||||
return file_enterprise_x_aibridged_proto_aibridged_proto_rawDescGZIP(), []int{4}
|
||||
}
|
||||
|
||||
func (x *RecordPromptUsageRequest) GetInterceptionId() string {
|
||||
@@ -360,7 +360,7 @@ type RecordPromptUsageResponse struct {
|
||||
func (x *RecordPromptUsageResponse) Reset() {
|
||||
*x = RecordPromptUsageResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_aibridged_proto_aibridged_proto_msgTypes[5]
|
||||
mi := &file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[5]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -373,7 +373,7 @@ func (x *RecordPromptUsageResponse) String() string {
|
||||
func (*RecordPromptUsageResponse) ProtoMessage() {}
|
||||
|
||||
func (x *RecordPromptUsageResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_aibridged_proto_aibridged_proto_msgTypes[5]
|
||||
mi := &file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[5]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -386,7 +386,7 @@ func (x *RecordPromptUsageResponse) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use RecordPromptUsageResponse.ProtoReflect.Descriptor instead.
|
||||
func (*RecordPromptUsageResponse) Descriptor() ([]byte, []int) {
|
||||
return file_aibridged_proto_aibridged_proto_rawDescGZIP(), []int{5}
|
||||
return file_enterprise_x_aibridged_proto_aibridged_proto_rawDescGZIP(), []int{5}
|
||||
}
|
||||
|
||||
type RecordToolUsageRequest struct {
|
||||
@@ -408,7 +408,7 @@ type RecordToolUsageRequest struct {
|
||||
func (x *RecordToolUsageRequest) Reset() {
|
||||
*x = RecordToolUsageRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_aibridged_proto_aibridged_proto_msgTypes[6]
|
||||
mi := &file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[6]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -421,7 +421,7 @@ func (x *RecordToolUsageRequest) String() string {
|
||||
func (*RecordToolUsageRequest) ProtoMessage() {}
|
||||
|
||||
func (x *RecordToolUsageRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_aibridged_proto_aibridged_proto_msgTypes[6]
|
||||
mi := &file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[6]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -434,7 +434,7 @@ func (x *RecordToolUsageRequest) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use RecordToolUsageRequest.ProtoReflect.Descriptor instead.
|
||||
func (*RecordToolUsageRequest) Descriptor() ([]byte, []int) {
|
||||
return file_aibridged_proto_aibridged_proto_rawDescGZIP(), []int{6}
|
||||
return file_enterprise_x_aibridged_proto_aibridged_proto_rawDescGZIP(), []int{6}
|
||||
}
|
||||
|
||||
func (x *RecordToolUsageRequest) GetInterceptionId() string {
|
||||
@@ -509,7 +509,7 @@ type RecordToolUsageResponse struct {
|
||||
func (x *RecordToolUsageResponse) Reset() {
|
||||
*x = RecordToolUsageResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_aibridged_proto_aibridged_proto_msgTypes[7]
|
||||
mi := &file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[7]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -522,7 +522,7 @@ func (x *RecordToolUsageResponse) String() string {
|
||||
func (*RecordToolUsageResponse) ProtoMessage() {}
|
||||
|
||||
func (x *RecordToolUsageResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_aibridged_proto_aibridged_proto_msgTypes[7]
|
||||
mi := &file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[7]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -535,7 +535,7 @@ func (x *RecordToolUsageResponse) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use RecordToolUsageResponse.ProtoReflect.Descriptor instead.
|
||||
func (*RecordToolUsageResponse) Descriptor() ([]byte, []int) {
|
||||
return file_aibridged_proto_aibridged_proto_rawDescGZIP(), []int{7}
|
||||
return file_enterprise_x_aibridged_proto_aibridged_proto_rawDescGZIP(), []int{7}
|
||||
}
|
||||
|
||||
type GetMCPServerConfigsRequest struct {
|
||||
@@ -549,7 +549,7 @@ type GetMCPServerConfigsRequest struct {
|
||||
func (x *GetMCPServerConfigsRequest) Reset() {
|
||||
*x = GetMCPServerConfigsRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_aibridged_proto_aibridged_proto_msgTypes[8]
|
||||
mi := &file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[8]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -562,7 +562,7 @@ func (x *GetMCPServerConfigsRequest) String() string {
|
||||
func (*GetMCPServerConfigsRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetMCPServerConfigsRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_aibridged_proto_aibridged_proto_msgTypes[8]
|
||||
mi := &file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[8]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -575,7 +575,7 @@ func (x *GetMCPServerConfigsRequest) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use GetMCPServerConfigsRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GetMCPServerConfigsRequest) Descriptor() ([]byte, []int) {
|
||||
return file_aibridged_proto_aibridged_proto_rawDescGZIP(), []int{8}
|
||||
return file_enterprise_x_aibridged_proto_aibridged_proto_rawDescGZIP(), []int{8}
|
||||
}
|
||||
|
||||
func (x *GetMCPServerConfigsRequest) GetUserId() string {
|
||||
@@ -597,7 +597,7 @@ type GetMCPServerConfigsResponse struct {
|
||||
func (x *GetMCPServerConfigsResponse) Reset() {
|
||||
*x = GetMCPServerConfigsResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_aibridged_proto_aibridged_proto_msgTypes[9]
|
||||
mi := &file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[9]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -610,7 +610,7 @@ func (x *GetMCPServerConfigsResponse) String() string {
|
||||
func (*GetMCPServerConfigsResponse) ProtoMessage() {}
|
||||
|
||||
func (x *GetMCPServerConfigsResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_aibridged_proto_aibridged_proto_msgTypes[9]
|
||||
mi := &file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[9]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -623,7 +623,7 @@ func (x *GetMCPServerConfigsResponse) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use GetMCPServerConfigsResponse.ProtoReflect.Descriptor instead.
|
||||
func (*GetMCPServerConfigsResponse) Descriptor() ([]byte, []int) {
|
||||
return file_aibridged_proto_aibridged_proto_rawDescGZIP(), []int{9}
|
||||
return file_enterprise_x_aibridged_proto_aibridged_proto_rawDescGZIP(), []int{9}
|
||||
}
|
||||
|
||||
func (x *GetMCPServerConfigsResponse) GetCoderMcpConfig() *MCPServerConfig {
|
||||
@@ -654,7 +654,7 @@ type MCPServerConfig struct {
|
||||
func (x *MCPServerConfig) Reset() {
|
||||
*x = MCPServerConfig{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_aibridged_proto_aibridged_proto_msgTypes[10]
|
||||
mi := &file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[10]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -667,7 +667,7 @@ func (x *MCPServerConfig) String() string {
|
||||
func (*MCPServerConfig) ProtoMessage() {}
|
||||
|
||||
func (x *MCPServerConfig) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_aibridged_proto_aibridged_proto_msgTypes[10]
|
||||
mi := &file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[10]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -680,7 +680,7 @@ func (x *MCPServerConfig) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use MCPServerConfig.ProtoReflect.Descriptor instead.
|
||||
func (*MCPServerConfig) Descriptor() ([]byte, []int) {
|
||||
return file_aibridged_proto_aibridged_proto_rawDescGZIP(), []int{10}
|
||||
return file_enterprise_x_aibridged_proto_aibridged_proto_rawDescGZIP(), []int{10}
|
||||
}
|
||||
|
||||
func (x *MCPServerConfig) GetId() string {
|
||||
@@ -723,7 +723,7 @@ type GetMCPServerAccessTokensBatchRequest struct {
|
||||
func (x *GetMCPServerAccessTokensBatchRequest) Reset() {
|
||||
*x = GetMCPServerAccessTokensBatchRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_aibridged_proto_aibridged_proto_msgTypes[11]
|
||||
mi := &file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[11]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -736,7 +736,7 @@ func (x *GetMCPServerAccessTokensBatchRequest) String() string {
|
||||
func (*GetMCPServerAccessTokensBatchRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetMCPServerAccessTokensBatchRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_aibridged_proto_aibridged_proto_msgTypes[11]
|
||||
mi := &file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[11]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -749,7 +749,7 @@ func (x *GetMCPServerAccessTokensBatchRequest) ProtoReflect() protoreflect.Messa
|
||||
|
||||
// Deprecated: Use GetMCPServerAccessTokensBatchRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GetMCPServerAccessTokensBatchRequest) Descriptor() ([]byte, []int) {
|
||||
return file_aibridged_proto_aibridged_proto_rawDescGZIP(), []int{11}
|
||||
return file_enterprise_x_aibridged_proto_aibridged_proto_rawDescGZIP(), []int{11}
|
||||
}
|
||||
|
||||
func (x *GetMCPServerAccessTokensBatchRequest) GetUserId() string {
|
||||
@@ -780,7 +780,7 @@ type GetMCPServerAccessTokensBatchResponse struct {
|
||||
func (x *GetMCPServerAccessTokensBatchResponse) Reset() {
|
||||
*x = GetMCPServerAccessTokensBatchResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_aibridged_proto_aibridged_proto_msgTypes[12]
|
||||
mi := &file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[12]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -793,7 +793,7 @@ func (x *GetMCPServerAccessTokensBatchResponse) String() string {
|
||||
func (*GetMCPServerAccessTokensBatchResponse) ProtoMessage() {}
|
||||
|
||||
func (x *GetMCPServerAccessTokensBatchResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_aibridged_proto_aibridged_proto_msgTypes[12]
|
||||
mi := &file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[12]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -806,7 +806,7 @@ func (x *GetMCPServerAccessTokensBatchResponse) ProtoReflect() protoreflect.Mess
|
||||
|
||||
// Deprecated: Use GetMCPServerAccessTokensBatchResponse.ProtoReflect.Descriptor instead.
|
||||
func (*GetMCPServerAccessTokensBatchResponse) Descriptor() ([]byte, []int) {
|
||||
return file_aibridged_proto_aibridged_proto_rawDescGZIP(), []int{12}
|
||||
return file_enterprise_x_aibridged_proto_aibridged_proto_rawDescGZIP(), []int{12}
|
||||
}
|
||||
|
||||
func (x *GetMCPServerAccessTokensBatchResponse) GetAccessTokens() map[string]string {
|
||||
@@ -834,7 +834,7 @@ type IsAuthorizedRequest struct {
|
||||
func (x *IsAuthorizedRequest) Reset() {
|
||||
*x = IsAuthorizedRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_aibridged_proto_aibridged_proto_msgTypes[13]
|
||||
mi := &file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[13]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -847,7 +847,7 @@ func (x *IsAuthorizedRequest) String() string {
|
||||
func (*IsAuthorizedRequest) ProtoMessage() {}
|
||||
|
||||
func (x *IsAuthorizedRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_aibridged_proto_aibridged_proto_msgTypes[13]
|
||||
mi := &file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[13]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -860,7 +860,7 @@ func (x *IsAuthorizedRequest) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use IsAuthorizedRequest.ProtoReflect.Descriptor instead.
|
||||
func (*IsAuthorizedRequest) Descriptor() ([]byte, []int) {
|
||||
return file_aibridged_proto_aibridged_proto_rawDescGZIP(), []int{13}
|
||||
return file_enterprise_x_aibridged_proto_aibridged_proto_rawDescGZIP(), []int{13}
|
||||
}
|
||||
|
||||
func (x *IsAuthorizedRequest) GetKey() string {
|
||||
@@ -881,7 +881,7 @@ type IsAuthorizedResponse struct {
|
||||
func (x *IsAuthorizedResponse) Reset() {
|
||||
*x = IsAuthorizedResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_aibridged_proto_aibridged_proto_msgTypes[14]
|
||||
mi := &file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[14]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
ms.StoreMessageInfo(mi)
|
||||
}
|
||||
@@ -894,7 +894,7 @@ func (x *IsAuthorizedResponse) String() string {
|
||||
func (*IsAuthorizedResponse) ProtoMessage() {}
|
||||
|
||||
func (x *IsAuthorizedResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_aibridged_proto_aibridged_proto_msgTypes[14]
|
||||
mi := &file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[14]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
if ms.LoadMessageInfo() == nil {
|
||||
@@ -907,7 +907,7 @@ func (x *IsAuthorizedResponse) ProtoReflect() protoreflect.Message {
|
||||
|
||||
// Deprecated: Use IsAuthorizedResponse.ProtoReflect.Descriptor instead.
|
||||
func (*IsAuthorizedResponse) Descriptor() ([]byte, []int) {
|
||||
return file_aibridged_proto_aibridged_proto_rawDescGZIP(), []int{14}
|
||||
return file_enterprise_x_aibridged_proto_aibridged_proto_rawDescGZIP(), []int{14}
|
||||
}
|
||||
|
||||
func (x *IsAuthorizedResponse) GetOwnerId() string {
|
||||
@@ -917,55 +917,109 @@ func (x *IsAuthorizedResponse) GetOwnerId() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
var File_aibridged_proto_aibridged_proto protoreflect.FileDescriptor
|
||||
var File_enterprise_x_aibridged_proto_aibridged_proto protoreflect.FileDescriptor
|
||||
|
||||
var file_aibridged_proto_aibridged_proto_rawDesc = []byte{
|
||||
0x0a, 0x1f, 0x61, 0x69, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x2f, 0x61, 0x69, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x12, 0x05, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
|
||||
0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x22, 0xda, 0x02, 0x0a, 0x19, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x49,
|
||||
0x6e, 0x74, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02,
|
||||
0x69, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x6f, 0x72, 0x5f,
|
||||
0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61,
|
||||
0x74, 0x6f, 0x72, 0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65,
|
||||
0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65,
|
||||
0x72, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x12, 0x4a, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64,
|
||||
0x61, 0x74, 0x61, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x65, 0x70,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x61,
|
||||
0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64,
|
||||
0x61, 0x74, 0x61, 0x12, 0x39, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x61,
|
||||
0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74,
|
||||
0x61, 0x6d, 0x70, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x41, 0x74, 0x1a, 0x51,
|
||||
0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12,
|
||||
0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65,
|
||||
0x79, 0x12, 0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
|
||||
0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
|
||||
0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38,
|
||||
0x01, 0x22, 0x1c, 0x0a, 0x1a, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x49, 0x6e, 0x74, 0x65, 0x72,
|
||||
0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||
0xf9, 0x02, 0x0a, 0x17, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x55,
|
||||
0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x69,
|
||||
0x6e, 0x74, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x49, 0x64, 0x12, 0x15, 0x0a, 0x06, 0x6d, 0x73, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x73, 0x67, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x69,
|
||||
0x6e, 0x70, 0x75, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||
0x03, 0x52, 0x0b, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x23,
|
||||
0x0a, 0x0d, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18,
|
||||
0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0c, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x54, 0x6f, 0x6b,
|
||||
0x65, 0x6e, 0x73, 0x12, 0x48, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18,
|
||||
0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65,
|
||||
0x63, 0x6f, 0x72, 0x64, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65,
|
||||
var file_enterprise_x_aibridged_proto_aibridged_proto_rawDesc = []byte{
|
||||
0x0a, 0x2c, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x2f, 0x78, 0x2f, 0x61,
|
||||
0x69, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x61,
|
||||
0x69, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x64, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x05,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
|
||||
0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x22, 0xda, 0x02, 0x0a, 0x19, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x49, 0x6e, 0x74, 0x65,
|
||||
0x72, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12,
|
||||
0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12,
|
||||
0x21, 0x0a, 0x0c, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x6f, 0x72, 0x5f, 0x69, 0x64, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x74, 0x6f, 0x72,
|
||||
0x49, 0x64, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x18, 0x03,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x14,
|
||||
0x0a, 0x05, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d,
|
||||
0x6f, 0x64, 0x65, 0x6c, 0x12, 0x4a, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
|
||||
0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52,
|
||||
0x65, 0x63, 0x6f, 0x72, 0x64, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
|
||||
0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
|
||||
0x12, 0x39, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x06,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
|
||||
0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x65, 0x64, 0x41, 0x74, 0x1a, 0x51, 0x0a, 0x0d, 0x4d,
|
||||
0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03,
|
||||
0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2a,
|
||||
0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e,
|
||||
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
|
||||
0x41, 0x6e, 0x79, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x1c,
|
||||
0x0a, 0x1a, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x65, 0x70,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xf9, 0x02, 0x0a,
|
||||
0x17, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x55, 0x73, 0x61, 0x67,
|
||||
0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x74, 0x65,
|
||||
0x72, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49,
|
||||
0x64, 0x12, 0x15, 0x0a, 0x06, 0x6d, 0x73, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x05, 0x6d, 0x73, 0x67, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x69, 0x6e, 0x70, 0x75,
|
||||
0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b,
|
||||
0x69, 0x6e, 0x70, 0x75, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x6f,
|
||||
0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x04, 0x20, 0x01,
|
||||
0x28, 0x03, 0x52, 0x0c, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73,
|
||||
0x12, 0x48, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x05, 0x20, 0x03,
|
||||
0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x72,
|
||||
0x64, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79,
|
||||
0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72,
|
||||
0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a,
|
||||
0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66,
|
||||
0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61,
|
||||
0x74, 0x65, 0x64, 0x41, 0x74, 0x1a, 0x51, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
|
||||
0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
|
||||
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x05, 0x76,
|
||||
0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x1a, 0x0a, 0x18, 0x52, 0x65, 0x63, 0x6f,
|
||||
0x72, 0x64, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x22, 0xcb, 0x02, 0x0a, 0x18, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x50,
|
||||
0x72, 0x6f, 0x6d, 0x70, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x69, 0x6e, 0x74, 0x65,
|
||||
0x72, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x15, 0x0a, 0x06, 0x6d, 0x73,
|
||||
0x67, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x73, 0x67, 0x49,
|
||||
0x64, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x06, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x12, 0x49, 0x0a, 0x08, 0x6d, 0x65, 0x74,
|
||||
0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74,
|
||||
0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4d, 0x65, 0x74,
|
||||
0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61,
|
||||
0x64, 0x61, 0x74, 0x61, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f,
|
||||
0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
|
||||
0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73,
|
||||
0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x1a,
|
||||
0x51, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79,
|
||||
0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b,
|
||||
0x65, 0x79, 0x12, 0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02,
|
||||
0x38, 0x01, 0x22, 0x1b, 0x0a, 0x19, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x50, 0x72, 0x6f, 0x6d,
|
||||
0x70, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
|
||||
0xed, 0x03, 0x0a, 0x16, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x6f, 0x6f, 0x6c, 0x55, 0x73,
|
||||
0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e,
|
||||
0x74, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x49, 0x64, 0x12, 0x15, 0x0a, 0x06, 0x6d, 0x73, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x73, 0x67, 0x49, 0x64, 0x12, 0x22, 0x0a, 0x0a, 0x73, 0x65,
|
||||
0x72, 0x76, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00,
|
||||
0x52, 0x09, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x55, 0x72, 0x6c, 0x88, 0x01, 0x01, 0x12, 0x12,
|
||||
0x0a, 0x04, 0x74, 0x6f, 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x6f,
|
||||
0x6f, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x6e, 0x6a, 0x65,
|
||||
0x63, 0x74, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x69, 0x6e, 0x6a, 0x65,
|
||||
0x63, 0x74, 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x10, 0x69, 0x6e, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69,
|
||||
0x6f, 0x6e, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x48, 0x01,
|
||||
0x52, 0x0f, 0x69, 0x6e, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45, 0x72, 0x72, 0x6f,
|
||||
0x72, 0x88, 0x01, 0x01, 0x12, 0x47, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
|
||||
0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52,
|
||||
0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x6f, 0x6f, 0x6c, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e,
|
||||
0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x39, 0x0a,
|
||||
0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28,
|
||||
0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28,
|
||||
0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63,
|
||||
0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x1a, 0x51, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61,
|
||||
@@ -973,184 +1027,131 @@ var file_aibridged_proto_aibridged_proto_rawDesc = []byte{
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2a, 0x0a, 0x05, 0x76,
|
||||
0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f,
|
||||
0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79,
|
||||
0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x1a, 0x0a, 0x18, 0x52,
|
||||
0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0xcb, 0x02, 0x0a, 0x18, 0x52, 0x65, 0x63, 0x6f,
|
||||
0x72, 0x64, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71,
|
||||
0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x65, 0x70,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x69,
|
||||
0x6e, 0x74, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x15, 0x0a,
|
||||
0x06, 0x6d, 0x73, 0x67, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d,
|
||||
0x73, 0x67, 0x49, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x18, 0x03,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x12, 0x49, 0x0a, 0x08,
|
||||
0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x50, 0x72, 0x6f,
|
||||
0x6d, 0x70, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e,
|
||||
0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d,
|
||||
0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74,
|
||||
0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f,
|
||||
0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69,
|
||||
0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64,
|
||||
0x41, 0x74, 0x1a, 0x51, 0x0a, 0x0d, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e,
|
||||
0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2a, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75,
|
||||
0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x1b, 0x0a, 0x19, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x50,
|
||||
0x72, 0x6f, 0x6d, 0x70, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x22, 0xed, 0x03, 0x0a, 0x16, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x6f, 0x6f,
|
||||
0x6c, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a,
|
||||
0x0f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x65, 0x70,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x15, 0x0a, 0x06, 0x6d, 0x73, 0x67, 0x5f, 0x69, 0x64,
|
||||
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6d, 0x73, 0x67, 0x49, 0x64, 0x12, 0x22, 0x0a,
|
||||
0x0a, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28,
|
||||
0x09, 0x48, 0x00, 0x52, 0x09, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x55, 0x72, 0x6c, 0x88, 0x01,
|
||||
0x01, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x6f, 0x6f, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x04, 0x74, 0x6f, 0x6f, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x18, 0x05,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x69,
|
||||
0x6e, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x69,
|
||||
0x6e, 0x6a, 0x65, 0x63, 0x74, 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x10, 0x69, 0x6e, 0x76, 0x6f, 0x63,
|
||||
0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28,
|
||||
0x09, 0x48, 0x01, 0x52, 0x0f, 0x69, 0x6e, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x45,
|
||||
0x72, 0x72, 0x6f, 0x72, 0x88, 0x01, 0x01, 0x12, 0x47, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64,
|
||||
0x61, 0x74, 0x61, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x6f, 0x6f, 0x6c, 0x55, 0x73, 0x61, 0x67,
|
||||
0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74,
|
||||
0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
|
||||
0x12, 0x39, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x5f, 0x61, 0x74, 0x18, 0x09,
|
||||
0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
|
||||
0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x41, 0x74, 0x1a, 0x51, 0x0a, 0x0d, 0x4d,
|
||||
0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03,
|
||||
0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2a,
|
||||
0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e,
|
||||
0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
|
||||
0x41, 0x6e, 0x79, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x0d,
|
||||
0x0a, 0x0b, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x42, 0x13, 0x0a,
|
||||
0x11, 0x5f, 0x69, 0x6e, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x72, 0x72,
|
||||
0x6f, 0x72, 0x22, 0x19, 0x0a, 0x17, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x6f, 0x6f, 0x6c,
|
||||
0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x35, 0x0a,
|
||||
0x1a, 0x47, 0x65, 0x74, 0x4d, 0x43, 0x50, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e,
|
||||
0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x75,
|
||||
0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73,
|
||||
0x65, 0x72, 0x49, 0x64, 0x22, 0xb2, 0x01, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x4d, 0x43, 0x50, 0x53,
|
||||
0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x40, 0x0a, 0x10, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x5f, 0x6d, 0x63,
|
||||
0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4d, 0x43, 0x50, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72,
|
||||
0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x4d, 0x63, 0x70,
|
||||
0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x51, 0x0a, 0x19, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e,
|
||||
0x61, 0x6c, 0x5f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x6d, 0x63, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x66,
|
||||
0x69, 0x67, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x2e, 0x4d, 0x43, 0x50, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69,
|
||||
0x67, 0x52, 0x16, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x75, 0x74, 0x68, 0x4d,
|
||||
0x63, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x22, 0x85, 0x01, 0x0a, 0x0f, 0x4d, 0x43,
|
||||
0x50, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x0e, 0x0a,
|
||||
0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a,
|
||||
0x03, 0x75, 0x72, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12,
|
||||
0x28, 0x0a, 0x10, 0x74, 0x6f, 0x6f, 0x6c, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x72, 0x65,
|
||||
0x67, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x6f, 0x6f, 0x6c, 0x41,
|
||||
0x6c, 0x6c, 0x6f, 0x77, 0x52, 0x65, 0x67, 0x65, 0x78, 0x12, 0x26, 0x0a, 0x0f, 0x74, 0x6f, 0x6f,
|
||||
0x6c, 0x5f, 0x64, 0x65, 0x6e, 0x79, 0x5f, 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x0d, 0x74, 0x6f, 0x6f, 0x6c, 0x44, 0x65, 0x6e, 0x79, 0x52, 0x65, 0x67, 0x65,
|
||||
0x78, 0x22, 0x72, 0x0a, 0x24, 0x47, 0x65, 0x74, 0x4d, 0x43, 0x50, 0x53, 0x65, 0x72, 0x76, 0x65,
|
||||
0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x42, 0x61, 0x74,
|
||||
0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65,
|
||||
0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72,
|
||||
0x49, 0x64, 0x12, 0x31, 0x0a, 0x15, 0x6d, 0x63, 0x70, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72,
|
||||
0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28,
|
||||
0x09, 0x52, 0x12, 0x6d, 0x63, 0x70, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66,
|
||||
0x69, 0x67, 0x49, 0x64, 0x73, 0x22, 0xda, 0x02, 0x0a, 0x25, 0x47, 0x65, 0x74, 0x4d, 0x43, 0x50,
|
||||
0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x42, 0x0d, 0x0a, 0x0b, 0x5f,
|
||||
0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x42, 0x13, 0x0a, 0x11, 0x5f, 0x69,
|
||||
0x6e, 0x76, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22,
|
||||
0x19, 0x0a, 0x17, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x6f, 0x6f, 0x6c, 0x55, 0x73, 0x61,
|
||||
0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x35, 0x0a, 0x1a, 0x47, 0x65,
|
||||
0x74, 0x4d, 0x43, 0x50, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
|
||||
0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72,
|
||||
0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49,
|
||||
0x64, 0x22, 0xb2, 0x01, 0x0a, 0x1b, 0x47, 0x65, 0x74, 0x4d, 0x43, 0x50, 0x53, 0x65, 0x72, 0x76,
|
||||
0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x12, 0x40, 0x0a, 0x10, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x5f, 0x6d, 0x63, 0x70, 0x5f, 0x63,
|
||||
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x2e, 0x4d, 0x43, 0x50, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e,
|
||||
0x66, 0x69, 0x67, 0x52, 0x0e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x4d, 0x63, 0x70, 0x43, 0x6f, 0x6e,
|
||||
0x66, 0x69, 0x67, 0x12, 0x51, 0x0a, 0x19, 0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x5f,
|
||||
0x61, 0x75, 0x74, 0x68, 0x5f, 0x6d, 0x63, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73,
|
||||
0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x4d,
|
||||
0x43, 0x50, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x16,
|
||||
0x65, 0x78, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x41, 0x75, 0x74, 0x68, 0x4d, 0x63, 0x70, 0x43,
|
||||
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x22, 0x85, 0x01, 0x0a, 0x0f, 0x4d, 0x43, 0x50, 0x53, 0x65,
|
||||
0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x10, 0x0a, 0x03, 0x75, 0x72,
|
||||
0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x75, 0x72, 0x6c, 0x12, 0x28, 0x0a, 0x10,
|
||||
0x74, 0x6f, 0x6f, 0x6c, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x5f, 0x72, 0x65, 0x67, 0x65, 0x78,
|
||||
0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x74, 0x6f, 0x6f, 0x6c, 0x41, 0x6c, 0x6c, 0x6f,
|
||||
0x77, 0x52, 0x65, 0x67, 0x65, 0x78, 0x12, 0x26, 0x0a, 0x0f, 0x74, 0x6f, 0x6f, 0x6c, 0x5f, 0x64,
|
||||
0x65, 0x6e, 0x79, 0x5f, 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x0d, 0x74, 0x6f, 0x6f, 0x6c, 0x44, 0x65, 0x6e, 0x79, 0x52, 0x65, 0x67, 0x65, 0x78, 0x22, 0x72,
|
||||
0x0a, 0x24, 0x47, 0x65, 0x74, 0x4d, 0x43, 0x50, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x63,
|
||||
0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69,
|
||||
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12,
|
||||
0x31, 0x0a, 0x15, 0x6d, 0x63, 0x70, 0x5f, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x63, 0x6f,
|
||||
0x6e, 0x66, 0x69, 0x67, 0x5f, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x12,
|
||||
0x6d, 0x63, 0x70, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x49,
|
||||
0x64, 0x73, 0x22, 0xda, 0x02, 0x0a, 0x25, 0x47, 0x65, 0x74, 0x4d, 0x43, 0x50, 0x53, 0x65, 0x72,
|
||||
0x76, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x42,
|
||||
0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x63, 0x0a, 0x0d,
|
||||
0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x01, 0x20,
|
||||
0x03, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x4d,
|
||||
0x43, 0x50, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f,
|
||||
0x6b, 0x65, 0x6e, 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
|
||||
0x65, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x45, 0x6e,
|
||||
0x74, 0x72, 0x79, 0x52, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e,
|
||||
0x73, 0x12, 0x50, 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28,
|
||||
0x0b, 0x32, 0x38, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x43, 0x50,
|
||||
0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65,
|
||||
0x6e, 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
|
||||
0x63, 0x0a, 0x0d, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73,
|
||||
0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47,
|
||||
0x65, 0x74, 0x4d, 0x43, 0x50, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73,
|
||||
0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e,
|
||||
0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f,
|
||||
0x6b, 0x65, 0x6e, 0x73, 0x12, 0x50, 0x0a, 0x06, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x18, 0x02,
|
||||
0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74,
|
||||
0x4d, 0x43, 0x50, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54,
|
||||
0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06,
|
||||
0x65, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x1a, 0x3f, 0x0a, 0x11, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73,
|
||||
0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b,
|
||||
0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a,
|
||||
0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61,
|
||||
0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x39, 0x0a, 0x0b, 0x45, 0x72, 0x72, 0x6f, 0x72,
|
||||
0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75,
|
||||
0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02,
|
||||
0x38, 0x01, 0x22, 0x27, 0x0a, 0x13, 0x49, 0x73, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a,
|
||||
0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x31, 0x0a, 0x14, 0x49,
|
||||
0x73, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x32, 0xe4,
|
||||
0x02, 0x0a, 0x08, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x59, 0x0a, 0x12, 0x52,
|
||||
0x65, 0x63, 0x6f, 0x72, 0x64, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x12, 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64,
|
||||
0x49, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x63, 0x6f,
|
||||
0x72, 0x64, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65,
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x10, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64,
|
||||
0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1e, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x55, 0x73,
|
||||
0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x55, 0x73,
|
||||
0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, 0x11, 0x52,
|
||||
0x65, 0x63, 0x6f, 0x72, 0x64, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65,
|
||||
0x12, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x50,
|
||||
0x72, 0x6f, 0x6d, 0x70, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
|
||||
0x74, 0x1a, 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64,
|
||||
0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x12, 0x50, 0x0a, 0x0f, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x6f, 0x6f,
|
||||
0x6c, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52,
|
||||
0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x6f, 0x6f, 0x6c, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65,
|
||||
0x63, 0x6f, 0x72, 0x64, 0x54, 0x6f, 0x6f, 0x6c, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xeb, 0x01, 0x0a, 0x0f, 0x4d, 0x43, 0x50, 0x43, 0x6f, 0x6e,
|
||||
0x66, 0x69, 0x67, 0x75, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x5c, 0x0a, 0x13, 0x47, 0x65, 0x74,
|
||||
0x4d, 0x43, 0x50, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73,
|
||||
0x12, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x43, 0x50, 0x53,
|
||||
0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75,
|
||||
0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x4d,
|
||||
0x43, 0x50, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7a, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x4d, 0x43,
|
||||
0x50, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b,
|
||||
0x65, 0x6e, 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x2b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x2e, 0x47, 0x65, 0x74, 0x4d, 0x43, 0x50, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x63, 0x63,
|
||||
0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65,
|
||||
0x6e, 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e,
|
||||
0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x06, 0x65, 0x72, 0x72,
|
||||
0x6f, 0x72, 0x73, 0x1a, 0x3f, 0x0a, 0x11, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b,
|
||||
0x65, 0x6e, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18,
|
||||
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61,
|
||||
0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
|
||||
0x3a, 0x02, 0x38, 0x01, 0x1a, 0x39, 0x0a, 0x0b, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x73, 0x45, 0x6e,
|
||||
0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22,
|
||||
0x27, 0x0a, 0x13, 0x49, 0x73, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x52,
|
||||
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x22, 0x31, 0x0a, 0x14, 0x49, 0x73, 0x41, 0x75,
|
||||
0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x12, 0x19, 0x0a, 0x08, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x07, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x32, 0xe4, 0x02, 0x0a, 0x08,
|
||||
0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x12, 0x59, 0x0a, 0x12, 0x52, 0x65, 0x63, 0x6f,
|
||||
0x72, 0x64, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x20,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x49, 0x6e, 0x74,
|
||||
0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x21, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x49,
|
||||
0x6e, 0x74, 0x65, 0x72, 0x63, 0x65, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x12, 0x53, 0x0a, 0x10, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x6f, 0x6b,
|
||||
0x65, 0x6e, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
|
||||
0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x55, 0x73, 0x61, 0x67, 0x65,
|
||||
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e,
|
||||
0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x55, 0x73, 0x61, 0x67, 0x65,
|
||||
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x56, 0x0a, 0x11, 0x52, 0x65, 0x63, 0x6f,
|
||||
0x72, 0x64, 0x50, 0x72, 0x6f, 0x6d, 0x70, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1f, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x50, 0x72, 0x6f, 0x6d,
|
||||
0x70, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x50, 0x72, 0x6f,
|
||||
0x6d, 0x70, 0x74, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x12, 0x50, 0x0a, 0x0f, 0x52, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x54, 0x6f, 0x6f, 0x6c, 0x55, 0x73,
|
||||
0x61, 0x67, 0x65, 0x12, 0x1d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x63, 0x6f,
|
||||
0x72, 0x64, 0x54, 0x6f, 0x6f, 0x6c, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x1a, 0x1e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x52, 0x65, 0x63, 0x6f, 0x72,
|
||||
0x64, 0x54, 0x6f, 0x6f, 0x6c, 0x55, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
|
||||
0x73, 0x65, 0x32, 0xeb, 0x01, 0x0a, 0x0f, 0x4d, 0x43, 0x50, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
|
||||
0x75, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x12, 0x5c, 0x0a, 0x13, 0x47, 0x65, 0x74, 0x4d, 0x43, 0x50,
|
||||
0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x12, 0x21, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x43, 0x50, 0x53, 0x65, 0x72, 0x76,
|
||||
0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
|
||||
0x1a, 0x22, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x43, 0x50, 0x53,
|
||||
0x65, 0x72, 0x76, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x73, 0x52, 0x65, 0x73, 0x70,
|
||||
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7a, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x4d, 0x43, 0x50, 0x53, 0x65,
|
||||
0x72, 0x76, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73,
|
||||
0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x2b, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65,
|
||||
0x74, 0x4d, 0x43, 0x50, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73,
|
||||
0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f,
|
||||
0x6e, 0x73, 0x65, 0x32, 0x55, 0x0a, 0x0a, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65,
|
||||
0x72, 0x12, 0x47, 0x0a, 0x0c, 0x49, 0x73, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65,
|
||||
0x64, 0x12, 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x73, 0x41, 0x75, 0x74, 0x68,
|
||||
0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x73, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a,
|
||||
0x65, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x2b, 0x5a, 0x29, 0x67, 0x69,
|
||||
0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x63,
|
||||
0x6f, 0x64, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x2f, 0x61, 0x69, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65,
|
||||
0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65,
|
||||
0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x43,
|
||||
0x50, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b,
|
||||
0x65, 0x6e, 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
|
||||
0x32, 0x55, 0x0a, 0x0a, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x72, 0x12, 0x47,
|
||||
0x0a, 0x0c, 0x49, 0x73, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x12, 0x1a,
|
||||
0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2e, 0x49, 0x73, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69,
|
||||
0x7a, 0x65, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1b, 0x2e, 0x70, 0x72, 0x6f,
|
||||
0x74, 0x6f, 0x2e, 0x49, 0x73, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x2b, 0x5a, 0x29, 0x67, 0x69, 0x74, 0x68, 0x75,
|
||||
0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x63, 0x6f, 0x64, 0x65,
|
||||
0x72, 0x2f, 0x76, 0x32, 0x2f, 0x61, 0x69, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x64, 0x2f, 0x70,
|
||||
0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
file_aibridged_proto_aibridged_proto_rawDescOnce sync.Once
|
||||
file_aibridged_proto_aibridged_proto_rawDescData = file_aibridged_proto_aibridged_proto_rawDesc
|
||||
file_enterprise_x_aibridged_proto_aibridged_proto_rawDescOnce sync.Once
|
||||
file_enterprise_x_aibridged_proto_aibridged_proto_rawDescData = file_enterprise_x_aibridged_proto_aibridged_proto_rawDesc
|
||||
)
|
||||
|
||||
func file_aibridged_proto_aibridged_proto_rawDescGZIP() []byte {
|
||||
file_aibridged_proto_aibridged_proto_rawDescOnce.Do(func() {
|
||||
file_aibridged_proto_aibridged_proto_rawDescData = protoimpl.X.CompressGZIP(file_aibridged_proto_aibridged_proto_rawDescData)
|
||||
func file_enterprise_x_aibridged_proto_aibridged_proto_rawDescGZIP() []byte {
|
||||
file_enterprise_x_aibridged_proto_aibridged_proto_rawDescOnce.Do(func() {
|
||||
file_enterprise_x_aibridged_proto_aibridged_proto_rawDescData = protoimpl.X.CompressGZIP(file_enterprise_x_aibridged_proto_aibridged_proto_rawDescData)
|
||||
})
|
||||
return file_aibridged_proto_aibridged_proto_rawDescData
|
||||
return file_enterprise_x_aibridged_proto_aibridged_proto_rawDescData
|
||||
}
|
||||
|
||||
var file_aibridged_proto_aibridged_proto_msgTypes = make([]protoimpl.MessageInfo, 21)
|
||||
var file_aibridged_proto_aibridged_proto_goTypes = []interface{}{
|
||||
var file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes = make([]protoimpl.MessageInfo, 21)
|
||||
var file_enterprise_x_aibridged_proto_aibridged_proto_goTypes = []interface{}{
|
||||
(*RecordInterceptionRequest)(nil), // 0: proto.RecordInterceptionRequest
|
||||
(*RecordInterceptionResponse)(nil), // 1: proto.RecordInterceptionResponse
|
||||
(*RecordTokenUsageRequest)(nil), // 2: proto.RecordTokenUsageRequest
|
||||
@@ -1175,7 +1176,7 @@ var file_aibridged_proto_aibridged_proto_goTypes = []interface{}{
|
||||
(*timestamppb.Timestamp)(nil), // 21: google.protobuf.Timestamp
|
||||
(*anypb.Any)(nil), // 22: google.protobuf.Any
|
||||
}
|
||||
var file_aibridged_proto_aibridged_proto_depIdxs = []int32{
|
||||
var file_enterprise_x_aibridged_proto_aibridged_proto_depIdxs = []int32{
|
||||
15, // 0: proto.RecordInterceptionRequest.metadata:type_name -> proto.RecordInterceptionRequest.MetadataEntry
|
||||
21, // 1: proto.RecordInterceptionRequest.started_at:type_name -> google.protobuf.Timestamp
|
||||
16, // 2: proto.RecordTokenUsageRequest.metadata:type_name -> proto.RecordTokenUsageRequest.MetadataEntry
|
||||
@@ -1213,13 +1214,13 @@ var file_aibridged_proto_aibridged_proto_depIdxs = []int32{
|
||||
0, // [0:16] is the sub-list for field type_name
|
||||
}
|
||||
|
||||
func init() { file_aibridged_proto_aibridged_proto_init() }
|
||||
func file_aibridged_proto_aibridged_proto_init() {
|
||||
if File_aibridged_proto_aibridged_proto != nil {
|
||||
func init() { file_enterprise_x_aibridged_proto_aibridged_proto_init() }
|
||||
func file_enterprise_x_aibridged_proto_aibridged_proto_init() {
|
||||
if File_enterprise_x_aibridged_proto_aibridged_proto != nil {
|
||||
return
|
||||
}
|
||||
if !protoimpl.UnsafeEnabled {
|
||||
file_aibridged_proto_aibridged_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*RecordInterceptionRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -1231,7 +1232,7 @@ func file_aibridged_proto_aibridged_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_aibridged_proto_aibridged_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*RecordInterceptionResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -1243,7 +1244,7 @@ func file_aibridged_proto_aibridged_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_aibridged_proto_aibridged_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*RecordTokenUsageRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -1255,7 +1256,7 @@ func file_aibridged_proto_aibridged_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_aibridged_proto_aibridged_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*RecordTokenUsageResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -1267,7 +1268,7 @@ func file_aibridged_proto_aibridged_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_aibridged_proto_aibridged_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*RecordPromptUsageRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -1279,7 +1280,7 @@ func file_aibridged_proto_aibridged_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_aibridged_proto_aibridged_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*RecordPromptUsageResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -1291,7 +1292,7 @@ func file_aibridged_proto_aibridged_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_aibridged_proto_aibridged_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*RecordToolUsageRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -1303,7 +1304,7 @@ func file_aibridged_proto_aibridged_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_aibridged_proto_aibridged_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*RecordToolUsageResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -1315,7 +1316,7 @@ func file_aibridged_proto_aibridged_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_aibridged_proto_aibridged_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetMCPServerConfigsRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -1327,7 +1328,7 @@ func file_aibridged_proto_aibridged_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_aibridged_proto_aibridged_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetMCPServerConfigsResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -1339,7 +1340,7 @@ func file_aibridged_proto_aibridged_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_aibridged_proto_aibridged_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*MCPServerConfig); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -1351,7 +1352,7 @@ func file_aibridged_proto_aibridged_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_aibridged_proto_aibridged_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetMCPServerAccessTokensBatchRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -1363,7 +1364,7 @@ func file_aibridged_proto_aibridged_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_aibridged_proto_aibridged_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetMCPServerAccessTokensBatchResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -1375,7 +1376,7 @@ func file_aibridged_proto_aibridged_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_aibridged_proto_aibridged_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*IsAuthorizedRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -1387,7 +1388,7 @@ func file_aibridged_proto_aibridged_proto_init() {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
file_aibridged_proto_aibridged_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
|
||||
file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*IsAuthorizedResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
@@ -1400,23 +1401,23 @@ func file_aibridged_proto_aibridged_proto_init() {
|
||||
}
|
||||
}
|
||||
}
|
||||
file_aibridged_proto_aibridged_proto_msgTypes[6].OneofWrappers = []interface{}{}
|
||||
file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes[6].OneofWrappers = []interface{}{}
|
||||
type x struct{}
|
||||
out := protoimpl.TypeBuilder{
|
||||
File: protoimpl.DescBuilder{
|
||||
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
|
||||
RawDescriptor: file_aibridged_proto_aibridged_proto_rawDesc,
|
||||
RawDescriptor: file_enterprise_x_aibridged_proto_aibridged_proto_rawDesc,
|
||||
NumEnums: 0,
|
||||
NumMessages: 21,
|
||||
NumExtensions: 0,
|
||||
NumServices: 3,
|
||||
},
|
||||
GoTypes: file_aibridged_proto_aibridged_proto_goTypes,
|
||||
DependencyIndexes: file_aibridged_proto_aibridged_proto_depIdxs,
|
||||
MessageInfos: file_aibridged_proto_aibridged_proto_msgTypes,
|
||||
GoTypes: file_enterprise_x_aibridged_proto_aibridged_proto_goTypes,
|
||||
DependencyIndexes: file_enterprise_x_aibridged_proto_aibridged_proto_depIdxs,
|
||||
MessageInfos: file_enterprise_x_aibridged_proto_aibridged_proto_msgTypes,
|
||||
}.Build()
|
||||
File_aibridged_proto_aibridged_proto = out.File
|
||||
file_aibridged_proto_aibridged_proto_rawDesc = nil
|
||||
file_aibridged_proto_aibridged_proto_goTypes = nil
|
||||
file_aibridged_proto_aibridged_proto_depIdxs = nil
|
||||
File_enterprise_x_aibridged_proto_aibridged_proto = out.File
|
||||
file_enterprise_x_aibridged_proto_aibridged_proto_rawDesc = nil
|
||||
file_enterprise_x_aibridged_proto_aibridged_proto_goTypes = nil
|
||||
file_enterprise_x_aibridged_proto_aibridged_proto_depIdxs = nil
|
||||
}
|
||||
+28
-28
@@ -1,6 +1,6 @@
|
||||
// Code generated by protoc-gen-go-drpc. DO NOT EDIT.
|
||||
// protoc-gen-go-drpc version: v0.0.34
|
||||
// source: aibridged/proto/aibridged.proto
|
||||
// source: enterprise/x/aibridged/proto/aibridged.proto
|
||||
|
||||
package proto
|
||||
|
||||
@@ -13,25 +13,25 @@ import (
|
||||
drpcerr "storj.io/drpc/drpcerr"
|
||||
)
|
||||
|
||||
type drpcEncoding_File_aibridged_proto_aibridged_proto struct{}
|
||||
type drpcEncoding_File_enterprise_x_aibridged_proto_aibridged_proto struct{}
|
||||
|
||||
func (drpcEncoding_File_aibridged_proto_aibridged_proto) Marshal(msg drpc.Message) ([]byte, error) {
|
||||
func (drpcEncoding_File_enterprise_x_aibridged_proto_aibridged_proto) Marshal(msg drpc.Message) ([]byte, error) {
|
||||
return proto.Marshal(msg.(proto.Message))
|
||||
}
|
||||
|
||||
func (drpcEncoding_File_aibridged_proto_aibridged_proto) MarshalAppend(buf []byte, msg drpc.Message) ([]byte, error) {
|
||||
func (drpcEncoding_File_enterprise_x_aibridged_proto_aibridged_proto) MarshalAppend(buf []byte, msg drpc.Message) ([]byte, error) {
|
||||
return proto.MarshalOptions{}.MarshalAppend(buf, msg.(proto.Message))
|
||||
}
|
||||
|
||||
func (drpcEncoding_File_aibridged_proto_aibridged_proto) Unmarshal(buf []byte, msg drpc.Message) error {
|
||||
func (drpcEncoding_File_enterprise_x_aibridged_proto_aibridged_proto) Unmarshal(buf []byte, msg drpc.Message) error {
|
||||
return proto.Unmarshal(buf, msg.(proto.Message))
|
||||
}
|
||||
|
||||
func (drpcEncoding_File_aibridged_proto_aibridged_proto) JSONMarshal(msg drpc.Message) ([]byte, error) {
|
||||
func (drpcEncoding_File_enterprise_x_aibridged_proto_aibridged_proto) JSONMarshal(msg drpc.Message) ([]byte, error) {
|
||||
return protojson.Marshal(msg.(proto.Message))
|
||||
}
|
||||
|
||||
func (drpcEncoding_File_aibridged_proto_aibridged_proto) JSONUnmarshal(buf []byte, msg drpc.Message) error {
|
||||
func (drpcEncoding_File_enterprise_x_aibridged_proto_aibridged_proto) JSONUnmarshal(buf []byte, msg drpc.Message) error {
|
||||
return protojson.Unmarshal(buf, msg.(proto.Message))
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ func (c *drpcRecorderClient) DRPCConn() drpc.Conn { return c.cc }
|
||||
|
||||
func (c *drpcRecorderClient) RecordInterception(ctx context.Context, in *RecordInterceptionRequest) (*RecordInterceptionResponse, error) {
|
||||
out := new(RecordInterceptionResponse)
|
||||
err := c.cc.Invoke(ctx, "/proto.Recorder/RecordInterception", drpcEncoding_File_aibridged_proto_aibridged_proto{}, in, out)
|
||||
err := c.cc.Invoke(ctx, "/proto.Recorder/RecordInterception", drpcEncoding_File_enterprise_x_aibridged_proto_aibridged_proto{}, in, out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -65,7 +65,7 @@ func (c *drpcRecorderClient) RecordInterception(ctx context.Context, in *RecordI
|
||||
|
||||
func (c *drpcRecorderClient) RecordTokenUsage(ctx context.Context, in *RecordTokenUsageRequest) (*RecordTokenUsageResponse, error) {
|
||||
out := new(RecordTokenUsageResponse)
|
||||
err := c.cc.Invoke(ctx, "/proto.Recorder/RecordTokenUsage", drpcEncoding_File_aibridged_proto_aibridged_proto{}, in, out)
|
||||
err := c.cc.Invoke(ctx, "/proto.Recorder/RecordTokenUsage", drpcEncoding_File_enterprise_x_aibridged_proto_aibridged_proto{}, in, out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -74,7 +74,7 @@ func (c *drpcRecorderClient) RecordTokenUsage(ctx context.Context, in *RecordTok
|
||||
|
||||
func (c *drpcRecorderClient) RecordPromptUsage(ctx context.Context, in *RecordPromptUsageRequest) (*RecordPromptUsageResponse, error) {
|
||||
out := new(RecordPromptUsageResponse)
|
||||
err := c.cc.Invoke(ctx, "/proto.Recorder/RecordPromptUsage", drpcEncoding_File_aibridged_proto_aibridged_proto{}, in, out)
|
||||
err := c.cc.Invoke(ctx, "/proto.Recorder/RecordPromptUsage", drpcEncoding_File_enterprise_x_aibridged_proto_aibridged_proto{}, in, out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -83,7 +83,7 @@ func (c *drpcRecorderClient) RecordPromptUsage(ctx context.Context, in *RecordPr
|
||||
|
||||
func (c *drpcRecorderClient) RecordToolUsage(ctx context.Context, in *RecordToolUsageRequest) (*RecordToolUsageResponse, error) {
|
||||
out := new(RecordToolUsageResponse)
|
||||
err := c.cc.Invoke(ctx, "/proto.Recorder/RecordToolUsage", drpcEncoding_File_aibridged_proto_aibridged_proto{}, in, out)
|
||||
err := c.cc.Invoke(ctx, "/proto.Recorder/RecordToolUsage", drpcEncoding_File_enterprise_x_aibridged_proto_aibridged_proto{}, in, out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -122,7 +122,7 @@ func (DRPCRecorderDescription) NumMethods() int { return 4 }
|
||||
func (DRPCRecorderDescription) Method(n int) (string, drpc.Encoding, drpc.Receiver, interface{}, bool) {
|
||||
switch n {
|
||||
case 0:
|
||||
return "/proto.Recorder/RecordInterception", drpcEncoding_File_aibridged_proto_aibridged_proto{},
|
||||
return "/proto.Recorder/RecordInterception", drpcEncoding_File_enterprise_x_aibridged_proto_aibridged_proto{},
|
||||
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
|
||||
return srv.(DRPCRecorderServer).
|
||||
RecordInterception(
|
||||
@@ -131,7 +131,7 @@ func (DRPCRecorderDescription) Method(n int) (string, drpc.Encoding, drpc.Receiv
|
||||
)
|
||||
}, DRPCRecorderServer.RecordInterception, true
|
||||
case 1:
|
||||
return "/proto.Recorder/RecordTokenUsage", drpcEncoding_File_aibridged_proto_aibridged_proto{},
|
||||
return "/proto.Recorder/RecordTokenUsage", drpcEncoding_File_enterprise_x_aibridged_proto_aibridged_proto{},
|
||||
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
|
||||
return srv.(DRPCRecorderServer).
|
||||
RecordTokenUsage(
|
||||
@@ -140,7 +140,7 @@ func (DRPCRecorderDescription) Method(n int) (string, drpc.Encoding, drpc.Receiv
|
||||
)
|
||||
}, DRPCRecorderServer.RecordTokenUsage, true
|
||||
case 2:
|
||||
return "/proto.Recorder/RecordPromptUsage", drpcEncoding_File_aibridged_proto_aibridged_proto{},
|
||||
return "/proto.Recorder/RecordPromptUsage", drpcEncoding_File_enterprise_x_aibridged_proto_aibridged_proto{},
|
||||
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
|
||||
return srv.(DRPCRecorderServer).
|
||||
RecordPromptUsage(
|
||||
@@ -149,7 +149,7 @@ func (DRPCRecorderDescription) Method(n int) (string, drpc.Encoding, drpc.Receiv
|
||||
)
|
||||
}, DRPCRecorderServer.RecordPromptUsage, true
|
||||
case 3:
|
||||
return "/proto.Recorder/RecordToolUsage", drpcEncoding_File_aibridged_proto_aibridged_proto{},
|
||||
return "/proto.Recorder/RecordToolUsage", drpcEncoding_File_enterprise_x_aibridged_proto_aibridged_proto{},
|
||||
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
|
||||
return srv.(DRPCRecorderServer).
|
||||
RecordToolUsage(
|
||||
@@ -176,7 +176,7 @@ type drpcRecorder_RecordInterceptionStream struct {
|
||||
}
|
||||
|
||||
func (x *drpcRecorder_RecordInterceptionStream) SendAndClose(m *RecordInterceptionResponse) error {
|
||||
if err := x.MsgSend(m, drpcEncoding_File_aibridged_proto_aibridged_proto{}); err != nil {
|
||||
if err := x.MsgSend(m, drpcEncoding_File_enterprise_x_aibridged_proto_aibridged_proto{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return x.CloseSend()
|
||||
@@ -192,7 +192,7 @@ type drpcRecorder_RecordTokenUsageStream struct {
|
||||
}
|
||||
|
||||
func (x *drpcRecorder_RecordTokenUsageStream) SendAndClose(m *RecordTokenUsageResponse) error {
|
||||
if err := x.MsgSend(m, drpcEncoding_File_aibridged_proto_aibridged_proto{}); err != nil {
|
||||
if err := x.MsgSend(m, drpcEncoding_File_enterprise_x_aibridged_proto_aibridged_proto{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return x.CloseSend()
|
||||
@@ -208,7 +208,7 @@ type drpcRecorder_RecordPromptUsageStream struct {
|
||||
}
|
||||
|
||||
func (x *drpcRecorder_RecordPromptUsageStream) SendAndClose(m *RecordPromptUsageResponse) error {
|
||||
if err := x.MsgSend(m, drpcEncoding_File_aibridged_proto_aibridged_proto{}); err != nil {
|
||||
if err := x.MsgSend(m, drpcEncoding_File_enterprise_x_aibridged_proto_aibridged_proto{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return x.CloseSend()
|
||||
@@ -224,7 +224,7 @@ type drpcRecorder_RecordToolUsageStream struct {
|
||||
}
|
||||
|
||||
func (x *drpcRecorder_RecordToolUsageStream) SendAndClose(m *RecordToolUsageResponse) error {
|
||||
if err := x.MsgSend(m, drpcEncoding_File_aibridged_proto_aibridged_proto{}); err != nil {
|
||||
if err := x.MsgSend(m, drpcEncoding_File_enterprise_x_aibridged_proto_aibridged_proto{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return x.CloseSend()
|
||||
@@ -249,7 +249,7 @@ func (c *drpcMCPConfiguratorClient) DRPCConn() drpc.Conn { return c.cc }
|
||||
|
||||
func (c *drpcMCPConfiguratorClient) GetMCPServerConfigs(ctx context.Context, in *GetMCPServerConfigsRequest) (*GetMCPServerConfigsResponse, error) {
|
||||
out := new(GetMCPServerConfigsResponse)
|
||||
err := c.cc.Invoke(ctx, "/proto.MCPConfigurator/GetMCPServerConfigs", drpcEncoding_File_aibridged_proto_aibridged_proto{}, in, out)
|
||||
err := c.cc.Invoke(ctx, "/proto.MCPConfigurator/GetMCPServerConfigs", drpcEncoding_File_enterprise_x_aibridged_proto_aibridged_proto{}, in, out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -258,7 +258,7 @@ func (c *drpcMCPConfiguratorClient) GetMCPServerConfigs(ctx context.Context, in
|
||||
|
||||
func (c *drpcMCPConfiguratorClient) GetMCPServerAccessTokensBatch(ctx context.Context, in *GetMCPServerAccessTokensBatchRequest) (*GetMCPServerAccessTokensBatchResponse, error) {
|
||||
out := new(GetMCPServerAccessTokensBatchResponse)
|
||||
err := c.cc.Invoke(ctx, "/proto.MCPConfigurator/GetMCPServerAccessTokensBatch", drpcEncoding_File_aibridged_proto_aibridged_proto{}, in, out)
|
||||
err := c.cc.Invoke(ctx, "/proto.MCPConfigurator/GetMCPServerAccessTokensBatch", drpcEncoding_File_enterprise_x_aibridged_proto_aibridged_proto{}, in, out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -287,7 +287,7 @@ func (DRPCMCPConfiguratorDescription) NumMethods() int { return 2 }
|
||||
func (DRPCMCPConfiguratorDescription) Method(n int) (string, drpc.Encoding, drpc.Receiver, interface{}, bool) {
|
||||
switch n {
|
||||
case 0:
|
||||
return "/proto.MCPConfigurator/GetMCPServerConfigs", drpcEncoding_File_aibridged_proto_aibridged_proto{},
|
||||
return "/proto.MCPConfigurator/GetMCPServerConfigs", drpcEncoding_File_enterprise_x_aibridged_proto_aibridged_proto{},
|
||||
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
|
||||
return srv.(DRPCMCPConfiguratorServer).
|
||||
GetMCPServerConfigs(
|
||||
@@ -296,7 +296,7 @@ func (DRPCMCPConfiguratorDescription) Method(n int) (string, drpc.Encoding, drpc
|
||||
)
|
||||
}, DRPCMCPConfiguratorServer.GetMCPServerConfigs, true
|
||||
case 1:
|
||||
return "/proto.MCPConfigurator/GetMCPServerAccessTokensBatch", drpcEncoding_File_aibridged_proto_aibridged_proto{},
|
||||
return "/proto.MCPConfigurator/GetMCPServerAccessTokensBatch", drpcEncoding_File_enterprise_x_aibridged_proto_aibridged_proto{},
|
||||
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
|
||||
return srv.(DRPCMCPConfiguratorServer).
|
||||
GetMCPServerAccessTokensBatch(
|
||||
@@ -323,7 +323,7 @@ type drpcMCPConfigurator_GetMCPServerConfigsStream struct {
|
||||
}
|
||||
|
||||
func (x *drpcMCPConfigurator_GetMCPServerConfigsStream) SendAndClose(m *GetMCPServerConfigsResponse) error {
|
||||
if err := x.MsgSend(m, drpcEncoding_File_aibridged_proto_aibridged_proto{}); err != nil {
|
||||
if err := x.MsgSend(m, drpcEncoding_File_enterprise_x_aibridged_proto_aibridged_proto{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return x.CloseSend()
|
||||
@@ -339,7 +339,7 @@ type drpcMCPConfigurator_GetMCPServerAccessTokensBatchStream struct {
|
||||
}
|
||||
|
||||
func (x *drpcMCPConfigurator_GetMCPServerAccessTokensBatchStream) SendAndClose(m *GetMCPServerAccessTokensBatchResponse) error {
|
||||
if err := x.MsgSend(m, drpcEncoding_File_aibridged_proto_aibridged_proto{}); err != nil {
|
||||
if err := x.MsgSend(m, drpcEncoding_File_enterprise_x_aibridged_proto_aibridged_proto{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return x.CloseSend()
|
||||
@@ -363,7 +363,7 @@ func (c *drpcAuthorizerClient) DRPCConn() drpc.Conn { return c.cc }
|
||||
|
||||
func (c *drpcAuthorizerClient) IsAuthorized(ctx context.Context, in *IsAuthorizedRequest) (*IsAuthorizedResponse, error) {
|
||||
out := new(IsAuthorizedResponse)
|
||||
err := c.cc.Invoke(ctx, "/proto.Authorizer/IsAuthorized", drpcEncoding_File_aibridged_proto_aibridged_proto{}, in, out)
|
||||
err := c.cc.Invoke(ctx, "/proto.Authorizer/IsAuthorized", drpcEncoding_File_enterprise_x_aibridged_proto_aibridged_proto{}, in, out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -387,7 +387,7 @@ func (DRPCAuthorizerDescription) NumMethods() int { return 1 }
|
||||
func (DRPCAuthorizerDescription) Method(n int) (string, drpc.Encoding, drpc.Receiver, interface{}, bool) {
|
||||
switch n {
|
||||
case 0:
|
||||
return "/proto.Authorizer/IsAuthorized", drpcEncoding_File_aibridged_proto_aibridged_proto{},
|
||||
return "/proto.Authorizer/IsAuthorized", drpcEncoding_File_enterprise_x_aibridged_proto_aibridged_proto{},
|
||||
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
|
||||
return srv.(DRPCAuthorizerServer).
|
||||
IsAuthorized(
|
||||
@@ -414,7 +414,7 @@ type drpcAuthorizer_IsAuthorizedStream struct {
|
||||
}
|
||||
|
||||
func (x *drpcAuthorizer_IsAuthorizedStream) SendAndClose(m *IsAuthorizedResponse) error {
|
||||
if err := x.MsgSend(m, drpcEncoding_File_aibridged_proto_aibridged_proto{}); err != nil {
|
||||
if err := x.MsgSend(m, drpcEncoding_File_enterprise_x_aibridged_proto_aibridged_proto{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return x.CloseSend()
|
||||
@@ -0,0 +1,430 @@
|
||||
package aibridgedserver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"crypto/subtle"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"net/url"
|
||||
"slices"
|
||||
"sync"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
"golang.org/x/xerrors"
|
||||
"google.golang.org/protobuf/types/known/anypb"
|
||||
"google.golang.org/protobuf/types/known/structpb"
|
||||
|
||||
"cdr.dev/slog"
|
||||
|
||||
"github.com/coder/coder/v2/coderd/database"
|
||||
"github.com/coder/coder/v2/coderd/database/dbauthz"
|
||||
"github.com/coder/coder/v2/coderd/database/dbtime"
|
||||
"github.com/coder/coder/v2/coderd/externalauth"
|
||||
"github.com/coder/coder/v2/coderd/httpmw"
|
||||
codermcp "github.com/coder/coder/v2/coderd/mcp"
|
||||
"github.com/coder/coder/v2/codersdk"
|
||||
"github.com/coder/coder/v2/enterprise/x/aibridged/proto"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrExpiredOrInvalidOAuthToken = xerrors.New("expired or invalid OAuth2 token")
|
||||
ErrNoMCPConfigFound = xerrors.New("no MCP config found")
|
||||
|
||||
// These errors are returned by IsAuthorized. Since they're just returned as
|
||||
// a generic dRPC error, it's difficult to tell them apart without string
|
||||
// matching.
|
||||
// TODO: return these errors to the client in a more structured/comparable
|
||||
// way.
|
||||
ErrInvalidKey = xerrors.New("invalid key")
|
||||
ErrUnknownKey = xerrors.New("unknown key")
|
||||
ErrExpired = xerrors.New("expired")
|
||||
ErrUnknownUser = xerrors.New("unknown user")
|
||||
ErrDeletedUser = xerrors.New("deleted user")
|
||||
ErrSystemUser = xerrors.New("system user")
|
||||
|
||||
ErrNoExternalAuthLinkFound = xerrors.New("no external auth link found")
|
||||
)
|
||||
|
||||
var (
|
||||
_ proto.DRPCAuthorizerServer = &Server{}
|
||||
_ proto.DRPCMCPConfiguratorServer = &Server{}
|
||||
_ proto.DRPCRecorderServer = &Server{}
|
||||
)
|
||||
|
||||
type store interface {
|
||||
// Recorder-related queries.
|
||||
InsertAIBridgeInterception(ctx context.Context, arg database.InsertAIBridgeInterceptionParams) (database.AIBridgeInterception, error)
|
||||
InsertAIBridgeTokenUsage(ctx context.Context, arg database.InsertAIBridgeTokenUsageParams) error
|
||||
InsertAIBridgeUserPrompt(ctx context.Context, arg database.InsertAIBridgeUserPromptParams) error
|
||||
InsertAIBridgeToolUsage(ctx context.Context, arg database.InsertAIBridgeToolUsageParams) error
|
||||
|
||||
// MCPConfigurator-related queries.
|
||||
GetExternalAuthLinksByUserID(ctx context.Context, userID uuid.UUID) ([]database.ExternalAuthLink, error)
|
||||
|
||||
// Authorizer-related queries.
|
||||
GetAPIKeyByID(ctx context.Context, id string) (database.APIKey, error)
|
||||
GetUserByID(ctx context.Context, id uuid.UUID) (database.User, error)
|
||||
}
|
||||
|
||||
type Server struct {
|
||||
// lifecycleCtx must be tied to the API server's lifecycle
|
||||
// as when the API server shuts down, we want to cancel any
|
||||
// long-running operations.
|
||||
lifecycleCtx context.Context
|
||||
store store
|
||||
logger slog.Logger
|
||||
externalAuthConfigs map[string]*externalauth.Config
|
||||
|
||||
coderMCPConfig *proto.MCPServerConfig // may be nil if not available
|
||||
}
|
||||
|
||||
func NewServer(lifecycleCtx context.Context, store store, logger slog.Logger, accessURL string, externalAuthConfigs []*externalauth.Config, experiments codersdk.Experiments) (*Server, error) {
|
||||
eac := make(map[string]*externalauth.Config, len(externalAuthConfigs))
|
||||
|
||||
for _, cfg := range externalAuthConfigs {
|
||||
// Only External Auth configs which are configured with an MCP URL are relevant to aibridged.
|
||||
if cfg.MCPURL == "" {
|
||||
continue
|
||||
}
|
||||
eac[cfg.ID] = cfg
|
||||
}
|
||||
|
||||
coderMCPConfig, err := getCoderMCPServerConfig(experiments, accessURL)
|
||||
if err != nil {
|
||||
logger.Warn(lifecycleCtx, "failed to retrieve coder MCP server config, Coder MCP will not be available", slog.Error(err))
|
||||
}
|
||||
|
||||
return &Server{
|
||||
lifecycleCtx: lifecycleCtx,
|
||||
store: store,
|
||||
logger: logger.Named("aibridgedserver"),
|
||||
externalAuthConfigs: eac,
|
||||
coderMCPConfig: coderMCPConfig,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) RecordInterception(ctx context.Context, in *proto.RecordInterceptionRequest) (*proto.RecordInterceptionResponse, error) {
|
||||
//nolint:gocritic // AIBridged has specific authz rules.
|
||||
ctx = dbauthz.AsAIBridged(ctx)
|
||||
|
||||
intcID, err := uuid.Parse(in.GetId())
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("invalid interception ID %q: %w", in.GetId(), err)
|
||||
}
|
||||
initID, err := uuid.Parse(in.GetInitiatorId())
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("invalid initiator ID %q: %w", in.GetInitiatorId(), err)
|
||||
}
|
||||
|
||||
_, err = s.store.InsertAIBridgeInterception(ctx, database.InsertAIBridgeInterceptionParams{
|
||||
ID: intcID,
|
||||
InitiatorID: initID,
|
||||
Provider: in.Provider,
|
||||
Model: in.Model,
|
||||
Metadata: marshalMetadata(ctx, s.logger, in.GetMetadata()),
|
||||
StartedAt: in.StartedAt.AsTime(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("start interception: %w", err)
|
||||
}
|
||||
|
||||
return &proto.RecordInterceptionResponse{}, nil
|
||||
}
|
||||
|
||||
func (s *Server) RecordTokenUsage(ctx context.Context, in *proto.RecordTokenUsageRequest) (*proto.RecordTokenUsageResponse, error) {
|
||||
//nolint:gocritic // AIBridged has specific authz rules.
|
||||
ctx = dbauthz.AsAIBridged(ctx)
|
||||
|
||||
intcID, err := uuid.Parse(in.GetInterceptionId())
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to parse interception_id %q: %w", in.GetInterceptionId(), err)
|
||||
}
|
||||
|
||||
err = s.store.InsertAIBridgeTokenUsage(ctx, database.InsertAIBridgeTokenUsageParams{
|
||||
ID: uuid.New(),
|
||||
InterceptionID: intcID,
|
||||
ProviderResponseID: in.GetMsgId(),
|
||||
InputTokens: in.GetInputTokens(),
|
||||
OutputTokens: in.GetOutputTokens(),
|
||||
Metadata: marshalMetadata(ctx, s.logger, in.GetMetadata()),
|
||||
CreatedAt: in.GetCreatedAt().AsTime(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("insert token usage: %w", err)
|
||||
}
|
||||
return &proto.RecordTokenUsageResponse{}, nil
|
||||
}
|
||||
|
||||
func (s *Server) RecordPromptUsage(ctx context.Context, in *proto.RecordPromptUsageRequest) (*proto.RecordPromptUsageResponse, error) {
|
||||
//nolint:gocritic // AIBridged has specific authz rules.
|
||||
ctx = dbauthz.AsAIBridged(ctx)
|
||||
|
||||
intcID, err := uuid.Parse(in.GetInterceptionId())
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to parse interception_id %q: %w", in.GetInterceptionId(), err)
|
||||
}
|
||||
|
||||
err = s.store.InsertAIBridgeUserPrompt(ctx, database.InsertAIBridgeUserPromptParams{
|
||||
ID: uuid.New(),
|
||||
InterceptionID: intcID,
|
||||
ProviderResponseID: in.GetMsgId(),
|
||||
Prompt: in.GetPrompt(),
|
||||
Metadata: marshalMetadata(ctx, s.logger, in.GetMetadata()),
|
||||
CreatedAt: in.GetCreatedAt().AsTime(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("insert user prompt: %w", err)
|
||||
}
|
||||
return &proto.RecordPromptUsageResponse{}, nil
|
||||
}
|
||||
|
||||
func (s *Server) RecordToolUsage(ctx context.Context, in *proto.RecordToolUsageRequest) (*proto.RecordToolUsageResponse, error) {
|
||||
//nolint:gocritic // AIBridged has specific authz rules.
|
||||
ctx = dbauthz.AsAIBridged(ctx)
|
||||
|
||||
intcID, err := uuid.Parse(in.GetInterceptionId())
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("failed to parse interception_id %q: %w", in.GetInterceptionId(), err)
|
||||
}
|
||||
|
||||
err = s.store.InsertAIBridgeToolUsage(ctx, database.InsertAIBridgeToolUsageParams{
|
||||
ID: uuid.New(),
|
||||
InterceptionID: intcID,
|
||||
ProviderResponseID: in.GetMsgId(),
|
||||
ServerUrl: sql.NullString{String: in.GetServerUrl(), Valid: in.ServerUrl != nil},
|
||||
Tool: in.GetTool(),
|
||||
Input: in.GetInput(),
|
||||
Injected: in.GetInjected(),
|
||||
InvocationError: sql.NullString{String: in.GetInvocationError(), Valid: in.InvocationError != nil},
|
||||
Metadata: marshalMetadata(ctx, s.logger, in.GetMetadata()),
|
||||
CreatedAt: in.GetCreatedAt().AsTime(),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("insert tool usage: %w", err)
|
||||
}
|
||||
return &proto.RecordToolUsageResponse{}, nil
|
||||
}
|
||||
|
||||
func (s *Server) GetMCPServerConfigs(_ context.Context, _ *proto.GetMCPServerConfigsRequest) (*proto.GetMCPServerConfigsResponse, error) {
|
||||
cfgs := make([]*proto.MCPServerConfig, 0, len(s.externalAuthConfigs))
|
||||
for _, eac := range s.externalAuthConfigs {
|
||||
var allowlist, denylist string
|
||||
if eac.MCPToolAllowRegex != nil {
|
||||
allowlist = eac.MCPToolAllowRegex.String()
|
||||
}
|
||||
if eac.MCPToolDenyRegex != nil {
|
||||
denylist = eac.MCPToolDenyRegex.String()
|
||||
}
|
||||
|
||||
cfgs = append(cfgs, &proto.MCPServerConfig{
|
||||
Id: eac.ID,
|
||||
Url: eac.MCPURL,
|
||||
ToolAllowRegex: allowlist,
|
||||
ToolDenyRegex: denylist,
|
||||
})
|
||||
}
|
||||
|
||||
return &proto.GetMCPServerConfigsResponse{
|
||||
CoderMcpConfig: s.coderMCPConfig, // it's fine if this is nil
|
||||
ExternalAuthMcpConfigs: cfgs,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) GetMCPServerAccessTokensBatch(ctx context.Context, in *proto.GetMCPServerAccessTokensBatchRequest) (*proto.GetMCPServerAccessTokensBatchResponse, error) {
|
||||
if len(in.GetMcpServerConfigIds()) == 0 {
|
||||
return &proto.GetMCPServerAccessTokensBatchResponse{}, nil
|
||||
}
|
||||
|
||||
userID, err := uuid.Parse(in.GetUserId())
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("parse user_id: %w", err)
|
||||
}
|
||||
|
||||
//nolint:gocritic // AIBridged has specific authz rules.
|
||||
ctx = dbauthz.AsAIBridged(ctx)
|
||||
links, err := s.store.GetExternalAuthLinksByUserID(ctx, userID)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("fetch external auth links: %w", err)
|
||||
}
|
||||
|
||||
if len(links) == 0 {
|
||||
return &proto.GetMCPServerAccessTokensBatchResponse{}, nil
|
||||
}
|
||||
|
||||
// Ensure unique to prevent unnecessary effort.
|
||||
ids := in.GetMcpServerConfigIds()
|
||||
slices.Sort(ids)
|
||||
ids = slices.Compact(ids)
|
||||
|
||||
var (
|
||||
wg sync.WaitGroup
|
||||
errs error
|
||||
|
||||
mu sync.Mutex
|
||||
tokens = make(map[string]string, len(ids))
|
||||
tokenErrs = make(map[string]string)
|
||||
)
|
||||
|
||||
externalAuthLoop:
|
||||
for _, id := range ids {
|
||||
eac, ok := s.externalAuthConfigs[id]
|
||||
if !ok {
|
||||
mu.Lock()
|
||||
s.logger.Warn(ctx, "no MCP server config found by given ID", slog.F("id", id))
|
||||
tokenErrs[id] = ErrNoMCPConfigFound.Error()
|
||||
mu.Unlock()
|
||||
continue
|
||||
}
|
||||
|
||||
for _, link := range links {
|
||||
if link.ProviderID != eac.ID {
|
||||
continue
|
||||
}
|
||||
|
||||
// Validate all configured External Auth links concurrently.
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
// TODO: timeout.
|
||||
valid, _, validateErr := eac.ValidateToken(ctx, link.OAuthToken())
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
if !valid {
|
||||
// TODO: attempt refresh.
|
||||
s.logger.Warn(ctx, "invalid/expired access token, cannot auto-configure MCP", slog.F("provider", link.ProviderID), slog.Error(validateErr))
|
||||
tokenErrs[id] = ErrExpiredOrInvalidOAuthToken.Error()
|
||||
return
|
||||
}
|
||||
|
||||
if validateErr != nil {
|
||||
errs = multierror.Append(errs, validateErr)
|
||||
tokenErrs[id] = validateErr.Error()
|
||||
} else {
|
||||
tokens[id] = link.OAuthAccessToken
|
||||
}
|
||||
}()
|
||||
|
||||
continue externalAuthLoop
|
||||
}
|
||||
|
||||
// No link found for this external auth config, so include a generic
|
||||
// error.
|
||||
mu.Lock()
|
||||
tokenErrs[id] = ErrNoExternalAuthLinkFound.Error()
|
||||
mu.Unlock()
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
return &proto.GetMCPServerAccessTokensBatchResponse{
|
||||
AccessTokens: tokens,
|
||||
Errors: tokenErrs,
|
||||
}, errs
|
||||
}
|
||||
|
||||
// IsAuthorized validates a given Coder API key and returns the user ID to which it belongs (if valid).
|
||||
//
|
||||
// NOTE: this should really be using the code from [httpmw.ExtractAPIKey]. That function not only validates the key
|
||||
// but handles many other cases like updating last used, expiry, etc. This code does not currently use it for
|
||||
// a few reasons:
|
||||
//
|
||||
// 1. [httpmw.ExtractAPIKey] relies on keys being given in specific headers [httpmw.APITokenFromRequest] which AI
|
||||
// bridge requests will not conform to.
|
||||
// 2. The code mixes many different concerns, and handles HTTP responses too, which is undesirable here.
|
||||
// 3. The core logic would need to be extracted, but that will surely be a complex & time-consuming distraction right now.
|
||||
// 4. Once we have an Early Access release of AI Bridge, we need to return to this.
|
||||
//
|
||||
// TODO: replace with logic from [httpmw.ExtractAPIKey].
|
||||
func (s *Server) IsAuthorized(ctx context.Context, in *proto.IsAuthorizedRequest) (*proto.IsAuthorizedResponse, error) {
|
||||
//nolint:gocritic // AIBridged has specific authz rules.
|
||||
ctx = dbauthz.AsAIBridged(ctx)
|
||||
|
||||
// Key matches expected format.
|
||||
keyID, keySecret, err := httpmw.SplitAPIToken(in.GetKey())
|
||||
if err != nil {
|
||||
return nil, ErrInvalidKey
|
||||
}
|
||||
|
||||
// Key exists.
|
||||
key, err := s.store.GetAPIKeyByID(ctx, keyID)
|
||||
if err != nil {
|
||||
s.logger.Warn(ctx, "failed to retrieve API key by id", slog.F("key_id", keyID), slog.Error(err))
|
||||
return nil, ErrUnknownKey
|
||||
}
|
||||
|
||||
// Key has not expired.
|
||||
now := dbtime.Now()
|
||||
if key.ExpiresAt.Before(now) {
|
||||
return nil, ErrExpired
|
||||
}
|
||||
|
||||
// Key secret matches.
|
||||
hashedSecret := sha256.Sum256([]byte(keySecret))
|
||||
if subtle.ConstantTimeCompare(key.HashedSecret, hashedSecret[:]) != 1 {
|
||||
return nil, ErrInvalidKey
|
||||
}
|
||||
|
||||
// User exists.
|
||||
user, err := s.store.GetUserByID(ctx, key.UserID)
|
||||
if err != nil {
|
||||
s.logger.Warn(ctx, "failed to retrieve API key user", slog.F("key_id", keyID), slog.F("user_id", key.UserID), slog.Error(err))
|
||||
return nil, ErrUnknownUser
|
||||
}
|
||||
|
||||
// User is not deleted or a system user.
|
||||
if user.Deleted {
|
||||
return nil, ErrDeletedUser
|
||||
}
|
||||
if user.IsSystem {
|
||||
return nil, ErrSystemUser
|
||||
}
|
||||
|
||||
return &proto.IsAuthorizedResponse{
|
||||
OwnerId: key.UserID.String(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func getCoderMCPServerConfig(experiments codersdk.Experiments, accessURL string) (*proto.MCPServerConfig, error) {
|
||||
// Both the MCP & OAuth2 experiments are currently required in order to use our
|
||||
// internal MCP server.
|
||||
if !experiments.Enabled(codersdk.ExperimentMCPServerHTTP) {
|
||||
return nil, xerrors.Errorf("%q experiment not enabled", codersdk.ExperimentMCPServerHTTP)
|
||||
}
|
||||
if !experiments.Enabled(codersdk.ExperimentOAuth2) {
|
||||
return nil, xerrors.Errorf("%q experiment not enabled", codersdk.ExperimentOAuth2)
|
||||
}
|
||||
|
||||
u, err := url.JoinPath(accessURL, codermcp.MCPEndpoint)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("build MCP URL with %q: %w", accessURL, err)
|
||||
}
|
||||
|
||||
return &proto.MCPServerConfig{
|
||||
Id: "coder",
|
||||
Url: u,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// marshalMetadata attempts to marshal the given metadata map into a
|
||||
// JSON-encoded byte slice. If the marshaling fails, the function logs a
|
||||
// warning and returns nil. The supplied context is only used for logging.
|
||||
func marshalMetadata(ctx context.Context, logger slog.Logger, in map[string]*anypb.Any) []byte {
|
||||
mdMap := make(map[string]any, len(in))
|
||||
for k, v := range in {
|
||||
if v == nil {
|
||||
continue
|
||||
}
|
||||
var sv structpb.Value
|
||||
if err := v.UnmarshalTo(&sv); err == nil {
|
||||
mdMap[k] = sv.AsInterface()
|
||||
}
|
||||
}
|
||||
out, err := json.Marshal(mdMap)
|
||||
if err != nil {
|
||||
logger.Warn(ctx, "failed to marshal aibridge metadata from proto to JSON", slog.F("metadata", in), slog.Error(err))
|
||||
return nil
|
||||
}
|
||||
return out
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package aibridgedserver
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"math"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"google.golang.org/protobuf/proto"
|
||||
"google.golang.org/protobuf/types/known/anypb"
|
||||
"google.golang.org/protobuf/types/known/structpb"
|
||||
|
||||
"cdr.dev/slog"
|
||||
"cdr.dev/slog/sloggers/slogtest"
|
||||
)
|
||||
|
||||
func TestMarshalMetadata(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Run("NilData", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
logger := slogtest.Make(t, &slogtest.Options{IgnoreErrors: true}).Leveled(slog.LevelDebug)
|
||||
out := marshalMetadata(context.Background(), logger, nil)
|
||||
require.JSONEq(t, "{}", string(out))
|
||||
})
|
||||
|
||||
t.Run("WithData", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
logger := slogtest.Make(t, &slogtest.Options{IgnoreErrors: true}).Leveled(slog.LevelDebug)
|
||||
|
||||
list := structpb.NewListValue(&structpb.ListValue{Values: []*structpb.Value{
|
||||
structpb.NewStringValue("a"),
|
||||
structpb.NewNumberValue(1),
|
||||
structpb.NewBoolValue(false),
|
||||
}})
|
||||
obj := structpb.NewStructValue(&structpb.Struct{Fields: map[string]*structpb.Value{
|
||||
"a": structpb.NewStringValue("b"),
|
||||
"n": structpb.NewNumberValue(3),
|
||||
}})
|
||||
|
||||
nonValue := mustMarshalAny(t, &structpb.Struct{Fields: map[string]*structpb.Value{
|
||||
"ignored": structpb.NewStringValue("yes"),
|
||||
}})
|
||||
invalid := &anypb.Any{TypeUrl: "type.googleapis.com/google.protobuf.Value", Value: []byte{0xff, 0x00}}
|
||||
|
||||
in := map[string]*anypb.Any{
|
||||
"null": mustMarshalAny(t, structpb.NewNullValue()),
|
||||
// Scalars
|
||||
"string": mustMarshalAny(t, structpb.NewStringValue("hello")),
|
||||
"bool": mustMarshalAny(t, structpb.NewBoolValue(true)),
|
||||
"number": mustMarshalAny(t, structpb.NewNumberValue(42)),
|
||||
// Complex types
|
||||
"list": mustMarshalAny(t, list),
|
||||
"object": mustMarshalAny(t, obj),
|
||||
// Extra valid entries
|
||||
"ok": mustMarshalAny(t, structpb.NewStringValue("present")),
|
||||
"nan": mustMarshalAny(t, structpb.NewNumberValue(math.NaN())),
|
||||
// Entries that should be ignored
|
||||
"invalid": invalid,
|
||||
"non_value": nonValue,
|
||||
}
|
||||
|
||||
out := marshalMetadata(context.Background(), logger, in)
|
||||
require.NotNil(t, out)
|
||||
var got map[string]any
|
||||
require.NoError(t, json.Unmarshal(out, &got))
|
||||
|
||||
expected := map[string]any{
|
||||
"string": "hello",
|
||||
"bool": true,
|
||||
"number": float64(42),
|
||||
"null": nil,
|
||||
"list": []any{"a", float64(1), false},
|
||||
"object": map[string]any{"a": "b", "n": float64(3)},
|
||||
"ok": "present",
|
||||
"nan": "NaN",
|
||||
}
|
||||
require.Equal(t, expected, got)
|
||||
})
|
||||
}
|
||||
|
||||
func mustMarshalAny(t testing.TB, m proto.Message) *anypb.Any {
|
||||
t.Helper()
|
||||
a, err := anypb.New(m)
|
||||
require.NoError(t, err)
|
||||
return a
|
||||
}
|
||||
@@ -0,0 +1,710 @@
|
||||
package aibridgedserver_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/url"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/sqlc-dev/pqtype"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.uber.org/mock/gomock"
|
||||
protobufproto "google.golang.org/protobuf/proto"
|
||||
"google.golang.org/protobuf/types/known/anypb"
|
||||
"google.golang.org/protobuf/types/known/structpb"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
"github.com/coder/coder/v2/coderd/database"
|
||||
"github.com/coder/coder/v2/coderd/database/dbmock"
|
||||
"github.com/coder/coder/v2/coderd/database/dbtime"
|
||||
"github.com/coder/coder/v2/coderd/externalauth"
|
||||
codermcp "github.com/coder/coder/v2/coderd/mcp"
|
||||
"github.com/coder/coder/v2/codersdk"
|
||||
"github.com/coder/coder/v2/cryptorand"
|
||||
"github.com/coder/coder/v2/enterprise/x/aibridged/proto"
|
||||
"github.com/coder/coder/v2/enterprise/x/aibridgedserver"
|
||||
"github.com/coder/coder/v2/testutil"
|
||||
)
|
||||
|
||||
var requiredExperiments = []codersdk.Experiment{
|
||||
codersdk.ExperimentMCPServerHTTP, codersdk.ExperimentOAuth2,
|
||||
}
|
||||
|
||||
// TestAuthorization validates the authorization logic.
|
||||
// No other tests are explicitly defined in this package because aibridgedserver is
|
||||
// tested via integration tests in the aibridged package (see aibridged/aibridged_integration_test.go).
|
||||
func TestAuthorization(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
// Key will be set to the same key passed to mocksFn if unset.
|
||||
key string
|
||||
// mocksFn is called with a valid API key and user. If the test needs
|
||||
// invalid values, it should just mutate them directly.
|
||||
mocksFn func(db *dbmock.MockStore, apiKey database.APIKey, user database.User)
|
||||
expectedErr error
|
||||
}{
|
||||
{
|
||||
name: "invalid key format",
|
||||
key: "foo",
|
||||
expectedErr: aibridgedserver.ErrInvalidKey,
|
||||
},
|
||||
{
|
||||
name: "unknown key",
|
||||
expectedErr: aibridgedserver.ErrUnknownKey,
|
||||
mocksFn: func(db *dbmock.MockStore, apiKey database.APIKey, user database.User) {
|
||||
db.EXPECT().GetAPIKeyByID(gomock.Any(), apiKey.ID).Times(1).Return(database.APIKey{}, sql.ErrNoRows)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "expired",
|
||||
expectedErr: aibridgedserver.ErrExpired,
|
||||
mocksFn: func(db *dbmock.MockStore, apiKey database.APIKey, user database.User) {
|
||||
apiKey.ExpiresAt = dbtime.Now().Add(-time.Hour)
|
||||
db.EXPECT().GetAPIKeyByID(gomock.Any(), apiKey.ID).Times(1).Return(apiKey, nil)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid key secret",
|
||||
expectedErr: aibridgedserver.ErrInvalidKey,
|
||||
mocksFn: func(db *dbmock.MockStore, apiKey database.APIKey, user database.User) {
|
||||
apiKey.HashedSecret = []byte("differentsecret")
|
||||
db.EXPECT().GetAPIKeyByID(gomock.Any(), apiKey.ID).Times(1).Return(apiKey, nil)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "unknown user",
|
||||
expectedErr: aibridgedserver.ErrUnknownUser,
|
||||
mocksFn: func(db *dbmock.MockStore, apiKey database.APIKey, user database.User) {
|
||||
db.EXPECT().GetAPIKeyByID(gomock.Any(), apiKey.ID).Times(1).Return(apiKey, nil)
|
||||
db.EXPECT().GetUserByID(gomock.Any(), user.ID).Times(1).Return(database.User{}, sql.ErrNoRows)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "deleted user",
|
||||
expectedErr: aibridgedserver.ErrDeletedUser,
|
||||
mocksFn: func(db *dbmock.MockStore, apiKey database.APIKey, user database.User) {
|
||||
db.EXPECT().GetAPIKeyByID(gomock.Any(), apiKey.ID).Times(1).Return(apiKey, nil)
|
||||
db.EXPECT().GetUserByID(gomock.Any(), user.ID).Times(1).Return(database.User{ID: user.ID, Deleted: true}, nil)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "system user",
|
||||
expectedErr: aibridgedserver.ErrSystemUser,
|
||||
mocksFn: func(db *dbmock.MockStore, apiKey database.APIKey, user database.User) {
|
||||
db.EXPECT().GetAPIKeyByID(gomock.Any(), apiKey.ID).Times(1).Return(apiKey, nil)
|
||||
db.EXPECT().GetUserByID(gomock.Any(), user.ID).Times(1).Return(database.User{ID: user.ID, IsSystem: true}, nil)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "valid",
|
||||
mocksFn: func(db *dbmock.MockStore, apiKey database.APIKey, user database.User) {
|
||||
db.EXPECT().GetAPIKeyByID(gomock.Any(), apiKey.ID).Times(1).Return(apiKey, nil)
|
||||
db.EXPECT().GetUserByID(gomock.Any(), user.ID).Times(1).Return(user, nil)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ctrl := gomock.NewController(t)
|
||||
db := dbmock.NewMockStore(ctrl)
|
||||
logger := testutil.Logger(t)
|
||||
|
||||
// Make a fake user and an API key for the mock calls.
|
||||
now := dbtime.Now()
|
||||
user := database.User{
|
||||
ID: uuid.New(),
|
||||
Email: "test@coder.com",
|
||||
Username: "test",
|
||||
Name: "Test User",
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
RBACRoles: []string{},
|
||||
LoginType: database.LoginTypePassword,
|
||||
Status: database.UserStatusActive,
|
||||
LastSeenAt: now,
|
||||
}
|
||||
|
||||
keyID, _ := cryptorand.String(10)
|
||||
keySecret, _ := cryptorand.String(22)
|
||||
token := fmt.Sprintf("%s-%s", keyID, keySecret)
|
||||
keySecretHashed := sha256.Sum256([]byte(keySecret))
|
||||
apiKey := database.APIKey{
|
||||
ID: keyID,
|
||||
LifetimeSeconds: 86400, // default in db
|
||||
HashedSecret: keySecretHashed[:],
|
||||
IPAddress: pqtype.Inet{
|
||||
IPNet: net.IPNet{
|
||||
IP: net.IPv4(127, 0, 0, 1),
|
||||
Mask: net.IPv4Mask(255, 255, 255, 255),
|
||||
},
|
||||
Valid: true,
|
||||
},
|
||||
UserID: user.ID,
|
||||
LastUsed: now,
|
||||
ExpiresAt: now.Add(time.Hour),
|
||||
CreatedAt: now,
|
||||
UpdatedAt: now,
|
||||
LoginType: database.LoginTypePassword,
|
||||
Scopes: []database.APIKeyScope{database.APIKeyScopeAll},
|
||||
TokenName: "",
|
||||
}
|
||||
if tc.key == "" {
|
||||
tc.key = token
|
||||
}
|
||||
|
||||
// Define any case-specific mocks.
|
||||
if tc.mocksFn != nil {
|
||||
tc.mocksFn(db, apiKey, user)
|
||||
}
|
||||
|
||||
srv, err := aibridgedserver.NewServer(t.Context(), db, logger, "/", nil, requiredExperiments)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, srv)
|
||||
|
||||
_, err = srv.IsAuthorized(t.Context(), &proto.IsAuthorizedRequest{Key: tc.key})
|
||||
if tc.expectedErr != nil {
|
||||
require.Error(t, err)
|
||||
require.ErrorIs(t, err, tc.expectedErr)
|
||||
} else {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetMCPServerConfigs(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
externalAuthCfgs := []*externalauth.Config{
|
||||
{
|
||||
ID: "1",
|
||||
MCPURL: "1.com/mcp",
|
||||
},
|
||||
{
|
||||
ID: "2", // Will not be eligible for inclusion since MCPURL is not defined.
|
||||
},
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
experiments codersdk.Experiments
|
||||
externalAuthConfigs []*externalauth.Config
|
||||
expectCoderMCP bool
|
||||
expectedExternalMCP bool
|
||||
}{
|
||||
{
|
||||
name: "experiments not enabled",
|
||||
experiments: codersdk.Experiments{},
|
||||
},
|
||||
{
|
||||
name: "MCP experiment enabled, not OAuth2",
|
||||
experiments: codersdk.Experiments{codersdk.ExperimentMCPServerHTTP},
|
||||
},
|
||||
{
|
||||
name: "OAuth2 experiment enabled, not MCP",
|
||||
experiments: codersdk.Experiments{codersdk.ExperimentOAuth2},
|
||||
},
|
||||
{
|
||||
name: "only internal MCP",
|
||||
experiments: requiredExperiments,
|
||||
expectCoderMCP: true,
|
||||
},
|
||||
{
|
||||
name: "only external MCP",
|
||||
externalAuthConfigs: externalAuthCfgs,
|
||||
expectedExternalMCP: true,
|
||||
},
|
||||
{
|
||||
name: "both internal & external MCP",
|
||||
experiments: requiredExperiments,
|
||||
externalAuthConfigs: externalAuthCfgs,
|
||||
expectCoderMCP: true,
|
||||
expectedExternalMCP: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ctrl := gomock.NewController(t)
|
||||
db := dbmock.NewMockStore(ctrl)
|
||||
logger := testutil.Logger(t)
|
||||
|
||||
accessURL := "https://my-cool-deployment.com"
|
||||
srv, err := aibridgedserver.NewServer(t.Context(), db, logger, accessURL, tc.externalAuthConfigs, tc.experiments)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, srv)
|
||||
|
||||
resp, err := srv.GetMCPServerConfigs(t.Context(), &proto.GetMCPServerConfigsRequest{})
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, resp)
|
||||
|
||||
if tc.expectCoderMCP {
|
||||
coderConfig := resp.CoderMcpConfig
|
||||
require.NotNil(t, coderConfig)
|
||||
require.Equal(t, "coder", coderConfig.GetId())
|
||||
expectedURL, err := url.JoinPath(accessURL, codermcp.MCPEndpoint)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, expectedURL, coderConfig.GetUrl())
|
||||
require.Empty(t, coderConfig.GetToolAllowRegex())
|
||||
require.Empty(t, coderConfig.GetToolDenyRegex())
|
||||
} else {
|
||||
require.Empty(t, resp.GetCoderMcpConfig())
|
||||
}
|
||||
|
||||
if tc.expectedExternalMCP {
|
||||
require.Len(t, resp.GetExternalAuthMcpConfigs(), 1)
|
||||
} else {
|
||||
require.Empty(t, resp.GetExternalAuthMcpConfigs())
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetMCPServerAccessTokensBatch(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ctrl := gomock.NewController(t)
|
||||
db := dbmock.NewMockStore(ctrl)
|
||||
logger := testutil.Logger(t)
|
||||
|
||||
// Given: 2 external auth configured with MCP and 1 without.
|
||||
srv, err := aibridgedserver.NewServer(t.Context(), db, logger, "/", []*externalauth.Config{
|
||||
{
|
||||
ID: "1",
|
||||
MCPURL: "1.com/mcp",
|
||||
},
|
||||
{
|
||||
ID: "2",
|
||||
MCPURL: "2.com/mcp",
|
||||
},
|
||||
{
|
||||
ID: "3",
|
||||
},
|
||||
}, requiredExperiments)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, srv)
|
||||
|
||||
// When: requesting all external auth links, return all.
|
||||
db.EXPECT().GetExternalAuthLinksByUserID(gomock.Any(), gomock.Any()).MinTimes(1).DoAndReturn(func(ctx context.Context, userID uuid.UUID) ([]database.ExternalAuthLink, error) {
|
||||
return []database.ExternalAuthLink{
|
||||
{
|
||||
UserID: userID,
|
||||
ProviderID: "1",
|
||||
OAuthAccessToken: "1-token",
|
||||
},
|
||||
{
|
||||
UserID: userID,
|
||||
ProviderID: "2",
|
||||
OAuthAccessToken: "2-token",
|
||||
OAuthExpiry: dbtime.Now().Add(-time.Minute), // This token is expired and should not be returned.
|
||||
},
|
||||
{
|
||||
UserID: userID,
|
||||
ProviderID: "3",
|
||||
OAuthAccessToken: "3-token",
|
||||
},
|
||||
}, nil
|
||||
})
|
||||
|
||||
// When: accessing the MCP server access tokens, only the 2 with MCP configured should be returned, and the 1 without should
|
||||
// not fail the request but rather have an error returned specifically for that server.
|
||||
resp, err := srv.GetMCPServerAccessTokensBatch(t.Context(), &proto.GetMCPServerAccessTokensBatchRequest{
|
||||
UserId: uuid.NewString(),
|
||||
McpServerConfigIds: []string{"1", "1", "2", "3"}, // Duplicates must be tolerated.
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
// Then: 2 MCP servers are eligible but only 1 will return a valid token as the other expired.
|
||||
require.Len(t, resp.GetAccessTokens(), 1)
|
||||
require.Equal(t, "1-token", resp.GetAccessTokens()["1"])
|
||||
require.Len(t, resp.GetErrors(), 2)
|
||||
require.Contains(t, resp.GetErrors()["2"], aibridgedserver.ErrExpiredOrInvalidOAuthToken.Error())
|
||||
require.Contains(t, resp.GetErrors()["3"], aibridgedserver.ErrNoMCPConfigFound.Error())
|
||||
}
|
||||
|
||||
func TestRecordInterception(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var (
|
||||
metadataProto = map[string]*anypb.Any{
|
||||
"key": mustMarshalAny(t, &structpb.Value{Kind: &structpb.Value_StringValue{StringValue: "value"}}),
|
||||
}
|
||||
metadataJSON = `{"key":"value"}`
|
||||
)
|
||||
|
||||
testRecordMethod(t,
|
||||
func(srv *aibridgedserver.Server, ctx context.Context, req *proto.RecordInterceptionRequest) (*proto.RecordInterceptionResponse, error) {
|
||||
return srv.RecordInterception(ctx, req)
|
||||
},
|
||||
[]testRecordMethodCase[*proto.RecordInterceptionRequest]{
|
||||
{
|
||||
name: "valid interception",
|
||||
request: &proto.RecordInterceptionRequest{
|
||||
Id: uuid.NewString(),
|
||||
InitiatorId: uuid.NewString(),
|
||||
Provider: "anthropic",
|
||||
Model: "claude-4-opus",
|
||||
Metadata: metadataProto,
|
||||
StartedAt: timestamppb.Now(),
|
||||
},
|
||||
setupMocks: func(t *testing.T, db *dbmock.MockStore, req *proto.RecordInterceptionRequest) {
|
||||
interceptionID, err := uuid.Parse(req.GetId())
|
||||
assert.NoError(t, err, "parse interception UUID")
|
||||
initiatorID, err := uuid.Parse(req.GetInitiatorId())
|
||||
assert.NoError(t, err, "parse interception initiator UUID")
|
||||
|
||||
db.EXPECT().InsertAIBridgeInterception(gomock.Any(), database.InsertAIBridgeInterceptionParams{
|
||||
ID: interceptionID,
|
||||
InitiatorID: initiatorID,
|
||||
Provider: req.GetProvider(),
|
||||
Model: req.GetModel(),
|
||||
Metadata: json.RawMessage(metadataJSON),
|
||||
StartedAt: req.StartedAt.AsTime().UTC(),
|
||||
}).Return(database.AIBridgeInterception{
|
||||
ID: interceptionID,
|
||||
InitiatorID: initiatorID,
|
||||
Provider: req.GetProvider(),
|
||||
Model: req.GetModel(),
|
||||
StartedAt: req.StartedAt.AsTime().UTC(),
|
||||
}, nil)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid interception ID",
|
||||
request: &proto.RecordInterceptionRequest{
|
||||
Id: "not-a-uuid",
|
||||
InitiatorId: uuid.NewString(),
|
||||
Provider: "anthropic",
|
||||
Model: "claude-4-opus",
|
||||
StartedAt: timestamppb.Now(),
|
||||
},
|
||||
expectedErr: "invalid interception ID",
|
||||
},
|
||||
{
|
||||
name: "invalid initiator ID",
|
||||
request: &proto.RecordInterceptionRequest{
|
||||
Id: uuid.NewString(),
|
||||
InitiatorId: "not-a-uuid",
|
||||
Provider: "anthropic",
|
||||
Model: "claude-4-opus",
|
||||
StartedAt: timestamppb.Now(),
|
||||
},
|
||||
expectedErr: "invalid initiator ID",
|
||||
},
|
||||
{
|
||||
name: "database error",
|
||||
request: &proto.RecordInterceptionRequest{
|
||||
Id: uuid.NewString(),
|
||||
InitiatorId: uuid.NewString(),
|
||||
Provider: "anthropic",
|
||||
Model: "claude-4-opus",
|
||||
StartedAt: timestamppb.Now(),
|
||||
},
|
||||
setupMocks: func(t *testing.T, db *dbmock.MockStore, req *proto.RecordInterceptionRequest) {
|
||||
db.EXPECT().InsertAIBridgeInterception(gomock.Any(), gomock.Any()).Return(database.AIBridgeInterception{}, sql.ErrConnDone)
|
||||
},
|
||||
expectedErr: "start interception",
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func TestRecordTokenUsage(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var (
|
||||
metadataProto = map[string]*anypb.Any{
|
||||
"key": mustMarshalAny(t, &structpb.Value{Kind: &structpb.Value_StringValue{StringValue: "value"}}),
|
||||
}
|
||||
metadataJSON = `{"key":"value"}`
|
||||
)
|
||||
|
||||
testRecordMethod(t,
|
||||
func(srv *aibridgedserver.Server, ctx context.Context, req *proto.RecordTokenUsageRequest) (*proto.RecordTokenUsageResponse, error) {
|
||||
return srv.RecordTokenUsage(ctx, req)
|
||||
},
|
||||
[]testRecordMethodCase[*proto.RecordTokenUsageRequest]{
|
||||
{
|
||||
name: "valid token usage",
|
||||
request: &proto.RecordTokenUsageRequest{
|
||||
InterceptionId: uuid.NewString(),
|
||||
MsgId: "msg_123",
|
||||
InputTokens: 100,
|
||||
OutputTokens: 200,
|
||||
Metadata: metadataProto,
|
||||
CreatedAt: timestamppb.Now(),
|
||||
},
|
||||
setupMocks: func(t *testing.T, db *dbmock.MockStore, req *proto.RecordTokenUsageRequest) {
|
||||
interceptionID, err := uuid.Parse(req.GetInterceptionId())
|
||||
assert.NoError(t, err, "parse interception UUID")
|
||||
|
||||
db.EXPECT().InsertAIBridgeTokenUsage(gomock.Any(), gomock.Cond(func(p database.InsertAIBridgeTokenUsageParams) bool {
|
||||
if !assert.NotEqual(t, uuid.Nil, p.ID, "ID") ||
|
||||
!assert.Equal(t, interceptionID, p.InterceptionID, "interception ID") ||
|
||||
!assert.Equal(t, req.GetMsgId(), p.ProviderResponseID, "provider response ID") ||
|
||||
!assert.Equal(t, req.GetInputTokens(), p.InputTokens, "input tokens") ||
|
||||
!assert.Equal(t, req.GetOutputTokens(), p.OutputTokens, "output tokens") ||
|
||||
!assert.JSONEq(t, metadataJSON, string(p.Metadata), "metadata") ||
|
||||
!assert.WithinDuration(t, req.GetCreatedAt().AsTime(), p.CreatedAt, time.Second, "created at") {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})).Return(nil)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid interception ID",
|
||||
request: &proto.RecordTokenUsageRequest{
|
||||
InterceptionId: "not-a-uuid",
|
||||
MsgId: "msg_123",
|
||||
InputTokens: 100,
|
||||
OutputTokens: 200,
|
||||
CreatedAt: timestamppb.Now(),
|
||||
},
|
||||
expectedErr: "failed to parse interception_id",
|
||||
},
|
||||
{
|
||||
name: "database error",
|
||||
request: &proto.RecordTokenUsageRequest{
|
||||
InterceptionId: uuid.NewString(),
|
||||
MsgId: "msg_123",
|
||||
InputTokens: 100,
|
||||
OutputTokens: 200,
|
||||
CreatedAt: timestamppb.Now(),
|
||||
},
|
||||
setupMocks: func(t *testing.T, db *dbmock.MockStore, req *proto.RecordTokenUsageRequest) {
|
||||
db.EXPECT().InsertAIBridgeTokenUsage(gomock.Any(), gomock.Any()).Return(sql.ErrConnDone)
|
||||
},
|
||||
expectedErr: "insert token usage",
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func TestRecordPromptUsage(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var (
|
||||
metadataProto = map[string]*anypb.Any{
|
||||
"key": mustMarshalAny(t, &structpb.Value{Kind: &structpb.Value_StringValue{StringValue: "value"}}),
|
||||
}
|
||||
metadataJSON = `{"key":"value"}`
|
||||
)
|
||||
|
||||
testRecordMethod(t,
|
||||
func(srv *aibridgedserver.Server, ctx context.Context, req *proto.RecordPromptUsageRequest) (*proto.RecordPromptUsageResponse, error) {
|
||||
return srv.RecordPromptUsage(ctx, req)
|
||||
},
|
||||
[]testRecordMethodCase[*proto.RecordPromptUsageRequest]{
|
||||
{
|
||||
name: "valid prompt usage",
|
||||
request: &proto.RecordPromptUsageRequest{
|
||||
InterceptionId: uuid.NewString(),
|
||||
MsgId: "msg_123",
|
||||
Prompt: "yo",
|
||||
Metadata: metadataProto,
|
||||
CreatedAt: timestamppb.Now(),
|
||||
},
|
||||
setupMocks: func(t *testing.T, db *dbmock.MockStore, req *proto.RecordPromptUsageRequest) {
|
||||
interceptionID, err := uuid.Parse(req.GetInterceptionId())
|
||||
assert.NoError(t, err, "parse interception UUID")
|
||||
|
||||
db.EXPECT().InsertAIBridgeUserPrompt(gomock.Any(), gomock.Cond(func(p database.InsertAIBridgeUserPromptParams) bool {
|
||||
if !assert.NotEqual(t, uuid.Nil, p.ID, "ID") ||
|
||||
!assert.Equal(t, interceptionID, p.InterceptionID, "interception ID") ||
|
||||
!assert.Equal(t, req.GetMsgId(), p.ProviderResponseID, "provider response ID") ||
|
||||
!assert.Equal(t, req.GetPrompt(), p.Prompt, "prompt") ||
|
||||
!assert.JSONEq(t, metadataJSON, string(p.Metadata), "metadata") ||
|
||||
!assert.WithinDuration(t, req.GetCreatedAt().AsTime(), p.CreatedAt, time.Second, "created at") {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})).Return(nil)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid interception ID",
|
||||
request: &proto.RecordPromptUsageRequest{
|
||||
InterceptionId: "not-a-uuid",
|
||||
MsgId: "msg_123",
|
||||
Prompt: "yo",
|
||||
CreatedAt: timestamppb.Now(),
|
||||
},
|
||||
expectedErr: "failed to parse interception_id",
|
||||
},
|
||||
{
|
||||
name: "database error",
|
||||
request: &proto.RecordPromptUsageRequest{
|
||||
InterceptionId: uuid.NewString(),
|
||||
MsgId: "msg_123",
|
||||
Prompt: "yo",
|
||||
CreatedAt: timestamppb.Now(),
|
||||
},
|
||||
setupMocks: func(t *testing.T, db *dbmock.MockStore, req *proto.RecordPromptUsageRequest) {
|
||||
db.EXPECT().InsertAIBridgeUserPrompt(gomock.Any(), gomock.Any()).Return(sql.ErrConnDone)
|
||||
},
|
||||
expectedErr: "insert user prompt",
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func TestRecordToolUsage(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var (
|
||||
metadataProto = map[string]*anypb.Any{
|
||||
"key": mustMarshalAny(t, &structpb.Value{Kind: &structpb.Value_NumberValue{NumberValue: 123.45}}),
|
||||
}
|
||||
metadataJSON = `{"key":123.45}`
|
||||
)
|
||||
|
||||
testRecordMethod(t,
|
||||
func(srv *aibridgedserver.Server, ctx context.Context, req *proto.RecordToolUsageRequest) (*proto.RecordToolUsageResponse, error) {
|
||||
return srv.RecordToolUsage(ctx, req)
|
||||
},
|
||||
[]testRecordMethodCase[*proto.RecordToolUsageRequest]{
|
||||
{
|
||||
name: "valid tool usage with all fields",
|
||||
request: &proto.RecordToolUsageRequest{
|
||||
InterceptionId: uuid.NewString(),
|
||||
MsgId: "msg_123",
|
||||
ServerUrl: strPtr("https://api.example.com"),
|
||||
Tool: "read_file",
|
||||
Input: `{"path": "/etc/hosts"}`,
|
||||
Injected: false,
|
||||
InvocationError: strPtr("permission denied"),
|
||||
Metadata: metadataProto,
|
||||
CreatedAt: timestamppb.Now(),
|
||||
},
|
||||
setupMocks: func(t *testing.T, db *dbmock.MockStore, req *proto.RecordToolUsageRequest) {
|
||||
interceptionID, err := uuid.Parse(req.GetInterceptionId())
|
||||
assert.NoError(t, err, "parse interception UUID")
|
||||
|
||||
dbServerURL := sql.NullString{}
|
||||
if req.ServerUrl != nil {
|
||||
dbServerURL.String = *req.ServerUrl
|
||||
dbServerURL.Valid = true
|
||||
}
|
||||
|
||||
dbInvocationError := sql.NullString{}
|
||||
if req.InvocationError != nil {
|
||||
dbInvocationError.String = *req.InvocationError
|
||||
dbInvocationError.Valid = true
|
||||
}
|
||||
|
||||
db.EXPECT().InsertAIBridgeToolUsage(gomock.Any(), gomock.Cond(func(p database.InsertAIBridgeToolUsageParams) bool {
|
||||
if !assert.NotEqual(t, uuid.Nil, p.ID, "ID") ||
|
||||
!assert.Equal(t, interceptionID, p.InterceptionID, "interception ID") ||
|
||||
!assert.Equal(t, req.GetMsgId(), p.ProviderResponseID, "provider response ID") ||
|
||||
!assert.Equal(t, req.GetTool(), p.Tool, "tool") ||
|
||||
!assert.Equal(t, dbServerURL, p.ServerUrl, "server URL") ||
|
||||
!assert.Equal(t, req.GetInput(), p.Input, "input") ||
|
||||
!assert.Equal(t, req.GetInjected(), p.Injected, "injected") ||
|
||||
!assert.Equal(t, dbInvocationError, p.InvocationError, "invocation error") ||
|
||||
!assert.JSONEq(t, metadataJSON, string(p.Metadata), "metadata") ||
|
||||
!assert.WithinDuration(t, req.GetCreatedAt().AsTime(), p.CreatedAt, time.Second, "created at") {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})).Return(nil)
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid interception ID",
|
||||
request: &proto.RecordToolUsageRequest{
|
||||
InterceptionId: "not-a-uuid",
|
||||
MsgId: "msg_123",
|
||||
Tool: "read_file",
|
||||
Input: `{"path": "/etc/hosts"}`,
|
||||
CreatedAt: timestamppb.Now(),
|
||||
},
|
||||
expectedErr: "failed to parse interception_id",
|
||||
},
|
||||
{
|
||||
name: "database error",
|
||||
request: &proto.RecordToolUsageRequest{
|
||||
InterceptionId: uuid.NewString(),
|
||||
MsgId: "msg_123",
|
||||
Tool: "read_file",
|
||||
Input: `{"path": "/etc/hosts"}`,
|
||||
CreatedAt: timestamppb.Now(),
|
||||
},
|
||||
setupMocks: func(t *testing.T, db *dbmock.MockStore, req *proto.RecordToolUsageRequest) {
|
||||
db.EXPECT().InsertAIBridgeToolUsage(gomock.Any(), gomock.Any()).Return(sql.ErrConnDone)
|
||||
},
|
||||
expectedErr: "insert tool usage",
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
type testRecordMethodCase[Req any] struct {
|
||||
name string
|
||||
request Req
|
||||
// setupMocks is called with the mock store and the above request.
|
||||
setupMocks func(t *testing.T, db *dbmock.MockStore, req Req)
|
||||
expectedErr string
|
||||
}
|
||||
|
||||
// testRecordMethod is a helper that abstracts the common testing pattern for all Record* methods.
|
||||
func testRecordMethod[Req any, Resp any](
|
||||
t *testing.T,
|
||||
callMethod func(srv *aibridgedserver.Server, ctx context.Context, req Req) (Resp, error),
|
||||
cases []testRecordMethodCase[Req],
|
||||
) {
|
||||
t.Helper()
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
ctrl := gomock.NewController(t)
|
||||
db := dbmock.NewMockStore(ctrl)
|
||||
logger := testutil.Logger(t)
|
||||
|
||||
if tc.setupMocks != nil {
|
||||
tc.setupMocks(t, db, tc.request)
|
||||
}
|
||||
|
||||
ctx := testutil.Context(t, testutil.WaitLong)
|
||||
srv, err := aibridgedserver.NewServer(ctx, db, logger, "/", nil, requiredExperiments)
|
||||
require.NoError(t, err)
|
||||
|
||||
resp, err := callMethod(srv, ctx, tc.request)
|
||||
if tc.expectedErr != "" {
|
||||
require.Error(t, err, "Expected error for test case: %s", tc.name)
|
||||
require.Contains(t, err.Error(), tc.expectedErr)
|
||||
} else {
|
||||
require.NoError(t, err, "Unexpected error for test case: %s", tc.name)
|
||||
require.NotNil(t, resp)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Helper functions.
|
||||
func mustMarshalAny(t *testing.T, msg protobufproto.Message) *anypb.Any {
|
||||
t.Helper()
|
||||
v, err := anypb.New(msg)
|
||||
require.NoError(t, err)
|
||||
return v
|
||||
}
|
||||
|
||||
func strPtr(s string) *string {
|
||||
return &s
|
||||
}
|
||||
Reference in New Issue
Block a user